From f6682e6cefe235d94600f637d336330c485f151b Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Thu, 20 Jan 2011 18:08:01 -0600 Subject: [PATCH 001/111] added default label to nova-manage and create_networks --- bin/nova-manage | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index d0901ddf..38d36ab0 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -442,7 +442,7 @@ class NetworkCommands(object): def create(self, fixed_range=None, num_networks=None, network_size=None, vlan_start=None, vpn_start=None, - fixed_range_v6=None): + fixed_range_v6=None, label='public'): """Creates fixed ips for host by range arguments: [fixed_range=FLAG], [num_networks=FLAG], [network_size=FLAG], [vlan_start=FLAG], @@ -463,7 +463,8 @@ class NetworkCommands(object): net_manager.create_networks(context.get_admin_context(), fixed_range, int(num_networks), int(network_size), int(vlan_start), - int(vpn_start), fixed_range_v6) + int(vpn_start), fixed_range_v6, + label) class ServiceCommands(object): From 51d5452ff1e1b09f8b4a9759f607caf0af9a95a8 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Thu, 20 Jan 2011 18:44:00 -0600 Subject: [PATCH 002/111] moved argument for label --- bin/nova-manage | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 38d36ab0..73832b0e 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -441,8 +441,8 @@ class NetworkCommands(object): """Class for managing networks.""" def create(self, fixed_range=None, num_networks=None, - network_size=None, vlan_start=None, vpn_start=None, - fixed_range_v6=None, label='public'): + network_size=None, label='public', vlan_start=None, + vpn_start=None, fixed_range_v6=None): """Creates fixed ips for host by range arguments: [fixed_range=FLAG], [num_networks=FLAG], [network_size=FLAG], [vlan_start=FLAG], From 9a7b8c6fe03860f80d6dd14193eac1cc6ad324e3 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Thu, 20 Jan 2011 18:51:46 -0600 Subject: [PATCH 003/111] undid moving argument --- bin/nova-manage | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 73832b0e..9603c6a4 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -441,8 +441,8 @@ class NetworkCommands(object): """Class for managing networks.""" def create(self, fixed_range=None, num_networks=None, - network_size=None, label='public', vlan_start=None, - vpn_start=None, fixed_range_v6=None): + network_size=None, vlan_start=None, + vpn_start=None, fixed_range_v6=None, label='public'): """Creates fixed ips for host by range arguments: [fixed_range=FLAG], [num_networks=FLAG], [network_size=FLAG], [vlan_start=FLAG], From 303a653db4c3eb2dc756bbe7e63637486c3fce70 Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of nova-core <> Date: Fri, 28 Jan 2011 05:21:04 +0000 Subject: [PATCH 004/111] Launchpad automatic translations update. --- locale/ast.po | 2130 ++++++++++++++++++++++++++++++++++++++++++++++ locale/da.po | 2130 ++++++++++++++++++++++++++++++++++++++++++++++ locale/es.po | 2177 +++++++++++++++++++++++++++++++++++++++++++++++ locale/it.po | 2141 ++++++++++++++++++++++++++++++++++++++++++++++ locale/ja.po | 2143 ++++++++++++++++++++++++++++++++++++++++++++++ locale/pt_BR.po | 2148 ++++++++++++++++++++++++++++++++++++++++++++++ locale/ru.po | 2136 ++++++++++++++++++++++++++++++++++++++++++++++ locale/uk.po | 2130 ++++++++++++++++++++++++++++++++++++++++++++++ locale/zh_CN.po | 2135 ++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 19270 insertions(+) create mode 100644 locale/ast.po create mode 100644 locale/da.po create mode 100644 locale/es.po create mode 100644 locale/it.po create mode 100644 locale/ja.po create mode 100644 locale/pt_BR.po create mode 100644 locale/ru.po create mode 100644 locale/uk.po create mode 100644 locale/zh_CN.po diff --git a/locale/ast.po b/locale/ast.po new file mode 100644 index 00000000..c887bbc9 --- /dev/null +++ b/locale/ast.po @@ -0,0 +1,2130 @@ +# Asturian translation for nova +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the nova package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: nova\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"PO-Revision-Date: 2011-01-12 19:50+0000\n" +"Last-Translator: Xuacu Saturio \n" +"Language-Team: Asturian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-01-28 05:20+0000\n" +"X-Generator: Launchpad (build 12177)\n" + +#: nova/crypto.py:46 +msgid "Filename of root CA" +msgstr "Nome del ficheru de l'autoridá de certificáu raíz" + +#: nova/crypto.py:49 +msgid "Filename of private key" +msgstr "Nome del ficheru de clave privada" + +#: nova/crypto.py:51 +msgid "Filename of root Certificate Revokation List" +msgstr "Nome del ficheru de llista de refugu de certificáu raíz" + +#: nova/crypto.py:53 +msgid "Where we keep our keys" +msgstr "" + +#: nova/crypto.py:55 +msgid "Where we keep our root CA" +msgstr "" + +#: nova/crypto.py:57 +msgid "Should we use a CA for each project?" +msgstr "" + +#: nova/crypto.py:61 +#, python-format +msgid "Subject for certificate for users, %s for project, user, timestamp" +msgstr "" + +#: nova/crypto.py:66 +#, python-format +msgid "Subject for certificate for projects, %s for project, timestamp" +msgstr "" + +#: nova/crypto.py:71 +#, python-format +msgid "Subject for certificate for vpns, %s for project, timestamp" +msgstr "" + +#: nova/crypto.py:258 +#, python-format +msgid "Flags path: %s" +msgstr "" + +#: nova/exception.py:33 +msgid "Unexpected error while running command." +msgstr "" + +#: nova/exception.py:36 +#, python-format +msgid "" +"%s\n" +"Command: %s\n" +"Exit code: %s\n" +"Stdout: %r\n" +"Stderr: %r" +msgstr "" + +#: nova/exception.py:86 +msgid "Uncaught exception" +msgstr "" + +#: nova/fakerabbit.py:48 +#, python-format +msgid "(%s) publish (key: %s) %s" +msgstr "" + +#: nova/fakerabbit.py:53 +#, python-format +msgid "Publishing to route %s" +msgstr "" + +#: nova/fakerabbit.py:83 +#, python-format +msgid "Declaring queue %s" +msgstr "" + +#: nova/fakerabbit.py:89 +#, python-format +msgid "Declaring exchange %s" +msgstr "" + +#: nova/fakerabbit.py:95 +#, python-format +msgid "Binding %s to %s with key %s" +msgstr "" + +#: nova/fakerabbit.py:120 +#, python-format +msgid "Getting from %s: %s" +msgstr "" + +#: nova/rpc.py:92 +#, python-format +msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgstr "" + +#: nova/rpc.py:99 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "" + +#: nova/rpc.py:118 +msgid "Reconnected to queue" +msgstr "" + +#: nova/rpc.py:125 +msgid "Failed to fetch message from queue" +msgstr "" + +#: nova/rpc.py:155 +#, python-format +msgid "Initing the Adapter Consumer for %s" +msgstr "" + +#: nova/rpc.py:170 +#, python-format +msgid "received %s" +msgstr "" + +#: nova/rpc.py:183 +#, python-format +msgid "no method for message: %s" +msgstr "" + +#: nova/rpc.py:184 +#, python-format +msgid "No method for message: %s" +msgstr "" + +#: nova/rpc.py:245 +#, python-format +msgid "Returning exception %s to caller" +msgstr "" + +#: nova/rpc.py:286 +#, python-format +msgid "unpacked context: %s" +msgstr "" + +#: nova/rpc.py:305 +msgid "Making asynchronous call..." +msgstr "" + +#: nova/rpc.py:308 +#, python-format +msgid "MSG_ID is %s" +msgstr "" + +#: nova/rpc.py:356 +#, python-format +msgid "response %s" +msgstr "" + +#: nova/rpc.py:365 +#, python-format +msgid "topic is %s" +msgstr "" + +#: nova/rpc.py:366 +#, python-format +msgid "message %s" +msgstr "" + +#: nova/service.py:157 +#, python-format +msgid "Starting %s node" +msgstr "" + +#: nova/service.py:169 +msgid "Service killed that has no database entry" +msgstr "" + +#: nova/service.py:190 +msgid "The service database object disappeared, Recreating it." +msgstr "" + +#: nova/service.py:202 +msgid "Recovered model server connection!" +msgstr "" + +#: nova/service.py:208 +msgid "model server went away" +msgstr "" + +#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#, python-format +msgid "Data store %s is unreachable. Trying again in %d seconds." +msgstr "" + +#: nova/service.py:232 nova/twistd.py:232 +#, python-format +msgid "Serving %s" +msgstr "" + +#: nova/service.py:234 nova/twistd.py:264 +msgid "Full set of FLAGS:" +msgstr "" + +#: nova/twistd.py:211 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "" + +#: nova/twistd.py:268 +#, python-format +msgid "Starting %s" +msgstr "" + +#: nova/utils.py:53 +#, python-format +msgid "Inner Exception: %s" +msgstr "" + +#: nova/utils.py:54 +#, python-format +msgid "Class %s cannot be found" +msgstr "" + +#: nova/utils.py:113 +#, python-format +msgid "Fetching %s" +msgstr "" + +#: nova/utils.py:125 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "" + +#: nova/utils.py:138 +#, python-format +msgid "Result was %s" +msgstr "" + +#: nova/utils.py:171 +#, python-format +msgid "debug in callback: %s" +msgstr "" + +#: nova/utils.py:176 +#, python-format +msgid "Running %s" +msgstr "" + +#: nova/utils.py:207 +#, python-format +msgid "Couldn't get IP, using 127.0.0.1 %s" +msgstr "" + +#: nova/utils.py:289 +#, python-format +msgid "Invalid backend: %s" +msgstr "" + +#: nova/utils.py:300 +#, python-format +msgid "backend %s" +msgstr "" + +#: nova/api/ec2/__init__.py:133 +msgid "Too many failed authentications." +msgstr "" + +#: nova/api/ec2/__init__.py:142 +#, python-format +msgid "" +"Access key %s has had %d failed authentications and will be locked out for " +"%d minutes." +msgstr "" + +#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#, python-format +msgid "Authentication Failure: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:190 +#, python-format +msgid "Authenticated Request For %s:%s)" +msgstr "" + +#: nova/api/ec2/__init__.py:227 +#, python-format +msgid "action: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:229 +#, python-format +msgid "arg: %s\t\tval: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:301 +#, python-format +msgid "Unauthorized request for controller=%s and action=%s" +msgstr "" + +#: nova/api/ec2/__init__.py:339 +#, python-format +msgid "NotFound raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:342 +#, python-format +msgid "ApiError raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:349 +#, python-format +msgid "Unexpected error raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:354 +msgid "An unknown error has occurred. Please try your request again." +msgstr "" + +#: nova/api/ec2/admin.py:84 +#, python-format +msgid "Creating new user: %s" +msgstr "" + +#: nova/api/ec2/admin.py:92 +#, python-format +msgid "Deleting user: %s" +msgstr "" + +#: nova/api/ec2/admin.py:114 +#, python-format +msgid "Adding role %s to user %s for project %s" +msgstr "" + +#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#, python-format +msgid "Adding sitewide role %s to user %s" +msgstr "" + +#: nova/api/ec2/admin.py:122 +#, python-format +msgid "Removing role %s from user %s for project %s" +msgstr "" + +#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#, python-format +msgid "Removing sitewide role %s from user %s" +msgstr "" + +#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 +msgid "operation must be add or remove" +msgstr "" + +#: nova/api/ec2/admin.py:142 +#, python-format +msgid "Getting x509 for user: %s on project: %s" +msgstr "" + +#: nova/api/ec2/admin.py:159 +#, python-format +msgid "Create project %s managed by %s" +msgstr "" + +#: nova/api/ec2/admin.py:170 +#, python-format +msgid "Delete project: %s" +msgstr "" + +#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#, python-format +msgid "Adding user %s to project %s" +msgstr "" + +#: nova/api/ec2/admin.py:188 +#, python-format +msgid "Removing user %s from project %s" +msgstr "" + +#: nova/api/ec2/apirequest.py:95 +#, python-format +msgid "Unsupported API request: controller = %s,action = %s" +msgstr "" + +#: nova/api/ec2/cloud.py:117 +#, python-format +msgid "Generating root CA: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:277 +#, python-format +msgid "Create key pair %s" +msgstr "" + +#: nova/api/ec2/cloud.py:285 +#, python-format +msgid "Delete key pair %s" +msgstr "" + +#: nova/api/ec2/cloud.py:357 +#, python-format +msgid "%s is not a valid ipProtocol" +msgstr "" + +#: nova/api/ec2/cloud.py:361 +msgid "Invalid port range" +msgstr "" + +#: nova/api/ec2/cloud.py:392 +#, python-format +msgid "Revoke security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 +msgid "No rule for the specified parameters." +msgstr "" + +#: nova/api/ec2/cloud.py:421 +#, python-format +msgid "Authorize security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:432 +#, python-format +msgid "This rule already exists in group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:460 +#, python-format +msgid "Create Security Group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:463 +#, python-format +msgid "group %s already exists" +msgstr "" + +#: nova/api/ec2/cloud.py:475 +#, python-format +msgid "Delete security group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:543 +#, python-format +msgid "Create volume of %s GB" +msgstr "" + +#: nova/api/ec2/cloud.py:567 +#, python-format +msgid "Attach volume %s to instacne %s at %s" +msgstr "" + +#: nova/api/ec2/cloud.py:579 +#, python-format +msgid "Detach volume %s" +msgstr "" + +#: nova/api/ec2/cloud.py:686 +msgid "Allocate address" +msgstr "" + +#: nova/api/ec2/cloud.py:691 +#, python-format +msgid "Release address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:696 +#, python-format +msgid "Associate address %s to instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:703 +#, python-format +msgid "Disassociate address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:730 +msgid "Going to start terminating instances" +msgstr "" + +#: nova/api/ec2/cloud.py:738 +#, python-format +msgid "Reboot instance %r" +msgstr "" + +#: nova/api/ec2/cloud.py:775 +#, python-format +msgid "De-registering image %s" +msgstr "" + +#: nova/api/ec2/cloud.py:783 +#, python-format +msgid "Registered image %s with id %s" +msgstr "" + +#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#, python-format +msgid "attribute not supported: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:794 +#, python-format +msgid "invalid id: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:807 +msgid "user or group not specified" +msgstr "" + +#: nova/api/ec2/cloud.py:809 +msgid "only group \"all\" is supported" +msgstr "" + +#: nova/api/ec2/cloud.py:811 +msgid "operation_type must be add or remove" +msgstr "" + +#: nova/api/ec2/cloud.py:812 +#, python-format +msgid "Updating image %s publicity" +msgstr "" + +#: nova/api/ec2/metadatarequesthandler.py:75 +#, python-format +msgid "Failed to get metadata for ip: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:70 +#, python-format +msgid "Caught error: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:86 +msgid "Including admin operations in API." +msgstr "" + +#: nova/api/openstack/servers.py:184 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:199 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: nova/api/openstack/servers.py:213 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:224 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: nova/api/openstack/servers.py:235 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: nova/api/openstack/servers.py:246 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: nova/api/openstack/servers.py:257 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: nova/auth/dbdriver.py:84 +#, python-format +msgid "User %s already exists" +msgstr "" + +#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#, python-format +msgid "Project can't be created because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#, python-format +msgid "Project can't be created because project %s already exists" +msgstr "" + +#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#, python-format +msgid "Project can't be modified because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:245 +#, python-format +msgid "User \"%s\" not found" +msgstr "" + +#: nova/auth/dbdriver.py:248 +#, python-format +msgid "Project \"%s\" not found" +msgstr "" + +#: nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "" + +#: nova/auth/ldapdriver.py:181 +#, python-format +msgid "LDAP object for %s doesn't exist" +msgstr "" + +#: nova/auth/ldapdriver.py:218 +#, python-format +msgid "Project can't be created because user %s doesn't exist" +msgstr "" + +#: nova/auth/ldapdriver.py:478 +#, python-format +msgid "User %s is already a member of the group %s" +msgstr "" + +#: nova/auth/ldapdriver.py:507 +#, python-format +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." +msgstr "" + +#: nova/auth/ldapdriver.py:528 +#, python-format +msgid "Group at dn %s doesn't exist" +msgstr "" + +#: nova/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "" + +#: nova/auth/manager.py:263 +#, python-format +msgid "Failed authorization for access key %s" +msgstr "" + +#: nova/auth/manager.py:264 +#, python-format +msgid "No user found for access key %s" +msgstr "" + +#: nova/auth/manager.py:270 +#, python-format +msgid "Using project name = user name (%s)" +msgstr "" + +#: nova/auth/manager.py:275 +#, python-format +msgid "failed authorization: no project named %s (user=%s)" +msgstr "" + +#: nova/auth/manager.py:277 +#, python-format +msgid "No project called %s could be found" +msgstr "" + +#: nova/auth/manager.py:281 +#, python-format +msgid "Failed authorization: user %s not admin and not member of project %s" +msgstr "" + +#: nova/auth/manager.py:283 +#, python-format +msgid "User %s is not a member of project %s" +msgstr "" + +#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#, python-format +msgid "Invalid signature for user %s" +msgstr "" + +#: nova/auth/manager.py:293 nova/auth/manager.py:304 +msgid "Signature does not match" +msgstr "" + +#: nova/auth/manager.py:374 +msgid "Must specify project" +msgstr "" + +#: nova/auth/manager.py:408 +#, python-format +msgid "The %s role can not be found" +msgstr "" + +#: nova/auth/manager.py:410 +#, python-format +msgid "The %s role is global only" +msgstr "" + +#: nova/auth/manager.py:412 +#, python-format +msgid "Adding role %s to user %s in project %s" +msgstr "" + +#: nova/auth/manager.py:438 +#, python-format +msgid "Removing role %s from user %s on project %s" +msgstr "" + +#: nova/auth/manager.py:505 +#, python-format +msgid "Created project %s with manager %s" +msgstr "" + +#: nova/auth/manager.py:523 +#, python-format +msgid "modifying project %s" +msgstr "" + +#: nova/auth/manager.py:553 +#, python-format +msgid "Remove user %s from project %s" +msgstr "" + +#: nova/auth/manager.py:581 +#, python-format +msgid "Deleting project %s" +msgstr "" + +#: nova/auth/manager.py:637 +#, python-format +msgid "Created user %s (admin: %r)" +msgstr "" + +#: nova/auth/manager.py:645 +#, python-format +msgid "Deleting user %s" +msgstr "" + +#: nova/auth/manager.py:655 +#, python-format +msgid "Access Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:657 +#, python-format +msgid "Secret Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:659 +#, python-format +msgid "Admin status set to %r for user %s" +msgstr "" + +#: nova/auth/manager.py:708 +#, python-format +msgid "No vpn data for project %s" +msgstr "" + +#: nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" +msgstr "" + +#: nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:97 +#, python-format +msgid "Launching VPN for %s" +msgstr "" + +#: nova/compute/api.py:67 +#, python-format +msgid "Instance %d was not found in get_network_topic" +msgstr "" + +#: nova/compute/api.py:73 +#, python-format +msgid "Instance %d has no host" +msgstr "" + +#: nova/compute/api.py:92 +#, python-format +msgid "Quota exceeeded for %s, tried to run %s instances" +msgstr "" + +#: nova/compute/api.py:94 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." +msgstr "" + +#: nova/compute/api.py:109 +msgid "Creating a raw instance" +msgstr "" + +#: nova/compute/api.py:156 +#, python-format +msgid "Going to run %s instances..." +msgstr "" + +#: nova/compute/api.py:180 +#, python-format +msgid "Casting to scheduler for %s/%s's instance %s" +msgstr "" + +#: nova/compute/api.py:279 +#, python-format +msgid "Going to try and terminate %s" +msgstr "" + +#: nova/compute/api.py:283 +#, python-format +msgid "Instance %d was not found during terminate" +msgstr "" + +#: nova/compute/api.py:288 +#, python-format +msgid "Instance %d is already being terminated" +msgstr "" + +#: nova/compute/api.py:450 +#, python-format +msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgstr "" + +#: nova/compute/api.py:465 +msgid "Volume isn't attached to anything!" +msgstr "" + +#: nova/compute/disk.py:71 +#, python-format +msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:75 +#, python-format +msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:128 +#, python-format +msgid "Could not attach image to loopback: %s" +msgstr "" + +#: nova/compute/disk.py:136 +#, python-format +msgid "Failed to load partition: %s" +msgstr "" + +#: nova/compute/disk.py:158 +#, python-format +msgid "Failed to mount filesystem: %s" +msgstr "" + +#: nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "" + +#: nova/compute/manager.py:69 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: nova/compute/manager.py:71 +#, python-format +msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgstr "" + +#: nova/compute/manager.py:75 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: nova/compute/manager.py:77 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: nova/compute/manager.py:82 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: nova/compute/manager.py:157 +msgid "Instance has already been created" +msgstr "" + +#: nova/compute/manager.py:158 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#: nova/compute/manager.py:197 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: nova/compute/manager.py:217 +#, python-format +msgid "Disassociating address %s" +msgstr "" + +#: nova/compute/manager.py:230 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: nova/compute/manager.py:243 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: nova/compute/manager.py:257 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: nova/compute/manager.py:260 +#, python-format +msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:286 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: nova/compute/manager.py:289 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:301 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: nova/compute/manager.py:316 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: nova/compute/manager.py:335 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: nova/compute/manager.py:352 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: nova/compute/manager.py:369 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: nova/compute/manager.py:382 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: nova/compute/manager.py:401 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: nova/compute/manager.py:420 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: nova/compute/manager.py:432 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: nova/compute/manager.py:442 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: nova/compute/manager.py:462 +#, python-format +msgid "instance %s: attaching volume %s to %s" +msgstr "" + +#: nova/compute/manager.py:478 +#, python-format +msgid "instance %s: attach failed %s, removing" +msgstr "" + +#: nova/compute/manager.py:493 +#, python-format +msgid "Detach volume %s from mountpoint %s on instance %s" +msgstr "" + +#: nova/compute/manager.py:497 +#, python-format +msgid "Detaching volume from unknown instance %s" +msgstr "" + +#: nova/compute/monitor.py:259 +#, python-format +msgid "updating %s..." +msgstr "" + +#: nova/compute/monitor.py:289 +msgid "unexpected error during update" +msgstr "" + +#: nova/compute/monitor.py:355 +#, python-format +msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:377 +#, python-format +msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:412 +msgid "unexpected exception getting connection" +msgstr "" + +#: nova/compute/monitor.py:427 +#, python-format +msgid "Found instance: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:43 +msgid "Use of empty request context is deprecated" +msgstr "" + +#: nova/db/sqlalchemy/api.py:132 +#, python-format +msgid "No service for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:229 +#, python-format +msgid "No service for %s, %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:574 +#, python-format +msgid "No floating ip for address %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:668 +#, python-format +msgid "No instance for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:758 nova/virt/libvirt_conn.py:598 +#: nova/virt/xenapi/volumeops.py:48 nova/virt/xenapi/volumeops.py:103 +#, python-format +msgid "Instance %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:891 +#, python-format +msgid "no keypair for user %s, name %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#, python-format +msgid "No network for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1036 +#, python-format +msgid "No network for bridge %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1050 +#, python-format +msgid "No network for instance %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1180 +#, python-format +msgid "Token %s does not exist" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1205 +#, python-format +msgid "No quota for project_id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1356 +#, python-format +msgid "No volume for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1401 +#, python-format +msgid "Volume %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1413 +#, python-format +msgid "No export device found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1426 +#, python-format +msgid "No target id found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1471 +#, python-format +msgid "No security group with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1488 +#, python-format +msgid "No security group named %s for project: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1576 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1650 +#, python-format +msgid "No user for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1666 +#, python-format +msgid "No user for access key %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1728 +#, python-format +msgid "No project with id %s" +msgstr "" + +#: nova/image/glance.py:78 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images" +msgstr "" + +#: nova/image/glance.py:97 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images/detail" +msgstr "" + +#: nova/image/s3.py:82 +#, python-format +msgid "Image %s could not be found" +msgstr "" + +#: nova/network/api.py:39 +#, python-format +msgid "Quota exceeeded for %s, tried to allocate address" +msgstr "" + +#: nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" +msgstr "" + +#: nova/network/linux_net.py:176 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: nova/network/linux_net.py:186 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#: nova/network/linux_net.py:254 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: nova/network/linux_net.py:256 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#: nova/network/linux_net.py:334 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: nova/network/manager.py:135 +msgid "setting network host" +msgstr "" + +#: nova/network/manager.py:190 +#, python-format +msgid "Leasing IP %s" +msgstr "" + +#: nova/network/manager.py:194 +#, python-format +msgid "IP %s leased that isn't associated" +msgstr "" + +#: nova/network/manager.py:197 +#, python-format +msgid "IP %s leased to bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:205 +#, python-format +msgid "IP %s leased that was already deallocated" +msgstr "" + +#: nova/network/manager.py:214 +#, python-format +msgid "IP %s released that isn't associated" +msgstr "" + +#: nova/network/manager.py:217 +#, python-format +msgid "IP %s released from bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:220 +#, python-format +msgid "IP %s released that was not leased" +msgstr "" + +#: nova/network/manager.py:442 +#, python-format +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "" + +#: nova/objectstore/handler.py:106 +#, python-format +msgid "Unknown S3 value type %r" +msgstr "" + +#: nova/objectstore/handler.py:137 +msgid "Authenticated request" +msgstr "" + +#: nova/objectstore/handler.py:182 +msgid "List of buckets requested" +msgstr "" + +#: nova/objectstore/handler.py:209 +#, python-format +msgid "List keys for bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:217 +#, python-format +msgid "Unauthorized attempt to access bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:235 +#, python-format +msgid "Creating bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:245 +#, python-format +msgid "Deleting bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:249 +#, python-format +msgid "Unauthorized attempt to delete bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:271 +#, python-format +msgid "Getting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:274 +#, python-format +msgid "Unauthorized attempt to get object %s from bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:292 +#, python-format +msgid "Putting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:295 +#, python-format +msgid "Unauthorized attempt to upload object %s to bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:314 +#, python-format +msgid "Deleting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:393 +#, python-format +msgid "Not authorized to upload image: invalid directory %s" +msgstr "" + +#: nova/objectstore/handler.py:401 +#, python-format +msgid "Not authorized to upload image: unauthorized bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:406 +#, python-format +msgid "Starting image upload: %s" +msgstr "" + +#: nova/objectstore/handler.py:420 +#, python-format +msgid "Not authorized to update attributes of image %s" +msgstr "" + +#: nova/objectstore/handler.py:428 +#, python-format +msgid "Toggling publicity flag of image %s %r" +msgstr "" + +#: nova/objectstore/handler.py:433 +#, python-format +msgid "Updating user fields on image %s" +msgstr "" + +#: nova/objectstore/handler.py:447 +#, python-format +msgid "Unauthorized attempt to delete image %s" +msgstr "" + +#: nova/objectstore/handler.py:452 +#, python-format +msgid "Deleted image: %s" +msgstr "" + +#: nova/scheduler/chance.py:37 nova/scheduler/simple.py:73 +#: nova/scheduler/simple.py:106 nova/scheduler/simple.py:118 +msgid "No hosts found" +msgstr "" + +#: nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "" + +#: nova/scheduler/manager.py:69 +#, python-format +msgid "Casting to %s %s for %s" +msgstr "" + +#: nova/scheduler/simple.py:63 +msgid "All hosts have too many cores" +msgstr "" + +#: nova/scheduler/simple.py:95 +msgid "All hosts have too many gigabytes" +msgstr "" + +#: nova/scheduler/simple.py:115 +msgid "All hosts have too many networks" +msgstr "" + +#: nova/tests/test_cloud.py:198 +msgid "Can't test instances without a real virtual env." +msgstr "" + +#: nova/tests/test_cloud.py:210 +#, python-format +msgid "Need to watch instance %s until it's running..." +msgstr "" + +#: nova/tests/test_compute.py:104 +#, python-format +msgid "Running instances: %s" +msgstr "" + +#: nova/tests/test_compute.py:110 +#, python-format +msgid "After terminating instances: %s" +msgstr "" + +#: nova/tests/test_rpc.py:89 +#, python-format +msgid "Nested received %s, %s" +msgstr "" + +#: nova/tests/test_rpc.py:94 +#, python-format +msgid "Nested return %s" +msgstr "" + +#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#, python-format +msgid "Received %s" +msgstr "" + +#: nova/tests/test_volume.py:162 +#, python-format +msgid "Target %s allocated" +msgstr "" + +#: nova/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "" + +#: nova/virt/fake.py:210 +#, python-format +msgid "Instance %s Not Found" +msgstr "" + +#: nova/virt/hyperv.py:118 +msgid "In init host" +msgstr "" + +#: nova/virt/hyperv.py:131 +#, python-format +msgid "Attempt to create duplicate vm %s" +msgstr "" + +#: nova/virt/hyperv.py:148 +#, python-format +msgid "Starting VM %s " +msgstr "" + +#: nova/virt/hyperv.py:150 +#, python-format +msgid "Started VM %s " +msgstr "" + +#: nova/virt/hyperv.py:152 +#, python-format +msgid "spawn vm failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:169 +#, python-format +msgid "Failed to create VM %s" +msgstr "" + +#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#, python-format +msgid "Created VM %s..." +msgstr "" + +#: nova/virt/hyperv.py:188 +#, python-format +msgid "Set memory for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:198 +#, python-format +msgid "Set vcpus for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:202 +#, python-format +msgid "Creating disk for %s by attaching disk file %s" +msgstr "" + +#: nova/virt/hyperv.py:227 +#, python-format +msgid "Failed to add diskdrive to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:230 +#, python-format +msgid "New disk drive path is %s" +msgstr "" + +#: nova/virt/hyperv.py:247 +#, python-format +msgid "Failed to add vhd file to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:249 +#, python-format +msgid "Created disk for %s" +msgstr "" + +#: nova/virt/hyperv.py:253 +#, python-format +msgid "Creating nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" +msgstr "" + +#: nova/virt/hyperv.py:273 +#, python-format +msgid "Failed creating port for %s" +msgstr "" + +#: nova/virt/hyperv.py:275 +#, python-format +msgid "Created switch port %s on switch %s" +msgstr "" + +#: nova/virt/hyperv.py:285 +#, python-format +msgid "Failed to add nic to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:287 +#, python-format +msgid "Created nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:320 +#, python-format +msgid "WMI job failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:322 +#, python-format +msgid "WMI job succeeded: %s, Elapsed=%s " +msgstr "" + +#: nova/virt/hyperv.py:358 +#, python-format +msgid "Got request to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:383 +#, python-format +msgid "Failed to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:389 +#, python-format +msgid "Del: disk %s vm %s" +msgstr "" + +#: nova/virt/hyperv.py:405 +#, python-format +msgid "" +"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " +"cpu_time=%s" +msgstr "" + +#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#, python-format +msgid "duplicate name found: %s" +msgstr "" + +#: nova/virt/hyperv.py:444 +#, python-format +msgid "Successfully changed vm state of %s to %s" +msgstr "" + +#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#, python-format +msgid "Failed to change vm state of %s to %s" +msgstr "" + +#: nova/virt/images.py:70 +#, python-format +msgid "Finished retreving %s -- placed in %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:144 +#, python-format +msgid "Connecting to libvirt: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:157 +msgid "Connection to libvirt broke" +msgstr "" + +#: nova/virt/libvirt_conn.py:229 +#, python-format +msgid "instance %s: deleting instance files %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:271 +#, python-format +msgid "No disk at %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:278 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "" + +#: nova/virt/libvirt_conn.py:294 +#, python-format +msgid "instance %s: rebooted" +msgstr "" + +#: nova/virt/libvirt_conn.py:297 +#, python-format +msgid "_wait_for_reboot failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:340 +#, python-format +msgid "instance %s: rescued" +msgstr "" + +#: nova/virt/libvirt_conn.py:343 +#, python-format +msgid "_wait_for_rescue failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:370 +#, python-format +msgid "instance %s: is running" +msgstr "" + +#: nova/virt/libvirt_conn.py:381 +#, python-format +msgid "instance %s: booted" +msgstr "" + +#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#, python-format +msgid "instance %s: failed to boot" +msgstr "" + +#: nova/virt/libvirt_conn.py:395 +#, python-format +msgid "virsh said: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:399 +msgid "cool, it's a device" +msgstr "" + +#: nova/virt/libvirt_conn.py:407 +#, python-format +msgid "data: %r, fpath: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:415 +#, python-format +msgid "Contents of file %s: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:449 +#, python-format +msgid "instance %s: Creating image" +msgstr "" + +#: nova/virt/libvirt_conn.py:505 +#, python-format +msgid "instance %s: injecting key into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:508 +#, python-format +msgid "instance %s: injecting net into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:516 +#, python-format +msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgstr "" + +#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#, python-format +msgid "instance %s: starting toXML method" +msgstr "" + +#: nova/virt/libvirt_conn.py:589 +#, python-format +msgid "instance %s: finished toXML method" +msgstr "" + +#: nova/virt/xenapi_conn.py:113 +msgid "" +"Must specify xenapi_connection_url, xenapi_connection_username (optionally), " +"and xenapi_connection_password to use connection_type=xenapi" +msgstr "" + +#: nova/virt/xenapi_conn.py:263 +#, python-format +msgid "Task [%s] %s status: success %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:271 +#, python-format +msgid "Task [%s] %s status: %s %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#, python-format +msgid "Got exception: %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:72 +#, python-format +msgid "%s: _db_content => %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:247 nova/virt/xenapi/fake.py:338 +#: nova/virt/xenapi/fake.py:356 nova/virt/xenapi/fake.py:404 +msgid "Raising NotImplemented" +msgstr "" + +#: nova/virt/xenapi/fake.py:249 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:283 +#, python-format +msgid "Calling %s %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:288 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:340 +#, python-format +msgid "" +"xenapi.fake does not have an implementation for %s or it has been called " +"with the wrong number of arguments" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:40 +#, python-format +msgid "Found non-unique network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:43 +#, python-format +msgid "Found no network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:127 +#, python-format +msgid "Created VM %s as %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:147 +#, python-format +msgid "Creating VBD for VM %s, VDI %s ... " +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:149 +#, python-format +msgid "Created VBD %s for VM %s, VDI %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:165 +#, python-format +msgid "VBD not found in instance %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:175 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:202 +#, python-format +msgid "Creating VIF for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:205 +#, python-format +msgid "Created VIF %s for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:216 +#, python-format +msgid "Snapshotting VM %s with label '%s'..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:229 +#, python-format +msgid "Created snapshot %s from VM %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:243 +#, python-format +msgid "Asking xapi to upload %s as '%s'" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:261 +#, python-format +msgid "Asking xapi to fetch %s as %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:279 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:290 +#, python-format +msgid "PV Kernel in VDI:%d" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:318 +#, python-format +msgid "VDI %s is still available" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:331 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:333 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:390 +#, python-format +msgid "VHD %s has parent %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:407 +#, python-format +msgid "Re-scanning SR %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:431 +#, python-format +msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:448 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:452 +#, python-format +msgid "Unexpected number of VDIs (%s) found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:62 +#, python-format +msgid "Attempted to create non-unique name %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:99 +#, python-format +msgid "Starting VM %s..." +msgstr "" + +#: nova/virt/xenapi/vmops.py:101 +#, python-format +msgid "Spawning VM %s created %s." +msgstr "" + +#: nova/virt/xenapi/vmops.py:112 +#, python-format +msgid "Instance %s: booted" +msgstr "" + +#: nova/virt/xenapi/vmops.py:137 +#, python-format +msgid "Instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:166 +#, python-format +msgid "Starting snapshot for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:174 +#, python-format +msgid "Unable to Snapshot %s: %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:184 +#, python-format +msgid "Finished snapshot and upload for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:252 +#, python-format +msgid "suspend: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:262 +#, python-format +msgid "resume: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:271 +#, python-format +msgid "Instance not found %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:57 +#, python-format +msgid "Introducing %s..." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:74 +#, python-format +msgid "Introduced %s as %s." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:90 +#, python-format +msgid "Unable to find SR from VBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:96 +#, python-format +msgid "Forgetting SR %s ... " +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:101 +#, python-format +msgid "Ignoring exception %s when getting PBDs for %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:107 +#, python-format +msgid "Ignoring exception %s when unplugging PBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:111 +#, python-format +msgid "Forgetting SR %s done." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:113 +#, python-format +msgid "Ignoring exception %s when forgetting SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:123 +#, python-format +msgid "Unable to introduce VDI on SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:128 +#, python-format +msgid "Unable to get record of VDI %s on" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:146 +#, python-format +msgid "Unable to introduce VDI for SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:175 +#, python-format +msgid "Unable to obtain target information %s, %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:197 +#, python-format +msgid "Mountpoint cannot be translated: %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:51 +#, python-format +msgid "Attach_volume: %s, %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:69 +#, python-format +msgid "Unable to create VDI on SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:81 +#, python-format +msgid "Unable to use SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Unable to attach volume to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:95 +#, python-format +msgid "Mountpoint %s attached to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:106 +#, python-format +msgid "Detach_volume: %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:113 +#, python-format +msgid "Unable to locate volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:121 +#, python-format +msgid "Unable to detach volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:128 +#, python-format +msgid "Mountpoint %s detached from instance %s" +msgstr "" + +#: nova/volume/api.py:44 +#, python-format +msgid "Quota exceeeded for %s, tried to create %sG volume" +msgstr "" + +#: nova/volume/api.py:46 +#, python-format +msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgstr "" + +#: nova/volume/api.py:70 nova/volume/api.py:95 +msgid "Volume status must be available" +msgstr "" + +#: nova/volume/api.py:97 +msgid "Volume is already attached" +msgstr "" + +#: nova/volume/api.py:103 +msgid "Volume is already detached" +msgstr "" + +#: nova/volume/driver.py:76 +#, python-format +msgid "Recovering from a failed execute. Try number %s" +msgstr "" + +#: nova/volume/driver.py:85 +#, python-format +msgid "volume group %s doesn't exist" +msgstr "" + +#: nova/volume/driver.py:210 +#, python-format +msgid "FAKE AOE: %s" +msgstr "" + +#: nova/volume/driver.py:315 +#, python-format +msgid "FAKE ISCSI: %s" +msgstr "" + +#: nova/volume/manager.py:85 +#, python-format +msgid "Re-exporting %s volumes" +msgstr "" + +#: nova/volume/manager.py:93 +#, python-format +msgid "volume %s: creating" +msgstr "" + +#: nova/volume/manager.py:102 +#, python-format +msgid "volume %s: creating lv of size %sG" +msgstr "" + +#: nova/volume/manager.py:106 +#, python-format +msgid "volume %s: creating export" +msgstr "" + +#: nova/volume/manager.py:113 +#, python-format +msgid "volume %s: created successfully" +msgstr "" + +#: nova/volume/manager.py:121 +msgid "Volume is still attached" +msgstr "" + +#: nova/volume/manager.py:123 +msgid "Volume is not local to this node" +msgstr "" + +#: nova/volume/manager.py:124 +#, python-format +msgid "volume %s: removing export" +msgstr "" + +#: nova/volume/manager.py:126 +#, python-format +msgid "volume %s: deleting" +msgstr "" + +#: nova/volume/manager.py:129 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "" diff --git a/locale/da.po b/locale/da.po new file mode 100644 index 00000000..524b27a6 --- /dev/null +++ b/locale/da.po @@ -0,0 +1,2130 @@ +# Danish translation for nova +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the nova package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: nova\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"PO-Revision-Date: 2011-01-15 21:46+0000\n" +"Last-Translator: Soren Hansen \n" +"Language-Team: Danish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-01-28 05:20+0000\n" +"X-Generator: Launchpad (build 12177)\n" + +#: nova/crypto.py:46 +msgid "Filename of root CA" +msgstr "" + +#: nova/crypto.py:49 +msgid "Filename of private key" +msgstr "Filnavn for privatnøgle" + +#: nova/crypto.py:51 +msgid "Filename of root Certificate Revokation List" +msgstr "" + +#: nova/crypto.py:53 +msgid "Where we keep our keys" +msgstr "" + +#: nova/crypto.py:55 +msgid "Where we keep our root CA" +msgstr "" + +#: nova/crypto.py:57 +msgid "Should we use a CA for each project?" +msgstr "" + +#: nova/crypto.py:61 +#, python-format +msgid "Subject for certificate for users, %s for project, user, timestamp" +msgstr "" + +#: nova/crypto.py:66 +#, python-format +msgid "Subject for certificate for projects, %s for project, timestamp" +msgstr "" + +#: nova/crypto.py:71 +#, python-format +msgid "Subject for certificate for vpns, %s for project, timestamp" +msgstr "" + +#: nova/crypto.py:258 +#, python-format +msgid "Flags path: %s" +msgstr "" + +#: nova/exception.py:33 +msgid "Unexpected error while running command." +msgstr "" + +#: nova/exception.py:36 +#, python-format +msgid "" +"%s\n" +"Command: %s\n" +"Exit code: %s\n" +"Stdout: %r\n" +"Stderr: %r" +msgstr "" + +#: nova/exception.py:86 +msgid "Uncaught exception" +msgstr "" + +#: nova/fakerabbit.py:48 +#, python-format +msgid "(%s) publish (key: %s) %s" +msgstr "" + +#: nova/fakerabbit.py:53 +#, python-format +msgid "Publishing to route %s" +msgstr "" + +#: nova/fakerabbit.py:83 +#, python-format +msgid "Declaring queue %s" +msgstr "" + +#: nova/fakerabbit.py:89 +#, python-format +msgid "Declaring exchange %s" +msgstr "" + +#: nova/fakerabbit.py:95 +#, python-format +msgid "Binding %s to %s with key %s" +msgstr "" + +#: nova/fakerabbit.py:120 +#, python-format +msgid "Getting from %s: %s" +msgstr "" + +#: nova/rpc.py:92 +#, python-format +msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgstr "" + +#: nova/rpc.py:99 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "" + +#: nova/rpc.py:118 +msgid "Reconnected to queue" +msgstr "" + +#: nova/rpc.py:125 +msgid "Failed to fetch message from queue" +msgstr "" + +#: nova/rpc.py:155 +#, python-format +msgid "Initing the Adapter Consumer for %s" +msgstr "" + +#: nova/rpc.py:170 +#, python-format +msgid "received %s" +msgstr "" + +#: nova/rpc.py:183 +#, python-format +msgid "no method for message: %s" +msgstr "" + +#: nova/rpc.py:184 +#, python-format +msgid "No method for message: %s" +msgstr "" + +#: nova/rpc.py:245 +#, python-format +msgid "Returning exception %s to caller" +msgstr "" + +#: nova/rpc.py:286 +#, python-format +msgid "unpacked context: %s" +msgstr "" + +#: nova/rpc.py:305 +msgid "Making asynchronous call..." +msgstr "" + +#: nova/rpc.py:308 +#, python-format +msgid "MSG_ID is %s" +msgstr "" + +#: nova/rpc.py:356 +#, python-format +msgid "response %s" +msgstr "" + +#: nova/rpc.py:365 +#, python-format +msgid "topic is %s" +msgstr "" + +#: nova/rpc.py:366 +#, python-format +msgid "message %s" +msgstr "" + +#: nova/service.py:157 +#, python-format +msgid "Starting %s node" +msgstr "" + +#: nova/service.py:169 +msgid "Service killed that has no database entry" +msgstr "" + +#: nova/service.py:190 +msgid "The service database object disappeared, Recreating it." +msgstr "" + +#: nova/service.py:202 +msgid "Recovered model server connection!" +msgstr "" + +#: nova/service.py:208 +msgid "model server went away" +msgstr "" + +#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#, python-format +msgid "Data store %s is unreachable. Trying again in %d seconds." +msgstr "" + +#: nova/service.py:232 nova/twistd.py:232 +#, python-format +msgid "Serving %s" +msgstr "" + +#: nova/service.py:234 nova/twistd.py:264 +msgid "Full set of FLAGS:" +msgstr "" + +#: nova/twistd.py:211 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "" + +#: nova/twistd.py:268 +#, python-format +msgid "Starting %s" +msgstr "" + +#: nova/utils.py:53 +#, python-format +msgid "Inner Exception: %s" +msgstr "" + +#: nova/utils.py:54 +#, python-format +msgid "Class %s cannot be found" +msgstr "" + +#: nova/utils.py:113 +#, python-format +msgid "Fetching %s" +msgstr "" + +#: nova/utils.py:125 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "" + +#: nova/utils.py:138 +#, python-format +msgid "Result was %s" +msgstr "" + +#: nova/utils.py:171 +#, python-format +msgid "debug in callback: %s" +msgstr "" + +#: nova/utils.py:176 +#, python-format +msgid "Running %s" +msgstr "" + +#: nova/utils.py:207 +#, python-format +msgid "Couldn't get IP, using 127.0.0.1 %s" +msgstr "" + +#: nova/utils.py:289 +#, python-format +msgid "Invalid backend: %s" +msgstr "" + +#: nova/utils.py:300 +#, python-format +msgid "backend %s" +msgstr "" + +#: nova/api/ec2/__init__.py:133 +msgid "Too many failed authentications." +msgstr "" + +#: nova/api/ec2/__init__.py:142 +#, python-format +msgid "" +"Access key %s has had %d failed authentications and will be locked out for " +"%d minutes." +msgstr "" + +#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#, python-format +msgid "Authentication Failure: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:190 +#, python-format +msgid "Authenticated Request For %s:%s)" +msgstr "" + +#: nova/api/ec2/__init__.py:227 +#, python-format +msgid "action: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:229 +#, python-format +msgid "arg: %s\t\tval: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:301 +#, python-format +msgid "Unauthorized request for controller=%s and action=%s" +msgstr "" + +#: nova/api/ec2/__init__.py:339 +#, python-format +msgid "NotFound raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:342 +#, python-format +msgid "ApiError raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:349 +#, python-format +msgid "Unexpected error raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:354 +msgid "An unknown error has occurred. Please try your request again." +msgstr "" + +#: nova/api/ec2/admin.py:84 +#, python-format +msgid "Creating new user: %s" +msgstr "" + +#: nova/api/ec2/admin.py:92 +#, python-format +msgid "Deleting user: %s" +msgstr "" + +#: nova/api/ec2/admin.py:114 +#, python-format +msgid "Adding role %s to user %s for project %s" +msgstr "" + +#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#, python-format +msgid "Adding sitewide role %s to user %s" +msgstr "" + +#: nova/api/ec2/admin.py:122 +#, python-format +msgid "Removing role %s from user %s for project %s" +msgstr "" + +#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#, python-format +msgid "Removing sitewide role %s from user %s" +msgstr "" + +#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 +msgid "operation must be add or remove" +msgstr "" + +#: nova/api/ec2/admin.py:142 +#, python-format +msgid "Getting x509 for user: %s on project: %s" +msgstr "" + +#: nova/api/ec2/admin.py:159 +#, python-format +msgid "Create project %s managed by %s" +msgstr "" + +#: nova/api/ec2/admin.py:170 +#, python-format +msgid "Delete project: %s" +msgstr "" + +#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#, python-format +msgid "Adding user %s to project %s" +msgstr "" + +#: nova/api/ec2/admin.py:188 +#, python-format +msgid "Removing user %s from project %s" +msgstr "" + +#: nova/api/ec2/apirequest.py:95 +#, python-format +msgid "Unsupported API request: controller = %s,action = %s" +msgstr "" + +#: nova/api/ec2/cloud.py:117 +#, python-format +msgid "Generating root CA: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:277 +#, python-format +msgid "Create key pair %s" +msgstr "" + +#: nova/api/ec2/cloud.py:285 +#, python-format +msgid "Delete key pair %s" +msgstr "" + +#: nova/api/ec2/cloud.py:357 +#, python-format +msgid "%s is not a valid ipProtocol" +msgstr "" + +#: nova/api/ec2/cloud.py:361 +msgid "Invalid port range" +msgstr "" + +#: nova/api/ec2/cloud.py:392 +#, python-format +msgid "Revoke security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 +msgid "No rule for the specified parameters." +msgstr "" + +#: nova/api/ec2/cloud.py:421 +#, python-format +msgid "Authorize security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:432 +#, python-format +msgid "This rule already exists in group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:460 +#, python-format +msgid "Create Security Group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:463 +#, python-format +msgid "group %s already exists" +msgstr "" + +#: nova/api/ec2/cloud.py:475 +#, python-format +msgid "Delete security group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:543 +#, python-format +msgid "Create volume of %s GB" +msgstr "" + +#: nova/api/ec2/cloud.py:567 +#, python-format +msgid "Attach volume %s to instacne %s at %s" +msgstr "" + +#: nova/api/ec2/cloud.py:579 +#, python-format +msgid "Detach volume %s" +msgstr "" + +#: nova/api/ec2/cloud.py:686 +msgid "Allocate address" +msgstr "" + +#: nova/api/ec2/cloud.py:691 +#, python-format +msgid "Release address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:696 +#, python-format +msgid "Associate address %s to instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:703 +#, python-format +msgid "Disassociate address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:730 +msgid "Going to start terminating instances" +msgstr "" + +#: nova/api/ec2/cloud.py:738 +#, python-format +msgid "Reboot instance %r" +msgstr "" + +#: nova/api/ec2/cloud.py:775 +#, python-format +msgid "De-registering image %s" +msgstr "" + +#: nova/api/ec2/cloud.py:783 +#, python-format +msgid "Registered image %s with id %s" +msgstr "" + +#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#, python-format +msgid "attribute not supported: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:794 +#, python-format +msgid "invalid id: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:807 +msgid "user or group not specified" +msgstr "" + +#: nova/api/ec2/cloud.py:809 +msgid "only group \"all\" is supported" +msgstr "" + +#: nova/api/ec2/cloud.py:811 +msgid "operation_type must be add or remove" +msgstr "" + +#: nova/api/ec2/cloud.py:812 +#, python-format +msgid "Updating image %s publicity" +msgstr "" + +#: nova/api/ec2/metadatarequesthandler.py:75 +#, python-format +msgid "Failed to get metadata for ip: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:70 +#, python-format +msgid "Caught error: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:86 +msgid "Including admin operations in API." +msgstr "" + +#: nova/api/openstack/servers.py:184 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:199 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: nova/api/openstack/servers.py:213 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:224 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: nova/api/openstack/servers.py:235 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: nova/api/openstack/servers.py:246 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: nova/api/openstack/servers.py:257 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: nova/auth/dbdriver.py:84 +#, python-format +msgid "User %s already exists" +msgstr "" + +#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#, python-format +msgid "Project can't be created because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#, python-format +msgid "Project can't be created because project %s already exists" +msgstr "" + +#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#, python-format +msgid "Project can't be modified because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:245 +#, python-format +msgid "User \"%s\" not found" +msgstr "" + +#: nova/auth/dbdriver.py:248 +#, python-format +msgid "Project \"%s\" not found" +msgstr "" + +#: nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "" + +#: nova/auth/ldapdriver.py:181 +#, python-format +msgid "LDAP object for %s doesn't exist" +msgstr "" + +#: nova/auth/ldapdriver.py:218 +#, python-format +msgid "Project can't be created because user %s doesn't exist" +msgstr "" + +#: nova/auth/ldapdriver.py:478 +#, python-format +msgid "User %s is already a member of the group %s" +msgstr "" + +#: nova/auth/ldapdriver.py:507 +#, python-format +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." +msgstr "" + +#: nova/auth/ldapdriver.py:528 +#, python-format +msgid "Group at dn %s doesn't exist" +msgstr "" + +#: nova/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "" + +#: nova/auth/manager.py:263 +#, python-format +msgid "Failed authorization for access key %s" +msgstr "" + +#: nova/auth/manager.py:264 +#, python-format +msgid "No user found for access key %s" +msgstr "" + +#: nova/auth/manager.py:270 +#, python-format +msgid "Using project name = user name (%s)" +msgstr "" + +#: nova/auth/manager.py:275 +#, python-format +msgid "failed authorization: no project named %s (user=%s)" +msgstr "" + +#: nova/auth/manager.py:277 +#, python-format +msgid "No project called %s could be found" +msgstr "" + +#: nova/auth/manager.py:281 +#, python-format +msgid "Failed authorization: user %s not admin and not member of project %s" +msgstr "" + +#: nova/auth/manager.py:283 +#, python-format +msgid "User %s is not a member of project %s" +msgstr "" + +#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#, python-format +msgid "Invalid signature for user %s" +msgstr "" + +#: nova/auth/manager.py:293 nova/auth/manager.py:304 +msgid "Signature does not match" +msgstr "" + +#: nova/auth/manager.py:374 +msgid "Must specify project" +msgstr "" + +#: nova/auth/manager.py:408 +#, python-format +msgid "The %s role can not be found" +msgstr "" + +#: nova/auth/manager.py:410 +#, python-format +msgid "The %s role is global only" +msgstr "" + +#: nova/auth/manager.py:412 +#, python-format +msgid "Adding role %s to user %s in project %s" +msgstr "" + +#: nova/auth/manager.py:438 +#, python-format +msgid "Removing role %s from user %s on project %s" +msgstr "" + +#: nova/auth/manager.py:505 +#, python-format +msgid "Created project %s with manager %s" +msgstr "" + +#: nova/auth/manager.py:523 +#, python-format +msgid "modifying project %s" +msgstr "" + +#: nova/auth/manager.py:553 +#, python-format +msgid "Remove user %s from project %s" +msgstr "" + +#: nova/auth/manager.py:581 +#, python-format +msgid "Deleting project %s" +msgstr "" + +#: nova/auth/manager.py:637 +#, python-format +msgid "Created user %s (admin: %r)" +msgstr "" + +#: nova/auth/manager.py:645 +#, python-format +msgid "Deleting user %s" +msgstr "" + +#: nova/auth/manager.py:655 +#, python-format +msgid "Access Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:657 +#, python-format +msgid "Secret Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:659 +#, python-format +msgid "Admin status set to %r for user %s" +msgstr "" + +#: nova/auth/manager.py:708 +#, python-format +msgid "No vpn data for project %s" +msgstr "" + +#: nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" +msgstr "" + +#: nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:97 +#, python-format +msgid "Launching VPN for %s" +msgstr "" + +#: nova/compute/api.py:67 +#, python-format +msgid "Instance %d was not found in get_network_topic" +msgstr "" + +#: nova/compute/api.py:73 +#, python-format +msgid "Instance %d has no host" +msgstr "" + +#: nova/compute/api.py:92 +#, python-format +msgid "Quota exceeeded for %s, tried to run %s instances" +msgstr "" + +#: nova/compute/api.py:94 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." +msgstr "" + +#: nova/compute/api.py:109 +msgid "Creating a raw instance" +msgstr "" + +#: nova/compute/api.py:156 +#, python-format +msgid "Going to run %s instances..." +msgstr "" + +#: nova/compute/api.py:180 +#, python-format +msgid "Casting to scheduler for %s/%s's instance %s" +msgstr "" + +#: nova/compute/api.py:279 +#, python-format +msgid "Going to try and terminate %s" +msgstr "" + +#: nova/compute/api.py:283 +#, python-format +msgid "Instance %d was not found during terminate" +msgstr "" + +#: nova/compute/api.py:288 +#, python-format +msgid "Instance %d is already being terminated" +msgstr "" + +#: nova/compute/api.py:450 +#, python-format +msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgstr "" + +#: nova/compute/api.py:465 +msgid "Volume isn't attached to anything!" +msgstr "" + +#: nova/compute/disk.py:71 +#, python-format +msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:75 +#, python-format +msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:128 +#, python-format +msgid "Could not attach image to loopback: %s" +msgstr "" + +#: nova/compute/disk.py:136 +#, python-format +msgid "Failed to load partition: %s" +msgstr "" + +#: nova/compute/disk.py:158 +#, python-format +msgid "Failed to mount filesystem: %s" +msgstr "" + +#: nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "" + +#: nova/compute/manager.py:69 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: nova/compute/manager.py:71 +#, python-format +msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgstr "" + +#: nova/compute/manager.py:75 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: nova/compute/manager.py:77 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: nova/compute/manager.py:82 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: nova/compute/manager.py:157 +msgid "Instance has already been created" +msgstr "" + +#: nova/compute/manager.py:158 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#: nova/compute/manager.py:197 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: nova/compute/manager.py:217 +#, python-format +msgid "Disassociating address %s" +msgstr "" + +#: nova/compute/manager.py:230 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: nova/compute/manager.py:243 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: nova/compute/manager.py:257 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: nova/compute/manager.py:260 +#, python-format +msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:286 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: nova/compute/manager.py:289 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:301 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: nova/compute/manager.py:316 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: nova/compute/manager.py:335 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: nova/compute/manager.py:352 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: nova/compute/manager.py:369 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: nova/compute/manager.py:382 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: nova/compute/manager.py:401 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: nova/compute/manager.py:420 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: nova/compute/manager.py:432 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: nova/compute/manager.py:442 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: nova/compute/manager.py:462 +#, python-format +msgid "instance %s: attaching volume %s to %s" +msgstr "" + +#: nova/compute/manager.py:478 +#, python-format +msgid "instance %s: attach failed %s, removing" +msgstr "" + +#: nova/compute/manager.py:493 +#, python-format +msgid "Detach volume %s from mountpoint %s on instance %s" +msgstr "" + +#: nova/compute/manager.py:497 +#, python-format +msgid "Detaching volume from unknown instance %s" +msgstr "" + +#: nova/compute/monitor.py:259 +#, python-format +msgid "updating %s..." +msgstr "" + +#: nova/compute/monitor.py:289 +msgid "unexpected error during update" +msgstr "" + +#: nova/compute/monitor.py:355 +#, python-format +msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:377 +#, python-format +msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:412 +msgid "unexpected exception getting connection" +msgstr "" + +#: nova/compute/monitor.py:427 +#, python-format +msgid "Found instance: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:43 +msgid "Use of empty request context is deprecated" +msgstr "" + +#: nova/db/sqlalchemy/api.py:132 +#, python-format +msgid "No service for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:229 +#, python-format +msgid "No service for %s, %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:574 +#, python-format +msgid "No floating ip for address %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:668 +#, python-format +msgid "No instance for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:758 nova/virt/libvirt_conn.py:598 +#: nova/virt/xenapi/volumeops.py:48 nova/virt/xenapi/volumeops.py:103 +#, python-format +msgid "Instance %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:891 +#, python-format +msgid "no keypair for user %s, name %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#, python-format +msgid "No network for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1036 +#, python-format +msgid "No network for bridge %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1050 +#, python-format +msgid "No network for instance %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1180 +#, python-format +msgid "Token %s does not exist" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1205 +#, python-format +msgid "No quota for project_id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1356 +#, python-format +msgid "No volume for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1401 +#, python-format +msgid "Volume %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1413 +#, python-format +msgid "No export device found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1426 +#, python-format +msgid "No target id found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1471 +#, python-format +msgid "No security group with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1488 +#, python-format +msgid "No security group named %s for project: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1576 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1650 +#, python-format +msgid "No user for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1666 +#, python-format +msgid "No user for access key %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1728 +#, python-format +msgid "No project with id %s" +msgstr "" + +#: nova/image/glance.py:78 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images" +msgstr "" + +#: nova/image/glance.py:97 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images/detail" +msgstr "" + +#: nova/image/s3.py:82 +#, python-format +msgid "Image %s could not be found" +msgstr "" + +#: nova/network/api.py:39 +#, python-format +msgid "Quota exceeeded for %s, tried to allocate address" +msgstr "" + +#: nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" +msgstr "" + +#: nova/network/linux_net.py:176 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: nova/network/linux_net.py:186 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#: nova/network/linux_net.py:254 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: nova/network/linux_net.py:256 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#: nova/network/linux_net.py:334 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: nova/network/manager.py:135 +msgid "setting network host" +msgstr "" + +#: nova/network/manager.py:190 +#, python-format +msgid "Leasing IP %s" +msgstr "" + +#: nova/network/manager.py:194 +#, python-format +msgid "IP %s leased that isn't associated" +msgstr "" + +#: nova/network/manager.py:197 +#, python-format +msgid "IP %s leased to bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:205 +#, python-format +msgid "IP %s leased that was already deallocated" +msgstr "" + +#: nova/network/manager.py:214 +#, python-format +msgid "IP %s released that isn't associated" +msgstr "" + +#: nova/network/manager.py:217 +#, python-format +msgid "IP %s released from bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:220 +#, python-format +msgid "IP %s released that was not leased" +msgstr "" + +#: nova/network/manager.py:442 +#, python-format +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "" + +#: nova/objectstore/handler.py:106 +#, python-format +msgid "Unknown S3 value type %r" +msgstr "" + +#: nova/objectstore/handler.py:137 +msgid "Authenticated request" +msgstr "" + +#: nova/objectstore/handler.py:182 +msgid "List of buckets requested" +msgstr "" + +#: nova/objectstore/handler.py:209 +#, python-format +msgid "List keys for bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:217 +#, python-format +msgid "Unauthorized attempt to access bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:235 +#, python-format +msgid "Creating bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:245 +#, python-format +msgid "Deleting bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:249 +#, python-format +msgid "Unauthorized attempt to delete bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:271 +#, python-format +msgid "Getting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:274 +#, python-format +msgid "Unauthorized attempt to get object %s from bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:292 +#, python-format +msgid "Putting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:295 +#, python-format +msgid "Unauthorized attempt to upload object %s to bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:314 +#, python-format +msgid "Deleting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:393 +#, python-format +msgid "Not authorized to upload image: invalid directory %s" +msgstr "" + +#: nova/objectstore/handler.py:401 +#, python-format +msgid "Not authorized to upload image: unauthorized bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:406 +#, python-format +msgid "Starting image upload: %s" +msgstr "" + +#: nova/objectstore/handler.py:420 +#, python-format +msgid "Not authorized to update attributes of image %s" +msgstr "" + +#: nova/objectstore/handler.py:428 +#, python-format +msgid "Toggling publicity flag of image %s %r" +msgstr "" + +#: nova/objectstore/handler.py:433 +#, python-format +msgid "Updating user fields on image %s" +msgstr "" + +#: nova/objectstore/handler.py:447 +#, python-format +msgid "Unauthorized attempt to delete image %s" +msgstr "" + +#: nova/objectstore/handler.py:452 +#, python-format +msgid "Deleted image: %s" +msgstr "" + +#: nova/scheduler/chance.py:37 nova/scheduler/simple.py:73 +#: nova/scheduler/simple.py:106 nova/scheduler/simple.py:118 +msgid "No hosts found" +msgstr "" + +#: nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "" + +#: nova/scheduler/manager.py:69 +#, python-format +msgid "Casting to %s %s for %s" +msgstr "" + +#: nova/scheduler/simple.py:63 +msgid "All hosts have too many cores" +msgstr "" + +#: nova/scheduler/simple.py:95 +msgid "All hosts have too many gigabytes" +msgstr "" + +#: nova/scheduler/simple.py:115 +msgid "All hosts have too many networks" +msgstr "" + +#: nova/tests/test_cloud.py:198 +msgid "Can't test instances without a real virtual env." +msgstr "" + +#: nova/tests/test_cloud.py:210 +#, python-format +msgid "Need to watch instance %s until it's running..." +msgstr "" + +#: nova/tests/test_compute.py:104 +#, python-format +msgid "Running instances: %s" +msgstr "" + +#: nova/tests/test_compute.py:110 +#, python-format +msgid "After terminating instances: %s" +msgstr "" + +#: nova/tests/test_rpc.py:89 +#, python-format +msgid "Nested received %s, %s" +msgstr "" + +#: nova/tests/test_rpc.py:94 +#, python-format +msgid "Nested return %s" +msgstr "" + +#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#, python-format +msgid "Received %s" +msgstr "" + +#: nova/tests/test_volume.py:162 +#, python-format +msgid "Target %s allocated" +msgstr "" + +#: nova/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "" + +#: nova/virt/fake.py:210 +#, python-format +msgid "Instance %s Not Found" +msgstr "" + +#: nova/virt/hyperv.py:118 +msgid "In init host" +msgstr "" + +#: nova/virt/hyperv.py:131 +#, python-format +msgid "Attempt to create duplicate vm %s" +msgstr "" + +#: nova/virt/hyperv.py:148 +#, python-format +msgid "Starting VM %s " +msgstr "" + +#: nova/virt/hyperv.py:150 +#, python-format +msgid "Started VM %s " +msgstr "" + +#: nova/virt/hyperv.py:152 +#, python-format +msgid "spawn vm failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:169 +#, python-format +msgid "Failed to create VM %s" +msgstr "" + +#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#, python-format +msgid "Created VM %s..." +msgstr "" + +#: nova/virt/hyperv.py:188 +#, python-format +msgid "Set memory for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:198 +#, python-format +msgid "Set vcpus for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:202 +#, python-format +msgid "Creating disk for %s by attaching disk file %s" +msgstr "" + +#: nova/virt/hyperv.py:227 +#, python-format +msgid "Failed to add diskdrive to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:230 +#, python-format +msgid "New disk drive path is %s" +msgstr "" + +#: nova/virt/hyperv.py:247 +#, python-format +msgid "Failed to add vhd file to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:249 +#, python-format +msgid "Created disk for %s" +msgstr "" + +#: nova/virt/hyperv.py:253 +#, python-format +msgid "Creating nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" +msgstr "" + +#: nova/virt/hyperv.py:273 +#, python-format +msgid "Failed creating port for %s" +msgstr "" + +#: nova/virt/hyperv.py:275 +#, python-format +msgid "Created switch port %s on switch %s" +msgstr "" + +#: nova/virt/hyperv.py:285 +#, python-format +msgid "Failed to add nic to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:287 +#, python-format +msgid "Created nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:320 +#, python-format +msgid "WMI job failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:322 +#, python-format +msgid "WMI job succeeded: %s, Elapsed=%s " +msgstr "" + +#: nova/virt/hyperv.py:358 +#, python-format +msgid "Got request to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:383 +#, python-format +msgid "Failed to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:389 +#, python-format +msgid "Del: disk %s vm %s" +msgstr "" + +#: nova/virt/hyperv.py:405 +#, python-format +msgid "" +"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " +"cpu_time=%s" +msgstr "" + +#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#, python-format +msgid "duplicate name found: %s" +msgstr "" + +#: nova/virt/hyperv.py:444 +#, python-format +msgid "Successfully changed vm state of %s to %s" +msgstr "" + +#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#, python-format +msgid "Failed to change vm state of %s to %s" +msgstr "" + +#: nova/virt/images.py:70 +#, python-format +msgid "Finished retreving %s -- placed in %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:144 +#, python-format +msgid "Connecting to libvirt: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:157 +msgid "Connection to libvirt broke" +msgstr "" + +#: nova/virt/libvirt_conn.py:229 +#, python-format +msgid "instance %s: deleting instance files %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:271 +#, python-format +msgid "No disk at %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:278 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "" + +#: nova/virt/libvirt_conn.py:294 +#, python-format +msgid "instance %s: rebooted" +msgstr "" + +#: nova/virt/libvirt_conn.py:297 +#, python-format +msgid "_wait_for_reboot failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:340 +#, python-format +msgid "instance %s: rescued" +msgstr "" + +#: nova/virt/libvirt_conn.py:343 +#, python-format +msgid "_wait_for_rescue failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:370 +#, python-format +msgid "instance %s: is running" +msgstr "" + +#: nova/virt/libvirt_conn.py:381 +#, python-format +msgid "instance %s: booted" +msgstr "" + +#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#, python-format +msgid "instance %s: failed to boot" +msgstr "" + +#: nova/virt/libvirt_conn.py:395 +#, python-format +msgid "virsh said: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:399 +msgid "cool, it's a device" +msgstr "" + +#: nova/virt/libvirt_conn.py:407 +#, python-format +msgid "data: %r, fpath: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:415 +#, python-format +msgid "Contents of file %s: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:449 +#, python-format +msgid "instance %s: Creating image" +msgstr "" + +#: nova/virt/libvirt_conn.py:505 +#, python-format +msgid "instance %s: injecting key into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:508 +#, python-format +msgid "instance %s: injecting net into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:516 +#, python-format +msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgstr "" + +#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#, python-format +msgid "instance %s: starting toXML method" +msgstr "" + +#: nova/virt/libvirt_conn.py:589 +#, python-format +msgid "instance %s: finished toXML method" +msgstr "" + +#: nova/virt/xenapi_conn.py:113 +msgid "" +"Must specify xenapi_connection_url, xenapi_connection_username (optionally), " +"and xenapi_connection_password to use connection_type=xenapi" +msgstr "" + +#: nova/virt/xenapi_conn.py:263 +#, python-format +msgid "Task [%s] %s status: success %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:271 +#, python-format +msgid "Task [%s] %s status: %s %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#, python-format +msgid "Got exception: %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:72 +#, python-format +msgid "%s: _db_content => %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:247 nova/virt/xenapi/fake.py:338 +#: nova/virt/xenapi/fake.py:356 nova/virt/xenapi/fake.py:404 +msgid "Raising NotImplemented" +msgstr "" + +#: nova/virt/xenapi/fake.py:249 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:283 +#, python-format +msgid "Calling %s %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:288 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:340 +#, python-format +msgid "" +"xenapi.fake does not have an implementation for %s or it has been called " +"with the wrong number of arguments" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:40 +#, python-format +msgid "Found non-unique network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:43 +#, python-format +msgid "Found no network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:127 +#, python-format +msgid "Created VM %s as %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:147 +#, python-format +msgid "Creating VBD for VM %s, VDI %s ... " +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:149 +#, python-format +msgid "Created VBD %s for VM %s, VDI %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:165 +#, python-format +msgid "VBD not found in instance %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:175 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:202 +#, python-format +msgid "Creating VIF for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:205 +#, python-format +msgid "Created VIF %s for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:216 +#, python-format +msgid "Snapshotting VM %s with label '%s'..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:229 +#, python-format +msgid "Created snapshot %s from VM %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:243 +#, python-format +msgid "Asking xapi to upload %s as '%s'" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:261 +#, python-format +msgid "Asking xapi to fetch %s as %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:279 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:290 +#, python-format +msgid "PV Kernel in VDI:%d" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:318 +#, python-format +msgid "VDI %s is still available" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:331 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:333 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:390 +#, python-format +msgid "VHD %s has parent %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:407 +#, python-format +msgid "Re-scanning SR %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:431 +#, python-format +msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:448 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:452 +#, python-format +msgid "Unexpected number of VDIs (%s) found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:62 +#, python-format +msgid "Attempted to create non-unique name %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:99 +#, python-format +msgid "Starting VM %s..." +msgstr "" + +#: nova/virt/xenapi/vmops.py:101 +#, python-format +msgid "Spawning VM %s created %s." +msgstr "" + +#: nova/virt/xenapi/vmops.py:112 +#, python-format +msgid "Instance %s: booted" +msgstr "" + +#: nova/virt/xenapi/vmops.py:137 +#, python-format +msgid "Instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:166 +#, python-format +msgid "Starting snapshot for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:174 +#, python-format +msgid "Unable to Snapshot %s: %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:184 +#, python-format +msgid "Finished snapshot and upload for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:252 +#, python-format +msgid "suspend: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:262 +#, python-format +msgid "resume: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:271 +#, python-format +msgid "Instance not found %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:57 +#, python-format +msgid "Introducing %s..." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:74 +#, python-format +msgid "Introduced %s as %s." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:90 +#, python-format +msgid "Unable to find SR from VBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:96 +#, python-format +msgid "Forgetting SR %s ... " +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:101 +#, python-format +msgid "Ignoring exception %s when getting PBDs for %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:107 +#, python-format +msgid "Ignoring exception %s when unplugging PBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:111 +#, python-format +msgid "Forgetting SR %s done." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:113 +#, python-format +msgid "Ignoring exception %s when forgetting SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:123 +#, python-format +msgid "Unable to introduce VDI on SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:128 +#, python-format +msgid "Unable to get record of VDI %s on" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:146 +#, python-format +msgid "Unable to introduce VDI for SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:175 +#, python-format +msgid "Unable to obtain target information %s, %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:197 +#, python-format +msgid "Mountpoint cannot be translated: %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:51 +#, python-format +msgid "Attach_volume: %s, %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:69 +#, python-format +msgid "Unable to create VDI on SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:81 +#, python-format +msgid "Unable to use SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Unable to attach volume to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:95 +#, python-format +msgid "Mountpoint %s attached to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:106 +#, python-format +msgid "Detach_volume: %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:113 +#, python-format +msgid "Unable to locate volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:121 +#, python-format +msgid "Unable to detach volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:128 +#, python-format +msgid "Mountpoint %s detached from instance %s" +msgstr "" + +#: nova/volume/api.py:44 +#, python-format +msgid "Quota exceeeded for %s, tried to create %sG volume" +msgstr "" + +#: nova/volume/api.py:46 +#, python-format +msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgstr "" + +#: nova/volume/api.py:70 nova/volume/api.py:95 +msgid "Volume status must be available" +msgstr "" + +#: nova/volume/api.py:97 +msgid "Volume is already attached" +msgstr "" + +#: nova/volume/api.py:103 +msgid "Volume is already detached" +msgstr "" + +#: nova/volume/driver.py:76 +#, python-format +msgid "Recovering from a failed execute. Try number %s" +msgstr "" + +#: nova/volume/driver.py:85 +#, python-format +msgid "volume group %s doesn't exist" +msgstr "" + +#: nova/volume/driver.py:210 +#, python-format +msgid "FAKE AOE: %s" +msgstr "" + +#: nova/volume/driver.py:315 +#, python-format +msgid "FAKE ISCSI: %s" +msgstr "" + +#: nova/volume/manager.py:85 +#, python-format +msgid "Re-exporting %s volumes" +msgstr "" + +#: nova/volume/manager.py:93 +#, python-format +msgid "volume %s: creating" +msgstr "" + +#: nova/volume/manager.py:102 +#, python-format +msgid "volume %s: creating lv of size %sG" +msgstr "" + +#: nova/volume/manager.py:106 +#, python-format +msgid "volume %s: creating export" +msgstr "" + +#: nova/volume/manager.py:113 +#, python-format +msgid "volume %s: created successfully" +msgstr "" + +#: nova/volume/manager.py:121 +msgid "Volume is still attached" +msgstr "" + +#: nova/volume/manager.py:123 +msgid "Volume is not local to this node" +msgstr "" + +#: nova/volume/manager.py:124 +#, python-format +msgid "volume %s: removing export" +msgstr "" + +#: nova/volume/manager.py:126 +#, python-format +msgid "volume %s: deleting" +msgstr "" + +#: nova/volume/manager.py:129 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "bind %s: slettet" diff --git a/locale/es.po b/locale/es.po new file mode 100644 index 00000000..a1cf5b7f --- /dev/null +++ b/locale/es.po @@ -0,0 +1,2177 @@ +# Spanish translation for nova +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the nova package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: nova\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"PO-Revision-Date: 2011-01-18 14:56+0000\n" +"Last-Translator: Javier Turégano \n" +"Language-Team: Spanish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-01-28 05:20+0000\n" +"X-Generator: Launchpad (build 12177)\n" + +#: nova/crypto.py:46 +msgid "Filename of root CA" +msgstr "Nombre de fichero de la CA raíz" + +#: nova/crypto.py:49 +msgid "Filename of private key" +msgstr "Nombre de fichero de la clave privada" + +#: nova/crypto.py:51 +msgid "Filename of root Certificate Revokation List" +msgstr "Nombre de fichero de la lista de certificados de revocación raíz" + +#: nova/crypto.py:53 +msgid "Where we keep our keys" +msgstr "Donde guardamos nuestras claves" + +#: nova/crypto.py:55 +msgid "Where we keep our root CA" +msgstr "Dónde guardamos nuestra CA raíz" + +#: nova/crypto.py:57 +msgid "Should we use a CA for each project?" +msgstr "¿Deberíamos usar una CA para cada proyecto?" + +#: nova/crypto.py:61 +#, python-format +msgid "Subject for certificate for users, %s for project, user, timestamp" +msgstr "" +"Sujeto (Subject) para el certificado de usuarios, %s para el proyecto, " +"usuario, marca de tiempo" + +#: nova/crypto.py:66 +#, python-format +msgid "Subject for certificate for projects, %s for project, timestamp" +msgstr "" +"Sujeto (Subject) para el certificado del proyecto, %s para el proyecto, " +"marca de tiempo" + +#: nova/crypto.py:71 +#, python-format +msgid "Subject for certificate for vpns, %s for project, timestamp" +msgstr "" +"Sujeto (Subject) para el certificado para vpns, %s para el proyecto, marca " +"de tiempo" + +#: nova/crypto.py:258 +#, python-format +msgid "Flags path: %s" +msgstr "" + +#: nova/exception.py:33 +msgid "Unexpected error while running command." +msgstr "Sucedió un error inesperado mientras el comando se ejecutaba." + +#: nova/exception.py:36 +#, python-format +msgid "" +"%s\n" +"Command: %s\n" +"Exit code: %s\n" +"Stdout: %r\n" +"Stderr: %r" +msgstr "" +"%s\n" +"Comando: %s\n" +"Código de salida: %s\n" +"Stdout: %s\n" +"Stderr: %r" + +#: nova/exception.py:86 +msgid "Uncaught exception" +msgstr "Excepción no controlada" + +#: nova/fakerabbit.py:48 +#, python-format +msgid "(%s) publish (key: %s) %s" +msgstr "(%s) públicar (clave: %s) %s" + +#: nova/fakerabbit.py:53 +#, python-format +msgid "Publishing to route %s" +msgstr "Publicando la ruta %s" + +#: nova/fakerabbit.py:83 +#, python-format +msgid "Declaring queue %s" +msgstr "Declarando cola %s" + +#: nova/fakerabbit.py:89 +#, python-format +msgid "Declaring exchange %s" +msgstr "Declarando intercambio %s" + +#: nova/fakerabbit.py:95 +#, python-format +msgid "Binding %s to %s with key %s" +msgstr "Asociando %s a %s con clave %s" + +#: nova/fakerabbit.py:120 +#, python-format +msgid "Getting from %s: %s" +msgstr "Obteniendo desde %s: %s" + +#: nova/rpc.py:92 +#, python-format +msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgstr "" +"El servidor AMQP en %s:%d no se puede alcanzar. Se reintentará en %d " +"segundos." + +#: nova/rpc.py:99 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "" +"Imposible conectar al servidor AMQP después de %d intentos. Apagando." + +#: nova/rpc.py:118 +msgid "Reconnected to queue" +msgstr "Reconectado a la cola" + +#: nova/rpc.py:125 +msgid "Failed to fetch message from queue" +msgstr "Fallo al obtener el mensaje de la cola" + +#: nova/rpc.py:155 +#, python-format +msgid "Initing the Adapter Consumer for %s" +msgstr "" + +#: nova/rpc.py:170 +#, python-format +msgid "received %s" +msgstr "recibido %s" + +#: nova/rpc.py:183 +#, python-format +msgid "no method for message: %s" +msgstr "no hay método para el mensaje: %s" + +#: nova/rpc.py:184 +#, python-format +msgid "No method for message: %s" +msgstr "No hay método para el mensaje: %s" + +#: nova/rpc.py:245 +#, python-format +msgid "Returning exception %s to caller" +msgstr "" + +#: nova/rpc.py:286 +#, python-format +msgid "unpacked context: %s" +msgstr "contenido desempaquetado: %s" + +#: nova/rpc.py:305 +msgid "Making asynchronous call..." +msgstr "Haciendo una llamada asíncrona..." + +#: nova/rpc.py:308 +#, python-format +msgid "MSG_ID is %s" +msgstr "MSG_ID es %s" + +#: nova/rpc.py:356 +#, python-format +msgid "response %s" +msgstr "respuesta %s" + +#: nova/rpc.py:365 +#, python-format +msgid "topic is %s" +msgstr "" + +#: nova/rpc.py:366 +#, python-format +msgid "message %s" +msgstr "mensaje %s" + +#: nova/service.py:157 +#, python-format +msgid "Starting %s node" +msgstr "Inciando nodo %s" + +#: nova/service.py:169 +msgid "Service killed that has no database entry" +msgstr "Se detuvo un servicio sin entrada en la base de datos" + +#: nova/service.py:190 +msgid "The service database object disappeared, Recreating it." +msgstr "El servicio objeto de base de datos ha desaparecido, recreándolo." + +#: nova/service.py:202 +msgid "Recovered model server connection!" +msgstr "Recuperada la conexión al servidor de modelos." + +#: nova/service.py:208 +msgid "model server went away" +msgstr "el servidor de modelos se ha ido" + +#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#, python-format +msgid "Data store %s is unreachable. Trying again in %d seconds." +msgstr "" +"El almacen de datos %s es inalcanzable. Reintentandolo en %d segundos." + +#: nova/service.py:232 nova/twistd.py:232 +#, python-format +msgid "Serving %s" +msgstr "Sirviendo %s" + +#: nova/service.py:234 nova/twistd.py:264 +msgid "Full set of FLAGS:" +msgstr "Conjunto completo de opciones:" + +#: nova/twistd.py:211 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "el pidfile %s no existe. ¿No estará el demonio parado?\n" + +#: nova/twistd.py:268 +#, python-format +msgid "Starting %s" +msgstr "Comenzando %s" + +#: nova/utils.py:53 +#, python-format +msgid "Inner Exception: %s" +msgstr "Excepción interna: %s" + +#: nova/utils.py:54 +#, python-format +msgid "Class %s cannot be found" +msgstr "La clase %s no ha podido ser encontrada." + +#: nova/utils.py:113 +#, python-format +msgid "Fetching %s" +msgstr "Obteniendo %s" + +#: nova/utils.py:125 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "Ejecutando cmd (subprocesos): %s" + +#: nova/utils.py:138 +#, python-format +msgid "Result was %s" +msgstr "El resultado fue %s" + +#: nova/utils.py:171 +#, python-format +msgid "debug in callback: %s" +msgstr "Depuración de la devolución de llamada: %s" + +#: nova/utils.py:176 +#, python-format +msgid "Running %s" +msgstr "Ejecutando %s" + +#: nova/utils.py:207 +#, python-format +msgid "Couldn't get IP, using 127.0.0.1 %s" +msgstr "No puedo obtener IP, usando 127.0.0.1 %s" + +#: nova/utils.py:289 +#, python-format +msgid "Invalid backend: %s" +msgstr "backend inválido: %s" + +#: nova/utils.py:300 +#, python-format +msgid "backend %s" +msgstr "backend %s" + +#: nova/api/ec2/__init__.py:133 +msgid "Too many failed authentications." +msgstr "Demasiados intentos de autenticacion fallidos." + +#: nova/api/ec2/__init__.py:142 +#, python-format +msgid "" +"Access key %s has had %d failed authentications and will be locked out for " +"%d minutes." +msgstr "" +"La clave de acceso %s ha tenido %d fallos de autenticación y se bloqueará " +"por %d minutos." + +#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#, python-format +msgid "Authentication Failure: %s" +msgstr "Fallo de autenticación: %s" + +#: nova/api/ec2/__init__.py:190 +#, python-format +msgid "Authenticated Request For %s:%s)" +msgstr "Solicitud de autenticación para %s:%s" + +#: nova/api/ec2/__init__.py:227 +#, python-format +msgid "action: %s" +msgstr "acción: %s" + +#: nova/api/ec2/__init__.py:229 +#, python-format +msgid "arg: %s\t\tval: %s" +msgstr "arg: %s \t \t val: %s" + +#: nova/api/ec2/__init__.py:301 +#, python-format +msgid "Unauthorized request for controller=%s and action=%s" +msgstr "Solicitud no autorizada para controller=%s y action=%s" + +#: nova/api/ec2/__init__.py:339 +#, python-format +msgid "NotFound raised: %s" +msgstr "No encontrado: %s" + +#: nova/api/ec2/__init__.py:342 +#, python-format +msgid "ApiError raised: %s" +msgstr "Sucedió un ApiError: %s" + +#: nova/api/ec2/__init__.py:349 +#, python-format +msgid "Unexpected error raised: %s" +msgstr "Sucedió un error inexperado: %s" + +#: nova/api/ec2/__init__.py:354 +msgid "An unknown error has occurred. Please try your request again." +msgstr "" +"Ha sucedido un error desconocido. Por favor repite el intento de nuevo." + +#: nova/api/ec2/admin.py:84 +#, python-format +msgid "Creating new user: %s" +msgstr "Creando nuevo usuario: %s" + +#: nova/api/ec2/admin.py:92 +#, python-format +msgid "Deleting user: %s" +msgstr "Eliminando usuario: %s" + +#: nova/api/ec2/admin.py:114 +#, python-format +msgid "Adding role %s to user %s for project %s" +msgstr "Añadiendo rol %s al usuario %s para el proyecto %s" + +#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#, python-format +msgid "Adding sitewide role %s to user %s" +msgstr "Añadiendo rol global %s al usuario %s" + +#: nova/api/ec2/admin.py:122 +#, python-format +msgid "Removing role %s from user %s for project %s" +msgstr "Eliminando rol %s del usuario %s para el proyecto %s" + +#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#, python-format +msgid "Removing sitewide role %s from user %s" +msgstr "Eliminando rol global %s del usuario %s" + +#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 +msgid "operation must be add or remove" +msgstr "la operación debe ser añadir o eliminar" + +#: nova/api/ec2/admin.py:142 +#, python-format +msgid "Getting x509 for user: %s on project: %s" +msgstr "Obteniendo x509 para el usuario: %s en el proyecto %s" + +#: nova/api/ec2/admin.py:159 +#, python-format +msgid "Create project %s managed by %s" +msgstr "Creación del proyecto %s gestionada por %s" + +#: nova/api/ec2/admin.py:170 +#, python-format +msgid "Delete project: %s" +msgstr "Borrar proyecto: %s" + +#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#, python-format +msgid "Adding user %s to project %s" +msgstr "Añadiendo usuario %s al proyecto %s" + +#: nova/api/ec2/admin.py:188 +#, python-format +msgid "Removing user %s from project %s" +msgstr "Eliminando usuario %s del proyecto %s" + +#: nova/api/ec2/apirequest.py:95 +#, python-format +msgid "Unsupported API request: controller = %s,action = %s" +msgstr "Solicitud de API no soportada: controller=%s,action=%s" + +#: nova/api/ec2/cloud.py:117 +#, python-format +msgid "Generating root CA: %s" +msgstr "Generando CA raiz: %s" + +#: nova/api/ec2/cloud.py:277 +#, python-format +msgid "Create key pair %s" +msgstr "Creando par de claves %s" + +#: nova/api/ec2/cloud.py:285 +#, python-format +msgid "Delete key pair %s" +msgstr "Borrar para de claves %s" + +#: nova/api/ec2/cloud.py:357 +#, python-format +msgid "%s is not a valid ipProtocol" +msgstr "%s no es un ipProtocol valido" + +#: nova/api/ec2/cloud.py:361 +msgid "Invalid port range" +msgstr "Rango de puerto inválido" + +#: nova/api/ec2/cloud.py:392 +#, python-format +msgid "Revoke security group ingress %s" +msgstr "Revocar ingreso al grupo de seguridad %s" + +#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 +msgid "No rule for the specified parameters." +msgstr "No hay regla para los parámetros especificados." + +#: nova/api/ec2/cloud.py:421 +#, python-format +msgid "Authorize security group ingress %s" +msgstr "Autorizar ingreso al grupo de seguridad %s" + +#: nova/api/ec2/cloud.py:432 +#, python-format +msgid "This rule already exists in group %s" +msgstr "Esta regla ya existe en el grupo %s" + +#: nova/api/ec2/cloud.py:460 +#, python-format +msgid "Create Security Group %s" +msgstr "Crear Grupo de Seguridad %s" + +#: nova/api/ec2/cloud.py:463 +#, python-format +msgid "group %s already exists" +msgstr "el grupo %s ya existe" + +#: nova/api/ec2/cloud.py:475 +#, python-format +msgid "Delete security group %s" +msgstr "Borrar grupo de seguridad %s" + +#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#, python-format +msgid "Get console output for instance %s" +msgstr "Obtener salida de la consola para la instancia %s" + +#: nova/api/ec2/cloud.py:543 +#, python-format +msgid "Create volume of %s GB" +msgstr "Crear volumen de %s GB" + +#: nova/api/ec2/cloud.py:567 +#, python-format +msgid "Attach volume %s to instacne %s at %s" +msgstr "Asociar volumen %s a la instancia %s en %s" + +#: nova/api/ec2/cloud.py:579 +#, python-format +msgid "Detach volume %s" +msgstr "Desasociar volumen %s" + +#: nova/api/ec2/cloud.py:686 +msgid "Allocate address" +msgstr "Asignar dirección" + +#: nova/api/ec2/cloud.py:691 +#, python-format +msgid "Release address %s" +msgstr "Liberar dirección %s" + +#: nova/api/ec2/cloud.py:696 +#, python-format +msgid "Associate address %s to instance %s" +msgstr "Asociar dirección %s a la instancia %s" + +#: nova/api/ec2/cloud.py:703 +#, python-format +msgid "Disassociate address %s" +msgstr "Desasociar dirección %s" + +#: nova/api/ec2/cloud.py:730 +msgid "Going to start terminating instances" +msgstr "Se va a iniciar la finalización de las instancias" + +#: nova/api/ec2/cloud.py:738 +#, python-format +msgid "Reboot instance %r" +msgstr "Reiniciar instancia %r" + +#: nova/api/ec2/cloud.py:775 +#, python-format +msgid "De-registering image %s" +msgstr "Des-registrando la imagen %s" + +#: nova/api/ec2/cloud.py:783 +#, python-format +msgid "Registered image %s with id %s" +msgstr "Registrada imagen %s con id %s" + +#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#, python-format +msgid "attribute not supported: %s" +msgstr "atributo no soportado: %s" + +#: nova/api/ec2/cloud.py:794 +#, python-format +msgid "invalid id: %s" +msgstr "id no valido: %s" + +#: nova/api/ec2/cloud.py:807 +msgid "user or group not specified" +msgstr "usuario o grupo no especificado" + +#: nova/api/ec2/cloud.py:809 +msgid "only group \"all\" is supported" +msgstr "sólo el grupo \"all\" está soportado" + +#: nova/api/ec2/cloud.py:811 +msgid "operation_type must be add or remove" +msgstr "operation_type debe ser añadir o eliminar" + +#: nova/api/ec2/cloud.py:812 +#, python-format +msgid "Updating image %s publicity" +msgstr "Actualizando imagen %s públicamente" + +#: nova/api/ec2/metadatarequesthandler.py:75 +#, python-format +msgid "Failed to get metadata for ip: %s" +msgstr "Fallo al generar metadatos para la ip %s" + +#: nova/api/openstack/__init__.py:70 +#, python-format +msgid "Caught error: %s" +msgstr "Capturado error: %s" + +#: nova/api/openstack/__init__.py:86 +msgid "Including admin operations in API." +msgstr "Incluyendo operaciones de administración in API." + +#: nova/api/openstack/servers.py:184 +#, python-format +msgid "Compute.api::lock %s" +msgstr "Compute.api::lock %s" + +#: nova/api/openstack/servers.py:199 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "Compute.api::unlock %s" + +#: nova/api/openstack/servers.py:213 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "Compute.api::get_lock %s" + +#: nova/api/openstack/servers.py:224 +#, python-format +msgid "Compute.api::pause %s" +msgstr "Compute.api::pause %s" + +#: nova/api/openstack/servers.py:235 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "Compute.api::unpause %s" + +#: nova/api/openstack/servers.py:246 +#, python-format +msgid "compute.api::suspend %s" +msgstr "compute.api::suspend %s" + +#: nova/api/openstack/servers.py:257 +#, python-format +msgid "compute.api::resume %s" +msgstr "compute.api::resume %s" + +#: nova/auth/dbdriver.py:84 +#, python-format +msgid "User %s already exists" +msgstr "El usuario %s ya existe" + +#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#, python-format +msgid "Project can't be created because manager %s doesn't exist" +msgstr "El proyecto no puede ser creado porque el administrador %s no existe" + +#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#, python-format +msgid "Project can't be created because project %s already exists" +msgstr "El proyecto no puede ser creado porque el proyecto %s ya existe" + +#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#, python-format +msgid "Project can't be modified because manager %s doesn't exist" +msgstr "" +"El proyecto no puede ser modificado porque el administrador %s no existe" + +#: nova/auth/dbdriver.py:245 +#, python-format +msgid "User \"%s\" not found" +msgstr "No se ha encontrado el usuario \"%s\"" + +#: nova/auth/dbdriver.py:248 +#, python-format +msgid "Project \"%s\" not found" +msgstr "No se ha encontrado el proyecto \"%s\"" + +#: nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "Intento de instanciar sigleton" + +#: nova/auth/ldapdriver.py:181 +#, python-format +msgid "LDAP object for %s doesn't exist" +msgstr "El objeto LDAP para %s no existe" + +#: nova/auth/ldapdriver.py:218 +#, python-format +msgid "Project can't be created because user %s doesn't exist" +msgstr "El proyecto no puede ser creado porque el usuario %s no existe" + +#: nova/auth/ldapdriver.py:478 +#, python-format +msgid "User %s is already a member of the group %s" +msgstr "El usuario %s ya es miembro de el grupo %s" + +#: nova/auth/ldapdriver.py:507 +#, python-format +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." +msgstr "" +"Se ha intentado eliminar el último miembro de un grupo. Eliminando el grupo " +"%s en su lugar." + +#: nova/auth/ldapdriver.py:528 +#, python-format +msgid "Group at dn %s doesn't exist" +msgstr "El grupo con dn %s no existe" + +#: nova/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "Buscando usuario: %r" + +#: nova/auth/manager.py:263 +#, python-format +msgid "Failed authorization for access key %s" +msgstr "Fallo de autorización para la clave de acceso %s" + +#: nova/auth/manager.py:264 +#, python-format +msgid "No user found for access key %s" +msgstr "No se ha encontrado usuario para la clave de acceso %s" + +#: nova/auth/manager.py:270 +#, python-format +msgid "Using project name = user name (%s)" +msgstr "Utilizando nombre de proyecto = nombre de usuario (%s)" + +#: nova/auth/manager.py:275 +#, python-format +msgid "failed authorization: no project named %s (user=%s)" +msgstr "" +"fallo de autorización: no existe proyecto con el nombre %s (usuario=%s)" + +#: nova/auth/manager.py:277 +#, python-format +msgid "No project called %s could be found" +msgstr "No se ha podido encontrar un proyecto con nombre %s" + +#: nova/auth/manager.py:281 +#, python-format +msgid "Failed authorization: user %s not admin and not member of project %s" +msgstr "" +"Fallo de autorización: el usuario %s no es administrador y no es miembro del " +"proyecto %s" + +#: nova/auth/manager.py:283 +#, python-format +msgid "User %s is not a member of project %s" +msgstr "El usuario %s no es miembro del proyecto %s" + +#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#, python-format +msgid "Invalid signature for user %s" +msgstr "Firma invalida para el usuario %s" + +#: nova/auth/manager.py:293 nova/auth/manager.py:304 +msgid "Signature does not match" +msgstr "Las firmas no concuerdan" + +#: nova/auth/manager.py:374 +msgid "Must specify project" +msgstr "Debes especificar un proyecto" + +#: nova/auth/manager.py:408 +#, python-format +msgid "The %s role can not be found" +msgstr "El rol %s no se ha podido encontrar" + +#: nova/auth/manager.py:410 +#, python-format +msgid "The %s role is global only" +msgstr "El rol %s es únicamente global" + +#: nova/auth/manager.py:412 +#, python-format +msgid "Adding role %s to user %s in project %s" +msgstr "Añadiendo rol %s al usuario %s en el proyecto %s" + +#: nova/auth/manager.py:438 +#, python-format +msgid "Removing role %s from user %s on project %s" +msgstr "Eliminando rol %s al usuario %s en el proyecto %s" + +#: nova/auth/manager.py:505 +#, python-format +msgid "Created project %s with manager %s" +msgstr "Proyecto %s creado con administrador %s" + +#: nova/auth/manager.py:523 +#, python-format +msgid "modifying project %s" +msgstr "modificando proyecto %s" + +#: nova/auth/manager.py:553 +#, python-format +msgid "Remove user %s from project %s" +msgstr "Eliminar usuario %s del proyecto %s" + +#: nova/auth/manager.py:581 +#, python-format +msgid "Deleting project %s" +msgstr "Eliminando proyecto %s" + +#: nova/auth/manager.py:637 +#, python-format +msgid "Created user %s (admin: %r)" +msgstr "Creado usuario %s (administrador: %r)" + +#: nova/auth/manager.py:645 +#, python-format +msgid "Deleting user %s" +msgstr "Eliminando usuario %s" + +#: nova/auth/manager.py:655 +#, python-format +msgid "Access Key change for user %s" +msgstr "Cambio de clave de acceso para el usuario %s" + +#: nova/auth/manager.py:657 +#, python-format +msgid "Secret Key change for user %s" +msgstr "Cambio de clave secreta para el usuario %s" + +#: nova/auth/manager.py:659 +#, python-format +msgid "Admin status set to %r for user %s" +msgstr "El estado del administrador se ha fijado a %r para el usuario %s" + +#: nova/auth/manager.py:708 +#, python-format +msgid "No vpn data for project %s" +msgstr "No hay datos vpn para el proyecto %s" + +#: nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" +msgstr "" + +#: nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" +msgstr "Red a insertar en la configuración de openvpn" + +#: nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" +msgstr "Mascara de red a insertar en la configuración de openvpn" + +#: nova/cloudpipe/pipelib.py:97 +#, python-format +msgid "Launching VPN for %s" +msgstr "Lanzando VPN para %s" + +#: nova/compute/api.py:67 +#, python-format +msgid "Instance %d was not found in get_network_topic" +msgstr "La instancia %d no se ha encontrado en get_network_topic" + +#: nova/compute/api.py:73 +#, python-format +msgid "Instance %d has no host" +msgstr "La instancia %d no tiene host" + +#: nova/compute/api.py:92 +#, python-format +msgid "Quota exceeeded for %s, tried to run %s instances" +msgstr "Quota superada por %s, intentando lanzar %s instancias" + +#: nova/compute/api.py:94 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." +msgstr "" +"Quota de instancias superada. Sólo puedes ejecutar %s instancias más de este " +"tipo." + +#: nova/compute/api.py:109 +msgid "Creating a raw instance" +msgstr "Creando una instancia raw" + +#: nova/compute/api.py:156 +#, python-format +msgid "Going to run %s instances..." +msgstr "Vamos a ejecutar %s insntacias..." + +#: nova/compute/api.py:180 +#, python-format +msgid "Casting to scheduler for %s/%s's instance %s" +msgstr "Llamando al planificar para %s/%s insntancia %s" + +#: nova/compute/api.py:279 +#, python-format +msgid "Going to try and terminate %s" +msgstr "Se va a probar y terminar %s" + +#: nova/compute/api.py:283 +#, python-format +msgid "Instance %d was not found during terminate" +msgstr "La instancia %d no se ha encontrado durante la finalización" + +#: nova/compute/api.py:288 +#, python-format +msgid "Instance %d is already being terminated" +msgstr "La instancia %d ha sido finalizada" + +#: nova/compute/api.py:450 +#, python-format +msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgstr "" +"El dispositivo especificado no es válido: %s. Ejemplo de dispositivo: " +"/dev/vdb" + +#: nova/compute/api.py:465 +msgid "Volume isn't attached to anything!" +msgstr "¡El volumen no está unido a nada!" + +#: nova/compute/disk.py:71 +#, python-format +msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgstr "" +"El tamaño de la partición de entrada no es divisible de forma uniforme por " +"el tamaño del sector: %d / %d" + +#: nova/compute/disk.py:75 +#, python-format +msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgstr "" +"Los bytes del almacenamiento local no son divisibles de forma uniforme por " +"el tamaño del sector: %d / %d" + +#: nova/compute/disk.py:128 +#, python-format +msgid "Could not attach image to loopback: %s" +msgstr "No se puede unir la imagen con el loopback: %s" + +#: nova/compute/disk.py:136 +#, python-format +msgid "Failed to load partition: %s" +msgstr "Fallo al cargar la partición: %s" + +#: nova/compute/disk.py:158 +#, python-format +msgid "Failed to mount filesystem: %s" +msgstr "Fallo al montar el sistema de ficheros: %s" + +#: nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "Tipo de instancia desconocido: %s" + +#: nova/compute/manager.py:69 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "check_instance_lock: decorating: |%s|" + +#: nova/compute/manager.py:71 +#, python-format +msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgstr "check_instance_lock: arguments: |%s| |%s| |%s|" + +#: nova/compute/manager.py:75 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "check_instance_lock: locked: |%s|" + +#: nova/compute/manager.py:77 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "check_instance_lock: admin: |%s|" + +#: nova/compute/manager.py:82 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "check_instance_lock: ejecutando: |%s|" + +#: nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "check_instance_lock: no ejecutando |%s|" + +#: nova/compute/manager.py:157 +msgid "Instance has already been created" +msgstr "La instancia ha sido creada previamente" + +#: nova/compute/manager.py:158 +#, python-format +msgid "instance %s: starting..." +msgstr "instancia %s: iniciando..." + +#: nova/compute/manager.py:197 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "Instancia %s: no se pudo iniciar" + +#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#, python-format +msgid "Terminating instance %s" +msgstr "Finalizando la instancia %s" + +#: nova/compute/manager.py:217 +#, python-format +msgid "Disassociating address %s" +msgstr "Desasociando la dirección %s" + +#: nova/compute/manager.py:230 +#, python-format +msgid "Deallocating address %s" +msgstr "Desasociando la dirección %s" + +#: nova/compute/manager.py:243 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "intentando finalizar una instancia que ya había sido finalizada: %s" + +#: nova/compute/manager.py:257 +#, python-format +msgid "Rebooting instance %s" +msgstr "Reiniciando instancia %s" + +#: nova/compute/manager.py:260 +#, python-format +msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" +"intentando reiniciar una instancia que no está en ejecución: %s (estado: %s " +"esperado: %s)" + +#: nova/compute/manager.py:286 +#, python-format +msgid "instance %s: snapshotting" +msgstr "instancia %s: creando snapshot" + +#: nova/compute/manager.py:289 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" +"intentando crear un snapshot de una instancia que no está en ejecución: %s " +"(estado: %s esperado: %s)" + +#: nova/compute/manager.py:301 +#, python-format +msgid "instance %s: rescuing" +msgstr "instancia %s: rescatando" + +#: nova/compute/manager.py:316 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: nova/compute/manager.py:335 +#, python-format +msgid "instance %s: pausing" +msgstr "instancia %s: pausando" + +#: nova/compute/manager.py:352 +#, python-format +msgid "instance %s: unpausing" +msgstr "instnacia %s: continuando tras pausa" + +#: nova/compute/manager.py:369 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "instancia %s: obteniendo los diagnosticos" + +#: nova/compute/manager.py:382 +#, python-format +msgid "instance %s: suspending" +msgstr "instancia %s: suspendiendo" + +#: nova/compute/manager.py:401 +#, python-format +msgid "instance %s: resuming" +msgstr "instancia %s: continuando" + +#: nova/compute/manager.py:420 +#, python-format +msgid "instance %s: locking" +msgstr "instancia %s: bloqueando" + +#: nova/compute/manager.py:432 +#, python-format +msgid "instance %s: unlocking" +msgstr "instancia %s: desbloqueando" + +#: nova/compute/manager.py:442 +#, python-format +msgid "instance %s: getting locked state" +msgstr "instancia %s: pasando a estado bloqueado" + +#: nova/compute/manager.py:462 +#, python-format +msgid "instance %s: attaching volume %s to %s" +msgstr "instancia %s: asociando volumen %s a %s" + +#: nova/compute/manager.py:478 +#, python-format +msgid "instance %s: attach failed %s, removing" +msgstr "instalación %s: asociación fallida %s, eliminando" + +#: nova/compute/manager.py:493 +#, python-format +msgid "Detach volume %s from mountpoint %s on instance %s" +msgstr "Desvinculando volumen %s del punto de montaje %s en la instancia %s" + +#: nova/compute/manager.py:497 +#, python-format +msgid "Detaching volume from unknown instance %s" +msgstr "Desvinculando volumen de instancia desconocida %s" + +#: nova/compute/monitor.py:259 +#, python-format +msgid "updating %s..." +msgstr "actualizando %s..." + +#: nova/compute/monitor.py:289 +msgid "unexpected error during update" +msgstr "error inesperado durante la actualización" + +#: nova/compute/monitor.py:355 +#, python-format +msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgstr "No puedo obtener estadísticas del bloque para \"%s\" en \"%s\"" + +#: nova/compute/monitor.py:377 +#, python-format +msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgstr "No puedo obtener estadísticas de la interfaz para \"%s\" en \"%s\"" + +#: nova/compute/monitor.py:412 +msgid "unexpected exception getting connection" +msgstr "excepción inexperada al obtener la conexión" + +#: nova/compute/monitor.py:427 +#, python-format +msgid "Found instance: %s" +msgstr "Encontrada interfaz: %s" + +#: nova/db/sqlalchemy/api.py:43 +msgid "Use of empty request context is deprecated" +msgstr "El uso de una petición de contexto vacía está en desuso" + +#: nova/db/sqlalchemy/api.py:132 +#, python-format +msgid "No service for id %s" +msgstr "No hay servicio para el id %s" + +#: nova/db/sqlalchemy/api.py:229 +#, python-format +msgid "No service for %s, %s" +msgstr "No hay servicio para %s, %s" + +#: nova/db/sqlalchemy/api.py:574 +#, python-format +msgid "No floating ip for address %s" +msgstr "No hay ip flotante para la dirección %s" + +#: nova/db/sqlalchemy/api.py:668 +#, python-format +msgid "No instance for id %s" +msgstr "No hay instancia con id %s" + +#: nova/db/sqlalchemy/api.py:758 nova/virt/libvirt_conn.py:598 +#: nova/virt/xenapi/volumeops.py:48 nova/virt/xenapi/volumeops.py:103 +#, python-format +msgid "Instance %s not found" +msgstr "La instancia %s no se ha encontrado" + +#: nova/db/sqlalchemy/api.py:891 +#, python-format +msgid "no keypair for user %s, name %s" +msgstr "no hay par de claves para el usuario %s, nombre %s" + +#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#, python-format +msgid "No network for id %s" +msgstr "No hay red para el id %s" + +#: nova/db/sqlalchemy/api.py:1036 +#, python-format +msgid "No network for bridge %s" +msgstr "No hay red para el puente %s" + +#: nova/db/sqlalchemy/api.py:1050 +#, python-format +msgid "No network for instance %s" +msgstr "No hay red para la instancia %s" + +#: nova/db/sqlalchemy/api.py:1180 +#, python-format +msgid "Token %s does not exist" +msgstr "El token %s no existe" + +#: nova/db/sqlalchemy/api.py:1205 +#, python-format +msgid "No quota for project_id %s" +msgstr "No hay quota para el project:id %s" + +#: nova/db/sqlalchemy/api.py:1356 +#, python-format +msgid "No volume for id %s" +msgstr "No hay volumen para el id %s" + +#: nova/db/sqlalchemy/api.py:1401 +#, python-format +msgid "Volume %s not found" +msgstr "El volumen %s no se ha encontrado" + +#: nova/db/sqlalchemy/api.py:1413 +#, python-format +msgid "No export device found for volume %s" +msgstr "No se ha encontrado dispositivo exportado para el volumen %s" + +#: nova/db/sqlalchemy/api.py:1426 +#, python-format +msgid "No target id found for volume %s" +msgstr "No se ha encontrado id de destino para el volumen %s" + +#: nova/db/sqlalchemy/api.py:1471 +#, python-format +msgid "No security group with id %s" +msgstr "No hay un grupo de seguridad con el id %s" + +#: nova/db/sqlalchemy/api.py:1488 +#, python-format +msgid "No security group named %s for project: %s" +msgstr "No hay un grupo de seguridad con nombre %s para el proyecto: %s" + +#: nova/db/sqlalchemy/api.py:1576 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "No hay una regla para el grupo de seguridad con el id %s" + +#: nova/db/sqlalchemy/api.py:1650 +#, python-format +msgid "No user for id %s" +msgstr "No hay un usuario con el id %s" + +#: nova/db/sqlalchemy/api.py:1666 +#, python-format +msgid "No user for access key %s" +msgstr "No hay un usuario para la clave de acceso %s" + +#: nova/db/sqlalchemy/api.py:1728 +#, python-format +msgid "No project with id %s" +msgstr "No hay proyecto con id %s" + +#: nova/image/glance.py:78 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images" +msgstr "Parallax ha devuelto un error HTTP %d a la petición para /images" + +#: nova/image/glance.py:97 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images/detail" +msgstr "" +"Parallax ha devuelto un error HTTP %d para la petición para /images/detail" + +#: nova/image/s3.py:82 +#, python-format +msgid "Image %s could not be found" +msgstr "La imagen %s no ha podido ser encontrada" + +#: nova/network/api.py:39 +#, python-format +msgid "Quota exceeeded for %s, tried to allocate address" +msgstr "Quota excedida para %s, intentando asignar direcciones" + +#: nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" +msgstr "" +"La quota de direcciones ha sido excedida. No puedes asignar más direcciones" + +#: nova/network/linux_net.py:176 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "Iniciando interfaz VLAN %s" + +#: nova/network/linux_net.py:186 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "Iniciando interfaz puente para %s" + +#: nova/network/linux_net.py:254 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "Excepción al recargar la configuración de dnsmasq: %s" + +#: nova/network/linux_net.py:256 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "El pid %d está pasado, relanzando dnsmasq" + +#: nova/network/linux_net.py:334 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "Al matar dnsmasq se lanzó %s" + +#: nova/network/manager.py:135 +msgid "setting network host" +msgstr "configurando la red del host" + +#: nova/network/manager.py:190 +#, python-format +msgid "Leasing IP %s" +msgstr "Liberando IP %s" + +#: nova/network/manager.py:194 +#, python-format +msgid "IP %s leased that isn't associated" +msgstr "" + +#: nova/network/manager.py:197 +#, python-format +msgid "IP %s leased to bad mac %s vs %s" +msgstr "IP %s asociada a una mac incorrecta %s vs %s" + +#: nova/network/manager.py:205 +#, python-format +msgid "IP %s leased that was already deallocated" +msgstr "" + +#: nova/network/manager.py:214 +#, python-format +msgid "IP %s released that isn't associated" +msgstr "" + +#: nova/network/manager.py:217 +#, python-format +msgid "IP %s released from bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:220 +#, python-format +msgid "IP %s released that was not leased" +msgstr "" + +#: nova/network/manager.py:442 +#, python-format +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "" + +#: nova/objectstore/handler.py:106 +#, python-format +msgid "Unknown S3 value type %r" +msgstr "Tipo de valor S3 %r desconocido" + +#: nova/objectstore/handler.py:137 +msgid "Authenticated request" +msgstr "Petición autenticada" + +#: nova/objectstore/handler.py:182 +msgid "List of buckets requested" +msgstr "Listado de cubos solicitado" + +#: nova/objectstore/handler.py:209 +#, python-format +msgid "List keys for bucket %s" +msgstr "Lista de claves para el cubo %s" + +#: nova/objectstore/handler.py:217 +#, python-format +msgid "Unauthorized attempt to access bucket %s" +msgstr "Intento no autorizado para acceder al cubo %s" + +#: nova/objectstore/handler.py:235 +#, python-format +msgid "Creating bucket %s" +msgstr "Creando el cubo %s" + +#: nova/objectstore/handler.py:245 +#, python-format +msgid "Deleting bucket %s" +msgstr "Eliminando el cubo %s" + +#: nova/objectstore/handler.py:249 +#, python-format +msgid "Unauthorized attempt to delete bucket %s" +msgstr "Intento no autorizado de eliminar el cubo %s" + +#: nova/objectstore/handler.py:271 +#, python-format +msgid "Getting object: %s / %s" +msgstr "Obteniendo objeto: %s / %s" + +#: nova/objectstore/handler.py:274 +#, python-format +msgid "Unauthorized attempt to get object %s from bucket %s" +msgstr "Intento no autorizado de obtener el objeto %s en el cubo %s" + +#: nova/objectstore/handler.py:292 +#, python-format +msgid "Putting object: %s / %s" +msgstr "Colocando objeto: %s / %s" + +#: nova/objectstore/handler.py:295 +#, python-format +msgid "Unauthorized attempt to upload object %s to bucket %s" +msgstr "Intento no autorizado de subir el objeto %s al cubo %s" + +#: nova/objectstore/handler.py:314 +#, python-format +msgid "Deleting object: %s / %s" +msgstr "Eliminando objeto: %s / %s" + +#: nova/objectstore/handler.py:393 +#, python-format +msgid "Not authorized to upload image: invalid directory %s" +msgstr "No autorizado para subir imagen: directorio incorrecto %s" + +#: nova/objectstore/handler.py:401 +#, python-format +msgid "Not authorized to upload image: unauthorized bucket %s" +msgstr "No autorizado para subir imagen: cubo %s no autorizado" + +#: nova/objectstore/handler.py:406 +#, python-format +msgid "Starting image upload: %s" +msgstr "Comenzando la subida de la imagen: %s" + +#: nova/objectstore/handler.py:420 +#, python-format +msgid "Not authorized to update attributes of image %s" +msgstr "No autorizado para actualizar los atributos de la imagen %s" + +#: nova/objectstore/handler.py:428 +#, python-format +msgid "Toggling publicity flag of image %s %r" +msgstr "Cambiando los atributos de publicidad de la imagen %s %r" + +#: nova/objectstore/handler.py:433 +#, python-format +msgid "Updating user fields on image %s" +msgstr "Actualizando los campos de usuario de la imagen %s" + +#: nova/objectstore/handler.py:447 +#, python-format +msgid "Unauthorized attempt to delete image %s" +msgstr "Intento no autorizado de borrar la imagen %s" + +#: nova/objectstore/handler.py:452 +#, python-format +msgid "Deleted image: %s" +msgstr "Eliminada imagen: %s" + +#: nova/scheduler/chance.py:37 nova/scheduler/simple.py:73 +#: nova/scheduler/simple.py:106 nova/scheduler/simple.py:118 +msgid "No hosts found" +msgstr "No se han encontrado hosts" + +#: nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "Debe de implementar un horario de reserva" + +#: nova/scheduler/manager.py:69 +#, python-format +msgid "Casting to %s %s for %s" +msgstr "" + +#: nova/scheduler/simple.py:63 +msgid "All hosts have too many cores" +msgstr "Todos los hosts tienen demasiados cores" + +#: nova/scheduler/simple.py:95 +msgid "All hosts have too many gigabytes" +msgstr "Todos los hosts tienen demasiados gigabytes" + +#: nova/scheduler/simple.py:115 +msgid "All hosts have too many networks" +msgstr "Todos los hosts tienen demasiadas redes" + +#: nova/tests/test_cloud.py:198 +msgid "Can't test instances without a real virtual env." +msgstr "No puedo probar las imágenes sin un entorno real virtual" + +#: nova/tests/test_cloud.py:210 +#, python-format +msgid "Need to watch instance %s until it's running..." +msgstr "Hay que vigilar la instancia %s hasta que este en ejecución..." + +#: nova/tests/test_compute.py:104 +#, python-format +msgid "Running instances: %s" +msgstr "Ejecutando instancias: %s" + +#: nova/tests/test_compute.py:110 +#, python-format +msgid "After terminating instances: %s" +msgstr "Después de terminar las instancias: %s" + +#: nova/tests/test_rpc.py:89 +#, python-format +msgid "Nested received %s, %s" +msgstr "" + +#: nova/tests/test_rpc.py:94 +#, python-format +msgid "Nested return %s" +msgstr "" + +#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#, python-format +msgid "Received %s" +msgstr "Recibido %s" + +#: nova/tests/test_volume.py:162 +#, python-format +msgid "Target %s allocated" +msgstr "Destino %s asignado" + +#: nova/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "Fallo al abrir conexión con el hypervisor" + +#: nova/virt/fake.py:210 +#, python-format +msgid "Instance %s Not Found" +msgstr "La instancia %s no ha sido encontrada" + +#: nova/virt/hyperv.py:118 +msgid "In init host" +msgstr "En el host inicial" + +#: nova/virt/hyperv.py:131 +#, python-format +msgid "Attempt to create duplicate vm %s" +msgstr "Intento de crear una vm duplicada %s" + +#: nova/virt/hyperv.py:148 +#, python-format +msgid "Starting VM %s " +msgstr "Comenzando VM %s " + +#: nova/virt/hyperv.py:150 +#, python-format +msgid "Started VM %s " +msgstr "VM %s iniciada " + +#: nova/virt/hyperv.py:152 +#, python-format +msgid "spawn vm failed: %s" +msgstr "Inicio de vm fallido: %s" + +#: nova/virt/hyperv.py:169 +#, python-format +msgid "Failed to create VM %s" +msgstr "Fallo al crear la VM %s" + +#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#, python-format +msgid "Created VM %s..." +msgstr "Creada VM %s..." + +#: nova/virt/hyperv.py:188 +#, python-format +msgid "Set memory for vm %s..." +msgstr "Se ha establecido la memoria para vm %s..." + +#: nova/virt/hyperv.py:198 +#, python-format +msgid "Set vcpus for vm %s..." +msgstr "Establecidas vcpus para vm %s..." + +#: nova/virt/hyperv.py:202 +#, python-format +msgid "Creating disk for %s by attaching disk file %s" +msgstr "" +"Creando disco para %s a través de la asignación del fichero de disco %s" + +#: nova/virt/hyperv.py:227 +#, python-format +msgid "Failed to add diskdrive to VM %s" +msgstr "Fallo al añadir unidad de disco a la VM %s" + +#: nova/virt/hyperv.py:230 +#, python-format +msgid "New disk drive path is %s" +msgstr "La nueva ruta para unidad de disco es %s" + +#: nova/virt/hyperv.py:247 +#, python-format +msgid "Failed to add vhd file to VM %s" +msgstr "Fallo al añadir el fichero vhd a la VM %s" + +#: nova/virt/hyperv.py:249 +#, python-format +msgid "Created disk for %s" +msgstr "Discos creados para %s" + +#: nova/virt/hyperv.py:253 +#, python-format +msgid "Creating nic for %s " +msgstr "Creando nic para %s " + +#: nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" +msgstr "Fallo al crear un puerto en el vswitch externo" + +#: nova/virt/hyperv.py:273 +#, python-format +msgid "Failed creating port for %s" +msgstr "Fallo creando puerto para %s" + +#: nova/virt/hyperv.py:275 +#, python-format +msgid "Created switch port %s on switch %s" +msgstr "Creado puerto %s en el switch %s" + +#: nova/virt/hyperv.py:285 +#, python-format +msgid "Failed to add nic to VM %s" +msgstr "Fallo al añadir nic a la VM %s" + +#: nova/virt/hyperv.py:287 +#, python-format +msgid "Created nic for %s " +msgstr "Creando nic para %s " + +#: nova/virt/hyperv.py:320 +#, python-format +msgid "WMI job failed: %s" +msgstr "Trabajo WMI falló: %s" + +#: nova/virt/hyperv.py:322 +#, python-format +msgid "WMI job succeeded: %s, Elapsed=%s " +msgstr "Trabajo WMI ha tenido exito: %s, Transcurrido=%s " + +#: nova/virt/hyperv.py:358 +#, python-format +msgid "Got request to destroy vm %s" +msgstr "Recibida solicitud para destruir vm %s" + +#: nova/virt/hyperv.py:383 +#, python-format +msgid "Failed to destroy vm %s" +msgstr "Fallo al destruir vm %s" + +#: nova/virt/hyperv.py:389 +#, python-format +msgid "Del: disk %s vm %s" +msgstr "Del: disco %s vm %s" + +#: nova/virt/hyperv.py:405 +#, python-format +msgid "" +"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " +"cpu_time=%s" +msgstr "" +"Obtenida información para vm %s: state=%s, mem=%s, num_cpu=%s, cpu_time=%s" + +#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#, python-format +msgid "duplicate name found: %s" +msgstr "se ha encontrado un nombre duplicado: %s" + +#: nova/virt/hyperv.py:444 +#, python-format +msgid "Successfully changed vm state of %s to %s" +msgstr "Cambio de estado de la vm con éxito de %s a %s" + +#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#, python-format +msgid "Failed to change vm state of %s to %s" +msgstr "Fallo al cambiar el estado de la vm de %s a %s" + +#: nova/virt/images.py:70 +#, python-format +msgid "Finished retreving %s -- placed in %s" +msgstr "Finalizada la obtención de %s -- coloado en %s" + +#: nova/virt/libvirt_conn.py:144 +#, python-format +msgid "Connecting to libvirt: %s" +msgstr "Conectando a libvirt: %s" + +#: nova/virt/libvirt_conn.py:157 +msgid "Connection to libvirt broke" +msgstr "Conexión a libvirt rota" + +#: nova/virt/libvirt_conn.py:229 +#, python-format +msgid "instance %s: deleting instance files %s" +msgstr "instancia %s: eliminando los ficheros de la instancia %s" + +#: nova/virt/libvirt_conn.py:271 +#, python-format +msgid "No disk at %s" +msgstr "No hay disco en %s" + +#: nova/virt/libvirt_conn.py:278 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "" +"El snapshotting de instancias no está soportado en libvirt en este momento" + +#: nova/virt/libvirt_conn.py:294 +#, python-format +msgid "instance %s: rebooted" +msgstr "instancia %s: reiniciada" + +#: nova/virt/libvirt_conn.py:297 +#, python-format +msgid "_wait_for_reboot failed: %s" +msgstr "_wait_for_reboot falló: %s" + +#: nova/virt/libvirt_conn.py:340 +#, python-format +msgid "instance %s: rescued" +msgstr "instancia %s: rescatada" + +#: nova/virt/libvirt_conn.py:343 +#, python-format +msgid "_wait_for_rescue failed: %s" +msgstr "_wait_for_rescue falló: %s" + +#: nova/virt/libvirt_conn.py:370 +#, python-format +msgid "instance %s: is running" +msgstr "instancia %s: está ejecutándose" + +#: nova/virt/libvirt_conn.py:381 +#, python-format +msgid "instance %s: booted" +msgstr "instancia %s: arrancada" + +#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#, python-format +msgid "instance %s: failed to boot" +msgstr "insntancia %s: falló al arrancar" + +#: nova/virt/libvirt_conn.py:395 +#, python-format +msgid "virsh said: %r" +msgstr "virsh dijo: %r" + +#: nova/virt/libvirt_conn.py:399 +msgid "cool, it's a device" +msgstr "genial, es un dispositivo" + +#: nova/virt/libvirt_conn.py:407 +#, python-format +msgid "data: %r, fpath: %r" +msgstr "datos: %r, fpath: %r" + +#: nova/virt/libvirt_conn.py:415 +#, python-format +msgid "Contents of file %s: %r" +msgstr "Contenidos del fichero %s: %r" + +#: nova/virt/libvirt_conn.py:449 +#, python-format +msgid "instance %s: Creating image" +msgstr "instancia %s: Creando imagen" + +#: nova/virt/libvirt_conn.py:505 +#, python-format +msgid "instance %s: injecting key into image %s" +msgstr "instancia %s: inyectando clave en la imagen %s" + +#: nova/virt/libvirt_conn.py:508 +#, python-format +msgid "instance %s: injecting net into image %s" +msgstr "instancia %s: inyectando red en la imagen %s" + +#: nova/virt/libvirt_conn.py:516 +#, python-format +msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgstr "" +"instancia %s: ignorando el error al inyectar datos en la imagen %s (%s)" + +#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#, python-format +msgid "instance %s: starting toXML method" +msgstr "instancia %s: comenzando método toXML" + +#: nova/virt/libvirt_conn.py:589 +#, python-format +msgid "instance %s: finished toXML method" +msgstr "instancia %s: finalizado método toXML" + +#: nova/virt/xenapi_conn.py:113 +msgid "" +"Must specify xenapi_connection_url, xenapi_connection_username (optionally), " +"and xenapi_connection_password to use connection_type=xenapi" +msgstr "" +"Debes especificar xenapi_connection_url, xenapi_connection_username " +"(opcional), y xenapi_connection_password para usar connection_type=xenapi" + +#: nova/virt/xenapi_conn.py:263 +#, python-format +msgid "Task [%s] %s status: success %s" +msgstr "Tarea [%s] %s estado: éxito %s" + +#: nova/virt/xenapi_conn.py:271 +#, python-format +msgid "Task [%s] %s status: %s %s" +msgstr "Tarea [%s] %s estado: %s %s" + +#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#, python-format +msgid "Got exception: %s" +msgstr "Obtenida excepción %s" + +#: nova/virt/xenapi/fake.py:72 +#, python-format +msgid "%s: _db_content => %s" +msgstr "%s: _db_content => %s" + +#: nova/virt/xenapi/fake.py:247 nova/virt/xenapi/fake.py:338 +#: nova/virt/xenapi/fake.py:356 nova/virt/xenapi/fake.py:404 +msgid "Raising NotImplemented" +msgstr "Lanzando NotImplemented" + +#: nova/virt/xenapi/fake.py:249 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "xenapi.fake no tiene una implementación para %s" + +#: nova/virt/xenapi/fake.py:283 +#, python-format +msgid "Calling %s %s" +msgstr "Llamando %s %s" + +#: nova/virt/xenapi/fake.py:288 +#, python-format +msgid "Calling getter %s" +msgstr "Llanado al adquiridor %s" + +#: nova/virt/xenapi/fake.py:340 +#, python-format +msgid "" +"xenapi.fake does not have an implementation for %s or it has been called " +"with the wrong number of arguments" +msgstr "" +"xenapi.fake no tiene una implementación para %s o ha sido llamada con un " +"número incorrecto de argumentos" + +#: nova/virt/xenapi/network_utils.py:40 +#, python-format +msgid "Found non-unique network for bridge %s" +msgstr "Encontrada una red no única para el puente %s" + +#: nova/virt/xenapi/network_utils.py:43 +#, python-format +msgid "Found no network for bridge %s" +msgstr "No se ha encontrado red para el puente %s" + +#: nova/virt/xenapi/vm_utils.py:127 +#, python-format +msgid "Created VM %s as %s." +msgstr "Creada VM %s cómo %s" + +#: nova/virt/xenapi/vm_utils.py:147 +#, python-format +msgid "Creating VBD for VM %s, VDI %s ... " +msgstr "Creando VBD para VM %s, VDI %s... " + +#: nova/virt/xenapi/vm_utils.py:149 +#, python-format +msgid "Created VBD %s for VM %s, VDI %s." +msgstr "Creado VBD %s for VM %s, VDI %s." + +#: nova/virt/xenapi/vm_utils.py:165 +#, python-format +msgid "VBD not found in instance %s" +msgstr "VBD no encontrado en la instancia %s" + +#: nova/virt/xenapi/vm_utils.py:175 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "Imposible desconectar VBD %s" + +#: nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "Imposible destruir VBD %s" + +#: nova/virt/xenapi/vm_utils.py:202 +#, python-format +msgid "Creating VIF for VM %s, network %s." +msgstr "Creando VIF para VM %s, red %s." + +#: nova/virt/xenapi/vm_utils.py:205 +#, python-format +msgid "Created VIF %s for VM %s, network %s." +msgstr "Creado VIF %s para VM %s, red %s." + +#: nova/virt/xenapi/vm_utils.py:216 +#, python-format +msgid "Snapshotting VM %s with label '%s'..." +msgstr "Creando snapshot de la VM %s con la etiqueta '%s'..." + +#: nova/virt/xenapi/vm_utils.py:229 +#, python-format +msgid "Created snapshot %s from VM %s." +msgstr "Creando snapshot %s de la VM %s" + +#: nova/virt/xenapi/vm_utils.py:243 +#, python-format +msgid "Asking xapi to upload %s as '%s'" +msgstr "Solicitando a xapi la subida de %s cómo %s'" + +#: nova/virt/xenapi/vm_utils.py:261 +#, python-format +msgid "Asking xapi to fetch %s as %s" +msgstr "Solicitando a xapi obtener %s cómo %s" + +#: nova/virt/xenapi/vm_utils.py:279 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "Buscando vid %s para el kernel PV" + +#: nova/virt/xenapi/vm_utils.py:290 +#, python-format +msgid "PV Kernel in VDI:%d" +msgstr "PV Kernel en VDI:%d" + +#: nova/virt/xenapi/vm_utils.py:318 +#, python-format +msgid "VDI %s is still available" +msgstr "VDI %s está todavía disponible" + +#: nova/virt/xenapi/vm_utils.py:331 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "(VM_UTILS) xenserver vm state -> |%s|" + +#: nova/virt/xenapi/vm_utils.py:333 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "(VM_UTILS) xenapi power_state -> |%s|" + +#: nova/virt/xenapi/vm_utils.py:390 +#, python-format +msgid "VHD %s has parent %s" +msgstr "VHD %s tiene cómo padre a %s" + +#: nova/virt/xenapi/vm_utils.py:407 +#, python-format +msgid "Re-scanning SR %s" +msgstr "Re-escaneando SR %s" + +#: nova/virt/xenapi/vm_utils.py:431 +#, python-format +msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgstr "" +"El padre %s no concuerda con el padre original %s, esperando la unión..." + +#: nova/virt/xenapi/vm_utils.py:448 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "No se han encontrado VDI's para VM %s" + +#: nova/virt/xenapi/vm_utils.py:452 +#, python-format +msgid "Unexpected number of VDIs (%s) found for VM %s" +msgstr "Número no esperado de VDIs (%s) encontrados para VM %s" + +#: nova/virt/xenapi/vmops.py:62 +#, python-format +msgid "Attempted to create non-unique name %s" +msgstr "Intentado la creación del nombre no único %s" + +#: nova/virt/xenapi/vmops.py:99 +#, python-format +msgid "Starting VM %s..." +msgstr "Iniciando VM %s..." + +#: nova/virt/xenapi/vmops.py:101 +#, python-format +msgid "Spawning VM %s created %s." +msgstr "Iniciando VM %s creado %s." + +#: nova/virt/xenapi/vmops.py:112 +#, python-format +msgid "Instance %s: booted" +msgstr "Instancia %s: iniciada" + +#: nova/virt/xenapi/vmops.py:137 +#, python-format +msgid "Instance not present %s" +msgstr "Instancia no existente %s" + +#: nova/virt/xenapi/vmops.py:166 +#, python-format +msgid "Starting snapshot for VM %s" +msgstr "Comenzando snapshot para la VM %s" + +#: nova/virt/xenapi/vmops.py:174 +#, python-format +msgid "Unable to Snapshot %s: %s" +msgstr "Incapaz de realizar snapshot %s: %s" + +#: nova/virt/xenapi/vmops.py:184 +#, python-format +msgid "Finished snapshot and upload for VM %s" +msgstr "Finalizado el snapshot y la subida de la VM %s" + +#: nova/virt/xenapi/vmops.py:252 +#, python-format +msgid "suspend: instance not present %s" +msgstr "suspendido: instancia no encontrada: %s" + +#: nova/virt/xenapi/vmops.py:262 +#, python-format +msgid "resume: instance not present %s" +msgstr "reanudar: instancia no encontrada %s" + +#: nova/virt/xenapi/vmops.py:271 +#, python-format +msgid "Instance not found %s" +msgstr "instancia no encontrada %s" + +#: nova/virt/xenapi/volume_utils.py:57 +#, python-format +msgid "Introducing %s..." +msgstr "Introduciendo %s..." + +#: nova/virt/xenapi/volume_utils.py:74 +#, python-format +msgid "Introduced %s as %s." +msgstr "Introducido %s cómo %s." + +#: nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" +msgstr "Imposible crear el repositorio de almacenamiento" + +#: nova/virt/xenapi/volume_utils.py:90 +#, python-format +msgid "Unable to find SR from VBD %s" +msgstr "Imposible encontrar SR en VBD %s" + +#: nova/virt/xenapi/volume_utils.py:96 +#, python-format +msgid "Forgetting SR %s ... " +msgstr "Olvidando SR %s... " + +#: nova/virt/xenapi/volume_utils.py:101 +#, python-format +msgid "Ignoring exception %s when getting PBDs for %s" +msgstr "Ignorando excepción %s al obtener PBDs de %s" + +#: nova/virt/xenapi/volume_utils.py:107 +#, python-format +msgid "Ignoring exception %s when unplugging PBD %s" +msgstr "Ignorando excepción %s al desconectar PBD %s" + +#: nova/virt/xenapi/volume_utils.py:111 +#, python-format +msgid "Forgetting SR %s done." +msgstr "Olvidando SR %s completado." + +#: nova/virt/xenapi/volume_utils.py:113 +#, python-format +msgid "Ignoring exception %s when forgetting SR %s" +msgstr "Ignorando excepción %s al olvidar SR %s" + +#: nova/virt/xenapi/volume_utils.py:123 +#, python-format +msgid "Unable to introduce VDI on SR %s" +msgstr "Incapaz de insertar VDI en SR %s" + +#: nova/virt/xenapi/volume_utils.py:128 +#, python-format +msgid "Unable to get record of VDI %s on" +msgstr "Imposible obtener copia del VDI %s en" + +#: nova/virt/xenapi/volume_utils.py:146 +#, python-format +msgid "Unable to introduce VDI for SR %s" +msgstr "Inposible insertar VDI para SR %s" + +#: nova/virt/xenapi/volume_utils.py:175 +#, python-format +msgid "Unable to obtain target information %s, %s" +msgstr "Imposible obtener información del destino %s, %s" + +#: nova/virt/xenapi/volume_utils.py:197 +#, python-format +msgid "Mountpoint cannot be translated: %s" +msgstr "Punto de montaje no puede ser traducido: %s" + +#: nova/virt/xenapi/volumeops.py:51 +#, python-format +msgid "Attach_volume: %s, %s, %s" +msgstr "Attach_volume: %s, %s, %s" + +#: nova/virt/xenapi/volumeops.py:69 +#, python-format +msgid "Unable to create VDI on SR %s for instance %s" +msgstr "Inpoisble crear VDI en SR %s para la instancia %s" + +#: nova/virt/xenapi/volumeops.py:81 +#, python-format +msgid "Unable to use SR %s for instance %s" +msgstr "Imposible utilizar SR %s para la instancia %s" + +#: nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Unable to attach volume to instance %s" +msgstr "Imposible adjuntar volumen a la instancia %s" + +#: nova/virt/xenapi/volumeops.py:95 +#, python-format +msgid "Mountpoint %s attached to instance %s" +msgstr "Punto de montaje %s unido a la instancia %s" + +#: nova/virt/xenapi/volumeops.py:106 +#, python-format +msgid "Detach_volume: %s, %s" +msgstr "Detach_volume: %s, %s" + +#: nova/virt/xenapi/volumeops.py:113 +#, python-format +msgid "Unable to locate volume %s" +msgstr "Imposible encontrar volumen %s" + +#: nova/virt/xenapi/volumeops.py:121 +#, python-format +msgid "Unable to detach volume %s" +msgstr "Imposible desasociar volumen %s" + +#: nova/virt/xenapi/volumeops.py:128 +#, python-format +msgid "Mountpoint %s detached from instance %s" +msgstr "Punto d emontaje %s desasociado de la instancia %s" + +#: nova/volume/api.py:44 +#, python-format +msgid "Quota exceeeded for %s, tried to create %sG volume" +msgstr "Quota excedida para %s, intentando crear el volumen %sG" + +#: nova/volume/api.py:46 +#, python-format +msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgstr "Quota de volumen superada. No puedes crear un volumen de tamaño %s" + +#: nova/volume/api.py:70 nova/volume/api.py:95 +msgid "Volume status must be available" +msgstr "El estado del volumen debe estar disponible" + +#: nova/volume/api.py:97 +msgid "Volume is already attached" +msgstr "El volumen ya está asociado previamente" + +#: nova/volume/api.py:103 +msgid "Volume is already detached" +msgstr "El volumen ya ha sido desasociado previamente" + +#: nova/volume/driver.py:76 +#, python-format +msgid "Recovering from a failed execute. Try number %s" +msgstr "Recuperandose de una ejecución fallida. Intenta el número %s" + +#: nova/volume/driver.py:85 +#, python-format +msgid "volume group %s doesn't exist" +msgstr "el grupo de volumenes %s no existe" + +#: nova/volume/driver.py:210 +#, python-format +msgid "FAKE AOE: %s" +msgstr "Falso AOE: %s" + +#: nova/volume/driver.py:315 +#, python-format +msgid "FAKE ISCSI: %s" +msgstr "Falso ISCSI: %s" + +#: nova/volume/manager.py:85 +#, python-format +msgid "Re-exporting %s volumes" +msgstr "Exportando de nuevo los volumenes %s" + +#: nova/volume/manager.py:93 +#, python-format +msgid "volume %s: creating" +msgstr "volumen %s: creando" + +#: nova/volume/manager.py:102 +#, python-format +msgid "volume %s: creating lv of size %sG" +msgstr "volumen %s: creando lv de tamaño %sG" + +#: nova/volume/manager.py:106 +#, python-format +msgid "volume %s: creating export" +msgstr "volumen %s: exportando" + +#: nova/volume/manager.py:113 +#, python-format +msgid "volume %s: created successfully" +msgstr "volumen %s: creado satisfactoriamente" + +#: nova/volume/manager.py:121 +msgid "Volume is still attached" +msgstr "El volumen todavía está asociado" + +#: nova/volume/manager.py:123 +msgid "Volume is not local to this node" +msgstr "Volumen no local a este nodo" + +#: nova/volume/manager.py:124 +#, python-format +msgid "volume %s: removing export" +msgstr "volumen %s: eliminando exportación" + +#: nova/volume/manager.py:126 +#, python-format +msgid "volume %s: deleting" +msgstr "volumen %s: eliminando" + +#: nova/volume/manager.py:129 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "volumen %s: eliminado satisfactoriamente" diff --git a/locale/it.po b/locale/it.po new file mode 100644 index 00000000..f2f6a6b8 --- /dev/null +++ b/locale/it.po @@ -0,0 +1,2141 @@ +# Italian translation for nova +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the nova package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: nova\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"PO-Revision-Date: 2011-01-14 17:17+0000\n" +"Last-Translator: Armando Migliaccio \n" +"Language-Team: Italian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-01-28 05:20+0000\n" +"X-Generator: Launchpad (build 12177)\n" + +#: nova/crypto.py:46 +msgid "Filename of root CA" +msgstr "Nome del file root CA" + +#: nova/crypto.py:49 +msgid "Filename of private key" +msgstr "Nome del file della chiave privata" + +#: nova/crypto.py:51 +msgid "Filename of root Certificate Revokation List" +msgstr "" + +#: nova/crypto.py:53 +msgid "Where we keep our keys" +msgstr "Dove si conservano le chiavi" + +#: nova/crypto.py:55 +msgid "Where we keep our root CA" +msgstr "Dove si conserva root CA" + +#: nova/crypto.py:57 +msgid "Should we use a CA for each project?" +msgstr "Si dovrebbe usare un CA per ogni progetto?" + +#: nova/crypto.py:61 +#, python-format +msgid "Subject for certificate for users, %s for project, user, timestamp" +msgstr "" +"Soggetto per il certificato degli utenti, %s per progetto, utente, orario" + +#: nova/crypto.py:66 +#, python-format +msgid "Subject for certificate for projects, %s for project, timestamp" +msgstr "Soggetto per il certificato dei progetti, %s per progetto, orario" + +#: nova/crypto.py:71 +#, python-format +msgid "Subject for certificate for vpns, %s for project, timestamp" +msgstr "Soggetto per il certificato delle vpn, %s per progetto, orario" + +#: nova/crypto.py:258 +#, python-format +msgid "Flags path: %s" +msgstr "Percorso dei flags: %s" + +#: nova/exception.py:33 +msgid "Unexpected error while running command." +msgstr "" +"Si e' verificato un errore inatteso durante l'esecuzione del comando." + +#: nova/exception.py:36 +#, python-format +msgid "" +"%s\n" +"Command: %s\n" +"Exit code: %s\n" +"Stdout: %r\n" +"Stderr: %r" +msgstr "" +"%s\n" +"Comando: %s\n" +"Exit code: %s\n" +"Stdout: %r\n" +"Stderr: %r" + +#: nova/exception.py:86 +msgid "Uncaught exception" +msgstr "Eccezione non gestita" + +#: nova/fakerabbit.py:48 +#, python-format +msgid "(%s) publish (key: %s) %s" +msgstr "(%s) pubblica (chiave: %s) %s" + +#: nova/fakerabbit.py:53 +#, python-format +msgid "Publishing to route %s" +msgstr "Pubblicando sulla route %s" + +#: nova/fakerabbit.py:83 +#, python-format +msgid "Declaring queue %s" +msgstr "Dichiarando la coda %s" + +#: nova/fakerabbit.py:89 +#, python-format +msgid "Declaring exchange %s" +msgstr "Dichiarando il centralino %s" + +#: nova/fakerabbit.py:95 +#, python-format +msgid "Binding %s to %s with key %s" +msgstr "Collegando %s a %s con la chiave %s" + +#: nova/fakerabbit.py:120 +#, python-format +msgid "Getting from %s: %s" +msgstr "" + +#: nova/rpc.py:92 +#, python-format +msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgstr "" +"Il server AMQP su %s:%d non é raggiungibile. Riprovare in %d secondi." + +#: nova/rpc.py:99 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "" +"Impossibile connettersi al server AMQP dopo %d tentativi. Terminando " +"l'applicazione." + +#: nova/rpc.py:118 +msgid "Reconnected to queue" +msgstr "Riconnesso alla coda" + +#: nova/rpc.py:125 +msgid "Failed to fetch message from queue" +msgstr "Impossibile prelevare il messaggio dalla coda" + +#: nova/rpc.py:155 +#, python-format +msgid "Initing the Adapter Consumer for %s" +msgstr "Inizializzando il Consumer Adapter per %s" + +#: nova/rpc.py:170 +#, python-format +msgid "received %s" +msgstr "ricevuto %s" + +#: nova/rpc.py:183 +#, python-format +msgid "no method for message: %s" +msgstr "nessun metodo per il messaggio: %s" + +#: nova/rpc.py:184 +#, python-format +msgid "No method for message: %s" +msgstr "nessun metodo per il messagggio: %s" + +#: nova/rpc.py:245 +#, python-format +msgid "Returning exception %s to caller" +msgstr "Sollevando eccezione %s al chiamante" + +#: nova/rpc.py:286 +#, python-format +msgid "unpacked context: %s" +msgstr "contesto decompresso: %s" + +#: nova/rpc.py:305 +msgid "Making asynchronous call..." +msgstr "Facendo chiamata asincrona..." + +#: nova/rpc.py:308 +#, python-format +msgid "MSG_ID is %s" +msgstr "MSG_ID é %s" + +#: nova/rpc.py:356 +#, python-format +msgid "response %s" +msgstr "risposta %s" + +#: nova/rpc.py:365 +#, python-format +msgid "topic is %s" +msgstr "argomento é %s" + +#: nova/rpc.py:366 +#, python-format +msgid "message %s" +msgstr "messaggio %s" + +#: nova/service.py:157 +#, python-format +msgid "Starting %s node" +msgstr "Avviando il nodo %s" + +#: nova/service.py:169 +msgid "Service killed that has no database entry" +msgstr "Servizio terminato che non ha entry nel database" + +#: nova/service.py:190 +msgid "The service database object disappeared, Recreating it." +msgstr "Il servizio é scomparso dal database, ricreo." + +#: nova/service.py:202 +msgid "Recovered model server connection!" +msgstr "Connessione al model server ripristinata!" + +#: nova/service.py:208 +msgid "model server went away" +msgstr "model server é scomparso" + +#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#, python-format +msgid "Data store %s is unreachable. Trying again in %d seconds." +msgstr "Datastore %s é irrangiungibile. Riprovare in %d seconds." + +#: nova/service.py:232 nova/twistd.py:232 +#, python-format +msgid "Serving %s" +msgstr "Servire %s" + +#: nova/service.py:234 nova/twistd.py:264 +msgid "Full set of FLAGS:" +msgstr "Insieme di FLAGS:" + +#: nova/twistd.py:211 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "" +"Il pidfile %s non esiste. Assicurarsi che il demone é in esecuzione.\n" + +#: nova/twistd.py:268 +#, python-format +msgid "Starting %s" +msgstr "Avvio di %s" + +#: nova/utils.py:53 +#, python-format +msgid "Inner Exception: %s" +msgstr "Eccezione interna: %s" + +#: nova/utils.py:54 +#, python-format +msgid "Class %s cannot be found" +msgstr "Classe %s non può essere trovata" + +#: nova/utils.py:113 +#, python-format +msgid "Fetching %s" +msgstr "Prelievo %s" + +#: nova/utils.py:125 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "Esecuzione del comando (sottoprocesso): %s" + +#: nova/utils.py:138 +#, python-format +msgid "Result was %s" +msgstr "Il risultato é %s" + +#: nova/utils.py:171 +#, python-format +msgid "debug in callback: %s" +msgstr "debug in callback: %s" + +#: nova/utils.py:176 +#, python-format +msgid "Running %s" +msgstr "" + +#: nova/utils.py:207 +#, python-format +msgid "Couldn't get IP, using 127.0.0.1 %s" +msgstr "" + +#: nova/utils.py:289 +#, python-format +msgid "Invalid backend: %s" +msgstr "" + +#: nova/utils.py:300 +#, python-format +msgid "backend %s" +msgstr "" + +#: nova/api/ec2/__init__.py:133 +msgid "Too many failed authentications." +msgstr "" + +#: nova/api/ec2/__init__.py:142 +#, python-format +msgid "" +"Access key %s has had %d failed authentications and will be locked out for " +"%d minutes." +msgstr "" + +#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#, python-format +msgid "Authentication Failure: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:190 +#, python-format +msgid "Authenticated Request For %s:%s)" +msgstr "" + +#: nova/api/ec2/__init__.py:227 +#, python-format +msgid "action: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:229 +#, python-format +msgid "arg: %s\t\tval: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:301 +#, python-format +msgid "Unauthorized request for controller=%s and action=%s" +msgstr "" + +#: nova/api/ec2/__init__.py:339 +#, python-format +msgid "NotFound raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:342 +#, python-format +msgid "ApiError raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:349 +#, python-format +msgid "Unexpected error raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:354 +msgid "An unknown error has occurred. Please try your request again." +msgstr "" + +#: nova/api/ec2/admin.py:84 +#, python-format +msgid "Creating new user: %s" +msgstr "" + +#: nova/api/ec2/admin.py:92 +#, python-format +msgid "Deleting user: %s" +msgstr "" + +#: nova/api/ec2/admin.py:114 +#, python-format +msgid "Adding role %s to user %s for project %s" +msgstr "" + +#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#, python-format +msgid "Adding sitewide role %s to user %s" +msgstr "" + +#: nova/api/ec2/admin.py:122 +#, python-format +msgid "Removing role %s from user %s for project %s" +msgstr "" + +#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#, python-format +msgid "Removing sitewide role %s from user %s" +msgstr "" + +#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 +msgid "operation must be add or remove" +msgstr "" + +#: nova/api/ec2/admin.py:142 +#, python-format +msgid "Getting x509 for user: %s on project: %s" +msgstr "" + +#: nova/api/ec2/admin.py:159 +#, python-format +msgid "Create project %s managed by %s" +msgstr "" + +#: nova/api/ec2/admin.py:170 +#, python-format +msgid "Delete project: %s" +msgstr "" + +#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#, python-format +msgid "Adding user %s to project %s" +msgstr "" + +#: nova/api/ec2/admin.py:188 +#, python-format +msgid "Removing user %s from project %s" +msgstr "" + +#: nova/api/ec2/apirequest.py:95 +#, python-format +msgid "Unsupported API request: controller = %s,action = %s" +msgstr "" + +#: nova/api/ec2/cloud.py:117 +#, python-format +msgid "Generating root CA: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:277 +#, python-format +msgid "Create key pair %s" +msgstr "" + +#: nova/api/ec2/cloud.py:285 +#, python-format +msgid "Delete key pair %s" +msgstr "" + +#: nova/api/ec2/cloud.py:357 +#, python-format +msgid "%s is not a valid ipProtocol" +msgstr "" + +#: nova/api/ec2/cloud.py:361 +msgid "Invalid port range" +msgstr "" + +#: nova/api/ec2/cloud.py:392 +#, python-format +msgid "Revoke security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 +msgid "No rule for the specified parameters." +msgstr "" + +#: nova/api/ec2/cloud.py:421 +#, python-format +msgid "Authorize security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:432 +#, python-format +msgid "This rule already exists in group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:460 +#, python-format +msgid "Create Security Group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:463 +#, python-format +msgid "group %s already exists" +msgstr "" + +#: nova/api/ec2/cloud.py:475 +#, python-format +msgid "Delete security group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:543 +#, python-format +msgid "Create volume of %s GB" +msgstr "" + +#: nova/api/ec2/cloud.py:567 +#, python-format +msgid "Attach volume %s to instacne %s at %s" +msgstr "" + +#: nova/api/ec2/cloud.py:579 +#, python-format +msgid "Detach volume %s" +msgstr "" + +#: nova/api/ec2/cloud.py:686 +msgid "Allocate address" +msgstr "" + +#: nova/api/ec2/cloud.py:691 +#, python-format +msgid "Release address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:696 +#, python-format +msgid "Associate address %s to instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:703 +#, python-format +msgid "Disassociate address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:730 +msgid "Going to start terminating instances" +msgstr "" + +#: nova/api/ec2/cloud.py:738 +#, python-format +msgid "Reboot instance %r" +msgstr "" + +#: nova/api/ec2/cloud.py:775 +#, python-format +msgid "De-registering image %s" +msgstr "" + +#: nova/api/ec2/cloud.py:783 +#, python-format +msgid "Registered image %s with id %s" +msgstr "" + +#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#, python-format +msgid "attribute not supported: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:794 +#, python-format +msgid "invalid id: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:807 +msgid "user or group not specified" +msgstr "" + +#: nova/api/ec2/cloud.py:809 +msgid "only group \"all\" is supported" +msgstr "" + +#: nova/api/ec2/cloud.py:811 +msgid "operation_type must be add or remove" +msgstr "" + +#: nova/api/ec2/cloud.py:812 +#, python-format +msgid "Updating image %s publicity" +msgstr "" + +#: nova/api/ec2/metadatarequesthandler.py:75 +#, python-format +msgid "Failed to get metadata for ip: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:70 +#, python-format +msgid "Caught error: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:86 +msgid "Including admin operations in API." +msgstr "" + +#: nova/api/openstack/servers.py:184 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:199 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: nova/api/openstack/servers.py:213 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:224 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: nova/api/openstack/servers.py:235 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: nova/api/openstack/servers.py:246 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: nova/api/openstack/servers.py:257 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: nova/auth/dbdriver.py:84 +#, python-format +msgid "User %s already exists" +msgstr "" + +#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#, python-format +msgid "Project can't be created because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#, python-format +msgid "Project can't be created because project %s already exists" +msgstr "" + +#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#, python-format +msgid "Project can't be modified because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:245 +#, python-format +msgid "User \"%s\" not found" +msgstr "" + +#: nova/auth/dbdriver.py:248 +#, python-format +msgid "Project \"%s\" not found" +msgstr "" + +#: nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "" + +#: nova/auth/ldapdriver.py:181 +#, python-format +msgid "LDAP object for %s doesn't exist" +msgstr "" + +#: nova/auth/ldapdriver.py:218 +#, python-format +msgid "Project can't be created because user %s doesn't exist" +msgstr "" + +#: nova/auth/ldapdriver.py:478 +#, python-format +msgid "User %s is already a member of the group %s" +msgstr "" + +#: nova/auth/ldapdriver.py:507 +#, python-format +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." +msgstr "" + +#: nova/auth/ldapdriver.py:528 +#, python-format +msgid "Group at dn %s doesn't exist" +msgstr "" + +#: nova/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "" + +#: nova/auth/manager.py:263 +#, python-format +msgid "Failed authorization for access key %s" +msgstr "" + +#: nova/auth/manager.py:264 +#, python-format +msgid "No user found for access key %s" +msgstr "" + +#: nova/auth/manager.py:270 +#, python-format +msgid "Using project name = user name (%s)" +msgstr "" + +#: nova/auth/manager.py:275 +#, python-format +msgid "failed authorization: no project named %s (user=%s)" +msgstr "" + +#: nova/auth/manager.py:277 +#, python-format +msgid "No project called %s could be found" +msgstr "" + +#: nova/auth/manager.py:281 +#, python-format +msgid "Failed authorization: user %s not admin and not member of project %s" +msgstr "" + +#: nova/auth/manager.py:283 +#, python-format +msgid "User %s is not a member of project %s" +msgstr "" + +#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#, python-format +msgid "Invalid signature for user %s" +msgstr "" + +#: nova/auth/manager.py:293 nova/auth/manager.py:304 +msgid "Signature does not match" +msgstr "" + +#: nova/auth/manager.py:374 +msgid "Must specify project" +msgstr "" + +#: nova/auth/manager.py:408 +#, python-format +msgid "The %s role can not be found" +msgstr "" + +#: nova/auth/manager.py:410 +#, python-format +msgid "The %s role is global only" +msgstr "" + +#: nova/auth/manager.py:412 +#, python-format +msgid "Adding role %s to user %s in project %s" +msgstr "" + +#: nova/auth/manager.py:438 +#, python-format +msgid "Removing role %s from user %s on project %s" +msgstr "" + +#: nova/auth/manager.py:505 +#, python-format +msgid "Created project %s with manager %s" +msgstr "" + +#: nova/auth/manager.py:523 +#, python-format +msgid "modifying project %s" +msgstr "" + +#: nova/auth/manager.py:553 +#, python-format +msgid "Remove user %s from project %s" +msgstr "" + +#: nova/auth/manager.py:581 +#, python-format +msgid "Deleting project %s" +msgstr "" + +#: nova/auth/manager.py:637 +#, python-format +msgid "Created user %s (admin: %r)" +msgstr "" + +#: nova/auth/manager.py:645 +#, python-format +msgid "Deleting user %s" +msgstr "" + +#: nova/auth/manager.py:655 +#, python-format +msgid "Access Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:657 +#, python-format +msgid "Secret Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:659 +#, python-format +msgid "Admin status set to %r for user %s" +msgstr "" + +#: nova/auth/manager.py:708 +#, python-format +msgid "No vpn data for project %s" +msgstr "" + +#: nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" +msgstr "" + +#: nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:97 +#, python-format +msgid "Launching VPN for %s" +msgstr "" + +#: nova/compute/api.py:67 +#, python-format +msgid "Instance %d was not found in get_network_topic" +msgstr "" + +#: nova/compute/api.py:73 +#, python-format +msgid "Instance %d has no host" +msgstr "" + +#: nova/compute/api.py:92 +#, python-format +msgid "Quota exceeeded for %s, tried to run %s instances" +msgstr "" + +#: nova/compute/api.py:94 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." +msgstr "" + +#: nova/compute/api.py:109 +msgid "Creating a raw instance" +msgstr "" + +#: nova/compute/api.py:156 +#, python-format +msgid "Going to run %s instances..." +msgstr "" + +#: nova/compute/api.py:180 +#, python-format +msgid "Casting to scheduler for %s/%s's instance %s" +msgstr "" + +#: nova/compute/api.py:279 +#, python-format +msgid "Going to try and terminate %s" +msgstr "" + +#: nova/compute/api.py:283 +#, python-format +msgid "Instance %d was not found during terminate" +msgstr "" + +#: nova/compute/api.py:288 +#, python-format +msgid "Instance %d is already being terminated" +msgstr "" + +#: nova/compute/api.py:450 +#, python-format +msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgstr "" + +#: nova/compute/api.py:465 +msgid "Volume isn't attached to anything!" +msgstr "" + +#: nova/compute/disk.py:71 +#, python-format +msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:75 +#, python-format +msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:128 +#, python-format +msgid "Could not attach image to loopback: %s" +msgstr "" + +#: nova/compute/disk.py:136 +#, python-format +msgid "Failed to load partition: %s" +msgstr "" + +#: nova/compute/disk.py:158 +#, python-format +msgid "Failed to mount filesystem: %s" +msgstr "" + +#: nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "" + +#: nova/compute/manager.py:69 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: nova/compute/manager.py:71 +#, python-format +msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgstr "" + +#: nova/compute/manager.py:75 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: nova/compute/manager.py:77 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: nova/compute/manager.py:82 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: nova/compute/manager.py:157 +msgid "Instance has already been created" +msgstr "" + +#: nova/compute/manager.py:158 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#: nova/compute/manager.py:197 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: nova/compute/manager.py:217 +#, python-format +msgid "Disassociating address %s" +msgstr "" + +#: nova/compute/manager.py:230 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: nova/compute/manager.py:243 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: nova/compute/manager.py:257 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: nova/compute/manager.py:260 +#, python-format +msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:286 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: nova/compute/manager.py:289 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:301 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: nova/compute/manager.py:316 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: nova/compute/manager.py:335 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: nova/compute/manager.py:352 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: nova/compute/manager.py:369 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: nova/compute/manager.py:382 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: nova/compute/manager.py:401 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: nova/compute/manager.py:420 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: nova/compute/manager.py:432 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: nova/compute/manager.py:442 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: nova/compute/manager.py:462 +#, python-format +msgid "instance %s: attaching volume %s to %s" +msgstr "" + +#: nova/compute/manager.py:478 +#, python-format +msgid "instance %s: attach failed %s, removing" +msgstr "" + +#: nova/compute/manager.py:493 +#, python-format +msgid "Detach volume %s from mountpoint %s on instance %s" +msgstr "" + +#: nova/compute/manager.py:497 +#, python-format +msgid "Detaching volume from unknown instance %s" +msgstr "" + +#: nova/compute/monitor.py:259 +#, python-format +msgid "updating %s..." +msgstr "" + +#: nova/compute/monitor.py:289 +msgid "unexpected error during update" +msgstr "" + +#: nova/compute/monitor.py:355 +#, python-format +msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:377 +#, python-format +msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:412 +msgid "unexpected exception getting connection" +msgstr "" + +#: nova/compute/monitor.py:427 +#, python-format +msgid "Found instance: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:43 +msgid "Use of empty request context is deprecated" +msgstr "" + +#: nova/db/sqlalchemy/api.py:132 +#, python-format +msgid "No service for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:229 +#, python-format +msgid "No service for %s, %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:574 +#, python-format +msgid "No floating ip for address %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:668 +#, python-format +msgid "No instance for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:758 nova/virt/libvirt_conn.py:598 +#: nova/virt/xenapi/volumeops.py:48 nova/virt/xenapi/volumeops.py:103 +#, python-format +msgid "Instance %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:891 +#, python-format +msgid "no keypair for user %s, name %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#, python-format +msgid "No network for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1036 +#, python-format +msgid "No network for bridge %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1050 +#, python-format +msgid "No network for instance %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1180 +#, python-format +msgid "Token %s does not exist" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1205 +#, python-format +msgid "No quota for project_id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1356 +#, python-format +msgid "No volume for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1401 +#, python-format +msgid "Volume %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1413 +#, python-format +msgid "No export device found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1426 +#, python-format +msgid "No target id found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1471 +#, python-format +msgid "No security group with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1488 +#, python-format +msgid "No security group named %s for project: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1576 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1650 +#, python-format +msgid "No user for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1666 +#, python-format +msgid "No user for access key %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1728 +#, python-format +msgid "No project with id %s" +msgstr "" + +#: nova/image/glance.py:78 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images" +msgstr "" + +#: nova/image/glance.py:97 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images/detail" +msgstr "" + +#: nova/image/s3.py:82 +#, python-format +msgid "Image %s could not be found" +msgstr "" + +#: nova/network/api.py:39 +#, python-format +msgid "Quota exceeeded for %s, tried to allocate address" +msgstr "" + +#: nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" +msgstr "" + +#: nova/network/linux_net.py:176 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: nova/network/linux_net.py:186 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#: nova/network/linux_net.py:254 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: nova/network/linux_net.py:256 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#: nova/network/linux_net.py:334 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: nova/network/manager.py:135 +msgid "setting network host" +msgstr "" + +#: nova/network/manager.py:190 +#, python-format +msgid "Leasing IP %s" +msgstr "" + +#: nova/network/manager.py:194 +#, python-format +msgid "IP %s leased that isn't associated" +msgstr "" + +#: nova/network/manager.py:197 +#, python-format +msgid "IP %s leased to bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:205 +#, python-format +msgid "IP %s leased that was already deallocated" +msgstr "" + +#: nova/network/manager.py:214 +#, python-format +msgid "IP %s released that isn't associated" +msgstr "" + +#: nova/network/manager.py:217 +#, python-format +msgid "IP %s released from bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:220 +#, python-format +msgid "IP %s released that was not leased" +msgstr "" + +#: nova/network/manager.py:442 +#, python-format +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "" + +#: nova/objectstore/handler.py:106 +#, python-format +msgid "Unknown S3 value type %r" +msgstr "" + +#: nova/objectstore/handler.py:137 +msgid "Authenticated request" +msgstr "" + +#: nova/objectstore/handler.py:182 +msgid "List of buckets requested" +msgstr "" + +#: nova/objectstore/handler.py:209 +#, python-format +msgid "List keys for bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:217 +#, python-format +msgid "Unauthorized attempt to access bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:235 +#, python-format +msgid "Creating bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:245 +#, python-format +msgid "Deleting bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:249 +#, python-format +msgid "Unauthorized attempt to delete bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:271 +#, python-format +msgid "Getting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:274 +#, python-format +msgid "Unauthorized attempt to get object %s from bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:292 +#, python-format +msgid "Putting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:295 +#, python-format +msgid "Unauthorized attempt to upload object %s to bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:314 +#, python-format +msgid "Deleting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:393 +#, python-format +msgid "Not authorized to upload image: invalid directory %s" +msgstr "" + +#: nova/objectstore/handler.py:401 +#, python-format +msgid "Not authorized to upload image: unauthorized bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:406 +#, python-format +msgid "Starting image upload: %s" +msgstr "" + +#: nova/objectstore/handler.py:420 +#, python-format +msgid "Not authorized to update attributes of image %s" +msgstr "" + +#: nova/objectstore/handler.py:428 +#, python-format +msgid "Toggling publicity flag of image %s %r" +msgstr "" + +#: nova/objectstore/handler.py:433 +#, python-format +msgid "Updating user fields on image %s" +msgstr "" + +#: nova/objectstore/handler.py:447 +#, python-format +msgid "Unauthorized attempt to delete image %s" +msgstr "" + +#: nova/objectstore/handler.py:452 +#, python-format +msgid "Deleted image: %s" +msgstr "" + +#: nova/scheduler/chance.py:37 nova/scheduler/simple.py:73 +#: nova/scheduler/simple.py:106 nova/scheduler/simple.py:118 +msgid "No hosts found" +msgstr "" + +#: nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "" + +#: nova/scheduler/manager.py:69 +#, python-format +msgid "Casting to %s %s for %s" +msgstr "" + +#: nova/scheduler/simple.py:63 +msgid "All hosts have too many cores" +msgstr "" + +#: nova/scheduler/simple.py:95 +msgid "All hosts have too many gigabytes" +msgstr "" + +#: nova/scheduler/simple.py:115 +msgid "All hosts have too many networks" +msgstr "" + +#: nova/tests/test_cloud.py:198 +msgid "Can't test instances without a real virtual env." +msgstr "" + +#: nova/tests/test_cloud.py:210 +#, python-format +msgid "Need to watch instance %s until it's running..." +msgstr "" + +#: nova/tests/test_compute.py:104 +#, python-format +msgid "Running instances: %s" +msgstr "" + +#: nova/tests/test_compute.py:110 +#, python-format +msgid "After terminating instances: %s" +msgstr "" + +#: nova/tests/test_rpc.py:89 +#, python-format +msgid "Nested received %s, %s" +msgstr "" + +#: nova/tests/test_rpc.py:94 +#, python-format +msgid "Nested return %s" +msgstr "" + +#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#, python-format +msgid "Received %s" +msgstr "" + +#: nova/tests/test_volume.py:162 +#, python-format +msgid "Target %s allocated" +msgstr "" + +#: nova/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "" + +#: nova/virt/fake.py:210 +#, python-format +msgid "Instance %s Not Found" +msgstr "" + +#: nova/virt/hyperv.py:118 +msgid "In init host" +msgstr "" + +#: nova/virt/hyperv.py:131 +#, python-format +msgid "Attempt to create duplicate vm %s" +msgstr "" + +#: nova/virt/hyperv.py:148 +#, python-format +msgid "Starting VM %s " +msgstr "" + +#: nova/virt/hyperv.py:150 +#, python-format +msgid "Started VM %s " +msgstr "" + +#: nova/virt/hyperv.py:152 +#, python-format +msgid "spawn vm failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:169 +#, python-format +msgid "Failed to create VM %s" +msgstr "" + +#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#, python-format +msgid "Created VM %s..." +msgstr "" + +#: nova/virt/hyperv.py:188 +#, python-format +msgid "Set memory for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:198 +#, python-format +msgid "Set vcpus for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:202 +#, python-format +msgid "Creating disk for %s by attaching disk file %s" +msgstr "" + +#: nova/virt/hyperv.py:227 +#, python-format +msgid "Failed to add diskdrive to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:230 +#, python-format +msgid "New disk drive path is %s" +msgstr "" + +#: nova/virt/hyperv.py:247 +#, python-format +msgid "Failed to add vhd file to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:249 +#, python-format +msgid "Created disk for %s" +msgstr "" + +#: nova/virt/hyperv.py:253 +#, python-format +msgid "Creating nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" +msgstr "" + +#: nova/virt/hyperv.py:273 +#, python-format +msgid "Failed creating port for %s" +msgstr "" + +#: nova/virt/hyperv.py:275 +#, python-format +msgid "Created switch port %s on switch %s" +msgstr "" + +#: nova/virt/hyperv.py:285 +#, python-format +msgid "Failed to add nic to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:287 +#, python-format +msgid "Created nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:320 +#, python-format +msgid "WMI job failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:322 +#, python-format +msgid "WMI job succeeded: %s, Elapsed=%s " +msgstr "" + +#: nova/virt/hyperv.py:358 +#, python-format +msgid "Got request to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:383 +#, python-format +msgid "Failed to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:389 +#, python-format +msgid "Del: disk %s vm %s" +msgstr "" + +#: nova/virt/hyperv.py:405 +#, python-format +msgid "" +"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " +"cpu_time=%s" +msgstr "" + +#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#, python-format +msgid "duplicate name found: %s" +msgstr "" + +#: nova/virt/hyperv.py:444 +#, python-format +msgid "Successfully changed vm state of %s to %s" +msgstr "" + +#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#, python-format +msgid "Failed to change vm state of %s to %s" +msgstr "" + +#: nova/virt/images.py:70 +#, python-format +msgid "Finished retreving %s -- placed in %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:144 +#, python-format +msgid "Connecting to libvirt: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:157 +msgid "Connection to libvirt broke" +msgstr "" + +#: nova/virt/libvirt_conn.py:229 +#, python-format +msgid "instance %s: deleting instance files %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:271 +#, python-format +msgid "No disk at %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:278 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "" + +#: nova/virt/libvirt_conn.py:294 +#, python-format +msgid "instance %s: rebooted" +msgstr "" + +#: nova/virt/libvirt_conn.py:297 +#, python-format +msgid "_wait_for_reboot failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:340 +#, python-format +msgid "instance %s: rescued" +msgstr "" + +#: nova/virt/libvirt_conn.py:343 +#, python-format +msgid "_wait_for_rescue failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:370 +#, python-format +msgid "instance %s: is running" +msgstr "" + +#: nova/virt/libvirt_conn.py:381 +#, python-format +msgid "instance %s: booted" +msgstr "" + +#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#, python-format +msgid "instance %s: failed to boot" +msgstr "" + +#: nova/virt/libvirt_conn.py:395 +#, python-format +msgid "virsh said: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:399 +msgid "cool, it's a device" +msgstr "" + +#: nova/virt/libvirt_conn.py:407 +#, python-format +msgid "data: %r, fpath: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:415 +#, python-format +msgid "Contents of file %s: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:449 +#, python-format +msgid "instance %s: Creating image" +msgstr "" + +#: nova/virt/libvirt_conn.py:505 +#, python-format +msgid "instance %s: injecting key into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:508 +#, python-format +msgid "instance %s: injecting net into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:516 +#, python-format +msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgstr "" + +#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#, python-format +msgid "instance %s: starting toXML method" +msgstr "" + +#: nova/virt/libvirt_conn.py:589 +#, python-format +msgid "instance %s: finished toXML method" +msgstr "" + +#: nova/virt/xenapi_conn.py:113 +msgid "" +"Must specify xenapi_connection_url, xenapi_connection_username (optionally), " +"and xenapi_connection_password to use connection_type=xenapi" +msgstr "" + +#: nova/virt/xenapi_conn.py:263 +#, python-format +msgid "Task [%s] %s status: success %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:271 +#, python-format +msgid "Task [%s] %s status: %s %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#, python-format +msgid "Got exception: %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:72 +#, python-format +msgid "%s: _db_content => %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:247 nova/virt/xenapi/fake.py:338 +#: nova/virt/xenapi/fake.py:356 nova/virt/xenapi/fake.py:404 +msgid "Raising NotImplemented" +msgstr "" + +#: nova/virt/xenapi/fake.py:249 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:283 +#, python-format +msgid "Calling %s %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:288 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:340 +#, python-format +msgid "" +"xenapi.fake does not have an implementation for %s or it has been called " +"with the wrong number of arguments" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:40 +#, python-format +msgid "Found non-unique network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:43 +#, python-format +msgid "Found no network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:127 +#, python-format +msgid "Created VM %s as %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:147 +#, python-format +msgid "Creating VBD for VM %s, VDI %s ... " +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:149 +#, python-format +msgid "Created VBD %s for VM %s, VDI %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:165 +#, python-format +msgid "VBD not found in instance %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:175 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:202 +#, python-format +msgid "Creating VIF for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:205 +#, python-format +msgid "Created VIF %s for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:216 +#, python-format +msgid "Snapshotting VM %s with label '%s'..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:229 +#, python-format +msgid "Created snapshot %s from VM %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:243 +#, python-format +msgid "Asking xapi to upload %s as '%s'" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:261 +#, python-format +msgid "Asking xapi to fetch %s as %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:279 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:290 +#, python-format +msgid "PV Kernel in VDI:%d" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:318 +#, python-format +msgid "VDI %s is still available" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:331 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:333 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:390 +#, python-format +msgid "VHD %s has parent %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:407 +#, python-format +msgid "Re-scanning SR %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:431 +#, python-format +msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:448 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:452 +#, python-format +msgid "Unexpected number of VDIs (%s) found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:62 +#, python-format +msgid "Attempted to create non-unique name %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:99 +#, python-format +msgid "Starting VM %s..." +msgstr "" + +#: nova/virt/xenapi/vmops.py:101 +#, python-format +msgid "Spawning VM %s created %s." +msgstr "" + +#: nova/virt/xenapi/vmops.py:112 +#, python-format +msgid "Instance %s: booted" +msgstr "" + +#: nova/virt/xenapi/vmops.py:137 +#, python-format +msgid "Instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:166 +#, python-format +msgid "Starting snapshot for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:174 +#, python-format +msgid "Unable to Snapshot %s: %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:184 +#, python-format +msgid "Finished snapshot and upload for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:252 +#, python-format +msgid "suspend: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:262 +#, python-format +msgid "resume: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:271 +#, python-format +msgid "Instance not found %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:57 +#, python-format +msgid "Introducing %s..." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:74 +#, python-format +msgid "Introduced %s as %s." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:90 +#, python-format +msgid "Unable to find SR from VBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:96 +#, python-format +msgid "Forgetting SR %s ... " +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:101 +#, python-format +msgid "Ignoring exception %s when getting PBDs for %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:107 +#, python-format +msgid "Ignoring exception %s when unplugging PBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:111 +#, python-format +msgid "Forgetting SR %s done." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:113 +#, python-format +msgid "Ignoring exception %s when forgetting SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:123 +#, python-format +msgid "Unable to introduce VDI on SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:128 +#, python-format +msgid "Unable to get record of VDI %s on" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:146 +#, python-format +msgid "Unable to introduce VDI for SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:175 +#, python-format +msgid "Unable to obtain target information %s, %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:197 +#, python-format +msgid "Mountpoint cannot be translated: %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:51 +#, python-format +msgid "Attach_volume: %s, %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:69 +#, python-format +msgid "Unable to create VDI on SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:81 +#, python-format +msgid "Unable to use SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Unable to attach volume to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:95 +#, python-format +msgid "Mountpoint %s attached to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:106 +#, python-format +msgid "Detach_volume: %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:113 +#, python-format +msgid "Unable to locate volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:121 +#, python-format +msgid "Unable to detach volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:128 +#, python-format +msgid "Mountpoint %s detached from instance %s" +msgstr "" + +#: nova/volume/api.py:44 +#, python-format +msgid "Quota exceeeded for %s, tried to create %sG volume" +msgstr "" + +#: nova/volume/api.py:46 +#, python-format +msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgstr "" + +#: nova/volume/api.py:70 nova/volume/api.py:95 +msgid "Volume status must be available" +msgstr "" + +#: nova/volume/api.py:97 +msgid "Volume is already attached" +msgstr "" + +#: nova/volume/api.py:103 +msgid "Volume is already detached" +msgstr "" + +#: nova/volume/driver.py:76 +#, python-format +msgid "Recovering from a failed execute. Try number %s" +msgstr "" + +#: nova/volume/driver.py:85 +#, python-format +msgid "volume group %s doesn't exist" +msgstr "" + +#: nova/volume/driver.py:210 +#, python-format +msgid "FAKE AOE: %s" +msgstr "" + +#: nova/volume/driver.py:315 +#, python-format +msgid "FAKE ISCSI: %s" +msgstr "" + +#: nova/volume/manager.py:85 +#, python-format +msgid "Re-exporting %s volumes" +msgstr "" + +#: nova/volume/manager.py:93 +#, python-format +msgid "volume %s: creating" +msgstr "" + +#: nova/volume/manager.py:102 +#, python-format +msgid "volume %s: creating lv of size %sG" +msgstr "" + +#: nova/volume/manager.py:106 +#, python-format +msgid "volume %s: creating export" +msgstr "" + +#: nova/volume/manager.py:113 +#, python-format +msgid "volume %s: created successfully" +msgstr "" + +#: nova/volume/manager.py:121 +msgid "Volume is still attached" +msgstr "" + +#: nova/volume/manager.py:123 +msgid "Volume is not local to this node" +msgstr "" + +#: nova/volume/manager.py:124 +#, python-format +msgid "volume %s: removing export" +msgstr "" + +#: nova/volume/manager.py:126 +#, python-format +msgid "volume %s: deleting" +msgstr "" + +#: nova/volume/manager.py:129 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "" diff --git a/locale/ja.po b/locale/ja.po new file mode 100644 index 00000000..919625e9 --- /dev/null +++ b/locale/ja.po @@ -0,0 +1,2143 @@ +# Japanese translation for nova +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the nova package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: nova\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"PO-Revision-Date: 2011-01-14 09:04+0000\n" +"Last-Translator: Koji Iida \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-01-28 05:20+0000\n" +"X-Generator: Launchpad (build 12177)\n" + +#: nova/crypto.py:46 +msgid "Filename of root CA" +msgstr "ルートCAのファイル名" + +#: nova/crypto.py:49 +msgid "Filename of private key" +msgstr "プライベートキーのファイル名" + +#: nova/crypto.py:51 +msgid "Filename of root Certificate Revokation List" +msgstr "ルート証明書失効リストのファイル名" + +#: nova/crypto.py:53 +msgid "Where we keep our keys" +msgstr "キーを格納するパス" + +#: nova/crypto.py:55 +msgid "Where we keep our root CA" +msgstr "ルートCAを格納するパス" + +#: nova/crypto.py:57 +msgid "Should we use a CA for each project?" +msgstr "プロジェクトごとにCAを使用するか否かのフラグ" + +#: nova/crypto.py:61 +#, python-format +msgid "Subject for certificate for users, %s for project, user, timestamp" +msgstr "ユーザの証明書のサブジェクト、%s はプロジェクト、ユーザ、タイムスタンプ" + +#: nova/crypto.py:66 +#, python-format +msgid "Subject for certificate for projects, %s for project, timestamp" +msgstr "プロジェクトの証明書のサブジェクト、%s はプロジェクト、およびタイムスタンプ" + +#: nova/crypto.py:71 +#, python-format +msgid "Subject for certificate for vpns, %s for project, timestamp" +msgstr "vpnの証明書のサブジェクト、%sはプロジェクト、およびタイムスタンプ" + +#: nova/crypto.py:258 +#, python-format +msgid "Flags path: %s" +msgstr "Flags のパス: %s" + +#: nova/exception.py:33 +msgid "Unexpected error while running command." +msgstr "コマンド実行において予期しないエラーが発生しました。" + +#: nova/exception.py:36 +#, python-format +msgid "" +"%s\n" +"Command: %s\n" +"Exit code: %s\n" +"Stdout: %r\n" +"Stderr: %r" +msgstr "" +"%s\n" +"コマンド: %s\n" +"終了コード: %s\n" +"標準出力: %r\n" +"標準エラー出力: %r" + +#: nova/exception.py:86 +msgid "Uncaught exception" +msgstr "キャッチされなかった例外" + +#: nova/fakerabbit.py:48 +#, python-format +msgid "(%s) publish (key: %s) %s" +msgstr "(%s) パブリッシュ (key: %s) %s" + +#: nova/fakerabbit.py:53 +#, python-format +msgid "Publishing to route %s" +msgstr "ルート %s へパブリッシュ" + +#: nova/fakerabbit.py:83 +#, python-format +msgid "Declaring queue %s" +msgstr "queue %s の宣言" + +#: nova/fakerabbit.py:89 +#, python-format +msgid "Declaring exchange %s" +msgstr "exchange %s の宣言" + +#: nova/fakerabbit.py:95 +#, python-format +msgid "Binding %s to %s with key %s" +msgstr "%s を %s にキー %s でバインドします。" + +#: nova/fakerabbit.py:120 +#, python-format +msgid "Getting from %s: %s" +msgstr "%s から %s を取得" + +#: nova/rpc.py:92 +#, python-format +msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgstr "AMQPサーバ %s:%d に接続できません。 %d 秒後に再度試みます。" + +#: nova/rpc.py:99 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "AMQPサーバーに %d 回接続を試みましたが、接続できませんでした。シャットダウンします。" + +#: nova/rpc.py:118 +msgid "Reconnected to queue" +msgstr "キューに再接続しました。" + +#: nova/rpc.py:125 +msgid "Failed to fetch message from queue" +msgstr "キューからメッセージの取得に失敗しました。" + +#: nova/rpc.py:155 +#, python-format +msgid "Initing the Adapter Consumer for %s" +msgstr "%sのアダプターコンシューマー(Adapter Consumer)を初期化しています。" + +#: nova/rpc.py:170 +#, python-format +msgid "received %s" +msgstr "受信: %s" + +#: nova/rpc.py:183 +#, python-format +msgid "no method for message: %s" +msgstr "メッセージ %s に対するメソッドが存在しません。" + +#: nova/rpc.py:184 +#, python-format +msgid "No method for message: %s" +msgstr "メッセージ %s に対するメソッドが存在しません。" + +#: nova/rpc.py:245 +#, python-format +msgid "Returning exception %s to caller" +msgstr "呼び出し元に 例外 %s を返却します。" + +#: nova/rpc.py:286 +#, python-format +msgid "unpacked context: %s" +msgstr "context %s をアンパックしました。" + +#: nova/rpc.py:305 +msgid "Making asynchronous call..." +msgstr "非同期呼び出しを実行します…" + +#: nova/rpc.py:308 +#, python-format +msgid "MSG_ID is %s" +msgstr "MSG_IDは %s です。" + +#: nova/rpc.py:356 +#, python-format +msgid "response %s" +msgstr "応答 %s" + +#: nova/rpc.py:365 +#, python-format +msgid "topic is %s" +msgstr "topic は %s です。" + +#: nova/rpc.py:366 +#, python-format +msgid "message %s" +msgstr "メッセージ %s" + +#: nova/service.py:157 +#, python-format +msgid "Starting %s node" +msgstr "ノード %s を開始します。" + +#: nova/service.py:169 +msgid "Service killed that has no database entry" +msgstr "データベースにエントリの存在しないサービスを終了します。" + +#: nova/service.py:190 +msgid "The service database object disappeared, Recreating it." +msgstr "サービスデータベースオブジェクトが消滅しました。再作成します。" + +#: nova/service.py:202 +msgid "Recovered model server connection!" +msgstr "モデルサーバへの接続を復旧しました。" + +#: nova/service.py:208 +msgid "model server went away" +msgstr "モデルサーバが消滅しました。" + +#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#, python-format +msgid "Data store %s is unreachable. Trying again in %d seconds." +msgstr "データストア %s に接続できません。 %d 秒後に再接続します。" + +#: nova/service.py:232 nova/twistd.py:232 +#, python-format +msgid "Serving %s" +msgstr "%s サービスの開始" + +#: nova/service.py:234 nova/twistd.py:264 +msgid "Full set of FLAGS:" +msgstr "FLAGSの一覧:" + +#: nova/twistd.py:211 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "pidfile %s が存在しません。デーモンは実行中ですか?\n" + +#: nova/twistd.py:268 +#, python-format +msgid "Starting %s" +msgstr "%s を開始します。" + +#: nova/utils.py:53 +#, python-format +msgid "Inner Exception: %s" +msgstr "内側で発生した例外: %s" + +#: nova/utils.py:54 +#, python-format +msgid "Class %s cannot be found" +msgstr "クラス %s が見つかりません。" + +#: nova/utils.py:113 +#, python-format +msgid "Fetching %s" +msgstr "ファイルをフェッチ: %s" + +#: nova/utils.py:125 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "コマンド実行(subprocess): %s" + +#: nova/utils.py:138 +#, python-format +msgid "Result was %s" +msgstr "コマンド実行結果: %s" + +#: nova/utils.py:171 +#, python-format +msgid "debug in callback: %s" +msgstr "コールバック中のデバッグ: %s" + +#: nova/utils.py:176 +#, python-format +msgid "Running %s" +msgstr "コマンド実行: %s" + +#: nova/utils.py:207 +#, python-format +msgid "Couldn't get IP, using 127.0.0.1 %s" +msgstr "IPを取得できません。127.0.0.1 を %s として使います。" + +#: nova/utils.py:289 +#, python-format +msgid "Invalid backend: %s" +msgstr "不正なバックエンドです: %s" + +#: nova/utils.py:300 +#, python-format +msgid "backend %s" +msgstr "バックエンドは %s です。" + +#: nova/api/ec2/__init__.py:133 +msgid "Too many failed authentications." +msgstr "認証失敗の回数が多すぎます。" + +#: nova/api/ec2/__init__.py:142 +#, python-format +msgid "" +"Access key %s has had %d failed authentications and will be locked out for " +"%d minutes." +msgstr "アクセスキー %s は %d 回認証に失敗したため、%d 分間ロックされます。" + +#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#, python-format +msgid "Authentication Failure: %s" +msgstr "%s の認証に失敗しました。" + +#: nova/api/ec2/__init__.py:190 +#, python-format +msgid "Authenticated Request For %s:%s)" +msgstr "リクエストを認証しました: %s:%s" + +#: nova/api/ec2/__init__.py:227 +#, python-format +msgid "action: %s" +msgstr "アクション(action): %s" + +#: nova/api/ec2/__init__.py:229 +#, python-format +msgid "arg: %s\t\tval: %s" +msgstr "引数(arg): %s\t値(val): %s" + +#: nova/api/ec2/__init__.py:301 +#, python-format +msgid "Unauthorized request for controller=%s and action=%s" +msgstr "許可されていないリクエスト: controller=%s, action %sです。" + +#: nova/api/ec2/__init__.py:339 +#, python-format +msgid "NotFound raised: %s" +msgstr "NotFound 発生: %s" + +#: nova/api/ec2/__init__.py:342 +#, python-format +msgid "ApiError raised: %s" +msgstr "APIエラー発生: %s" + +#: nova/api/ec2/__init__.py:349 +#, python-format +msgid "Unexpected error raised: %s" +msgstr "予期しないエラー発生: %s" + +#: nova/api/ec2/__init__.py:354 +msgid "An unknown error has occurred. Please try your request again." +msgstr "未知のエラーが発生しました。再度リクエストを実行してください。" + +#: nova/api/ec2/admin.py:84 +#, python-format +msgid "Creating new user: %s" +msgstr "Creating new user: 新しいユーザ %s を作成します。" + +#: nova/api/ec2/admin.py:92 +#, python-format +msgid "Deleting user: %s" +msgstr "Deleting user: ユーザ %s を削除します。" + +#: nova/api/ec2/admin.py:114 +#, python-format +msgid "Adding role %s to user %s for project %s" +msgstr "Adding role: ロール %s をユーザ %s、プロジェクト %s に追加します。" + +#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#, python-format +msgid "Adding sitewide role %s to user %s" +msgstr "Adding sitewide role: サイトワイドのロール %s をユーザ %s に追加します。" + +#: nova/api/ec2/admin.py:122 +#, python-format +msgid "Removing role %s from user %s for project %s" +msgstr "Removing role: ロール %s をユーザ %s プロジェクト %s から削除します。" + +#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#, python-format +msgid "Removing sitewide role %s from user %s" +msgstr "Removing sitewide role: サイトワイドのロール %s をユーザ %s から削除します。" + +#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 +msgid "operation must be add or remove" +msgstr "operation は add または remove の何れかである必要があります。" + +#: nova/api/ec2/admin.py:142 +#, python-format +msgid "Getting x509 for user: %s on project: %s" +msgstr "Getting X509: x509の取得: ユーザ %s, プロジェクト %s" + +#: nova/api/ec2/admin.py:159 +#, python-format +msgid "Create project %s managed by %s" +msgstr "Create project: プロジェクト %s (%s により管理される)を作成します。" + +#: nova/api/ec2/admin.py:170 +#, python-format +msgid "Delete project: %s" +msgstr "Delete project: プロジェクト %s を削除しました。" + +#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#, python-format +msgid "Adding user %s to project %s" +msgstr "Adding user: ユーザ %s をプロジェクト %s に追加します。" + +#: nova/api/ec2/admin.py:188 +#, python-format +msgid "Removing user %s from project %s" +msgstr "Removing user: ユーザ %s をプロジェクト %s から削除します。" + +#: nova/api/ec2/apirequest.py:95 +#, python-format +msgid "Unsupported API request: controller = %s,action = %s" +msgstr "サポートされていないAPIリクエストです。 controller = %s,action = %s" + +#: nova/api/ec2/cloud.py:117 +#, python-format +msgid "Generating root CA: %s" +msgstr "ルートCA %s を生成しています。" + +#: nova/api/ec2/cloud.py:277 +#, python-format +msgid "Create key pair %s" +msgstr "Create key pair: キーペア %s を作成します。" + +#: nova/api/ec2/cloud.py:285 +#, python-format +msgid "Delete key pair %s" +msgstr "Delete key pair: キーペア %s を削除します。" + +#: nova/api/ec2/cloud.py:357 +#, python-format +msgid "%s is not a valid ipProtocol" +msgstr "%s は適切なipProtocolではありません。" + +#: nova/api/ec2/cloud.py:361 +msgid "Invalid port range" +msgstr "ポートの範囲が不正です。" + +#: nova/api/ec2/cloud.py:392 +#, python-format +msgid "Revoke security group ingress %s" +msgstr "Revoke security group ingress: セキュリティグループ許可 %s の取消" + +#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 +msgid "No rule for the specified parameters." +msgstr "指定されたパラメータに該当するルールがありません。" + +#: nova/api/ec2/cloud.py:421 +#, python-format +msgid "Authorize security group ingress %s" +msgstr "Authorize security group ingress: セキュリティグループ許可 %s" + +#: nova/api/ec2/cloud.py:432 +#, python-format +msgid "This rule already exists in group %s" +msgstr "指定されたルールは既にグループ %s に存在しています。" + +#: nova/api/ec2/cloud.py:460 +#, python-format +msgid "Create Security Group %s" +msgstr "Create Security Group: セキュリティグループ %s を作成します。" + +#: nova/api/ec2/cloud.py:463 +#, python-format +msgid "group %s already exists" +msgstr "グループ %s は既に存在しています。" + +#: nova/api/ec2/cloud.py:475 +#, python-format +msgid "Delete security group %s" +msgstr "Delete security group: セキュリティグループ %s を削除します。" + +#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#, python-format +msgid "Get console output for instance %s" +msgstr "Get console output: インスタンス %s のコンソール出力を取得します。" + +#: nova/api/ec2/cloud.py:543 +#, python-format +msgid "Create volume of %s GB" +msgstr "Create volume: %s GBのボリュームを作成します。" + +#: nova/api/ec2/cloud.py:567 +#, python-format +msgid "Attach volume %s to instacne %s at %s" +msgstr "Attach volume: ボリューム%s をインスタンス %s にデバイス %s でアタッチします。" + +#: nova/api/ec2/cloud.py:579 +#, python-format +msgid "Detach volume %s" +msgstr "Detach volume: ボリューム %s をデタッチします" + +#: nova/api/ec2/cloud.py:686 +msgid "Allocate address" +msgstr "Allocate address: アドレスを割り当てます。" + +#: nova/api/ec2/cloud.py:691 +#, python-format +msgid "Release address %s" +msgstr "Release address: アドレス %s を開放します。" + +#: nova/api/ec2/cloud.py:696 +#, python-format +msgid "Associate address %s to instance %s" +msgstr "Associate address: アドレス %s をインスタンス %s に関連付けます。" + +#: nova/api/ec2/cloud.py:703 +#, python-format +msgid "Disassociate address %s" +msgstr "Disassociate address: アドレス %s の関連付けを解除します。" + +#: nova/api/ec2/cloud.py:730 +msgid "Going to start terminating instances" +msgstr "インスタンス終了処理を開始します。" + +#: nova/api/ec2/cloud.py:738 +#, python-format +msgid "Reboot instance %r" +msgstr "Reboot instance: インスタンス %r を再起動します。" + +#: nova/api/ec2/cloud.py:775 +#, python-format +msgid "De-registering image %s" +msgstr "De-registering image: イメージ %s を登録解除します。" + +#: nova/api/ec2/cloud.py:783 +#, python-format +msgid "Registered image %s with id %s" +msgstr "Registered image: イメージ %s をid %s で登録します。" + +#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#, python-format +msgid "attribute not supported: %s" +msgstr "アトリビュート %s はサポートされていません。" + +#: nova/api/ec2/cloud.py:794 +#, python-format +msgid "invalid id: %s" +msgstr "id %s は不正です。" + +#: nova/api/ec2/cloud.py:807 +msgid "user or group not specified" +msgstr "ユーザまたはグループが指定されていません。" + +#: nova/api/ec2/cloud.py:809 +msgid "only group \"all\" is supported" +msgstr "グループ \"all\" のみサポートされています。" + +#: nova/api/ec2/cloud.py:811 +msgid "operation_type must be add or remove" +msgstr "operation_type は add または remove の何れかである必要があります。" + +#: nova/api/ec2/cloud.py:812 +#, python-format +msgid "Updating image %s publicity" +msgstr "イメージ %s の公開設定を更新します。" + +#: nova/api/ec2/metadatarequesthandler.py:75 +#, python-format +msgid "Failed to get metadata for ip: %s" +msgstr "ip %s に対するメタデータの取得に失敗しました。" + +#: nova/api/openstack/__init__.py:70 +#, python-format +msgid "Caught error: %s" +msgstr "エラー %s をキャッチしました。" + +#: nova/api/openstack/__init__.py:86 +msgid "Including admin operations in API." +msgstr "管理用オペレーション(admin operation)をAPIに登録します。" + +#: nova/api/openstack/servers.py:184 +#, python-format +msgid "Compute.api::lock %s" +msgstr "例外: Compute.api::lock %s" + +#: nova/api/openstack/servers.py:199 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "例外: Compute.api::unlock %s" + +#: nova/api/openstack/servers.py:213 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "例外: Compute.api::get_lock %s" + +#: nova/api/openstack/servers.py:224 +#, python-format +msgid "Compute.api::pause %s" +msgstr "例外: Compute.api::pause %s" + +#: nova/api/openstack/servers.py:235 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "例外: Compute.api::unpause %s" + +#: nova/api/openstack/servers.py:246 +#, python-format +msgid "compute.api::suspend %s" +msgstr "例外: compute.api::suspend %s" + +#: nova/api/openstack/servers.py:257 +#, python-format +msgid "compute.api::resume %s" +msgstr "例外: compute.api::resume %s" + +#: nova/auth/dbdriver.py:84 +#, python-format +msgid "User %s already exists" +msgstr "ユーザー %s は既に存在しています。" + +#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#, python-format +msgid "Project can't be created because manager %s doesn't exist" +msgstr "マネージャ %s が存在しないためプロジェクトを作成できません。" + +#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#, python-format +msgid "Project can't be created because project %s already exists" +msgstr "プロジェクト %s が既に存在するためプロジェクトを作成できません。" + +#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#, python-format +msgid "Project can't be modified because manager %s doesn't exist" +msgstr "マネージャ %s が存在しないためプロジェクトを更新できません。" + +#: nova/auth/dbdriver.py:245 +#, python-format +msgid "User \"%s\" not found" +msgstr "ユーザ \"%s\" が見つかりません。" + +#: nova/auth/dbdriver.py:248 +#, python-format +msgid "Project \"%s\" not found" +msgstr "プロジェクト \"%s\" が見つかりません。" + +#: nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "シングルトンをインスタンス化しようとしました。" + +#: nova/auth/ldapdriver.py:181 +#, python-format +msgid "LDAP object for %s doesn't exist" +msgstr "LDAPオブジェクト %s が存在しません。" + +#: nova/auth/ldapdriver.py:218 +#, python-format +msgid "Project can't be created because user %s doesn't exist" +msgstr "ユーザ %s が存在しないためプロジェクトを作成できません。" + +#: nova/auth/ldapdriver.py:478 +#, python-format +msgid "User %s is already a member of the group %s" +msgstr "ユーザ %s は既にグループ %s のメンバーです。" + +#: nova/auth/ldapdriver.py:507 +#, python-format +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." +msgstr "グループの最後のメンバーを削除しようとしました。代わりにグループ %s を削除してください。" + +#: nova/auth/ldapdriver.py:528 +#, python-format +msgid "Group at dn %s doesn't exist" +msgstr "dnが %s のグループは存在しません。" + +#: nova/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "ユーザ %r を検索します。" + +#: nova/auth/manager.py:263 +#, python-format +msgid "Failed authorization for access key %s" +msgstr "Failed authorization: アクセスキー %s の認証に失敗しました。" + +#: nova/auth/manager.py:264 +#, python-format +msgid "No user found for access key %s" +msgstr "アクセスキー %s に対するユーザが見つかりませんでした。" + +#: nova/auth/manager.py:270 +#, python-format +msgid "Using project name = user name (%s)" +msgstr "ユーザ名 (%s) をプロジェクト名として使用します。" + +#: nova/auth/manager.py:275 +#, python-format +msgid "failed authorization: no project named %s (user=%s)" +msgstr "Failed authorization: 認証に失敗しました。プロジェクト名 %s (ユーザ = %s) は存在しません。" + +#: nova/auth/manager.py:277 +#, python-format +msgid "No project called %s could be found" +msgstr "プロジェクト %s は見つかりませんでした。" + +#: nova/auth/manager.py:281 +#, python-format +msgid "Failed authorization: user %s not admin and not member of project %s" +msgstr "" +"Failed authorization: 認証に失敗しました: ユーザ %s は管理者ではなくかつプロジェクト %s のメンバーではありません。" + +#: nova/auth/manager.py:283 +#, python-format +msgid "User %s is not a member of project %s" +msgstr "ユーザ %s はプロジェクト %s のメンバーではありません。" + +#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#, python-format +msgid "Invalid signature for user %s" +msgstr "Invalid signature: ユーザ %s の署名が不正です。" + +#: nova/auth/manager.py:293 nova/auth/manager.py:304 +msgid "Signature does not match" +msgstr "署名が一致しません。" + +#: nova/auth/manager.py:374 +msgid "Must specify project" +msgstr "プロジェクトを指定してください。" + +#: nova/auth/manager.py:408 +#, python-format +msgid "The %s role can not be found" +msgstr "ロール %s が見つかりません。" + +#: nova/auth/manager.py:410 +#, python-format +msgid "The %s role is global only" +msgstr "ロール %s はグローバルでのみ使用可能です。" + +#: nova/auth/manager.py:412 +#, python-format +msgid "Adding role %s to user %s in project %s" +msgstr "Adding role: ロール %s をユーザ %s (プロジェクト %s の) に追加します。" + +#: nova/auth/manager.py:438 +#, python-format +msgid "Removing role %s from user %s on project %s" +msgstr "Removing role: ロール %s をユーザ %s (プロジェクト %s の)から削除します。" + +#: nova/auth/manager.py:505 +#, python-format +msgid "Created project %s with manager %s" +msgstr "Created project: プロジェクト %s (マネージャ %s)を作成します。" + +#: nova/auth/manager.py:523 +#, python-format +msgid "modifying project %s" +msgstr "modifying project: プロジェクト %s を更新します。" + +#: nova/auth/manager.py:553 +#, python-format +msgid "Remove user %s from project %s" +msgstr "Remove user: ユーザ %s をプロジェクト %s から削除します。" + +#: nova/auth/manager.py:581 +#, python-format +msgid "Deleting project %s" +msgstr "Deleting project: プロジェクト %s を削除します。" + +#: nova/auth/manager.py:637 +#, python-format +msgid "Created user %s (admin: %r)" +msgstr "Created user: ユーザ %s (admin: %r) を作成しました。" + +#: nova/auth/manager.py:645 +#, python-format +msgid "Deleting user %s" +msgstr "Deleting user: ユーザ %s を削除します。" + +#: nova/auth/manager.py:655 +#, python-format +msgid "Access Key change for user %s" +msgstr "Access Key change: ユーザ %s のアクセスキーを更新します。" + +#: nova/auth/manager.py:657 +#, python-format +msgid "Secret Key change for user %s" +msgstr "Secret Key change: ユーザ %s のシークレットキーを更新します。" + +#: nova/auth/manager.py:659 +#, python-format +msgid "Admin status set to %r for user %s" +msgstr "Admin status set: 管理者ステータス %r をユーザ %s に設定します。" + +#: nova/auth/manager.py:708 +#, python-format +msgid "No vpn data for project %s" +msgstr "プロジェクト %s に関するvpnデータがありません。" + +#: nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" +msgstr "cloudpipeインスタンス起動時に実行するスクリプトのテンプレート" + +#: nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" +msgstr "openvpnの設定に入れるネットワークの値" + +#: nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" +msgstr "openvpnの設定に入れるネットマスクの値" + +#: nova/cloudpipe/pipelib.py:97 +#, python-format +msgid "Launching VPN for %s" +msgstr "%s 用のVPNを起動します。" + +#: nova/compute/api.py:67 +#, python-format +msgid "Instance %d was not found in get_network_topic" +msgstr "get_network_topicにおいてインスタンス %d が見つかりませんでした。" + +#: nova/compute/api.py:73 +#, python-format +msgid "Instance %d has no host" +msgstr "インスタンス %d にホストが登録されていません。" + +#: nova/compute/api.py:92 +#, python-format +msgid "Quota exceeeded for %s, tried to run %s instances" +msgstr "%s のクオータ上限を超えました。%s インスタンスを実行しようとしました。" + +#: nova/compute/api.py:94 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." +msgstr "インスタンスのクオータを超えました。このタイプにおいてはあと %s インスタンスしか実行できません。" + +#: nova/compute/api.py:109 +msgid "Creating a raw instance" +msgstr "raw instanceを生成します。" + +#: nova/compute/api.py:156 +#, python-format +msgid "Going to run %s instances..." +msgstr "%s 個のインスタンスの起動を始めます…" + +#: nova/compute/api.py:180 +#, python-format +msgid "Casting to scheduler for %s/%s's instance %s" +msgstr "スケジューラに対して %s/%s のインスタンス %s を送信します。" + +#: nova/compute/api.py:279 +#, python-format +msgid "Going to try and terminate %s" +msgstr "%s を終了します。" + +#: nova/compute/api.py:283 +#, python-format +msgid "Instance %d was not found during terminate" +msgstr "インスタンス %d が終了処理において見つかりませんでした。" + +#: nova/compute/api.py:288 +#, python-format +msgid "Instance %d is already being terminated" +msgstr "インスタンス %d は既に終了済みです。" + +#: nova/compute/api.py:450 +#, python-format +msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgstr "デバイスの指定 %s が不正です: デバイス指定の例: /dev/vdb" + +#: nova/compute/api.py:465 +msgid "Volume isn't attached to anything!" +msgstr "ボリュームはどこにもアタッチされていません。" + +#: nova/compute/disk.py:71 +#, python-format +msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgstr "インプットパーティションサイズがセクターサイズで割り切れません。 %d / %d" + +#: nova/compute/disk.py:75 +#, python-format +msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgstr "ローカルストレージのバイト数がセクターサイズで割り切れません: %d / %d" + +#: nova/compute/disk.py:128 +#, python-format +msgid "Could not attach image to loopback: %s" +msgstr "イメージをループバック %s にアタッチできません。" + +#: nova/compute/disk.py:136 +#, python-format +msgid "Failed to load partition: %s" +msgstr "パーティション %s のロードに失敗しました。" + +#: nova/compute/disk.py:158 +#, python-format +msgid "Failed to mount filesystem: %s" +msgstr "ファイルシステム %s のマウントに失敗しました。" + +#: nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "%s は未知のインスタンスタイプです。" + +#: nova/compute/manager.py:69 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "check_instance_lock: decorating: |%s|" + +#: nova/compute/manager.py:71 +#, python-format +msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgstr "check_instance_lock: arguments: |%s| |%s| |%s|" + +#: nova/compute/manager.py:75 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "check_instance_lock: locked: |%s|" + +#: nova/compute/manager.py:77 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "check_instance_lock: admin: |%s|" + +#: nova/compute/manager.py:82 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "check_instance_lock: executing: |%s|" + +#: nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "check_instance_lock: not executing |%s|" + +#: nova/compute/manager.py:157 +msgid "Instance has already been created" +msgstr "インスタンスは既に生成されています。" + +#: nova/compute/manager.py:158 +#, python-format +msgid "instance %s: starting..." +msgstr "インスタンス %s を開始します。" + +#: nova/compute/manager.py:197 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "インスタンス %s の起動に失敗しました。" + +#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#, python-format +msgid "Terminating instance %s" +msgstr "Terminating instance: インスタンス %s を終了します。" + +#: nova/compute/manager.py:217 +#, python-format +msgid "Disassociating address %s" +msgstr "アドレス %s の関連付けを解除(disassociate)しています。" + +#: nova/compute/manager.py:230 +#, python-format +msgid "Deallocating address %s" +msgstr "アドレス %s の割当を解除(deallocate)します。" + +#: nova/compute/manager.py:243 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "既に消去済みのインスタンス%sを消去しようとしました。" + +#: nova/compute/manager.py:257 +#, python-format +msgid "Rebooting instance %s" +msgstr "Rebooting instance: インスタンス %s を再起動します。" + +#: nova/compute/manager.py:260 +#, python-format +msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgstr "実行していないインスタンスの再起動を試みます。%s (状態: %s 期待する状態: %s)" + +#: nova/compute/manager.py:286 +#, python-format +msgid "instance %s: snapshotting" +msgstr "snapshotting: インスタンス %s のスナップショットを取得します。" + +#: nova/compute/manager.py:289 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgstr "実行していないインスタンスのスナップショット取得を試みます。%s (状態: %s 期待する状態: %s)" + +#: nova/compute/manager.py:301 +#, python-format +msgid "instance %s: rescuing" +msgstr "Rescuing: インスタンス %s をレスキューします。" + +#: nova/compute/manager.py:316 +#, python-format +msgid "instance %s: unrescuing" +msgstr "Unrescuing: インスタンス %s をアンレスキューします。" + +#: nova/compute/manager.py:335 +#, python-format +msgid "instance %s: pausing" +msgstr "pausing: インスタンス %s を一時停止します。" + +#: nova/compute/manager.py:352 +#, python-format +msgid "instance %s: unpausing" +msgstr "unpausing: インスタンス %s の一時停止を解除します。" + +#: nova/compute/manager.py:369 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "retrieving diagnostics: インスタンス %s の診断情報を取得します。" + +#: nova/compute/manager.py:382 +#, python-format +msgid "instance %s: suspending" +msgstr "suspending: インスタンス %s をサスペンドします。" + +#: nova/compute/manager.py:401 +#, python-format +msgid "instance %s: resuming" +msgstr "resuming: インスタンス %s をレジュームします。" + +#: nova/compute/manager.py:420 +#, python-format +msgid "instance %s: locking" +msgstr "locking: インスタンス %s をロックします。" + +#: nova/compute/manager.py:432 +#, python-format +msgid "instance %s: unlocking" +msgstr "unlocking: インスタンス %s のロックを解除します。" + +#: nova/compute/manager.py:442 +#, python-format +msgid "instance %s: getting locked state" +msgstr "getting locked state: インスタンス %s のロックを取得しました。" + +#: nova/compute/manager.py:462 +#, python-format +msgid "instance %s: attaching volume %s to %s" +msgstr "attaching volume: インスタンス %s についてボリューム %s を %s にアタッチします。" + +#: nova/compute/manager.py:478 +#, python-format +msgid "instance %s: attach failed %s, removing" +msgstr "インスタンス %s: %sのアタッチに失敗しました。リムーブします。" + +#: nova/compute/manager.py:493 +#, python-format +msgid "Detach volume %s from mountpoint %s on instance %s" +msgstr "Detach volume: ボリューム %s をマウントポイント %s (インスタンス%s)からデタッチします。" + +#: nova/compute/manager.py:497 +#, python-format +msgid "Detaching volume from unknown instance %s" +msgstr "ボリュームを未知のインスタンス %s からデタッチします。" + +#: nova/compute/monitor.py:259 +#, python-format +msgid "updating %s..." +msgstr "%s の情報の更新…" + +#: nova/compute/monitor.py:289 +msgid "unexpected error during update" +msgstr "更新の最中に予期しないエラーが発生しました。" + +#: nova/compute/monitor.py:355 +#, python-format +msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgstr "ブロックデバイス \"%s\" の統計を \"%s\" について取得できません。" + +#: nova/compute/monitor.py:377 +#, python-format +msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgstr "インタフェース \"%s\" の統計を \"%s\" について取得できません。" + +#: nova/compute/monitor.py:412 +msgid "unexpected exception getting connection" +msgstr "接続に際し予期しないエラーが発生しました。" + +#: nova/compute/monitor.py:427 +#, python-format +msgid "Found instance: %s" +msgstr "インスタンス %s が見つかりました。" + +#: nova/db/sqlalchemy/api.py:43 +msgid "Use of empty request context is deprecated" +msgstr "Request context を空とすることは非推奨です。" + +#: nova/db/sqlalchemy/api.py:132 +#, python-format +msgid "No service for id %s" +msgstr "id %s のserviceが存在しません。" + +#: nova/db/sqlalchemy/api.py:229 +#, python-format +msgid "No service for %s, %s" +msgstr "%s, %s のserviceが存在しません。" + +#: nova/db/sqlalchemy/api.py:574 +#, python-format +msgid "No floating ip for address %s" +msgstr "アドレス %s の floating ip が存在しません。" + +#: nova/db/sqlalchemy/api.py:668 +#, python-format +msgid "No instance for id %s" +msgstr "id %s のinstanceが存在しません。" + +#: nova/db/sqlalchemy/api.py:758 nova/virt/libvirt_conn.py:598 +#: nova/virt/xenapi/volumeops.py:48 nova/virt/xenapi/volumeops.py:103 +#, python-format +msgid "Instance %s not found" +msgstr "インスタンス %s が見つかりません。" + +#: nova/db/sqlalchemy/api.py:891 +#, python-format +msgid "no keypair for user %s, name %s" +msgstr "ユーザ %s, ネーム%s に該当するキーペアが存在しません。" + +#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#, python-format +msgid "No network for id %s" +msgstr "id %s に該当するnetwork が存在しません。" + +#: nova/db/sqlalchemy/api.py:1036 +#, python-format +msgid "No network for bridge %s" +msgstr "ブリッジ %s に該当する network が存在しません。" + +#: nova/db/sqlalchemy/api.py:1050 +#, python-format +msgid "No network for instance %s" +msgstr "instance %s に該当する network が存在しません。" + +#: nova/db/sqlalchemy/api.py:1180 +#, python-format +msgid "Token %s does not exist" +msgstr "トークン %s が存在しません。" + +#: nova/db/sqlalchemy/api.py:1205 +#, python-format +msgid "No quota for project_id %s" +msgstr "project_id %s に対するクオータが存在しません。" + +#: nova/db/sqlalchemy/api.py:1356 +#, python-format +msgid "No volume for id %s" +msgstr "id %s に該当するボリュームが存在しません。" + +#: nova/db/sqlalchemy/api.py:1401 +#, python-format +msgid "Volume %s not found" +msgstr "ボリューム %s が見つかりません。" + +#: nova/db/sqlalchemy/api.py:1413 +#, python-format +msgid "No export device found for volume %s" +msgstr "ボリューム %s に関してエクスポートされているデバイスがありません。" + +#: nova/db/sqlalchemy/api.py:1426 +#, python-format +msgid "No target id found for volume %s" +msgstr "ボリューム %s に対する target idが存在しません。" + +#: nova/db/sqlalchemy/api.py:1471 +#, python-format +msgid "No security group with id %s" +msgstr "id %s のセキュリティグループが存在しません。" + +#: nova/db/sqlalchemy/api.py:1488 +#, python-format +msgid "No security group named %s for project: %s" +msgstr "セキュリティグループ名 %s がプロジェクト %s に存在しません。" + +#: nova/db/sqlalchemy/api.py:1576 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "id %s のセキュリティグループルールが存在しません。" + +#: nova/db/sqlalchemy/api.py:1650 +#, python-format +msgid "No user for id %s" +msgstr "id %s のユーザが存在しません。" + +#: nova/db/sqlalchemy/api.py:1666 +#, python-format +msgid "No user for access key %s" +msgstr "アクセスキー %s に該当するユーザが存在しません。" + +#: nova/db/sqlalchemy/api.py:1728 +#, python-format +msgid "No project with id %s" +msgstr "id %s のプロジェクトが存在しません。" + +#: nova/image/glance.py:78 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images" +msgstr "Parallax がHTTPエラー%d を /images に対するリクエストに対して返しました。" + +#: nova/image/glance.py:97 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images/detail" +msgstr "Parallax がHTTPエラー %d を /images/detail に対するリクエストに対して返しました" + +#: nova/image/s3.py:82 +#, python-format +msgid "Image %s could not be found" +msgstr "イメージ %s が見つかりませんでした。" + +#: nova/network/api.py:39 +#, python-format +msgid "Quota exceeeded for %s, tried to allocate address" +msgstr "アドレスを割り当てようとしましたが、%s のクオータを超えました。" + +#: nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" +msgstr "アドレスのクオータを超えました。これ以上アドレスを割り当てることはできません。" + +#: nova/network/linux_net.py:176 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "VLANインタフェース %s を開始します。" + +#: nova/network/linux_net.py:186 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "%s 用のブリッジインタフェースを開始します。" + +#: nova/network/linux_net.py:254 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "dnsmasqに対してhupを送信しましたが %s が発生しました。" + +#: nova/network/linux_net.py:256 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "Pid %d は無効です。dnsmasqを再実行します。" + +#: nova/network/linux_net.py:334 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "dnsmasq をkillしましたが、 %s が発生しました。" + +#: nova/network/manager.py:135 +msgid "setting network host" +msgstr "ネットワークホストの設定をします。" + +#: nova/network/manager.py:190 +#, python-format +msgid "Leasing IP %s" +msgstr "IP %s をリースします。" + +#: nova/network/manager.py:194 +#, python-format +msgid "IP %s leased that isn't associated" +msgstr "IP %s がリースされましたが関連付けられていません。" + +#: nova/network/manager.py:197 +#, python-format +msgid "IP %s leased to bad mac %s vs %s" +msgstr "IP %s が期待した mac %s ではなく %s にリースされました。" + +#: nova/network/manager.py:205 +#, python-format +msgid "IP %s leased that was already deallocated" +msgstr "既に割当解除しているIP %s がリースされました。" + +#: nova/network/manager.py:214 +#, python-format +msgid "IP %s released that isn't associated" +msgstr "割り当てていないIP %s が開放されました。" + +#: nova/network/manager.py:217 +#, python-format +msgid "IP %s released from bad mac %s vs %s" +msgstr "IP %s がmac %s ではない mac %s への割当から開放されました。" + +#: nova/network/manager.py:220 +#, python-format +msgid "IP %s released that was not leased" +msgstr "リースしていないIP %s が開放されました。" + +#: nova/network/manager.py:442 +#, python-format +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "無効になった %s 個の fixed ip を割当解除しました。" + +#: nova/objectstore/handler.py:106 +#, python-format +msgid "Unknown S3 value type %r" +msgstr "未知のS3 value type %r です。" + +#: nova/objectstore/handler.py:137 +msgid "Authenticated request" +msgstr "認証リクエスト" + +#: nova/objectstore/handler.py:182 +msgid "List of buckets requested" +msgstr "List of buckets が呼ばれました。" + +#: nova/objectstore/handler.py:209 +#, python-format +msgid "List keys for bucket %s" +msgstr "バケット %s のキーの一覧" + +#: nova/objectstore/handler.py:217 +#, python-format +msgid "Unauthorized attempt to access bucket %s" +msgstr "Unauthorized attempt to access bucket: バケット %s に対するアクセスは許可されていません。" + +#: nova/objectstore/handler.py:235 +#, python-format +msgid "Creating bucket %s" +msgstr "バケットを作成します。 %s" + +#: nova/objectstore/handler.py:245 +#, python-format +msgid "Deleting bucket %s" +msgstr "バケットを削除します。 %s" + +#: nova/objectstore/handler.py:249 +#, python-format +msgid "Unauthorized attempt to delete bucket %s" +msgstr "Unauthorized attempt to delete bucket: バケット %s に対する削除は許可されていません。" + +#: nova/objectstore/handler.py:271 +#, python-format +msgid "Getting object: %s / %s" +msgstr "オブジェクトの取得: %s / %s" + +#: nova/objectstore/handler.py:274 +#, python-format +msgid "Unauthorized attempt to get object %s from bucket %s" +msgstr "" +"Unauthorized attempt to get object: オブジェクト %s のバケット %s からの取得は許可されていません。" + +#: nova/objectstore/handler.py:292 +#, python-format +msgid "Putting object: %s / %s" +msgstr "オブジェクトの格納:: %s / %s" + +#: nova/objectstore/handler.py:295 +#, python-format +msgid "Unauthorized attempt to upload object %s to bucket %s" +msgstr "" +"Unauthorized attempt to upload: オブジェクト %s のバケット %s へのアップロードは許可されていません。" + +#: nova/objectstore/handler.py:314 +#, python-format +msgid "Deleting object: %s / %s" +msgstr "オブジェクトを削除しています。: %s / %s" + +#: nova/objectstore/handler.py:393 +#, python-format +msgid "Not authorized to upload image: invalid directory %s" +msgstr "" +"Not authorized to upload image: イメージの格納は許可されていません。ディレクトリ %s は正しくありません。" + +#: nova/objectstore/handler.py:401 +#, python-format +msgid "Not authorized to upload image: unauthorized bucket %s" +msgstr "" +"Not authorized to upload image: イメージの格納は許可されていません。バケット %s への格納は許可されていません。" + +#: nova/objectstore/handler.py:406 +#, python-format +msgid "Starting image upload: %s" +msgstr "イメージのアップロードを開始しました。 %s" + +#: nova/objectstore/handler.py:420 +#, python-format +msgid "Not authorized to update attributes of image %s" +msgstr "Not authorized to update attributes: イメージ %s のアトリビュートの更新は許可されていません。" + +#: nova/objectstore/handler.py:428 +#, python-format +msgid "Toggling publicity flag of image %s %r" +msgstr "Toggling publicity flag: イメージ %s の公開フラグを %r に更新します。" + +#: nova/objectstore/handler.py:433 +#, python-format +msgid "Updating user fields on image %s" +msgstr "Updating user fields: イメージ %s のユーザフィールドを更新します。" + +#: nova/objectstore/handler.py:447 +#, python-format +msgid "Unauthorized attempt to delete image %s" +msgstr "Unauthorized attempt to delete image: イメージ %s の削除は許可されていません。" + +#: nova/objectstore/handler.py:452 +#, python-format +msgid "Deleted image: %s" +msgstr "イメージ %s を削除しました。" + +#: nova/scheduler/chance.py:37 nova/scheduler/simple.py:73 +#: nova/scheduler/simple.py:106 nova/scheduler/simple.py:118 +msgid "No hosts found" +msgstr "適切なホストが見つかりません。" + +#: nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "予備の(fallback)スケジューラを実装する必要があります。" + +#: nova/scheduler/manager.py:69 +#, python-format +msgid "Casting to %s %s for %s" +msgstr "メッセージのcast: %s %s for %s" + +#: nova/scheduler/simple.py:63 +msgid "All hosts have too many cores" +msgstr "全てのホストにコア数の空きがありません。" + +#: nova/scheduler/simple.py:95 +msgid "All hosts have too many gigabytes" +msgstr "全てのホストが利用可能な容量(gigabytes)に達しています。" + +#: nova/scheduler/simple.py:115 +msgid "All hosts have too many networks" +msgstr "全てのホストがネットワークの最大数に達しています。" + +#: nova/tests/test_cloud.py:198 +msgid "Can't test instances without a real virtual env." +msgstr "インスタンスのテストには実際の仮想環境が必要です。(fakeでは実行できません。)" + +#: nova/tests/test_cloud.py:210 +#, python-format +msgid "Need to watch instance %s until it's running..." +msgstr "インスタンス %s が実行するまで監視します…" + +#: nova/tests/test_compute.py:104 +#, python-format +msgid "Running instances: %s" +msgstr "インスタンス %s は実行中です。" + +#: nova/tests/test_compute.py:110 +#, python-format +msgid "After terminating instances: %s" +msgstr "インスタンス %s を終了した後です。" + +#: nova/tests/test_rpc.py:89 +#, python-format +msgid "Nested received %s, %s" +msgstr "ネスとした受信: %s, %s" + +#: nova/tests/test_rpc.py:94 +#, python-format +msgid "Nested return %s" +msgstr "ネストした戻り値: %s" + +#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#, python-format +msgid "Received %s" +msgstr "%s を受信。" + +#: nova/tests/test_volume.py:162 +#, python-format +msgid "Target %s allocated" +msgstr "ターゲット %s をアロケートしました。" + +#: nova/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "ハイパーバイザへの接続に失敗しました。" + +#: nova/virt/fake.py:210 +#, python-format +msgid "Instance %s Not Found" +msgstr "インスタンス %s が見つかりません。" + +#: nova/virt/hyperv.py:118 +msgid "In init host" +msgstr "In init host" + +#: nova/virt/hyperv.py:131 +#, python-format +msgid "Attempt to create duplicate vm %s" +msgstr "VM %s を二重に作成しようとしました。" + +#: nova/virt/hyperv.py:148 +#, python-format +msgid "Starting VM %s " +msgstr "VM %s を開始します。 " + +#: nova/virt/hyperv.py:150 +#, python-format +msgid "Started VM %s " +msgstr "VM %s を開始しました。 " + +#: nova/virt/hyperv.py:152 +#, python-format +msgid "spawn vm failed: %s" +msgstr "vmの生成(spawn)に失敗しました: %s" + +#: nova/virt/hyperv.py:169 +#, python-format +msgid "Failed to create VM %s" +msgstr "VM %s の作成に失敗しました。" + +#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#, python-format +msgid "Created VM %s..." +msgstr "VM %s を作成します。" + +#: nova/virt/hyperv.py:188 +#, python-format +msgid "Set memory for vm %s..." +msgstr "vm %s のメモリを設定します。" + +#: nova/virt/hyperv.py:198 +#, python-format +msgid "Set vcpus for vm %s..." +msgstr "vm %s のvcpus を設定します。" + +#: nova/virt/hyperv.py:202 +#, python-format +msgid "Creating disk for %s by attaching disk file %s" +msgstr "%s のディスクをディスクファイル %s をアタッチして作成します。" + +#: nova/virt/hyperv.py:227 +#, python-format +msgid "Failed to add diskdrive to VM %s" +msgstr "VM %s へのディスクドライブの追加に失敗しました。" + +#: nova/virt/hyperv.py:230 +#, python-format +msgid "New disk drive path is %s" +msgstr "新しいドライブパスは %s です。" + +#: nova/virt/hyperv.py:247 +#, python-format +msgid "Failed to add vhd file to VM %s" +msgstr "vhdファイルの VM %s への追加に失敗しました。" + +#: nova/virt/hyperv.py:249 +#, python-format +msgid "Created disk for %s" +msgstr "%s に diskを作成します。" + +#: nova/virt/hyperv.py:253 +#, python-format +msgid "Creating nic for %s " +msgstr "%s にNICを作成します。 " + +#: nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" +msgstr "外部vswitchへのポート作成に失敗しました。" + +#: nova/virt/hyperv.py:273 +#, python-format +msgid "Failed creating port for %s" +msgstr "ポート %s の作成に失敗しました。" + +#: nova/virt/hyperv.py:275 +#, python-format +msgid "Created switch port %s on switch %s" +msgstr "スイッチポート %s をスイッチ %s に作成しました。" + +#: nova/virt/hyperv.py:285 +#, python-format +msgid "Failed to add nic to VM %s" +msgstr "VM %s に対してNICの追加に失敗しました。" + +#: nova/virt/hyperv.py:287 +#, python-format +msgid "Created nic for %s " +msgstr "%s のNICを作成しました。 " + +#: nova/virt/hyperv.py:320 +#, python-format +msgid "WMI job failed: %s" +msgstr "WMIジョブに失敗しました: %s" + +#: nova/virt/hyperv.py:322 +#, python-format +msgid "WMI job succeeded: %s, Elapsed=%s " +msgstr "WMIジョブが成功しました: %s, 経過時間=%s " + +#: nova/virt/hyperv.py:358 +#, python-format +msgid "Got request to destroy vm %s" +msgstr "destroy vm %s リクエストを受信しました。" + +#: nova/virt/hyperv.py:383 +#, python-format +msgid "Failed to destroy vm %s" +msgstr "vm %s の削除に失敗しました。" + +#: nova/virt/hyperv.py:389 +#, python-format +msgid "Del: disk %s vm %s" +msgstr "Del: 削除: disk %s vm %s" + +#: nova/virt/hyperv.py:405 +#, python-format +msgid "" +"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " +"cpu_time=%s" +msgstr "" +"vm %s の情報の取得: state=%s, mem=%s, num_cpu=%s, cpu_time=%s" + +#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#, python-format +msgid "duplicate name found: %s" +msgstr "%s は重複しています。" + +#: nova/virt/hyperv.py:444 +#, python-format +msgid "Successfully changed vm state of %s to %s" +msgstr "vmの状態の %s から %s への変更に成功しました。" + +#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#, python-format +msgid "Failed to change vm state of %s to %s" +msgstr "VMの状態の %s から %s への変更に失敗しました。" + +#: nova/virt/images.py:70 +#, python-format +msgid "Finished retreving %s -- placed in %s" +msgstr "%s を取得しました。格納先: %s" + +#: nova/virt/libvirt_conn.py:144 +#, python-format +msgid "Connecting to libvirt: %s" +msgstr "libvirt %s へ接続します。" + +#: nova/virt/libvirt_conn.py:157 +msgid "Connection to libvirt broke" +msgstr "libvirtへの接続が切れています。" + +#: nova/virt/libvirt_conn.py:229 +#, python-format +msgid "instance %s: deleting instance files %s" +msgstr "インスタンス %s: インスタンスファイル %s を削除しています。" + +#: nova/virt/libvirt_conn.py:271 +#, python-format +msgid "No disk at %s" +msgstr "%s にディスクが存在しません。" + +#: nova/virt/libvirt_conn.py:278 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "インスタンスのスナップショットは現在libvirtに対してはサポートされていません。" + +#: nova/virt/libvirt_conn.py:294 +#, python-format +msgid "instance %s: rebooted" +msgstr "インスタンス%s: 再起動しました。" + +#: nova/virt/libvirt_conn.py:297 +#, python-format +msgid "_wait_for_reboot failed: %s" +msgstr "_wait_for_reboot 失敗: %s" + +#: nova/virt/libvirt_conn.py:340 +#, python-format +msgid "instance %s: rescued" +msgstr "インスタンス %s: rescued" + +#: nova/virt/libvirt_conn.py:343 +#, python-format +msgid "_wait_for_rescue failed: %s" +msgstr "_wait_for_rescue 失敗: %s" + +#: nova/virt/libvirt_conn.py:370 +#, python-format +msgid "instance %s: is running" +msgstr "インスタンス %s を起動中です。" + +#: nova/virt/libvirt_conn.py:381 +#, python-format +msgid "instance %s: booted" +msgstr "インスタンス %s: 起動しました。" + +#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#, python-format +msgid "instance %s: failed to boot" +msgstr "インスタンス %s の起動に失敗しました。" + +#: nova/virt/libvirt_conn.py:395 +#, python-format +msgid "virsh said: %r" +msgstr "virsh の出力: %r" + +#: nova/virt/libvirt_conn.py:399 +msgid "cool, it's a device" +msgstr "デバイスです。" + +#: nova/virt/libvirt_conn.py:407 +#, python-format +msgid "data: %r, fpath: %r" +msgstr "データ:%r ファイルパス: %r" + +#: nova/virt/libvirt_conn.py:415 +#, python-format +msgid "Contents of file %s: %r" +msgstr "ファイル %s の中身: %r" + +#: nova/virt/libvirt_conn.py:449 +#, python-format +msgid "instance %s: Creating image" +msgstr "インスタンス %s のイメージを生成します。" + +#: nova/virt/libvirt_conn.py:505 +#, python-format +msgid "instance %s: injecting key into image %s" +msgstr "インスタンス %s にキー %s をインジェクトします。" + +#: nova/virt/libvirt_conn.py:508 +#, python-format +msgid "instance %s: injecting net into image %s" +msgstr "インスタンス %s のネットワーク設定をイメージ %s にインジェクトします。" + +#: nova/virt/libvirt_conn.py:516 +#, python-format +msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgstr "インスタンス %s: データをイメージ %s にインジェクトする際にエラーが発生しました。(%s)" + +#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#, python-format +msgid "instance %s: starting toXML method" +msgstr "インスタンス %s: toXML メソッドを開始。" + +#: nova/virt/libvirt_conn.py:589 +#, python-format +msgid "instance %s: finished toXML method" +msgstr "インスタンス %s: toXML メソッドを完了。" + +#: nova/virt/xenapi_conn.py:113 +msgid "" +"Must specify xenapi_connection_url, xenapi_connection_username (optionally), " +"and xenapi_connection_password to use connection_type=xenapi" +msgstr "" +"connection_type=xenapi を使用するには、以下の指定が必要です: xenapi_connection_url, " +"xenapi_connection_username (オプション), xenapi_connection_password" + +#: nova/virt/xenapi_conn.py:263 +#, python-format +msgid "Task [%s] %s status: success %s" +msgstr "タスク [%s] %s ステータス: success %s" + +#: nova/virt/xenapi_conn.py:271 +#, python-format +msgid "Task [%s] %s status: %s %s" +msgstr "タスク [%s] %s ステータス: %s %s" + +#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#, python-format +msgid "Got exception: %s" +msgstr "例外 %s が発生しました。" + +#: nova/virt/xenapi/fake.py:72 +#, python-format +msgid "%s: _db_content => %s" +msgstr "%s: _db_content => %s" + +#: nova/virt/xenapi/fake.py:247 nova/virt/xenapi/fake.py:338 +#: nova/virt/xenapi/fake.py:356 nova/virt/xenapi/fake.py:404 +msgid "Raising NotImplemented" +msgstr "NotImplemented 例外を発生させます。" + +#: nova/virt/xenapi/fake.py:249 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "xenapi.fake には %s が実装されていません。" + +#: nova/virt/xenapi/fake.py:283 +#, python-format +msgid "Calling %s %s" +msgstr "呼び出し: %s %s" + +#: nova/virt/xenapi/fake.py:288 +#, python-format +msgid "Calling getter %s" +msgstr "getter %s をコールします。" + +#: nova/virt/xenapi/fake.py:340 +#, python-format +msgid "" +"xenapi.fake does not have an implementation for %s or it has been called " +"with the wrong number of arguments" +msgstr "xenapi.fake に %s に関する実装がないか、引数の数が誤っています。" + +#: nova/virt/xenapi/network_utils.py:40 +#, python-format +msgid "Found non-unique network for bridge %s" +msgstr "ブリッジ %s に対してブリッジが複数存在します。" + +#: nova/virt/xenapi/network_utils.py:43 +#, python-format +msgid "Found no network for bridge %s" +msgstr "ブリッジ %s に対するネットワークが存在しません。" + +#: nova/virt/xenapi/vm_utils.py:127 +#, python-format +msgid "Created VM %s as %s." +msgstr "VM %s を %s として作成しました。" + +#: nova/virt/xenapi/vm_utils.py:147 +#, python-format +msgid "Creating VBD for VM %s, VDI %s ... " +msgstr "VM %s, VDI %s のVBDを作成します… " + +#: nova/virt/xenapi/vm_utils.py:149 +#, python-format +msgid "Created VBD %s for VM %s, VDI %s." +msgstr "VBD %s を VM %s, VDI %s に対して作成しました。" + +#: nova/virt/xenapi/vm_utils.py:165 +#, python-format +msgid "VBD not found in instance %s" +msgstr "インスタンス %s のVBDが見つかりません。" + +#: nova/virt/xenapi/vm_utils.py:175 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "VBD %s の unplug に失敗しました。" + +#: nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "VBD %s の削除に失敗しました。" + +#: nova/virt/xenapi/vm_utils.py:202 +#, python-format +msgid "Creating VIF for VM %s, network %s." +msgstr "VM %s, ネットワーク %s を作成します。" + +#: nova/virt/xenapi/vm_utils.py:205 +#, python-format +msgid "Created VIF %s for VM %s, network %s." +msgstr "VIF %s を VM %s, ネットワーク %s に作成しました。" + +#: nova/virt/xenapi/vm_utils.py:216 +#, python-format +msgid "Snapshotting VM %s with label '%s'..." +msgstr "VM %s のスナップショットをラベル '%s' で作成します。" + +#: nova/virt/xenapi/vm_utils.py:229 +#, python-format +msgid "Created snapshot %s from VM %s." +msgstr "スナップショット %s を VM %s について作成しました。" + +#: nova/virt/xenapi/vm_utils.py:243 +#, python-format +msgid "Asking xapi to upload %s as '%s'" +msgstr "xapiに対して %s を '%s' としてアップロードするように指示します。" + +#: nova/virt/xenapi/vm_utils.py:261 +#, python-format +msgid "Asking xapi to fetch %s as %s" +msgstr "xapi に対して %s を %s として取得するように指示します。" + +#: nova/virt/xenapi/vm_utils.py:279 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "PV kernelのvdi %s を取得します。" + +#: nova/virt/xenapi/vm_utils.py:290 +#, python-format +msgid "PV Kernel in VDI:%d" +msgstr "VDIのPV Kernel: %d" + +#: nova/virt/xenapi/vm_utils.py:318 +#, python-format +msgid "VDI %s is still available" +msgstr "VDI %s は依然として存在しています。" + +#: nova/virt/xenapi/vm_utils.py:331 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "(VM_UTILS) xenserver の vm state -> |%s|" + +#: nova/virt/xenapi/vm_utils.py:333 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "(VM_UTILS) xenapi の power_state -> |%s|" + +#: nova/virt/xenapi/vm_utils.py:390 +#, python-format +msgid "VHD %s has parent %s" +msgstr "VHD %s のペアレントは %s です。" + +#: nova/virt/xenapi/vm_utils.py:407 +#, python-format +msgid "Re-scanning SR %s" +msgstr "SR %s を再スキャンします。" + +#: nova/virt/xenapi/vm_utils.py:431 +#, python-format +msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgstr "ペアレント %s がオリジナルのペアレント %s と一致しません。合致するのを待ちます…" + +#: nova/virt/xenapi/vm_utils.py:448 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "VM %s にVDIが存在しません。" + +#: nova/virt/xenapi/vm_utils.py:452 +#, python-format +msgid "Unexpected number of VDIs (%s) found for VM %s" +msgstr "予期しない数 (%s) のVDIがVM %s に存在します。" + +#: nova/virt/xenapi/vmops.py:62 +#, python-format +msgid "Attempted to create non-unique name %s" +msgstr "ユニークではないname %s を作成しようとしました。" + +#: nova/virt/xenapi/vmops.py:99 +#, python-format +msgid "Starting VM %s..." +msgstr "VM %s を開始します…" + +#: nova/virt/xenapi/vmops.py:101 +#, python-format +msgid "Spawning VM %s created %s." +msgstr "VM %s の生成(spawning) により %s を作成しました。" + +#: nova/virt/xenapi/vmops.py:112 +#, python-format +msgid "Instance %s: booted" +msgstr "インスタンス%s: ブートしました。" + +#: nova/virt/xenapi/vmops.py:137 +#, python-format +msgid "Instance not present %s" +msgstr "インスタンス%s が存在しません。" + +#: nova/virt/xenapi/vmops.py:166 +#, python-format +msgid "Starting snapshot for VM %s" +msgstr "VM %s に対するスナップショットを開始します。" + +#: nova/virt/xenapi/vmops.py:174 +#, python-format +msgid "Unable to Snapshot %s: %s" +msgstr "%s のスナップショットに失敗しました: %s" + +#: nova/virt/xenapi/vmops.py:184 +#, python-format +msgid "Finished snapshot and upload for VM %s" +msgstr "VM %s のスナップショットとアップロードが完了しました。" + +#: nova/virt/xenapi/vmops.py:252 +#, python-format +msgid "suspend: instance not present %s" +msgstr "suspend: インスタンス %s は存在しません。" + +#: nova/virt/xenapi/vmops.py:262 +#, python-format +msgid "resume: instance not present %s" +msgstr "resume: インスタンス %s は存在しません。" + +#: nova/virt/xenapi/vmops.py:271 +#, python-format +msgid "Instance not found %s" +msgstr "インスタンス %s が見つかりません。" + +#: nova/virt/xenapi/volume_utils.py:57 +#, python-format +msgid "Introducing %s..." +msgstr "%s を introduce します…" + +#: nova/virt/xenapi/volume_utils.py:74 +#, python-format +msgid "Introduced %s as %s." +msgstr "%s を %s として introduce しました。" + +#: nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" +msgstr "Storage Repository を作成できません。" + +#: nova/virt/xenapi/volume_utils.py:90 +#, python-format +msgid "Unable to find SR from VBD %s" +msgstr "VBD %s から SRを取得できません。" + +#: nova/virt/xenapi/volume_utils.py:96 +#, python-format +msgid "Forgetting SR %s ... " +msgstr "SR %s をforgetします。 " + +#: nova/virt/xenapi/volume_utils.py:101 +#, python-format +msgid "Ignoring exception %s when getting PBDs for %s" +msgstr "例外 %s が %s のPBDを取得する際に発生しましたが無視します。" + +#: nova/virt/xenapi/volume_utils.py:107 +#, python-format +msgid "Ignoring exception %s when unplugging PBD %s" +msgstr "例外 %s が %s のPBDをunplugする際に発生しましたが無視します。" + +#: nova/virt/xenapi/volume_utils.py:111 +#, python-format +msgid "Forgetting SR %s done." +msgstr "SR %s のforgetが完了。" + +#: nova/virt/xenapi/volume_utils.py:113 +#, python-format +msgid "Ignoring exception %s when forgetting SR %s" +msgstr "例外 %s がSR %s をforgetする際に発生しましたが無視します。" + +#: nova/virt/xenapi/volume_utils.py:123 +#, python-format +msgid "Unable to introduce VDI on SR %s" +msgstr "SR %s のVDIのintroduceができません。" + +#: nova/virt/xenapi/volume_utils.py:128 +#, python-format +msgid "Unable to get record of VDI %s on" +msgstr "VDI %s のレコードを取得できません。" + +#: nova/virt/xenapi/volume_utils.py:146 +#, python-format +msgid "Unable to introduce VDI for SR %s" +msgstr "SR %s のVDIをintroduceできません。" + +#: nova/virt/xenapi/volume_utils.py:175 +#, python-format +msgid "Unable to obtain target information %s, %s" +msgstr "ターゲットの情報を取得できません。 %s, %s" + +#: nova/virt/xenapi/volume_utils.py:197 +#, python-format +msgid "Mountpoint cannot be translated: %s" +msgstr "マウントポイントを変換できません。 %s" + +#: nova/virt/xenapi/volumeops.py:51 +#, python-format +msgid "Attach_volume: %s, %s, %s" +msgstr "Attach_volume: ボリュームのアタッチ: %s, %s, %s" + +#: nova/virt/xenapi/volumeops.py:69 +#, python-format +msgid "Unable to create VDI on SR %s for instance %s" +msgstr "SR %s にインスタンス %s のVDIを作成できません。" + +#: nova/virt/xenapi/volumeops.py:81 +#, python-format +msgid "Unable to use SR %s for instance %s" +msgstr "SR %s をインスタンス %s に対して利用できません。" + +#: nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Unable to attach volume to instance %s" +msgstr "インスタンス %s にボリュームをアタッチできません。" + +#: nova/virt/xenapi/volumeops.py:95 +#, python-format +msgid "Mountpoint %s attached to instance %s" +msgstr "マウントポイント %s をインスタンス %s にアタッチしました。" + +#: nova/virt/xenapi/volumeops.py:106 +#, python-format +msgid "Detach_volume: %s, %s" +msgstr "Detach_volume: ボリュームのデタッチ: %s, %s" + +#: nova/virt/xenapi/volumeops.py:113 +#, python-format +msgid "Unable to locate volume %s" +msgstr "ボリューム %s の存在が確認できません。" + +#: nova/virt/xenapi/volumeops.py:121 +#, python-format +msgid "Unable to detach volume %s" +msgstr "ボリューム %s のデタッチができません。" + +#: nova/virt/xenapi/volumeops.py:128 +#, python-format +msgid "Mountpoint %s detached from instance %s" +msgstr "マウントポイント %s をインスタンス %s からデタッチしました。" + +#: nova/volume/api.py:44 +#, python-format +msgid "Quota exceeeded for %s, tried to create %sG volume" +msgstr "%sのクオータを超えています。サイズ %sG のボリュームの作成を行おうとしました。" + +#: nova/volume/api.py:46 +#, python-format +msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgstr "ボリュームのクオータを超えています。%sの大きさのボリュームは作成できません。" + +#: nova/volume/api.py:70 nova/volume/api.py:95 +msgid "Volume status must be available" +msgstr "ボリュームのステータス(status)が available でなければなりません。" + +#: nova/volume/api.py:97 +msgid "Volume is already attached" +msgstr "ボリュームは既にアタッチされています(attached)。" + +#: nova/volume/api.py:103 +msgid "Volume is already detached" +msgstr "ボリュームは既にデタッチされています(detached)。" + +#: nova/volume/driver.py:76 +#, python-format +msgid "Recovering from a failed execute. Try number %s" +msgstr "実行失敗からリカバリーします。%s 回目のトライ。" + +#: nova/volume/driver.py:85 +#, python-format +msgid "volume group %s doesn't exist" +msgstr "ボリュームグループ%sが存在しません。" + +#: nova/volume/driver.py:210 +#, python-format +msgid "FAKE AOE: %s" +msgstr "偽のAOE: %s" + +#: nova/volume/driver.py:315 +#, python-format +msgid "FAKE ISCSI: %s" +msgstr "偽のISCSI: %s" + +#: nova/volume/manager.py:85 +#, python-format +msgid "Re-exporting %s volumes" +msgstr "%s 個のボリュームを再エクスポートします。" + +#: nova/volume/manager.py:93 +#, python-format +msgid "volume %s: creating" +msgstr "ボリューム%sを作成します。" + +#: nova/volume/manager.py:102 +#, python-format +msgid "volume %s: creating lv of size %sG" +msgstr "ボリューム%sの%sGのlv (論理ボリューム) を作成します。" + +#: nova/volume/manager.py:106 +#, python-format +msgid "volume %s: creating export" +msgstr "ボリューム %s をエクスポートします。" + +#: nova/volume/manager.py:113 +#, python-format +msgid "volume %s: created successfully" +msgstr "ボリューム %s の作成に成功しました。" + +#: nova/volume/manager.py:121 +msgid "Volume is still attached" +msgstr "ボリュームはアタッチされたままです。" + +#: nova/volume/manager.py:123 +msgid "Volume is not local to this node" +msgstr "ボリュームはこのノードのローカルではありません。" + +#: nova/volume/manager.py:124 +#, python-format +msgid "volume %s: removing export" +msgstr "ボリューム %s のエクスポートを解除します。" + +#: nova/volume/manager.py:126 +#, python-format +msgid "volume %s: deleting" +msgstr "ボリューム %s を削除します。" + +#: nova/volume/manager.py:129 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "ボリューム %s の削除に成功しました。" diff --git a/locale/pt_BR.po b/locale/pt_BR.po new file mode 100644 index 00000000..a58ccc18 --- /dev/null +++ b/locale/pt_BR.po @@ -0,0 +1,2148 @@ +# Brazilian Portuguese translation for nova +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the nova package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: nova\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"PO-Revision-Date: 2011-01-13 18:44+0000\n" +"Last-Translator: Gustavo Morozowski \n" +"Language-Team: Brazilian Portuguese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-01-28 05:21+0000\n" +"X-Generator: Launchpad (build 12177)\n" + +#: nova/crypto.py:46 +msgid "Filename of root CA" +msgstr "Nome do arquivo da CA raiz" + +#: nova/crypto.py:49 +msgid "Filename of private key" +msgstr "Nome do arquivo da chave privada" + +#: nova/crypto.py:51 +msgid "Filename of root Certificate Revokation List" +msgstr "Nome de arquivo da Lista de Revogação de Certificados" + +#: nova/crypto.py:53 +msgid "Where we keep our keys" +msgstr "Aonde armazenamos nossas chaves" + +#: nova/crypto.py:55 +msgid "Where we keep our root CA" +msgstr "Aonde mantemos nosso CA raiz" + +#: nova/crypto.py:57 +msgid "Should we use a CA for each project?" +msgstr "Devemos usar um CA para cada projeto?" + +#: nova/crypto.py:61 +#, python-format +msgid "Subject for certificate for users, %s for project, user, timestamp" +msgstr "" +"Sujeito do certificado para usuários, %s para projeto, usuário, timestamp" + +#: nova/crypto.py:66 +#, python-format +msgid "Subject for certificate for projects, %s for project, timestamp" +msgstr "Sujeito do certificado para projetos, %s para projeto, timestamp" + +#: nova/crypto.py:71 +#, python-format +msgid "Subject for certificate for vpns, %s for project, timestamp" +msgstr "Sujeito do certificado para vpns, %s para projeto, timestamp" + +#: nova/crypto.py:258 +#, python-format +msgid "Flags path: %s" +msgstr "" + +#: nova/exception.py:33 +msgid "Unexpected error while running command." +msgstr "Erro inesperado ao executar o comando." + +#: nova/exception.py:36 +#, python-format +msgid "" +"%s\n" +"Command: %s\n" +"Exit code: %s\n" +"Stdout: %r\n" +"Stderr: %r" +msgstr "" +"%s\n" +"Comando: %s\n" +"Código de retorno: %s\n" +"Stdout: %r\n" +"Stderr: %r" + +#: nova/exception.py:86 +msgid "Uncaught exception" +msgstr "Exceção não capturada" + +#: nova/fakerabbit.py:48 +#, python-format +msgid "(%s) publish (key: %s) %s" +msgstr "(%s) publicar (key: %s) %s" + +#: nova/fakerabbit.py:53 +#, python-format +msgid "Publishing to route %s" +msgstr "Publicando para rota %s" + +#: nova/fakerabbit.py:83 +#, python-format +msgid "Declaring queue %s" +msgstr "Declarando fila %s" + +#: nova/fakerabbit.py:89 +#, python-format +msgid "Declaring exchange %s" +msgstr "" + +#: nova/fakerabbit.py:95 +#, python-format +msgid "Binding %s to %s with key %s" +msgstr "Atribuindo %s para %s com chave %s" + +#: nova/fakerabbit.py:120 +#, python-format +msgid "Getting from %s: %s" +msgstr "Obtendo de %s: %s" + +#: nova/rpc.py:92 +#, python-format +msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgstr "" +"Servidor AMQP em %s:%d inatingível. Tentando novamente em %d segundos." + +#: nova/rpc.py:99 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "" +"Não foi possível conectar ao servidor AMQP após %d tentativas. Desligando." + +#: nova/rpc.py:118 +msgid "Reconnected to queue" +msgstr "Reconectado à fila" + +#: nova/rpc.py:125 +msgid "Failed to fetch message from queue" +msgstr "Falha ao obter mensagem da fila" + +#: nova/rpc.py:155 +#, python-format +msgid "Initing the Adapter Consumer for %s" +msgstr "Iniciando o Adaptador Consumidor para %s" + +#: nova/rpc.py:170 +#, python-format +msgid "received %s" +msgstr "recebido %s" + +#: nova/rpc.py:183 +#, python-format +msgid "no method for message: %s" +msgstr "sem método para mensagem: %s" + +#: nova/rpc.py:184 +#, python-format +msgid "No method for message: %s" +msgstr "Sem método para mensagem: %s" + +#: nova/rpc.py:245 +#, python-format +msgid "Returning exception %s to caller" +msgstr "Retornando exceção %s ao método de origem" + +#: nova/rpc.py:286 +#, python-format +msgid "unpacked context: %s" +msgstr "conteúdo descompactado: %s" + +#: nova/rpc.py:305 +msgid "Making asynchronous call..." +msgstr "Fazendo chamada assíncrona..." + +#: nova/rpc.py:308 +#, python-format +msgid "MSG_ID is %s" +msgstr "MSG_ID é %s" + +#: nova/rpc.py:356 +#, python-format +msgid "response %s" +msgstr "resposta %s" + +#: nova/rpc.py:365 +#, python-format +msgid "topic is %s" +msgstr "topico é %s" + +#: nova/rpc.py:366 +#, python-format +msgid "message %s" +msgstr "mensagem %s" + +#: nova/service.py:157 +#, python-format +msgid "Starting %s node" +msgstr "Iniciando nó %s" + +#: nova/service.py:169 +msgid "Service killed that has no database entry" +msgstr "Encerrado serviço que não tem entrada na base de dados" + +#: nova/service.py:190 +msgid "The service database object disappeared, Recreating it." +msgstr "O objeto da base de dados do serviço desapareceu, Recriando." + +#: nova/service.py:202 +msgid "Recovered model server connection!" +msgstr "Recuperada conexão servidor de modelo." + +#: nova/service.py:208 +msgid "model server went away" +msgstr "servidor de modelo perdido" + +#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#, python-format +msgid "Data store %s is unreachable. Trying again in %d seconds." +msgstr "" +"Repositório de dados %s não pode ser atingido. Tentando novamente em %d " +"segundos." + +#: nova/service.py:232 nova/twistd.py:232 +#, python-format +msgid "Serving %s" +msgstr "Servindo %s" + +#: nova/service.py:234 nova/twistd.py:264 +msgid "Full set of FLAGS:" +msgstr "Conjunto completo de FLAGS:" + +#: nova/twistd.py:211 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "" +"Arquivo de id de processo (pidfile) %s não existe. Daemon não está " +"executando?\n" + +#: nova/twistd.py:268 +#, python-format +msgid "Starting %s" +msgstr "Iniciando %s" + +#: nova/utils.py:53 +#, python-format +msgid "Inner Exception: %s" +msgstr "Exceção interna: %s" + +#: nova/utils.py:54 +#, python-format +msgid "Class %s cannot be found" +msgstr "Classe %s não pode ser encontrada" + +#: nova/utils.py:113 +#, python-format +msgid "Fetching %s" +msgstr "Obtendo %s" + +#: nova/utils.py:125 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "Executando comando (subprocesso): %s" + +#: nova/utils.py:138 +#, python-format +msgid "Result was %s" +msgstr "Resultado foi %s" + +#: nova/utils.py:171 +#, python-format +msgid "debug in callback: %s" +msgstr "debug em callback: %s" + +#: nova/utils.py:176 +#, python-format +msgid "Running %s" +msgstr "Executando %s" + +#: nova/utils.py:207 +#, python-format +msgid "Couldn't get IP, using 127.0.0.1 %s" +msgstr "Não foi possível obter IP, usando 127.0.0.1 %s" + +#: nova/utils.py:289 +#, python-format +msgid "Invalid backend: %s" +msgstr "Backend inválido: %s" + +#: nova/utils.py:300 +#, python-format +msgid "backend %s" +msgstr "backend %s" + +#: nova/api/ec2/__init__.py:133 +msgid "Too many failed authentications." +msgstr "Muitas falhas de autenticação." + +#: nova/api/ec2/__init__.py:142 +#, python-format +msgid "" +"Access key %s has had %d failed authentications and will be locked out for " +"%d minutes." +msgstr "" +"Chave de acesso %s tem %d falhas de autenticação e vai ser bloqueada por %d " +"minutos." + +#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#, python-format +msgid "Authentication Failure: %s" +msgstr "Falha de Autenticação: %s" + +#: nova/api/ec2/__init__.py:190 +#, python-format +msgid "Authenticated Request For %s:%s)" +msgstr "Pedido de Autenticação Para: %s:%s" + +#: nova/api/ec2/__init__.py:227 +#, python-format +msgid "action: %s" +msgstr "ação: %s" + +#: nova/api/ec2/__init__.py:229 +#, python-format +msgid "arg: %s\t\tval: %s" +msgstr "argumento: %s\t\tvalor: %s" + +#: nova/api/ec2/__init__.py:301 +#, python-format +msgid "Unauthorized request for controller=%s and action=%s" +msgstr "Requisição não autorizada para controlador=%s e ação=%s" + +#: nova/api/ec2/__init__.py:339 +#, python-format +msgid "NotFound raised: %s" +msgstr "NotFound lançado: %s" + +#: nova/api/ec2/__init__.py:342 +#, python-format +msgid "ApiError raised: %s" +msgstr "ApiError lançado: %s" + +#: nova/api/ec2/__init__.py:349 +#, python-format +msgid "Unexpected error raised: %s" +msgstr "Erro inexperado lançado: %s" + +#: nova/api/ec2/__init__.py:354 +msgid "An unknown error has occurred. Please try your request again." +msgstr "" +"Ocorreu um erro desconhecido. Por favor tente sua requisição novamente." + +#: nova/api/ec2/admin.py:84 +#, python-format +msgid "Creating new user: %s" +msgstr "Criando novo usuário: %s" + +#: nova/api/ec2/admin.py:92 +#, python-format +msgid "Deleting user: %s" +msgstr "Excluindo usuário: %s" + +#: nova/api/ec2/admin.py:114 +#, python-format +msgid "Adding role %s to user %s for project %s" +msgstr "Adicionando papel %s ao usuário %s para o projeto %s" + +#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#, python-format +msgid "Adding sitewide role %s to user %s" +msgstr "Adicionando papel em todo site %s ao usuário %s" + +#: nova/api/ec2/admin.py:122 +#, python-format +msgid "Removing role %s from user %s for project %s" +msgstr "Removendo papel %s do usuário %s para o projeto %s" + +#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#, python-format +msgid "Removing sitewide role %s from user %s" +msgstr "Removendo papel %s em todo site do usuário %s" + +#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 +msgid "operation must be add or remove" +msgstr "operações devem ser adicionar e excluir" + +#: nova/api/ec2/admin.py:142 +#, python-format +msgid "Getting x509 for user: %s on project: %s" +msgstr "Obtendo x509 para usuário: %s do projeto: %s" + +#: nova/api/ec2/admin.py:159 +#, python-format +msgid "Create project %s managed by %s" +msgstr "Criar projeto %s gerenciado por %s" + +#: nova/api/ec2/admin.py:170 +#, python-format +msgid "Delete project: %s" +msgstr "Excluir projeto: %s" + +#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#, python-format +msgid "Adding user %s to project %s" +msgstr "Adicionando usuário %s ao projeto %s" + +#: nova/api/ec2/admin.py:188 +#, python-format +msgid "Removing user %s from project %s" +msgstr "Excluindo usuário %s do projeto %s" + +#: nova/api/ec2/apirequest.py:95 +#, python-format +msgid "Unsupported API request: controller = %s,action = %s" +msgstr "Requisição de API não suportada: controlador = %s,ação = %s" + +#: nova/api/ec2/cloud.py:117 +#, python-format +msgid "Generating root CA: %s" +msgstr "Gerando CA raiz: %s" + +#: nova/api/ec2/cloud.py:277 +#, python-format +msgid "Create key pair %s" +msgstr "Criar par de chaves %s" + +#: nova/api/ec2/cloud.py:285 +#, python-format +msgid "Delete key pair %s" +msgstr "Remover par de chaves %s" + +#: nova/api/ec2/cloud.py:357 +#, python-format +msgid "%s is not a valid ipProtocol" +msgstr "%s não é um ipProtocol válido" + +#: nova/api/ec2/cloud.py:361 +msgid "Invalid port range" +msgstr "" + +#: nova/api/ec2/cloud.py:392 +#, python-format +msgid "Revoke security group ingress %s" +msgstr "Revogado entrada do grupo de segurança %s" + +#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 +msgid "No rule for the specified parameters." +msgstr "Não existe regra para os parâmetros especificados" + +#: nova/api/ec2/cloud.py:421 +#, python-format +msgid "Authorize security group ingress %s" +msgstr "Autorizada entrada do grupo de segurança %s" + +#: nova/api/ec2/cloud.py:432 +#, python-format +msgid "This rule already exists in group %s" +msgstr "Esta regra já existe no grupo %s" + +#: nova/api/ec2/cloud.py:460 +#, python-format +msgid "Create Security Group %s" +msgstr "Criar Grupo de Segurança %s" + +#: nova/api/ec2/cloud.py:463 +#, python-format +msgid "group %s already exists" +msgstr "group %s já existe" + +#: nova/api/ec2/cloud.py:475 +#, python-format +msgid "Delete security group %s" +msgstr "Excluir grupo de segurança %s" + +#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#, python-format +msgid "Get console output for instance %s" +msgstr "Obter saída do console para instância %s" + +#: nova/api/ec2/cloud.py:543 +#, python-format +msgid "Create volume of %s GB" +msgstr "Criar volume de %s GB" + +#: nova/api/ec2/cloud.py:567 +#, python-format +msgid "Attach volume %s to instacne %s at %s" +msgstr "Anexar volume %s para instância %s em %s" + +#: nova/api/ec2/cloud.py:579 +#, python-format +msgid "Detach volume %s" +msgstr "Desanexar volume %s" + +#: nova/api/ec2/cloud.py:686 +msgid "Allocate address" +msgstr "Alocar endereço" + +#: nova/api/ec2/cloud.py:691 +#, python-format +msgid "Release address %s" +msgstr "Liberar endereço %s" + +#: nova/api/ec2/cloud.py:696 +#, python-format +msgid "Associate address %s to instance %s" +msgstr "Atribuir endereço %s à instância %s" + +#: nova/api/ec2/cloud.py:703 +#, python-format +msgid "Disassociate address %s" +msgstr "Desatribuir endereço %s" + +#: nova/api/ec2/cloud.py:730 +msgid "Going to start terminating instances" +msgstr "Começando a terminar instâncias" + +#: nova/api/ec2/cloud.py:738 +#, python-format +msgid "Reboot instance %r" +msgstr "Reiniciar instância %r" + +#: nova/api/ec2/cloud.py:775 +#, python-format +msgid "De-registering image %s" +msgstr "Removendo o registro da imagem %s" + +#: nova/api/ec2/cloud.py:783 +#, python-format +msgid "Registered image %s with id %s" +msgstr "Registrada imagem %s com id %s" + +#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#, python-format +msgid "attribute not supported: %s" +msgstr "atributo não suportado: %s" + +#: nova/api/ec2/cloud.py:794 +#, python-format +msgid "invalid id: %s" +msgstr "id inválido: %s" + +#: nova/api/ec2/cloud.py:807 +msgid "user or group not specified" +msgstr "usuário ou grupo não especificado" + +#: nova/api/ec2/cloud.py:809 +msgid "only group \"all\" is supported" +msgstr "apenas o grupo \"all\" é suportado" + +#: nova/api/ec2/cloud.py:811 +msgid "operation_type must be add or remove" +msgstr "operation_type deve ser add ou remove" + +#: nova/api/ec2/cloud.py:812 +#, python-format +msgid "Updating image %s publicity" +msgstr "Atualizando publicidade da imagem %s" + +#: nova/api/ec2/metadatarequesthandler.py:75 +#, python-format +msgid "Failed to get metadata for ip: %s" +msgstr "Falha ao obter metadados para o ip: %s" + +#: nova/api/openstack/__init__.py:70 +#, python-format +msgid "Caught error: %s" +msgstr "Capturado o erro: %s" + +#: nova/api/openstack/__init__.py:86 +msgid "Including admin operations in API." +msgstr "Incluindo operações administrativas na API." + +#: nova/api/openstack/servers.py:184 +#, python-format +msgid "Compute.api::lock %s" +msgstr "Compute.api::lock %s" + +#: nova/api/openstack/servers.py:199 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "Compute.api::unlock %s" + +#: nova/api/openstack/servers.py:213 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "Compute.api::get_lock %s" + +#: nova/api/openstack/servers.py:224 +#, python-format +msgid "Compute.api::pause %s" +msgstr "Compute.api::pause %s" + +#: nova/api/openstack/servers.py:235 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "Compute.api::unpause %s" + +#: nova/api/openstack/servers.py:246 +#, python-format +msgid "compute.api::suspend %s" +msgstr "compute.api::suspend %s" + +#: nova/api/openstack/servers.py:257 +#, python-format +msgid "compute.api::resume %s" +msgstr "compute.api::resume %s" + +#: nova/auth/dbdriver.py:84 +#, python-format +msgid "User %s already exists" +msgstr "Usuário %s já existe" + +#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#, python-format +msgid "Project can't be created because manager %s doesn't exist" +msgstr "Projeto não pode ser criado porque o gerente %s não existe." + +#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#, python-format +msgid "Project can't be created because project %s already exists" +msgstr "Projeto não pode ser criado porque o projeto %s já existe." + +#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#, python-format +msgid "Project can't be modified because manager %s doesn't exist" +msgstr "Projeto não pode ser modificado porque o gerente %s não existe." + +#: nova/auth/dbdriver.py:245 +#, python-format +msgid "User \"%s\" not found" +msgstr "Usuário \"%s\" não encontrado" + +#: nova/auth/dbdriver.py:248 +#, python-format +msgid "Project \"%s\" not found" +msgstr "Projeto \"%s\" não encontrado" + +#: nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "Tentativa de instanciar singleton" + +#: nova/auth/ldapdriver.py:181 +#, python-format +msgid "LDAP object for %s doesn't exist" +msgstr "Objeto LDAP para %s não existe" + +#: nova/auth/ldapdriver.py:218 +#, python-format +msgid "Project can't be created because user %s doesn't exist" +msgstr "Projeto não pode ser criado porque o usuário %s não existe" + +#: nova/auth/ldapdriver.py:478 +#, python-format +msgid "User %s is already a member of the group %s" +msgstr "Usuário %s já pertence ao grupo %s" + +#: nova/auth/ldapdriver.py:507 +#, python-format +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." +msgstr "" +"Tentatica de remover o último membto de um grupo. Ao invés disso excluindo o " +"grupo %s." + +#: nova/auth/ldapdriver.py:528 +#, python-format +msgid "Group at dn %s doesn't exist" +msgstr "Grupo no dn %s não existe" + +#: nova/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "Procurando usuário: %r" + +#: nova/auth/manager.py:263 +#, python-format +msgid "Failed authorization for access key %s" +msgstr "Falha de autorização para chave de acesso %s" + +#: nova/auth/manager.py:264 +#, python-format +msgid "No user found for access key %s" +msgstr "Nenhum usuário encontrado para chave de acesso %s" + +#: nova/auth/manager.py:270 +#, python-format +msgid "Using project name = user name (%s)" +msgstr "Usando nome do projeto = nome do usuário (%s)" + +#: nova/auth/manager.py:275 +#, python-format +msgid "failed authorization: no project named %s (user=%s)" +msgstr "falha de autorização: nenhum projeto de nome %s (usuário=%s)" + +#: nova/auth/manager.py:277 +#, python-format +msgid "No project called %s could be found" +msgstr "Nenhum projeto chamado %s pode ser encontrado." + +#: nova/auth/manager.py:281 +#, python-format +msgid "Failed authorization: user %s not admin and not member of project %s" +msgstr "" +"Falha de autorização: usuário %s não é administrador nem membro do projeto %s" + +#: nova/auth/manager.py:283 +#, python-format +msgid "User %s is not a member of project %s" +msgstr "Usuário %s não é membro do projeto %s" + +#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#, python-format +msgid "Invalid signature for user %s" +msgstr "Assinatura inválida para usuário %s" + +#: nova/auth/manager.py:293 nova/auth/manager.py:304 +msgid "Signature does not match" +msgstr "Assinatura não confere" + +#: nova/auth/manager.py:374 +msgid "Must specify project" +msgstr "Deve especificar projeto" + +#: nova/auth/manager.py:408 +#, python-format +msgid "The %s role can not be found" +msgstr "O papel %s não foi encontrado" + +#: nova/auth/manager.py:410 +#, python-format +msgid "The %s role is global only" +msgstr "O papel %s é apenas global" + +#: nova/auth/manager.py:412 +#, python-format +msgid "Adding role %s to user %s in project %s" +msgstr "Adicionando papel %s ao usuário %s no projeto %s" + +#: nova/auth/manager.py:438 +#, python-format +msgid "Removing role %s from user %s on project %s" +msgstr "Removendo papel %s do usuário %s no projeto %s" + +#: nova/auth/manager.py:505 +#, python-format +msgid "Created project %s with manager %s" +msgstr "Criado projeto %s com gerente %s" + +#: nova/auth/manager.py:523 +#, python-format +msgid "modifying project %s" +msgstr "modificando projeto %s" + +#: nova/auth/manager.py:553 +#, python-format +msgid "Remove user %s from project %s" +msgstr "Remover usuário %s do projeto %s" + +#: nova/auth/manager.py:581 +#, python-format +msgid "Deleting project %s" +msgstr "Excluindo projeto %s" + +#: nova/auth/manager.py:637 +#, python-format +msgid "Created user %s (admin: %r)" +msgstr "Criado usuário %s (administrador: %r)" + +#: nova/auth/manager.py:645 +#, python-format +msgid "Deleting user %s" +msgstr "" + +#: nova/auth/manager.py:655 +#, python-format +msgid "Access Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:657 +#, python-format +msgid "Secret Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:659 +#, python-format +msgid "Admin status set to %r for user %s" +msgstr "" + +#: nova/auth/manager.py:708 +#, python-format +msgid "No vpn data for project %s" +msgstr "" + +#: nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" +msgstr "" + +#: nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:97 +#, python-format +msgid "Launching VPN for %s" +msgstr "" + +#: nova/compute/api.py:67 +#, python-format +msgid "Instance %d was not found in get_network_topic" +msgstr "" + +#: nova/compute/api.py:73 +#, python-format +msgid "Instance %d has no host" +msgstr "" + +#: nova/compute/api.py:92 +#, python-format +msgid "Quota exceeeded for %s, tried to run %s instances" +msgstr "" + +#: nova/compute/api.py:94 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." +msgstr "" + +#: nova/compute/api.py:109 +msgid "Creating a raw instance" +msgstr "" + +#: nova/compute/api.py:156 +#, python-format +msgid "Going to run %s instances..." +msgstr "" + +#: nova/compute/api.py:180 +#, python-format +msgid "Casting to scheduler for %s/%s's instance %s" +msgstr "" + +#: nova/compute/api.py:279 +#, python-format +msgid "Going to try and terminate %s" +msgstr "" + +#: nova/compute/api.py:283 +#, python-format +msgid "Instance %d was not found during terminate" +msgstr "" + +#: nova/compute/api.py:288 +#, python-format +msgid "Instance %d is already being terminated" +msgstr "" + +#: nova/compute/api.py:450 +#, python-format +msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgstr "" + +#: nova/compute/api.py:465 +msgid "Volume isn't attached to anything!" +msgstr "" + +#: nova/compute/disk.py:71 +#, python-format +msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:75 +#, python-format +msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:128 +#, python-format +msgid "Could not attach image to loopback: %s" +msgstr "" + +#: nova/compute/disk.py:136 +#, python-format +msgid "Failed to load partition: %s" +msgstr "" + +#: nova/compute/disk.py:158 +#, python-format +msgid "Failed to mount filesystem: %s" +msgstr "" + +#: nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "" + +#: nova/compute/manager.py:69 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: nova/compute/manager.py:71 +#, python-format +msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgstr "" + +#: nova/compute/manager.py:75 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: nova/compute/manager.py:77 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: nova/compute/manager.py:82 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: nova/compute/manager.py:157 +msgid "Instance has already been created" +msgstr "" + +#: nova/compute/manager.py:158 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#: nova/compute/manager.py:197 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: nova/compute/manager.py:217 +#, python-format +msgid "Disassociating address %s" +msgstr "" + +#: nova/compute/manager.py:230 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: nova/compute/manager.py:243 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: nova/compute/manager.py:257 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: nova/compute/manager.py:260 +#, python-format +msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:286 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: nova/compute/manager.py:289 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:301 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: nova/compute/manager.py:316 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: nova/compute/manager.py:335 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: nova/compute/manager.py:352 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: nova/compute/manager.py:369 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: nova/compute/manager.py:382 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: nova/compute/manager.py:401 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: nova/compute/manager.py:420 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: nova/compute/manager.py:432 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: nova/compute/manager.py:442 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: nova/compute/manager.py:462 +#, python-format +msgid "instance %s: attaching volume %s to %s" +msgstr "" + +#: nova/compute/manager.py:478 +#, python-format +msgid "instance %s: attach failed %s, removing" +msgstr "" + +#: nova/compute/manager.py:493 +#, python-format +msgid "Detach volume %s from mountpoint %s on instance %s" +msgstr "" + +#: nova/compute/manager.py:497 +#, python-format +msgid "Detaching volume from unknown instance %s" +msgstr "" + +#: nova/compute/monitor.py:259 +#, python-format +msgid "updating %s..." +msgstr "" + +#: nova/compute/monitor.py:289 +msgid "unexpected error during update" +msgstr "" + +#: nova/compute/monitor.py:355 +#, python-format +msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:377 +#, python-format +msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:412 +msgid "unexpected exception getting connection" +msgstr "" + +#: nova/compute/monitor.py:427 +#, python-format +msgid "Found instance: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:43 +msgid "Use of empty request context is deprecated" +msgstr "" + +#: nova/db/sqlalchemy/api.py:132 +#, python-format +msgid "No service for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:229 +#, python-format +msgid "No service for %s, %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:574 +#, python-format +msgid "No floating ip for address %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:668 +#, python-format +msgid "No instance for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:758 nova/virt/libvirt_conn.py:598 +#: nova/virt/xenapi/volumeops.py:48 nova/virt/xenapi/volumeops.py:103 +#, python-format +msgid "Instance %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:891 +#, python-format +msgid "no keypair for user %s, name %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#, python-format +msgid "No network for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1036 +#, python-format +msgid "No network for bridge %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1050 +#, python-format +msgid "No network for instance %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1180 +#, python-format +msgid "Token %s does not exist" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1205 +#, python-format +msgid "No quota for project_id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1356 +#, python-format +msgid "No volume for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1401 +#, python-format +msgid "Volume %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1413 +#, python-format +msgid "No export device found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1426 +#, python-format +msgid "No target id found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1471 +#, python-format +msgid "No security group with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1488 +#, python-format +msgid "No security group named %s for project: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1576 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1650 +#, python-format +msgid "No user for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1666 +#, python-format +msgid "No user for access key %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1728 +#, python-format +msgid "No project with id %s" +msgstr "" + +#: nova/image/glance.py:78 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images" +msgstr "" + +#: nova/image/glance.py:97 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images/detail" +msgstr "" + +#: nova/image/s3.py:82 +#, python-format +msgid "Image %s could not be found" +msgstr "" + +#: nova/network/api.py:39 +#, python-format +msgid "Quota exceeeded for %s, tried to allocate address" +msgstr "" + +#: nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" +msgstr "" + +#: nova/network/linux_net.py:176 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: nova/network/linux_net.py:186 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#: nova/network/linux_net.py:254 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: nova/network/linux_net.py:256 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#: nova/network/linux_net.py:334 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: nova/network/manager.py:135 +msgid "setting network host" +msgstr "" + +#: nova/network/manager.py:190 +#, python-format +msgid "Leasing IP %s" +msgstr "" + +#: nova/network/manager.py:194 +#, python-format +msgid "IP %s leased that isn't associated" +msgstr "" + +#: nova/network/manager.py:197 +#, python-format +msgid "IP %s leased to bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:205 +#, python-format +msgid "IP %s leased that was already deallocated" +msgstr "" + +#: nova/network/manager.py:214 +#, python-format +msgid "IP %s released that isn't associated" +msgstr "" + +#: nova/network/manager.py:217 +#, python-format +msgid "IP %s released from bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:220 +#, python-format +msgid "IP %s released that was not leased" +msgstr "" + +#: nova/network/manager.py:442 +#, python-format +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "" + +#: nova/objectstore/handler.py:106 +#, python-format +msgid "Unknown S3 value type %r" +msgstr "" + +#: nova/objectstore/handler.py:137 +msgid "Authenticated request" +msgstr "" + +#: nova/objectstore/handler.py:182 +msgid "List of buckets requested" +msgstr "" + +#: nova/objectstore/handler.py:209 +#, python-format +msgid "List keys for bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:217 +#, python-format +msgid "Unauthorized attempt to access bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:235 +#, python-format +msgid "Creating bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:245 +#, python-format +msgid "Deleting bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:249 +#, python-format +msgid "Unauthorized attempt to delete bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:271 +#, python-format +msgid "Getting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:274 +#, python-format +msgid "Unauthorized attempt to get object %s from bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:292 +#, python-format +msgid "Putting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:295 +#, python-format +msgid "Unauthorized attempt to upload object %s to bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:314 +#, python-format +msgid "Deleting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:393 +#, python-format +msgid "Not authorized to upload image: invalid directory %s" +msgstr "" + +#: nova/objectstore/handler.py:401 +#, python-format +msgid "Not authorized to upload image: unauthorized bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:406 +#, python-format +msgid "Starting image upload: %s" +msgstr "" + +#: nova/objectstore/handler.py:420 +#, python-format +msgid "Not authorized to update attributes of image %s" +msgstr "" + +#: nova/objectstore/handler.py:428 +#, python-format +msgid "Toggling publicity flag of image %s %r" +msgstr "" + +#: nova/objectstore/handler.py:433 +#, python-format +msgid "Updating user fields on image %s" +msgstr "" + +#: nova/objectstore/handler.py:447 +#, python-format +msgid "Unauthorized attempt to delete image %s" +msgstr "" + +#: nova/objectstore/handler.py:452 +#, python-format +msgid "Deleted image: %s" +msgstr "" + +#: nova/scheduler/chance.py:37 nova/scheduler/simple.py:73 +#: nova/scheduler/simple.py:106 nova/scheduler/simple.py:118 +msgid "No hosts found" +msgstr "" + +#: nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "" + +#: nova/scheduler/manager.py:69 +#, python-format +msgid "Casting to %s %s for %s" +msgstr "" + +#: nova/scheduler/simple.py:63 +msgid "All hosts have too many cores" +msgstr "" + +#: nova/scheduler/simple.py:95 +msgid "All hosts have too many gigabytes" +msgstr "" + +#: nova/scheduler/simple.py:115 +msgid "All hosts have too many networks" +msgstr "" + +#: nova/tests/test_cloud.py:198 +msgid "Can't test instances without a real virtual env." +msgstr "" + +#: nova/tests/test_cloud.py:210 +#, python-format +msgid "Need to watch instance %s until it's running..." +msgstr "" + +#: nova/tests/test_compute.py:104 +#, python-format +msgid "Running instances: %s" +msgstr "" + +#: nova/tests/test_compute.py:110 +#, python-format +msgid "After terminating instances: %s" +msgstr "" + +#: nova/tests/test_rpc.py:89 +#, python-format +msgid "Nested received %s, %s" +msgstr "" + +#: nova/tests/test_rpc.py:94 +#, python-format +msgid "Nested return %s" +msgstr "" + +#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#, python-format +msgid "Received %s" +msgstr "" + +#: nova/tests/test_volume.py:162 +#, python-format +msgid "Target %s allocated" +msgstr "" + +#: nova/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "" + +#: nova/virt/fake.py:210 +#, python-format +msgid "Instance %s Not Found" +msgstr "" + +#: nova/virt/hyperv.py:118 +msgid "In init host" +msgstr "" + +#: nova/virt/hyperv.py:131 +#, python-format +msgid "Attempt to create duplicate vm %s" +msgstr "" + +#: nova/virt/hyperv.py:148 +#, python-format +msgid "Starting VM %s " +msgstr "" + +#: nova/virt/hyperv.py:150 +#, python-format +msgid "Started VM %s " +msgstr "" + +#: nova/virt/hyperv.py:152 +#, python-format +msgid "spawn vm failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:169 +#, python-format +msgid "Failed to create VM %s" +msgstr "" + +#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#, python-format +msgid "Created VM %s..." +msgstr "" + +#: nova/virt/hyperv.py:188 +#, python-format +msgid "Set memory for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:198 +#, python-format +msgid "Set vcpus for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:202 +#, python-format +msgid "Creating disk for %s by attaching disk file %s" +msgstr "" + +#: nova/virt/hyperv.py:227 +#, python-format +msgid "Failed to add diskdrive to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:230 +#, python-format +msgid "New disk drive path is %s" +msgstr "" + +#: nova/virt/hyperv.py:247 +#, python-format +msgid "Failed to add vhd file to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:249 +#, python-format +msgid "Created disk for %s" +msgstr "" + +#: nova/virt/hyperv.py:253 +#, python-format +msgid "Creating nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" +msgstr "" + +#: nova/virt/hyperv.py:273 +#, python-format +msgid "Failed creating port for %s" +msgstr "" + +#: nova/virt/hyperv.py:275 +#, python-format +msgid "Created switch port %s on switch %s" +msgstr "" + +#: nova/virt/hyperv.py:285 +#, python-format +msgid "Failed to add nic to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:287 +#, python-format +msgid "Created nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:320 +#, python-format +msgid "WMI job failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:322 +#, python-format +msgid "WMI job succeeded: %s, Elapsed=%s " +msgstr "" + +#: nova/virt/hyperv.py:358 +#, python-format +msgid "Got request to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:383 +#, python-format +msgid "Failed to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:389 +#, python-format +msgid "Del: disk %s vm %s" +msgstr "" + +#: nova/virt/hyperv.py:405 +#, python-format +msgid "" +"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " +"cpu_time=%s" +msgstr "" + +#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#, python-format +msgid "duplicate name found: %s" +msgstr "" + +#: nova/virt/hyperv.py:444 +#, python-format +msgid "Successfully changed vm state of %s to %s" +msgstr "" + +#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#, python-format +msgid "Failed to change vm state of %s to %s" +msgstr "" + +#: nova/virt/images.py:70 +#, python-format +msgid "Finished retreving %s -- placed in %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:144 +#, python-format +msgid "Connecting to libvirt: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:157 +msgid "Connection to libvirt broke" +msgstr "" + +#: nova/virt/libvirt_conn.py:229 +#, python-format +msgid "instance %s: deleting instance files %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:271 +#, python-format +msgid "No disk at %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:278 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "" + +#: nova/virt/libvirt_conn.py:294 +#, python-format +msgid "instance %s: rebooted" +msgstr "" + +#: nova/virt/libvirt_conn.py:297 +#, python-format +msgid "_wait_for_reboot failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:340 +#, python-format +msgid "instance %s: rescued" +msgstr "" + +#: nova/virt/libvirt_conn.py:343 +#, python-format +msgid "_wait_for_rescue failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:370 +#, python-format +msgid "instance %s: is running" +msgstr "" + +#: nova/virt/libvirt_conn.py:381 +#, python-format +msgid "instance %s: booted" +msgstr "" + +#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#, python-format +msgid "instance %s: failed to boot" +msgstr "" + +#: nova/virt/libvirt_conn.py:395 +#, python-format +msgid "virsh said: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:399 +msgid "cool, it's a device" +msgstr "" + +#: nova/virt/libvirt_conn.py:407 +#, python-format +msgid "data: %r, fpath: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:415 +#, python-format +msgid "Contents of file %s: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:449 +#, python-format +msgid "instance %s: Creating image" +msgstr "" + +#: nova/virt/libvirt_conn.py:505 +#, python-format +msgid "instance %s: injecting key into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:508 +#, python-format +msgid "instance %s: injecting net into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:516 +#, python-format +msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgstr "" + +#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#, python-format +msgid "instance %s: starting toXML method" +msgstr "" + +#: nova/virt/libvirt_conn.py:589 +#, python-format +msgid "instance %s: finished toXML method" +msgstr "" + +#: nova/virt/xenapi_conn.py:113 +msgid "" +"Must specify xenapi_connection_url, xenapi_connection_username (optionally), " +"and xenapi_connection_password to use connection_type=xenapi" +msgstr "" + +#: nova/virt/xenapi_conn.py:263 +#, python-format +msgid "Task [%s] %s status: success %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:271 +#, python-format +msgid "Task [%s] %s status: %s %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#, python-format +msgid "Got exception: %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:72 +#, python-format +msgid "%s: _db_content => %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:247 nova/virt/xenapi/fake.py:338 +#: nova/virt/xenapi/fake.py:356 nova/virt/xenapi/fake.py:404 +msgid "Raising NotImplemented" +msgstr "" + +#: nova/virt/xenapi/fake.py:249 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:283 +#, python-format +msgid "Calling %s %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:288 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:340 +#, python-format +msgid "" +"xenapi.fake does not have an implementation for %s or it has been called " +"with the wrong number of arguments" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:40 +#, python-format +msgid "Found non-unique network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:43 +#, python-format +msgid "Found no network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:127 +#, python-format +msgid "Created VM %s as %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:147 +#, python-format +msgid "Creating VBD for VM %s, VDI %s ... " +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:149 +#, python-format +msgid "Created VBD %s for VM %s, VDI %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:165 +#, python-format +msgid "VBD not found in instance %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:175 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:202 +#, python-format +msgid "Creating VIF for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:205 +#, python-format +msgid "Created VIF %s for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:216 +#, python-format +msgid "Snapshotting VM %s with label '%s'..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:229 +#, python-format +msgid "Created snapshot %s from VM %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:243 +#, python-format +msgid "Asking xapi to upload %s as '%s'" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:261 +#, python-format +msgid "Asking xapi to fetch %s as %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:279 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:290 +#, python-format +msgid "PV Kernel in VDI:%d" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:318 +#, python-format +msgid "VDI %s is still available" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:331 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:333 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:390 +#, python-format +msgid "VHD %s has parent %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:407 +#, python-format +msgid "Re-scanning SR %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:431 +#, python-format +msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:448 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:452 +#, python-format +msgid "Unexpected number of VDIs (%s) found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:62 +#, python-format +msgid "Attempted to create non-unique name %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:99 +#, python-format +msgid "Starting VM %s..." +msgstr "" + +#: nova/virt/xenapi/vmops.py:101 +#, python-format +msgid "Spawning VM %s created %s." +msgstr "" + +#: nova/virt/xenapi/vmops.py:112 +#, python-format +msgid "Instance %s: booted" +msgstr "" + +#: nova/virt/xenapi/vmops.py:137 +#, python-format +msgid "Instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:166 +#, python-format +msgid "Starting snapshot for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:174 +#, python-format +msgid "Unable to Snapshot %s: %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:184 +#, python-format +msgid "Finished snapshot and upload for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:252 +#, python-format +msgid "suspend: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:262 +#, python-format +msgid "resume: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:271 +#, python-format +msgid "Instance not found %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:57 +#, python-format +msgid "Introducing %s..." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:74 +#, python-format +msgid "Introduced %s as %s." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:90 +#, python-format +msgid "Unable to find SR from VBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:96 +#, python-format +msgid "Forgetting SR %s ... " +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:101 +#, python-format +msgid "Ignoring exception %s when getting PBDs for %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:107 +#, python-format +msgid "Ignoring exception %s when unplugging PBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:111 +#, python-format +msgid "Forgetting SR %s done." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:113 +#, python-format +msgid "Ignoring exception %s when forgetting SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:123 +#, python-format +msgid "Unable to introduce VDI on SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:128 +#, python-format +msgid "Unable to get record of VDI %s on" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:146 +#, python-format +msgid "Unable to introduce VDI for SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:175 +#, python-format +msgid "Unable to obtain target information %s, %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:197 +#, python-format +msgid "Mountpoint cannot be translated: %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:51 +#, python-format +msgid "Attach_volume: %s, %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:69 +#, python-format +msgid "Unable to create VDI on SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:81 +#, python-format +msgid "Unable to use SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Unable to attach volume to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:95 +#, python-format +msgid "Mountpoint %s attached to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:106 +#, python-format +msgid "Detach_volume: %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:113 +#, python-format +msgid "Unable to locate volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:121 +#, python-format +msgid "Unable to detach volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:128 +#, python-format +msgid "Mountpoint %s detached from instance %s" +msgstr "" + +#: nova/volume/api.py:44 +#, python-format +msgid "Quota exceeeded for %s, tried to create %sG volume" +msgstr "" + +#: nova/volume/api.py:46 +#, python-format +msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgstr "" + +#: nova/volume/api.py:70 nova/volume/api.py:95 +msgid "Volume status must be available" +msgstr "" + +#: nova/volume/api.py:97 +msgid "Volume is already attached" +msgstr "" + +#: nova/volume/api.py:103 +msgid "Volume is already detached" +msgstr "" + +#: nova/volume/driver.py:76 +#, python-format +msgid "Recovering from a failed execute. Try number %s" +msgstr "" + +#: nova/volume/driver.py:85 +#, python-format +msgid "volume group %s doesn't exist" +msgstr "" + +#: nova/volume/driver.py:210 +#, python-format +msgid "FAKE AOE: %s" +msgstr "" + +#: nova/volume/driver.py:315 +#, python-format +msgid "FAKE ISCSI: %s" +msgstr "" + +#: nova/volume/manager.py:85 +#, python-format +msgid "Re-exporting %s volumes" +msgstr "" + +#: nova/volume/manager.py:93 +#, python-format +msgid "volume %s: creating" +msgstr "" + +#: nova/volume/manager.py:102 +#, python-format +msgid "volume %s: creating lv of size %sG" +msgstr "" + +#: nova/volume/manager.py:106 +#, python-format +msgid "volume %s: creating export" +msgstr "" + +#: nova/volume/manager.py:113 +#, python-format +msgid "volume %s: created successfully" +msgstr "" + +#: nova/volume/manager.py:121 +msgid "Volume is still attached" +msgstr "" + +#: nova/volume/manager.py:123 +msgid "Volume is not local to this node" +msgstr "" + +#: nova/volume/manager.py:124 +#, python-format +msgid "volume %s: removing export" +msgstr "" + +#: nova/volume/manager.py:126 +#, python-format +msgid "volume %s: deleting" +msgstr "" + +#: nova/volume/manager.py:129 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "" diff --git a/locale/ru.po b/locale/ru.po new file mode 100644 index 00000000..c751f41b --- /dev/null +++ b/locale/ru.po @@ -0,0 +1,2136 @@ +# Russian translation for nova +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the nova package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: nova\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"PO-Revision-Date: 2011-01-25 17:45+0000\n" +"Last-Translator: Ilya Alekseyev \n" +"Language-Team: Russian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-01-28 05:20+0000\n" +"X-Generator: Launchpad (build 12177)\n" + +#: nova/crypto.py:46 +msgid "Filename of root CA" +msgstr "" + +#: nova/crypto.py:49 +msgid "Filename of private key" +msgstr "Имя файла секретного ключа" + +#: nova/crypto.py:51 +msgid "Filename of root Certificate Revokation List" +msgstr "" + +#: nova/crypto.py:53 +msgid "Where we keep our keys" +msgstr "" + +#: nova/crypto.py:55 +msgid "Where we keep our root CA" +msgstr "" + +#: nova/crypto.py:57 +msgid "Should we use a CA for each project?" +msgstr "" + +#: nova/crypto.py:61 +#, python-format +msgid "Subject for certificate for users, %s for project, user, timestamp" +msgstr "" + +#: nova/crypto.py:66 +#, python-format +msgid "Subject for certificate for projects, %s for project, timestamp" +msgstr "" + +#: nova/crypto.py:71 +#, python-format +msgid "Subject for certificate for vpns, %s for project, timestamp" +msgstr "" + +#: nova/crypto.py:258 +#, python-format +msgid "Flags path: %s" +msgstr "" + +#: nova/exception.py:33 +msgid "Unexpected error while running command." +msgstr "Неожиданная ошибка при выполнении команды." + +#: nova/exception.py:36 +#, python-format +msgid "" +"%s\n" +"Command: %s\n" +"Exit code: %s\n" +"Stdout: %r\n" +"Stderr: %r" +msgstr "" +"%s\n" +"Команда: %s\n" +"Код завершения: %s\n" +"Stdout: %r\n" +"Stderr: %r" + +#: nova/exception.py:86 +msgid "Uncaught exception" +msgstr "Необработанное исключение" + +#: nova/fakerabbit.py:48 +#, python-format +msgid "(%s) publish (key: %s) %s" +msgstr "" + +#: nova/fakerabbit.py:53 +#, python-format +msgid "Publishing to route %s" +msgstr "" + +#: nova/fakerabbit.py:83 +#, python-format +msgid "Declaring queue %s" +msgstr "Объявление очереди %s" + +#: nova/fakerabbit.py:89 +#, python-format +msgid "Declaring exchange %s" +msgstr "Объявление точки обмена %s" + +#: nova/fakerabbit.py:95 +#, python-format +msgid "Binding %s to %s with key %s" +msgstr "" + +#: nova/fakerabbit.py:120 +#, python-format +msgid "Getting from %s: %s" +msgstr "" + +#: nova/rpc.py:92 +#, python-format +msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgstr "AMQP сервер %s:%d недоступен. Повторная попытка через %d секунд." + +#: nova/rpc.py:99 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "Не удалось подключиться к серверу AMQP после %d попыток. Выключение." + +#: nova/rpc.py:118 +msgid "Reconnected to queue" +msgstr "Переподлючено к очереди" + +#: nova/rpc.py:125 +msgid "Failed to fetch message from queue" +msgstr "Не удалось получить сообщение из очереди" + +#: nova/rpc.py:155 +#, python-format +msgid "Initing the Adapter Consumer for %s" +msgstr "" + +#: nova/rpc.py:170 +#, python-format +msgid "received %s" +msgstr "получено %s" + +#: nova/rpc.py:183 +#, python-format +msgid "no method for message: %s" +msgstr "не определен метод для сообщения: %s" + +#: nova/rpc.py:184 +#, python-format +msgid "No method for message: %s" +msgstr "Не определен метод для сообщения: %s" + +#: nova/rpc.py:245 +#, python-format +msgid "Returning exception %s to caller" +msgstr "" + +#: nova/rpc.py:286 +#, python-format +msgid "unpacked context: %s" +msgstr "" + +#: nova/rpc.py:305 +msgid "Making asynchronous call..." +msgstr "Выполняется асинхронный вызов..." + +#: nova/rpc.py:308 +#, python-format +msgid "MSG_ID is %s" +msgstr "MSG_ID is %s" + +#: nova/rpc.py:356 +#, python-format +msgid "response %s" +msgstr "" + +#: nova/rpc.py:365 +#, python-format +msgid "topic is %s" +msgstr "тема %s" + +#: nova/rpc.py:366 +#, python-format +msgid "message %s" +msgstr "сообщение %s" + +#: nova/service.py:157 +#, python-format +msgid "Starting %s node" +msgstr "Запускается нода %s" + +#: nova/service.py:169 +msgid "Service killed that has no database entry" +msgstr "" + +#: nova/service.py:190 +msgid "The service database object disappeared, Recreating it." +msgstr "Объект сервиса в базе данных отсутствует, Повторное создание." + +#: nova/service.py:202 +msgid "Recovered model server connection!" +msgstr "" + +#: nova/service.py:208 +msgid "model server went away" +msgstr "" + +#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#, python-format +msgid "Data store %s is unreachable. Trying again in %d seconds." +msgstr "Хранилище данных %s недоступно. Повторная попытка через %d секунд." + +#: nova/service.py:232 nova/twistd.py:232 +#, python-format +msgid "Serving %s" +msgstr "" + +#: nova/service.py:234 nova/twistd.py:264 +msgid "Full set of FLAGS:" +msgstr "" + +#: nova/twistd.py:211 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "pidfile %s не обнаружен. Демон не запущен?\n" + +#: nova/twistd.py:268 +#, python-format +msgid "Starting %s" +msgstr "Запускается %s" + +#: nova/utils.py:53 +#, python-format +msgid "Inner Exception: %s" +msgstr "Вложенное исключение: %s" + +#: nova/utils.py:54 +#, python-format +msgid "Class %s cannot be found" +msgstr "Класс %s не найден" + +#: nova/utils.py:113 +#, python-format +msgid "Fetching %s" +msgstr "" + +#: nova/utils.py:125 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "" + +#: nova/utils.py:138 +#, python-format +msgid "Result was %s" +msgstr "Результат %s" + +#: nova/utils.py:171 +#, python-format +msgid "debug in callback: %s" +msgstr "" + +#: nova/utils.py:176 +#, python-format +msgid "Running %s" +msgstr "" + +#: nova/utils.py:207 +#, python-format +msgid "Couldn't get IP, using 127.0.0.1 %s" +msgstr "Не удалось получить IP, используем 127.0.0.1 %s" + +#: nova/utils.py:289 +#, python-format +msgid "Invalid backend: %s" +msgstr "" + +#: nova/utils.py:300 +#, python-format +msgid "backend %s" +msgstr "" + +#: nova/api/ec2/__init__.py:133 +msgid "Too many failed authentications." +msgstr "Слишком много неудачных попыток аутентификации." + +#: nova/api/ec2/__init__.py:142 +#, python-format +msgid "" +"Access key %s has had %d failed authentications and will be locked out for " +"%d minutes." +msgstr "" + +#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#, python-format +msgid "Authentication Failure: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:190 +#, python-format +msgid "Authenticated Request For %s:%s)" +msgstr "" + +#: nova/api/ec2/__init__.py:227 +#, python-format +msgid "action: %s" +msgstr "действие: %s" + +#: nova/api/ec2/__init__.py:229 +#, python-format +msgid "arg: %s\t\tval: %s" +msgstr "arg: %s\t\tval: %s" + +#: nova/api/ec2/__init__.py:301 +#, python-format +msgid "Unauthorized request for controller=%s and action=%s" +msgstr "" + +#: nova/api/ec2/__init__.py:339 +#, python-format +msgid "NotFound raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:342 +#, python-format +msgid "ApiError raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:349 +#, python-format +msgid "Unexpected error raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:354 +msgid "An unknown error has occurred. Please try your request again." +msgstr "" +"Произошла неизвестная ошибка. Пожалуйста, попытайтесь повторить ваш запрос." + +#: nova/api/ec2/admin.py:84 +#, python-format +msgid "Creating new user: %s" +msgstr "Создание нового пользователя: %s" + +#: nova/api/ec2/admin.py:92 +#, python-format +msgid "Deleting user: %s" +msgstr "Удаление пользователя: %s" + +#: nova/api/ec2/admin.py:114 +#, python-format +msgid "Adding role %s to user %s for project %s" +msgstr "Добавление роли %s для пользователя %s для проекта %s" + +#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#, python-format +msgid "Adding sitewide role %s to user %s" +msgstr "" + +#: nova/api/ec2/admin.py:122 +#, python-format +msgid "Removing role %s from user %s for project %s" +msgstr "Удаление роли %s пользователя %s для проекта %s" + +#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#, python-format +msgid "Removing sitewide role %s from user %s" +msgstr "" + +#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 +msgid "operation must be add or remove" +msgstr "" + +#: nova/api/ec2/admin.py:142 +#, python-format +msgid "Getting x509 for user: %s on project: %s" +msgstr "" + +#: nova/api/ec2/admin.py:159 +#, python-format +msgid "Create project %s managed by %s" +msgstr "Создать проект %s под управлением %s" + +#: nova/api/ec2/admin.py:170 +#, python-format +msgid "Delete project: %s" +msgstr "Удалить проект: %s" + +#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#, python-format +msgid "Adding user %s to project %s" +msgstr "Добавление пользователя %s к проекту %s" + +#: nova/api/ec2/admin.py:188 +#, python-format +msgid "Removing user %s from project %s" +msgstr "Удаление пользователя %s с проекта %s" + +#: nova/api/ec2/apirequest.py:95 +#, python-format +msgid "Unsupported API request: controller = %s,action = %s" +msgstr "" + +#: nova/api/ec2/cloud.py:117 +#, python-format +msgid "Generating root CA: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:277 +#, python-format +msgid "Create key pair %s" +msgstr "Создание пары ключей %s" + +#: nova/api/ec2/cloud.py:285 +#, python-format +msgid "Delete key pair %s" +msgstr "Удаление пары ключей %s" + +#: nova/api/ec2/cloud.py:357 +#, python-format +msgid "%s is not a valid ipProtocol" +msgstr "" + +#: nova/api/ec2/cloud.py:361 +msgid "Invalid port range" +msgstr "Неверный диапазон портов" + +#: nova/api/ec2/cloud.py:392 +#, python-format +msgid "Revoke security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 +msgid "No rule for the specified parameters." +msgstr "" + +#: nova/api/ec2/cloud.py:421 +#, python-format +msgid "Authorize security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:432 +#, python-format +msgid "This rule already exists in group %s" +msgstr "Это правило уже существует в группе %s" + +#: nova/api/ec2/cloud.py:460 +#, python-format +msgid "Create Security Group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:463 +#, python-format +msgid "group %s already exists" +msgstr "группа %s уже существует" + +#: nova/api/ec2/cloud.py:475 +#, python-format +msgid "Delete security group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:543 +#, python-format +msgid "Create volume of %s GB" +msgstr "Создание раздела %s ГБ" + +#: nova/api/ec2/cloud.py:567 +#, python-format +msgid "Attach volume %s to instacne %s at %s" +msgstr "" + +#: nova/api/ec2/cloud.py:579 +#, python-format +msgid "Detach volume %s" +msgstr "" + +#: nova/api/ec2/cloud.py:686 +msgid "Allocate address" +msgstr "" + +#: nova/api/ec2/cloud.py:691 +#, python-format +msgid "Release address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:696 +#, python-format +msgid "Associate address %s to instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:703 +#, python-format +msgid "Disassociate address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:730 +msgid "Going to start terminating instances" +msgstr "" + +#: nova/api/ec2/cloud.py:738 +#, python-format +msgid "Reboot instance %r" +msgstr "" + +#: nova/api/ec2/cloud.py:775 +#, python-format +msgid "De-registering image %s" +msgstr "" + +#: nova/api/ec2/cloud.py:783 +#, python-format +msgid "Registered image %s with id %s" +msgstr "" + +#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#, python-format +msgid "attribute not supported: %s" +msgstr "аттрибут не поддерживается: %s" + +#: nova/api/ec2/cloud.py:794 +#, python-format +msgid "invalid id: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:807 +msgid "user or group not specified" +msgstr "не указан пользователь или группа" + +#: nova/api/ec2/cloud.py:809 +msgid "only group \"all\" is supported" +msgstr "" + +#: nova/api/ec2/cloud.py:811 +msgid "operation_type must be add or remove" +msgstr "" + +#: nova/api/ec2/cloud.py:812 +#, python-format +msgid "Updating image %s publicity" +msgstr "" + +#: nova/api/ec2/metadatarequesthandler.py:75 +#, python-format +msgid "Failed to get metadata for ip: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:70 +#, python-format +msgid "Caught error: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:86 +msgid "Including admin operations in API." +msgstr "" + +#: nova/api/openstack/servers.py:184 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:199 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: nova/api/openstack/servers.py:213 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:224 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: nova/api/openstack/servers.py:235 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: nova/api/openstack/servers.py:246 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: nova/api/openstack/servers.py:257 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: nova/auth/dbdriver.py:84 +#, python-format +msgid "User %s already exists" +msgstr "Пользователь %s уже существует" + +#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#, python-format +msgid "Project can't be created because manager %s doesn't exist" +msgstr "Проект не может быть создан поскольку менеджер %s не существует" + +#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#, python-format +msgid "Project can't be created because project %s already exists" +msgstr "Проект не может быть созан поскольку проект %s уже существует" + +#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#, python-format +msgid "Project can't be modified because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:245 +#, python-format +msgid "User \"%s\" not found" +msgstr "Пользователь \"%s\" не существует" + +#: nova/auth/dbdriver.py:248 +#, python-format +msgid "Project \"%s\" not found" +msgstr "Проект \"%s\" не найден" + +#: nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "" + +#: nova/auth/ldapdriver.py:181 +#, python-format +msgid "LDAP object for %s doesn't exist" +msgstr "Объект LDAP %s не существует" + +#: nova/auth/ldapdriver.py:218 +#, python-format +msgid "Project can't be created because user %s doesn't exist" +msgstr "Проект не может быть создан поскольку пользователь %s не существует" + +#: nova/auth/ldapdriver.py:478 +#, python-format +msgid "User %s is already a member of the group %s" +msgstr "Пользователь %s уже член группы %s" + +#: nova/auth/ldapdriver.py:507 +#, python-format +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." +msgstr "" + +#: nova/auth/ldapdriver.py:528 +#, python-format +msgid "Group at dn %s doesn't exist" +msgstr "" + +#: nova/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "" + +#: nova/auth/manager.py:263 +#, python-format +msgid "Failed authorization for access key %s" +msgstr "" + +#: nova/auth/manager.py:264 +#, python-format +msgid "No user found for access key %s" +msgstr "" + +#: nova/auth/manager.py:270 +#, python-format +msgid "Using project name = user name (%s)" +msgstr "" + +#: nova/auth/manager.py:275 +#, python-format +msgid "failed authorization: no project named %s (user=%s)" +msgstr "" + +#: nova/auth/manager.py:277 +#, python-format +msgid "No project called %s could be found" +msgstr "" + +#: nova/auth/manager.py:281 +#, python-format +msgid "Failed authorization: user %s not admin and not member of project %s" +msgstr "" + +#: nova/auth/manager.py:283 +#, python-format +msgid "User %s is not a member of project %s" +msgstr "Пользователь %s не является членом группы %s" + +#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#, python-format +msgid "Invalid signature for user %s" +msgstr "Не допустимая подпись для пользователя %s" + +#: nova/auth/manager.py:293 nova/auth/manager.py:304 +msgid "Signature does not match" +msgstr "Подпись не совпадает" + +#: nova/auth/manager.py:374 +msgid "Must specify project" +msgstr "Необходимо указать проект" + +#: nova/auth/manager.py:408 +#, python-format +msgid "The %s role can not be found" +msgstr "Роль %s не может быть найдена" + +#: nova/auth/manager.py:410 +#, python-format +msgid "The %s role is global only" +msgstr "" + +#: nova/auth/manager.py:412 +#, python-format +msgid "Adding role %s to user %s in project %s" +msgstr "Добавление роли %s для пользователя %s в проект %s" + +#: nova/auth/manager.py:438 +#, python-format +msgid "Removing role %s from user %s on project %s" +msgstr "Удаление роли %s пользователя %s в проекте %s" + +#: nova/auth/manager.py:505 +#, python-format +msgid "Created project %s with manager %s" +msgstr "Создан проект %s под управлением %s" + +#: nova/auth/manager.py:523 +#, python-format +msgid "modifying project %s" +msgstr "изменение проекта %s" + +#: nova/auth/manager.py:553 +#, python-format +msgid "Remove user %s from project %s" +msgstr "Удалить пользователя %s из проекта %s" + +#: nova/auth/manager.py:581 +#, python-format +msgid "Deleting project %s" +msgstr "Удаление проекта %s" + +#: nova/auth/manager.py:637 +#, python-format +msgid "Created user %s (admin: %r)" +msgstr "Создан пользователь %s (администратор: %r)" + +#: nova/auth/manager.py:645 +#, python-format +msgid "Deleting user %s" +msgstr "Удаление пользователя %s" + +#: nova/auth/manager.py:655 +#, python-format +msgid "Access Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:657 +#, python-format +msgid "Secret Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:659 +#, python-format +msgid "Admin status set to %r for user %s" +msgstr "" + +#: nova/auth/manager.py:708 +#, python-format +msgid "No vpn data for project %s" +msgstr "Нет vpn данных для проекта %s" + +#: nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" +msgstr "" + +#: nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:97 +#, python-format +msgid "Launching VPN for %s" +msgstr "Запуск VPN для %s" + +#: nova/compute/api.py:67 +#, python-format +msgid "Instance %d was not found in get_network_topic" +msgstr "" + +#: nova/compute/api.py:73 +#, python-format +msgid "Instance %d has no host" +msgstr "" + +#: nova/compute/api.py:92 +#, python-format +msgid "Quota exceeeded for %s, tried to run %s instances" +msgstr "" + +#: nova/compute/api.py:94 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." +msgstr "" + +#: nova/compute/api.py:109 +msgid "Creating a raw instance" +msgstr "" + +#: nova/compute/api.py:156 +#, python-format +msgid "Going to run %s instances..." +msgstr "" + +#: nova/compute/api.py:180 +#, python-format +msgid "Casting to scheduler for %s/%s's instance %s" +msgstr "" + +#: nova/compute/api.py:279 +#, python-format +msgid "Going to try and terminate %s" +msgstr "" + +#: nova/compute/api.py:283 +#, python-format +msgid "Instance %d was not found during terminate" +msgstr "" + +#: nova/compute/api.py:288 +#, python-format +msgid "Instance %d is already being terminated" +msgstr "" + +#: nova/compute/api.py:450 +#, python-format +msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgstr "" + +#: nova/compute/api.py:465 +msgid "Volume isn't attached to anything!" +msgstr "" + +#: nova/compute/disk.py:71 +#, python-format +msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:75 +#, python-format +msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:128 +#, python-format +msgid "Could not attach image to loopback: %s" +msgstr "" + +#: nova/compute/disk.py:136 +#, python-format +msgid "Failed to load partition: %s" +msgstr "" + +#: nova/compute/disk.py:158 +#, python-format +msgid "Failed to mount filesystem: %s" +msgstr "Ошибка монтирования файловой системы: %s" + +#: nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "" + +#: nova/compute/manager.py:69 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: nova/compute/manager.py:71 +#, python-format +msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgstr "" + +#: nova/compute/manager.py:75 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: nova/compute/manager.py:77 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: nova/compute/manager.py:82 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: nova/compute/manager.py:157 +msgid "Instance has already been created" +msgstr "" + +#: nova/compute/manager.py:158 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#: nova/compute/manager.py:197 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: nova/compute/manager.py:217 +#, python-format +msgid "Disassociating address %s" +msgstr "" + +#: nova/compute/manager.py:230 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: nova/compute/manager.py:243 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: nova/compute/manager.py:257 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: nova/compute/manager.py:260 +#, python-format +msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:286 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: nova/compute/manager.py:289 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:301 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: nova/compute/manager.py:316 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: nova/compute/manager.py:335 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: nova/compute/manager.py:352 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: nova/compute/manager.py:369 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: nova/compute/manager.py:382 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: nova/compute/manager.py:401 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: nova/compute/manager.py:420 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: nova/compute/manager.py:432 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: nova/compute/manager.py:442 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: nova/compute/manager.py:462 +#, python-format +msgid "instance %s: attaching volume %s to %s" +msgstr "" + +#: nova/compute/manager.py:478 +#, python-format +msgid "instance %s: attach failed %s, removing" +msgstr "" + +#: nova/compute/manager.py:493 +#, python-format +msgid "Detach volume %s from mountpoint %s on instance %s" +msgstr "" + +#: nova/compute/manager.py:497 +#, python-format +msgid "Detaching volume from unknown instance %s" +msgstr "" + +#: nova/compute/monitor.py:259 +#, python-format +msgid "updating %s..." +msgstr "обновление %s..." + +#: nova/compute/monitor.py:289 +msgid "unexpected error during update" +msgstr "неожиданная ошибка во время обновления" + +#: nova/compute/monitor.py:355 +#, python-format +msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:377 +#, python-format +msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:412 +msgid "unexpected exception getting connection" +msgstr "" + +#: nova/compute/monitor.py:427 +#, python-format +msgid "Found instance: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:43 +msgid "Use of empty request context is deprecated" +msgstr "" + +#: nova/db/sqlalchemy/api.py:132 +#, python-format +msgid "No service for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:229 +#, python-format +msgid "No service for %s, %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:574 +#, python-format +msgid "No floating ip for address %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:668 +#, python-format +msgid "No instance for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:758 nova/virt/libvirt_conn.py:598 +#: nova/virt/xenapi/volumeops.py:48 nova/virt/xenapi/volumeops.py:103 +#, python-format +msgid "Instance %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:891 +#, python-format +msgid "no keypair for user %s, name %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#, python-format +msgid "No network for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1036 +#, python-format +msgid "No network for bridge %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1050 +#, python-format +msgid "No network for instance %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1180 +#, python-format +msgid "Token %s does not exist" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1205 +#, python-format +msgid "No quota for project_id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1356 +#, python-format +msgid "No volume for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1401 +#, python-format +msgid "Volume %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1413 +#, python-format +msgid "No export device found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1426 +#, python-format +msgid "No target id found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1471 +#, python-format +msgid "No security group with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1488 +#, python-format +msgid "No security group named %s for project: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1576 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1650 +#, python-format +msgid "No user for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1666 +#, python-format +msgid "No user for access key %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1728 +#, python-format +msgid "No project with id %s" +msgstr "" + +#: nova/image/glance.py:78 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images" +msgstr "" + +#: nova/image/glance.py:97 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images/detail" +msgstr "" + +#: nova/image/s3.py:82 +#, python-format +msgid "Image %s could not be found" +msgstr "" + +#: nova/network/api.py:39 +#, python-format +msgid "Quota exceeeded for %s, tried to allocate address" +msgstr "" + +#: nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" +msgstr "" + +#: nova/network/linux_net.py:176 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: nova/network/linux_net.py:186 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#: nova/network/linux_net.py:254 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: nova/network/linux_net.py:256 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#: nova/network/linux_net.py:334 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: nova/network/manager.py:135 +msgid "setting network host" +msgstr "" + +#: nova/network/manager.py:190 +#, python-format +msgid "Leasing IP %s" +msgstr "" + +#: nova/network/manager.py:194 +#, python-format +msgid "IP %s leased that isn't associated" +msgstr "" + +#: nova/network/manager.py:197 +#, python-format +msgid "IP %s leased to bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:205 +#, python-format +msgid "IP %s leased that was already deallocated" +msgstr "" + +#: nova/network/manager.py:214 +#, python-format +msgid "IP %s released that isn't associated" +msgstr "" + +#: nova/network/manager.py:217 +#, python-format +msgid "IP %s released from bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:220 +#, python-format +msgid "IP %s released that was not leased" +msgstr "" + +#: nova/network/manager.py:442 +#, python-format +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "" + +#: nova/objectstore/handler.py:106 +#, python-format +msgid "Unknown S3 value type %r" +msgstr "" + +#: nova/objectstore/handler.py:137 +msgid "Authenticated request" +msgstr "" + +#: nova/objectstore/handler.py:182 +msgid "List of buckets requested" +msgstr "" + +#: nova/objectstore/handler.py:209 +#, python-format +msgid "List keys for bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:217 +#, python-format +msgid "Unauthorized attempt to access bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:235 +#, python-format +msgid "Creating bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:245 +#, python-format +msgid "Deleting bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:249 +#, python-format +msgid "Unauthorized attempt to delete bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:271 +#, python-format +msgid "Getting object: %s / %s" +msgstr "Получение объекта: %s / %s" + +#: nova/objectstore/handler.py:274 +#, python-format +msgid "Unauthorized attempt to get object %s from bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:292 +#, python-format +msgid "Putting object: %s / %s" +msgstr "Вставка объекта: %s / %s" + +#: nova/objectstore/handler.py:295 +#, python-format +msgid "Unauthorized attempt to upload object %s to bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:314 +#, python-format +msgid "Deleting object: %s / %s" +msgstr "Удаление объекта: %s / %s" + +#: nova/objectstore/handler.py:393 +#, python-format +msgid "Not authorized to upload image: invalid directory %s" +msgstr "" + +#: nova/objectstore/handler.py:401 +#, python-format +msgid "Not authorized to upload image: unauthorized bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:406 +#, python-format +msgid "Starting image upload: %s" +msgstr "" + +#: nova/objectstore/handler.py:420 +#, python-format +msgid "Not authorized to update attributes of image %s" +msgstr "" + +#: nova/objectstore/handler.py:428 +#, python-format +msgid "Toggling publicity flag of image %s %r" +msgstr "" + +#: nova/objectstore/handler.py:433 +#, python-format +msgid "Updating user fields on image %s" +msgstr "" + +#: nova/objectstore/handler.py:447 +#, python-format +msgid "Unauthorized attempt to delete image %s" +msgstr "" + +#: nova/objectstore/handler.py:452 +#, python-format +msgid "Deleted image: %s" +msgstr "Удаленное изображение: %s" + +#: nova/scheduler/chance.py:37 nova/scheduler/simple.py:73 +#: nova/scheduler/simple.py:106 nova/scheduler/simple.py:118 +msgid "No hosts found" +msgstr "" + +#: nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "" + +#: nova/scheduler/manager.py:69 +#, python-format +msgid "Casting to %s %s for %s" +msgstr "" + +#: nova/scheduler/simple.py:63 +msgid "All hosts have too many cores" +msgstr "" + +#: nova/scheduler/simple.py:95 +msgid "All hosts have too many gigabytes" +msgstr "" + +#: nova/scheduler/simple.py:115 +msgid "All hosts have too many networks" +msgstr "" + +#: nova/tests/test_cloud.py:198 +msgid "Can't test instances without a real virtual env." +msgstr "" + +#: nova/tests/test_cloud.py:210 +#, python-format +msgid "Need to watch instance %s until it's running..." +msgstr "" + +#: nova/tests/test_compute.py:104 +#, python-format +msgid "Running instances: %s" +msgstr "" + +#: nova/tests/test_compute.py:110 +#, python-format +msgid "After terminating instances: %s" +msgstr "" + +#: nova/tests/test_rpc.py:89 +#, python-format +msgid "Nested received %s, %s" +msgstr "" + +#: nova/tests/test_rpc.py:94 +#, python-format +msgid "Nested return %s" +msgstr "" + +#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#, python-format +msgid "Received %s" +msgstr "Получено %s" + +#: nova/tests/test_volume.py:162 +#, python-format +msgid "Target %s allocated" +msgstr "" + +#: nova/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "" + +#: nova/virt/fake.py:210 +#, python-format +msgid "Instance %s Not Found" +msgstr "" + +#: nova/virt/hyperv.py:118 +msgid "In init host" +msgstr "" + +#: nova/virt/hyperv.py:131 +#, python-format +msgid "Attempt to create duplicate vm %s" +msgstr "" + +#: nova/virt/hyperv.py:148 +#, python-format +msgid "Starting VM %s " +msgstr "Запускается VM %s " + +#: nova/virt/hyperv.py:150 +#, python-format +msgid "Started VM %s " +msgstr "Запущен VM %s " + +#: nova/virt/hyperv.py:152 +#, python-format +msgid "spawn vm failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:169 +#, python-format +msgid "Failed to create VM %s" +msgstr "" + +#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#, python-format +msgid "Created VM %s..." +msgstr "" + +#: nova/virt/hyperv.py:188 +#, python-format +msgid "Set memory for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:198 +#, python-format +msgid "Set vcpus for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:202 +#, python-format +msgid "Creating disk for %s by attaching disk file %s" +msgstr "" + +#: nova/virt/hyperv.py:227 +#, python-format +msgid "Failed to add diskdrive to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:230 +#, python-format +msgid "New disk drive path is %s" +msgstr "" + +#: nova/virt/hyperv.py:247 +#, python-format +msgid "Failed to add vhd file to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:249 +#, python-format +msgid "Created disk for %s" +msgstr "Создан диск для %s" + +#: nova/virt/hyperv.py:253 +#, python-format +msgid "Creating nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" +msgstr "" + +#: nova/virt/hyperv.py:273 +#, python-format +msgid "Failed creating port for %s" +msgstr "" + +#: nova/virt/hyperv.py:275 +#, python-format +msgid "Created switch port %s on switch %s" +msgstr "" + +#: nova/virt/hyperv.py:285 +#, python-format +msgid "Failed to add nic to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:287 +#, python-format +msgid "Created nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:320 +#, python-format +msgid "WMI job failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:322 +#, python-format +msgid "WMI job succeeded: %s, Elapsed=%s " +msgstr "" + +#: nova/virt/hyperv.py:358 +#, python-format +msgid "Got request to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:383 +#, python-format +msgid "Failed to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:389 +#, python-format +msgid "Del: disk %s vm %s" +msgstr "" + +#: nova/virt/hyperv.py:405 +#, python-format +msgid "" +"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " +"cpu_time=%s" +msgstr "" + +#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#, python-format +msgid "duplicate name found: %s" +msgstr "" + +#: nova/virt/hyperv.py:444 +#, python-format +msgid "Successfully changed vm state of %s to %s" +msgstr "" + +#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#, python-format +msgid "Failed to change vm state of %s to %s" +msgstr "" + +#: nova/virt/images.py:70 +#, python-format +msgid "Finished retreving %s -- placed in %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:144 +#, python-format +msgid "Connecting to libvirt: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:157 +msgid "Connection to libvirt broke" +msgstr "" + +#: nova/virt/libvirt_conn.py:229 +#, python-format +msgid "instance %s: deleting instance files %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:271 +#, python-format +msgid "No disk at %s" +msgstr "Нет диска в %s" + +#: nova/virt/libvirt_conn.py:278 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "" + +#: nova/virt/libvirt_conn.py:294 +#, python-format +msgid "instance %s: rebooted" +msgstr "" + +#: nova/virt/libvirt_conn.py:297 +#, python-format +msgid "_wait_for_reboot failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:340 +#, python-format +msgid "instance %s: rescued" +msgstr "" + +#: nova/virt/libvirt_conn.py:343 +#, python-format +msgid "_wait_for_rescue failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:370 +#, python-format +msgid "instance %s: is running" +msgstr "" + +#: nova/virt/libvirt_conn.py:381 +#, python-format +msgid "instance %s: booted" +msgstr "" + +#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#, python-format +msgid "instance %s: failed to boot" +msgstr "" + +#: nova/virt/libvirt_conn.py:395 +#, python-format +msgid "virsh said: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:399 +msgid "cool, it's a device" +msgstr "" + +#: nova/virt/libvirt_conn.py:407 +#, python-format +msgid "data: %r, fpath: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:415 +#, python-format +msgid "Contents of file %s: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:449 +#, python-format +msgid "instance %s: Creating image" +msgstr "" + +#: nova/virt/libvirt_conn.py:505 +#, python-format +msgid "instance %s: injecting key into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:508 +#, python-format +msgid "instance %s: injecting net into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:516 +#, python-format +msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgstr "" + +#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#, python-format +msgid "instance %s: starting toXML method" +msgstr "" + +#: nova/virt/libvirt_conn.py:589 +#, python-format +msgid "instance %s: finished toXML method" +msgstr "" + +#: nova/virt/xenapi_conn.py:113 +msgid "" +"Must specify xenapi_connection_url, xenapi_connection_username (optionally), " +"and xenapi_connection_password to use connection_type=xenapi" +msgstr "" + +#: nova/virt/xenapi_conn.py:263 +#, python-format +msgid "Task [%s] %s status: success %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:271 +#, python-format +msgid "Task [%s] %s status: %s %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#, python-format +msgid "Got exception: %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:72 +#, python-format +msgid "%s: _db_content => %s" +msgstr "%s: _db_content => %s" + +#: nova/virt/xenapi/fake.py:247 nova/virt/xenapi/fake.py:338 +#: nova/virt/xenapi/fake.py:356 nova/virt/xenapi/fake.py:404 +msgid "Raising NotImplemented" +msgstr "" + +#: nova/virt/xenapi/fake.py:249 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:283 +#, python-format +msgid "Calling %s %s" +msgstr "Звонок %s %s" + +#: nova/virt/xenapi/fake.py:288 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:340 +#, python-format +msgid "" +"xenapi.fake does not have an implementation for %s or it has been called " +"with the wrong number of arguments" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:40 +#, python-format +msgid "Found non-unique network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:43 +#, python-format +msgid "Found no network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:127 +#, python-format +msgid "Created VM %s as %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:147 +#, python-format +msgid "Creating VBD for VM %s, VDI %s ... " +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:149 +#, python-format +msgid "Created VBD %s for VM %s, VDI %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:165 +#, python-format +msgid "VBD not found in instance %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:175 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:202 +#, python-format +msgid "Creating VIF for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:205 +#, python-format +msgid "Created VIF %s for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:216 +#, python-format +msgid "Snapshotting VM %s with label '%s'..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:229 +#, python-format +msgid "Created snapshot %s from VM %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:243 +#, python-format +msgid "Asking xapi to upload %s as '%s'" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:261 +#, python-format +msgid "Asking xapi to fetch %s as %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:279 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:290 +#, python-format +msgid "PV Kernel in VDI:%d" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:318 +#, python-format +msgid "VDI %s is still available" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:331 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:333 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:390 +#, python-format +msgid "VHD %s has parent %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:407 +#, python-format +msgid "Re-scanning SR %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:431 +#, python-format +msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:448 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:452 +#, python-format +msgid "Unexpected number of VDIs (%s) found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:62 +#, python-format +msgid "Attempted to create non-unique name %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:99 +#, python-format +msgid "Starting VM %s..." +msgstr "" + +#: nova/virt/xenapi/vmops.py:101 +#, python-format +msgid "Spawning VM %s created %s." +msgstr "" + +#: nova/virt/xenapi/vmops.py:112 +#, python-format +msgid "Instance %s: booted" +msgstr "" + +#: nova/virt/xenapi/vmops.py:137 +#, python-format +msgid "Instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:166 +#, python-format +msgid "Starting snapshot for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:174 +#, python-format +msgid "Unable to Snapshot %s: %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:184 +#, python-format +msgid "Finished snapshot and upload for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:252 +#, python-format +msgid "suspend: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:262 +#, python-format +msgid "resume: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:271 +#, python-format +msgid "Instance not found %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:57 +#, python-format +msgid "Introducing %s..." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:74 +#, python-format +msgid "Introduced %s as %s." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:90 +#, python-format +msgid "Unable to find SR from VBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:96 +#, python-format +msgid "Forgetting SR %s ... " +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:101 +#, python-format +msgid "Ignoring exception %s when getting PBDs for %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:107 +#, python-format +msgid "Ignoring exception %s when unplugging PBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:111 +#, python-format +msgid "Forgetting SR %s done." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:113 +#, python-format +msgid "Ignoring exception %s when forgetting SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:123 +#, python-format +msgid "Unable to introduce VDI on SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:128 +#, python-format +msgid "Unable to get record of VDI %s on" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:146 +#, python-format +msgid "Unable to introduce VDI for SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:175 +#, python-format +msgid "Unable to obtain target information %s, %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:197 +#, python-format +msgid "Mountpoint cannot be translated: %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:51 +#, python-format +msgid "Attach_volume: %s, %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:69 +#, python-format +msgid "Unable to create VDI on SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:81 +#, python-format +msgid "Unable to use SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Unable to attach volume to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:95 +#, python-format +msgid "Mountpoint %s attached to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:106 +#, python-format +msgid "Detach_volume: %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:113 +#, python-format +msgid "Unable to locate volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:121 +#, python-format +msgid "Unable to detach volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:128 +#, python-format +msgid "Mountpoint %s detached from instance %s" +msgstr "" + +#: nova/volume/api.py:44 +#, python-format +msgid "Quota exceeeded for %s, tried to create %sG volume" +msgstr "" + +#: nova/volume/api.py:46 +#, python-format +msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgstr "" + +#: nova/volume/api.py:70 nova/volume/api.py:95 +msgid "Volume status must be available" +msgstr "" + +#: nova/volume/api.py:97 +msgid "Volume is already attached" +msgstr "" + +#: nova/volume/api.py:103 +msgid "Volume is already detached" +msgstr "" + +#: nova/volume/driver.py:76 +#, python-format +msgid "Recovering from a failed execute. Try number %s" +msgstr "" + +#: nova/volume/driver.py:85 +#, python-format +msgid "volume group %s doesn't exist" +msgstr "" + +#: nova/volume/driver.py:210 +#, python-format +msgid "FAKE AOE: %s" +msgstr "" + +#: nova/volume/driver.py:315 +#, python-format +msgid "FAKE ISCSI: %s" +msgstr "" + +#: nova/volume/manager.py:85 +#, python-format +msgid "Re-exporting %s volumes" +msgstr "" + +#: nova/volume/manager.py:93 +#, python-format +msgid "volume %s: creating" +msgstr "" + +#: nova/volume/manager.py:102 +#, python-format +msgid "volume %s: creating lv of size %sG" +msgstr "" + +#: nova/volume/manager.py:106 +#, python-format +msgid "volume %s: creating export" +msgstr "" + +#: nova/volume/manager.py:113 +#, python-format +msgid "volume %s: created successfully" +msgstr "" + +#: nova/volume/manager.py:121 +msgid "Volume is still attached" +msgstr "" + +#: nova/volume/manager.py:123 +msgid "Volume is not local to this node" +msgstr "" + +#: nova/volume/manager.py:124 +#, python-format +msgid "volume %s: removing export" +msgstr "" + +#: nova/volume/manager.py:126 +#, python-format +msgid "volume %s: deleting" +msgstr "" + +#: nova/volume/manager.py:129 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "" diff --git a/locale/uk.po b/locale/uk.po new file mode 100644 index 00000000..cdbffd13 --- /dev/null +++ b/locale/uk.po @@ -0,0 +1,2130 @@ +# Ukrainian translation for nova +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the nova package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: nova\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"PO-Revision-Date: 2011-01-13 07:03+0000\n" +"Last-Translator: Wladimir Rossinski \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-01-28 05:20+0000\n" +"X-Generator: Launchpad (build 12177)\n" + +#: nova/crypto.py:46 +msgid "Filename of root CA" +msgstr "" + +#: nova/crypto.py:49 +msgid "Filename of private key" +msgstr "" + +#: nova/crypto.py:51 +msgid "Filename of root Certificate Revokation List" +msgstr "" + +#: nova/crypto.py:53 +msgid "Where we keep our keys" +msgstr "" + +#: nova/crypto.py:55 +msgid "Where we keep our root CA" +msgstr "" + +#: nova/crypto.py:57 +msgid "Should we use a CA for each project?" +msgstr "" + +#: nova/crypto.py:61 +#, python-format +msgid "Subject for certificate for users, %s for project, user, timestamp" +msgstr "" + +#: nova/crypto.py:66 +#, python-format +msgid "Subject for certificate for projects, %s for project, timestamp" +msgstr "" + +#: nova/crypto.py:71 +#, python-format +msgid "Subject for certificate for vpns, %s for project, timestamp" +msgstr "" + +#: nova/crypto.py:258 +#, python-format +msgid "Flags path: %s" +msgstr "" + +#: nova/exception.py:33 +msgid "Unexpected error while running command." +msgstr "" + +#: nova/exception.py:36 +#, python-format +msgid "" +"%s\n" +"Command: %s\n" +"Exit code: %s\n" +"Stdout: %r\n" +"Stderr: %r" +msgstr "" + +#: nova/exception.py:86 +msgid "Uncaught exception" +msgstr "" + +#: nova/fakerabbit.py:48 +#, python-format +msgid "(%s) publish (key: %s) %s" +msgstr "" + +#: nova/fakerabbit.py:53 +#, python-format +msgid "Publishing to route %s" +msgstr "" + +#: nova/fakerabbit.py:83 +#, python-format +msgid "Declaring queue %s" +msgstr "" + +#: nova/fakerabbit.py:89 +#, python-format +msgid "Declaring exchange %s" +msgstr "" + +#: nova/fakerabbit.py:95 +#, python-format +msgid "Binding %s to %s with key %s" +msgstr "" + +#: nova/fakerabbit.py:120 +#, python-format +msgid "Getting from %s: %s" +msgstr "" + +#: nova/rpc.py:92 +#, python-format +msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgstr "AMQP сервер %s:%d недоступний. Спроба під'єднання через %d секунд." + +#: nova/rpc.py:99 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "Не вдалось під'єднатися до серверу AMQP після %d спроб. Вимкнення." + +#: nova/rpc.py:118 +msgid "Reconnected to queue" +msgstr "" + +#: nova/rpc.py:125 +msgid "Failed to fetch message from queue" +msgstr "" + +#: nova/rpc.py:155 +#, python-format +msgid "Initing the Adapter Consumer for %s" +msgstr "" + +#: nova/rpc.py:170 +#, python-format +msgid "received %s" +msgstr "отримано %s" + +#: nova/rpc.py:183 +#, python-format +msgid "no method for message: %s" +msgstr "без порядку для повідомлень: %s" + +#: nova/rpc.py:184 +#, python-format +msgid "No method for message: %s" +msgstr "Без порядку для повідомлень: %s" + +#: nova/rpc.py:245 +#, python-format +msgid "Returning exception %s to caller" +msgstr "" + +#: nova/rpc.py:286 +#, python-format +msgid "unpacked context: %s" +msgstr "" + +#: nova/rpc.py:305 +msgid "Making asynchronous call..." +msgstr "Створення асинхронного виклику..." + +#: nova/rpc.py:308 +#, python-format +msgid "MSG_ID is %s" +msgstr "MSG_ID %s" + +#: nova/rpc.py:356 +#, python-format +msgid "response %s" +msgstr "відповідь %s" + +#: nova/rpc.py:365 +#, python-format +msgid "topic is %s" +msgstr "заголовок %s" + +#: nova/rpc.py:366 +#, python-format +msgid "message %s" +msgstr "повідомлення %s" + +#: nova/service.py:157 +#, python-format +msgid "Starting %s node" +msgstr "" + +#: nova/service.py:169 +msgid "Service killed that has no database entry" +msgstr "" + +#: nova/service.py:190 +msgid "The service database object disappeared, Recreating it." +msgstr "" + +#: nova/service.py:202 +msgid "Recovered model server connection!" +msgstr "" + +#: nova/service.py:208 +msgid "model server went away" +msgstr "" + +#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#, python-format +msgid "Data store %s is unreachable. Trying again in %d seconds." +msgstr "" + +#: nova/service.py:232 nova/twistd.py:232 +#, python-format +msgid "Serving %s" +msgstr "Обслуговування %s" + +#: nova/service.py:234 nova/twistd.py:264 +msgid "Full set of FLAGS:" +msgstr "" + +#: nova/twistd.py:211 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "" + +#: nova/twistd.py:268 +#, python-format +msgid "Starting %s" +msgstr "Запускається %s" + +#: nova/utils.py:53 +#, python-format +msgid "Inner Exception: %s" +msgstr "" + +#: nova/utils.py:54 +#, python-format +msgid "Class %s cannot be found" +msgstr "" + +#: nova/utils.py:113 +#, python-format +msgid "Fetching %s" +msgstr "" + +#: nova/utils.py:125 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "" + +#: nova/utils.py:138 +#, python-format +msgid "Result was %s" +msgstr "" + +#: nova/utils.py:171 +#, python-format +msgid "debug in callback: %s" +msgstr "" + +#: nova/utils.py:176 +#, python-format +msgid "Running %s" +msgstr "Запускається %s" + +#: nova/utils.py:207 +#, python-format +msgid "Couldn't get IP, using 127.0.0.1 %s" +msgstr "Не вдалось отримати IP, використовуючи 127.0.0.1 %s" + +#: nova/utils.py:289 +#, python-format +msgid "Invalid backend: %s" +msgstr "" + +#: nova/utils.py:300 +#, python-format +msgid "backend %s" +msgstr "" + +#: nova/api/ec2/__init__.py:133 +msgid "Too many failed authentications." +msgstr "Занадто багато невдалих аутентифікацій." + +#: nova/api/ec2/__init__.py:142 +#, python-format +msgid "" +"Access key %s has had %d failed authentications and will be locked out for " +"%d minutes." +msgstr "" + +#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#, python-format +msgid "Authentication Failure: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:190 +#, python-format +msgid "Authenticated Request For %s:%s)" +msgstr "" + +#: nova/api/ec2/__init__.py:227 +#, python-format +msgid "action: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:229 +#, python-format +msgid "arg: %s\t\tval: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:301 +#, python-format +msgid "Unauthorized request for controller=%s and action=%s" +msgstr "" + +#: nova/api/ec2/__init__.py:339 +#, python-format +msgid "NotFound raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:342 +#, python-format +msgid "ApiError raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:349 +#, python-format +msgid "Unexpected error raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:354 +msgid "An unknown error has occurred. Please try your request again." +msgstr "" + +#: nova/api/ec2/admin.py:84 +#, python-format +msgid "Creating new user: %s" +msgstr "" + +#: nova/api/ec2/admin.py:92 +#, python-format +msgid "Deleting user: %s" +msgstr "" + +#: nova/api/ec2/admin.py:114 +#, python-format +msgid "Adding role %s to user %s for project %s" +msgstr "" + +#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#, python-format +msgid "Adding sitewide role %s to user %s" +msgstr "" + +#: nova/api/ec2/admin.py:122 +#, python-format +msgid "Removing role %s from user %s for project %s" +msgstr "" + +#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#, python-format +msgid "Removing sitewide role %s from user %s" +msgstr "" + +#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 +msgid "operation must be add or remove" +msgstr "" + +#: nova/api/ec2/admin.py:142 +#, python-format +msgid "Getting x509 for user: %s on project: %s" +msgstr "" + +#: nova/api/ec2/admin.py:159 +#, python-format +msgid "Create project %s managed by %s" +msgstr "" + +#: nova/api/ec2/admin.py:170 +#, python-format +msgid "Delete project: %s" +msgstr "Вилучити проект: %s" + +#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#, python-format +msgid "Adding user %s to project %s" +msgstr "Долучення користувача %s до проекту %s" + +#: nova/api/ec2/admin.py:188 +#, python-format +msgid "Removing user %s from project %s" +msgstr "Вилучення користувача %s з проекту %s" + +#: nova/api/ec2/apirequest.py:95 +#, python-format +msgid "Unsupported API request: controller = %s,action = %s" +msgstr "" + +#: nova/api/ec2/cloud.py:117 +#, python-format +msgid "Generating root CA: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:277 +#, python-format +msgid "Create key pair %s" +msgstr "" + +#: nova/api/ec2/cloud.py:285 +#, python-format +msgid "Delete key pair %s" +msgstr "" + +#: nova/api/ec2/cloud.py:357 +#, python-format +msgid "%s is not a valid ipProtocol" +msgstr "%s не допустимий ipProtocol" + +#: nova/api/ec2/cloud.py:361 +msgid "Invalid port range" +msgstr "Невірний діапазон портів" + +#: nova/api/ec2/cloud.py:392 +#, python-format +msgid "Revoke security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 +msgid "No rule for the specified parameters." +msgstr "" + +#: nova/api/ec2/cloud.py:421 +#, python-format +msgid "Authorize security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:432 +#, python-format +msgid "This rule already exists in group %s" +msgstr "Це правило вже існує в групі %s" + +#: nova/api/ec2/cloud.py:460 +#, python-format +msgid "Create Security Group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:463 +#, python-format +msgid "group %s already exists" +msgstr "" + +#: nova/api/ec2/cloud.py:475 +#, python-format +msgid "Delete security group %s" +msgstr "Вилучити групу безпеки %s" + +#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:543 +#, python-format +msgid "Create volume of %s GB" +msgstr "Створити розділ на %s ГБ" + +#: nova/api/ec2/cloud.py:567 +#, python-format +msgid "Attach volume %s to instacne %s at %s" +msgstr "" + +#: nova/api/ec2/cloud.py:579 +#, python-format +msgid "Detach volume %s" +msgstr "Від'єднати том %s" + +#: nova/api/ec2/cloud.py:686 +msgid "Allocate address" +msgstr "" + +#: nova/api/ec2/cloud.py:691 +#, python-format +msgid "Release address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:696 +#, python-format +msgid "Associate address %s to instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:703 +#, python-format +msgid "Disassociate address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:730 +msgid "Going to start terminating instances" +msgstr "" + +#: nova/api/ec2/cloud.py:738 +#, python-format +msgid "Reboot instance %r" +msgstr "" + +#: nova/api/ec2/cloud.py:775 +#, python-format +msgid "De-registering image %s" +msgstr "" + +#: nova/api/ec2/cloud.py:783 +#, python-format +msgid "Registered image %s with id %s" +msgstr "" + +#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#, python-format +msgid "attribute not supported: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:794 +#, python-format +msgid "invalid id: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:807 +msgid "user or group not specified" +msgstr "" + +#: nova/api/ec2/cloud.py:809 +msgid "only group \"all\" is supported" +msgstr "лише група \"всі\" підтримується" + +#: nova/api/ec2/cloud.py:811 +msgid "operation_type must be add or remove" +msgstr "" + +#: nova/api/ec2/cloud.py:812 +#, python-format +msgid "Updating image %s publicity" +msgstr "" + +#: nova/api/ec2/metadatarequesthandler.py:75 +#, python-format +msgid "Failed to get metadata for ip: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:70 +#, python-format +msgid "Caught error: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:86 +msgid "Including admin operations in API." +msgstr "" + +#: nova/api/openstack/servers.py:184 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:199 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: nova/api/openstack/servers.py:213 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:224 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: nova/api/openstack/servers.py:235 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: nova/api/openstack/servers.py:246 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: nova/api/openstack/servers.py:257 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: nova/auth/dbdriver.py:84 +#, python-format +msgid "User %s already exists" +msgstr "Користувач %s вже існує" + +#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#, python-format +msgid "Project can't be created because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#, python-format +msgid "Project can't be created because project %s already exists" +msgstr "" + +#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#, python-format +msgid "Project can't be modified because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:245 +#, python-format +msgid "User \"%s\" not found" +msgstr "Користувач \"%s\" не знайдено" + +#: nova/auth/dbdriver.py:248 +#, python-format +msgid "Project \"%s\" not found" +msgstr "Проект \"%s\" не знайдено" + +#: nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "" + +#: nova/auth/ldapdriver.py:181 +#, python-format +msgid "LDAP object for %s doesn't exist" +msgstr "" + +#: nova/auth/ldapdriver.py:218 +#, python-format +msgid "Project can't be created because user %s doesn't exist" +msgstr "" + +#: nova/auth/ldapdriver.py:478 +#, python-format +msgid "User %s is already a member of the group %s" +msgstr "" + +#: nova/auth/ldapdriver.py:507 +#, python-format +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." +msgstr "" + +#: nova/auth/ldapdriver.py:528 +#, python-format +msgid "Group at dn %s doesn't exist" +msgstr "" + +#: nova/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "" + +#: nova/auth/manager.py:263 +#, python-format +msgid "Failed authorization for access key %s" +msgstr "" + +#: nova/auth/manager.py:264 +#, python-format +msgid "No user found for access key %s" +msgstr "" + +#: nova/auth/manager.py:270 +#, python-format +msgid "Using project name = user name (%s)" +msgstr "" + +#: nova/auth/manager.py:275 +#, python-format +msgid "failed authorization: no project named %s (user=%s)" +msgstr "" + +#: nova/auth/manager.py:277 +#, python-format +msgid "No project called %s could be found" +msgstr "" + +#: nova/auth/manager.py:281 +#, python-format +msgid "Failed authorization: user %s not admin and not member of project %s" +msgstr "" + +#: nova/auth/manager.py:283 +#, python-format +msgid "User %s is not a member of project %s" +msgstr "" + +#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#, python-format +msgid "Invalid signature for user %s" +msgstr "" + +#: nova/auth/manager.py:293 nova/auth/manager.py:304 +msgid "Signature does not match" +msgstr "" + +#: nova/auth/manager.py:374 +msgid "Must specify project" +msgstr "" + +#: nova/auth/manager.py:408 +#, python-format +msgid "The %s role can not be found" +msgstr "" + +#: nova/auth/manager.py:410 +#, python-format +msgid "The %s role is global only" +msgstr "" + +#: nova/auth/manager.py:412 +#, python-format +msgid "Adding role %s to user %s in project %s" +msgstr "" + +#: nova/auth/manager.py:438 +#, python-format +msgid "Removing role %s from user %s on project %s" +msgstr "" + +#: nova/auth/manager.py:505 +#, python-format +msgid "Created project %s with manager %s" +msgstr "" + +#: nova/auth/manager.py:523 +#, python-format +msgid "modifying project %s" +msgstr "" + +#: nova/auth/manager.py:553 +#, python-format +msgid "Remove user %s from project %s" +msgstr "" + +#: nova/auth/manager.py:581 +#, python-format +msgid "Deleting project %s" +msgstr "" + +#: nova/auth/manager.py:637 +#, python-format +msgid "Created user %s (admin: %r)" +msgstr "" + +#: nova/auth/manager.py:645 +#, python-format +msgid "Deleting user %s" +msgstr "" + +#: nova/auth/manager.py:655 +#, python-format +msgid "Access Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:657 +#, python-format +msgid "Secret Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:659 +#, python-format +msgid "Admin status set to %r for user %s" +msgstr "" + +#: nova/auth/manager.py:708 +#, python-format +msgid "No vpn data for project %s" +msgstr "" + +#: nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" +msgstr "" + +#: nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:97 +#, python-format +msgid "Launching VPN for %s" +msgstr "" + +#: nova/compute/api.py:67 +#, python-format +msgid "Instance %d was not found in get_network_topic" +msgstr "" + +#: nova/compute/api.py:73 +#, python-format +msgid "Instance %d has no host" +msgstr "" + +#: nova/compute/api.py:92 +#, python-format +msgid "Quota exceeeded for %s, tried to run %s instances" +msgstr "" + +#: nova/compute/api.py:94 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." +msgstr "" + +#: nova/compute/api.py:109 +msgid "Creating a raw instance" +msgstr "" + +#: nova/compute/api.py:156 +#, python-format +msgid "Going to run %s instances..." +msgstr "" + +#: nova/compute/api.py:180 +#, python-format +msgid "Casting to scheduler for %s/%s's instance %s" +msgstr "" + +#: nova/compute/api.py:279 +#, python-format +msgid "Going to try and terminate %s" +msgstr "" + +#: nova/compute/api.py:283 +#, python-format +msgid "Instance %d was not found during terminate" +msgstr "" + +#: nova/compute/api.py:288 +#, python-format +msgid "Instance %d is already being terminated" +msgstr "" + +#: nova/compute/api.py:450 +#, python-format +msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgstr "" + +#: nova/compute/api.py:465 +msgid "Volume isn't attached to anything!" +msgstr "" + +#: nova/compute/disk.py:71 +#, python-format +msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:75 +#, python-format +msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:128 +#, python-format +msgid "Could not attach image to loopback: %s" +msgstr "" + +#: nova/compute/disk.py:136 +#, python-format +msgid "Failed to load partition: %s" +msgstr "" + +#: nova/compute/disk.py:158 +#, python-format +msgid "Failed to mount filesystem: %s" +msgstr "" + +#: nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "" + +#: nova/compute/manager.py:69 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: nova/compute/manager.py:71 +#, python-format +msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgstr "" + +#: nova/compute/manager.py:75 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: nova/compute/manager.py:77 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: nova/compute/manager.py:82 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: nova/compute/manager.py:157 +msgid "Instance has already been created" +msgstr "" + +#: nova/compute/manager.py:158 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#: nova/compute/manager.py:197 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: nova/compute/manager.py:217 +#, python-format +msgid "Disassociating address %s" +msgstr "" + +#: nova/compute/manager.py:230 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: nova/compute/manager.py:243 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: nova/compute/manager.py:257 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: nova/compute/manager.py:260 +#, python-format +msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:286 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: nova/compute/manager.py:289 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:301 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: nova/compute/manager.py:316 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: nova/compute/manager.py:335 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: nova/compute/manager.py:352 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: nova/compute/manager.py:369 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: nova/compute/manager.py:382 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: nova/compute/manager.py:401 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: nova/compute/manager.py:420 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: nova/compute/manager.py:432 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: nova/compute/manager.py:442 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: nova/compute/manager.py:462 +#, python-format +msgid "instance %s: attaching volume %s to %s" +msgstr "" + +#: nova/compute/manager.py:478 +#, python-format +msgid "instance %s: attach failed %s, removing" +msgstr "" + +#: nova/compute/manager.py:493 +#, python-format +msgid "Detach volume %s from mountpoint %s on instance %s" +msgstr "" + +#: nova/compute/manager.py:497 +#, python-format +msgid "Detaching volume from unknown instance %s" +msgstr "" + +#: nova/compute/monitor.py:259 +#, python-format +msgid "updating %s..." +msgstr "" + +#: nova/compute/monitor.py:289 +msgid "unexpected error during update" +msgstr "" + +#: nova/compute/monitor.py:355 +#, python-format +msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:377 +#, python-format +msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:412 +msgid "unexpected exception getting connection" +msgstr "" + +#: nova/compute/monitor.py:427 +#, python-format +msgid "Found instance: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:43 +msgid "Use of empty request context is deprecated" +msgstr "" + +#: nova/db/sqlalchemy/api.py:132 +#, python-format +msgid "No service for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:229 +#, python-format +msgid "No service for %s, %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:574 +#, python-format +msgid "No floating ip for address %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:668 +#, python-format +msgid "No instance for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:758 nova/virt/libvirt_conn.py:598 +#: nova/virt/xenapi/volumeops.py:48 nova/virt/xenapi/volumeops.py:103 +#, python-format +msgid "Instance %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:891 +#, python-format +msgid "no keypair for user %s, name %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#, python-format +msgid "No network for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1036 +#, python-format +msgid "No network for bridge %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1050 +#, python-format +msgid "No network for instance %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1180 +#, python-format +msgid "Token %s does not exist" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1205 +#, python-format +msgid "No quota for project_id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1356 +#, python-format +msgid "No volume for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1401 +#, python-format +msgid "Volume %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1413 +#, python-format +msgid "No export device found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1426 +#, python-format +msgid "No target id found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1471 +#, python-format +msgid "No security group with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1488 +#, python-format +msgid "No security group named %s for project: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1576 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1650 +#, python-format +msgid "No user for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1666 +#, python-format +msgid "No user for access key %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1728 +#, python-format +msgid "No project with id %s" +msgstr "" + +#: nova/image/glance.py:78 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images" +msgstr "" + +#: nova/image/glance.py:97 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images/detail" +msgstr "" + +#: nova/image/s3.py:82 +#, python-format +msgid "Image %s could not be found" +msgstr "" + +#: nova/network/api.py:39 +#, python-format +msgid "Quota exceeeded for %s, tried to allocate address" +msgstr "" + +#: nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" +msgstr "" + +#: nova/network/linux_net.py:176 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: nova/network/linux_net.py:186 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#: nova/network/linux_net.py:254 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: nova/network/linux_net.py:256 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#: nova/network/linux_net.py:334 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: nova/network/manager.py:135 +msgid "setting network host" +msgstr "" + +#: nova/network/manager.py:190 +#, python-format +msgid "Leasing IP %s" +msgstr "" + +#: nova/network/manager.py:194 +#, python-format +msgid "IP %s leased that isn't associated" +msgstr "" + +#: nova/network/manager.py:197 +#, python-format +msgid "IP %s leased to bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:205 +#, python-format +msgid "IP %s leased that was already deallocated" +msgstr "" + +#: nova/network/manager.py:214 +#, python-format +msgid "IP %s released that isn't associated" +msgstr "" + +#: nova/network/manager.py:217 +#, python-format +msgid "IP %s released from bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:220 +#, python-format +msgid "IP %s released that was not leased" +msgstr "" + +#: nova/network/manager.py:442 +#, python-format +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "" + +#: nova/objectstore/handler.py:106 +#, python-format +msgid "Unknown S3 value type %r" +msgstr "" + +#: nova/objectstore/handler.py:137 +msgid "Authenticated request" +msgstr "" + +#: nova/objectstore/handler.py:182 +msgid "List of buckets requested" +msgstr "" + +#: nova/objectstore/handler.py:209 +#, python-format +msgid "List keys for bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:217 +#, python-format +msgid "Unauthorized attempt to access bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:235 +#, python-format +msgid "Creating bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:245 +#, python-format +msgid "Deleting bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:249 +#, python-format +msgid "Unauthorized attempt to delete bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:271 +#, python-format +msgid "Getting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:274 +#, python-format +msgid "Unauthorized attempt to get object %s from bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:292 +#, python-format +msgid "Putting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:295 +#, python-format +msgid "Unauthorized attempt to upload object %s to bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:314 +#, python-format +msgid "Deleting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:393 +#, python-format +msgid "Not authorized to upload image: invalid directory %s" +msgstr "" + +#: nova/objectstore/handler.py:401 +#, python-format +msgid "Not authorized to upload image: unauthorized bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:406 +#, python-format +msgid "Starting image upload: %s" +msgstr "" + +#: nova/objectstore/handler.py:420 +#, python-format +msgid "Not authorized to update attributes of image %s" +msgstr "" + +#: nova/objectstore/handler.py:428 +#, python-format +msgid "Toggling publicity flag of image %s %r" +msgstr "" + +#: nova/objectstore/handler.py:433 +#, python-format +msgid "Updating user fields on image %s" +msgstr "" + +#: nova/objectstore/handler.py:447 +#, python-format +msgid "Unauthorized attempt to delete image %s" +msgstr "" + +#: nova/objectstore/handler.py:452 +#, python-format +msgid "Deleted image: %s" +msgstr "" + +#: nova/scheduler/chance.py:37 nova/scheduler/simple.py:73 +#: nova/scheduler/simple.py:106 nova/scheduler/simple.py:118 +msgid "No hosts found" +msgstr "" + +#: nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "" + +#: nova/scheduler/manager.py:69 +#, python-format +msgid "Casting to %s %s for %s" +msgstr "" + +#: nova/scheduler/simple.py:63 +msgid "All hosts have too many cores" +msgstr "" + +#: nova/scheduler/simple.py:95 +msgid "All hosts have too many gigabytes" +msgstr "" + +#: nova/scheduler/simple.py:115 +msgid "All hosts have too many networks" +msgstr "" + +#: nova/tests/test_cloud.py:198 +msgid "Can't test instances without a real virtual env." +msgstr "" + +#: nova/tests/test_cloud.py:210 +#, python-format +msgid "Need to watch instance %s until it's running..." +msgstr "" + +#: nova/tests/test_compute.py:104 +#, python-format +msgid "Running instances: %s" +msgstr "" + +#: nova/tests/test_compute.py:110 +#, python-format +msgid "After terminating instances: %s" +msgstr "" + +#: nova/tests/test_rpc.py:89 +#, python-format +msgid "Nested received %s, %s" +msgstr "" + +#: nova/tests/test_rpc.py:94 +#, python-format +msgid "Nested return %s" +msgstr "" + +#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#, python-format +msgid "Received %s" +msgstr "" + +#: nova/tests/test_volume.py:162 +#, python-format +msgid "Target %s allocated" +msgstr "" + +#: nova/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "" + +#: nova/virt/fake.py:210 +#, python-format +msgid "Instance %s Not Found" +msgstr "" + +#: nova/virt/hyperv.py:118 +msgid "In init host" +msgstr "" + +#: nova/virt/hyperv.py:131 +#, python-format +msgid "Attempt to create duplicate vm %s" +msgstr "" + +#: nova/virt/hyperv.py:148 +#, python-format +msgid "Starting VM %s " +msgstr "" + +#: nova/virt/hyperv.py:150 +#, python-format +msgid "Started VM %s " +msgstr "" + +#: nova/virt/hyperv.py:152 +#, python-format +msgid "spawn vm failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:169 +#, python-format +msgid "Failed to create VM %s" +msgstr "" + +#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#, python-format +msgid "Created VM %s..." +msgstr "" + +#: nova/virt/hyperv.py:188 +#, python-format +msgid "Set memory for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:198 +#, python-format +msgid "Set vcpus for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:202 +#, python-format +msgid "Creating disk for %s by attaching disk file %s" +msgstr "" + +#: nova/virt/hyperv.py:227 +#, python-format +msgid "Failed to add diskdrive to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:230 +#, python-format +msgid "New disk drive path is %s" +msgstr "" + +#: nova/virt/hyperv.py:247 +#, python-format +msgid "Failed to add vhd file to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:249 +#, python-format +msgid "Created disk for %s" +msgstr "" + +#: nova/virt/hyperv.py:253 +#, python-format +msgid "Creating nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" +msgstr "" + +#: nova/virt/hyperv.py:273 +#, python-format +msgid "Failed creating port for %s" +msgstr "" + +#: nova/virt/hyperv.py:275 +#, python-format +msgid "Created switch port %s on switch %s" +msgstr "" + +#: nova/virt/hyperv.py:285 +#, python-format +msgid "Failed to add nic to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:287 +#, python-format +msgid "Created nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:320 +#, python-format +msgid "WMI job failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:322 +#, python-format +msgid "WMI job succeeded: %s, Elapsed=%s " +msgstr "" + +#: nova/virt/hyperv.py:358 +#, python-format +msgid "Got request to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:383 +#, python-format +msgid "Failed to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:389 +#, python-format +msgid "Del: disk %s vm %s" +msgstr "" + +#: nova/virt/hyperv.py:405 +#, python-format +msgid "" +"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " +"cpu_time=%s" +msgstr "" + +#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#, python-format +msgid "duplicate name found: %s" +msgstr "" + +#: nova/virt/hyperv.py:444 +#, python-format +msgid "Successfully changed vm state of %s to %s" +msgstr "" + +#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#, python-format +msgid "Failed to change vm state of %s to %s" +msgstr "" + +#: nova/virt/images.py:70 +#, python-format +msgid "Finished retreving %s -- placed in %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:144 +#, python-format +msgid "Connecting to libvirt: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:157 +msgid "Connection to libvirt broke" +msgstr "" + +#: nova/virt/libvirt_conn.py:229 +#, python-format +msgid "instance %s: deleting instance files %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:271 +#, python-format +msgid "No disk at %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:278 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "" + +#: nova/virt/libvirt_conn.py:294 +#, python-format +msgid "instance %s: rebooted" +msgstr "" + +#: nova/virt/libvirt_conn.py:297 +#, python-format +msgid "_wait_for_reboot failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:340 +#, python-format +msgid "instance %s: rescued" +msgstr "" + +#: nova/virt/libvirt_conn.py:343 +#, python-format +msgid "_wait_for_rescue failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:370 +#, python-format +msgid "instance %s: is running" +msgstr "" + +#: nova/virt/libvirt_conn.py:381 +#, python-format +msgid "instance %s: booted" +msgstr "" + +#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#, python-format +msgid "instance %s: failed to boot" +msgstr "" + +#: nova/virt/libvirt_conn.py:395 +#, python-format +msgid "virsh said: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:399 +msgid "cool, it's a device" +msgstr "" + +#: nova/virt/libvirt_conn.py:407 +#, python-format +msgid "data: %r, fpath: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:415 +#, python-format +msgid "Contents of file %s: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:449 +#, python-format +msgid "instance %s: Creating image" +msgstr "" + +#: nova/virt/libvirt_conn.py:505 +#, python-format +msgid "instance %s: injecting key into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:508 +#, python-format +msgid "instance %s: injecting net into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:516 +#, python-format +msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgstr "" + +#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#, python-format +msgid "instance %s: starting toXML method" +msgstr "" + +#: nova/virt/libvirt_conn.py:589 +#, python-format +msgid "instance %s: finished toXML method" +msgstr "" + +#: nova/virt/xenapi_conn.py:113 +msgid "" +"Must specify xenapi_connection_url, xenapi_connection_username (optionally), " +"and xenapi_connection_password to use connection_type=xenapi" +msgstr "" + +#: nova/virt/xenapi_conn.py:263 +#, python-format +msgid "Task [%s] %s status: success %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:271 +#, python-format +msgid "Task [%s] %s status: %s %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#, python-format +msgid "Got exception: %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:72 +#, python-format +msgid "%s: _db_content => %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:247 nova/virt/xenapi/fake.py:338 +#: nova/virt/xenapi/fake.py:356 nova/virt/xenapi/fake.py:404 +msgid "Raising NotImplemented" +msgstr "" + +#: nova/virt/xenapi/fake.py:249 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:283 +#, python-format +msgid "Calling %s %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:288 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:340 +#, python-format +msgid "" +"xenapi.fake does not have an implementation for %s or it has been called " +"with the wrong number of arguments" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:40 +#, python-format +msgid "Found non-unique network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:43 +#, python-format +msgid "Found no network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:127 +#, python-format +msgid "Created VM %s as %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:147 +#, python-format +msgid "Creating VBD for VM %s, VDI %s ... " +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:149 +#, python-format +msgid "Created VBD %s for VM %s, VDI %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:165 +#, python-format +msgid "VBD not found in instance %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:175 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:202 +#, python-format +msgid "Creating VIF for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:205 +#, python-format +msgid "Created VIF %s for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:216 +#, python-format +msgid "Snapshotting VM %s with label '%s'..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:229 +#, python-format +msgid "Created snapshot %s from VM %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:243 +#, python-format +msgid "Asking xapi to upload %s as '%s'" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:261 +#, python-format +msgid "Asking xapi to fetch %s as %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:279 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:290 +#, python-format +msgid "PV Kernel in VDI:%d" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:318 +#, python-format +msgid "VDI %s is still available" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:331 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:333 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:390 +#, python-format +msgid "VHD %s has parent %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:407 +#, python-format +msgid "Re-scanning SR %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:431 +#, python-format +msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:448 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:452 +#, python-format +msgid "Unexpected number of VDIs (%s) found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:62 +#, python-format +msgid "Attempted to create non-unique name %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:99 +#, python-format +msgid "Starting VM %s..." +msgstr "" + +#: nova/virt/xenapi/vmops.py:101 +#, python-format +msgid "Spawning VM %s created %s." +msgstr "" + +#: nova/virt/xenapi/vmops.py:112 +#, python-format +msgid "Instance %s: booted" +msgstr "" + +#: nova/virt/xenapi/vmops.py:137 +#, python-format +msgid "Instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:166 +#, python-format +msgid "Starting snapshot for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:174 +#, python-format +msgid "Unable to Snapshot %s: %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:184 +#, python-format +msgid "Finished snapshot and upload for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:252 +#, python-format +msgid "suspend: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:262 +#, python-format +msgid "resume: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:271 +#, python-format +msgid "Instance not found %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:57 +#, python-format +msgid "Introducing %s..." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:74 +#, python-format +msgid "Introduced %s as %s." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:90 +#, python-format +msgid "Unable to find SR from VBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:96 +#, python-format +msgid "Forgetting SR %s ... " +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:101 +#, python-format +msgid "Ignoring exception %s when getting PBDs for %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:107 +#, python-format +msgid "Ignoring exception %s when unplugging PBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:111 +#, python-format +msgid "Forgetting SR %s done." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:113 +#, python-format +msgid "Ignoring exception %s when forgetting SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:123 +#, python-format +msgid "Unable to introduce VDI on SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:128 +#, python-format +msgid "Unable to get record of VDI %s on" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:146 +#, python-format +msgid "Unable to introduce VDI for SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:175 +#, python-format +msgid "Unable to obtain target information %s, %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:197 +#, python-format +msgid "Mountpoint cannot be translated: %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:51 +#, python-format +msgid "Attach_volume: %s, %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:69 +#, python-format +msgid "Unable to create VDI on SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:81 +#, python-format +msgid "Unable to use SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Unable to attach volume to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:95 +#, python-format +msgid "Mountpoint %s attached to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:106 +#, python-format +msgid "Detach_volume: %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:113 +#, python-format +msgid "Unable to locate volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:121 +#, python-format +msgid "Unable to detach volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:128 +#, python-format +msgid "Mountpoint %s detached from instance %s" +msgstr "" + +#: nova/volume/api.py:44 +#, python-format +msgid "Quota exceeeded for %s, tried to create %sG volume" +msgstr "" + +#: nova/volume/api.py:46 +#, python-format +msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgstr "" + +#: nova/volume/api.py:70 nova/volume/api.py:95 +msgid "Volume status must be available" +msgstr "" + +#: nova/volume/api.py:97 +msgid "Volume is already attached" +msgstr "" + +#: nova/volume/api.py:103 +msgid "Volume is already detached" +msgstr "" + +#: nova/volume/driver.py:76 +#, python-format +msgid "Recovering from a failed execute. Try number %s" +msgstr "" + +#: nova/volume/driver.py:85 +#, python-format +msgid "volume group %s doesn't exist" +msgstr "" + +#: nova/volume/driver.py:210 +#, python-format +msgid "FAKE AOE: %s" +msgstr "" + +#: nova/volume/driver.py:315 +#, python-format +msgid "FAKE ISCSI: %s" +msgstr "" + +#: nova/volume/manager.py:85 +#, python-format +msgid "Re-exporting %s volumes" +msgstr "" + +#: nova/volume/manager.py:93 +#, python-format +msgid "volume %s: creating" +msgstr "" + +#: nova/volume/manager.py:102 +#, python-format +msgid "volume %s: creating lv of size %sG" +msgstr "" + +#: nova/volume/manager.py:106 +#, python-format +msgid "volume %s: creating export" +msgstr "" + +#: nova/volume/manager.py:113 +#, python-format +msgid "volume %s: created successfully" +msgstr "" + +#: nova/volume/manager.py:121 +msgid "Volume is still attached" +msgstr "" + +#: nova/volume/manager.py:123 +msgid "Volume is not local to this node" +msgstr "" + +#: nova/volume/manager.py:124 +#, python-format +msgid "volume %s: removing export" +msgstr "" + +#: nova/volume/manager.py:126 +#, python-format +msgid "volume %s: deleting" +msgstr "" + +#: nova/volume/manager.py:129 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "" diff --git a/locale/zh_CN.po b/locale/zh_CN.po new file mode 100644 index 00000000..4805eb32 --- /dev/null +++ b/locale/zh_CN.po @@ -0,0 +1,2135 @@ +# Chinese (Simplified) translation for nova +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the nova package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: nova\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"PO-Revision-Date: 2011-01-22 03:11+0000\n" +"Last-Translator: combo \n" +"Language-Team: Chinese (Simplified) \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-01-28 05:21+0000\n" +"X-Generator: Launchpad (build 12177)\n" + +#: nova/twistd.py:268 +#, python-format +msgid "Starting %s" +msgstr "正在启动 %s" + +#: nova/crypto.py:46 +msgid "Filename of root CA" +msgstr "根证书文件名" + +#: nova/crypto.py:49 +msgid "Filename of private key" +msgstr "私钥文件名" + +#: nova/crypto.py:51 +msgid "Filename of root Certificate Revokation List" +msgstr "" + +#: nova/crypto.py:53 +msgid "Where we keep our keys" +msgstr "保存密钥的位置" + +#: nova/crypto.py:55 +msgid "Where we keep our root CA" +msgstr "保存根证书的位置" + +#: nova/crypto.py:57 +msgid "Should we use a CA for each project?" +msgstr "是否所有项目都是用证书授权(CA)?" + +#: nova/crypto.py:61 +#, python-format +msgid "Subject for certificate for users, %s for project, user, timestamp" +msgstr "用户证书的标题,%s依次分别为项目,用户,时间戳" + +#: nova/crypto.py:66 +#, python-format +msgid "Subject for certificate for projects, %s for project, timestamp" +msgstr "项目证书的标题,%s依次分别为项目,时间戳" + +#: nova/crypto.py:71 +#, python-format +msgid "Subject for certificate for vpns, %s for project, timestamp" +msgstr "VPN证书的标题,%s依次分别为项目,时间戳" + +#: nova/crypto.py:258 +#, python-format +msgid "Flags path: %s" +msgstr "Flag所在路径:%s" + +#: nova/exception.py:33 +msgid "Unexpected error while running command." +msgstr "运行命令时出现了意外错误。" + +#: nova/exception.py:36 +#, python-format +msgid "" +"%s\n" +"Command: %s\n" +"Exit code: %s\n" +"Stdout: %r\n" +"Stderr: %r" +msgstr "" +"%s\n" +"命令:%s\n" +"退出代码:%s\n" +"标准输出(stdout):%r\n" +"标准错误(stderr):%r" + +#: nova/exception.py:86 +msgid "Uncaught exception" +msgstr "未捕获异常" + +#: nova/fakerabbit.py:48 +#, python-format +msgid "(%s) publish (key: %s) %s" +msgstr "(%s)发布(键值:%s)%s" + +#: nova/fakerabbit.py:53 +#, python-format +msgid "Publishing to route %s" +msgstr "发布并路由到 %s" + +#: nova/fakerabbit.py:83 +#, python-format +msgid "Declaring queue %s" +msgstr "正在声明队列%s" + +#: nova/fakerabbit.py:89 +#, python-format +msgid "Declaring exchange %s" +msgstr "正在声明交换(exchange)%s" + +#: nova/fakerabbit.py:95 +#, python-format +msgid "Binding %s to %s with key %s" +msgstr "将%s绑定到%s(以%s键值)" + +#: nova/fakerabbit.py:120 +#, python-format +msgid "Getting from %s: %s" +msgstr "从%s获得如下内容:%s" + +#: nova/rpc.py:92 +#, python-format +msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgstr "位于%s:%d的AMQP服务器不可用。%d秒后重试。" + +#: nova/rpc.py:99 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "已尝试%d次,均无法连接到AMQP服务器。关闭中。" + +#: nova/rpc.py:118 +msgid "Reconnected to queue" +msgstr "重新与队列建立连接" + +#: nova/rpc.py:125 +msgid "Failed to fetch message from queue" +msgstr "从队列获取数据失败" + +#: nova/rpc.py:155 +#, python-format +msgid "Initing the Adapter Consumer for %s" +msgstr "" + +#: nova/rpc.py:170 +#, python-format +msgid "received %s" +msgstr "已接收 %s" + +#: nova/rpc.py:183 +#, python-format +msgid "no method for message: %s" +msgstr "没有适用于消息%s的方法" + +#: nova/rpc.py:184 +#, python-format +msgid "No method for message: %s" +msgstr "没有适用于消息%s的方法" + +#: nova/rpc.py:245 +#, python-format +msgid "Returning exception %s to caller" +msgstr "返回%s异常给调用者" + +#: nova/rpc.py:286 +#, python-format +msgid "unpacked context: %s" +msgstr "" + +#: nova/rpc.py:305 +msgid "Making asynchronous call..." +msgstr "产生异步调用中……" + +#: nova/rpc.py:308 +#, python-format +msgid "MSG_ID is %s" +msgstr "消息ID(MSG_ID)是 %s" + +#: nova/rpc.py:356 +#, python-format +msgid "response %s" +msgstr "回复 %s" + +#: nova/rpc.py:365 +#, python-format +msgid "topic is %s" +msgstr "话题是 %s" + +#: nova/rpc.py:366 +#, python-format +msgid "message %s" +msgstr "消息 %s" + +#: nova/service.py:157 +#, python-format +msgid "Starting %s node" +msgstr "启动%s节点" + +#: nova/service.py:169 +msgid "Service killed that has no database entry" +msgstr "因无数据库记录,服务已被中止" + +#: nova/service.py:190 +msgid "The service database object disappeared, Recreating it." +msgstr "" + +#: nova/service.py:202 +msgid "Recovered model server connection!" +msgstr "与模型服务器(model server)的连接已恢复!" + +#: nova/service.py:208 +msgid "model server went away" +msgstr "失去与模型服务器的连接" + +#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#, python-format +msgid "Data store %s is unreachable. Trying again in %d seconds." +msgstr "数据储存服务%s不可用。%d秒之后继续尝试。" + +#: nova/service.py:232 nova/twistd.py:232 +#, python-format +msgid "Serving %s" +msgstr "正在为%s服务" + +#: nova/service.py:234 nova/twistd.py:264 +msgid "Full set of FLAGS:" +msgstr "FLAGS全集:" + +#: nova/twistd.py:211 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "pidfile %s不存在。后台服务没有运行?\n" + +#: nova/utils.py:53 +#, python-format +msgid "Inner Exception: %s" +msgstr "内层异常:%s" + +#: nova/utils.py:54 +#, python-format +msgid "Class %s cannot be found" +msgstr "无法找到%s类" + +#: nova/utils.py:113 +#, python-format +msgid "Fetching %s" +msgstr "正在抓取%s" + +#: nova/utils.py:125 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "正在运行(在子进程中)运行命令:%s" + +#: nova/utils.py:138 +#, python-format +msgid "Result was %s" +msgstr "运行结果为 %s" + +#: nova/utils.py:171 +#, python-format +msgid "debug in callback: %s" +msgstr "回调中debug:%s" + +#: nova/utils.py:176 +#, python-format +msgid "Running %s" +msgstr "正在运行 %s" + +#: nova/utils.py:207 +#, python-format +msgid "Couldn't get IP, using 127.0.0.1 %s" +msgstr "不能获取IP,将使用 127.0.0.1 %s" + +#: nova/utils.py:289 +#, python-format +msgid "Invalid backend: %s" +msgstr "无效的后台:%s" + +#: nova/utils.py:300 +#, python-format +msgid "backend %s" +msgstr "后台 %s" + +#: nova/api/ec2/__init__.py:133 +msgid "Too many failed authentications." +msgstr "较多失败的认证" + +#: nova/api/ec2/__init__.py:142 +#, python-format +msgid "" +"Access key %s has had %d failed authentications and will be locked out for " +"%d minutes." +msgstr "访问键 %s时,存在%d个失败的认证,将于%d分钟后解锁" + +#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#, python-format +msgid "Authentication Failure: %s" +msgstr "认证失败:%s" + +#: nova/api/ec2/__init__.py:190 +#, python-format +msgid "Authenticated Request For %s:%s)" +msgstr "为%s:%s申请认证" + +#: nova/api/ec2/__init__.py:227 +#, python-format +msgid "action: %s" +msgstr "执行: %s" + +#: nova/api/ec2/__init__.py:229 +#, python-format +msgid "arg: %s\t\tval: %s" +msgstr "键为: %s\t\t值为: %s" + +#: nova/api/ec2/__init__.py:301 +#, python-format +msgid "Unauthorized request for controller=%s and action=%s" +msgstr "对于控制器=%s和执行=%s的请求,未审核" + +#: nova/api/ec2/__init__.py:339 +#, python-format +msgid "NotFound raised: %s" +msgstr "引起没有找到的错误: %s" + +#: nova/api/ec2/__init__.py:342 +#, python-format +msgid "ApiError raised: %s" +msgstr "引发了Api错误: %s" + +#: nova/api/ec2/__init__.py:349 +#, python-format +msgid "Unexpected error raised: %s" +msgstr "引发了未知的错误: %s" + +#: nova/api/ec2/__init__.py:354 +msgid "An unknown error has occurred. Please try your request again." +msgstr "发生了一个未知的错误. 请重试你的请求." + +#: nova/api/ec2/admin.py:84 +#, python-format +msgid "Creating new user: %s" +msgstr "创建新用户: %s" + +#: nova/api/ec2/admin.py:92 +#, python-format +msgid "Deleting user: %s" +msgstr "删除用户: %s" + +#: nova/api/ec2/admin.py:114 +#, python-format +msgid "Adding role %s to user %s for project %s" +msgstr "增加角色 %s给用户 %s,在工程 %s中" + +#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#, python-format +msgid "Adding sitewide role %s to user %s" +msgstr "增加站点范围的 %s角色给用户 %s" + +#: nova/api/ec2/admin.py:122 +#, python-format +msgid "Removing role %s from user %s for project %s" +msgstr "移除角色 %s从用户 %s中,在工程 %s" + +#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#, python-format +msgid "Removing sitewide role %s from user %s" +msgstr "移除站点范围的 %s角色从用户 %s中" + +#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 +msgid "operation must be add or remove" +msgstr "操作必须为增加或删除" + +#: nova/api/ec2/admin.py:142 +#, python-format +msgid "Getting x509 for user: %s on project: %s" +msgstr "为用户 %s从工程%s中获取 x509" + +#: nova/api/ec2/admin.py:159 +#, python-format +msgid "Create project %s managed by %s" +msgstr "创建工程%s,此工程由%s管理" + +#: nova/api/ec2/admin.py:170 +#, python-format +msgid "Delete project: %s" +msgstr "删除工程%s" + +#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#, python-format +msgid "Adding user %s to project %s" +msgstr "增加用户%s到%s工程" + +#: nova/api/ec2/admin.py:188 +#, python-format +msgid "Removing user %s from project %s" +msgstr "移除用户%s从工程%s中" + +#: nova/api/ec2/apirequest.py:95 +#, python-format +msgid "Unsupported API request: controller = %s,action = %s" +msgstr "不支持的API请求: 控制器 = %s,执行 = %s" + +#: nova/api/ec2/cloud.py:117 +#, python-format +msgid "Generating root CA: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:277 +#, python-format +msgid "Create key pair %s" +msgstr "创建键值对 %s" + +#: nova/api/ec2/cloud.py:285 +#, python-format +msgid "Delete key pair %s" +msgstr "" + +#: nova/api/ec2/cloud.py:357 +#, python-format +msgid "%s is not a valid ipProtocol" +msgstr "" + +#: nova/api/ec2/cloud.py:361 +msgid "Invalid port range" +msgstr "" + +#: nova/api/ec2/cloud.py:392 +#, python-format +msgid "Revoke security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 +msgid "No rule for the specified parameters." +msgstr "" + +#: nova/api/ec2/cloud.py:421 +#, python-format +msgid "Authorize security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:432 +#, python-format +msgid "This rule already exists in group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:460 +#, python-format +msgid "Create Security Group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:463 +#, python-format +msgid "group %s already exists" +msgstr "" + +#: nova/api/ec2/cloud.py:475 +#, python-format +msgid "Delete security group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:543 +#, python-format +msgid "Create volume of %s GB" +msgstr "" + +#: nova/api/ec2/cloud.py:567 +#, python-format +msgid "Attach volume %s to instacne %s at %s" +msgstr "" + +#: nova/api/ec2/cloud.py:579 +#, python-format +msgid "Detach volume %s" +msgstr "" + +#: nova/api/ec2/cloud.py:686 +msgid "Allocate address" +msgstr "" + +#: nova/api/ec2/cloud.py:691 +#, python-format +msgid "Release address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:696 +#, python-format +msgid "Associate address %s to instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:703 +#, python-format +msgid "Disassociate address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:730 +msgid "Going to start terminating instances" +msgstr "" + +#: nova/api/ec2/cloud.py:738 +#, python-format +msgid "Reboot instance %r" +msgstr "" + +#: nova/api/ec2/cloud.py:775 +#, python-format +msgid "De-registering image %s" +msgstr "" + +#: nova/api/ec2/cloud.py:783 +#, python-format +msgid "Registered image %s with id %s" +msgstr "" + +#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#, python-format +msgid "attribute not supported: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:794 +#, python-format +msgid "invalid id: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:807 +msgid "user or group not specified" +msgstr "" + +#: nova/api/ec2/cloud.py:809 +msgid "only group \"all\" is supported" +msgstr "" + +#: nova/api/ec2/cloud.py:811 +msgid "operation_type must be add or remove" +msgstr "" + +#: nova/api/ec2/cloud.py:812 +#, python-format +msgid "Updating image %s publicity" +msgstr "" + +#: nova/api/ec2/metadatarequesthandler.py:75 +#, python-format +msgid "Failed to get metadata for ip: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:70 +#, python-format +msgid "Caught error: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:86 +msgid "Including admin operations in API." +msgstr "" + +#: nova/api/openstack/servers.py:184 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:199 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: nova/api/openstack/servers.py:213 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:224 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: nova/api/openstack/servers.py:235 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: nova/api/openstack/servers.py:246 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: nova/api/openstack/servers.py:257 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: nova/auth/dbdriver.py:84 +#, python-format +msgid "User %s already exists" +msgstr "" + +#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#, python-format +msgid "Project can't be created because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#, python-format +msgid "Project can't be created because project %s already exists" +msgstr "" + +#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#, python-format +msgid "Project can't be modified because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:245 +#, python-format +msgid "User \"%s\" not found" +msgstr "" + +#: nova/auth/dbdriver.py:248 +#, python-format +msgid "Project \"%s\" not found" +msgstr "" + +#: nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "" + +#: nova/auth/ldapdriver.py:181 +#, python-format +msgid "LDAP object for %s doesn't exist" +msgstr "" + +#: nova/auth/ldapdriver.py:218 +#, python-format +msgid "Project can't be created because user %s doesn't exist" +msgstr "" + +#: nova/auth/ldapdriver.py:478 +#, python-format +msgid "User %s is already a member of the group %s" +msgstr "" + +#: nova/auth/ldapdriver.py:507 +#, python-format +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." +msgstr "" + +#: nova/auth/ldapdriver.py:528 +#, python-format +msgid "Group at dn %s doesn't exist" +msgstr "" + +#: nova/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "" + +#: nova/auth/manager.py:263 +#, python-format +msgid "Failed authorization for access key %s" +msgstr "" + +#: nova/auth/manager.py:264 +#, python-format +msgid "No user found for access key %s" +msgstr "" + +#: nova/auth/manager.py:270 +#, python-format +msgid "Using project name = user name (%s)" +msgstr "" + +#: nova/auth/manager.py:275 +#, python-format +msgid "failed authorization: no project named %s (user=%s)" +msgstr "" + +#: nova/auth/manager.py:277 +#, python-format +msgid "No project called %s could be found" +msgstr "" + +#: nova/auth/manager.py:281 +#, python-format +msgid "Failed authorization: user %s not admin and not member of project %s" +msgstr "" + +#: nova/auth/manager.py:283 +#, python-format +msgid "User %s is not a member of project %s" +msgstr "" + +#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#, python-format +msgid "Invalid signature for user %s" +msgstr "" + +#: nova/auth/manager.py:293 nova/auth/manager.py:304 +msgid "Signature does not match" +msgstr "" + +#: nova/auth/manager.py:374 +msgid "Must specify project" +msgstr "" + +#: nova/auth/manager.py:408 +#, python-format +msgid "The %s role can not be found" +msgstr "" + +#: nova/auth/manager.py:410 +#, python-format +msgid "The %s role is global only" +msgstr "" + +#: nova/auth/manager.py:412 +#, python-format +msgid "Adding role %s to user %s in project %s" +msgstr "" + +#: nova/auth/manager.py:438 +#, python-format +msgid "Removing role %s from user %s on project %s" +msgstr "" + +#: nova/auth/manager.py:505 +#, python-format +msgid "Created project %s with manager %s" +msgstr "" + +#: nova/auth/manager.py:523 +#, python-format +msgid "modifying project %s" +msgstr "" + +#: nova/auth/manager.py:553 +#, python-format +msgid "Remove user %s from project %s" +msgstr "" + +#: nova/auth/manager.py:581 +#, python-format +msgid "Deleting project %s" +msgstr "" + +#: nova/auth/manager.py:637 +#, python-format +msgid "Created user %s (admin: %r)" +msgstr "" + +#: nova/auth/manager.py:645 +#, python-format +msgid "Deleting user %s" +msgstr "" + +#: nova/auth/manager.py:655 +#, python-format +msgid "Access Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:657 +#, python-format +msgid "Secret Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:659 +#, python-format +msgid "Admin status set to %r for user %s" +msgstr "" + +#: nova/auth/manager.py:708 +#, python-format +msgid "No vpn data for project %s" +msgstr "" + +#: nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" +msgstr "" + +#: nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:97 +#, python-format +msgid "Launching VPN for %s" +msgstr "" + +#: nova/compute/api.py:67 +#, python-format +msgid "Instance %d was not found in get_network_topic" +msgstr "" + +#: nova/compute/api.py:73 +#, python-format +msgid "Instance %d has no host" +msgstr "" + +#: nova/compute/api.py:92 +#, python-format +msgid "Quota exceeeded for %s, tried to run %s instances" +msgstr "" + +#: nova/compute/api.py:94 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." +msgstr "" + +#: nova/compute/api.py:109 +msgid "Creating a raw instance" +msgstr "" + +#: nova/compute/api.py:156 +#, python-format +msgid "Going to run %s instances..." +msgstr "" + +#: nova/compute/api.py:180 +#, python-format +msgid "Casting to scheduler for %s/%s's instance %s" +msgstr "" + +#: nova/compute/api.py:279 +#, python-format +msgid "Going to try and terminate %s" +msgstr "" + +#: nova/compute/api.py:283 +#, python-format +msgid "Instance %d was not found during terminate" +msgstr "" + +#: nova/compute/api.py:288 +#, python-format +msgid "Instance %d is already being terminated" +msgstr "" + +#: nova/compute/api.py:450 +#, python-format +msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgstr "" + +#: nova/compute/api.py:465 +msgid "Volume isn't attached to anything!" +msgstr "" + +#: nova/compute/disk.py:71 +#, python-format +msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:75 +#, python-format +msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:128 +#, python-format +msgid "Could not attach image to loopback: %s" +msgstr "" + +#: nova/compute/disk.py:136 +#, python-format +msgid "Failed to load partition: %s" +msgstr "" + +#: nova/compute/disk.py:158 +#, python-format +msgid "Failed to mount filesystem: %s" +msgstr "" + +#: nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "" + +#: nova/compute/manager.py:69 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: nova/compute/manager.py:71 +#, python-format +msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgstr "" + +#: nova/compute/manager.py:75 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: nova/compute/manager.py:77 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: nova/compute/manager.py:82 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: nova/compute/manager.py:157 +msgid "Instance has already been created" +msgstr "" + +#: nova/compute/manager.py:158 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#: nova/compute/manager.py:197 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: nova/compute/manager.py:217 +#, python-format +msgid "Disassociating address %s" +msgstr "" + +#: nova/compute/manager.py:230 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: nova/compute/manager.py:243 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: nova/compute/manager.py:257 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: nova/compute/manager.py:260 +#, python-format +msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:286 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: nova/compute/manager.py:289 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:301 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: nova/compute/manager.py:316 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: nova/compute/manager.py:335 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: nova/compute/manager.py:352 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: nova/compute/manager.py:369 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: nova/compute/manager.py:382 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: nova/compute/manager.py:401 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: nova/compute/manager.py:420 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: nova/compute/manager.py:432 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: nova/compute/manager.py:442 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: nova/compute/manager.py:462 +#, python-format +msgid "instance %s: attaching volume %s to %s" +msgstr "" + +#: nova/compute/manager.py:478 +#, python-format +msgid "instance %s: attach failed %s, removing" +msgstr "" + +#: nova/compute/manager.py:493 +#, python-format +msgid "Detach volume %s from mountpoint %s on instance %s" +msgstr "" + +#: nova/compute/manager.py:497 +#, python-format +msgid "Detaching volume from unknown instance %s" +msgstr "" + +#: nova/compute/monitor.py:259 +#, python-format +msgid "updating %s..." +msgstr "" + +#: nova/compute/monitor.py:289 +msgid "unexpected error during update" +msgstr "" + +#: nova/compute/monitor.py:355 +#, python-format +msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:377 +#, python-format +msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:412 +msgid "unexpected exception getting connection" +msgstr "" + +#: nova/compute/monitor.py:427 +#, python-format +msgid "Found instance: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:43 +msgid "Use of empty request context is deprecated" +msgstr "" + +#: nova/db/sqlalchemy/api.py:132 +#, python-format +msgid "No service for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:229 +#, python-format +msgid "No service for %s, %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:574 +#, python-format +msgid "No floating ip for address %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:668 +#, python-format +msgid "No instance for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:758 nova/virt/libvirt_conn.py:598 +#: nova/virt/xenapi/volumeops.py:48 nova/virt/xenapi/volumeops.py:103 +#, python-format +msgid "Instance %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:891 +#, python-format +msgid "no keypair for user %s, name %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#, python-format +msgid "No network for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1036 +#, python-format +msgid "No network for bridge %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1050 +#, python-format +msgid "No network for instance %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1180 +#, python-format +msgid "Token %s does not exist" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1205 +#, python-format +msgid "No quota for project_id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1356 +#, python-format +msgid "No volume for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1401 +#, python-format +msgid "Volume %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1413 +#, python-format +msgid "No export device found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1426 +#, python-format +msgid "No target id found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1471 +#, python-format +msgid "No security group with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1488 +#, python-format +msgid "No security group named %s for project: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1576 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1650 +#, python-format +msgid "No user for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1666 +#, python-format +msgid "No user for access key %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1728 +#, python-format +msgid "No project with id %s" +msgstr "" + +#: nova/image/glance.py:78 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images" +msgstr "" + +#: nova/image/glance.py:97 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images/detail" +msgstr "" + +#: nova/image/s3.py:82 +#, python-format +msgid "Image %s could not be found" +msgstr "" + +#: nova/network/api.py:39 +#, python-format +msgid "Quota exceeeded for %s, tried to allocate address" +msgstr "" + +#: nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" +msgstr "" + +#: nova/network/linux_net.py:176 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: nova/network/linux_net.py:186 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#: nova/network/linux_net.py:254 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: nova/network/linux_net.py:256 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#: nova/network/linux_net.py:334 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: nova/network/manager.py:135 +msgid "setting network host" +msgstr "" + +#: nova/network/manager.py:190 +#, python-format +msgid "Leasing IP %s" +msgstr "" + +#: nova/network/manager.py:194 +#, python-format +msgid "IP %s leased that isn't associated" +msgstr "" + +#: nova/network/manager.py:197 +#, python-format +msgid "IP %s leased to bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:205 +#, python-format +msgid "IP %s leased that was already deallocated" +msgstr "" + +#: nova/network/manager.py:214 +#, python-format +msgid "IP %s released that isn't associated" +msgstr "" + +#: nova/network/manager.py:217 +#, python-format +msgid "IP %s released from bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:220 +#, python-format +msgid "IP %s released that was not leased" +msgstr "" + +#: nova/network/manager.py:442 +#, python-format +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "" + +#: nova/objectstore/handler.py:106 +#, python-format +msgid "Unknown S3 value type %r" +msgstr "" + +#: nova/objectstore/handler.py:137 +msgid "Authenticated request" +msgstr "" + +#: nova/objectstore/handler.py:182 +msgid "List of buckets requested" +msgstr "" + +#: nova/objectstore/handler.py:209 +#, python-format +msgid "List keys for bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:217 +#, python-format +msgid "Unauthorized attempt to access bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:235 +#, python-format +msgid "Creating bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:245 +#, python-format +msgid "Deleting bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:249 +#, python-format +msgid "Unauthorized attempt to delete bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:271 +#, python-format +msgid "Getting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:274 +#, python-format +msgid "Unauthorized attempt to get object %s from bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:292 +#, python-format +msgid "Putting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:295 +#, python-format +msgid "Unauthorized attempt to upload object %s to bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:314 +#, python-format +msgid "Deleting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:393 +#, python-format +msgid "Not authorized to upload image: invalid directory %s" +msgstr "" + +#: nova/objectstore/handler.py:401 +#, python-format +msgid "Not authorized to upload image: unauthorized bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:406 +#, python-format +msgid "Starting image upload: %s" +msgstr "" + +#: nova/objectstore/handler.py:420 +#, python-format +msgid "Not authorized to update attributes of image %s" +msgstr "" + +#: nova/objectstore/handler.py:428 +#, python-format +msgid "Toggling publicity flag of image %s %r" +msgstr "" + +#: nova/objectstore/handler.py:433 +#, python-format +msgid "Updating user fields on image %s" +msgstr "" + +#: nova/objectstore/handler.py:447 +#, python-format +msgid "Unauthorized attempt to delete image %s" +msgstr "" + +#: nova/objectstore/handler.py:452 +#, python-format +msgid "Deleted image: %s" +msgstr "" + +#: nova/scheduler/chance.py:37 nova/scheduler/simple.py:73 +#: nova/scheduler/simple.py:106 nova/scheduler/simple.py:118 +msgid "No hosts found" +msgstr "" + +#: nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "" + +#: nova/scheduler/manager.py:69 +#, python-format +msgid "Casting to %s %s for %s" +msgstr "" + +#: nova/scheduler/simple.py:63 +msgid "All hosts have too many cores" +msgstr "" + +#: nova/scheduler/simple.py:95 +msgid "All hosts have too many gigabytes" +msgstr "" + +#: nova/scheduler/simple.py:115 +msgid "All hosts have too many networks" +msgstr "" + +#: nova/tests/test_cloud.py:198 +msgid "Can't test instances without a real virtual env." +msgstr "" + +#: nova/tests/test_cloud.py:210 +#, python-format +msgid "Need to watch instance %s until it's running..." +msgstr "" + +#: nova/tests/test_compute.py:104 +#, python-format +msgid "Running instances: %s" +msgstr "" + +#: nova/tests/test_compute.py:110 +#, python-format +msgid "After terminating instances: %s" +msgstr "" + +#: nova/tests/test_rpc.py:89 +#, python-format +msgid "Nested received %s, %s" +msgstr "" + +#: nova/tests/test_rpc.py:94 +#, python-format +msgid "Nested return %s" +msgstr "" + +#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#, python-format +msgid "Received %s" +msgstr "" + +#: nova/tests/test_volume.py:162 +#, python-format +msgid "Target %s allocated" +msgstr "" + +#: nova/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "" + +#: nova/virt/fake.py:210 +#, python-format +msgid "Instance %s Not Found" +msgstr "" + +#: nova/virt/hyperv.py:118 +msgid "In init host" +msgstr "" + +#: nova/virt/hyperv.py:131 +#, python-format +msgid "Attempt to create duplicate vm %s" +msgstr "" + +#: nova/virt/hyperv.py:148 +#, python-format +msgid "Starting VM %s " +msgstr "" + +#: nova/virt/hyperv.py:150 +#, python-format +msgid "Started VM %s " +msgstr "" + +#: nova/virt/hyperv.py:152 +#, python-format +msgid "spawn vm failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:169 +#, python-format +msgid "Failed to create VM %s" +msgstr "" + +#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#, python-format +msgid "Created VM %s..." +msgstr "" + +#: nova/virt/hyperv.py:188 +#, python-format +msgid "Set memory for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:198 +#, python-format +msgid "Set vcpus for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:202 +#, python-format +msgid "Creating disk for %s by attaching disk file %s" +msgstr "" + +#: nova/virt/hyperv.py:227 +#, python-format +msgid "Failed to add diskdrive to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:230 +#, python-format +msgid "New disk drive path is %s" +msgstr "" + +#: nova/virt/hyperv.py:247 +#, python-format +msgid "Failed to add vhd file to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:249 +#, python-format +msgid "Created disk for %s" +msgstr "" + +#: nova/virt/hyperv.py:253 +#, python-format +msgid "Creating nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" +msgstr "" + +#: nova/virt/hyperv.py:273 +#, python-format +msgid "Failed creating port for %s" +msgstr "" + +#: nova/virt/hyperv.py:275 +#, python-format +msgid "Created switch port %s on switch %s" +msgstr "" + +#: nova/virt/hyperv.py:285 +#, python-format +msgid "Failed to add nic to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:287 +#, python-format +msgid "Created nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:320 +#, python-format +msgid "WMI job failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:322 +#, python-format +msgid "WMI job succeeded: %s, Elapsed=%s " +msgstr "" + +#: nova/virt/hyperv.py:358 +#, python-format +msgid "Got request to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:383 +#, python-format +msgid "Failed to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:389 +#, python-format +msgid "Del: disk %s vm %s" +msgstr "" + +#: nova/virt/hyperv.py:405 +#, python-format +msgid "" +"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " +"cpu_time=%s" +msgstr "" + +#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#, python-format +msgid "duplicate name found: %s" +msgstr "" + +#: nova/virt/hyperv.py:444 +#, python-format +msgid "Successfully changed vm state of %s to %s" +msgstr "" + +#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#, python-format +msgid "Failed to change vm state of %s to %s" +msgstr "" + +#: nova/virt/images.py:70 +#, python-format +msgid "Finished retreving %s -- placed in %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:144 +#, python-format +msgid "Connecting to libvirt: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:157 +msgid "Connection to libvirt broke" +msgstr "" + +#: nova/virt/libvirt_conn.py:229 +#, python-format +msgid "instance %s: deleting instance files %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:271 +#, python-format +msgid "No disk at %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:278 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "" + +#: nova/virt/libvirt_conn.py:294 +#, python-format +msgid "instance %s: rebooted" +msgstr "" + +#: nova/virt/libvirt_conn.py:297 +#, python-format +msgid "_wait_for_reboot failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:340 +#, python-format +msgid "instance %s: rescued" +msgstr "" + +#: nova/virt/libvirt_conn.py:343 +#, python-format +msgid "_wait_for_rescue failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:370 +#, python-format +msgid "instance %s: is running" +msgstr "" + +#: nova/virt/libvirt_conn.py:381 +#, python-format +msgid "instance %s: booted" +msgstr "" + +#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#, python-format +msgid "instance %s: failed to boot" +msgstr "" + +#: nova/virt/libvirt_conn.py:395 +#, python-format +msgid "virsh said: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:399 +msgid "cool, it's a device" +msgstr "" + +#: nova/virt/libvirt_conn.py:407 +#, python-format +msgid "data: %r, fpath: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:415 +#, python-format +msgid "Contents of file %s: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:449 +#, python-format +msgid "instance %s: Creating image" +msgstr "" + +#: nova/virt/libvirt_conn.py:505 +#, python-format +msgid "instance %s: injecting key into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:508 +#, python-format +msgid "instance %s: injecting net into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:516 +#, python-format +msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgstr "" + +#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#, python-format +msgid "instance %s: starting toXML method" +msgstr "" + +#: nova/virt/libvirt_conn.py:589 +#, python-format +msgid "instance %s: finished toXML method" +msgstr "" + +#: nova/virt/xenapi_conn.py:113 +msgid "" +"Must specify xenapi_connection_url, xenapi_connection_username (optionally), " +"and xenapi_connection_password to use connection_type=xenapi" +msgstr "" + +#: nova/virt/xenapi_conn.py:263 +#, python-format +msgid "Task [%s] %s status: success %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:271 +#, python-format +msgid "Task [%s] %s status: %s %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#, python-format +msgid "Got exception: %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:72 +#, python-format +msgid "%s: _db_content => %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:247 nova/virt/xenapi/fake.py:338 +#: nova/virt/xenapi/fake.py:356 nova/virt/xenapi/fake.py:404 +msgid "Raising NotImplemented" +msgstr "" + +#: nova/virt/xenapi/fake.py:249 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:283 +#, python-format +msgid "Calling %s %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:288 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:340 +#, python-format +msgid "" +"xenapi.fake does not have an implementation for %s or it has been called " +"with the wrong number of arguments" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:40 +#, python-format +msgid "Found non-unique network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:43 +#, python-format +msgid "Found no network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:127 +#, python-format +msgid "Created VM %s as %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:147 +#, python-format +msgid "Creating VBD for VM %s, VDI %s ... " +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:149 +#, python-format +msgid "Created VBD %s for VM %s, VDI %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:165 +#, python-format +msgid "VBD not found in instance %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:175 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:202 +#, python-format +msgid "Creating VIF for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:205 +#, python-format +msgid "Created VIF %s for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:216 +#, python-format +msgid "Snapshotting VM %s with label '%s'..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:229 +#, python-format +msgid "Created snapshot %s from VM %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:243 +#, python-format +msgid "Asking xapi to upload %s as '%s'" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:261 +#, python-format +msgid "Asking xapi to fetch %s as %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:279 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:290 +#, python-format +msgid "PV Kernel in VDI:%d" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:318 +#, python-format +msgid "VDI %s is still available" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:331 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:333 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:390 +#, python-format +msgid "VHD %s has parent %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:407 +#, python-format +msgid "Re-scanning SR %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:431 +#, python-format +msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:448 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:452 +#, python-format +msgid "Unexpected number of VDIs (%s) found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:62 +#, python-format +msgid "Attempted to create non-unique name %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:99 +#, python-format +msgid "Starting VM %s..." +msgstr "" + +#: nova/virt/xenapi/vmops.py:101 +#, python-format +msgid "Spawning VM %s created %s." +msgstr "" + +#: nova/virt/xenapi/vmops.py:112 +#, python-format +msgid "Instance %s: booted" +msgstr "" + +#: nova/virt/xenapi/vmops.py:137 +#, python-format +msgid "Instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:166 +#, python-format +msgid "Starting snapshot for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:174 +#, python-format +msgid "Unable to Snapshot %s: %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:184 +#, python-format +msgid "Finished snapshot and upload for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:252 +#, python-format +msgid "suspend: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:262 +#, python-format +msgid "resume: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:271 +#, python-format +msgid "Instance not found %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:57 +#, python-format +msgid "Introducing %s..." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:74 +#, python-format +msgid "Introduced %s as %s." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:90 +#, python-format +msgid "Unable to find SR from VBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:96 +#, python-format +msgid "Forgetting SR %s ... " +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:101 +#, python-format +msgid "Ignoring exception %s when getting PBDs for %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:107 +#, python-format +msgid "Ignoring exception %s when unplugging PBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:111 +#, python-format +msgid "Forgetting SR %s done." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:113 +#, python-format +msgid "Ignoring exception %s when forgetting SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:123 +#, python-format +msgid "Unable to introduce VDI on SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:128 +#, python-format +msgid "Unable to get record of VDI %s on" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:146 +#, python-format +msgid "Unable to introduce VDI for SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:175 +#, python-format +msgid "Unable to obtain target information %s, %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:197 +#, python-format +msgid "Mountpoint cannot be translated: %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:51 +#, python-format +msgid "Attach_volume: %s, %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:69 +#, python-format +msgid "Unable to create VDI on SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:81 +#, python-format +msgid "Unable to use SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Unable to attach volume to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:95 +#, python-format +msgid "Mountpoint %s attached to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:106 +#, python-format +msgid "Detach_volume: %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:113 +#, python-format +msgid "Unable to locate volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:121 +#, python-format +msgid "Unable to detach volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:128 +#, python-format +msgid "Mountpoint %s detached from instance %s" +msgstr "" + +#: nova/volume/api.py:44 +#, python-format +msgid "Quota exceeeded for %s, tried to create %sG volume" +msgstr "" + +#: nova/volume/api.py:46 +#, python-format +msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgstr "" + +#: nova/volume/api.py:70 nova/volume/api.py:95 +msgid "Volume status must be available" +msgstr "" + +#: nova/volume/api.py:97 +msgid "Volume is already attached" +msgstr "" + +#: nova/volume/api.py:103 +msgid "Volume is already detached" +msgstr "" + +#: nova/volume/driver.py:76 +#, python-format +msgid "Recovering from a failed execute. Try number %s" +msgstr "" + +#: nova/volume/driver.py:85 +#, python-format +msgid "volume group %s doesn't exist" +msgstr "" + +#: nova/volume/driver.py:210 +#, python-format +msgid "FAKE AOE: %s" +msgstr "" + +#: nova/volume/driver.py:315 +#, python-format +msgid "FAKE ISCSI: %s" +msgstr "" + +#: nova/volume/manager.py:85 +#, python-format +msgid "Re-exporting %s volumes" +msgstr "" + +#: nova/volume/manager.py:93 +#, python-format +msgid "volume %s: creating" +msgstr "" + +#: nova/volume/manager.py:102 +#, python-format +msgid "volume %s: creating lv of size %sG" +msgstr "" + +#: nova/volume/manager.py:106 +#, python-format +msgid "volume %s: creating export" +msgstr "" + +#: nova/volume/manager.py:113 +#, python-format +msgid "volume %s: created successfully" +msgstr "" + +#: nova/volume/manager.py:121 +msgid "Volume is still attached" +msgstr "" + +#: nova/volume/manager.py:123 +msgid "Volume is not local to this node" +msgstr "" + +#: nova/volume/manager.py:124 +#, python-format +msgid "volume %s: removing export" +msgstr "" + +#: nova/volume/manager.py:126 +#, python-format +msgid "volume %s: deleting" +msgstr "" + +#: nova/volume/manager.py:129 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "" From 7919eb1d901768027fd23f08bddf2a41e7f2c452 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 27 Jan 2011 23:53:28 -0600 Subject: [PATCH 005/111] Working on api / manager / db support for zones --- bin/nova-manage | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/bin/nova-manage b/bin/nova-manage index 7835ca55..b62687ae 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -569,6 +569,15 @@ class DbCommands(object): print migration.db_version() +class ZoneCommands(object): + """Methods for defining zones.""" + + def create(self, name): + """Create a new Zone for this deployment.""" + ctxt = context.get_admin_context() + db.create_zone(ctxt, name) + + class VolumeCommands(object): """Methods for dealing with a cloud in an odd state""" @@ -620,6 +629,7 @@ CATEGORIES = [ ('service', ServiceCommands), ('log', LogCommands), ('db', DbCommands), + ('zone', ZoneCommands), ('volume', VolumeCommands)] From 6c72c5a43cd970081f45e439f875912422f7c3b2 Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of nova-core <> Date: Tue, 1 Feb 2011 05:19:59 +0000 Subject: [PATCH 006/111] Launchpad automatic translations update. --- locale/ru.po | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/locale/ru.po b/locale/ru.po index c751f41b..6a75c172 100644 --- a/locale/ru.po +++ b/locale/ru.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: nova\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-10 11:25-0800\n" -"PO-Revision-Date: 2011-01-25 17:45+0000\n" -"Last-Translator: Ilya Alekseyev \n" +"PO-Revision-Date: 2011-01-31 06:53+0000\n" +"Last-Translator: Andrey Olykainen \n" "Language-Team: Russian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-01-28 05:20+0000\n" +"X-Launchpad-Export-Date: 2011-02-01 05:19+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 @@ -31,7 +31,7 @@ msgstr "" #: nova/crypto.py:53 msgid "Where we keep our keys" -msgstr "" +msgstr "Путь к ключам" #: nova/crypto.py:55 msgid "Where we keep our root CA" @@ -112,7 +112,7 @@ msgstr "" #: nova/fakerabbit.py:120 #, python-format msgid "Getting from %s: %s" -msgstr "" +msgstr "Получение из %s: %s" #: nova/rpc.py:92 #, python-format @@ -174,7 +174,7 @@ msgstr "MSG_ID is %s" #: nova/rpc.py:356 #, python-format msgid "response %s" -msgstr "" +msgstr "ответ %s" #: nova/rpc.py:365 #, python-format @@ -264,7 +264,7 @@ msgstr "" #: nova/utils.py:176 #, python-format msgid "Running %s" -msgstr "" +msgstr "Выполняется %s" #: nova/utils.py:207 #, python-format @@ -291,16 +291,18 @@ msgid "" "Access key %s has had %d failed authentications and will be locked out for " "%d minutes." msgstr "" +"Ключ доступа %s имеет %d неудачных попыток аутентификации и будет " +"заблокирован на %d минут." #: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 #, python-format msgid "Authentication Failure: %s" -msgstr "" +msgstr "Ошибка аутентификации: %s" #: nova/api/ec2/__init__.py:190 #, python-format msgid "Authenticated Request For %s:%s)" -msgstr "" +msgstr "Запрос аутентификации для %s:%s)" #: nova/api/ec2/__init__.py:227 #, python-format @@ -547,7 +549,7 @@ msgstr "" #: nova/api/ec2/metadatarequesthandler.py:75 #, python-format msgid "Failed to get metadata for ip: %s" -msgstr "" +msgstr "Ошибка получения метаданных для ip: %s" #: nova/api/openstack/__init__.py:70 #, python-format From b81bb26d5d7e7d208adc500c7905759f16a16738 Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of nova-core <> Date: Fri, 4 Feb 2011 05:31:40 +0000 Subject: [PATCH 007/111] Launchpad automatic translations update. --- locale/ast.po | 2 +- locale/da.po | 2 +- locale/es.po | 2 +- locale/it.po | 2 +- locale/ja.po | 2 +- locale/pt_BR.po | 16 ++++++++-------- locale/ru.po | 2 +- locale/uk.po | 25 +++++++++++++++---------- locale/zh_CN.po | 2 +- 9 files changed, 30 insertions(+), 25 deletions(-) diff --git a/locale/ast.po b/locale/ast.po index c887bbc9..310f299b 100644 --- a/locale/ast.po +++ b/locale/ast.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-01-28 05:20+0000\n" +"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 diff --git a/locale/da.po b/locale/da.po index 524b27a6..ac1b593b 100644 --- a/locale/da.po +++ b/locale/da.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-01-28 05:20+0000\n" +"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 diff --git a/locale/es.po b/locale/es.po index a1cf5b7f..28f10c48 100644 --- a/locale/es.po +++ b/locale/es.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-01-28 05:20+0000\n" +"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 diff --git a/locale/it.po b/locale/it.po index f2f6a6b8..f08497ba 100644 --- a/locale/it.po +++ b/locale/it.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-01-28 05:20+0000\n" +"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 diff --git a/locale/ja.po b/locale/ja.po index 919625e9..b11bb67b 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-01-28 05:20+0000\n" +"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 diff --git a/locale/pt_BR.po b/locale/pt_BR.po index a58ccc18..c778bb63 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: nova\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-10 11:25-0800\n" -"PO-Revision-Date: 2011-01-13 18:44+0000\n" -"Last-Translator: Gustavo Morozowski \n" +"PO-Revision-Date: 2011-02-03 20:32+0000\n" +"Last-Translator: André Gondim \n" "Language-Team: Brazilian Portuguese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-01-28 05:21+0000\n" +"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 @@ -60,7 +60,7 @@ msgstr "Sujeito do certificado para vpns, %s para projeto, timestamp" #: nova/crypto.py:258 #, python-format msgid "Flags path: %s" -msgstr "" +msgstr "Caminho da sinalização: %s" #: nova/exception.py:33 msgid "Unexpected error while running command." @@ -103,7 +103,7 @@ msgstr "Declarando fila %s" #: nova/fakerabbit.py:89 #, python-format msgid "Declaring exchange %s" -msgstr "" +msgstr "Declarando troca %s" #: nova/fakerabbit.py:95 #, python-format @@ -432,7 +432,7 @@ msgstr "%s não é um ipProtocol válido" #: nova/api/ec2/cloud.py:361 msgid "Invalid port range" -msgstr "" +msgstr "Intervalo de porta inválido" #: nova/api/ec2/cloud.py:392 #, python-format @@ -767,7 +767,7 @@ msgstr "Criado usuário %s (administrador: %r)" #: nova/auth/manager.py:645 #, python-format msgid "Deleting user %s" -msgstr "" +msgstr "Apagando usuário %s" #: nova/auth/manager.py:655 #, python-format @@ -804,7 +804,7 @@ msgstr "" #: nova/cloudpipe/pipelib.py:97 #, python-format msgid "Launching VPN for %s" -msgstr "" +msgstr "Executando VPN para %s" #: nova/compute/api.py:67 #, python-format diff --git a/locale/ru.po b/locale/ru.po index 6a75c172..fc97d560 100644 --- a/locale/ru.po +++ b/locale/ru.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-01 05:19+0000\n" +"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 diff --git a/locale/uk.po b/locale/uk.po index cdbffd13..be2371db 100644 --- a/locale/uk.po +++ b/locale/uk.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: nova\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-10 11:25-0800\n" -"PO-Revision-Date: 2011-01-13 07:03+0000\n" +"PO-Revision-Date: 2011-02-03 22:02+0000\n" "Last-Translator: Wladimir Rossinski \n" "Language-Team: Ukrainian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-01-28 05:20+0000\n" +"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 @@ -23,7 +23,7 @@ msgstr "" #: nova/crypto.py:49 msgid "Filename of private key" -msgstr "" +msgstr "Ім'я файлу секретного ключа" #: nova/crypto.py:51 msgid "Filename of root Certificate Revokation List" @@ -31,7 +31,7 @@ msgstr "" #: nova/crypto.py:53 msgid "Where we keep our keys" -msgstr "" +msgstr "Шлях до збережених ключів" #: nova/crypto.py:55 msgid "Where we keep our root CA" @@ -63,7 +63,7 @@ msgstr "" #: nova/exception.py:33 msgid "Unexpected error while running command." -msgstr "" +msgstr "Неочікувана помилка при виконанні команди." #: nova/exception.py:36 #, python-format @@ -74,10 +74,15 @@ msgid "" "Stdout: %r\n" "Stderr: %r" msgstr "" +"%s\n" +"Команда: %s\n" +"Код завершення: %s\n" +"Stdout: %r\n" +"Stderr: %r" #: nova/exception.py:86 msgid "Uncaught exception" -msgstr "" +msgstr "Необроблене виключення" #: nova/fakerabbit.py:48 #, python-format @@ -92,12 +97,12 @@ msgstr "" #: nova/fakerabbit.py:83 #, python-format msgid "Declaring queue %s" -msgstr "" +msgstr "Оголошення черги %s" #: nova/fakerabbit.py:89 #, python-format msgid "Declaring exchange %s" -msgstr "" +msgstr "Оголошення точки обміну %s" #: nova/fakerabbit.py:95 #, python-format @@ -107,7 +112,7 @@ msgstr "" #: nova/fakerabbit.py:120 #, python-format msgid "Getting from %s: %s" -msgstr "" +msgstr "Отримання з %s: %s" #: nova/rpc.py:92 #, python-format @@ -121,7 +126,7 @@ msgstr "Не вдалось під'єднатися до серверу AMQP п #: nova/rpc.py:118 msgid "Reconnected to queue" -msgstr "" +msgstr "Оновлено з'єднання до черги" #: nova/rpc.py:125 msgid "Failed to fetch message from queue" diff --git a/locale/zh_CN.po b/locale/zh_CN.po index 4805eb32..feee54cf 100644 --- a/locale/zh_CN.po +++ b/locale/zh_CN.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-01-28 05:21+0000\n" +"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/twistd.py:268 From 528325c239c30b9d0df73950f5d86829bff1f7a7 Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of nova-core <> Date: Sat, 5 Feb 2011 05:36:48 +0000 Subject: [PATCH 008/111] Launchpad automatic translations update. --- locale/ast.po | 2 +- locale/da.po | 2 +- locale/es.po | 2 +- locale/it.po | 2 +- locale/ja.po | 2 +- locale/pt_BR.po | 2 +- locale/ru.po | 2 +- locale/uk.po | 2 +- locale/zh_CN.po | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/locale/ast.po b/locale/ast.po index 310f299b..6e224f23 100644 --- a/locale/ast.po +++ b/locale/ast.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" +"X-Launchpad-Export-Date: 2011-02-05 05:36+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 diff --git a/locale/da.po b/locale/da.po index ac1b593b..f845f11b 100644 --- a/locale/da.po +++ b/locale/da.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" +"X-Launchpad-Export-Date: 2011-02-05 05:36+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 diff --git a/locale/es.po b/locale/es.po index 28f10c48..8d4f90b2 100644 --- a/locale/es.po +++ b/locale/es.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" +"X-Launchpad-Export-Date: 2011-02-05 05:36+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 diff --git a/locale/it.po b/locale/it.po index f08497ba..3f439f9d 100644 --- a/locale/it.po +++ b/locale/it.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" +"X-Launchpad-Export-Date: 2011-02-05 05:36+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 diff --git a/locale/ja.po b/locale/ja.po index b11bb67b..2cea2464 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" +"X-Launchpad-Export-Date: 2011-02-05 05:36+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 diff --git a/locale/pt_BR.po b/locale/pt_BR.po index c778bb63..e57f7304 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" +"X-Launchpad-Export-Date: 2011-02-05 05:36+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 diff --git a/locale/ru.po b/locale/ru.po index fc97d560..5d031ac0 100644 --- a/locale/ru.po +++ b/locale/ru.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" +"X-Launchpad-Export-Date: 2011-02-05 05:36+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 diff --git a/locale/uk.po b/locale/uk.po index be2371db..f3e21769 100644 --- a/locale/uk.po +++ b/locale/uk.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" +"X-Launchpad-Export-Date: 2011-02-05 05:36+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 diff --git a/locale/zh_CN.po b/locale/zh_CN.po index feee54cf..6bc231e5 100644 --- a/locale/zh_CN.po +++ b/locale/zh_CN.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-04 05:31+0000\n" +"X-Launchpad-Export-Date: 2011-02-05 05:36+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/twistd.py:268 From fd2aad67217b010bb5c002c7f76bfe484e70792c Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of nova-core <> Date: Mon, 7 Feb 2011 05:52:49 +0000 Subject: [PATCH 009/111] Launchpad automatic translations update. --- locale/cs.po | 2130 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2130 insertions(+) create mode 100644 locale/cs.po diff --git a/locale/cs.po b/locale/cs.po new file mode 100644 index 00000000..b9403687 --- /dev/null +++ b/locale/cs.po @@ -0,0 +1,2130 @@ +# Czech translation for nova +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the nova package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: nova\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"PO-Revision-Date: 2011-02-07 04:36+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-02-07 05:52+0000\n" +"X-Generator: Launchpad (build 12177)\n" + +#: nova/crypto.py:46 +msgid "Filename of root CA" +msgstr "" + +#: nova/crypto.py:49 +msgid "Filename of private key" +msgstr "" + +#: nova/crypto.py:51 +msgid "Filename of root Certificate Revokation List" +msgstr "" + +#: nova/crypto.py:53 +msgid "Where we keep our keys" +msgstr "" + +#: nova/crypto.py:55 +msgid "Where we keep our root CA" +msgstr "" + +#: nova/crypto.py:57 +msgid "Should we use a CA for each project?" +msgstr "" + +#: nova/crypto.py:61 +#, python-format +msgid "Subject for certificate for users, %s for project, user, timestamp" +msgstr "" + +#: nova/crypto.py:66 +#, python-format +msgid "Subject for certificate for projects, %s for project, timestamp" +msgstr "" + +#: nova/crypto.py:71 +#, python-format +msgid "Subject for certificate for vpns, %s for project, timestamp" +msgstr "" + +#: nova/crypto.py:258 +#, python-format +msgid "Flags path: %s" +msgstr "" + +#: nova/exception.py:33 +msgid "Unexpected error while running command." +msgstr "" + +#: nova/exception.py:36 +#, python-format +msgid "" +"%s\n" +"Command: %s\n" +"Exit code: %s\n" +"Stdout: %r\n" +"Stderr: %r" +msgstr "" + +#: nova/exception.py:86 +msgid "Uncaught exception" +msgstr "" + +#: nova/fakerabbit.py:48 +#, python-format +msgid "(%s) publish (key: %s) %s" +msgstr "" + +#: nova/fakerabbit.py:53 +#, python-format +msgid "Publishing to route %s" +msgstr "" + +#: nova/fakerabbit.py:83 +#, python-format +msgid "Declaring queue %s" +msgstr "" + +#: nova/fakerabbit.py:89 +#, python-format +msgid "Declaring exchange %s" +msgstr "" + +#: nova/fakerabbit.py:95 +#, python-format +msgid "Binding %s to %s with key %s" +msgstr "" + +#: nova/fakerabbit.py:120 +#, python-format +msgid "Getting from %s: %s" +msgstr "" + +#: nova/rpc.py:92 +#, python-format +msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgstr "" + +#: nova/rpc.py:99 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "" + +#: nova/rpc.py:118 +msgid "Reconnected to queue" +msgstr "" + +#: nova/rpc.py:125 +msgid "Failed to fetch message from queue" +msgstr "" + +#: nova/rpc.py:155 +#, python-format +msgid "Initing the Adapter Consumer for %s" +msgstr "" + +#: nova/rpc.py:170 +#, python-format +msgid "received %s" +msgstr "" + +#: nova/rpc.py:183 +#, python-format +msgid "no method for message: %s" +msgstr "" + +#: nova/rpc.py:184 +#, python-format +msgid "No method for message: %s" +msgstr "" + +#: nova/rpc.py:245 +#, python-format +msgid "Returning exception %s to caller" +msgstr "" + +#: nova/rpc.py:286 +#, python-format +msgid "unpacked context: %s" +msgstr "" + +#: nova/rpc.py:305 +msgid "Making asynchronous call..." +msgstr "" + +#: nova/rpc.py:308 +#, python-format +msgid "MSG_ID is %s" +msgstr "" + +#: nova/rpc.py:356 +#, python-format +msgid "response %s" +msgstr "" + +#: nova/rpc.py:365 +#, python-format +msgid "topic is %s" +msgstr "" + +#: nova/rpc.py:366 +#, python-format +msgid "message %s" +msgstr "" + +#: nova/service.py:157 +#, python-format +msgid "Starting %s node" +msgstr "" + +#: nova/service.py:169 +msgid "Service killed that has no database entry" +msgstr "" + +#: nova/service.py:190 +msgid "The service database object disappeared, Recreating it." +msgstr "" + +#: nova/service.py:202 +msgid "Recovered model server connection!" +msgstr "" + +#: nova/service.py:208 +msgid "model server went away" +msgstr "" + +#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#, python-format +msgid "Data store %s is unreachable. Trying again in %d seconds." +msgstr "" + +#: nova/service.py:232 nova/twistd.py:232 +#, python-format +msgid "Serving %s" +msgstr "" + +#: nova/service.py:234 nova/twistd.py:264 +msgid "Full set of FLAGS:" +msgstr "" + +#: nova/twistd.py:211 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "" + +#: nova/twistd.py:268 +#, python-format +msgid "Starting %s" +msgstr "" + +#: nova/utils.py:53 +#, python-format +msgid "Inner Exception: %s" +msgstr "" + +#: nova/utils.py:54 +#, python-format +msgid "Class %s cannot be found" +msgstr "" + +#: nova/utils.py:113 +#, python-format +msgid "Fetching %s" +msgstr "" + +#: nova/utils.py:125 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "" + +#: nova/utils.py:138 +#, python-format +msgid "Result was %s" +msgstr "" + +#: nova/utils.py:171 +#, python-format +msgid "debug in callback: %s" +msgstr "" + +#: nova/utils.py:176 +#, python-format +msgid "Running %s" +msgstr "" + +#: nova/utils.py:207 +#, python-format +msgid "Couldn't get IP, using 127.0.0.1 %s" +msgstr "" + +#: nova/utils.py:289 +#, python-format +msgid "Invalid backend: %s" +msgstr "" + +#: nova/utils.py:300 +#, python-format +msgid "backend %s" +msgstr "" + +#: nova/api/ec2/__init__.py:133 +msgid "Too many failed authentications." +msgstr "" + +#: nova/api/ec2/__init__.py:142 +#, python-format +msgid "" +"Access key %s has had %d failed authentications and will be locked out for " +"%d minutes." +msgstr "" + +#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#, python-format +msgid "Authentication Failure: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:190 +#, python-format +msgid "Authenticated Request For %s:%s)" +msgstr "" + +#: nova/api/ec2/__init__.py:227 +#, python-format +msgid "action: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:229 +#, python-format +msgid "arg: %s\t\tval: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:301 +#, python-format +msgid "Unauthorized request for controller=%s and action=%s" +msgstr "" + +#: nova/api/ec2/__init__.py:339 +#, python-format +msgid "NotFound raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:342 +#, python-format +msgid "ApiError raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:349 +#, python-format +msgid "Unexpected error raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:354 +msgid "An unknown error has occurred. Please try your request again." +msgstr "" + +#: nova/api/ec2/admin.py:84 +#, python-format +msgid "Creating new user: %s" +msgstr "" + +#: nova/api/ec2/admin.py:92 +#, python-format +msgid "Deleting user: %s" +msgstr "" + +#: nova/api/ec2/admin.py:114 +#, python-format +msgid "Adding role %s to user %s for project %s" +msgstr "" + +#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#, python-format +msgid "Adding sitewide role %s to user %s" +msgstr "" + +#: nova/api/ec2/admin.py:122 +#, python-format +msgid "Removing role %s from user %s for project %s" +msgstr "" + +#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#, python-format +msgid "Removing sitewide role %s from user %s" +msgstr "" + +#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 +msgid "operation must be add or remove" +msgstr "" + +#: nova/api/ec2/admin.py:142 +#, python-format +msgid "Getting x509 for user: %s on project: %s" +msgstr "" + +#: nova/api/ec2/admin.py:159 +#, python-format +msgid "Create project %s managed by %s" +msgstr "" + +#: nova/api/ec2/admin.py:170 +#, python-format +msgid "Delete project: %s" +msgstr "" + +#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#, python-format +msgid "Adding user %s to project %s" +msgstr "" + +#: nova/api/ec2/admin.py:188 +#, python-format +msgid "Removing user %s from project %s" +msgstr "" + +#: nova/api/ec2/apirequest.py:95 +#, python-format +msgid "Unsupported API request: controller = %s,action = %s" +msgstr "" + +#: nova/api/ec2/cloud.py:117 +#, python-format +msgid "Generating root CA: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:277 +#, python-format +msgid "Create key pair %s" +msgstr "" + +#: nova/api/ec2/cloud.py:285 +#, python-format +msgid "Delete key pair %s" +msgstr "" + +#: nova/api/ec2/cloud.py:357 +#, python-format +msgid "%s is not a valid ipProtocol" +msgstr "" + +#: nova/api/ec2/cloud.py:361 +msgid "Invalid port range" +msgstr "" + +#: nova/api/ec2/cloud.py:392 +#, python-format +msgid "Revoke security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 +msgid "No rule for the specified parameters." +msgstr "" + +#: nova/api/ec2/cloud.py:421 +#, python-format +msgid "Authorize security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:432 +#, python-format +msgid "This rule already exists in group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:460 +#, python-format +msgid "Create Security Group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:463 +#, python-format +msgid "group %s already exists" +msgstr "" + +#: nova/api/ec2/cloud.py:475 +#, python-format +msgid "Delete security group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:543 +#, python-format +msgid "Create volume of %s GB" +msgstr "" + +#: nova/api/ec2/cloud.py:567 +#, python-format +msgid "Attach volume %s to instacne %s at %s" +msgstr "" + +#: nova/api/ec2/cloud.py:579 +#, python-format +msgid "Detach volume %s" +msgstr "" + +#: nova/api/ec2/cloud.py:686 +msgid "Allocate address" +msgstr "" + +#: nova/api/ec2/cloud.py:691 +#, python-format +msgid "Release address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:696 +#, python-format +msgid "Associate address %s to instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:703 +#, python-format +msgid "Disassociate address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:730 +msgid "Going to start terminating instances" +msgstr "" + +#: nova/api/ec2/cloud.py:738 +#, python-format +msgid "Reboot instance %r" +msgstr "" + +#: nova/api/ec2/cloud.py:775 +#, python-format +msgid "De-registering image %s" +msgstr "" + +#: nova/api/ec2/cloud.py:783 +#, python-format +msgid "Registered image %s with id %s" +msgstr "" + +#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#, python-format +msgid "attribute not supported: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:794 +#, python-format +msgid "invalid id: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:807 +msgid "user or group not specified" +msgstr "" + +#: nova/api/ec2/cloud.py:809 +msgid "only group \"all\" is supported" +msgstr "" + +#: nova/api/ec2/cloud.py:811 +msgid "operation_type must be add or remove" +msgstr "" + +#: nova/api/ec2/cloud.py:812 +#, python-format +msgid "Updating image %s publicity" +msgstr "" + +#: nova/api/ec2/metadatarequesthandler.py:75 +#, python-format +msgid "Failed to get metadata for ip: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:70 +#, python-format +msgid "Caught error: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:86 +msgid "Including admin operations in API." +msgstr "" + +#: nova/api/openstack/servers.py:184 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:199 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: nova/api/openstack/servers.py:213 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:224 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: nova/api/openstack/servers.py:235 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: nova/api/openstack/servers.py:246 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: nova/api/openstack/servers.py:257 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: nova/auth/dbdriver.py:84 +#, python-format +msgid "User %s already exists" +msgstr "" + +#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#, python-format +msgid "Project can't be created because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#, python-format +msgid "Project can't be created because project %s already exists" +msgstr "" + +#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#, python-format +msgid "Project can't be modified because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:245 +#, python-format +msgid "User \"%s\" not found" +msgstr "" + +#: nova/auth/dbdriver.py:248 +#, python-format +msgid "Project \"%s\" not found" +msgstr "" + +#: nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "" + +#: nova/auth/ldapdriver.py:181 +#, python-format +msgid "LDAP object for %s doesn't exist" +msgstr "" + +#: nova/auth/ldapdriver.py:218 +#, python-format +msgid "Project can't be created because user %s doesn't exist" +msgstr "" + +#: nova/auth/ldapdriver.py:478 +#, python-format +msgid "User %s is already a member of the group %s" +msgstr "" + +#: nova/auth/ldapdriver.py:507 +#, python-format +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." +msgstr "" + +#: nova/auth/ldapdriver.py:528 +#, python-format +msgid "Group at dn %s doesn't exist" +msgstr "" + +#: nova/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "" + +#: nova/auth/manager.py:263 +#, python-format +msgid "Failed authorization for access key %s" +msgstr "" + +#: nova/auth/manager.py:264 +#, python-format +msgid "No user found for access key %s" +msgstr "" + +#: nova/auth/manager.py:270 +#, python-format +msgid "Using project name = user name (%s)" +msgstr "" + +#: nova/auth/manager.py:275 +#, python-format +msgid "failed authorization: no project named %s (user=%s)" +msgstr "" + +#: nova/auth/manager.py:277 +#, python-format +msgid "No project called %s could be found" +msgstr "" + +#: nova/auth/manager.py:281 +#, python-format +msgid "Failed authorization: user %s not admin and not member of project %s" +msgstr "" + +#: nova/auth/manager.py:283 +#, python-format +msgid "User %s is not a member of project %s" +msgstr "" + +#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#, python-format +msgid "Invalid signature for user %s" +msgstr "" + +#: nova/auth/manager.py:293 nova/auth/manager.py:304 +msgid "Signature does not match" +msgstr "" + +#: nova/auth/manager.py:374 +msgid "Must specify project" +msgstr "" + +#: nova/auth/manager.py:408 +#, python-format +msgid "The %s role can not be found" +msgstr "" + +#: nova/auth/manager.py:410 +#, python-format +msgid "The %s role is global only" +msgstr "" + +#: nova/auth/manager.py:412 +#, python-format +msgid "Adding role %s to user %s in project %s" +msgstr "" + +#: nova/auth/manager.py:438 +#, python-format +msgid "Removing role %s from user %s on project %s" +msgstr "" + +#: nova/auth/manager.py:505 +#, python-format +msgid "Created project %s with manager %s" +msgstr "" + +#: nova/auth/manager.py:523 +#, python-format +msgid "modifying project %s" +msgstr "" + +#: nova/auth/manager.py:553 +#, python-format +msgid "Remove user %s from project %s" +msgstr "" + +#: nova/auth/manager.py:581 +#, python-format +msgid "Deleting project %s" +msgstr "" + +#: nova/auth/manager.py:637 +#, python-format +msgid "Created user %s (admin: %r)" +msgstr "" + +#: nova/auth/manager.py:645 +#, python-format +msgid "Deleting user %s" +msgstr "" + +#: nova/auth/manager.py:655 +#, python-format +msgid "Access Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:657 +#, python-format +msgid "Secret Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:659 +#, python-format +msgid "Admin status set to %r for user %s" +msgstr "" + +#: nova/auth/manager.py:708 +#, python-format +msgid "No vpn data for project %s" +msgstr "" + +#: nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" +msgstr "" + +#: nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:97 +#, python-format +msgid "Launching VPN for %s" +msgstr "" + +#: nova/compute/api.py:67 +#, python-format +msgid "Instance %d was not found in get_network_topic" +msgstr "" + +#: nova/compute/api.py:73 +#, python-format +msgid "Instance %d has no host" +msgstr "" + +#: nova/compute/api.py:92 +#, python-format +msgid "Quota exceeeded for %s, tried to run %s instances" +msgstr "" + +#: nova/compute/api.py:94 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." +msgstr "" + +#: nova/compute/api.py:109 +msgid "Creating a raw instance" +msgstr "" + +#: nova/compute/api.py:156 +#, python-format +msgid "Going to run %s instances..." +msgstr "" + +#: nova/compute/api.py:180 +#, python-format +msgid "Casting to scheduler for %s/%s's instance %s" +msgstr "" + +#: nova/compute/api.py:279 +#, python-format +msgid "Going to try and terminate %s" +msgstr "" + +#: nova/compute/api.py:283 +#, python-format +msgid "Instance %d was not found during terminate" +msgstr "" + +#: nova/compute/api.py:288 +#, python-format +msgid "Instance %d is already being terminated" +msgstr "" + +#: nova/compute/api.py:450 +#, python-format +msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgstr "" + +#: nova/compute/api.py:465 +msgid "Volume isn't attached to anything!" +msgstr "" + +#: nova/compute/disk.py:71 +#, python-format +msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:75 +#, python-format +msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:128 +#, python-format +msgid "Could not attach image to loopback: %s" +msgstr "" + +#: nova/compute/disk.py:136 +#, python-format +msgid "Failed to load partition: %s" +msgstr "" + +#: nova/compute/disk.py:158 +#, python-format +msgid "Failed to mount filesystem: %s" +msgstr "" + +#: nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "" + +#: nova/compute/manager.py:69 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: nova/compute/manager.py:71 +#, python-format +msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgstr "" + +#: nova/compute/manager.py:75 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: nova/compute/manager.py:77 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: nova/compute/manager.py:82 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: nova/compute/manager.py:157 +msgid "Instance has already been created" +msgstr "" + +#: nova/compute/manager.py:158 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#: nova/compute/manager.py:197 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: nova/compute/manager.py:217 +#, python-format +msgid "Disassociating address %s" +msgstr "" + +#: nova/compute/manager.py:230 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: nova/compute/manager.py:243 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: nova/compute/manager.py:257 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: nova/compute/manager.py:260 +#, python-format +msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:286 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: nova/compute/manager.py:289 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:301 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: nova/compute/manager.py:316 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: nova/compute/manager.py:335 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: nova/compute/manager.py:352 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: nova/compute/manager.py:369 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: nova/compute/manager.py:382 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: nova/compute/manager.py:401 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: nova/compute/manager.py:420 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: nova/compute/manager.py:432 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: nova/compute/manager.py:442 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: nova/compute/manager.py:462 +#, python-format +msgid "instance %s: attaching volume %s to %s" +msgstr "" + +#: nova/compute/manager.py:478 +#, python-format +msgid "instance %s: attach failed %s, removing" +msgstr "" + +#: nova/compute/manager.py:493 +#, python-format +msgid "Detach volume %s from mountpoint %s on instance %s" +msgstr "" + +#: nova/compute/manager.py:497 +#, python-format +msgid "Detaching volume from unknown instance %s" +msgstr "" + +#: nova/compute/monitor.py:259 +#, python-format +msgid "updating %s..." +msgstr "" + +#: nova/compute/monitor.py:289 +msgid "unexpected error during update" +msgstr "" + +#: nova/compute/monitor.py:355 +#, python-format +msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:377 +#, python-format +msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:412 +msgid "unexpected exception getting connection" +msgstr "" + +#: nova/compute/monitor.py:427 +#, python-format +msgid "Found instance: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:43 +msgid "Use of empty request context is deprecated" +msgstr "" + +#: nova/db/sqlalchemy/api.py:132 +#, python-format +msgid "No service for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:229 +#, python-format +msgid "No service for %s, %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:574 +#, python-format +msgid "No floating ip for address %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:668 +#, python-format +msgid "No instance for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:758 nova/virt/libvirt_conn.py:598 +#: nova/virt/xenapi/volumeops.py:48 nova/virt/xenapi/volumeops.py:103 +#, python-format +msgid "Instance %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:891 +#, python-format +msgid "no keypair for user %s, name %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#, python-format +msgid "No network for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1036 +#, python-format +msgid "No network for bridge %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1050 +#, python-format +msgid "No network for instance %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1180 +#, python-format +msgid "Token %s does not exist" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1205 +#, python-format +msgid "No quota for project_id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1356 +#, python-format +msgid "No volume for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1401 +#, python-format +msgid "Volume %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1413 +#, python-format +msgid "No export device found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1426 +#, python-format +msgid "No target id found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1471 +#, python-format +msgid "No security group with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1488 +#, python-format +msgid "No security group named %s for project: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1576 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1650 +#, python-format +msgid "No user for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1666 +#, python-format +msgid "No user for access key %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1728 +#, python-format +msgid "No project with id %s" +msgstr "" + +#: nova/image/glance.py:78 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images" +msgstr "" + +#: nova/image/glance.py:97 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images/detail" +msgstr "" + +#: nova/image/s3.py:82 +#, python-format +msgid "Image %s could not be found" +msgstr "" + +#: nova/network/api.py:39 +#, python-format +msgid "Quota exceeeded for %s, tried to allocate address" +msgstr "" + +#: nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" +msgstr "" + +#: nova/network/linux_net.py:176 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: nova/network/linux_net.py:186 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#: nova/network/linux_net.py:254 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: nova/network/linux_net.py:256 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#: nova/network/linux_net.py:334 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: nova/network/manager.py:135 +msgid "setting network host" +msgstr "" + +#: nova/network/manager.py:190 +#, python-format +msgid "Leasing IP %s" +msgstr "" + +#: nova/network/manager.py:194 +#, python-format +msgid "IP %s leased that isn't associated" +msgstr "" + +#: nova/network/manager.py:197 +#, python-format +msgid "IP %s leased to bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:205 +#, python-format +msgid "IP %s leased that was already deallocated" +msgstr "" + +#: nova/network/manager.py:214 +#, python-format +msgid "IP %s released that isn't associated" +msgstr "" + +#: nova/network/manager.py:217 +#, python-format +msgid "IP %s released from bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:220 +#, python-format +msgid "IP %s released that was not leased" +msgstr "" + +#: nova/network/manager.py:442 +#, python-format +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "" + +#: nova/objectstore/handler.py:106 +#, python-format +msgid "Unknown S3 value type %r" +msgstr "" + +#: nova/objectstore/handler.py:137 +msgid "Authenticated request" +msgstr "" + +#: nova/objectstore/handler.py:182 +msgid "List of buckets requested" +msgstr "" + +#: nova/objectstore/handler.py:209 +#, python-format +msgid "List keys for bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:217 +#, python-format +msgid "Unauthorized attempt to access bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:235 +#, python-format +msgid "Creating bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:245 +#, python-format +msgid "Deleting bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:249 +#, python-format +msgid "Unauthorized attempt to delete bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:271 +#, python-format +msgid "Getting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:274 +#, python-format +msgid "Unauthorized attempt to get object %s from bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:292 +#, python-format +msgid "Putting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:295 +#, python-format +msgid "Unauthorized attempt to upload object %s to bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:314 +#, python-format +msgid "Deleting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:393 +#, python-format +msgid "Not authorized to upload image: invalid directory %s" +msgstr "" + +#: nova/objectstore/handler.py:401 +#, python-format +msgid "Not authorized to upload image: unauthorized bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:406 +#, python-format +msgid "Starting image upload: %s" +msgstr "" + +#: nova/objectstore/handler.py:420 +#, python-format +msgid "Not authorized to update attributes of image %s" +msgstr "" + +#: nova/objectstore/handler.py:428 +#, python-format +msgid "Toggling publicity flag of image %s %r" +msgstr "" + +#: nova/objectstore/handler.py:433 +#, python-format +msgid "Updating user fields on image %s" +msgstr "" + +#: nova/objectstore/handler.py:447 +#, python-format +msgid "Unauthorized attempt to delete image %s" +msgstr "" + +#: nova/objectstore/handler.py:452 +#, python-format +msgid "Deleted image: %s" +msgstr "" + +#: nova/scheduler/chance.py:37 nova/scheduler/simple.py:73 +#: nova/scheduler/simple.py:106 nova/scheduler/simple.py:118 +msgid "No hosts found" +msgstr "" + +#: nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "" + +#: nova/scheduler/manager.py:69 +#, python-format +msgid "Casting to %s %s for %s" +msgstr "" + +#: nova/scheduler/simple.py:63 +msgid "All hosts have too many cores" +msgstr "" + +#: nova/scheduler/simple.py:95 +msgid "All hosts have too many gigabytes" +msgstr "" + +#: nova/scheduler/simple.py:115 +msgid "All hosts have too many networks" +msgstr "" + +#: nova/tests/test_cloud.py:198 +msgid "Can't test instances without a real virtual env." +msgstr "" + +#: nova/tests/test_cloud.py:210 +#, python-format +msgid "Need to watch instance %s until it's running..." +msgstr "" + +#: nova/tests/test_compute.py:104 +#, python-format +msgid "Running instances: %s" +msgstr "" + +#: nova/tests/test_compute.py:110 +#, python-format +msgid "After terminating instances: %s" +msgstr "" + +#: nova/tests/test_rpc.py:89 +#, python-format +msgid "Nested received %s, %s" +msgstr "" + +#: nova/tests/test_rpc.py:94 +#, python-format +msgid "Nested return %s" +msgstr "" + +#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#, python-format +msgid "Received %s" +msgstr "" + +#: nova/tests/test_volume.py:162 +#, python-format +msgid "Target %s allocated" +msgstr "" + +#: nova/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "" + +#: nova/virt/fake.py:210 +#, python-format +msgid "Instance %s Not Found" +msgstr "" + +#: nova/virt/hyperv.py:118 +msgid "In init host" +msgstr "" + +#: nova/virt/hyperv.py:131 +#, python-format +msgid "Attempt to create duplicate vm %s" +msgstr "" + +#: nova/virt/hyperv.py:148 +#, python-format +msgid "Starting VM %s " +msgstr "" + +#: nova/virt/hyperv.py:150 +#, python-format +msgid "Started VM %s " +msgstr "" + +#: nova/virt/hyperv.py:152 +#, python-format +msgid "spawn vm failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:169 +#, python-format +msgid "Failed to create VM %s" +msgstr "" + +#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#, python-format +msgid "Created VM %s..." +msgstr "" + +#: nova/virt/hyperv.py:188 +#, python-format +msgid "Set memory for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:198 +#, python-format +msgid "Set vcpus for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:202 +#, python-format +msgid "Creating disk for %s by attaching disk file %s" +msgstr "" + +#: nova/virt/hyperv.py:227 +#, python-format +msgid "Failed to add diskdrive to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:230 +#, python-format +msgid "New disk drive path is %s" +msgstr "" + +#: nova/virt/hyperv.py:247 +#, python-format +msgid "Failed to add vhd file to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:249 +#, python-format +msgid "Created disk for %s" +msgstr "" + +#: nova/virt/hyperv.py:253 +#, python-format +msgid "Creating nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" +msgstr "" + +#: nova/virt/hyperv.py:273 +#, python-format +msgid "Failed creating port for %s" +msgstr "" + +#: nova/virt/hyperv.py:275 +#, python-format +msgid "Created switch port %s on switch %s" +msgstr "" + +#: nova/virt/hyperv.py:285 +#, python-format +msgid "Failed to add nic to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:287 +#, python-format +msgid "Created nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:320 +#, python-format +msgid "WMI job failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:322 +#, python-format +msgid "WMI job succeeded: %s, Elapsed=%s " +msgstr "" + +#: nova/virt/hyperv.py:358 +#, python-format +msgid "Got request to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:383 +#, python-format +msgid "Failed to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:389 +#, python-format +msgid "Del: disk %s vm %s" +msgstr "" + +#: nova/virt/hyperv.py:405 +#, python-format +msgid "" +"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " +"cpu_time=%s" +msgstr "" + +#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#, python-format +msgid "duplicate name found: %s" +msgstr "" + +#: nova/virt/hyperv.py:444 +#, python-format +msgid "Successfully changed vm state of %s to %s" +msgstr "" + +#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#, python-format +msgid "Failed to change vm state of %s to %s" +msgstr "" + +#: nova/virt/images.py:70 +#, python-format +msgid "Finished retreving %s -- placed in %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:144 +#, python-format +msgid "Connecting to libvirt: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:157 +msgid "Connection to libvirt broke" +msgstr "" + +#: nova/virt/libvirt_conn.py:229 +#, python-format +msgid "instance %s: deleting instance files %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:271 +#, python-format +msgid "No disk at %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:278 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "" + +#: nova/virt/libvirt_conn.py:294 +#, python-format +msgid "instance %s: rebooted" +msgstr "" + +#: nova/virt/libvirt_conn.py:297 +#, python-format +msgid "_wait_for_reboot failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:340 +#, python-format +msgid "instance %s: rescued" +msgstr "" + +#: nova/virt/libvirt_conn.py:343 +#, python-format +msgid "_wait_for_rescue failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:370 +#, python-format +msgid "instance %s: is running" +msgstr "" + +#: nova/virt/libvirt_conn.py:381 +#, python-format +msgid "instance %s: booted" +msgstr "" + +#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#, python-format +msgid "instance %s: failed to boot" +msgstr "" + +#: nova/virt/libvirt_conn.py:395 +#, python-format +msgid "virsh said: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:399 +msgid "cool, it's a device" +msgstr "" + +#: nova/virt/libvirt_conn.py:407 +#, python-format +msgid "data: %r, fpath: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:415 +#, python-format +msgid "Contents of file %s: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:449 +#, python-format +msgid "instance %s: Creating image" +msgstr "" + +#: nova/virt/libvirt_conn.py:505 +#, python-format +msgid "instance %s: injecting key into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:508 +#, python-format +msgid "instance %s: injecting net into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:516 +#, python-format +msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgstr "" + +#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#, python-format +msgid "instance %s: starting toXML method" +msgstr "" + +#: nova/virt/libvirt_conn.py:589 +#, python-format +msgid "instance %s: finished toXML method" +msgstr "" + +#: nova/virt/xenapi_conn.py:113 +msgid "" +"Must specify xenapi_connection_url, xenapi_connection_username (optionally), " +"and xenapi_connection_password to use connection_type=xenapi" +msgstr "" + +#: nova/virt/xenapi_conn.py:263 +#, python-format +msgid "Task [%s] %s status: success %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:271 +#, python-format +msgid "Task [%s] %s status: %s %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#, python-format +msgid "Got exception: %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:72 +#, python-format +msgid "%s: _db_content => %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:247 nova/virt/xenapi/fake.py:338 +#: nova/virt/xenapi/fake.py:356 nova/virt/xenapi/fake.py:404 +msgid "Raising NotImplemented" +msgstr "" + +#: nova/virt/xenapi/fake.py:249 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:283 +#, python-format +msgid "Calling %s %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:288 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:340 +#, python-format +msgid "" +"xenapi.fake does not have an implementation for %s or it has been called " +"with the wrong number of arguments" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:40 +#, python-format +msgid "Found non-unique network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:43 +#, python-format +msgid "Found no network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:127 +#, python-format +msgid "Created VM %s as %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:147 +#, python-format +msgid "Creating VBD for VM %s, VDI %s ... " +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:149 +#, python-format +msgid "Created VBD %s for VM %s, VDI %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:165 +#, python-format +msgid "VBD not found in instance %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:175 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:202 +#, python-format +msgid "Creating VIF for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:205 +#, python-format +msgid "Created VIF %s for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:216 +#, python-format +msgid "Snapshotting VM %s with label '%s'..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:229 +#, python-format +msgid "Created snapshot %s from VM %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:243 +#, python-format +msgid "Asking xapi to upload %s as '%s'" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:261 +#, python-format +msgid "Asking xapi to fetch %s as %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:279 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:290 +#, python-format +msgid "PV Kernel in VDI:%d" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:318 +#, python-format +msgid "VDI %s is still available" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:331 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:333 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:390 +#, python-format +msgid "VHD %s has parent %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:407 +#, python-format +msgid "Re-scanning SR %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:431 +#, python-format +msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:448 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:452 +#, python-format +msgid "Unexpected number of VDIs (%s) found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:62 +#, python-format +msgid "Attempted to create non-unique name %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:99 +#, python-format +msgid "Starting VM %s..." +msgstr "" + +#: nova/virt/xenapi/vmops.py:101 +#, python-format +msgid "Spawning VM %s created %s." +msgstr "" + +#: nova/virt/xenapi/vmops.py:112 +#, python-format +msgid "Instance %s: booted" +msgstr "" + +#: nova/virt/xenapi/vmops.py:137 +#, python-format +msgid "Instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:166 +#, python-format +msgid "Starting snapshot for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:174 +#, python-format +msgid "Unable to Snapshot %s: %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:184 +#, python-format +msgid "Finished snapshot and upload for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:252 +#, python-format +msgid "suspend: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:262 +#, python-format +msgid "resume: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:271 +#, python-format +msgid "Instance not found %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:57 +#, python-format +msgid "Introducing %s..." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:74 +#, python-format +msgid "Introduced %s as %s." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:90 +#, python-format +msgid "Unable to find SR from VBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:96 +#, python-format +msgid "Forgetting SR %s ... " +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:101 +#, python-format +msgid "Ignoring exception %s when getting PBDs for %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:107 +#, python-format +msgid "Ignoring exception %s when unplugging PBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:111 +#, python-format +msgid "Forgetting SR %s done." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:113 +#, python-format +msgid "Ignoring exception %s when forgetting SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:123 +#, python-format +msgid "Unable to introduce VDI on SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:128 +#, python-format +msgid "Unable to get record of VDI %s on" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:146 +#, python-format +msgid "Unable to introduce VDI for SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:175 +#, python-format +msgid "Unable to obtain target information %s, %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:197 +#, python-format +msgid "Mountpoint cannot be translated: %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:51 +#, python-format +msgid "Attach_volume: %s, %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:69 +#, python-format +msgid "Unable to create VDI on SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:81 +#, python-format +msgid "Unable to use SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Unable to attach volume to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:95 +#, python-format +msgid "Mountpoint %s attached to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:106 +#, python-format +msgid "Detach_volume: %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:113 +#, python-format +msgid "Unable to locate volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:121 +#, python-format +msgid "Unable to detach volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:128 +#, python-format +msgid "Mountpoint %s detached from instance %s" +msgstr "" + +#: nova/volume/api.py:44 +#, python-format +msgid "Quota exceeeded for %s, tried to create %sG volume" +msgstr "" + +#: nova/volume/api.py:46 +#, python-format +msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgstr "" + +#: nova/volume/api.py:70 nova/volume/api.py:95 +msgid "Volume status must be available" +msgstr "" + +#: nova/volume/api.py:97 +msgid "Volume is already attached" +msgstr "" + +#: nova/volume/api.py:103 +msgid "Volume is already detached" +msgstr "" + +#: nova/volume/driver.py:76 +#, python-format +msgid "Recovering from a failed execute. Try number %s" +msgstr "" + +#: nova/volume/driver.py:85 +#, python-format +msgid "volume group %s doesn't exist" +msgstr "" + +#: nova/volume/driver.py:210 +#, python-format +msgid "FAKE AOE: %s" +msgstr "" + +#: nova/volume/driver.py:315 +#, python-format +msgid "FAKE ISCSI: %s" +msgstr "" + +#: nova/volume/manager.py:85 +#, python-format +msgid "Re-exporting %s volumes" +msgstr "" + +#: nova/volume/manager.py:93 +#, python-format +msgid "volume %s: creating" +msgstr "" + +#: nova/volume/manager.py:102 +#, python-format +msgid "volume %s: creating lv of size %sG" +msgstr "" + +#: nova/volume/manager.py:106 +#, python-format +msgid "volume %s: creating export" +msgstr "" + +#: nova/volume/manager.py:113 +#, python-format +msgid "volume %s: created successfully" +msgstr "" + +#: nova/volume/manager.py:121 +msgid "Volume is still attached" +msgstr "" + +#: nova/volume/manager.py:123 +msgid "Volume is not local to this node" +msgstr "" + +#: nova/volume/manager.py:124 +#, python-format +msgid "volume %s: removing export" +msgstr "" + +#: nova/volume/manager.py:126 +#, python-format +msgid "volume %s: deleting" +msgstr "" + +#: nova/volume/manager.py:129 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "" From fb2911067225f9dce686374ab84a47e199a7354c Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of nova-core <> Date: Tue, 8 Feb 2011 05:28:14 +0000 Subject: [PATCH 010/111] Launchpad automatic translations update. --- locale/cs.po | 51 +++++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/locale/cs.po b/locale/cs.po index b9403687..861efa37 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -8,22 +8,22 @@ msgstr "" "Project-Id-Version: nova\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-10 11:25-0800\n" -"PO-Revision-Date: 2011-02-07 04:36+0000\n" -"Last-Translator: FULL NAME \n" +"PO-Revision-Date: 2011-02-07 12:45+0000\n" +"Last-Translator: David Pravec \n" "Language-Team: Czech \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-07 05:52+0000\n" +"X-Launchpad-Export-Date: 2011-02-08 05:28+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 msgid "Filename of root CA" -msgstr "" +msgstr "Jméno souboru kořenové CA" #: nova/crypto.py:49 msgid "Filename of private key" -msgstr "" +msgstr "Jméno souboru s privátním klíčem" #: nova/crypto.py:51 msgid "Filename of root Certificate Revokation List" @@ -31,15 +31,15 @@ msgstr "" #: nova/crypto.py:53 msgid "Where we keep our keys" -msgstr "" +msgstr "Adresář, do kterého ukládáme naše klíče" #: nova/crypto.py:55 msgid "Where we keep our root CA" -msgstr "" +msgstr "Adresář, do kterého ukládáme naši kořenovou CA" #: nova/crypto.py:57 msgid "Should we use a CA for each project?" -msgstr "" +msgstr "Použijeme CA pro každý projekt?" #: nova/crypto.py:61 #, python-format @@ -63,7 +63,7 @@ msgstr "" #: nova/exception.py:33 msgid "Unexpected error while running command." -msgstr "" +msgstr "Při spouštění příkazu došlo k nečekané chybě" #: nova/exception.py:36 #, python-format @@ -74,10 +74,15 @@ msgid "" "Stdout: %r\n" "Stderr: %r" msgstr "" +"%s\n" +"Příkaz: %s\n" +"Vrácená hodnota: %s\n" +"Stdout: %r\n" +"Stderr: %r" #: nova/exception.py:86 msgid "Uncaught exception" -msgstr "" +msgstr "Neošetřená výjimka" #: nova/fakerabbit.py:48 #, python-format @@ -112,20 +117,22 @@ msgstr "" #: nova/rpc.py:92 #, python-format msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." -msgstr "" +msgstr "AMQP server na %s:%d není dosažitelný. Zkusím znovu za %d sekund." #: nova/rpc.py:99 #, python-format msgid "Unable to connect to AMQP server after %d tries. Shutting down." msgstr "" +"Nepodařilo se připojit k AMQP serveru ani po %d pokusech. Tento proces bude " +"ukončen." #: nova/rpc.py:118 msgid "Reconnected to queue" -msgstr "" +msgstr "Znovu připojeno k AMQP frontě" #: nova/rpc.py:125 msgid "Failed to fetch message from queue" -msgstr "" +msgstr "Selhalo získání zprávy z AMQP fronty" #: nova/rpc.py:155 #, python-format @@ -135,41 +142,41 @@ msgstr "" #: nova/rpc.py:170 #, python-format msgid "received %s" -msgstr "" +msgstr "získáno: %s" #: nova/rpc.py:183 #, python-format msgid "no method for message: %s" -msgstr "" +msgstr "Není metoda pro zpracování zprávy: %s" #: nova/rpc.py:184 #, python-format msgid "No method for message: %s" -msgstr "" +msgstr "Není metoda pro zpracování zprávy: %s" #: nova/rpc.py:245 #, python-format msgid "Returning exception %s to caller" -msgstr "" +msgstr "Volajícímu je vrácena výjimka: %s" #: nova/rpc.py:286 #, python-format msgid "unpacked context: %s" -msgstr "" +msgstr "rozbalený obsah: %s" #: nova/rpc.py:305 msgid "Making asynchronous call..." -msgstr "" +msgstr "Volání asynchronní funkce..." #: nova/rpc.py:308 #, python-format msgid "MSG_ID is %s" -msgstr "" +msgstr "MSG_ID je %s" #: nova/rpc.py:356 #, python-format msgid "response %s" -msgstr "" +msgstr "odpověď %s" #: nova/rpc.py:365 #, python-format @@ -179,7 +186,7 @@ msgstr "" #: nova/rpc.py:366 #, python-format msgid "message %s" -msgstr "" +msgstr "zpráva %s" #: nova/service.py:157 #, python-format From d0bd88de00facd9e87f58b1680f198eee919b88c Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of nova-core <> Date: Wed, 9 Feb 2011 05:41:14 +0000 Subject: [PATCH 011/111] Launchpad automatic translations update. --- locale/de.po | 2136 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2136 insertions(+) create mode 100644 locale/de.po diff --git a/locale/de.po b/locale/de.po new file mode 100644 index 00000000..e9629259 --- /dev/null +++ b/locale/de.po @@ -0,0 +1,2136 @@ +# German translation for nova +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the nova package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: nova\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"PO-Revision-Date: 2011-02-08 13:06+0000\n" +"Last-Translator: Christian Berendt \n" +"Language-Team: German \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-02-09 05:41+0000\n" +"X-Generator: Launchpad (build 12177)\n" + +#: nova/crypto.py:46 +msgid "Filename of root CA" +msgstr "Dateiname der Root CA" + +#: nova/crypto.py:49 +msgid "Filename of private key" +msgstr "Dateiname des Private Key" + +#: nova/crypto.py:51 +msgid "Filename of root Certificate Revokation List" +msgstr "Dateiname der Certificate Revocation List" + +#: nova/crypto.py:53 +msgid "Where we keep our keys" +msgstr "" + +#: nova/crypto.py:55 +msgid "Where we keep our root CA" +msgstr "" + +#: nova/crypto.py:57 +msgid "Should we use a CA for each project?" +msgstr "Soll eine eigenständige CA für jedes Projekt verwendet werden?" + +#: nova/crypto.py:61 +#, python-format +msgid "Subject for certificate for users, %s for project, user, timestamp" +msgstr "" + +#: nova/crypto.py:66 +#, python-format +msgid "Subject for certificate for projects, %s for project, timestamp" +msgstr "" + +#: nova/crypto.py:71 +#, python-format +msgid "Subject for certificate for vpns, %s for project, timestamp" +msgstr "" + +#: nova/crypto.py:258 +#, python-format +msgid "Flags path: %s" +msgstr "" + +#: nova/exception.py:33 +msgid "Unexpected error while running command." +msgstr "Unerwarteter Fehler bei Ausführung des Kommandos." + +#: nova/exception.py:36 +#, python-format +msgid "" +"%s\n" +"Command: %s\n" +"Exit code: %s\n" +"Stdout: %r\n" +"Stderr: %r" +msgstr "" +"%s\n" +"Kommando: %s\n" +"Exit Code: %s\n" +"Stdout: %r\n" +"Stderr: %r" + +#: nova/exception.py:86 +msgid "Uncaught exception" +msgstr "Nicht abgefangene Ausnahme" + +#: nova/fakerabbit.py:48 +#, python-format +msgid "(%s) publish (key: %s) %s" +msgstr "(%s) öffentlich (Schlüssel: %s) %s" + +#: nova/fakerabbit.py:53 +#, python-format +msgid "Publishing to route %s" +msgstr "" + +#: nova/fakerabbit.py:83 +#, python-format +msgid "Declaring queue %s" +msgstr "" + +#: nova/fakerabbit.py:89 +#, python-format +msgid "Declaring exchange %s" +msgstr "" + +#: nova/fakerabbit.py:95 +#, python-format +msgid "Binding %s to %s with key %s" +msgstr "" + +#: nova/fakerabbit.py:120 +#, python-format +msgid "Getting from %s: %s" +msgstr "Beziehe von %s: %s" + +#: nova/rpc.py:92 +#, python-format +msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgstr "" +"Der AMQP server %s:%d ist nicht erreichbar. Erneuter Versuch in %d Sekunden." + +#: nova/rpc.py:99 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "" + +#: nova/rpc.py:118 +msgid "Reconnected to queue" +msgstr "" + +#: nova/rpc.py:125 +msgid "Failed to fetch message from queue" +msgstr "" + +#: nova/rpc.py:155 +#, python-format +msgid "Initing the Adapter Consumer for %s" +msgstr "" + +#: nova/rpc.py:170 +#, python-format +msgid "received %s" +msgstr "" + +#: nova/rpc.py:183 +#, python-format +msgid "no method for message: %s" +msgstr "" + +#: nova/rpc.py:184 +#, python-format +msgid "No method for message: %s" +msgstr "" + +#: nova/rpc.py:245 +#, python-format +msgid "Returning exception %s to caller" +msgstr "" + +#: nova/rpc.py:286 +#, python-format +msgid "unpacked context: %s" +msgstr "" + +#: nova/rpc.py:305 +msgid "Making asynchronous call..." +msgstr "" + +#: nova/rpc.py:308 +#, python-format +msgid "MSG_ID is %s" +msgstr "" + +#: nova/rpc.py:356 +#, python-format +msgid "response %s" +msgstr "" + +#: nova/rpc.py:365 +#, python-format +msgid "topic is %s" +msgstr "" + +#: nova/rpc.py:366 +#, python-format +msgid "message %s" +msgstr "" + +#: nova/service.py:157 +#, python-format +msgid "Starting %s node" +msgstr "" + +#: nova/service.py:169 +msgid "Service killed that has no database entry" +msgstr "" + +#: nova/service.py:190 +msgid "The service database object disappeared, Recreating it." +msgstr "" + +#: nova/service.py:202 +msgid "Recovered model server connection!" +msgstr "" + +#: nova/service.py:208 +msgid "model server went away" +msgstr "" + +#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#, python-format +msgid "Data store %s is unreachable. Trying again in %d seconds." +msgstr "" + +#: nova/service.py:232 nova/twistd.py:232 +#, python-format +msgid "Serving %s" +msgstr "" + +#: nova/service.py:234 nova/twistd.py:264 +msgid "Full set of FLAGS:" +msgstr "" + +#: nova/twistd.py:211 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "" + +#: nova/twistd.py:268 +#, python-format +msgid "Starting %s" +msgstr "" + +#: nova/utils.py:53 +#, python-format +msgid "Inner Exception: %s" +msgstr "" + +#: nova/utils.py:54 +#, python-format +msgid "Class %s cannot be found" +msgstr "" + +#: nova/utils.py:113 +#, python-format +msgid "Fetching %s" +msgstr "" + +#: nova/utils.py:125 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "" + +#: nova/utils.py:138 +#, python-format +msgid "Result was %s" +msgstr "" + +#: nova/utils.py:171 +#, python-format +msgid "debug in callback: %s" +msgstr "" + +#: nova/utils.py:176 +#, python-format +msgid "Running %s" +msgstr "" + +#: nova/utils.py:207 +#, python-format +msgid "Couldn't get IP, using 127.0.0.1 %s" +msgstr "" + +#: nova/utils.py:289 +#, python-format +msgid "Invalid backend: %s" +msgstr "" + +#: nova/utils.py:300 +#, python-format +msgid "backend %s" +msgstr "" + +#: nova/api/ec2/__init__.py:133 +msgid "Too many failed authentications." +msgstr "" + +#: nova/api/ec2/__init__.py:142 +#, python-format +msgid "" +"Access key %s has had %d failed authentications and will be locked out for " +"%d minutes." +msgstr "" + +#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#, python-format +msgid "Authentication Failure: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:190 +#, python-format +msgid "Authenticated Request For %s:%s)" +msgstr "" + +#: nova/api/ec2/__init__.py:227 +#, python-format +msgid "action: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:229 +#, python-format +msgid "arg: %s\t\tval: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:301 +#, python-format +msgid "Unauthorized request for controller=%s and action=%s" +msgstr "" + +#: nova/api/ec2/__init__.py:339 +#, python-format +msgid "NotFound raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:342 +#, python-format +msgid "ApiError raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:349 +#, python-format +msgid "Unexpected error raised: %s" +msgstr "" + +#: nova/api/ec2/__init__.py:354 +msgid "An unknown error has occurred. Please try your request again." +msgstr "" + +#: nova/api/ec2/admin.py:84 +#, python-format +msgid "Creating new user: %s" +msgstr "" + +#: nova/api/ec2/admin.py:92 +#, python-format +msgid "Deleting user: %s" +msgstr "" + +#: nova/api/ec2/admin.py:114 +#, python-format +msgid "Adding role %s to user %s for project %s" +msgstr "" + +#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#, python-format +msgid "Adding sitewide role %s to user %s" +msgstr "" + +#: nova/api/ec2/admin.py:122 +#, python-format +msgid "Removing role %s from user %s for project %s" +msgstr "" + +#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#, python-format +msgid "Removing sitewide role %s from user %s" +msgstr "" + +#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 +msgid "operation must be add or remove" +msgstr "" + +#: nova/api/ec2/admin.py:142 +#, python-format +msgid "Getting x509 for user: %s on project: %s" +msgstr "" + +#: nova/api/ec2/admin.py:159 +#, python-format +msgid "Create project %s managed by %s" +msgstr "" + +#: nova/api/ec2/admin.py:170 +#, python-format +msgid "Delete project: %s" +msgstr "" + +#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#, python-format +msgid "Adding user %s to project %s" +msgstr "" + +#: nova/api/ec2/admin.py:188 +#, python-format +msgid "Removing user %s from project %s" +msgstr "" + +#: nova/api/ec2/apirequest.py:95 +#, python-format +msgid "Unsupported API request: controller = %s,action = %s" +msgstr "" + +#: nova/api/ec2/cloud.py:117 +#, python-format +msgid "Generating root CA: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:277 +#, python-format +msgid "Create key pair %s" +msgstr "" + +#: nova/api/ec2/cloud.py:285 +#, python-format +msgid "Delete key pair %s" +msgstr "" + +#: nova/api/ec2/cloud.py:357 +#, python-format +msgid "%s is not a valid ipProtocol" +msgstr "" + +#: nova/api/ec2/cloud.py:361 +msgid "Invalid port range" +msgstr "" + +#: nova/api/ec2/cloud.py:392 +#, python-format +msgid "Revoke security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 +msgid "No rule for the specified parameters." +msgstr "" + +#: nova/api/ec2/cloud.py:421 +#, python-format +msgid "Authorize security group ingress %s" +msgstr "" + +#: nova/api/ec2/cloud.py:432 +#, python-format +msgid "This rule already exists in group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:460 +#, python-format +msgid "Create Security Group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:463 +#, python-format +msgid "group %s already exists" +msgstr "" + +#: nova/api/ec2/cloud.py:475 +#, python-format +msgid "Delete security group %s" +msgstr "" + +#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:543 +#, python-format +msgid "Create volume of %s GB" +msgstr "" + +#: nova/api/ec2/cloud.py:567 +#, python-format +msgid "Attach volume %s to instacne %s at %s" +msgstr "" + +#: nova/api/ec2/cloud.py:579 +#, python-format +msgid "Detach volume %s" +msgstr "" + +#: nova/api/ec2/cloud.py:686 +msgid "Allocate address" +msgstr "" + +#: nova/api/ec2/cloud.py:691 +#, python-format +msgid "Release address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:696 +#, python-format +msgid "Associate address %s to instance %s" +msgstr "" + +#: nova/api/ec2/cloud.py:703 +#, python-format +msgid "Disassociate address %s" +msgstr "" + +#: nova/api/ec2/cloud.py:730 +msgid "Going to start terminating instances" +msgstr "" + +#: nova/api/ec2/cloud.py:738 +#, python-format +msgid "Reboot instance %r" +msgstr "" + +#: nova/api/ec2/cloud.py:775 +#, python-format +msgid "De-registering image %s" +msgstr "" + +#: nova/api/ec2/cloud.py:783 +#, python-format +msgid "Registered image %s with id %s" +msgstr "" + +#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#, python-format +msgid "attribute not supported: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:794 +#, python-format +msgid "invalid id: %s" +msgstr "" + +#: nova/api/ec2/cloud.py:807 +msgid "user or group not specified" +msgstr "" + +#: nova/api/ec2/cloud.py:809 +msgid "only group \"all\" is supported" +msgstr "" + +#: nova/api/ec2/cloud.py:811 +msgid "operation_type must be add or remove" +msgstr "" + +#: nova/api/ec2/cloud.py:812 +#, python-format +msgid "Updating image %s publicity" +msgstr "" + +#: nova/api/ec2/metadatarequesthandler.py:75 +#, python-format +msgid "Failed to get metadata for ip: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:70 +#, python-format +msgid "Caught error: %s" +msgstr "" + +#: nova/api/openstack/__init__.py:86 +msgid "Including admin operations in API." +msgstr "" + +#: nova/api/openstack/servers.py:184 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:199 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: nova/api/openstack/servers.py:213 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: nova/api/openstack/servers.py:224 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: nova/api/openstack/servers.py:235 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: nova/api/openstack/servers.py:246 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: nova/api/openstack/servers.py:257 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: nova/auth/dbdriver.py:84 +#, python-format +msgid "User %s already exists" +msgstr "" + +#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#, python-format +msgid "Project can't be created because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#, python-format +msgid "Project can't be created because project %s already exists" +msgstr "" + +#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#, python-format +msgid "Project can't be modified because manager %s doesn't exist" +msgstr "" + +#: nova/auth/dbdriver.py:245 +#, python-format +msgid "User \"%s\" not found" +msgstr "" + +#: nova/auth/dbdriver.py:248 +#, python-format +msgid "Project \"%s\" not found" +msgstr "" + +#: nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "" + +#: nova/auth/ldapdriver.py:181 +#, python-format +msgid "LDAP object for %s doesn't exist" +msgstr "" + +#: nova/auth/ldapdriver.py:218 +#, python-format +msgid "Project can't be created because user %s doesn't exist" +msgstr "" + +#: nova/auth/ldapdriver.py:478 +#, python-format +msgid "User %s is already a member of the group %s" +msgstr "" + +#: nova/auth/ldapdriver.py:507 +#, python-format +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." +msgstr "" + +#: nova/auth/ldapdriver.py:528 +#, python-format +msgid "Group at dn %s doesn't exist" +msgstr "" + +#: nova/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "" + +#: nova/auth/manager.py:263 +#, python-format +msgid "Failed authorization for access key %s" +msgstr "" + +#: nova/auth/manager.py:264 +#, python-format +msgid "No user found for access key %s" +msgstr "" + +#: nova/auth/manager.py:270 +#, python-format +msgid "Using project name = user name (%s)" +msgstr "" + +#: nova/auth/manager.py:275 +#, python-format +msgid "failed authorization: no project named %s (user=%s)" +msgstr "" + +#: nova/auth/manager.py:277 +#, python-format +msgid "No project called %s could be found" +msgstr "" + +#: nova/auth/manager.py:281 +#, python-format +msgid "Failed authorization: user %s not admin and not member of project %s" +msgstr "" + +#: nova/auth/manager.py:283 +#, python-format +msgid "User %s is not a member of project %s" +msgstr "" + +#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#, python-format +msgid "Invalid signature for user %s" +msgstr "" + +#: nova/auth/manager.py:293 nova/auth/manager.py:304 +msgid "Signature does not match" +msgstr "" + +#: nova/auth/manager.py:374 +msgid "Must specify project" +msgstr "" + +#: nova/auth/manager.py:408 +#, python-format +msgid "The %s role can not be found" +msgstr "" + +#: nova/auth/manager.py:410 +#, python-format +msgid "The %s role is global only" +msgstr "" + +#: nova/auth/manager.py:412 +#, python-format +msgid "Adding role %s to user %s in project %s" +msgstr "" + +#: nova/auth/manager.py:438 +#, python-format +msgid "Removing role %s from user %s on project %s" +msgstr "" + +#: nova/auth/manager.py:505 +#, python-format +msgid "Created project %s with manager %s" +msgstr "" + +#: nova/auth/manager.py:523 +#, python-format +msgid "modifying project %s" +msgstr "" + +#: nova/auth/manager.py:553 +#, python-format +msgid "Remove user %s from project %s" +msgstr "" + +#: nova/auth/manager.py:581 +#, python-format +msgid "Deleting project %s" +msgstr "" + +#: nova/auth/manager.py:637 +#, python-format +msgid "Created user %s (admin: %r)" +msgstr "" + +#: nova/auth/manager.py:645 +#, python-format +msgid "Deleting user %s" +msgstr "" + +#: nova/auth/manager.py:655 +#, python-format +msgid "Access Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:657 +#, python-format +msgid "Secret Key change for user %s" +msgstr "" + +#: nova/auth/manager.py:659 +#, python-format +msgid "Admin status set to %r for user %s" +msgstr "" + +#: nova/auth/manager.py:708 +#, python-format +msgid "No vpn data for project %s" +msgstr "" + +#: nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" +msgstr "" + +#: nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" +msgstr "" + +#: nova/cloudpipe/pipelib.py:97 +#, python-format +msgid "Launching VPN for %s" +msgstr "" + +#: nova/compute/api.py:67 +#, python-format +msgid "Instance %d was not found in get_network_topic" +msgstr "" + +#: nova/compute/api.py:73 +#, python-format +msgid "Instance %d has no host" +msgstr "" + +#: nova/compute/api.py:92 +#, python-format +msgid "Quota exceeeded for %s, tried to run %s instances" +msgstr "" + +#: nova/compute/api.py:94 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." +msgstr "" + +#: nova/compute/api.py:109 +msgid "Creating a raw instance" +msgstr "" + +#: nova/compute/api.py:156 +#, python-format +msgid "Going to run %s instances..." +msgstr "" + +#: nova/compute/api.py:180 +#, python-format +msgid "Casting to scheduler for %s/%s's instance %s" +msgstr "" + +#: nova/compute/api.py:279 +#, python-format +msgid "Going to try and terminate %s" +msgstr "" + +#: nova/compute/api.py:283 +#, python-format +msgid "Instance %d was not found during terminate" +msgstr "" + +#: nova/compute/api.py:288 +#, python-format +msgid "Instance %d is already being terminated" +msgstr "" + +#: nova/compute/api.py:450 +#, python-format +msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgstr "" + +#: nova/compute/api.py:465 +msgid "Volume isn't attached to anything!" +msgstr "" + +#: nova/compute/disk.py:71 +#, python-format +msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:75 +#, python-format +msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgstr "" + +#: nova/compute/disk.py:128 +#, python-format +msgid "Could not attach image to loopback: %s" +msgstr "" + +#: nova/compute/disk.py:136 +#, python-format +msgid "Failed to load partition: %s" +msgstr "" + +#: nova/compute/disk.py:158 +#, python-format +msgid "Failed to mount filesystem: %s" +msgstr "" + +#: nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "" + +#: nova/compute/manager.py:69 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: nova/compute/manager.py:71 +#, python-format +msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgstr "" + +#: nova/compute/manager.py:75 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: nova/compute/manager.py:77 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: nova/compute/manager.py:82 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: nova/compute/manager.py:157 +msgid "Instance has already been created" +msgstr "" + +#: nova/compute/manager.py:158 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#: nova/compute/manager.py:197 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: nova/compute/manager.py:217 +#, python-format +msgid "Disassociating address %s" +msgstr "" + +#: nova/compute/manager.py:230 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: nova/compute/manager.py:243 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: nova/compute/manager.py:257 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: nova/compute/manager.py:260 +#, python-format +msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:286 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: nova/compute/manager.py:289 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgstr "" + +#: nova/compute/manager.py:301 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: nova/compute/manager.py:316 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: nova/compute/manager.py:335 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: nova/compute/manager.py:352 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: nova/compute/manager.py:369 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: nova/compute/manager.py:382 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: nova/compute/manager.py:401 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: nova/compute/manager.py:420 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: nova/compute/manager.py:432 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: nova/compute/manager.py:442 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: nova/compute/manager.py:462 +#, python-format +msgid "instance %s: attaching volume %s to %s" +msgstr "" + +#: nova/compute/manager.py:478 +#, python-format +msgid "instance %s: attach failed %s, removing" +msgstr "" + +#: nova/compute/manager.py:493 +#, python-format +msgid "Detach volume %s from mountpoint %s on instance %s" +msgstr "" + +#: nova/compute/manager.py:497 +#, python-format +msgid "Detaching volume from unknown instance %s" +msgstr "" + +#: nova/compute/monitor.py:259 +#, python-format +msgid "updating %s..." +msgstr "" + +#: nova/compute/monitor.py:289 +msgid "unexpected error during update" +msgstr "" + +#: nova/compute/monitor.py:355 +#, python-format +msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:377 +#, python-format +msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgstr "" + +#: nova/compute/monitor.py:412 +msgid "unexpected exception getting connection" +msgstr "" + +#: nova/compute/monitor.py:427 +#, python-format +msgid "Found instance: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:43 +msgid "Use of empty request context is deprecated" +msgstr "" + +#: nova/db/sqlalchemy/api.py:132 +#, python-format +msgid "No service for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:229 +#, python-format +msgid "No service for %s, %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:574 +#, python-format +msgid "No floating ip for address %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:668 +#, python-format +msgid "No instance for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:758 nova/virt/libvirt_conn.py:598 +#: nova/virt/xenapi/volumeops.py:48 nova/virt/xenapi/volumeops.py:103 +#, python-format +msgid "Instance %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:891 +#, python-format +msgid "no keypair for user %s, name %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#, python-format +msgid "No network for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1036 +#, python-format +msgid "No network for bridge %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1050 +#, python-format +msgid "No network for instance %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1180 +#, python-format +msgid "Token %s does not exist" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1205 +#, python-format +msgid "No quota for project_id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1356 +#, python-format +msgid "No volume for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1401 +#, python-format +msgid "Volume %s not found" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1413 +#, python-format +msgid "No export device found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1426 +#, python-format +msgid "No target id found for volume %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1471 +#, python-format +msgid "No security group with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1488 +#, python-format +msgid "No security group named %s for project: %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1576 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1650 +#, python-format +msgid "No user for id %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1666 +#, python-format +msgid "No user for access key %s" +msgstr "" + +#: nova/db/sqlalchemy/api.py:1728 +#, python-format +msgid "No project with id %s" +msgstr "" + +#: nova/image/glance.py:78 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images" +msgstr "" + +#: nova/image/glance.py:97 +#, python-format +msgid "Parallax returned HTTP error %d from request for /images/detail" +msgstr "" + +#: nova/image/s3.py:82 +#, python-format +msgid "Image %s could not be found" +msgstr "" + +#: nova/network/api.py:39 +#, python-format +msgid "Quota exceeeded for %s, tried to allocate address" +msgstr "" + +#: nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" +msgstr "" + +#: nova/network/linux_net.py:176 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: nova/network/linux_net.py:186 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#: nova/network/linux_net.py:254 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: nova/network/linux_net.py:256 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#: nova/network/linux_net.py:334 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: nova/network/manager.py:135 +msgid "setting network host" +msgstr "" + +#: nova/network/manager.py:190 +#, python-format +msgid "Leasing IP %s" +msgstr "" + +#: nova/network/manager.py:194 +#, python-format +msgid "IP %s leased that isn't associated" +msgstr "" + +#: nova/network/manager.py:197 +#, python-format +msgid "IP %s leased to bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:205 +#, python-format +msgid "IP %s leased that was already deallocated" +msgstr "" + +#: nova/network/manager.py:214 +#, python-format +msgid "IP %s released that isn't associated" +msgstr "" + +#: nova/network/manager.py:217 +#, python-format +msgid "IP %s released from bad mac %s vs %s" +msgstr "" + +#: nova/network/manager.py:220 +#, python-format +msgid "IP %s released that was not leased" +msgstr "" + +#: nova/network/manager.py:442 +#, python-format +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "" + +#: nova/objectstore/handler.py:106 +#, python-format +msgid "Unknown S3 value type %r" +msgstr "" + +#: nova/objectstore/handler.py:137 +msgid "Authenticated request" +msgstr "" + +#: nova/objectstore/handler.py:182 +msgid "List of buckets requested" +msgstr "" + +#: nova/objectstore/handler.py:209 +#, python-format +msgid "List keys for bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:217 +#, python-format +msgid "Unauthorized attempt to access bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:235 +#, python-format +msgid "Creating bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:245 +#, python-format +msgid "Deleting bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:249 +#, python-format +msgid "Unauthorized attempt to delete bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:271 +#, python-format +msgid "Getting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:274 +#, python-format +msgid "Unauthorized attempt to get object %s from bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:292 +#, python-format +msgid "Putting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:295 +#, python-format +msgid "Unauthorized attempt to upload object %s to bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:314 +#, python-format +msgid "Deleting object: %s / %s" +msgstr "" + +#: nova/objectstore/handler.py:393 +#, python-format +msgid "Not authorized to upload image: invalid directory %s" +msgstr "" + +#: nova/objectstore/handler.py:401 +#, python-format +msgid "Not authorized to upload image: unauthorized bucket %s" +msgstr "" + +#: nova/objectstore/handler.py:406 +#, python-format +msgid "Starting image upload: %s" +msgstr "" + +#: nova/objectstore/handler.py:420 +#, python-format +msgid "Not authorized to update attributes of image %s" +msgstr "" + +#: nova/objectstore/handler.py:428 +#, python-format +msgid "Toggling publicity flag of image %s %r" +msgstr "" + +#: nova/objectstore/handler.py:433 +#, python-format +msgid "Updating user fields on image %s" +msgstr "" + +#: nova/objectstore/handler.py:447 +#, python-format +msgid "Unauthorized attempt to delete image %s" +msgstr "" + +#: nova/objectstore/handler.py:452 +#, python-format +msgid "Deleted image: %s" +msgstr "" + +#: nova/scheduler/chance.py:37 nova/scheduler/simple.py:73 +#: nova/scheduler/simple.py:106 nova/scheduler/simple.py:118 +msgid "No hosts found" +msgstr "" + +#: nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "" + +#: nova/scheduler/manager.py:69 +#, python-format +msgid "Casting to %s %s for %s" +msgstr "" + +#: nova/scheduler/simple.py:63 +msgid "All hosts have too many cores" +msgstr "" + +#: nova/scheduler/simple.py:95 +msgid "All hosts have too many gigabytes" +msgstr "" + +#: nova/scheduler/simple.py:115 +msgid "All hosts have too many networks" +msgstr "" + +#: nova/tests/test_cloud.py:198 +msgid "Can't test instances without a real virtual env." +msgstr "" + +#: nova/tests/test_cloud.py:210 +#, python-format +msgid "Need to watch instance %s until it's running..." +msgstr "" + +#: nova/tests/test_compute.py:104 +#, python-format +msgid "Running instances: %s" +msgstr "" + +#: nova/tests/test_compute.py:110 +#, python-format +msgid "After terminating instances: %s" +msgstr "" + +#: nova/tests/test_rpc.py:89 +#, python-format +msgid "Nested received %s, %s" +msgstr "" + +#: nova/tests/test_rpc.py:94 +#, python-format +msgid "Nested return %s" +msgstr "" + +#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#, python-format +msgid "Received %s" +msgstr "" + +#: nova/tests/test_volume.py:162 +#, python-format +msgid "Target %s allocated" +msgstr "" + +#: nova/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "" + +#: nova/virt/fake.py:210 +#, python-format +msgid "Instance %s Not Found" +msgstr "" + +#: nova/virt/hyperv.py:118 +msgid "In init host" +msgstr "" + +#: nova/virt/hyperv.py:131 +#, python-format +msgid "Attempt to create duplicate vm %s" +msgstr "" + +#: nova/virt/hyperv.py:148 +#, python-format +msgid "Starting VM %s " +msgstr "" + +#: nova/virt/hyperv.py:150 +#, python-format +msgid "Started VM %s " +msgstr "" + +#: nova/virt/hyperv.py:152 +#, python-format +msgid "spawn vm failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:169 +#, python-format +msgid "Failed to create VM %s" +msgstr "" + +#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#, python-format +msgid "Created VM %s..." +msgstr "" + +#: nova/virt/hyperv.py:188 +#, python-format +msgid "Set memory for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:198 +#, python-format +msgid "Set vcpus for vm %s..." +msgstr "" + +#: nova/virt/hyperv.py:202 +#, python-format +msgid "Creating disk for %s by attaching disk file %s" +msgstr "" + +#: nova/virt/hyperv.py:227 +#, python-format +msgid "Failed to add diskdrive to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:230 +#, python-format +msgid "New disk drive path is %s" +msgstr "" + +#: nova/virt/hyperv.py:247 +#, python-format +msgid "Failed to add vhd file to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:249 +#, python-format +msgid "Created disk for %s" +msgstr "" + +#: nova/virt/hyperv.py:253 +#, python-format +msgid "Creating nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" +msgstr "" + +#: nova/virt/hyperv.py:273 +#, python-format +msgid "Failed creating port for %s" +msgstr "" + +#: nova/virt/hyperv.py:275 +#, python-format +msgid "Created switch port %s on switch %s" +msgstr "" + +#: nova/virt/hyperv.py:285 +#, python-format +msgid "Failed to add nic to VM %s" +msgstr "" + +#: nova/virt/hyperv.py:287 +#, python-format +msgid "Created nic for %s " +msgstr "" + +#: nova/virt/hyperv.py:320 +#, python-format +msgid "WMI job failed: %s" +msgstr "" + +#: nova/virt/hyperv.py:322 +#, python-format +msgid "WMI job succeeded: %s, Elapsed=%s " +msgstr "" + +#: nova/virt/hyperv.py:358 +#, python-format +msgid "Got request to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:383 +#, python-format +msgid "Failed to destroy vm %s" +msgstr "" + +#: nova/virt/hyperv.py:389 +#, python-format +msgid "Del: disk %s vm %s" +msgstr "" + +#: nova/virt/hyperv.py:405 +#, python-format +msgid "" +"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " +"cpu_time=%s" +msgstr "" + +#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#, python-format +msgid "duplicate name found: %s" +msgstr "" + +#: nova/virt/hyperv.py:444 +#, python-format +msgid "Successfully changed vm state of %s to %s" +msgstr "" + +#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#, python-format +msgid "Failed to change vm state of %s to %s" +msgstr "" + +#: nova/virt/images.py:70 +#, python-format +msgid "Finished retreving %s -- placed in %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:144 +#, python-format +msgid "Connecting to libvirt: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:157 +msgid "Connection to libvirt broke" +msgstr "" + +#: nova/virt/libvirt_conn.py:229 +#, python-format +msgid "instance %s: deleting instance files %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:271 +#, python-format +msgid "No disk at %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:278 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "" + +#: nova/virt/libvirt_conn.py:294 +#, python-format +msgid "instance %s: rebooted" +msgstr "" + +#: nova/virt/libvirt_conn.py:297 +#, python-format +msgid "_wait_for_reboot failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:340 +#, python-format +msgid "instance %s: rescued" +msgstr "" + +#: nova/virt/libvirt_conn.py:343 +#, python-format +msgid "_wait_for_rescue failed: %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:370 +#, python-format +msgid "instance %s: is running" +msgstr "" + +#: nova/virt/libvirt_conn.py:381 +#, python-format +msgid "instance %s: booted" +msgstr "" + +#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#, python-format +msgid "instance %s: failed to boot" +msgstr "" + +#: nova/virt/libvirt_conn.py:395 +#, python-format +msgid "virsh said: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:399 +msgid "cool, it's a device" +msgstr "" + +#: nova/virt/libvirt_conn.py:407 +#, python-format +msgid "data: %r, fpath: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:415 +#, python-format +msgid "Contents of file %s: %r" +msgstr "" + +#: nova/virt/libvirt_conn.py:449 +#, python-format +msgid "instance %s: Creating image" +msgstr "" + +#: nova/virt/libvirt_conn.py:505 +#, python-format +msgid "instance %s: injecting key into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:508 +#, python-format +msgid "instance %s: injecting net into image %s" +msgstr "" + +#: nova/virt/libvirt_conn.py:516 +#, python-format +msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgstr "" + +#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#, python-format +msgid "instance %s: starting toXML method" +msgstr "" + +#: nova/virt/libvirt_conn.py:589 +#, python-format +msgid "instance %s: finished toXML method" +msgstr "" + +#: nova/virt/xenapi_conn.py:113 +msgid "" +"Must specify xenapi_connection_url, xenapi_connection_username (optionally), " +"and xenapi_connection_password to use connection_type=xenapi" +msgstr "" + +#: nova/virt/xenapi_conn.py:263 +#, python-format +msgid "Task [%s] %s status: success %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:271 +#, python-format +msgid "Task [%s] %s status: %s %s" +msgstr "" + +#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#, python-format +msgid "Got exception: %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:72 +#, python-format +msgid "%s: _db_content => %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:247 nova/virt/xenapi/fake.py:338 +#: nova/virt/xenapi/fake.py:356 nova/virt/xenapi/fake.py:404 +msgid "Raising NotImplemented" +msgstr "" + +#: nova/virt/xenapi/fake.py:249 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:283 +#, python-format +msgid "Calling %s %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:288 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: nova/virt/xenapi/fake.py:340 +#, python-format +msgid "" +"xenapi.fake does not have an implementation for %s or it has been called " +"with the wrong number of arguments" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:40 +#, python-format +msgid "Found non-unique network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/network_utils.py:43 +#, python-format +msgid "Found no network for bridge %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:127 +#, python-format +msgid "Created VM %s as %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:147 +#, python-format +msgid "Creating VBD for VM %s, VDI %s ... " +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:149 +#, python-format +msgid "Created VBD %s for VM %s, VDI %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:165 +#, python-format +msgid "VBD not found in instance %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:175 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:202 +#, python-format +msgid "Creating VIF for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:205 +#, python-format +msgid "Created VIF %s for VM %s, network %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:216 +#, python-format +msgid "Snapshotting VM %s with label '%s'..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:229 +#, python-format +msgid "Created snapshot %s from VM %s." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:243 +#, python-format +msgid "Asking xapi to upload %s as '%s'" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:261 +#, python-format +msgid "Asking xapi to fetch %s as %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:279 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:290 +#, python-format +msgid "PV Kernel in VDI:%d" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:318 +#, python-format +msgid "VDI %s is still available" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:331 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:333 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:390 +#, python-format +msgid "VHD %s has parent %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:407 +#, python-format +msgid "Re-scanning SR %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:431 +#, python-format +msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:448 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vm_utils.py:452 +#, python-format +msgid "Unexpected number of VDIs (%s) found for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:62 +#, python-format +msgid "Attempted to create non-unique name %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:99 +#, python-format +msgid "Starting VM %s..." +msgstr "" + +#: nova/virt/xenapi/vmops.py:101 +#, python-format +msgid "Spawning VM %s created %s." +msgstr "" + +#: nova/virt/xenapi/vmops.py:112 +#, python-format +msgid "Instance %s: booted" +msgstr "" + +#: nova/virt/xenapi/vmops.py:137 +#, python-format +msgid "Instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:166 +#, python-format +msgid "Starting snapshot for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:174 +#, python-format +msgid "Unable to Snapshot %s: %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:184 +#, python-format +msgid "Finished snapshot and upload for VM %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:252 +#, python-format +msgid "suspend: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:262 +#, python-format +msgid "resume: instance not present %s" +msgstr "" + +#: nova/virt/xenapi/vmops.py:271 +#, python-format +msgid "Instance not found %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:57 +#, python-format +msgid "Introducing %s..." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:74 +#, python-format +msgid "Introduced %s as %s." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:90 +#, python-format +msgid "Unable to find SR from VBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:96 +#, python-format +msgid "Forgetting SR %s ... " +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:101 +#, python-format +msgid "Ignoring exception %s when getting PBDs for %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:107 +#, python-format +msgid "Ignoring exception %s when unplugging PBD %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:111 +#, python-format +msgid "Forgetting SR %s done." +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:113 +#, python-format +msgid "Ignoring exception %s when forgetting SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:123 +#, python-format +msgid "Unable to introduce VDI on SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:128 +#, python-format +msgid "Unable to get record of VDI %s on" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:146 +#, python-format +msgid "Unable to introduce VDI for SR %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:175 +#, python-format +msgid "Unable to obtain target information %s, %s" +msgstr "" + +#: nova/virt/xenapi/volume_utils.py:197 +#, python-format +msgid "Mountpoint cannot be translated: %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:51 +#, python-format +msgid "Attach_volume: %s, %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:69 +#, python-format +msgid "Unable to create VDI on SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:81 +#, python-format +msgid "Unable to use SR %s for instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Unable to attach volume to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:95 +#, python-format +msgid "Mountpoint %s attached to instance %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:106 +#, python-format +msgid "Detach_volume: %s, %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:113 +#, python-format +msgid "Unable to locate volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:121 +#, python-format +msgid "Unable to detach volume %s" +msgstr "" + +#: nova/virt/xenapi/volumeops.py:128 +#, python-format +msgid "Mountpoint %s detached from instance %s" +msgstr "" + +#: nova/volume/api.py:44 +#, python-format +msgid "Quota exceeeded for %s, tried to create %sG volume" +msgstr "" + +#: nova/volume/api.py:46 +#, python-format +msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgstr "" + +#: nova/volume/api.py:70 nova/volume/api.py:95 +msgid "Volume status must be available" +msgstr "" + +#: nova/volume/api.py:97 +msgid "Volume is already attached" +msgstr "" + +#: nova/volume/api.py:103 +msgid "Volume is already detached" +msgstr "" + +#: nova/volume/driver.py:76 +#, python-format +msgid "Recovering from a failed execute. Try number %s" +msgstr "" + +#: nova/volume/driver.py:85 +#, python-format +msgid "volume group %s doesn't exist" +msgstr "" + +#: nova/volume/driver.py:210 +#, python-format +msgid "FAKE AOE: %s" +msgstr "" + +#: nova/volume/driver.py:315 +#, python-format +msgid "FAKE ISCSI: %s" +msgstr "" + +#: nova/volume/manager.py:85 +#, python-format +msgid "Re-exporting %s volumes" +msgstr "" + +#: nova/volume/manager.py:93 +#, python-format +msgid "volume %s: creating" +msgstr "" + +#: nova/volume/manager.py:102 +#, python-format +msgid "volume %s: creating lv of size %sG" +msgstr "" + +#: nova/volume/manager.py:106 +#, python-format +msgid "volume %s: creating export" +msgstr "" + +#: nova/volume/manager.py:113 +#, python-format +msgid "volume %s: created successfully" +msgstr "" + +#: nova/volume/manager.py:121 +msgid "Volume is still attached" +msgstr "" + +#: nova/volume/manager.py:123 +msgid "Volume is not local to this node" +msgstr "" + +#: nova/volume/manager.py:124 +#, python-format +msgid "volume %s: removing export" +msgstr "" + +#: nova/volume/manager.py:126 +#, python-format +msgid "volume %s: deleting" +msgstr "" + +#: nova/volume/manager.py:129 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "" From ca77f88c5fca6ddd045d59ed4b20c981125a1260 Mon Sep 17 00:00:00 2001 From: brian-lamar Date: Wed, 9 Feb 2011 13:36:16 -0500 Subject: [PATCH 012/111] Added myself to Authors --- Authors | 1 + 1 file changed, 1 insertion(+) diff --git a/Authors b/Authors index 27782738..14cc9537 100644 --- a/Authors +++ b/Authors @@ -3,6 +3,7 @@ Anne Gentle Anthony Young Antony Messerli Armando Migliaccio +Brian Lamar Chiradeep Vittal Chmouel Boudjnah Chris Behrens From 2e6a97091e0fb200b142c2b60c12ffd19ddf675f Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Wed, 9 Feb 2011 21:54:52 -0500 Subject: [PATCH 013/111] adding myself to Authors file --- Authors | 1 + 1 file changed, 1 insertion(+) diff --git a/Authors b/Authors index 27782738..563ddf75 100644 --- a/Authors +++ b/Authors @@ -3,6 +3,7 @@ Anne Gentle Anthony Young Antony Messerli Armando Migliaccio +Brian Waldon Chiradeep Vittal Chmouel Boudjnah Chris Behrens From 417d726ec7b367261594276fdb3f2b9c86b018a0 Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of nova-core <> Date: Thu, 10 Feb 2011 05:13:45 +0000 Subject: [PATCH 014/111] Launchpad automatic translations update. --- locale/de.po | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/locale/de.po b/locale/de.po index e9629259..3b30c2fa 100644 --- a/locale/de.po +++ b/locale/de.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: nova\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-10 11:25-0800\n" -"PO-Revision-Date: 2011-02-08 13:06+0000\n" +"PO-Revision-Date: 2011-02-09 10:49+0000\n" "Last-Translator: Christian Berendt \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-09 05:41+0000\n" +"X-Launchpad-Export-Date: 2011-02-10 05:13+0000\n" "X-Generator: Launchpad (build 12177)\n" #: nova/crypto.py:46 @@ -146,12 +146,12 @@ msgstr "" #: nova/rpc.py:183 #, python-format msgid "no method for message: %s" -msgstr "" +msgstr "keine Methode für diese Nachricht gefunden: %s" #: nova/rpc.py:184 #, python-format msgid "No method for message: %s" -msgstr "" +msgstr "keine Methode für diese Nachricht gefunden: %s" #: nova/rpc.py:245 #, python-format @@ -165,12 +165,12 @@ msgstr "" #: nova/rpc.py:305 msgid "Making asynchronous call..." -msgstr "" +msgstr "führe asynchronen Aufruf durch..." #: nova/rpc.py:308 #, python-format msgid "MSG_ID is %s" -msgstr "" +msgstr "MSG_ID ist %s" #: nova/rpc.py:356 #, python-format @@ -180,12 +180,12 @@ msgstr "" #: nova/rpc.py:365 #, python-format msgid "topic is %s" -msgstr "" +msgstr "Betreff ist %s" #: nova/rpc.py:366 #, python-format msgid "message %s" -msgstr "" +msgstr "Nachricht %s" #: nova/service.py:157 #, python-format @@ -212,6 +212,7 @@ msgstr "" #, python-format msgid "Data store %s is unreachable. Trying again in %d seconds." msgstr "" +"Datastore %s ist nicht erreichbar. Versuche es erneut in %d Sekunden." #: nova/service.py:232 nova/twistd.py:232 #, python-format @@ -220,17 +221,17 @@ msgstr "" #: nova/service.py:234 nova/twistd.py:264 msgid "Full set of FLAGS:" -msgstr "" +msgstr "Alle vorhandenen FLAGS:" #: nova/twistd.py:211 #, python-format msgid "pidfile %s does not exist. Daemon not running?\n" -msgstr "" +msgstr "PID-Datei %s existiert nicht. Läuft der Daemon nicht?\n" #: nova/twistd.py:268 #, python-format msgid "Starting %s" -msgstr "" +msgstr "%s wird gestartet" #: nova/utils.py:53 #, python-format @@ -240,7 +241,7 @@ msgstr "" #: nova/utils.py:54 #, python-format msgid "Class %s cannot be found" -msgstr "" +msgstr "Klasse %s konnte nicht gefunden werden" #: nova/utils.py:113 #, python-format @@ -250,12 +251,12 @@ msgstr "" #: nova/utils.py:125 #, python-format msgid "Running cmd (subprocess): %s" -msgstr "" +msgstr "Führe Kommando (subprocess) aus: %s" #: nova/utils.py:138 #, python-format msgid "Result was %s" -msgstr "" +msgstr "Ergebnis war %s" #: nova/utils.py:171 #, python-format @@ -2095,22 +2096,22 @@ msgstr "" #: nova/volume/manager.py:93 #, python-format msgid "volume %s: creating" -msgstr "" +msgstr "Volume %s: wird erstellt" #: nova/volume/manager.py:102 #, python-format msgid "volume %s: creating lv of size %sG" -msgstr "" +msgstr "Volume %s: erstelle LV mit %sG" #: nova/volume/manager.py:106 #, python-format msgid "volume %s: creating export" -msgstr "" +msgstr "Volume %s: erstelle Export" #: nova/volume/manager.py:113 #, python-format msgid "volume %s: created successfully" -msgstr "" +msgstr "Volume %s: erfolgreich erstellt" #: nova/volume/manager.py:121 msgid "Volume is still attached" @@ -2123,14 +2124,14 @@ msgstr "" #: nova/volume/manager.py:124 #, python-format msgid "volume %s: removing export" -msgstr "" +msgstr "Volume %s: entferne Export" #: nova/volume/manager.py:126 #, python-format msgid "volume %s: deleting" -msgstr "" +msgstr "Volume %s: wird entfernt" #: nova/volume/manager.py:129 #, python-format msgid "volume %s: deleted successfully" -msgstr "" +msgstr "Volume %s: erfolgreich entfernt" From f89ee0e47c808ffea7fbf564852186c90e184b86 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 10 Feb 2011 08:43:46 -0400 Subject: [PATCH 015/111] removed ZoneCommands from nova-manage --- bin/nova-manage | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index b62687ae..7835ca55 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -569,15 +569,6 @@ class DbCommands(object): print migration.db_version() -class ZoneCommands(object): - """Methods for defining zones.""" - - def create(self, name): - """Create a new Zone for this deployment.""" - ctxt = context.get_admin_context() - db.create_zone(ctxt, name) - - class VolumeCommands(object): """Methods for dealing with a cloud in an odd state""" @@ -629,7 +620,6 @@ CATEGORIES = [ ('service', ServiceCommands), ('log', LogCommands), ('db', DbCommands), - ('zone', ZoneCommands), ('volume', VolumeCommands)] From 52c03a736faf1cdd19ecdfca3f80553fc405cdb9 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 10 Feb 2011 16:08:19 -0400 Subject: [PATCH 016/111] template adjusted to NOVA_TOOLS, zone db & os api layers added --- nova/auth/novarc.template | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/nova/auth/novarc.template b/nova/auth/novarc.template index c53a4acd..702df3bb 100644 --- a/nova/auth/novarc.template +++ b/nova/auth/novarc.template @@ -10,7 +10,6 @@ export NOVA_CERT=${NOVA_KEY_DIR}/%(nova)s export EUCALYPTUS_CERT=${NOVA_CERT} # euca-bundle-image seems to require this set alias ec2-bundle-image="ec2-bundle-image --cert ${EC2_CERT} --privatekey ${EC2_PRIVATE_KEY} --user 42 --ec2cert ${NOVA_CERT}" alias ec2-upload-bundle="ec2-upload-bundle -a ${EC2_ACCESS_KEY} -s ${EC2_SECRET_KEY} --url ${S3_URL} --ec2cert ${NOVA_CERT}" -export CLOUD_SERVERS_API_KEY="%(access)s" -export CLOUD_SERVERS_USERNAME="%(user)s" -export CLOUD_SERVERS_URL="%(os)s" - +export NOVA_TOOLS_API_KEY="%(access)s" +export NOVA_TOOLS_USERNAME="%(user)s" +export NOVA_TOOLS_URL="%(os)s" From 27e98b474afdaec42274a07a22bcff04a1990744 Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of nova-core <> Date: Sat, 12 Feb 2011 05:37:22 +0000 Subject: [PATCH 017/111] Launchpad automatic translations update. --- locale/zh_CN.po | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/locale/zh_CN.po b/locale/zh_CN.po index 6bc231e5..bc82115a 100644 --- a/locale/zh_CN.po +++ b/locale/zh_CN.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: nova\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-10 11:25-0800\n" -"PO-Revision-Date: 2011-01-22 03:11+0000\n" -"Last-Translator: combo \n" +"PO-Revision-Date: 2011-02-12 05:05+0000\n" +"Last-Translator: Winston Dillon \n" "Language-Team: Chinese (Simplified) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-05 05:36+0000\n" -"X-Generator: Launchpad (build 12177)\n" +"X-Launchpad-Export-Date: 2011-02-12 05:37+0000\n" +"X-Generator: Launchpad (build 12351)\n" #: nova/twistd.py:268 #, python-format @@ -315,7 +315,7 @@ msgstr "键为: %s\t\t值为: %s" #: nova/api/ec2/__init__.py:301 #, python-format msgid "Unauthorized request for controller=%s and action=%s" -msgstr "对于控制器=%s和执行=%s的请求,未审核" +msgstr "对控制器=%s及动作=%s未经授权" #: nova/api/ec2/__init__.py:339 #, python-format @@ -330,7 +330,7 @@ msgstr "引发了Api错误: %s" #: nova/api/ec2/__init__.py:349 #, python-format msgid "Unexpected error raised: %s" -msgstr "引发了未知的错误: %s" +msgstr "引发了意外的错误:%s" #: nova/api/ec2/__init__.py:354 msgid "An unknown error has occurred. Please try your request again." @@ -349,7 +349,7 @@ msgstr "删除用户: %s" #: nova/api/ec2/admin.py:114 #, python-format msgid "Adding role %s to user %s for project %s" -msgstr "增加角色 %s给用户 %s,在工程 %s中" +msgstr "正将%s角色赋予用户%s(在工程%s中)" #: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 #, python-format @@ -359,12 +359,12 @@ msgstr "增加站点范围的 %s角色给用户 %s" #: nova/api/ec2/admin.py:122 #, python-format msgid "Removing role %s from user %s for project %s" -msgstr "移除角色 %s从用户 %s中,在工程 %s" +msgstr "正将角色%s从用户%s在工程%s中移除" #: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 #, python-format msgid "Removing sitewide role %s from user %s" -msgstr "移除站点范围的 %s角色从用户 %s中" +msgstr "" #: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 msgid "operation must be add or remove" @@ -393,7 +393,7 @@ msgstr "增加用户%s到%s工程" #: nova/api/ec2/admin.py:188 #, python-format msgid "Removing user %s from project %s" -msgstr "移除用户%s从工程%s中" +msgstr "正将用户%s从工程%s中移除" #: nova/api/ec2/apirequest.py:95 #, python-format @@ -403,7 +403,7 @@ msgstr "不支持的API请求: 控制器 = %s,执行 = %s" #: nova/api/ec2/cloud.py:117 #, python-format msgid "Generating root CA: %s" -msgstr "" +msgstr "生成根证书: %s" #: nova/api/ec2/cloud.py:277 #, python-format From 08edeb89069345fe1269b82a825ffbe52a645b2e Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of nova-core <> Date: Sun, 13 Feb 2011 05:09:17 +0000 Subject: [PATCH 018/111] Launchpad automatic translations update. --- locale/zh_CN.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/zh_CN.po b/locale/zh_CN.po index bc82115a..64e051a6 100644 --- a/locale/zh_CN.po +++ b/locale/zh_CN.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-12 05:37+0000\n" +"X-Launchpad-Export-Date: 2011-02-13 05:09+0000\n" "X-Generator: Launchpad (build 12351)\n" #: nova/twistd.py:268 From f6d3c6fda76b39977359714f3b0c3608222f78e8 Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of nova-core <> Date: Mon, 14 Feb 2011 05:22:52 +0000 Subject: [PATCH 019/111] Launchpad automatic translations update. --- locale/zh_CN.po | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/locale/zh_CN.po b/locale/zh_CN.po index 64e051a6..01b8dc37 100644 --- a/locale/zh_CN.po +++ b/locale/zh_CN.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: nova\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-10 11:25-0800\n" -"PO-Revision-Date: 2011-02-12 05:05+0000\n" +"PO-Revision-Date: 2011-02-14 02:26+0000\n" "Last-Translator: Winston Dillon \n" "Language-Team: Chinese (Simplified) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-13 05:09+0000\n" +"X-Launchpad-Export-Date: 2011-02-14 05:22+0000\n" "X-Generator: Launchpad (build 12351)\n" #: nova/twistd.py:268 @@ -413,50 +413,50 @@ msgstr "创建键值对 %s" #: nova/api/ec2/cloud.py:285 #, python-format msgid "Delete key pair %s" -msgstr "" +msgstr "删除键值对 %s" #: nova/api/ec2/cloud.py:357 #, python-format msgid "%s is not a valid ipProtocol" -msgstr "" +msgstr "%s是无效的IP协议" #: nova/api/ec2/cloud.py:361 msgid "Invalid port range" -msgstr "" +msgstr "端口范围无效" #: nova/api/ec2/cloud.py:392 #, python-format msgid "Revoke security group ingress %s" -msgstr "" +msgstr "撤销输入安全组 %s" #: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 msgid "No rule for the specified parameters." -msgstr "" +msgstr "对给定的参数无特定规则。" #: nova/api/ec2/cloud.py:421 #, python-format msgid "Authorize security group ingress %s" -msgstr "" +msgstr "验证输入安全组 %s" #: nova/api/ec2/cloud.py:432 #, python-format msgid "This rule already exists in group %s" -msgstr "" +msgstr "这条规则已经存在安全组%s中。" #: nova/api/ec2/cloud.py:460 #, python-format msgid "Create Security Group %s" -msgstr "" +msgstr "创建安全组%s" #: nova/api/ec2/cloud.py:463 #, python-format msgid "group %s already exists" -msgstr "" +msgstr "安全组%s已经存在" #: nova/api/ec2/cloud.py:475 #, python-format msgid "Delete security group %s" -msgstr "" +msgstr "删除安全组 %s" #: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 #, python-format From 68003db30383b87141617a09cc1e12bd733a2fd2 Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Mon, 14 Feb 2011 14:26:32 +0100 Subject: [PATCH 020/111] Fix DescribeRegion answer by using specific 'listen' configuration parameter instead of overloading ec2_host --- bin/nova-api | 4 ++-- bin/nova-combined | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/nova-api b/bin/nova-api index 11176a02..eb59d019 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -59,12 +59,12 @@ def run_app(paste_config_file): LOG.debug(_("App Config: %(api)s\n%(config)r") % locals()) wsgi.paste_config_to_flags(config, { "verbose": FLAGS.verbose, - "%s_host" % api: config.get('host', '0.0.0.0'), + "%s_host" % api: getattr(FLAGS, "%s_host" % api), "%s_port" % api: getattr(FLAGS, "%s_port" % api)}) LOG.info(_("Running %s API"), api) app = wsgi.load_paste_app(paste_config_file, api) apps.append((app, getattr(FLAGS, "%s_port" % api), - getattr(FLAGS, "%s_host" % api))) + config.get('listen', '0.0.0.0'))) if len(apps) == 0: LOG.error(_("No known API applications configured in %s."), paste_config_file) diff --git a/bin/nova-combined b/bin/nova-combined index 913c866b..889600eb 100755 --- a/bin/nova-combined +++ b/bin/nova-combined @@ -67,11 +67,11 @@ if __name__ == '__main__': continue wsgi.paste_config_to_flags(config, { "verbose": FLAGS.verbose, - "%s_host" % api: config.get('host', '0.0.0.0'), + "%s_host" % api: getattr(FLAGS, "%s_host" % api), "%s_port" % api: getattr(FLAGS, "%s_port" % api)}) app = wsgi.load_paste_app(paste_config_file, api) apps.append((app, getattr(FLAGS, "%s_port" % api), - getattr(FLAGS, "%s_host" % api))) + config.get('listen', '0.0.0.0'))) if len(apps) > 0: logging.basicConfig() server = wsgi.Server() From 8ba83d223a8ed84591782e80ceeecc717ee98596 Mon Sep 17 00:00:00 2001 From: "jaypipes@gmail.com" <> Date: Mon, 14 Feb 2011 11:04:45 -0500 Subject: [PATCH 021/111] Merge Distutils.Extra changes for automating translation message catalog compilation --- locale/nova.pot | 2130 ------------------------------------- po/nova.pot | 2705 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2705 insertions(+), 2130 deletions(-) delete mode 100644 locale/nova.pot create mode 100644 po/nova.pot diff --git a/locale/nova.pot b/locale/nova.pot deleted file mode 100644 index a96411e3..00000000 --- a/locale/nova.pot +++ /dev/null @@ -1,2130 +0,0 @@ -# Translations template for nova. -# Copyright (C) 2011 ORGANIZATION -# This file is distributed under the same license as the nova project. -# FIRST AUTHOR , 2011. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: nova 2011.1\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-01-10 11:25-0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.4\n" - -#: nova/crypto.py:46 -msgid "Filename of root CA" -msgstr "" - -#: nova/crypto.py:49 -msgid "Filename of private key" -msgstr "" - -#: nova/crypto.py:51 -msgid "Filename of root Certificate Revokation List" -msgstr "" - -#: nova/crypto.py:53 -msgid "Where we keep our keys" -msgstr "" - -#: nova/crypto.py:55 -msgid "Where we keep our root CA" -msgstr "" - -#: nova/crypto.py:57 -msgid "Should we use a CA for each project?" -msgstr "" - -#: nova/crypto.py:61 -#, python-format -msgid "Subject for certificate for users, %s for project, user, timestamp" -msgstr "" - -#: nova/crypto.py:66 -#, python-format -msgid "Subject for certificate for projects, %s for project, timestamp" -msgstr "" - -#: nova/crypto.py:71 -#, python-format -msgid "Subject for certificate for vpns, %s for project, timestamp" -msgstr "" - -#: nova/crypto.py:258 -#, python-format -msgid "Flags path: %s" -msgstr "" - -#: nova/exception.py:33 -msgid "Unexpected error while running command." -msgstr "" - -#: nova/exception.py:36 -#, python-format -msgid "" -"%s\n" -"Command: %s\n" -"Exit code: %s\n" -"Stdout: %r\n" -"Stderr: %r" -msgstr "" - -#: nova/exception.py:86 -msgid "Uncaught exception" -msgstr "" - -#: nova/fakerabbit.py:48 -#, python-format -msgid "(%s) publish (key: %s) %s" -msgstr "" - -#: nova/fakerabbit.py:53 -#, python-format -msgid "Publishing to route %s" -msgstr "" - -#: nova/fakerabbit.py:83 -#, python-format -msgid "Declaring queue %s" -msgstr "" - -#: nova/fakerabbit.py:89 -#, python-format -msgid "Declaring exchange %s" -msgstr "" - -#: nova/fakerabbit.py:95 -#, python-format -msgid "Binding %s to %s with key %s" -msgstr "" - -#: nova/fakerabbit.py:120 -#, python-format -msgid "Getting from %s: %s" -msgstr "" - -#: nova/rpc.py:92 -#, python-format -msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." -msgstr "" - -#: nova/rpc.py:99 -#, python-format -msgid "Unable to connect to AMQP server after %d tries. Shutting down." -msgstr "" - -#: nova/rpc.py:118 -msgid "Reconnected to queue" -msgstr "" - -#: nova/rpc.py:125 -msgid "Failed to fetch message from queue" -msgstr "" - -#: nova/rpc.py:155 -#, python-format -msgid "Initing the Adapter Consumer for %s" -msgstr "" - -#: nova/rpc.py:170 -#, python-format -msgid "received %s" -msgstr "" - -#: nova/rpc.py:183 -#, python-format -msgid "no method for message: %s" -msgstr "" - -#: nova/rpc.py:184 -#, python-format -msgid "No method for message: %s" -msgstr "" - -#: nova/rpc.py:245 -#, python-format -msgid "Returning exception %s to caller" -msgstr "" - -#: nova/rpc.py:286 -#, python-format -msgid "unpacked context: %s" -msgstr "" - -#: nova/rpc.py:305 -msgid "Making asynchronous call..." -msgstr "" - -#: nova/rpc.py:308 -#, python-format -msgid "MSG_ID is %s" -msgstr "" - -#: nova/rpc.py:356 -#, python-format -msgid "response %s" -msgstr "" - -#: nova/rpc.py:365 -#, python-format -msgid "topic is %s" -msgstr "" - -#: nova/rpc.py:366 -#, python-format -msgid "message %s" -msgstr "" - -#: nova/service.py:157 -#, python-format -msgid "Starting %s node" -msgstr "" - -#: nova/service.py:169 -msgid "Service killed that has no database entry" -msgstr "" - -#: nova/service.py:190 -msgid "The service database object disappeared, Recreating it." -msgstr "" - -#: nova/service.py:202 -msgid "Recovered model server connection!" -msgstr "" - -#: nova/service.py:208 -msgid "model server went away" -msgstr "" - -#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 -#, python-format -msgid "Data store %s is unreachable. Trying again in %d seconds." -msgstr "" - -#: nova/service.py:232 nova/twistd.py:232 -#, python-format -msgid "Serving %s" -msgstr "" - -#: nova/service.py:234 nova/twistd.py:264 -msgid "Full set of FLAGS:" -msgstr "" - -#: nova/twistd.py:211 -#, python-format -msgid "pidfile %s does not exist. Daemon not running?\n" -msgstr "" - -#: nova/twistd.py:268 -#, python-format -msgid "Starting %s" -msgstr "" - -#: nova/utils.py:53 -#, python-format -msgid "Inner Exception: %s" -msgstr "" - -#: nova/utils.py:54 -#, python-format -msgid "Class %s cannot be found" -msgstr "" - -#: nova/utils.py:113 -#, python-format -msgid "Fetching %s" -msgstr "" - -#: nova/utils.py:125 -#, python-format -msgid "Running cmd (subprocess): %s" -msgstr "" - -#: nova/utils.py:138 -#, python-format -msgid "Result was %s" -msgstr "" - -#: nova/utils.py:171 -#, python-format -msgid "debug in callback: %s" -msgstr "" - -#: nova/utils.py:176 -#, python-format -msgid "Running %s" -msgstr "" - -#: nova/utils.py:207 -#, python-format -msgid "Couldn't get IP, using 127.0.0.1 %s" -msgstr "" - -#: nova/utils.py:289 -#, python-format -msgid "Invalid backend: %s" -msgstr "" - -#: nova/utils.py:300 -#, python-format -msgid "backend %s" -msgstr "" - -#: nova/api/ec2/__init__.py:133 -msgid "Too many failed authentications." -msgstr "" - -#: nova/api/ec2/__init__.py:142 -#, python-format -msgid "" -"Access key %s has had %d failed authentications and will be locked out " -"for %d minutes." -msgstr "" - -#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 -#, python-format -msgid "Authentication Failure: %s" -msgstr "" - -#: nova/api/ec2/__init__.py:190 -#, python-format -msgid "Authenticated Request For %s:%s)" -msgstr "" - -#: nova/api/ec2/__init__.py:227 -#, python-format -msgid "action: %s" -msgstr "" - -#: nova/api/ec2/__init__.py:229 -#, python-format -msgid "arg: %s\t\tval: %s" -msgstr "" - -#: nova/api/ec2/__init__.py:301 -#, python-format -msgid "Unauthorized request for controller=%s and action=%s" -msgstr "" - -#: nova/api/ec2/__init__.py:339 -#, python-format -msgid "NotFound raised: %s" -msgstr "" - -#: nova/api/ec2/__init__.py:342 -#, python-format -msgid "ApiError raised: %s" -msgstr "" - -#: nova/api/ec2/__init__.py:349 -#, python-format -msgid "Unexpected error raised: %s" -msgstr "" - -#: nova/api/ec2/__init__.py:354 -msgid "An unknown error has occurred. Please try your request again." -msgstr "" - -#: nova/api/ec2/admin.py:84 -#, python-format -msgid "Creating new user: %s" -msgstr "" - -#: nova/api/ec2/admin.py:92 -#, python-format -msgid "Deleting user: %s" -msgstr "" - -#: nova/api/ec2/admin.py:114 -#, python-format -msgid "Adding role %s to user %s for project %s" -msgstr "" - -#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 -#, python-format -msgid "Adding sitewide role %s to user %s" -msgstr "" - -#: nova/api/ec2/admin.py:122 -#, python-format -msgid "Removing role %s from user %s for project %s" -msgstr "" - -#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 -#, python-format -msgid "Removing sitewide role %s from user %s" -msgstr "" - -#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 -msgid "operation must be add or remove" -msgstr "" - -#: nova/api/ec2/admin.py:142 -#, python-format -msgid "Getting x509 for user: %s on project: %s" -msgstr "" - -#: nova/api/ec2/admin.py:159 -#, python-format -msgid "Create project %s managed by %s" -msgstr "" - -#: nova/api/ec2/admin.py:170 -#, python-format -msgid "Delete project: %s" -msgstr "" - -#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 -#, python-format -msgid "Adding user %s to project %s" -msgstr "" - -#: nova/api/ec2/admin.py:188 -#, python-format -msgid "Removing user %s from project %s" -msgstr "" - -#: nova/api/ec2/apirequest.py:95 -#, python-format -msgid "Unsupported API request: controller = %s,action = %s" -msgstr "" - -#: nova/api/ec2/cloud.py:117 -#, python-format -msgid "Generating root CA: %s" -msgstr "" - -#: nova/api/ec2/cloud.py:277 -#, python-format -msgid "Create key pair %s" -msgstr "" - -#: nova/api/ec2/cloud.py:285 -#, python-format -msgid "Delete key pair %s" -msgstr "" - -#: nova/api/ec2/cloud.py:357 -#, python-format -msgid "%s is not a valid ipProtocol" -msgstr "" - -#: nova/api/ec2/cloud.py:361 -msgid "Invalid port range" -msgstr "" - -#: nova/api/ec2/cloud.py:392 -#, python-format -msgid "Revoke security group ingress %s" -msgstr "" - -#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 -msgid "No rule for the specified parameters." -msgstr "" - -#: nova/api/ec2/cloud.py:421 -#, python-format -msgid "Authorize security group ingress %s" -msgstr "" - -#: nova/api/ec2/cloud.py:432 -#, python-format -msgid "This rule already exists in group %s" -msgstr "" - -#: nova/api/ec2/cloud.py:460 -#, python-format -msgid "Create Security Group %s" -msgstr "" - -#: nova/api/ec2/cloud.py:463 -#, python-format -msgid "group %s already exists" -msgstr "" - -#: nova/api/ec2/cloud.py:475 -#, python-format -msgid "Delete security group %s" -msgstr "" - -#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 -#, python-format -msgid "Get console output for instance %s" -msgstr "" - -#: nova/api/ec2/cloud.py:543 -#, python-format -msgid "Create volume of %s GB" -msgstr "" - -#: nova/api/ec2/cloud.py:567 -#, python-format -msgid "Attach volume %s to instacne %s at %s" -msgstr "" - -#: nova/api/ec2/cloud.py:579 -#, python-format -msgid "Detach volume %s" -msgstr "" - -#: nova/api/ec2/cloud.py:686 -msgid "Allocate address" -msgstr "" - -#: nova/api/ec2/cloud.py:691 -#, python-format -msgid "Release address %s" -msgstr "" - -#: nova/api/ec2/cloud.py:696 -#, python-format -msgid "Associate address %s to instance %s" -msgstr "" - -#: nova/api/ec2/cloud.py:703 -#, python-format -msgid "Disassociate address %s" -msgstr "" - -#: nova/api/ec2/cloud.py:730 -msgid "Going to start terminating instances" -msgstr "" - -#: nova/api/ec2/cloud.py:738 -#, python-format -msgid "Reboot instance %r" -msgstr "" - -#: nova/api/ec2/cloud.py:775 -#, python-format -msgid "De-registering image %s" -msgstr "" - -#: nova/api/ec2/cloud.py:783 -#, python-format -msgid "Registered image %s with id %s" -msgstr "" - -#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 -#, python-format -msgid "attribute not supported: %s" -msgstr "" - -#: nova/api/ec2/cloud.py:794 -#, python-format -msgid "invalid id: %s" -msgstr "" - -#: nova/api/ec2/cloud.py:807 -msgid "user or group not specified" -msgstr "" - -#: nova/api/ec2/cloud.py:809 -msgid "only group \"all\" is supported" -msgstr "" - -#: nova/api/ec2/cloud.py:811 -msgid "operation_type must be add or remove" -msgstr "" - -#: nova/api/ec2/cloud.py:812 -#, python-format -msgid "Updating image %s publicity" -msgstr "" - -#: nova/api/ec2/metadatarequesthandler.py:75 -#, python-format -msgid "Failed to get metadata for ip: %s" -msgstr "" - -#: nova/api/openstack/__init__.py:70 -#, python-format -msgid "Caught error: %s" -msgstr "" - -#: nova/api/openstack/__init__.py:86 -msgid "Including admin operations in API." -msgstr "" - -#: nova/api/openstack/servers.py:184 -#, python-format -msgid "Compute.api::lock %s" -msgstr "" - -#: nova/api/openstack/servers.py:199 -#, python-format -msgid "Compute.api::unlock %s" -msgstr "" - -#: nova/api/openstack/servers.py:213 -#, python-format -msgid "Compute.api::get_lock %s" -msgstr "" - -#: nova/api/openstack/servers.py:224 -#, python-format -msgid "Compute.api::pause %s" -msgstr "" - -#: nova/api/openstack/servers.py:235 -#, python-format -msgid "Compute.api::unpause %s" -msgstr "" - -#: nova/api/openstack/servers.py:246 -#, python-format -msgid "compute.api::suspend %s" -msgstr "" - -#: nova/api/openstack/servers.py:257 -#, python-format -msgid "compute.api::resume %s" -msgstr "" - -#: nova/auth/dbdriver.py:84 -#, python-format -msgid "User %s already exists" -msgstr "" - -#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 -#, python-format -msgid "Project can't be created because manager %s doesn't exist" -msgstr "" - -#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 -#, python-format -msgid "Project can't be created because project %s already exists" -msgstr "" - -#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 -#, python-format -msgid "Project can't be modified because manager %s doesn't exist" -msgstr "" - -#: nova/auth/dbdriver.py:245 -#, python-format -msgid "User \"%s\" not found" -msgstr "" - -#: nova/auth/dbdriver.py:248 -#, python-format -msgid "Project \"%s\" not found" -msgstr "" - -#: nova/auth/fakeldap.py:33 -msgid "Attempted to instantiate singleton" -msgstr "" - -#: nova/auth/ldapdriver.py:181 -#, python-format -msgid "LDAP object for %s doesn't exist" -msgstr "" - -#: nova/auth/ldapdriver.py:218 -#, python-format -msgid "Project can't be created because user %s doesn't exist" -msgstr "" - -#: nova/auth/ldapdriver.py:478 -#, python-format -msgid "User %s is already a member of the group %s" -msgstr "" - -#: nova/auth/ldapdriver.py:507 -#, python-format -msgid "" -"Attempted to remove the last member of a group. Deleting the group at %s " -"instead." -msgstr "" - -#: nova/auth/ldapdriver.py:528 -#, python-format -msgid "Group at dn %s doesn't exist" -msgstr "" - -#: nova/auth/manager.py:259 -#, python-format -msgid "Looking up user: %r" -msgstr "" - -#: nova/auth/manager.py:263 -#, python-format -msgid "Failed authorization for access key %s" -msgstr "" - -#: nova/auth/manager.py:264 -#, python-format -msgid "No user found for access key %s" -msgstr "" - -#: nova/auth/manager.py:270 -#, python-format -msgid "Using project name = user name (%s)" -msgstr "" - -#: nova/auth/manager.py:275 -#, python-format -msgid "failed authorization: no project named %s (user=%s)" -msgstr "" - -#: nova/auth/manager.py:277 -#, python-format -msgid "No project called %s could be found" -msgstr "" - -#: nova/auth/manager.py:281 -#, python-format -msgid "Failed authorization: user %s not admin and not member of project %s" -msgstr "" - -#: nova/auth/manager.py:283 -#, python-format -msgid "User %s is not a member of project %s" -msgstr "" - -#: nova/auth/manager.py:292 nova/auth/manager.py:303 -#, python-format -msgid "Invalid signature for user %s" -msgstr "" - -#: nova/auth/manager.py:293 nova/auth/manager.py:304 -msgid "Signature does not match" -msgstr "" - -#: nova/auth/manager.py:374 -msgid "Must specify project" -msgstr "" - -#: nova/auth/manager.py:408 -#, python-format -msgid "The %s role can not be found" -msgstr "" - -#: nova/auth/manager.py:410 -#, python-format -msgid "The %s role is global only" -msgstr "" - -#: nova/auth/manager.py:412 -#, python-format -msgid "Adding role %s to user %s in project %s" -msgstr "" - -#: nova/auth/manager.py:438 -#, python-format -msgid "Removing role %s from user %s on project %s" -msgstr "" - -#: nova/auth/manager.py:505 -#, python-format -msgid "Created project %s with manager %s" -msgstr "" - -#: nova/auth/manager.py:523 -#, python-format -msgid "modifying project %s" -msgstr "" - -#: nova/auth/manager.py:553 -#, python-format -msgid "Remove user %s from project %s" -msgstr "" - -#: nova/auth/manager.py:581 -#, python-format -msgid "Deleting project %s" -msgstr "" - -#: nova/auth/manager.py:637 -#, python-format -msgid "Created user %s (admin: %r)" -msgstr "" - -#: nova/auth/manager.py:645 -#, python-format -msgid "Deleting user %s" -msgstr "" - -#: nova/auth/manager.py:655 -#, python-format -msgid "Access Key change for user %s" -msgstr "" - -#: nova/auth/manager.py:657 -#, python-format -msgid "Secret Key change for user %s" -msgstr "" - -#: nova/auth/manager.py:659 -#, python-format -msgid "Admin status set to %r for user %s" -msgstr "" - -#: nova/auth/manager.py:708 -#, python-format -msgid "No vpn data for project %s" -msgstr "" - -#: nova/cloudpipe/pipelib.py:45 -msgid "Template for script to run on cloudpipe instance boot" -msgstr "" - -#: nova/cloudpipe/pipelib.py:48 -msgid "Network to push into openvpn config" -msgstr "" - -#: nova/cloudpipe/pipelib.py:51 -msgid "Netmask to push into openvpn config" -msgstr "" - -#: nova/cloudpipe/pipelib.py:97 -#, python-format -msgid "Launching VPN for %s" -msgstr "" - -#: nova/compute/api.py:67 -#, python-format -msgid "Instance %d was not found in get_network_topic" -msgstr "" - -#: nova/compute/api.py:73 -#, python-format -msgid "Instance %d has no host" -msgstr "" - -#: nova/compute/api.py:92 -#, python-format -msgid "Quota exceeeded for %s, tried to run %s instances" -msgstr "" - -#: nova/compute/api.py:94 -#, python-format -msgid "Instance quota exceeded. You can only run %s more instances of this type." -msgstr "" - -#: nova/compute/api.py:109 -msgid "Creating a raw instance" -msgstr "" - -#: nova/compute/api.py:156 -#, python-format -msgid "Going to run %s instances..." -msgstr "" - -#: nova/compute/api.py:180 -#, python-format -msgid "Casting to scheduler for %s/%s's instance %s" -msgstr "" - -#: nova/compute/api.py:279 -#, python-format -msgid "Going to try and terminate %s" -msgstr "" - -#: nova/compute/api.py:283 -#, python-format -msgid "Instance %d was not found during terminate" -msgstr "" - -#: nova/compute/api.py:288 -#, python-format -msgid "Instance %d is already being terminated" -msgstr "" - -#: nova/compute/api.py:450 -#, python-format -msgid "Invalid device specified: %s. Example device: /dev/vdb" -msgstr "" - -#: nova/compute/api.py:465 -msgid "Volume isn't attached to anything!" -msgstr "" - -#: nova/compute/disk.py:71 -#, python-format -msgid "Input partition size not evenly divisible by sector size: %d / %d" -msgstr "" - -#: nova/compute/disk.py:75 -#, python-format -msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" -msgstr "" - -#: nova/compute/disk.py:128 -#, python-format -msgid "Could not attach image to loopback: %s" -msgstr "" - -#: nova/compute/disk.py:136 -#, python-format -msgid "Failed to load partition: %s" -msgstr "" - -#: nova/compute/disk.py:158 -#, python-format -msgid "Failed to mount filesystem: %s" -msgstr "" - -#: nova/compute/instance_types.py:41 -#, python-format -msgid "Unknown instance type: %s" -msgstr "" - -#: nova/compute/manager.py:69 -#, python-format -msgid "check_instance_lock: decorating: |%s|" -msgstr "" - -#: nova/compute/manager.py:71 -#, python-format -msgid "check_instance_lock: arguments: |%s| |%s| |%s|" -msgstr "" - -#: nova/compute/manager.py:75 -#, python-format -msgid "check_instance_lock: locked: |%s|" -msgstr "" - -#: nova/compute/manager.py:77 -#, python-format -msgid "check_instance_lock: admin: |%s|" -msgstr "" - -#: nova/compute/manager.py:82 -#, python-format -msgid "check_instance_lock: executing: |%s|" -msgstr "" - -#: nova/compute/manager.py:86 -#, python-format -msgid "check_instance_lock: not executing |%s|" -msgstr "" - -#: nova/compute/manager.py:157 -msgid "Instance has already been created" -msgstr "" - -#: nova/compute/manager.py:158 -#, python-format -msgid "instance %s: starting..." -msgstr "" - -#: nova/compute/manager.py:197 -#, python-format -msgid "instance %s: Failed to spawn" -msgstr "" - -#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 -#, python-format -msgid "Terminating instance %s" -msgstr "" - -#: nova/compute/manager.py:217 -#, python-format -msgid "Disassociating address %s" -msgstr "" - -#: nova/compute/manager.py:230 -#, python-format -msgid "Deallocating address %s" -msgstr "" - -#: nova/compute/manager.py:243 -#, python-format -msgid "trying to destroy already destroyed instance: %s" -msgstr "" - -#: nova/compute/manager.py:257 -#, python-format -msgid "Rebooting instance %s" -msgstr "" - -#: nova/compute/manager.py:260 -#, python-format -msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" -msgstr "" - -#: nova/compute/manager.py:286 -#, python-format -msgid "instance %s: snapshotting" -msgstr "" - -#: nova/compute/manager.py:289 -#, python-format -msgid "trying to snapshot a non-running instance: %s (state: %s excepted: %s)" -msgstr "" - -#: nova/compute/manager.py:301 -#, python-format -msgid "instance %s: rescuing" -msgstr "" - -#: nova/compute/manager.py:316 -#, python-format -msgid "instance %s: unrescuing" -msgstr "" - -#: nova/compute/manager.py:335 -#, python-format -msgid "instance %s: pausing" -msgstr "" - -#: nova/compute/manager.py:352 -#, python-format -msgid "instance %s: unpausing" -msgstr "" - -#: nova/compute/manager.py:369 -#, python-format -msgid "instance %s: retrieving diagnostics" -msgstr "" - -#: nova/compute/manager.py:382 -#, python-format -msgid "instance %s: suspending" -msgstr "" - -#: nova/compute/manager.py:401 -#, python-format -msgid "instance %s: resuming" -msgstr "" - -#: nova/compute/manager.py:420 -#, python-format -msgid "instance %s: locking" -msgstr "" - -#: nova/compute/manager.py:432 -#, python-format -msgid "instance %s: unlocking" -msgstr "" - -#: nova/compute/manager.py:442 -#, python-format -msgid "instance %s: getting locked state" -msgstr "" - -#: nova/compute/manager.py:462 -#, python-format -msgid "instance %s: attaching volume %s to %s" -msgstr "" - -#: nova/compute/manager.py:478 -#, python-format -msgid "instance %s: attach failed %s, removing" -msgstr "" - -#: nova/compute/manager.py:493 -#, python-format -msgid "Detach volume %s from mountpoint %s on instance %s" -msgstr "" - -#: nova/compute/manager.py:497 -#, python-format -msgid "Detaching volume from unknown instance %s" -msgstr "" - -#: nova/compute/monitor.py:259 -#, python-format -msgid "updating %s..." -msgstr "" - -#: nova/compute/monitor.py:289 -msgid "unexpected error during update" -msgstr "" - -#: nova/compute/monitor.py:355 -#, python-format -msgid "Cannot get blockstats for \"%s\" on \"%s\"" -msgstr "" - -#: nova/compute/monitor.py:377 -#, python-format -msgid "Cannot get ifstats for \"%s\" on \"%s\"" -msgstr "" - -#: nova/compute/monitor.py:412 -msgid "unexpected exception getting connection" -msgstr "" - -#: nova/compute/monitor.py:427 -#, python-format -msgid "Found instance: %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:43 -msgid "Use of empty request context is deprecated" -msgstr "" - -#: nova/db/sqlalchemy/api.py:132 -#, python-format -msgid "No service for id %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:229 -#, python-format -msgid "No service for %s, %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:574 -#, python-format -msgid "No floating ip for address %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:668 -#, python-format -msgid "No instance for id %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:758 nova/virt/libvirt_conn.py:598 -#: nova/virt/xenapi/volumeops.py:48 nova/virt/xenapi/volumeops.py:103 -#, python-format -msgid "Instance %s not found" -msgstr "" - -#: nova/db/sqlalchemy/api.py:891 -#, python-format -msgid "no keypair for user %s, name %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 -#, python-format -msgid "No network for id %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1036 -#, python-format -msgid "No network for bridge %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1050 -#, python-format -msgid "No network for instance %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1180 -#, python-format -msgid "Token %s does not exist" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1205 -#, python-format -msgid "No quota for project_id %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1356 -#, python-format -msgid "No volume for id %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1401 -#, python-format -msgid "Volume %s not found" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1413 -#, python-format -msgid "No export device found for volume %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1426 -#, python-format -msgid "No target id found for volume %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1471 -#, python-format -msgid "No security group with id %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1488 -#, python-format -msgid "No security group named %s for project: %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1576 -#, python-format -msgid "No secuity group rule with id %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1650 -#, python-format -msgid "No user for id %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1666 -#, python-format -msgid "No user for access key %s" -msgstr "" - -#: nova/db/sqlalchemy/api.py:1728 -#, python-format -msgid "No project with id %s" -msgstr "" - -#: nova/image/glance.py:78 -#, python-format -msgid "Parallax returned HTTP error %d from request for /images" -msgstr "" - -#: nova/image/glance.py:97 -#, python-format -msgid "Parallax returned HTTP error %d from request for /images/detail" -msgstr "" - -#: nova/image/s3.py:82 -#, python-format -msgid "Image %s could not be found" -msgstr "" - -#: nova/network/api.py:39 -#, python-format -msgid "Quota exceeeded for %s, tried to allocate address" -msgstr "" - -#: nova/network/api.py:42 -msgid "Address quota exceeded. You cannot allocate any more addresses" -msgstr "" - -#: nova/network/linux_net.py:176 -#, python-format -msgid "Starting VLAN inteface %s" -msgstr "" - -#: nova/network/linux_net.py:186 -#, python-format -msgid "Starting Bridge interface for %s" -msgstr "" - -#: nova/network/linux_net.py:254 -#, python-format -msgid "Hupping dnsmasq threw %s" -msgstr "" - -#: nova/network/linux_net.py:256 -#, python-format -msgid "Pid %d is stale, relaunching dnsmasq" -msgstr "" - -#: nova/network/linux_net.py:334 -#, python-format -msgid "Killing dnsmasq threw %s" -msgstr "" - -#: nova/network/manager.py:135 -msgid "setting network host" -msgstr "" - -#: nova/network/manager.py:190 -#, python-format -msgid "Leasing IP %s" -msgstr "" - -#: nova/network/manager.py:194 -#, python-format -msgid "IP %s leased that isn't associated" -msgstr "" - -#: nova/network/manager.py:197 -#, python-format -msgid "IP %s leased to bad mac %s vs %s" -msgstr "" - -#: nova/network/manager.py:205 -#, python-format -msgid "IP %s leased that was already deallocated" -msgstr "" - -#: nova/network/manager.py:214 -#, python-format -msgid "IP %s released that isn't associated" -msgstr "" - -#: nova/network/manager.py:217 -#, python-format -msgid "IP %s released from bad mac %s vs %s" -msgstr "" - -#: nova/network/manager.py:220 -#, python-format -msgid "IP %s released that was not leased" -msgstr "" - -#: nova/network/manager.py:442 -#, python-format -msgid "Dissassociated %s stale fixed ip(s)" -msgstr "" - -#: nova/objectstore/handler.py:106 -#, python-format -msgid "Unknown S3 value type %r" -msgstr "" - -#: nova/objectstore/handler.py:137 -msgid "Authenticated request" -msgstr "" - -#: nova/objectstore/handler.py:182 -msgid "List of buckets requested" -msgstr "" - -#: nova/objectstore/handler.py:209 -#, python-format -msgid "List keys for bucket %s" -msgstr "" - -#: nova/objectstore/handler.py:217 -#, python-format -msgid "Unauthorized attempt to access bucket %s" -msgstr "" - -#: nova/objectstore/handler.py:235 -#, python-format -msgid "Creating bucket %s" -msgstr "" - -#: nova/objectstore/handler.py:245 -#, python-format -msgid "Deleting bucket %s" -msgstr "" - -#: nova/objectstore/handler.py:249 -#, python-format -msgid "Unauthorized attempt to delete bucket %s" -msgstr "" - -#: nova/objectstore/handler.py:271 -#, python-format -msgid "Getting object: %s / %s" -msgstr "" - -#: nova/objectstore/handler.py:274 -#, python-format -msgid "Unauthorized attempt to get object %s from bucket %s" -msgstr "" - -#: nova/objectstore/handler.py:292 -#, python-format -msgid "Putting object: %s / %s" -msgstr "" - -#: nova/objectstore/handler.py:295 -#, python-format -msgid "Unauthorized attempt to upload object %s to bucket %s" -msgstr "" - -#: nova/objectstore/handler.py:314 -#, python-format -msgid "Deleting object: %s / %s" -msgstr "" - -#: nova/objectstore/handler.py:393 -#, python-format -msgid "Not authorized to upload image: invalid directory %s" -msgstr "" - -#: nova/objectstore/handler.py:401 -#, python-format -msgid "Not authorized to upload image: unauthorized bucket %s" -msgstr "" - -#: nova/objectstore/handler.py:406 -#, python-format -msgid "Starting image upload: %s" -msgstr "" - -#: nova/objectstore/handler.py:420 -#, python-format -msgid "Not authorized to update attributes of image %s" -msgstr "" - -#: nova/objectstore/handler.py:428 -#, python-format -msgid "Toggling publicity flag of image %s %r" -msgstr "" - -#: nova/objectstore/handler.py:433 -#, python-format -msgid "Updating user fields on image %s" -msgstr "" - -#: nova/objectstore/handler.py:447 -#, python-format -msgid "Unauthorized attempt to delete image %s" -msgstr "" - -#: nova/objectstore/handler.py:452 -#, python-format -msgid "Deleted image: %s" -msgstr "" - -#: nova/scheduler/chance.py:37 nova/scheduler/simple.py:73 -#: nova/scheduler/simple.py:106 nova/scheduler/simple.py:118 -msgid "No hosts found" -msgstr "" - -#: nova/scheduler/driver.py:66 -msgid "Must implement a fallback schedule" -msgstr "" - -#: nova/scheduler/manager.py:69 -#, python-format -msgid "Casting to %s %s for %s" -msgstr "" - -#: nova/scheduler/simple.py:63 -msgid "All hosts have too many cores" -msgstr "" - -#: nova/scheduler/simple.py:95 -msgid "All hosts have too many gigabytes" -msgstr "" - -#: nova/scheduler/simple.py:115 -msgid "All hosts have too many networks" -msgstr "" - -#: nova/tests/test_cloud.py:198 -msgid "Can't test instances without a real virtual env." -msgstr "" - -#: nova/tests/test_cloud.py:210 -#, python-format -msgid "Need to watch instance %s until it's running..." -msgstr "" - -#: nova/tests/test_compute.py:104 -#, python-format -msgid "Running instances: %s" -msgstr "" - -#: nova/tests/test_compute.py:110 -#, python-format -msgid "After terminating instances: %s" -msgstr "" - -#: nova/tests/test_rpc.py:89 -#, python-format -msgid "Nested received %s, %s" -msgstr "" - -#: nova/tests/test_rpc.py:94 -#, python-format -msgid "Nested return %s" -msgstr "" - -#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 -#, python-format -msgid "Received %s" -msgstr "" - -#: nova/tests/test_volume.py:162 -#, python-format -msgid "Target %s allocated" -msgstr "" - -#: nova/virt/connection.py:73 -msgid "Failed to open connection to the hypervisor" -msgstr "" - -#: nova/virt/fake.py:210 -#, python-format -msgid "Instance %s Not Found" -msgstr "" - -#: nova/virt/hyperv.py:118 -msgid "In init host" -msgstr "" - -#: nova/virt/hyperv.py:131 -#, python-format -msgid "Attempt to create duplicate vm %s" -msgstr "" - -#: nova/virt/hyperv.py:148 -#, python-format -msgid "Starting VM %s " -msgstr "" - -#: nova/virt/hyperv.py:150 -#, python-format -msgid "Started VM %s " -msgstr "" - -#: nova/virt/hyperv.py:152 -#, python-format -msgid "spawn vm failed: %s" -msgstr "" - -#: nova/virt/hyperv.py:169 -#, python-format -msgid "Failed to create VM %s" -msgstr "" - -#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 -#, python-format -msgid "Created VM %s..." -msgstr "" - -#: nova/virt/hyperv.py:188 -#, python-format -msgid "Set memory for vm %s..." -msgstr "" - -#: nova/virt/hyperv.py:198 -#, python-format -msgid "Set vcpus for vm %s..." -msgstr "" - -#: nova/virt/hyperv.py:202 -#, python-format -msgid "Creating disk for %s by attaching disk file %s" -msgstr "" - -#: nova/virt/hyperv.py:227 -#, python-format -msgid "Failed to add diskdrive to VM %s" -msgstr "" - -#: nova/virt/hyperv.py:230 -#, python-format -msgid "New disk drive path is %s" -msgstr "" - -#: nova/virt/hyperv.py:247 -#, python-format -msgid "Failed to add vhd file to VM %s" -msgstr "" - -#: nova/virt/hyperv.py:249 -#, python-format -msgid "Created disk for %s" -msgstr "" - -#: nova/virt/hyperv.py:253 -#, python-format -msgid "Creating nic for %s " -msgstr "" - -#: nova/virt/hyperv.py:272 -msgid "Failed creating a port on the external vswitch" -msgstr "" - -#: nova/virt/hyperv.py:273 -#, python-format -msgid "Failed creating port for %s" -msgstr "" - -#: nova/virt/hyperv.py:275 -#, python-format -msgid "Created switch port %s on switch %s" -msgstr "" - -#: nova/virt/hyperv.py:285 -#, python-format -msgid "Failed to add nic to VM %s" -msgstr "" - -#: nova/virt/hyperv.py:287 -#, python-format -msgid "Created nic for %s " -msgstr "" - -#: nova/virt/hyperv.py:320 -#, python-format -msgid "WMI job failed: %s" -msgstr "" - -#: nova/virt/hyperv.py:322 -#, python-format -msgid "WMI job succeeded: %s, Elapsed=%s " -msgstr "" - -#: nova/virt/hyperv.py:358 -#, python-format -msgid "Got request to destroy vm %s" -msgstr "" - -#: nova/virt/hyperv.py:383 -#, python-format -msgid "Failed to destroy vm %s" -msgstr "" - -#: nova/virt/hyperv.py:389 -#, python-format -msgid "Del: disk %s vm %s" -msgstr "" - -#: nova/virt/hyperv.py:405 -#, python-format -msgid "" -"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " -"cpu_time=%s" -msgstr "" - -#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 -#, python-format -msgid "duplicate name found: %s" -msgstr "" - -#: nova/virt/hyperv.py:444 -#, python-format -msgid "Successfully changed vm state of %s to %s" -msgstr "" - -#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 -#, python-format -msgid "Failed to change vm state of %s to %s" -msgstr "" - -#: nova/virt/images.py:70 -#, python-format -msgid "Finished retreving %s -- placed in %s" -msgstr "" - -#: nova/virt/libvirt_conn.py:144 -#, python-format -msgid "Connecting to libvirt: %s" -msgstr "" - -#: nova/virt/libvirt_conn.py:157 -msgid "Connection to libvirt broke" -msgstr "" - -#: nova/virt/libvirt_conn.py:229 -#, python-format -msgid "instance %s: deleting instance files %s" -msgstr "" - -#: nova/virt/libvirt_conn.py:271 -#, python-format -msgid "No disk at %s" -msgstr "" - -#: nova/virt/libvirt_conn.py:278 -msgid "Instance snapshotting is not supported for libvirtat this time" -msgstr "" - -#: nova/virt/libvirt_conn.py:294 -#, python-format -msgid "instance %s: rebooted" -msgstr "" - -#: nova/virt/libvirt_conn.py:297 -#, python-format -msgid "_wait_for_reboot failed: %s" -msgstr "" - -#: nova/virt/libvirt_conn.py:340 -#, python-format -msgid "instance %s: rescued" -msgstr "" - -#: nova/virt/libvirt_conn.py:343 -#, python-format -msgid "_wait_for_rescue failed: %s" -msgstr "" - -#: nova/virt/libvirt_conn.py:370 -#, python-format -msgid "instance %s: is running" -msgstr "" - -#: nova/virt/libvirt_conn.py:381 -#, python-format -msgid "instance %s: booted" -msgstr "" - -#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 -#, python-format -msgid "instance %s: failed to boot" -msgstr "" - -#: nova/virt/libvirt_conn.py:395 -#, python-format -msgid "virsh said: %r" -msgstr "" - -#: nova/virt/libvirt_conn.py:399 -msgid "cool, it's a device" -msgstr "" - -#: nova/virt/libvirt_conn.py:407 -#, python-format -msgid "data: %r, fpath: %r" -msgstr "" - -#: nova/virt/libvirt_conn.py:415 -#, python-format -msgid "Contents of file %s: %r" -msgstr "" - -#: nova/virt/libvirt_conn.py:449 -#, python-format -msgid "instance %s: Creating image" -msgstr "" - -#: nova/virt/libvirt_conn.py:505 -#, python-format -msgid "instance %s: injecting key into image %s" -msgstr "" - -#: nova/virt/libvirt_conn.py:508 -#, python-format -msgid "instance %s: injecting net into image %s" -msgstr "" - -#: nova/virt/libvirt_conn.py:516 -#, python-format -msgid "instance %s: ignoring error injecting data into image %s (%s)" -msgstr "" - -#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 -#, python-format -msgid "instance %s: starting toXML method" -msgstr "" - -#: nova/virt/libvirt_conn.py:589 -#, python-format -msgid "instance %s: finished toXML method" -msgstr "" - -#: nova/virt/xenapi_conn.py:113 -msgid "" -"Must specify xenapi_connection_url, xenapi_connection_username " -"(optionally), and xenapi_connection_password to use " -"connection_type=xenapi" -msgstr "" - -#: nova/virt/xenapi_conn.py:263 -#, python-format -msgid "Task [%s] %s status: success %s" -msgstr "" - -#: nova/virt/xenapi_conn.py:271 -#, python-format -msgid "Task [%s] %s status: %s %s" -msgstr "" - -#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 -#, python-format -msgid "Got exception: %s" -msgstr "" - -#: nova/virt/xenapi/fake.py:72 -#, python-format -msgid "%s: _db_content => %s" -msgstr "" - -#: nova/virt/xenapi/fake.py:247 nova/virt/xenapi/fake.py:338 -#: nova/virt/xenapi/fake.py:356 nova/virt/xenapi/fake.py:404 -msgid "Raising NotImplemented" -msgstr "" - -#: nova/virt/xenapi/fake.py:249 -#, python-format -msgid "xenapi.fake does not have an implementation for %s" -msgstr "" - -#: nova/virt/xenapi/fake.py:283 -#, python-format -msgid "Calling %s %s" -msgstr "" - -#: nova/virt/xenapi/fake.py:288 -#, python-format -msgid "Calling getter %s" -msgstr "" - -#: nova/virt/xenapi/fake.py:340 -#, python-format -msgid "" -"xenapi.fake does not have an implementation for %s or it has been called " -"with the wrong number of arguments" -msgstr "" - -#: nova/virt/xenapi/network_utils.py:40 -#, python-format -msgid "Found non-unique network for bridge %s" -msgstr "" - -#: nova/virt/xenapi/network_utils.py:43 -#, python-format -msgid "Found no network for bridge %s" -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:127 -#, python-format -msgid "Created VM %s as %s." -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:147 -#, python-format -msgid "Creating VBD for VM %s, VDI %s ... " -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:149 -#, python-format -msgid "Created VBD %s for VM %s, VDI %s." -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:165 -#, python-format -msgid "VBD not found in instance %s" -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:175 -#, python-format -msgid "Unable to unplug VBD %s" -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:187 -#, python-format -msgid "Unable to destroy VBD %s" -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:202 -#, python-format -msgid "Creating VIF for VM %s, network %s." -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:205 -#, python-format -msgid "Created VIF %s for VM %s, network %s." -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:216 -#, python-format -msgid "Snapshotting VM %s with label '%s'..." -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:229 -#, python-format -msgid "Created snapshot %s from VM %s." -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:243 -#, python-format -msgid "Asking xapi to upload %s as '%s'" -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:261 -#, python-format -msgid "Asking xapi to fetch %s as %s" -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:279 -#, python-format -msgid "Looking up vdi %s for PV kernel" -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:290 -#, python-format -msgid "PV Kernel in VDI:%d" -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:318 -#, python-format -msgid "VDI %s is still available" -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:331 -#, python-format -msgid "(VM_UTILS) xenserver vm state -> |%s|" -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:333 -#, python-format -msgid "(VM_UTILS) xenapi power_state -> |%s|" -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:390 -#, python-format -msgid "VHD %s has parent %s" -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:407 -#, python-format -msgid "Re-scanning SR %s" -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:431 -#, python-format -msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:448 -#, python-format -msgid "No VDIs found for VM %s" -msgstr "" - -#: nova/virt/xenapi/vm_utils.py:452 -#, python-format -msgid "Unexpected number of VDIs (%s) found for VM %s" -msgstr "" - -#: nova/virt/xenapi/vmops.py:62 -#, python-format -msgid "Attempted to create non-unique name %s" -msgstr "" - -#: nova/virt/xenapi/vmops.py:99 -#, python-format -msgid "Starting VM %s..." -msgstr "" - -#: nova/virt/xenapi/vmops.py:101 -#, python-format -msgid "Spawning VM %s created %s." -msgstr "" - -#: nova/virt/xenapi/vmops.py:112 -#, python-format -msgid "Instance %s: booted" -msgstr "" - -#: nova/virt/xenapi/vmops.py:137 -#, python-format -msgid "Instance not present %s" -msgstr "" - -#: nova/virt/xenapi/vmops.py:166 -#, python-format -msgid "Starting snapshot for VM %s" -msgstr "" - -#: nova/virt/xenapi/vmops.py:174 -#, python-format -msgid "Unable to Snapshot %s: %s" -msgstr "" - -#: nova/virt/xenapi/vmops.py:184 -#, python-format -msgid "Finished snapshot and upload for VM %s" -msgstr "" - -#: nova/virt/xenapi/vmops.py:252 -#, python-format -msgid "suspend: instance not present %s" -msgstr "" - -#: nova/virt/xenapi/vmops.py:262 -#, python-format -msgid "resume: instance not present %s" -msgstr "" - -#: nova/virt/xenapi/vmops.py:271 -#, python-format -msgid "Instance not found %s" -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:57 -#, python-format -msgid "Introducing %s..." -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:74 -#, python-format -msgid "Introduced %s as %s." -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:78 -msgid "Unable to create Storage Repository" -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:90 -#, python-format -msgid "Unable to find SR from VBD %s" -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:96 -#, python-format -msgid "Forgetting SR %s ... " -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:101 -#, python-format -msgid "Ignoring exception %s when getting PBDs for %s" -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:107 -#, python-format -msgid "Ignoring exception %s when unplugging PBD %s" -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:111 -#, python-format -msgid "Forgetting SR %s done." -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:113 -#, python-format -msgid "Ignoring exception %s when forgetting SR %s" -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:123 -#, python-format -msgid "Unable to introduce VDI on SR %s" -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:128 -#, python-format -msgid "Unable to get record of VDI %s on" -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:146 -#, python-format -msgid "Unable to introduce VDI for SR %s" -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:175 -#, python-format -msgid "Unable to obtain target information %s, %s" -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:197 -#, python-format -msgid "Mountpoint cannot be translated: %s" -msgstr "" - -#: nova/virt/xenapi/volumeops.py:51 -#, python-format -msgid "Attach_volume: %s, %s, %s" -msgstr "" - -#: nova/virt/xenapi/volumeops.py:69 -#, python-format -msgid "Unable to create VDI on SR %s for instance %s" -msgstr "" - -#: nova/virt/xenapi/volumeops.py:81 -#, python-format -msgid "Unable to use SR %s for instance %s" -msgstr "" - -#: nova/virt/xenapi/volumeops.py:93 -#, python-format -msgid "Unable to attach volume to instance %s" -msgstr "" - -#: nova/virt/xenapi/volumeops.py:95 -#, python-format -msgid "Mountpoint %s attached to instance %s" -msgstr "" - -#: nova/virt/xenapi/volumeops.py:106 -#, python-format -msgid "Detach_volume: %s, %s" -msgstr "" - -#: nova/virt/xenapi/volumeops.py:113 -#, python-format -msgid "Unable to locate volume %s" -msgstr "" - -#: nova/virt/xenapi/volumeops.py:121 -#, python-format -msgid "Unable to detach volume %s" -msgstr "" - -#: nova/virt/xenapi/volumeops.py:128 -#, python-format -msgid "Mountpoint %s detached from instance %s" -msgstr "" - -#: nova/volume/api.py:44 -#, python-format -msgid "Quota exceeeded for %s, tried to create %sG volume" -msgstr "" - -#: nova/volume/api.py:46 -#, python-format -msgid "Volume quota exceeded. You cannot create a volume of size %s" -msgstr "" - -#: nova/volume/api.py:70 nova/volume/api.py:95 -msgid "Volume status must be available" -msgstr "" - -#: nova/volume/api.py:97 -msgid "Volume is already attached" -msgstr "" - -#: nova/volume/api.py:103 -msgid "Volume is already detached" -msgstr "" - -#: nova/volume/driver.py:76 -#, python-format -msgid "Recovering from a failed execute. Try number %s" -msgstr "" - -#: nova/volume/driver.py:85 -#, python-format -msgid "volume group %s doesn't exist" -msgstr "" - -#: nova/volume/driver.py:210 -#, python-format -msgid "FAKE AOE: %s" -msgstr "" - -#: nova/volume/driver.py:315 -#, python-format -msgid "FAKE ISCSI: %s" -msgstr "" - -#: nova/volume/manager.py:85 -#, python-format -msgid "Re-exporting %s volumes" -msgstr "" - -#: nova/volume/manager.py:93 -#, python-format -msgid "volume %s: creating" -msgstr "" - -#: nova/volume/manager.py:102 -#, python-format -msgid "volume %s: creating lv of size %sG" -msgstr "" - -#: nova/volume/manager.py:106 -#, python-format -msgid "volume %s: creating export" -msgstr "" - -#: nova/volume/manager.py:113 -#, python-format -msgid "volume %s: created successfully" -msgstr "" - -#: nova/volume/manager.py:121 -msgid "Volume is still attached" -msgstr "" - -#: nova/volume/manager.py:123 -msgid "Volume is not local to this node" -msgstr "" - -#: nova/volume/manager.py:124 -#, python-format -msgid "volume %s: removing export" -msgstr "" - -#: nova/volume/manager.py:126 -#, python-format -msgid "volume %s: deleting" -msgstr "" - -#: nova/volume/manager.py:129 -#, python-format -msgid "volume %s: deleted successfully" -msgstr "" - diff --git a/po/nova.pot b/po/nova.pot new file mode 100644 index 00000000..576621ce --- /dev/null +++ b/po/nova.pot @@ -0,0 +1,2705 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-02-09 09:26-0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../nova/scheduler/chance.py:37 ../nova/scheduler/simple.py:75 +#: ../nova/scheduler/simple.py:110 ../nova/scheduler/simple.py:122 +#: ../nova/scheduler/zone.py:55 +msgid "No hosts found" +msgstr "" + +#: ../nova/exception.py:33 +msgid "Unexpected error while running command." +msgstr "" + +#: ../nova/exception.py:36 +#, python-format +msgid "" +"%(description)s\n" +"Command: %(cmd)s\n" +"Exit code: %(exit_code)s\n" +"Stdout: %(stdout)r\n" +"Stderr: %(stderr)r" +msgstr "" + +#: ../nova/exception.py:107 +msgid "DB exception wrapped" +msgstr "" + +#. exc_type, exc_value, exc_traceback = sys.exc_info() +#: ../nova/exception.py:120 +msgid "Uncaught exception" +msgstr "" + +#: ../nova/volume/api.py:45 +#, python-format +msgid "Quota exceeeded for %(pid)s, tried to create %(size)sG volume" +msgstr "" + +#: ../nova/volume/api.py:47 +#, python-format +msgid "Volume quota exceeded. You cannot create a volume of size %sG" +msgstr "" + +#: ../nova/volume/api.py:71 ../nova/volume/api.py:96 +msgid "Volume status must be available" +msgstr "" + +#: ../nova/volume/api.py:98 +msgid "Volume is already attached" +msgstr "" + +#: ../nova/volume/api.py:104 +msgid "Volume is already detached" +msgstr "" + +#: ../nova/virt/fake.py:224 +#, python-format +msgid "Instance %s Not Found" +msgstr "" + +#: ../nova/api/openstack/servers.py:138 +#, python-format +msgid "%(param)s property not found for image %(_image_id)s" +msgstr "" + +#: ../nova/api/openstack/servers.py:219 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:234 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:248 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:259 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:270 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:281 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:292 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: ../nova/twistd.py:159 +msgid "Wrong number of arguments." +msgstr "" + +#: ../nova/twistd.py:211 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "" + +#: ../nova/twistd.py:223 +msgid "No such process" +msgstr "" + +#: ../nova/twistd.py:232 ../nova/service.py:224 +#, python-format +msgid "Serving %s" +msgstr "" + +#: ../nova/twistd.py:264 ../nova/service.py:225 +msgid "Full set of FLAGS:" +msgstr "" + +#: ../nova/twistd.py:268 +#, python-format +msgid "Starting %s" +msgstr "" + +#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101 +#: ../nova/db/sqlalchemy/api.py:709 ../nova/virt/libvirt_conn.py:741 +#: ../nova/api/ec2/__init__.py:322 +#, python-format +msgid "Instance %s not found" +msgstr "" + +#. NOTE: No Resource Pool concept so far +#: ../nova/virt/xenapi/volumeops.py:51 +#, python-format +msgid "Attach_volume: %(instance_name)s, %(device_path)s, %(mountpoint)s" +msgstr "" + +#: ../nova/virt/xenapi/volumeops.py:69 +#, python-format +msgid "Unable to create VDI on SR %(sr_ref)s for instance %(instance_name)s" +msgstr "" + +#: ../nova/virt/xenapi/volumeops.py:80 +#, python-format +msgid "Unable to use SR %(sr_ref)s for instance %(instance_name)s" +msgstr "" + +#: ../nova/virt/xenapi/volumeops.py:91 +#, python-format +msgid "Unable to attach volume to instance %s" +msgstr "" + +#: ../nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Mountpoint %(mountpoint)s attached to instance %(instance_name)s" +msgstr "" + +#. Detach VBD from VM +#: ../nova/virt/xenapi/volumeops.py:104 +#, python-format +msgid "Detach_volume: %(instance_name)s, %(mountpoint)s" +msgstr "" + +#: ../nova/virt/xenapi/volumeops.py:112 +#, python-format +msgid "Unable to locate volume %s" +msgstr "" + +#: ../nova/virt/xenapi/volumeops.py:120 +#, python-format +msgid "Unable to detach volume %s" +msgstr "" + +#: ../nova/virt/xenapi/volumeops.py:127 +#, python-format +msgid "Mountpoint %(mountpoint)s detached from instance %(instance_name)s" +msgstr "" + +#: ../nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "" + +#: ../nova/crypto.py:46 +msgid "Filename of root CA" +msgstr "" + +#: ../nova/crypto.py:49 +msgid "Filename of private key" +msgstr "" + +#: ../nova/crypto.py:51 +msgid "Filename of root Certificate Revokation List" +msgstr "" + +#: ../nova/crypto.py:53 +msgid "Where we keep our keys" +msgstr "" + +#: ../nova/crypto.py:55 +msgid "Where we keep our root CA" +msgstr "" + +#: ../nova/crypto.py:57 +msgid "Should we use a CA for each project?" +msgstr "" + +#: ../nova/crypto.py:61 +#, python-format +msgid "Subject for certificate for users, %s for project, user, timestamp" +msgstr "" + +#: ../nova/crypto.py:66 +#, python-format +msgid "Subject for certificate for projects, %s for project, timestamp" +msgstr "" + +#: ../nova/crypto.py:71 +#, python-format +msgid "Subject for certificate for vpns, %s for project, timestamp" +msgstr "" + +#: ../nova/crypto.py:258 +#, python-format +msgid "Flags path: %s" +msgstr "" + +#: ../nova/scheduler/manager.py:69 +#, python-format +msgid "Casting to %(topic)s %(host)s for %(method)s" +msgstr "" + +#: ../nova/compute/manager.py:77 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:79 +#, python-format +msgid "" +"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|" +msgstr "" + +#: ../nova/compute/manager.py:83 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:85 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:90 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:94 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: ../nova/compute/manager.py:177 +msgid "Instance has already been created" +msgstr "" + +#: ../nova/compute/manager.py:178 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#. pylint: disable-msg=W0702 +#: ../nova/compute/manager.py:217 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: ../nova/compute/manager.py:231 ../nova/tests/test_cloud.py:286 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: ../nova/compute/manager.py:253 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: ../nova/compute/manager.py:266 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: ../nova/compute/manager.py:280 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: ../nova/compute/manager.py:285 +#, python-format +msgid "" +"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:309 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: ../nova/compute/manager.py:314 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:355 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: ../nova/compute/manager.py:370 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: ../nova/compute/manager.py:389 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: ../nova/compute/manager.py:406 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: ../nova/compute/manager.py:423 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: ../nova/compute/manager.py:436 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: ../nova/compute/manager.py:455 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: ../nova/compute/manager.py:474 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: ../nova/compute/manager.py:486 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: ../nova/compute/manager.py:496 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: ../nova/compute/manager.py:506 ../nova/api/ec2/cloud.py:513 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: ../nova/compute/manager.py:514 +#, python-format +msgid "instance %s: getting ajax console" +msgstr "" + +#: ../nova/compute/manager.py:524 +#, python-format +msgid "" +"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s" +msgstr "" + +#. pylint: disable-msg=W0702 +#. NOTE(vish): The inline callback eats the exception info so we +#. log the traceback here and reraise the same +#. ecxception below. +#: ../nova/compute/manager.py:540 +#, python-format +msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing" +msgstr "" + +#: ../nova/compute/manager.py:556 +#, python-format +msgid "" +"Detach volume %(volume_id)s from mountpoint %(mp)s on instance " +"%(instance_id)s" +msgstr "" + +#: ../nova/compute/manager.py:559 +#, python-format +msgid "Detaching volume from unknown instance %s" +msgstr "" + +#: ../nova/scheduler/simple.py:53 +#, python-format +msgid "Host %s is not alive" +msgstr "" + +#: ../nova/scheduler/simple.py:65 +msgid "All hosts have too many cores" +msgstr "" + +#: ../nova/scheduler/simple.py:87 +#, python-format +msgid "Host %s not available" +msgstr "" + +#: ../nova/scheduler/simple.py:99 +msgid "All hosts have too many gigabytes" +msgstr "" + +#: ../nova/scheduler/simple.py:119 +msgid "All hosts have too many networks" +msgstr "" + +#: ../nova/volume/manager.py:85 +#, python-format +msgid "Re-exporting %s volumes" +msgstr "" + +#: ../nova/volume/manager.py:90 +#, python-format +msgid "volume %s: skipping export" +msgstr "" + +#: ../nova/volume/manager.py:96 +#, python-format +msgid "volume %s: creating" +msgstr "" + +#: ../nova/volume/manager.py:108 +#, python-format +msgid "volume %(vol_name)s: creating lv of size %(vol_size)sG" +msgstr "" + +#: ../nova/volume/manager.py:112 +#, python-format +msgid "volume %s: creating export" +msgstr "" + +#: ../nova/volume/manager.py:123 +#, python-format +msgid "volume %s: created successfully" +msgstr "" + +#: ../nova/volume/manager.py:131 +msgid "Volume is still attached" +msgstr "" + +#: ../nova/volume/manager.py:133 +msgid "Volume is not local to this node" +msgstr "" + +#: ../nova/volume/manager.py:136 +#, python-format +msgid "volume %s: removing export" +msgstr "" + +#: ../nova/volume/manager.py:138 +#, python-format +msgid "volume %s: deleting" +msgstr "" + +#: ../nova/volume/manager.py:147 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:74 +#, python-format +msgid "%(text)s: _db_content => %(content)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:300 ../nova/virt/xenapi/fake.py:400 +#: ../nova/virt/xenapi/fake.py:418 ../nova/virt/xenapi/fake.py:474 +msgid "Raising NotImplemented" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:302 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:337 +#, python-format +msgid "Calling %(localname)s %(impl)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:342 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:402 +#, python-format +msgid "" +"xenapi.fake does not have an implementation for %s or it has been called " +"with the wrong number of arguments" +msgstr "" + +#: ../nova/tests/test_cloud.py:256 +msgid "Can't test instances without a real virtual env." +msgstr "" + +#: ../nova/tests/test_cloud.py:268 +#, python-format +msgid "Need to watch instance %s until it's running..." +msgstr "" + +#: ../nova/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "" + +#: ../nova/network/linux_net.py:181 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: ../nova/network/linux_net.py:202 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#. pylint: disable-msg=W0703 +#: ../nova/network/linux_net.py:308 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:310 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#. pylint: disable-msg=W0703 +#: ../nova/network/linux_net.py:352 +#, python-format +msgid "killing radvd threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:354 +#, python-format +msgid "Pid %d is stale, relaunching radvd" +msgstr "" + +#. pylint: disable-msg=W0703 +#: ../nova/network/linux_net.py:443 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: ../nova/utils.py:56 +#, python-format +msgid "Inner Exception: %s" +msgstr "" + +#: ../nova/utils.py:57 +#, python-format +msgid "Class %s cannot be found" +msgstr "" + +#: ../nova/utils.py:116 +#, python-format +msgid "Fetching %s" +msgstr "" + +#: ../nova/utils.py:128 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "" + +#: ../nova/utils.py:141 +#, python-format +msgid "Result was %s" +msgstr "" + +#: ../nova/utils.py:179 +#, python-format +msgid "debug in callback: %s" +msgstr "" + +#: ../nova/utils.py:184 +#, python-format +msgid "Running %s" +msgstr "" + +#: ../nova/utils.py:215 +#, python-format +msgid "Link Local address is not found.:%s" +msgstr "" + +#: ../nova/utils.py:218 +#, python-format +msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s" +msgstr "" + +#: ../nova/utils.py:316 +#, python-format +msgid "Invalid backend: %s" +msgstr "" + +#: ../nova/utils.py:327 +#, python-format +msgid "backend %s" +msgstr "" + +#: ../nova/fakerabbit.py:49 +#, python-format +msgid "(%(nm)s) publish (key: %(routing_key)s) %(message)s" +msgstr "" + +#: ../nova/fakerabbit.py:54 +#, python-format +msgid "Publishing to route %s" +msgstr "" + +#: ../nova/fakerabbit.py:84 +#, python-format +msgid "Declaring queue %s" +msgstr "" + +#: ../nova/fakerabbit.py:90 +#, python-format +msgid "Declaring exchange %s" +msgstr "" + +#: ../nova/fakerabbit.py:96 +#, python-format +msgid "Binding %(queue)s to %(exchange)s with key %(routing_key)s" +msgstr "" + +#: ../nova/fakerabbit.py:121 +#, python-format +msgid "Getting from %(queue)s: %(message)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:135 ../nova/virt/hyperv.py:171 +#, python-format +msgid "Created VM %s..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:138 +#, python-format +msgid "Created VM %(instance_name)s as %(vm_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:158 +#, python-format +msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:161 +#, python-format +msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:177 +#, python-format +msgid "VBD not found in instance %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:199 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:214 +#, python-format +msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:217 +#, python-format +msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:236 +#, python-format +msgid "" +"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on " +"%(sr_ref)s." +msgstr "" + +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vm_utils.py:248 +#, python-format +msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:262 +#, python-format +msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:276 +#, python-format +msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:317 +#, python-format +msgid "Size for image %(image)s:%(virtual_size)d" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:322 +#, python-format +msgid "Glance image %s" +msgstr "" + +#. we need to invoke a plugin for copying VDI's +#. content into proper path +#: ../nova/virt/xenapi/vm_utils.py:332 +#, python-format +msgid "Copying VDI %s to /boot/guest on dom0" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:342 +#, python-format +msgid "Kernel/Ramdisk VDI %s destroyed" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:351 +#, python-format +msgid "Asking xapi to fetch %(url)s as %(access)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:376 ../nova/virt/xenapi/vm_utils.py:392 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:387 +#, python-format +msgid "PV Kernel in VDI:%d" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:395 +#, python-format +msgid "Running pygrub against %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:401 +#, python-format +msgid "Found Xen kernel %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:403 +msgid "No Xen kernel found. Booting HVM." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:415 ../nova/virt/hyperv.py:431 +#, python-format +msgid "duplicate name found: %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:432 +#, python-format +msgid "VDI %s is still available" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:445 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:447 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:507 +#, python-format +msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:524 +#, python-format +msgid "Re-scanning SR %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:549 +#, python-format +msgid "" +"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:556 +#, python-format +msgid "" +"Parent %(parent_uuid)s doesn't match original parent " +"%(original_parent_uuid)s, waiting for coalesce..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:572 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:576 +#, python-format +msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:635 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188 +#, python-format +msgid "Creating VBD for VDI %s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:637 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190 +#, python-format +msgid "Creating VBD for VDI %s done." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:639 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192 +#, python-format +msgid "Plugging VBD %s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:641 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:194 +#, python-format +msgid "Plugging VBD %s done." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:643 +#, python-format +msgid "VBD %(vbd)s plugged as %(orig_dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:646 +#, python-format +msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:650 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:197 +#, python-format +msgid "Destroying VBD for VDI %s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:653 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:200 +#, python-format +msgid "Destroying VBD for VDI %s done." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:665 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211 +msgid "VBD.unplug successful first time." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:670 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216 +msgid "VBD.unplug rejected: retrying..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:674 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220 +msgid "VBD.unplug successful eventually." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:677 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:223 +#, python-format +msgid "Ignoring XenAPI.Failure in VBD.unplug: %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:686 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:66 +#, python-format +msgid "Ignoring XenAPI.Failure %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:717 +#, python-format +msgid "" +"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:729 +#, python-format +msgid "Writing partition table %s done." +msgstr "" + +#: ../nova/tests/test_rpc.py:89 +#, python-format +msgid "Nested received %(queue)s, %(value)s" +msgstr "" + +#: ../nova/tests/test_rpc.py:95 +#, python-format +msgid "Nested return %s" +msgstr "" + +#: ../nova/tests/test_rpc.py:120 ../nova/tests/test_rpc.py:126 +#, python-format +msgid "Received %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:44 +msgid "Use of empty request context is deprecated" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:133 +#, python-format +msgid "No service for id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:251 +#, python-format +msgid "No service for %(host)s, %(binary)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:597 +#, python-format +msgid "No floating ip for address %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:933 +#, python-format +msgid "no keypair for user %(user_id)s, name %(name)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1048 ../nova/db/sqlalchemy/api.py:1106 +#, python-format +msgid "No network for id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1078 +#, python-format +msgid "No network for bridge %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1092 +#, python-format +msgid "No network for instance %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1227 +#, python-format +msgid "Token %s does not exist" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1252 +#, python-format +msgid "No quota for project_id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1405 ../nova/db/sqlalchemy/api.py:1451 +#: ../nova/api/ec2/__init__.py:328 +#, python-format +msgid "Volume %s not found" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1464 +#, python-format +msgid "No export device found for volume %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1477 +#, python-format +msgid "No target id found for volume %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1522 +#, python-format +msgid "No security group with id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1539 +#, python-format +msgid "No security group named %(group_name)s for project: %(project_id)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1632 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1706 +#, python-format +msgid "No user for id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1722 +#, python-format +msgid "No user for access key %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1784 +#, python-format +msgid "No project with id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1929 +#, python-format +msgid "No console pool with id %(pool_id)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1946 +#, python-format +msgid "" +"No console pool of type %(console_type)s for compute host %(compute_host)s " +"on proxy host %(host)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1985 +#, python-format +msgid "No console for instance %(instance_id)s in pool %(pool_id)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:2007 +#, python-format +msgid "on instance %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:2008 +#, python-format +msgid "No console with id %(console_id)s %(idesc)s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:160 +#, python-format +msgid "Checking state of %s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:165 +#, python-format +msgid "Current state of %(name)s was %(state)s." +msgstr "" + +#: ../nova/virt/libvirt_conn.py:183 +#, python-format +msgid "Connecting to libvirt: %s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:196 +msgid "Connection to libvirt broke" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:258 +#, python-format +msgid "instance %(instance_name)s: deleting instance files %(target)s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:283 +#, python-format +msgid "Invalid device path %s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:313 +#, python-format +msgid "No disk at %s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:320 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:336 +#, python-format +msgid "instance %s: rebooted" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:339 +#, python-format +msgid "_wait_for_reboot failed: %s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:382 +#, python-format +msgid "instance %s: rescued" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:385 +#, python-format +msgid "_wait_for_rescue failed: %s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:411 +#, python-format +msgid "instance %s: is running" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:422 +#, python-format +msgid "instance %s: booted" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:124 +#, python-format +msgid "instance %s: failed to boot" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:436 +#, python-format +msgid "virsh said: %r" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:440 +msgid "cool, it's a device" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:448 +#, python-format +msgid "data: %(data)r, fpath: %(fpath)r" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:456 +#, python-format +msgid "Contents of file %(fpath)s: %(contents)r" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:489 +msgid "Unable to find an open port" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:563 +#, python-format +msgid "instance %s: Creating image" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:646 +#, python-format +msgid "instance %(inst_name)s: injecting key into image %(img_id)s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:649 +#, python-format +msgid "instance %(inst_name)s: injecting net into image %(img_id)s" +msgstr "" + +#. This could be a windows image, or a vmdk format disk +#: ../nova/virt/libvirt_conn.py:657 +#, python-format +msgid "" +"instance %(inst_name)s: ignoring error injecting data into image %(img_id)s " +"(%(e)s)" +msgstr "" + +#. TODO(termie): cache? +#: ../nova/virt/libvirt_conn.py:665 +#, python-format +msgid "instance %s: starting toXML method" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:732 +#, python-format +msgid "instance %s: finished toXML method" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:751 +msgid "diagnostics are not supported for libvirt" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:1225 +#, python-format +msgid "Attempted to unfilter instance %s which is not filtered" +msgstr "" + +#: ../nova/api/ec2/metadatarequesthandler.py:76 +#, python-format +msgid "Failed to get metadata for ip: %s" +msgstr "" + +#: ../nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "" + +#: ../nova/network/api.py:39 +#, python-format +msgid "Quota exceeeded for %s, tried to allocate address" +msgstr "" + +#: ../nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" +msgstr "" + +#: ../nova/tests/test_volume.py:162 +#, python-format +msgid "Target %s allocated" +msgstr "" + +#: ../nova/virt/images.py:70 +#, python-format +msgid "Finished retreving %(url)s -- placed in %(path)s" +msgstr "" + +#: ../nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "" + +#: ../nova/console/manager.py:70 +msgid "Adding console" +msgstr "" + +#: ../nova/console/manager.py:90 +#, python-format +msgid "Tried to remove non-existant console %(console_id)s." +msgstr "" + +#: ../nova/api/direct.py:149 +msgid "not available" +msgstr "" + +#: ../nova/api/ec2/cloud.py:62 +#, python-format +msgid "The key_pair %s already exists" +msgstr "" + +#. TODO(vish): Do this with M2Crypto instead +#: ../nova/api/ec2/cloud.py:118 +#, python-format +msgid "Generating root CA: %s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:303 +#, python-format +msgid "Create key pair %s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:311 +#, python-format +msgid "Delete key pair %s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:384 +#, python-format +msgid "%s is not a valid ipProtocol" +msgstr "" + +#: ../nova/api/ec2/cloud.py:388 +msgid "Invalid port range" +msgstr "" + +#: ../nova/api/ec2/cloud.py:419 +#, python-format +msgid "Revoke security group ingress %s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:428 ../nova/api/ec2/cloud.py:457 +msgid "Not enough parameters to build a valid rule." +msgstr "" + +#: ../nova/api/ec2/cloud.py:441 +msgid "No rule for the specified parameters." +msgstr "" + +#: ../nova/api/ec2/cloud.py:448 +#, python-format +msgid "Authorize security group ingress %s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:462 +#, python-format +msgid "This rule already exists in group %s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:490 +#, python-format +msgid "Create Security Group %s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:493 +#, python-format +msgid "group %s already exists" +msgstr "" + +#: ../nova/api/ec2/cloud.py:505 +#, python-format +msgid "Delete security group %s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:582 +#, python-format +msgid "Create volume of %s GB" +msgstr "" + +#: ../nova/api/ec2/cloud.py:610 +#, python-format +msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:627 +#, python-format +msgid "Detach volume %s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:759 +msgid "Allocate address" +msgstr "" + +#: ../nova/api/ec2/cloud.py:764 +#, python-format +msgid "Release address %s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:769 +#, python-format +msgid "Associate address %(public_ip)s to instance %(instance_id)s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:778 +#, python-format +msgid "Disassociate address %s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:805 +msgid "Going to start terminating instances" +msgstr "" + +#: ../nova/api/ec2/cloud.py:813 +#, python-format +msgid "Reboot instance %r" +msgstr "" + +#: ../nova/api/ec2/cloud.py:850 +#, python-format +msgid "De-registering image %s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:858 +#, python-format +msgid "Registered image %(image_location)s with id %(image_id)s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:865 ../nova/api/ec2/cloud.py:880 +#, python-format +msgid "attribute not supported: %s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:870 +#, python-format +msgid "invalid id: %s" +msgstr "" + +#: ../nova/api/ec2/cloud.py:883 +msgid "user or group not specified" +msgstr "" + +#: ../nova/api/ec2/cloud.py:885 +msgid "only group \"all\" is supported" +msgstr "" + +#: ../nova/api/ec2/cloud.py:887 +msgid "operation_type must be add or remove" +msgstr "" + +#: ../nova/api/ec2/cloud.py:888 +#, python-format +msgid "Updating image %s publicity" +msgstr "" + +#: ../bin/nova-api.py:52 +#, python-format +msgid "Using paste.deploy config at: %s" +msgstr "" + +#: ../bin/nova-api.py:57 +#, python-format +msgid "No paste configuration for app: %s" +msgstr "" + +#: ../bin/nova-api.py:59 +#, python-format +msgid "" +"App Config: %(api)s\n" +"%(config)r" +msgstr "" + +#: ../bin/nova-api.py:64 +#, python-format +msgid "Running %s API" +msgstr "" + +#: ../bin/nova-api.py:69 +#, python-format +msgid "No known API applications configured in %s." +msgstr "" + +#: ../bin/nova-api.py:83 +#, python-format +msgid "Starting nova-api node (version %s)" +msgstr "" + +#: ../bin/nova-api.py:89 +#, python-format +msgid "No paste configuration found for: %s" +msgstr "" + +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84 +#, python-format +msgid "Argument %(key)s value %(value)s is too short." +msgstr "" + +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89 +#, python-format +msgid "Argument %(key)s value %(value)s contains invalid characters." +msgstr "" + +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94 +#, python-format +msgid "Argument %(key)s value %(value)s starts with a hyphen." +msgstr "" + +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:102 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:130 +#, python-format +msgid "Argument %s is required." +msgstr "" + +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117 +#, python-format +msgid "" +"Argument %(key)s may not take value %(value)s. Valid values are ['true', " +"'false']." +msgstr "" + +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:163 +#, python-format +msgid "" +"Created VDI %(vdi_ref)s (%(label)s, %(size)s, %(read_only)s) on %(sr_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:67 +#, python-format +msgid "Attempted to create non-unique name %s" +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:105 +#, python-format +msgid "Starting VM %s..." +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:108 +#, python-format +msgid "Spawning VM %(instance_name)s created %(vm_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:120 +#, python-format +msgid "Instance %s: booted" +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:164 +#, python-format +msgid "Instance not present %s" +msgstr "" + +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vmops.py:193 +#, python-format +msgid "Starting snapshot for VM %s" +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:201 +#, python-format +msgid "Unable to Snapshot %(vm_ref)s: %(exc)s" +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:212 +#, python-format +msgid "Finished snapshot and upload for VM %s" +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:262 +#, python-format +msgid "VM %(vm)s already halted, skipping shutdown..." +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:444 +#, python-format +msgid "" +"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; args=" +"%(strargs)s" +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:447 +#, python-format +msgid "" +"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; args=" +"%(strargs)s" +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:638 +#, python-format +msgid "OpenSSL error: %s" +msgstr "" + +#: ../nova/tests/test_compute.py:148 +#, python-format +msgid "Running instances: %s" +msgstr "" + +#: ../nova/tests/test_compute.py:154 +#, python-format +msgid "After terminating instances: %s" +msgstr "" + +#: ../nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" +msgstr "" + +#: ../nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" +msgstr "" + +#: ../nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" +msgstr "" + +#: ../nova/cloudpipe/pipelib.py:97 +#, python-format +msgid "Launching VPN for %s" +msgstr "" + +#: ../nova/image/s3.py:89 +#, python-format +msgid "Image %s could not be found" +msgstr "" + +#: ../nova/api/ec2/__init__.py:126 +msgid "Too many failed authentications." +msgstr "" + +#: ../nova/api/ec2/__init__.py:136 +#, python-format +msgid "" +"Access key %(access_key)s has had %(failures)d failed authentications and " +"will be locked out for %(lock_mins)d minutes." +msgstr "" + +#: ../nova/api/ec2/__init__.py:174 ../nova/objectstore/handler.py:140 +#, python-format +msgid "Authentication Failure: %s" +msgstr "" + +#: ../nova/api/ec2/__init__.py:187 +#, python-format +msgid "Authenticated Request For %(uname)s:%(pname)s)" +msgstr "" + +#: ../nova/api/ec2/__init__.py:212 +#, python-format +msgid "action: %s" +msgstr "" + +#: ../nova/api/ec2/__init__.py:214 +#, python-format +msgid "arg: %(key)s\t\tval: %(value)s" +msgstr "" + +#: ../nova/api/ec2/__init__.py:286 +#, python-format +msgid "" +"Unauthorized request for controller=%(controller)s and action=%(action)s" +msgstr "" + +#: ../nova/api/ec2/__init__.py:319 +#, python-format +msgid "InstanceNotFound raised: %s" +msgstr "" + +#: ../nova/api/ec2/__init__.py:325 +#, python-format +msgid "VolumeNotFound raised: %s" +msgstr "" + +#: ../nova/api/ec2/__init__.py:331 +#, python-format +msgid "NotFound raised: %s" +msgstr "" + +#: ../nova/api/ec2/__init__.py:334 +#, python-format +msgid "ApiError raised: %s" +msgstr "" + +#: ../nova/api/ec2/__init__.py:343 +#, python-format +msgid "Unexpected error raised: %s" +msgstr "" + +#: ../nova/api/ec2/__init__.py:348 +msgid "An unknown error has occurred. Please try your request again." +msgstr "" + +#: ../nova/auth/dbdriver.py:84 +#, python-format +msgid "User %s already exists" +msgstr "" + +#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:206 +#, python-format +msgid "Project can't be created because manager %s doesn't exist" +msgstr "" + +#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:217 +#, python-format +msgid "Project can't be created because user %s doesn't exist" +msgstr "" + +#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:203 +#, python-format +msgid "Project can't be created because project %s already exists" +msgstr "" + +#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:241 +#, python-format +msgid "Project can't be modified because manager %s doesn't exist" +msgstr "" + +#: ../nova/auth/dbdriver.py:245 +#, python-format +msgid "User \"%s\" not found" +msgstr "" + +#: ../nova/auth/dbdriver.py:248 +#, python-format +msgid "Project \"%s\" not found" +msgstr "" + +#: ../nova/virt/xenapi_conn.py:129 +msgid "" +"Must specify xenapi_connection_url, xenapi_connection_username (optionally), " +"and xenapi_connection_password to use connection_type=xenapi" +msgstr "" + +#: ../nova/virt/xenapi_conn.py:301 +#, python-format +msgid "Task [%(name)s] %(task)s status: success %(result)s" +msgstr "" + +#: ../nova/virt/xenapi_conn.py:307 +#, python-format +msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s" +msgstr "" + +#: ../nova/virt/xenapi_conn.py:321 ../nova/virt/xenapi_conn.py:334 +#, python-format +msgid "Got exception: %s" +msgstr "" + +#: ../nova/compute/monitor.py:259 +#, python-format +msgid "updating %s..." +msgstr "" + +#: ../nova/compute/monitor.py:289 +msgid "unexpected error during update" +msgstr "" + +#: ../nova/compute/monitor.py:356 +#, python-format +msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\"" +msgstr "" + +#: ../nova/compute/monitor.py:379 +#, python-format +msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\"" +msgstr "" + +#: ../nova/compute/monitor.py:414 +msgid "unexpected exception getting connection" +msgstr "" + +#: ../nova/compute/monitor.py:429 +#, python-format +msgid "Found instance: %s" +msgstr "" + +#: ../nova/api/ec2/apirequest.py:99 +#, python-format +msgid "" +"Unsupported API request: controller = %(controller)s, action = %(action)s" +msgstr "" + +#: ../nova/api/openstack/__init__.py:54 +#, python-format +msgid "Caught error: %s" +msgstr "" + +#: ../nova/api/openstack/__init__.py:75 +msgid "Including admin operations in API." +msgstr "" + +#: ../nova/console/xvp.py:99 +msgid "Rebuilding xvp conf" +msgstr "" + +#: ../nova/console/xvp.py:116 +#, python-format +msgid "Re-wrote %s" +msgstr "" + +#: ../nova/console/xvp.py:121 +msgid "Stopping xvp" +msgstr "" + +#: ../nova/console/xvp.py:134 +msgid "Starting xvp" +msgstr "" + +#: ../nova/console/xvp.py:141 +#, python-format +msgid "Error starting xvp: %s" +msgstr "" + +#: ../nova/console/xvp.py:144 +msgid "Restarting xvp" +msgstr "" + +#: ../nova/console/xvp.py:146 +msgid "xvp not running..." +msgstr "" + +#: ../bin/nova-manage.py:272 +msgid "" +"The above error may show that the database has not been created.\n" +"Please create a database using nova-manage sync db before running this " +"command." +msgstr "" + +#: ../bin/nova-manage.py:426 +msgid "" +"No more networks available. If this is a new installation, you need\n" +"to call something like this:\n" +"\n" +" nova-manage network create 10.0.0.0/8 10 64\n" +"\n" +msgstr "" + +#: ../bin/nova-manage.py:431 +msgid "" +"The above error may show that the certificate db has not been created.\n" +"Please create a database by running a nova-api server on this host." +msgstr "" + +#: ../nova/virt/disk.py:69 +#, python-format +msgid "Failed to load partition: %s" +msgstr "" + +#: ../nova/virt/disk.py:91 +#, python-format +msgid "Failed to mount filesystem: %s" +msgstr "" + +#: ../nova/virt/disk.py:124 +#, python-format +msgid "nbd device %s did not show up" +msgstr "" + +#: ../nova/virt/disk.py:128 +#, python-format +msgid "Could not attach image to loopback: %s" +msgstr "" + +#: ../nova/virt/disk.py:151 +msgid "No free nbd devices" +msgstr "" + +#: ../doc/ext/nova_todo.py:46 +#, python-format +msgid "%(filename)s, line %(line_info)d" +msgstr "" + +#. FIXME(chiradeep): implement this +#: ../nova/virt/hyperv.py:118 +msgid "In init host" +msgstr "" + +#: ../nova/virt/hyperv.py:131 +#, python-format +msgid "Attempt to create duplicate vm %s" +msgstr "" + +#: ../nova/virt/hyperv.py:148 +#, python-format +msgid "Starting VM %s " +msgstr "" + +#: ../nova/virt/hyperv.py:150 +#, python-format +msgid "Started VM %s " +msgstr "" + +#: ../nova/virt/hyperv.py:152 +#, python-format +msgid "spawn vm failed: %s" +msgstr "" + +#: ../nova/virt/hyperv.py:169 +#, python-format +msgid "Failed to create VM %s" +msgstr "" + +#: ../nova/virt/hyperv.py:188 +#, python-format +msgid "Set memory for vm %s..." +msgstr "" + +#: ../nova/virt/hyperv.py:198 +#, python-format +msgid "Set vcpus for vm %s..." +msgstr "" + +#: ../nova/virt/hyperv.py:202 +#, python-format +msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s" +msgstr "" + +#: ../nova/virt/hyperv.py:227 +#, python-format +msgid "Failed to add diskdrive to VM %s" +msgstr "" + +#: ../nova/virt/hyperv.py:230 +#, python-format +msgid "New disk drive path is %s" +msgstr "" + +#: ../nova/virt/hyperv.py:247 +#, python-format +msgid "Failed to add vhd file to VM %s" +msgstr "" + +#: ../nova/virt/hyperv.py:249 +#, python-format +msgid "Created disk for %s" +msgstr "" + +#: ../nova/virt/hyperv.py:253 +#, python-format +msgid "Creating nic for %s " +msgstr "" + +#: ../nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" +msgstr "" + +#: ../nova/virt/hyperv.py:273 +#, python-format +msgid "Failed creating port for %s" +msgstr "" + +#: ../nova/virt/hyperv.py:276 +#, python-format +msgid "Created switch port %(vm_name)s on switch %(ext_path)s" +msgstr "" + +#: ../nova/virt/hyperv.py:286 +#, python-format +msgid "Failed to add nic to VM %s" +msgstr "" + +#: ../nova/virt/hyperv.py:288 +#, python-format +msgid "Created nic for %s " +msgstr "" + +#: ../nova/virt/hyperv.py:321 +#, python-format +msgid "WMI job failed: %s" +msgstr "" + +#: ../nova/virt/hyperv.py:325 +#, python-format +msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s " +msgstr "" + +#: ../nova/virt/hyperv.py:361 +#, python-format +msgid "Got request to destroy vm %s" +msgstr "" + +#: ../nova/virt/hyperv.py:386 +#, python-format +msgid "Failed to destroy vm %s" +msgstr "" + +#: ../nova/virt/hyperv.py:393 +#, python-format +msgid "Del: disk %(vhdfile)s vm %(instance_name)s" +msgstr "" + +#: ../nova/virt/hyperv.py:415 +#, python-format +msgid "" +"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, num_cpu=" +"%(numprocs)s, cpu_time=%(uptime)s" +msgstr "" + +#: ../nova/virt/hyperv.py:451 +#, python-format +msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s" +msgstr "" + +#: ../nova/virt/hyperv.py:454 +#, python-format +msgid "Failed to change vm state of %(vm_name)s to %(req_state)s" +msgstr "" + +#: ../nova/compute/api.py:71 +#, python-format +msgid "Instance %d was not found in get_network_topic" +msgstr "" + +#: ../nova/compute/api.py:77 +#, python-format +msgid "Instance %d has no host" +msgstr "" + +#: ../nova/compute/api.py:96 +#, python-format +msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances" +msgstr "" + +#: ../nova/compute/api.py:98 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." +msgstr "" + +#: ../nova/compute/api.py:113 +msgid "Creating a raw instance" +msgstr "" + +#: ../nova/compute/api.py:162 +#, python-format +msgid "Going to run %s instances..." +msgstr "" + +#: ../nova/compute/api.py:189 +#, python-format +msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s" +msgstr "" + +#: ../nova/compute/api.py:293 +#, python-format +msgid "Going to try to terminate %s" +msgstr "" + +#: ../nova/compute/api.py:297 +#, python-format +msgid "Instance %d was not found during terminate" +msgstr "" + +#: ../nova/compute/api.py:302 +#, python-format +msgid "Instance %d is already being terminated" +msgstr "" + +#: ../nova/compute/api.py:471 +#, python-format +msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgstr "" + +#: ../nova/compute/api.py:486 +msgid "Volume isn't attached to anything!" +msgstr "" + +#: ../nova/rpc.py:95 +#, python-format +msgid "" +"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in " +"%(fl_intv)d seconds." +msgstr "" + +#: ../nova/rpc.py:100 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "" + +#: ../nova/rpc.py:119 +msgid "Reconnected to queue" +msgstr "" + +#: ../nova/rpc.py:126 +msgid "Failed to fetch message from queue" +msgstr "" + +#: ../nova/rpc.py:156 +#, python-format +msgid "Initing the Adapter Consumer for %s" +msgstr "" + +#: ../nova/rpc.py:171 +#, python-format +msgid "received %s" +msgstr "" + +#. NOTE(vish): we may not want to ack here, but that means that bad +#. messages stay in the queue indefinitely, so for now +#. we just log the message and send an error string +#. back to the caller +#: ../nova/rpc.py:184 +#, python-format +msgid "no method for message: %s" +msgstr "" + +#: ../nova/rpc.py:185 +#, python-format +msgid "No method for message: %s" +msgstr "" + +#: ../nova/rpc.py:246 +#, python-format +msgid "Returning exception %s to caller" +msgstr "" + +#: ../nova/rpc.py:287 +#, python-format +msgid "unpacked context: %s" +msgstr "" + +#: ../nova/rpc.py:306 +msgid "Making asynchronous call..." +msgstr "" + +#: ../nova/rpc.py:309 +#, python-format +msgid "MSG_ID is %s" +msgstr "" + +#: ../nova/rpc.py:347 +msgid "Making asynchronous cast..." +msgstr "" + +#: ../nova/rpc.py:357 +#, python-format +msgid "response %s" +msgstr "" + +#: ../nova/rpc.py:366 +#, python-format +msgid "topic is %s" +msgstr "" + +#: ../nova/rpc.py:367 +#, python-format +msgid "message %s" +msgstr "" + +#: ../nova/volume/driver.py:78 +#, python-format +msgid "Recovering from a failed execute. Try number %s" +msgstr "" + +#: ../nova/volume/driver.py:87 +#, python-format +msgid "volume group %s doesn't exist" +msgstr "" + +#: ../nova/volume/driver.py:220 +#, python-format +msgid "FAKE AOE: %s" +msgstr "" + +#: ../nova/volume/driver.py:233 +msgid "Skipping ensure_export. No iscsi_target " +msgstr "" + +#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288 +msgid "Skipping remove_export. No iscsi_target " +msgstr "" + +#: ../nova/volume/driver.py:347 +#, python-format +msgid "FAKE ISCSI: %s" +msgstr "" + +#: ../nova/volume/driver.py:359 +#, python-format +msgid "rbd has no pool %s" +msgstr "" + +#: ../nova/volume/driver.py:414 +#, python-format +msgid "Sheepdog is not working: %s" +msgstr "" + +#: ../nova/volume/driver.py:416 +msgid "Sheepdog is not working" +msgstr "" + +#: ../nova/wsgi.py:68 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: ../nova/wsgi.py:147 +msgid "You must implement __call__" +msgstr "" + +#: ../bin/nova-instancemonitor.py:55 +msgid "Starting instance monitor" +msgstr "" + +#: ../bin/nova-dhcpbridge.py:58 +msgid "leasing ip" +msgstr "" + +#: ../bin/nova-dhcpbridge.py:73 +msgid "Adopted old lease or got a change of mac/hostname" +msgstr "" + +#: ../bin/nova-dhcpbridge.py:80 +msgid "releasing ip" +msgstr "" + +#: ../bin/nova-dhcpbridge.py:123 +#, python-format +msgid "" +"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s " +"on interface %(interface)s" +msgstr "" + +#: ../nova/network/manager.py:139 +msgid "setting network host" +msgstr "" + +#: ../nova/network/manager.py:194 +#, python-format +msgid "Leasing IP %s" +msgstr "" + +#: ../nova/network/manager.py:198 +#, python-format +msgid "IP %s leased that isn't associated" +msgstr "" + +#: ../nova/network/manager.py:202 +#, python-format +msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s" +msgstr "" + +#: ../nova/network/manager.py:210 +#, python-format +msgid "IP %s leased that was already deallocated" +msgstr "" + +#: ../nova/network/manager.py:215 +#, python-format +msgid "Releasing IP %s" +msgstr "" + +#: ../nova/network/manager.py:219 +#, python-format +msgid "IP %s released that isn't associated" +msgstr "" + +#: ../nova/network/manager.py:223 +#, python-format +msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s" +msgstr "" + +#: ../nova/network/manager.py:226 +#, python-format +msgid "IP %s released that was not leased" +msgstr "" + +#: ../nova/network/manager.py:461 +#, python-format +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "" + +#: ../nova/virt/xenapi/volume_utils.py:57 +#, python-format +msgid "Introducing %s..." +msgstr "" + +#: ../nova/virt/xenapi/volume_utils.py:74 +#, python-format +msgid "Introduced %(label)s as %(sr_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" +msgstr "" + +#: ../nova/virt/xenapi/volume_utils.py:90 +#, python-format +msgid "Unable to find SR from VBD %s" +msgstr "" + +#: ../nova/virt/xenapi/volume_utils.py:96 +#, python-format +msgid "Forgetting SR %s ... " +msgstr "" + +#: ../nova/virt/xenapi/volume_utils.py:101 +#, python-format +msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s" +msgstr "" + +#: ../nova/virt/xenapi/volume_utils.py:107 +#, python-format +msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s" +msgstr "" + +#: ../nova/virt/xenapi/volume_utils.py:111 +#, python-format +msgid "Forgetting SR %s done." +msgstr "" + +#: ../nova/virt/xenapi/volume_utils.py:113 +#, python-format +msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s" +msgstr "" + +#: ../nova/virt/xenapi/volume_utils.py:123 +#, python-format +msgid "Unable to introduce VDI on SR %s" +msgstr "" + +#: ../nova/virt/xenapi/volume_utils.py:128 +#, python-format +msgid "Unable to get record of VDI %s on" +msgstr "" + +#: ../nova/virt/xenapi/volume_utils.py:146 +#, python-format +msgid "Unable to introduce VDI for SR %s" +msgstr "" + +#: ../nova/virt/xenapi/volume_utils.py:175 +#, python-format +msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s" +msgstr "" + +#: ../nova/virt/xenapi/volume_utils.py:197 +#, python-format +msgid "Mountpoint cannot be translated: %s" +msgstr "" + +#: ../nova/objectstore/image.py:262 +#, python-format +msgid "Failed to decrypt private key: %s" +msgstr "" + +#: ../nova/objectstore/image.py:269 +#, python-format +msgid "Failed to decrypt initialization vector: %s" +msgstr "" + +#: ../nova/objectstore/image.py:277 +#, python-format +msgid "Failed to decrypt image file %(image_file)s: %(err)s" +msgstr "" + +#: ../nova/objectstore/handler.py:106 +#, python-format +msgid "Unknown S3 value type %r" +msgstr "" + +#: ../nova/objectstore/handler.py:137 +msgid "Authenticated request" +msgstr "" + +#: ../nova/objectstore/handler.py:182 +msgid "List of buckets requested" +msgstr "" + +#: ../nova/objectstore/handler.py:209 +#, python-format +msgid "List keys for bucket %s" +msgstr "" + +#: ../nova/objectstore/handler.py:217 +#, python-format +msgid "Unauthorized attempt to access bucket %s" +msgstr "" + +#: ../nova/objectstore/handler.py:235 +#, python-format +msgid "Creating bucket %s" +msgstr "" + +#: ../nova/objectstore/handler.py:245 +#, python-format +msgid "Deleting bucket %s" +msgstr "" + +#: ../nova/objectstore/handler.py:249 +#, python-format +msgid "Unauthorized attempt to delete bucket %s" +msgstr "" + +#: ../nova/objectstore/handler.py:273 +#, python-format +msgid "Getting object: %(bname)s / %(nm)s" +msgstr "" + +#: ../nova/objectstore/handler.py:276 +#, python-format +msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s" +msgstr "" + +#: ../nova/objectstore/handler.py:296 +#, python-format +msgid "Putting object: %(bname)s / %(nm)s" +msgstr "" + +#: ../nova/objectstore/handler.py:299 +#, python-format +msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s" +msgstr "" + +#: ../nova/objectstore/handler.py:318 +#, python-format +msgid "Deleting object: %(bname)s / %(nm)s" +msgstr "" + +#: ../nova/objectstore/handler.py:322 +#, python-format +msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s" +msgstr "" + +#: ../nova/objectstore/handler.py:396 +#, python-format +msgid "Not authorized to upload image: invalid directory %s" +msgstr "" + +#: ../nova/objectstore/handler.py:404 +#, python-format +msgid "Not authorized to upload image: unauthorized bucket %s" +msgstr "" + +#: ../nova/objectstore/handler.py:409 +#, python-format +msgid "Starting image upload: %s" +msgstr "" + +#: ../nova/objectstore/handler.py:423 +#, python-format +msgid "Not authorized to update attributes of image %s" +msgstr "" + +#: ../nova/objectstore/handler.py:431 +#, python-format +msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r" +msgstr "" + +#. other attributes imply update +#: ../nova/objectstore/handler.py:436 +#, python-format +msgid "Updating user fields on image %s" +msgstr "" + +#: ../nova/objectstore/handler.py:450 +#, python-format +msgid "Unauthorized attempt to delete image %s" +msgstr "" + +#: ../nova/objectstore/handler.py:455 +#, python-format +msgid "Deleted image: %s" +msgstr "" + +#: ../nova/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "" + +#: ../nova/auth/manager.py:263 +#, python-format +msgid "Failed authorization for access key %s" +msgstr "" + +#: ../nova/auth/manager.py:264 +#, python-format +msgid "No user found for access key %s" +msgstr "" + +#: ../nova/auth/manager.py:270 +#, python-format +msgid "Using project name = user name (%s)" +msgstr "" + +#: ../nova/auth/manager.py:277 +#, python-format +msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)" +msgstr "" + +#: ../nova/auth/manager.py:279 +#, python-format +msgid "No project called %s could be found" +msgstr "" + +#: ../nova/auth/manager.py:287 +#, python-format +msgid "" +"Failed authorization: user %(uname)s not admin and not member of project " +"%(pjname)s" +msgstr "" + +#: ../nova/auth/manager.py:289 +#, python-format +msgid "User %(uid)s is not a member of project %(pjid)s" +msgstr "" + +#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309 +#, python-format +msgid "Invalid signature for user %s" +msgstr "" + +#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310 +msgid "Signature does not match" +msgstr "" + +#: ../nova/auth/manager.py:380 +msgid "Must specify project" +msgstr "" + +#: ../nova/auth/manager.py:414 +#, python-format +msgid "The %s role can not be found" +msgstr "" + +#: ../nova/auth/manager.py:416 +#, python-format +msgid "The %s role is global only" +msgstr "" + +#: ../nova/auth/manager.py:420 +#, python-format +msgid "Adding role %(role)s to user %(uid)s in project %(pid)s" +msgstr "" + +#: ../nova/auth/manager.py:423 +#, python-format +msgid "Adding sitewide role %(role)s to user %(uid)s" +msgstr "" + +#: ../nova/auth/manager.py:448 +#, python-format +msgid "Removing role %(role)s from user %(uid)s on project %(pid)s" +msgstr "" + +#: ../nova/auth/manager.py:451 +#, python-format +msgid "Removing sitewide role %(role)s from user %(uid)s" +msgstr "" + +#: ../nova/auth/manager.py:515 +#, python-format +msgid "Created project %(name)s with manager %(manager_user)s" +msgstr "" + +#: ../nova/auth/manager.py:533 +#, python-format +msgid "modifying project %s" +msgstr "" + +#: ../nova/auth/manager.py:545 +#, python-format +msgid "Adding user %(uid)s to project %(pid)s" +msgstr "" + +#: ../nova/auth/manager.py:566 +#, python-format +msgid "Remove user %(uid)s from project %(pid)s" +msgstr "" + +#: ../nova/auth/manager.py:592 +#, python-format +msgid "Deleting project %s" +msgstr "" + +#: ../nova/auth/manager.py:650 +#, python-format +msgid "Created user %(rvname)s (admin: %(rvadmin)r)" +msgstr "" + +#: ../nova/auth/manager.py:659 +#, python-format +msgid "Deleting user %s" +msgstr "" + +#: ../nova/auth/manager.py:669 +#, python-format +msgid "Access Key change for user %s" +msgstr "" + +#: ../nova/auth/manager.py:671 +#, python-format +msgid "Secret Key change for user %s" +msgstr "" + +#: ../nova/auth/manager.py:673 +#, python-format +msgid "Admin status set to %(admin)r for user %(uid)s" +msgstr "" + +#: ../nova/auth/manager.py:722 +#, python-format +msgid "No vpn data for project %s" +msgstr "" + +#: ../nova/service.py:161 +#, python-format +msgid "Starting %(topic)s node (version %(vcs_string)s)" +msgstr "" + +#: ../nova/service.py:174 +msgid "Service killed that has no database entry" +msgstr "" + +#: ../nova/service.py:195 +msgid "The service database object disappeared, Recreating it." +msgstr "" + +#: ../nova/service.py:207 +msgid "Recovered model server connection!" +msgstr "" + +#: ../nova/service.py:213 +msgid "model server went away" +msgstr "" + +#: ../nova/auth/ldapdriver.py:149 +#, python-format +msgid "LDAP user %s already exists" +msgstr "" + +#: ../nova/auth/ldapdriver.py:180 +#, python-format +msgid "LDAP object for %s doesn't exist" +msgstr "" + +#: ../nova/auth/ldapdriver.py:313 +#, python-format +msgid "User %s doesn't exist" +msgstr "" + +#: ../nova/auth/ldapdriver.py:435 +#, python-format +msgid "Group can't be created because group %s already exists" +msgstr "" + +#: ../nova/auth/ldapdriver.py:441 +#, python-format +msgid "Group can't be created because user %s doesn't exist" +msgstr "" + +#: ../nova/auth/ldapdriver.py:458 +#, python-format +msgid "User %s can't be searched in group because the user doesn't exist" +msgstr "" + +#: ../nova/auth/ldapdriver.py:470 +#, python-format +msgid "User %s can't be added to the group because the user doesn't exist" +msgstr "" + +#: ../nova/auth/ldapdriver.py:473 ../nova/auth/ldapdriver.py:484 +#, python-format +msgid "The group at dn %s doesn't exist" +msgstr "" + +#: ../nova/auth/ldapdriver.py:476 +#, python-format +msgid "User %(uid)s is already a member of the group %(group_dn)s" +msgstr "" + +#: ../nova/auth/ldapdriver.py:487 +#, python-format +msgid "User %s can't be removed from the group because the user doesn't exist" +msgstr "" + +#: ../nova/auth/ldapdriver.py:491 +#, python-format +msgid "User %s is not a member of the group" +msgstr "" + +#: ../nova/auth/ldapdriver.py:505 +#, python-format +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." +msgstr "" + +#: ../nova/auth/ldapdriver.py:512 +#, python-format +msgid "User %s can't be removed from all because the user doesn't exist" +msgstr "" + +#: ../nova/auth/ldapdriver.py:527 +#, python-format +msgid "Group at dn %s doesn't exist" +msgstr "" + +#: ../nova/virt/xenapi/network_utils.py:40 +#, python-format +msgid "Found non-unique network for bridge %s" +msgstr "" + +#: ../nova/virt/xenapi/network_utils.py:43 +#, python-format +msgid "Found no network for bridge %s" +msgstr "" + +#: ../nova/api/ec2/admin.py:97 +#, python-format +msgid "Creating new user: %s" +msgstr "" + +#: ../nova/api/ec2/admin.py:105 +#, python-format +msgid "Deleting user: %s" +msgstr "" + +#: ../nova/api/ec2/admin.py:127 +#, python-format +msgid "Adding role %(role)s to user %(user)s for project %(project)s" +msgstr "" + +#: ../nova/api/ec2/admin.py:131 +#, python-format +msgid "Adding sitewide role %(role)s to user %(user)s" +msgstr "" + +#: ../nova/api/ec2/admin.py:137 +#, python-format +msgid "Removing role %(role)s from user %(user)s for project %(project)s" +msgstr "" + +#: ../nova/api/ec2/admin.py:141 +#, python-format +msgid "Removing sitewide role %(role)s from user %(user)s" +msgstr "" + +#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223 +msgid "operation must be add or remove" +msgstr "" + +#: ../nova/api/ec2/admin.py:159 +#, python-format +msgid "Getting x509 for user: %(name)s on project: %(project)s" +msgstr "" + +#: ../nova/api/ec2/admin.py:177 +#, python-format +msgid "Create project %(name)s managed by %(manager_user)s" +msgstr "" + +#: ../nova/api/ec2/admin.py:190 +#, python-format +msgid "Modify project: %(name)s managed by %(manager_user)s" +msgstr "" + +#: ../nova/api/ec2/admin.py:200 +#, python-format +msgid "Delete project: %s" +msgstr "" + +#: ../nova/api/ec2/admin.py:214 +#, python-format +msgid "Adding user %(user)s to project %(project)s" +msgstr "" + +#: ../nova/api/ec2/admin.py:218 +#, python-format +msgid "Removing user %(user)s from project %(project)s" +msgstr "" From 7f9258caea14fd0f2dcd0bece4b4b917e6a2b35d Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Mon, 14 Feb 2011 14:52:58 -0800 Subject: [PATCH 022/111] fixed template and added migration --- nova/auth/novarc.template | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/auth/novarc.template b/nova/auth/novarc.template index 702df3bb..cda2ecc2 100644 --- a/nova/auth/novarc.template +++ b/nova/auth/novarc.template @@ -10,6 +10,6 @@ export NOVA_CERT=${NOVA_KEY_DIR}/%(nova)s export EUCALYPTUS_CERT=${NOVA_CERT} # euca-bundle-image seems to require this set alias ec2-bundle-image="ec2-bundle-image --cert ${EC2_CERT} --privatekey ${EC2_PRIVATE_KEY} --user 42 --ec2cert ${NOVA_CERT}" alias ec2-upload-bundle="ec2-upload-bundle -a ${EC2_ACCESS_KEY} -s ${EC2_SECRET_KEY} --url ${S3_URL} --ec2cert ${NOVA_CERT}" -export NOVA_TOOLS_API_KEY="%(access)s" -export NOVA_TOOLS_USERNAME="%(user)s" -export NOVA_TOOLS_URL="%(os)s" +export NOVA_API_KEY="%(access)s" +export NOVA_USERNAME="%(user)s" +export NOVA_URL="%(os)s" From 1a7316904a6b30e2f4437e961b3c2fcfb78621df Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Mon, 14 Feb 2011 20:11:29 -0400 Subject: [PATCH 023/111] fixed nova-combined debug hack and renamed ChildZone to Zone --- bin/nova-combined | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/nova-combined b/bin/nova-combined index a0f552d6..913c866b 100755 --- a/bin/nova-combined +++ b/bin/nova-combined @@ -53,11 +53,11 @@ if __name__ == '__main__': compute = service.Service.create(binary='nova-compute') network = service.Service.create(binary='nova-network') - #volume = service.Service.create(binary='nova-volume') + volume = service.Service.create(binary='nova-volume') scheduler = service.Service.create(binary='nova-scheduler') #objectstore = service.Service.create(binary='nova-objectstore') - service.serve(compute, network, scheduler) + service.serve(compute, network, volume, scheduler) apps = [] paste_config_file = wsgi.paste_config_file('nova-api.conf') From b8864a17864668f4f86090a009c8b5ec7ce99d7a Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of nova-core <> Date: Tue, 15 Feb 2011 05:12:01 +0000 Subject: [PATCH 024/111] Launchpad automatic translations update. --- locale/zh_CN.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/zh_CN.po b/locale/zh_CN.po index 01b8dc37..a3938349 100644 --- a/locale/zh_CN.po +++ b/locale/zh_CN.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-02-14 05:22+0000\n" +"X-Launchpad-Export-Date: 2011-02-15 05:12+0000\n" "X-Generator: Launchpad (build 12351)\n" #: nova/twistd.py:268 From 4619725617afa6ebd0ef38a9ba0c53833df466a9 Mon Sep 17 00:00:00 2001 From: "jaypipes@gmail.com" <> Date: Tue, 15 Feb 2011 11:06:28 -0500 Subject: [PATCH 025/111] Update .pot file with source file and line numbers after running python setup.py build --- po/nova.pot | 276 ++++++++++++++++++++++++++++------------------------ 1 file changed, 147 insertions(+), 129 deletions(-) diff --git a/po/nova.pot b/po/nova.pot index 576621ce..f747ae0f 100644 --- a/po/nova.pot +++ b/po/nova.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-02-09 09:26-0800\n" +"POT-Creation-Date: 2011-02-15 11:05-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,9 +17,9 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: ../nova/scheduler/chance.py:37 ../nova/scheduler/simple.py:75 -#: ../nova/scheduler/simple.py:110 ../nova/scheduler/simple.py:122 -#: ../nova/scheduler/zone.py:55 +#: ../nova/scheduler/chance.py:37 ../nova/scheduler/zone.py:55 +#: ../nova/scheduler/simple.py:75 ../nova/scheduler/simple.py:110 +#: ../nova/scheduler/simple.py:122 msgid "No hosts found" msgstr "" @@ -68,11 +68,6 @@ msgstr "" msgid "Volume is already detached" msgstr "" -#: ../nova/virt/fake.py:224 -#, python-format -msgid "Instance %s Not Found" -msgstr "" - #: ../nova/api/openstack/servers.py:138 #, python-format msgid "%(param)s property not found for image %(_image_id)s" @@ -142,7 +137,7 @@ msgstr "" #: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101 #: ../nova/db/sqlalchemy/api.py:709 ../nova/virt/libvirt_conn.py:741 -#: ../nova/api/ec2/__init__.py:322 +#: ../nova/api/ec2/__init__.py:321 #, python-format msgid "Instance %s not found" msgstr "" @@ -383,7 +378,7 @@ msgstr "" msgid "instance %s: getting locked state" msgstr "" -#: ../nova/compute/manager.py:506 ../nova/api/ec2/cloud.py:513 +#: ../nova/compute/manager.py:506 ../nova/api/ec2/cloud.py:515 #, python-format msgid "Get console output for instance %s" msgstr "" @@ -540,40 +535,40 @@ msgstr "" msgid "Failed to open connection to the hypervisor" msgstr "" -#: ../nova/network/linux_net.py:181 +#: ../nova/network/linux_net.py:187 #, python-format msgid "Starting VLAN inteface %s" msgstr "" -#: ../nova/network/linux_net.py:202 +#: ../nova/network/linux_net.py:208 #, python-format msgid "Starting Bridge interface for %s" msgstr "" #. pylint: disable-msg=W0703 -#: ../nova/network/linux_net.py:308 +#: ../nova/network/linux_net.py:314 #, python-format msgid "Hupping dnsmasq threw %s" msgstr "" -#: ../nova/network/linux_net.py:310 +#: ../nova/network/linux_net.py:316 #, python-format msgid "Pid %d is stale, relaunching dnsmasq" msgstr "" #. pylint: disable-msg=W0703 -#: ../nova/network/linux_net.py:352 +#: ../nova/network/linux_net.py:358 #, python-format msgid "killing radvd threw %s" msgstr "" -#: ../nova/network/linux_net.py:354 +#: ../nova/network/linux_net.py:360 #, python-format msgid "Pid %d is stale, relaunching radvd" msgstr "" #. pylint: disable-msg=W0703 -#: ../nova/network/linux_net.py:443 +#: ../nova/network/linux_net.py:449 #, python-format msgid "Killing dnsmasq threw %s" msgstr "" @@ -598,37 +593,42 @@ msgstr "" msgid "Running cmd (subprocess): %s" msgstr "" -#: ../nova/utils.py:141 +#: ../nova/utils.py:141 ../nova/utils.py:181 #, python-format msgid "Result was %s" msgstr "" -#: ../nova/utils.py:179 +#: ../nova/utils.py:157 #, python-format -msgid "debug in callback: %s" -msgstr "" - -#: ../nova/utils.py:184 -#, python-format -msgid "Running %s" +msgid "Running cmd (SSH): %s" msgstr "" #: ../nova/utils.py:215 #, python-format +msgid "debug in callback: %s" +msgstr "" + +#: ../nova/utils.py:220 +#, python-format +msgid "Running %s" +msgstr "" + +#: ../nova/utils.py:251 +#, python-format msgid "Link Local address is not found.:%s" msgstr "" -#: ../nova/utils.py:218 +#: ../nova/utils.py:254 #, python-format msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s" msgstr "" -#: ../nova/utils.py:316 +#: ../nova/utils.py:352 #, python-format msgid "Invalid backend: %s" msgstr "" -#: ../nova/utils.py:327 +#: ../nova/utils.py:363 #, python-format msgid "backend %s" msgstr "" @@ -793,129 +793,129 @@ msgstr "" msgid "VDI %s is still available" msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:445 +#: ../nova/virt/xenapi/vm_utils.py:453 #, python-format msgid "(VM_UTILS) xenserver vm state -> |%s|" msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:447 +#: ../nova/virt/xenapi/vm_utils.py:455 #, python-format msgid "(VM_UTILS) xenapi power_state -> |%s|" msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:507 +#: ../nova/virt/xenapi/vm_utils.py:515 #, python-format msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s" msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:524 +#: ../nova/virt/xenapi/vm_utils.py:532 #, python-format msgid "Re-scanning SR %s" msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:549 +#: ../nova/virt/xenapi/vm_utils.py:557 #, python-format msgid "" "VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..." msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:556 +#: ../nova/virt/xenapi/vm_utils.py:564 #, python-format msgid "" "Parent %(parent_uuid)s doesn't match original parent " "%(original_parent_uuid)s, waiting for coalesce..." msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:572 +#: ../nova/virt/xenapi/vm_utils.py:580 #, python-format msgid "No VDIs found for VM %s" msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:576 +#: ../nova/virt/xenapi/vm_utils.py:584 #, python-format msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s" msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:635 +#: ../nova/virt/xenapi/vm_utils.py:643 #: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188 #, python-format msgid "Creating VBD for VDI %s ... " msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:637 +#: ../nova/virt/xenapi/vm_utils.py:645 #: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190 #, python-format msgid "Creating VBD for VDI %s done." msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:639 +#: ../nova/virt/xenapi/vm_utils.py:647 #: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192 #, python-format msgid "Plugging VBD %s ... " msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:641 +#: ../nova/virt/xenapi/vm_utils.py:649 #: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:194 #, python-format msgid "Plugging VBD %s done." msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:643 +#: ../nova/virt/xenapi/vm_utils.py:651 #, python-format msgid "VBD %(vbd)s plugged as %(orig_dev)s" msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:646 +#: ../nova/virt/xenapi/vm_utils.py:654 #, python-format msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s" msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:650 +#: ../nova/virt/xenapi/vm_utils.py:658 #: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:197 #, python-format msgid "Destroying VBD for VDI %s ... " msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:653 +#: ../nova/virt/xenapi/vm_utils.py:661 #: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:200 #, python-format msgid "Destroying VBD for VDI %s done." msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:665 +#: ../nova/virt/xenapi/vm_utils.py:673 #: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211 msgid "VBD.unplug successful first time." msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:670 +#: ../nova/virt/xenapi/vm_utils.py:678 #: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216 msgid "VBD.unplug rejected: retrying..." msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:674 +#: ../nova/virt/xenapi/vm_utils.py:682 #: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220 msgid "VBD.unplug successful eventually." msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:677 +#: ../nova/virt/xenapi/vm_utils.py:685 #: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:223 #, python-format msgid "Ignoring XenAPI.Failure in VBD.unplug: %s" msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:686 +#: ../nova/virt/xenapi/vm_utils.py:694 #: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:66 #, python-format msgid "Ignoring XenAPI.Failure %s" msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:717 +#: ../nova/virt/xenapi/vm_utils.py:725 #, python-format msgid "" "Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..." msgstr "" -#: ../nova/virt/xenapi/vm_utils.py:729 +#: ../nova/virt/xenapi/vm_utils.py:737 #, python-format msgid "Writing partition table %s done." msgstr "" @@ -954,105 +954,105 @@ msgstr "" msgid "No floating ip for address %s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:933 +#: ../nova/db/sqlalchemy/api.py:939 #, python-format msgid "no keypair for user %(user_id)s, name %(name)s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1048 ../nova/db/sqlalchemy/api.py:1106 +#: ../nova/db/sqlalchemy/api.py:1054 ../nova/db/sqlalchemy/api.py:1112 #, python-format msgid "No network for id %s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1078 +#: ../nova/db/sqlalchemy/api.py:1084 #, python-format msgid "No network for bridge %s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1092 +#: ../nova/db/sqlalchemy/api.py:1098 #, python-format msgid "No network for instance %s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1227 +#: ../nova/db/sqlalchemy/api.py:1233 #, python-format msgid "Token %s does not exist" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1252 +#: ../nova/db/sqlalchemy/api.py:1258 #, python-format msgid "No quota for project_id %s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1405 ../nova/db/sqlalchemy/api.py:1451 -#: ../nova/api/ec2/__init__.py:328 +#: ../nova/db/sqlalchemy/api.py:1411 ../nova/db/sqlalchemy/api.py:1457 +#: ../nova/api/ec2/__init__.py:327 #, python-format msgid "Volume %s not found" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1464 +#: ../nova/db/sqlalchemy/api.py:1470 #, python-format msgid "No export device found for volume %s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1477 +#: ../nova/db/sqlalchemy/api.py:1483 #, python-format msgid "No target id found for volume %s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1522 +#: ../nova/db/sqlalchemy/api.py:1528 #, python-format msgid "No security group with id %s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1539 +#: ../nova/db/sqlalchemy/api.py:1545 #, python-format msgid "No security group named %(group_name)s for project: %(project_id)s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1632 +#: ../nova/db/sqlalchemy/api.py:1638 #, python-format msgid "No secuity group rule with id %s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1706 +#: ../nova/db/sqlalchemy/api.py:1712 #, python-format msgid "No user for id %s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1722 +#: ../nova/db/sqlalchemy/api.py:1728 #, python-format msgid "No user for access key %s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1784 +#: ../nova/db/sqlalchemy/api.py:1790 #, python-format msgid "No project with id %s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1929 +#: ../nova/db/sqlalchemy/api.py:1935 #, python-format msgid "No console pool with id %(pool_id)s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1946 +#: ../nova/db/sqlalchemy/api.py:1952 #, python-format msgid "" "No console pool of type %(console_type)s for compute host %(compute_host)s " "on proxy host %(host)s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:1985 +#: ../nova/db/sqlalchemy/api.py:1991 #, python-format msgid "No console for instance %(instance_id)s in pool %(pool_id)s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:2007 +#: ../nova/db/sqlalchemy/api.py:2013 #, python-format msgid "on instance %s" msgstr "" -#: ../nova/db/sqlalchemy/api.py:2008 +#: ../nova/db/sqlalchemy/api.py:2014 #, python-format msgid "No console with id %(console_id)s %(idesc)s" msgstr "" @@ -1262,129 +1262,129 @@ msgstr "" msgid "Delete key pair %s" msgstr "" -#: ../nova/api/ec2/cloud.py:384 +#: ../nova/api/ec2/cloud.py:386 #, python-format msgid "%s is not a valid ipProtocol" msgstr "" -#: ../nova/api/ec2/cloud.py:388 +#: ../nova/api/ec2/cloud.py:390 msgid "Invalid port range" msgstr "" -#: ../nova/api/ec2/cloud.py:419 +#: ../nova/api/ec2/cloud.py:421 #, python-format msgid "Revoke security group ingress %s" msgstr "" -#: ../nova/api/ec2/cloud.py:428 ../nova/api/ec2/cloud.py:457 +#: ../nova/api/ec2/cloud.py:430 ../nova/api/ec2/cloud.py:459 msgid "Not enough parameters to build a valid rule." msgstr "" -#: ../nova/api/ec2/cloud.py:441 +#: ../nova/api/ec2/cloud.py:443 msgid "No rule for the specified parameters." msgstr "" -#: ../nova/api/ec2/cloud.py:448 +#: ../nova/api/ec2/cloud.py:450 #, python-format msgid "Authorize security group ingress %s" msgstr "" -#: ../nova/api/ec2/cloud.py:462 +#: ../nova/api/ec2/cloud.py:464 #, python-format msgid "This rule already exists in group %s" msgstr "" -#: ../nova/api/ec2/cloud.py:490 +#: ../nova/api/ec2/cloud.py:492 #, python-format msgid "Create Security Group %s" msgstr "" -#: ../nova/api/ec2/cloud.py:493 +#: ../nova/api/ec2/cloud.py:495 #, python-format msgid "group %s already exists" msgstr "" -#: ../nova/api/ec2/cloud.py:505 +#: ../nova/api/ec2/cloud.py:507 #, python-format msgid "Delete security group %s" msgstr "" -#: ../nova/api/ec2/cloud.py:582 +#: ../nova/api/ec2/cloud.py:584 #, python-format msgid "Create volume of %s GB" msgstr "" -#: ../nova/api/ec2/cloud.py:610 +#: ../nova/api/ec2/cloud.py:612 #, python-format msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s" msgstr "" -#: ../nova/api/ec2/cloud.py:627 +#: ../nova/api/ec2/cloud.py:629 #, python-format msgid "Detach volume %s" msgstr "" -#: ../nova/api/ec2/cloud.py:759 +#: ../nova/api/ec2/cloud.py:761 msgid "Allocate address" msgstr "" -#: ../nova/api/ec2/cloud.py:764 +#: ../nova/api/ec2/cloud.py:766 #, python-format msgid "Release address %s" msgstr "" -#: ../nova/api/ec2/cloud.py:769 +#: ../nova/api/ec2/cloud.py:771 #, python-format msgid "Associate address %(public_ip)s to instance %(instance_id)s" msgstr "" -#: ../nova/api/ec2/cloud.py:778 +#: ../nova/api/ec2/cloud.py:780 #, python-format msgid "Disassociate address %s" msgstr "" -#: ../nova/api/ec2/cloud.py:805 +#: ../nova/api/ec2/cloud.py:807 msgid "Going to start terminating instances" msgstr "" -#: ../nova/api/ec2/cloud.py:813 +#: ../nova/api/ec2/cloud.py:815 #, python-format msgid "Reboot instance %r" msgstr "" -#: ../nova/api/ec2/cloud.py:850 +#: ../nova/api/ec2/cloud.py:867 #, python-format msgid "De-registering image %s" msgstr "" -#: ../nova/api/ec2/cloud.py:858 +#: ../nova/api/ec2/cloud.py:875 #, python-format msgid "Registered image %(image_location)s with id %(image_id)s" msgstr "" -#: ../nova/api/ec2/cloud.py:865 ../nova/api/ec2/cloud.py:880 +#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900 #, python-format msgid "attribute not supported: %s" msgstr "" -#: ../nova/api/ec2/cloud.py:870 +#: ../nova/api/ec2/cloud.py:890 #, python-format msgid "invalid id: %s" msgstr "" -#: ../nova/api/ec2/cloud.py:883 +#: ../nova/api/ec2/cloud.py:903 msgid "user or group not specified" msgstr "" -#: ../nova/api/ec2/cloud.py:885 +#: ../nova/api/ec2/cloud.py:905 msgid "only group \"all\" is supported" msgstr "" -#: ../nova/api/ec2/cloud.py:887 +#: ../nova/api/ec2/cloud.py:907 msgid "operation_type must be add or remove" msgstr "" -#: ../nova/api/ec2/cloud.py:888 +#: ../nova/api/ec2/cloud.py:908 #, python-format msgid "Updating image %s publicity" msgstr "" @@ -1507,21 +1507,29 @@ msgstr "" msgid "VM %(vm)s already halted, skipping shutdown..." msgstr "" -#: ../nova/virt/xenapi/vmops.py:444 +#: ../nova/virt/xenapi/vmops.py:295 +msgid "Removing kernel/ramdisk files" +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:305 +msgid "kernel/ramdisk files removed" +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:459 #, python-format msgid "" "TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; args=" "%(strargs)s" msgstr "" -#: ../nova/virt/xenapi/vmops.py:447 +#: ../nova/virt/xenapi/vmops.py:462 #, python-format msgid "" "The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; args=" "%(strargs)s" msgstr "" -#: ../nova/virt/xenapi/vmops.py:638 +#: ../nova/virt/xenapi/vmops.py:653 #, python-format msgid "OpenSSL error: %s" msgstr "" @@ -1553,74 +1561,74 @@ msgstr "" msgid "Launching VPN for %s" msgstr "" -#: ../nova/image/s3.py:89 +#: ../nova/image/s3.py:99 #, python-format msgid "Image %s could not be found" msgstr "" -#: ../nova/api/ec2/__init__.py:126 +#: ../nova/api/ec2/__init__.py:125 msgid "Too many failed authentications." msgstr "" -#: ../nova/api/ec2/__init__.py:136 +#: ../nova/api/ec2/__init__.py:135 #, python-format msgid "" "Access key %(access_key)s has had %(failures)d failed authentications and " "will be locked out for %(lock_mins)d minutes." msgstr "" -#: ../nova/api/ec2/__init__.py:174 ../nova/objectstore/handler.py:140 +#: ../nova/api/ec2/__init__.py:173 ../nova/objectstore/handler.py:140 #, python-format msgid "Authentication Failure: %s" msgstr "" -#: ../nova/api/ec2/__init__.py:187 +#: ../nova/api/ec2/__init__.py:186 #, python-format msgid "Authenticated Request For %(uname)s:%(pname)s)" msgstr "" -#: ../nova/api/ec2/__init__.py:212 +#: ../nova/api/ec2/__init__.py:211 #, python-format msgid "action: %s" msgstr "" -#: ../nova/api/ec2/__init__.py:214 +#: ../nova/api/ec2/__init__.py:213 #, python-format msgid "arg: %(key)s\t\tval: %(value)s" msgstr "" -#: ../nova/api/ec2/__init__.py:286 +#: ../nova/api/ec2/__init__.py:285 #, python-format msgid "" "Unauthorized request for controller=%(controller)s and action=%(action)s" msgstr "" -#: ../nova/api/ec2/__init__.py:319 +#: ../nova/api/ec2/__init__.py:318 #, python-format msgid "InstanceNotFound raised: %s" msgstr "" -#: ../nova/api/ec2/__init__.py:325 +#: ../nova/api/ec2/__init__.py:324 #, python-format msgid "VolumeNotFound raised: %s" msgstr "" -#: ../nova/api/ec2/__init__.py:331 +#: ../nova/api/ec2/__init__.py:330 #, python-format msgid "NotFound raised: %s" msgstr "" -#: ../nova/api/ec2/__init__.py:334 +#: ../nova/api/ec2/__init__.py:333 #, python-format msgid "ApiError raised: %s" msgstr "" -#: ../nova/api/ec2/__init__.py:343 +#: ../nova/api/ec2/__init__.py:342 #, python-format msgid "Unexpected error raised: %s" msgstr "" -#: ../nova/api/ec2/__init__.py:348 +#: ../nova/api/ec2/__init__.py:347 msgid "An unknown error has occurred. Please try your request again." msgstr "" @@ -1708,6 +1716,11 @@ msgstr "" msgid "Found instance: %s" msgstr "" +#: ../nova/volume/san.py:67 +#, python-format +msgid "Could not find iSCSI export for volume %s" +msgstr "" + #: ../nova/api/ec2/apirequest.py:99 #, python-format msgid "" @@ -2155,51 +2168,56 @@ msgid "" "on interface %(interface)s" msgstr "" -#: ../nova/network/manager.py:139 -msgid "setting network host" +#: ../nova/virt/fake.py:224 +#, python-format +msgid "Instance %s Not Found" msgstr "" -#: ../nova/network/manager.py:194 -#, python-format -msgid "Leasing IP %s" +#: ../nova/network/manager.py:143 +msgid "setting network host" msgstr "" #: ../nova/network/manager.py:198 #, python-format -msgid "IP %s leased that isn't associated" +msgid "Leasing IP %s" msgstr "" #: ../nova/network/manager.py:202 #, python-format +msgid "IP %s leased that isn't associated" +msgstr "" + +#: ../nova/network/manager.py:206 +#, python-format msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: ../nova/network/manager.py:210 +#: ../nova/network/manager.py:214 #, python-format msgid "IP %s leased that was already deallocated" msgstr "" -#: ../nova/network/manager.py:215 +#: ../nova/network/manager.py:219 #, python-format msgid "Releasing IP %s" msgstr "" -#: ../nova/network/manager.py:219 +#: ../nova/network/manager.py:223 #, python-format msgid "IP %s released that isn't associated" msgstr "" -#: ../nova/network/manager.py:223 +#: ../nova/network/manager.py:227 #, python-format msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: ../nova/network/manager.py:226 +#: ../nova/network/manager.py:230 #, python-format msgid "IP %s released that was not leased" msgstr "" -#: ../nova/network/manager.py:461 +#: ../nova/network/manager.py:464 #, python-format msgid "Dissassociated %s stale fixed ip(s)" msgstr "" From 0f8b2b1353982bd2c4e44c18f4eb771ec8a47289 Mon Sep 17 00:00:00 2001 From: "jaypipes@gmail.com" <> Date: Tue, 15 Feb 2011 12:39:17 -0500 Subject: [PATCH 026/111] Replace placeholders in nova.pot with some actual values. --- po/nova.pot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/po/nova.pot b/po/nova.pot index f747ae0f..6cbb2f12 100644 --- a/po/nova.pot +++ b/po/nova.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-02-15 11:05-0500\n" +"POT-Creation-Date: 2011-02-15 12:38-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" From 662b27968029a3288fca7673cebdbb4dff8bd4c7 Mon Sep 17 00:00:00 2001 From: brian-lamar Date: Tue, 15 Feb 2011 15:33:17 -0500 Subject: [PATCH 027/111] Added teammate Naveed to authors file for his help. --- Authors | 1 + 1 file changed, 1 insertion(+) diff --git a/Authors b/Authors index e8bb5845..03f30084 100644 --- a/Authors +++ b/Authors @@ -43,6 +43,7 @@ Monty Taylor MORITA Kazutaka Muneyuki Noguchi Nachi Ueno +Naveed Massjouni Paul Voccio Ricardo Carrillo Cruz Rick Clark From 62d71f4b85ff958229de9fe1068d5028887913f3 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Tue, 15 Feb 2011 18:20:44 -0600 Subject: [PATCH 028/111] stubbed out reset networkin xenapi VM tests to solve domid problem --- nova/tests/test_xenapi.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index d5660c5d..6b8efc9d 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -32,6 +32,7 @@ from nova.virt import xenapi_conn from nova.virt.xenapi import fake as xenapi_fake from nova.virt.xenapi import volume_utils from nova.virt.xenapi.vmops import SimpleDH +from nova.virt.xenapi.vmops import VMOps from nova.tests.db import fakes as db_fakes from nova.tests.xenapi import stubs from nova.tests.glance import stubs as glance_stubs @@ -141,6 +142,10 @@ class XenAPIVolumeTestCase(test.TestCase): self.stubs.UnsetAll() +def reset_network(*args): + pass + + class XenAPIVMTestCase(test.TestCase): """ Unit tests for VM operations @@ -162,6 +167,7 @@ class XenAPIVMTestCase(test.TestCase): stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests) stubs.stubout_get_this_vm_uuid(self.stubs) stubs.stubout_stream_disk(self.stubs) + self.stubs.Set(VMOps, 'reset_network', reset_network) glance_stubs.stubout_glance_client(self.stubs, glance_stubs.FakeGlance) self.conn = xenapi_conn.get_connection(False) From 4f8703260bb7e8c16dbb082f9b0f3ca1d4edef3c Mon Sep 17 00:00:00 2001 From: Christian Berendt Date: Wed, 16 Feb 2011 12:15:48 +0100 Subject: [PATCH 029/111] added functionality to nova-manage to list created networks --- bin/nova-manage | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/bin/nova-manage b/bin/nova-manage index 7835ca55..f7cf77ad 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -499,6 +499,18 @@ class NetworkCommands(object): vlan_start=int(vlan_start), vpn_start=int(vpn_start)) + def list(self): + """List all created networks""" + print "%-18s\t%-15s\t%-15s\t%-15s" % ('CIDR', + 'netmask', + 'dhcp_start', + 'DNS') + for network in db.network_get_all(context.get_admin_context()): + print "%-18s\t%-15s\t%-15s\t%-15s" % (network.cidr, + network.netmask, + network.dhcp_start, + network.dns) + class ServiceCommands(object): """Enable and disable running services""" From 986fc0a5baa8a1eee7e628f1caced7e8fba30d0a Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Wed, 16 Feb 2011 16:19:57 -0500 Subject: [PATCH 030/111] Added alternate email to mailmap --- .mailmap | 1 + Authors | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index c6f6c9a8..a0552088 100644 --- a/.mailmap +++ b/.mailmap @@ -34,3 +34,4 @@ + diff --git a/Authors b/Authors index c57ca8ae..eb9d540b 100644 --- a/Authors +++ b/Authors @@ -4,7 +4,6 @@ Anthony Young Antony Messerli Armando Migliaccio Bilal Akhtar -Brian Lamar Chiradeep Vittal Chmouel Boudjnah Chris Behrens From ac4efd0877556c2f8d91d5703c78cefb7b4f42b1 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Wed, 16 Feb 2011 16:22:16 -0500 Subject: [PATCH 031/111] Accidently removed myself from Authors. --- Authors | 1 + 1 file changed, 1 insertion(+) diff --git a/Authors b/Authors index eb9d540b..c57ca8ae 100644 --- a/Authors +++ b/Authors @@ -4,6 +4,7 @@ Anthony Young Antony Messerli Armando Migliaccio Bilal Akhtar +Brian Lamar Chiradeep Vittal Chmouel Boudjnah Chris Behrens From 550c482018e07a5d8dd875d8751891f48b213c1e Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Wed, 16 Feb 2011 16:40:40 -0500 Subject: [PATCH 032/111] Flipped mailmap entries --- .mailmap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index a0552088..b2287d65 100644 --- a/.mailmap +++ b/.mailmap @@ -34,4 +34,4 @@ - + From 94e8e5dc2ca5311f8da1ec010057f3a154da5f32 Mon Sep 17 00:00:00 2001 From: Christian Berendt Date: Thu, 17 Feb 2011 16:46:55 +0100 Subject: [PATCH 033/111] added more I18N --- bin/nova-manage | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index f7cf77ad..c6427790 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -501,9 +501,9 @@ class NetworkCommands(object): def list(self): """List all created networks""" - print "%-18s\t%-15s\t%-15s\t%-15s" % ('CIDR', - 'netmask', - 'dhcp_start', + print "%-18s\t%-15s\t%-15s\t%-15s" % (_('network'), + _('netmask'), + _('start address'), 'DNS') for network in db.network_get_all(context.get_admin_context()): print "%-18s\t%-15s\t%-15s\t%-15s" % (network.cidr, From b6760ad51794adfa1b765178f22001b4dc86fcfa Mon Sep 17 00:00:00 2001 From: Christian Berendt Date: Thu, 17 Feb 2011 16:58:00 +0100 Subject: [PATCH 034/111] added new functionality to list all defined fixed ips --- bin/nova-manage | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/bin/nova-manage b/bin/nova-manage index e4c0684c..a8c9441e 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -433,6 +433,37 @@ class ProjectCommands(object): "nova-api server on this host.") +class FixedIpCommands(object): + """Class for managing fixed ip.""" + + def list(self, host=None): + """Lists all fixed ips (optionally by host) arguments: [host]""" + ctxt = context.get_admin_context() + if host == None: + fixed_ips = db.fixed_ip_get_all(ctxt) + else: + fixed_ips = db.fixed_ip_get_all_by_host(ctxt, host) + + print "%-18s\t%-15s\t%-17s\t%-15s\t%s" % (_('network'), + _('IP address'), + _('MAC address'), + _('hostname'), + _('host')) + for fixed_ip in fixed_ips: + hostname = None + host = None + mac_address = None + if fixed_ip['instance']: + instance = fixed_ip['instance'] + hostname = instance['hostname'] + host = instance['host'] + mac_address = instance['mac_address'] + print "%-18s\t%-15s\t%-17s\t%-15s\t%s" % ( + fixed_ip['network']['cidr'], + fixed_ip['address'], + mac_address, hostname, host) + + class FloatingIpCommands(object): """Class for managing floating ip.""" From c4f2a371a33d8a3ee508ce37f8e08c6fd5bb6a31 Mon Sep 17 00:00:00 2001 From: Christian Berendt Date: Thu, 17 Feb 2011 17:10:51 +0100 Subject: [PATCH 035/111] added entry in the category list --- bin/nova-manage | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/nova-manage b/bin/nova-manage index a8c9441e..ddc78f7e 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -653,6 +653,7 @@ CATEGORIES = [ ('role', RoleCommands), ('shell', ShellCommands), ('vpn', VpnCommands), + ('fixed', FixedIpCommands), ('floating', FloatingIpCommands), ('network', NetworkCommands), ('service', ServiceCommands), From a09568eeb87a3177a0c581b5a1d4c5de4d7a5de2 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Thu, 17 Feb 2011 12:13:20 -0500 Subject: [PATCH 036/111] Switched mailmap entries --- .mailmap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index b2287d65..a0552088 100644 --- a/.mailmap +++ b/.mailmap @@ -34,4 +34,4 @@ - + From 0c58f5f6ce0373682c093576181e5533ea6785c0 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Thu, 17 Feb 2011 21:27:48 +0100 Subject: [PATCH 037/111] Re-alphabetise Authors, move extra addressses into .mailmap. --- .mailmap | 50 ++++++++++++++++++++++++++++---------------------- Authors | 10 +++++----- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/.mailmap b/.mailmap index a0552088..a839eba6 100644 --- a/.mailmap +++ b/.mailmap @@ -1,37 +1,43 @@ # Format is: -# - - - - - - - - - +# +# - + + + + + + + + + + + + + - + Masumoto + + + - + + + + - + + + + - - - - - - - - + diff --git a/Authors b/Authors index 395c6b9e..494e614a 100644 --- a/Authors +++ b/Authors @@ -3,17 +3,17 @@ Anne Gentle Anthony Young Antony Messerli Armando Migliaccio -Brian Waldon Bilal Akhtar Brian Lamar -Brian Schott +Brian Schott +Brian Waldon Chiradeep Vittal Chmouel Boudjnah Chris Behrens Christian Berendt Cory Wright -David Pravec Dan Prince +David Pravec Dean Troyer Devin Carlen Ed Leafe @@ -44,7 +44,7 @@ Monsyne Dragon Monty Taylor MORITA Kazutaka Muneyuki Noguchi -Nachi Ueno +Nachi Ueno Naveed Massjouni Paul Voccio Ricardo Carrillo Cruz @@ -59,7 +59,7 @@ Soren Hansen Thierry Carrez Todd Willey Trey Morris -Tushar Patil +Tushar Patil Vasiliy Shlykov Vishvananda Ishaya Youcef Laribi From b7dd46b3052d7d1d1cca2712c1ecf611b033bafa Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Fri, 18 Feb 2011 10:24:55 +0100 Subject: [PATCH 038/111] Use WatchedFileHandler instead of RotatingFileHandler. --- nova/log.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/log.py b/nova/log.py index 87a6dd51..6b201ffc 100644 --- a/nova/log.py +++ b/nova/log.py @@ -94,7 +94,7 @@ critical = logging.critical log = logging.log # handlers StreamHandler = logging.StreamHandler -RotatingFileHandler = logging.handlers.RotatingFileHandler +WatchedFileHandler = logging.handlers.WatchedFileHandler # logging.SysLogHandler is nicer than logging.logging.handler.SysLogHandler. SysLogHandler = logging.handlers.SysLogHandler @@ -139,7 +139,7 @@ def basicConfig(): logging.root.addHandler(syslog) logpath = get_log_file_path() if logpath: - logfile = RotatingFileHandler(logpath) + logfile = WatchedFileHandler(logpath) logfile.setFormatter(_formatter) logging.root.addHandler(logfile) From f88c4415fe757076f8520a17e9665d6a98f66a0d Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Fri, 18 Feb 2011 16:02:55 +0100 Subject: [PATCH 039/111] Switch to API_listen and API_listen_port, drop wsgi.paste_config_to_flags --- bin/nova-api | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/bin/nova-api b/bin/nova-api index eb59d019..e7ee6f6f 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -47,6 +47,12 @@ FLAGS = flags.FLAGS API_ENDPOINTS = ['ec2', 'osapi'] +for api in API_ENDPOINTS: + flags.DEFINE_string("%s_api_listen" % api, "0.0.0.0", + "IP address to listen to for API %s" % api) + flags.DEFINE_integer("%s_api_listen_port" % api, + getattr(FLAGS, "%s_port" % api), + "Port to listen to for API %s" % api) def run_app(paste_config_file): LOG.debug(_("Using paste.deploy config at: %s"), paste_config_file) @@ -57,14 +63,10 @@ def run_app(paste_config_file): LOG.debug(_("No paste configuration for app: %s"), api) continue LOG.debug(_("App Config: %(api)s\n%(config)r") % locals()) - wsgi.paste_config_to_flags(config, { - "verbose": FLAGS.verbose, - "%s_host" % api: getattr(FLAGS, "%s_host" % api), - "%s_port" % api: getattr(FLAGS, "%s_port" % api)}) LOG.info(_("Running %s API"), api) app = wsgi.load_paste_app(paste_config_file, api) - apps.append((app, getattr(FLAGS, "%s_port" % api), - config.get('listen', '0.0.0.0'))) + apps.append((app, getattr(FLAGS, "%s_api_listen_port" % api), + getattr(FLAGS, "%s_api_listen" % api))) if len(apps) == 0: LOG.error(_("No known API applications configured in %s."), paste_config_file) @@ -82,6 +84,10 @@ if __name__ == '__main__': FLAGS(sys.argv) LOG.audit(_("Starting nova-api node (version %s)"), version.version_string_with_vcs()) + LOG.debug(_("Full set of FLAGS:")) + for flag in FLAGS: + flag_get = FLAGS.get(flag, None) + LOG.debug("%(flag)s : %(flag_get)s" % locals()) conf = wsgi.paste_config_file('nova-api.conf') if conf: run_app(conf) From 9667dc609f791e7dbb0fd9e68eddb89e3cc6bdf7 Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Fri, 18 Feb 2011 16:08:33 +0100 Subject: [PATCH 040/111] Set up logging once FLAGS properly read, no need to redo logging config anymore (was inoperant anyway) --- bin/nova-api | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/bin/nova-api b/bin/nova-api index e7ee6f6f..46f69524 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -39,10 +39,6 @@ from nova import log as logging from nova import version from nova import wsgi -logging.basicConfig() -LOG = logging.getLogger('nova.api') -LOG.setLevel(logging.DEBUG) - FLAGS = flags.FLAGS API_ENDPOINTS = ['ec2', 'osapi'] @@ -72,8 +68,6 @@ def run_app(paste_config_file): paste_config_file) return - # NOTE(todd): redo logging config, verbose could be set in paste config - logging.basicConfig() server = wsgi.Server() for app in apps: server.start(*app) @@ -82,6 +76,8 @@ def run_app(paste_config_file): if __name__ == '__main__': FLAGS(sys.argv) + logging.basicConfig() + LOG = logging.getLogger('nova.api') LOG.audit(_("Starting nova-api node (version %s)"), version.version_string_with_vcs()) LOG.debug(_("Full set of FLAGS:")) From 2ff58708dcc060247237e558a69af1db377045bc Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Fri, 18 Feb 2011 16:21:14 +0100 Subject: [PATCH 041/111] Port changes to nova-combined, rename flags to API_listen and API_listen_port --- bin/nova-api | 8 ++++---- bin/nova-combined | 20 ++++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/bin/nova-api b/bin/nova-api index 46f69524..8d47a656 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -44,9 +44,9 @@ FLAGS = flags.FLAGS API_ENDPOINTS = ['ec2', 'osapi'] for api in API_ENDPOINTS: - flags.DEFINE_string("%s_api_listen" % api, "0.0.0.0", + flags.DEFINE_string("%s_listen" % api, "0.0.0.0", "IP address to listen to for API %s" % api) - flags.DEFINE_integer("%s_api_listen_port" % api, + flags.DEFINE_integer("%s_listen_port" % api, getattr(FLAGS, "%s_port" % api), "Port to listen to for API %s" % api) @@ -61,8 +61,8 @@ def run_app(paste_config_file): LOG.debug(_("App Config: %(api)s\n%(config)r") % locals()) LOG.info(_("Running %s API"), api) app = wsgi.load_paste_app(paste_config_file, api) - apps.append((app, getattr(FLAGS, "%s_api_listen_port" % api), - getattr(FLAGS, "%s_api_listen" % api))) + apps.append((app, getattr(FLAGS, "%s_listen_port" % api), + getattr(FLAGS, "%s_listen" % api))) if len(apps) == 0: LOG.error(_("No known API applications configured in %s."), paste_config_file) diff --git a/bin/nova-combined b/bin/nova-combined index 889600eb..40dc2945 100755 --- a/bin/nova-combined +++ b/bin/nova-combined @@ -45,6 +45,14 @@ from nova import wsgi FLAGS = flags.FLAGS +API_ENDPOINTS = ['ec2', 'osapi'] + +for api in API_ENDPOINTS: + flags.DEFINE_string("%s_listen" % api, "0.0.0.0", + "IP address to listen to for API %s" % api) + flags.DEFINE_integer("%s_listen_port" % api, + getattr(FLAGS, "%s_port" % api), + "Port to listen to for API %s" % api) if __name__ == '__main__': utils.default_flagfile() @@ -57,21 +65,17 @@ if __name__ == '__main__': scheduler = service.Service.create(binary='nova-scheduler') #objectstore = service.Service.create(binary='nova-objectstore') - service.serve(compute, network, volume, scheduler) +# service.serve(compute, network, volume, scheduler) apps = [] paste_config_file = wsgi.paste_config_file('nova-api.conf') - for api in ['osapi', 'ec2']: + for api in API_ENDPOINTS: config = wsgi.load_paste_configuration(paste_config_file, api) if config is None: continue - wsgi.paste_config_to_flags(config, { - "verbose": FLAGS.verbose, - "%s_host" % api: getattr(FLAGS, "%s_host" % api), - "%s_port" % api: getattr(FLAGS, "%s_port" % api)}) app = wsgi.load_paste_app(paste_config_file, api) - apps.append((app, getattr(FLAGS, "%s_port" % api), - config.get('listen', '0.0.0.0'))) + apps.append((app, getattr(FLAGS, "%s_listen_port" % api), + getattr(FLAGS, "%s_listen" % api))) if len(apps) > 0: logging.basicConfig() server = wsgi.Server() From 5eaabbdc476a4d91ca40683b52b82f6fd4259947 Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Fri, 18 Feb 2011 16:23:52 +0100 Subject: [PATCH 042/111] PEP8 fix --- bin/nova-api | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/nova-api b/bin/nova-api index 8d47a656..1228f723 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -50,6 +50,7 @@ for api in API_ENDPOINTS: getattr(FLAGS, "%s_port" % api), "Port to listen to for API %s" % api) + def run_app(paste_config_file): LOG.debug(_("Using paste.deploy config at: %s"), paste_config_file) apps = [] From 478f5cff7e4b9e805a1eeaac4f033d22adfae48f Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Fri, 18 Feb 2011 16:37:00 +0100 Subject: [PATCH 043/111] Fixed testing mode leftover --- bin/nova-combined | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nova-combined b/bin/nova-combined index 40dc2945..dd21c8df 100755 --- a/bin/nova-combined +++ b/bin/nova-combined @@ -65,7 +65,7 @@ if __name__ == '__main__': scheduler = service.Service.create(binary='nova-scheduler') #objectstore = service.Service.create(binary='nova-objectstore') -# service.serve(compute, network, volume, scheduler) + service.serve(compute, network, volume, scheduler) apps = [] paste_config_file = wsgi.paste_config_file('nova-api.conf') From 13d01bc6820b7377a6d72e4bc5a0b02cbca49ffa Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Sun, 20 Feb 2011 23:16:10 -0800 Subject: [PATCH 045/111] fixes for various logging errors and issues --- nova/flags.py | 4 ++ nova/log.py | 115 ++++++++++++++++++++------------ nova/tests/fake_flags.py | 2 + nova/tests/test_auth.py | 9 --- nova/tests/test_console.py | 2 - nova/tests/test_direct.py | 1 - nova/tests/test_localization.py | 1 - nova/tests/test_log.py | 65 +++++++++--------- run_tests.py | 5 +- 9 files changed, 111 insertions(+), 93 deletions(-) diff --git a/nova/flags.py b/nova/flags.py index f64a62da..2f3bdd67 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -38,6 +38,7 @@ class FlagValues(gflags.FlagValues): defined after the initial parsing. """ + initialized = False def __init__(self, extra_context=None): gflags.FlagValues.__init__(self) @@ -45,6 +46,8 @@ class FlagValues(gflags.FlagValues): self.__dict__['__was_already_parsed'] = False self.__dict__['__stored_argv'] = [] self.__dict__['__extra_context'] = extra_context + # NOTE(vish): force a pseudo flag to keep track of whether + # flags have been parsed already def __call__(self, argv): # We're doing some hacky stuff here so that we don't have to copy @@ -90,6 +93,7 @@ class FlagValues(gflags.FlagValues): self.__dict__['__stored_argv'] = original_argv self.__dict__['__was_already_parsed'] = True self.ClearDirty() + FlagValues.initialized = True return args def Reset(self): diff --git a/nova/log.py b/nova/log.py index 6b201ffc..12b695a4 100644 --- a/nova/log.py +++ b/nova/log.py @@ -117,7 +117,22 @@ def _get_binary_name(): return os.path.basename(inspect.stack()[-1][1]) -def get_log_file_path(binary=None): +def _get_level_from_flags(name): + # if exactly "nova", or a child logger, honor the verbose flag + if (name == "nova" or name.startswith("nova.")) and FLAGS.verbose: + return 'DEBUG' + for pair in FLAGS.default_log_levels: + logger, _sep, level = pair.partition('=') + # NOTE(todd): if we set a.b, we want a.b.c to have the same level + # (but not a.bc, so we check the dot) + if name == logger: + return level + if name.startswith(logger) and name[len(logger)] == '.': + return level + return 'INFO' + + +def _get_log_file_path(binary=None): if FLAGS.logfile: return FLAGS.logfile if FLAGS.logdir: @@ -126,22 +141,13 @@ def get_log_file_path(binary=None): def basicConfig(): - logging.basicConfig() - for handler in logging.root.handlers: - handler.setFormatter(_formatter) - if FLAGS.verbose: - logging.root.setLevel(logging.DEBUG) - else: - logging.root.setLevel(logging.INFO) - if FLAGS.use_syslog: - syslog = SysLogHandler(address='/dev/log') - syslog.setFormatter(_formatter) - logging.root.addHandler(syslog) - logpath = get_log_file_path() - if logpath: - logfile = WatchedFileHandler(logpath) - logfile.setFormatter(_formatter) - logging.root.addHandler(logfile) + pass + + +logging.basicConfig = basicConfig +_syslog = SysLogHandler(address='/dev/log') +_filelog = None +_streamlog = StreamHandler() class NovaLogger(logging.Logger): @@ -151,23 +157,24 @@ class NovaLogger(logging.Logger): This becomes the class that is instanciated by logging.getLogger. """ def __init__(self, name, level=NOTSET): - level_name = self._get_level_from_flags(name, FLAGS) - level = globals()[level_name] logging.Logger.__init__(self, name, level) + self.initialized = False + if flags.FlagValues.initialized: + self._setup_from_flags() - def _get_level_from_flags(self, name, FLAGS): - # if exactly "nova", or a child logger, honor the verbose flag - if (name == "nova" or name.startswith("nova.")) and FLAGS.verbose: - return 'DEBUG' - for pair in FLAGS.default_log_levels: - logger, _sep, level = pair.partition('=') - # NOTE(todd): if we set a.b, we want a.b.c to have the same level - # (but not a.bc, so we check the dot) - if name == logger: - return level - if name.startswith(logger) and name[len(logger)] == '.': - return level - return 'INFO' + def _setup_from_flags(self): + """Setup logger from flags""" + level_name = _get_level_from_flags(self.name) + self.setLevel(globals()[level_name]) + self.initialized = True + if not logging.root.initialized: + logging.root._setup_from_flags() + + def isEnabledFor(self, level): + """Reset level after flags have been loaded""" + if not self.initialized and flags.FlagValues.initialized: + self._setup_from_flags() + return logging.Logger.isEnabledFor(self, level) def _log(self, level, msg, args, exc_info=None, extra=None, context=None): """Extract context from any log call""" @@ -176,12 +183,12 @@ class NovaLogger(logging.Logger): if context: extra.update(_dictify_context(context)) extra.update({"nova_version": version.version_string_with_vcs()}) - logging.Logger._log(self, level, msg, args, exc_info, extra) + return logging.Logger._log(self, level, msg, args, exc_info, extra) def addHandler(self, handler): """Each handler gets our custom formatter""" handler.setFormatter(_formatter) - logging.Logger.addHandler(self, handler) + return logging.Logger.addHandler(self, handler) def audit(self, msg, *args, **kwargs): """Shortcut for our AUDIT level""" @@ -192,7 +199,7 @@ class NovaLogger(logging.Logger): """Logging.exception doesn't handle kwargs, so breaks context""" if not kwargs.get('exc_info'): kwargs['exc_info'] = 1 - self.error(msg, *args, **kwargs) + return self.error(msg, *args, **kwargs) # NOTE(todd): does this really go here, or in _log ? extra = kwargs.get('extra') if not extra: @@ -209,6 +216,8 @@ class NovaLogger(logging.Logger): def handle_exception(type, value, tb): + if len(logging.root.handlers) == 0: + logging.root.addHandler(_streamlog) logging.root.critical(str(value), exc_info=(type, value, tb)) @@ -216,15 +225,6 @@ sys.excepthook = handle_exception logging.setLoggerClass(NovaLogger) -class NovaRootLogger(NovaLogger): - pass - -if not isinstance(logging.root, NovaRootLogger): - logging.root = NovaRootLogger("nova.root", WARNING) - NovaLogger.root = logging.root - NovaLogger.manager.root = logging.root - - class NovaFormatter(logging.Formatter): """ A nova.context.RequestContext aware formatter configured through flags. @@ -271,6 +271,33 @@ class NovaFormatter(logging.Formatter): _formatter = NovaFormatter() +class NovaRootLogger(NovaLogger): + def __init__(self, name, level=NOTSET): + NovaLogger.__init__(self, name, level) + self.addHandler(_streamlog) + + def _setup_from_flags(self): + """Setup logger from flags""" + global _filelog + if FLAGS.use_syslog: + self.addHandler(_syslog) + logpath = _get_log_file_path() + if logpath: + if not _filelog: + _filelog = WatchedFileHandler(logpath) + self.addHandler(_filelog) + self.removeHandler(_streamlog) + return NovaLogger._setup_from_flags(self) + + +if not isinstance(logging.root, NovaRootLogger): + for handler in logging.root.handlers: + logging.root.removeHandler(handler) + logging.root = NovaRootLogger("nova") + NovaLogger.root = logging.root + NovaLogger.manager.root = logging.root + + def audit(msg, *args, **kwargs): """Shortcut for logging to root log with sevrity 'AUDIT'.""" if len(logging.root.handlers) == 0: diff --git a/nova/tests/fake_flags.py b/nova/tests/fake_flags.py index 1097488e..68b14a46 100644 --- a/nova/tests/fake_flags.py +++ b/nova/tests/fake_flags.py @@ -41,3 +41,5 @@ FLAGS.iscsi_num_targets = 8 FLAGS.verbose = True FLAGS.sql_connection = 'sqlite:///nova.sqlite' FLAGS.use_ipv6 = True +FLAGS.logfile = 'run_tests.err' +flags.FlagValues.initialized = True diff --git a/nova/tests/test_auth.py b/nova/tests/test_auth.py index 35ffffb6..2a781703 100644 --- a/nova/tests/test_auth.py +++ b/nova/tests/test_auth.py @@ -327,15 +327,6 @@ class AuthManagerTestCase(object): class AuthManagerLdapTestCase(AuthManagerTestCase, test.TestCase): auth_driver = 'nova.auth.ldapdriver.FakeLdapDriver' - def __init__(self, *args, **kwargs): - AuthManagerTestCase.__init__(self) - test.TestCase.__init__(self, *args, **kwargs) - import nova.auth.fakeldap as fakeldap - if FLAGS.flush_db: - LOG.info("Flushing datastore") - r = fakeldap.Store.instance() - r.flushdb() - class AuthManagerDbTestCase(AuthManagerTestCase, test.TestCase): auth_driver = 'nova.auth.dbdriver.DbDriver' diff --git a/nova/tests/test_console.py b/nova/tests/test_console.py index 85bf9445..49ff2441 100644 --- a/nova/tests/test_console.py +++ b/nova/tests/test_console.py @@ -21,7 +21,6 @@ Tests For Console proxy. """ import datetime -import logging from nova import context from nova import db @@ -38,7 +37,6 @@ FLAGS = flags.FLAGS class ConsoleTestCase(test.TestCase): """Test case for console proxy""" def setUp(self): - logging.getLogger().setLevel(logging.DEBUG) super(ConsoleTestCase, self).setUp() self.flags(console_driver='nova.console.fake.FakeConsoleProxy', stub_compute=True) diff --git a/nova/tests/test_direct.py b/nova/tests/test_direct.py index 8a74b229..7656f539 100644 --- a/nova/tests/test_direct.py +++ b/nova/tests/test_direct.py @@ -19,7 +19,6 @@ """Tests for Direct API.""" import json -import logging import webob diff --git a/nova/tests/test_localization.py b/nova/tests/test_localization.py index 6992773f..393d7103 100644 --- a/nova/tests/test_localization.py +++ b/nova/tests/test_localization.py @@ -15,7 +15,6 @@ # under the License. import glob -import logging import os import re import sys diff --git a/nova/tests/test_log.py b/nova/tests/test_log.py index c2c9d777..ada8d0a5 100644 --- a/nova/tests/test_log.py +++ b/nova/tests/test_log.py @@ -1,9 +1,12 @@ import cStringIO from nova import context +from nova import flags from nova import log from nova import test +FLAGS = flags.FLAGS + def _fake_context(): return context.RequestContext(1, 1) @@ -14,15 +17,11 @@ class RootLoggerTestCase(test.TestCase): super(RootLoggerTestCase, self).setUp() self.log = log.logging.root - def tearDown(self): - super(RootLoggerTestCase, self).tearDown() - log.NovaLogger.manager.loggerDict = {} - def test_is_nova_instance(self): self.assert_(isinstance(self.log, log.NovaLogger)) - def test_name_is_nova_root(self): - self.assertEqual("nova.root", self.log.name) + def test_name_is_nova(self): + self.assertEqual("nova", self.log.name) def test_handlers_have_nova_formatter(self): formatters = [] @@ -45,25 +44,38 @@ class RootLoggerTestCase(test.TestCase): log.audit("foo", context=_fake_context()) self.assert_(True) # didn't raise exception + def test_will_be_verbose_if_verbose_flag_set(self): + self.flags(verbose=True) + self.log.initialized = False + log.audit("foo", context=_fake_context()) + self.assertEqual(log.DEBUG, self.log.level) + + def test_will_not_be_verbose_if_verbose_flag_not_set(self): + self.flags(verbose=False) + self.log.initialized = False + log.audit("foo", context=_fake_context()) + self.assertEqual(log.INFO, self.log.level) + class LogHandlerTestCase(test.TestCase): def test_log_path_logdir(self): - self.flags(logdir='/some/path') - self.assertEquals(log.get_log_file_path(binary='foo-bar'), + self.flags(logdir='/some/path', logfile=None) + self.assertEquals(log._get_log_file_path(binary='foo-bar'), '/some/path/foo-bar.log') def test_log_path_logfile(self): self.flags(logfile='/some/path/foo-bar.log') - self.assertEquals(log.get_log_file_path(binary='foo-bar'), + self.assertEquals(log._get_log_file_path(binary='foo-bar'), '/some/path/foo-bar.log') def test_log_path_none(self): - self.assertTrue(log.get_log_file_path(binary='foo-bar') is None) + self.flags(logdir=None, logfile=None) + self.assertTrue(log._get_log_file_path(binary='foo-bar') is None) def test_log_path_logfile_overrides_logdir(self): self.flags(logdir='/some/other/path', logfile='/some/path/foo-bar.log') - self.assertEquals(log.get_log_file_path(binary='foo-bar'), + self.assertEquals(log._get_log_file_path(binary='foo-bar'), '/some/path/foo-bar.log') @@ -76,13 +88,15 @@ class NovaFormatterTestCase(test.TestCase): logging_debug_format_suffix="--DBG") self.log = log.logging.root self.stream = cStringIO.StringIO() - handler = log.StreamHandler(self.stream) - self.log.addHandler(handler) + self.handler = log.StreamHandler(self.stream) + self.log.addHandler(self.handler) + self.level = self.log.level self.log.setLevel(log.DEBUG) def tearDown(self): + self.log.setLevel(self.level) + self.log.removeHandler(self.handler) super(NovaFormatterTestCase, self).tearDown() - log.NovaLogger.manager.loggerDict = {} def test_uncontextualized_log(self): self.log.info("foo") @@ -102,30 +116,15 @@ class NovaFormatterTestCase(test.TestCase): class NovaLoggerTestCase(test.TestCase): def setUp(self): super(NovaLoggerTestCase, self).setUp() - self.flags(default_log_levels=["nova-test=AUDIT"], verbose=False) + levels = FLAGS.default_log_levels + levels.append("nova-test=AUDIT") + self.flags(default_log_levels=levels, + verbose=True) self.log = log.getLogger('nova-test') - def tearDown(self): - super(NovaLoggerTestCase, self).tearDown() - log.NovaLogger.manager.loggerDict = {} - def test_has_level_from_flags(self): self.assertEqual(log.AUDIT, self.log.level) def test_child_log_has_level_of_parent_flag(self): l = log.getLogger('nova-test.foo') self.assertEqual(log.AUDIT, l.level) - - -class VerboseLoggerTestCase(test.TestCase): - def setUp(self): - super(VerboseLoggerTestCase, self).setUp() - self.flags(default_log_levels=["nova.test=AUDIT"], verbose=True) - self.log = log.getLogger('nova.test') - - def tearDown(self): - super(VerboseLoggerTestCase, self).tearDown() - log.NovaLogger.manager.loggerDict = {} - - def test_will_be_verbose_if_named_nova_and_verbose_flag_set(self): - self.assertEqual(log.DEBUG, self.log.level) diff --git a/run_tests.py b/run_tests.py index 24786e8a..bf12c62c 100644 --- a/run_tests.py +++ b/run_tests.py @@ -26,8 +26,6 @@ from nose import config from nose import result from nose import core -from nova import log as logging - class NovaTestResult(result.TextTestResult): def __init__(self, *args, **kw): @@ -60,7 +58,8 @@ class NovaTestRunner(core.TextTestRunner): if __name__ == '__main__': - logging.basicConfig() + if os.path.exists("nova.sqlite"): + os.unlink("nova.sqlite") c = config.Config(stream=sys.stdout, env=os.environ, verbosity=3, From d2308eeab57387305e5614a40eb59fc6f8dd7394 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Sun, 20 Feb 2011 23:18:09 -0800 Subject: [PATCH 046/111] move the fake initialized into fake flags --- nova/tests/fake_flags.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/tests/fake_flags.py b/nova/tests/fake_flags.py index 68b14a46..0a1011d8 100644 --- a/nova/tests/fake_flags.py +++ b/nova/tests/fake_flags.py @@ -42,4 +42,5 @@ FLAGS.verbose = True FLAGS.sql_connection = 'sqlite:///nova.sqlite' FLAGS.use_ipv6 = True FLAGS.logfile = 'run_tests.err' +# NOTE(vish): pretend like we've loaded flags from command line flags.FlagValues.initialized = True From 19c2952d4670fc5ef8f421933a850986d144756b Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Sun, 20 Feb 2011 23:36:36 -0800 Subject: [PATCH 047/111] remove extra references to logging.basicConfig --- bin/nova-api | 4 ++-- bin/nova-combined | 2 -- bin/nova-dhcpbridge | 1 - bin/nova-manage | 2 -- nova/log.py | 19 +++++++++++++------ nova/twistd.py | 1 - 6 files changed, 15 insertions(+), 14 deletions(-) diff --git a/bin/nova-api b/bin/nova-api index 11176a02..8b367488 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -39,7 +39,6 @@ from nova import log as logging from nova import version from nova import wsgi -logging.basicConfig() LOG = logging.getLogger('nova.api') LOG.setLevel(logging.DEBUG) @@ -71,7 +70,8 @@ def run_app(paste_config_file): return # NOTE(todd): redo logging config, verbose could be set in paste config - logging.basicConfig() + logging.root.setup_from_flags() + server = wsgi.Server() for app in apps: server.start(*app) diff --git a/bin/nova-combined b/bin/nova-combined index 913c866b..5911d901 100755 --- a/bin/nova-combined +++ b/bin/nova-combined @@ -49,7 +49,6 @@ FLAGS = flags.FLAGS if __name__ == '__main__': utils.default_flagfile() FLAGS(sys.argv) - logging.basicConfig() compute = service.Service.create(binary='nova-compute') network = service.Service.create(binary='nova-network') @@ -73,7 +72,6 @@ if __name__ == '__main__': apps.append((app, getattr(FLAGS, "%s_port" % api), getattr(FLAGS, "%s_host" % api))) if len(apps) > 0: - logging.basicConfig() server = wsgi.Server() for app in apps: server.start(*app) diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge index d38ba254..e0e6af82 100755 --- a/bin/nova-dhcpbridge +++ b/bin/nova-dhcpbridge @@ -102,7 +102,6 @@ def main(): flagfile = os.environ.get('FLAGFILE', FLAGS.dhcpbridge_flagfile) utils.default_flagfile(flagfile) argv = FLAGS(sys.argv) - logging.basicConfig() interface = os.environ.get('DNSMASQ_INTERFACE', 'br0') if int(os.environ.get('TESTING', '0')): FLAGS.fake_rabbit = True diff --git a/bin/nova-manage b/bin/nova-manage index 6d67252b..878a9afa 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -77,7 +77,6 @@ from nova import crypto from nova import db from nova import exception from nova import flags -from nova import log as logging from nova import quota from nova import rpc from nova import utils @@ -87,7 +86,6 @@ from nova.cloudpipe import pipelib from nova.db import migration -logging.basicConfig() FLAGS = flags.FLAGS flags.DECLARE('fixed_range', 'nova.network.manager') flags.DECLARE('num_networks', 'nova.network.manager') diff --git a/nova/log.py b/nova/log.py index 12b695a4..0a863c92 100644 --- a/nova/log.py +++ b/nova/log.py @@ -160,20 +160,20 @@ class NovaLogger(logging.Logger): logging.Logger.__init__(self, name, level) self.initialized = False if flags.FlagValues.initialized: - self._setup_from_flags() + self.setup_from_flags() - def _setup_from_flags(self): + def setup_from_flags(self): """Setup logger from flags""" level_name = _get_level_from_flags(self.name) self.setLevel(globals()[level_name]) self.initialized = True if not logging.root.initialized: - logging.root._setup_from_flags() + logging.root.setup_from_flags() def isEnabledFor(self, level): """Reset level after flags have been loaded""" if not self.initialized and flags.FlagValues.initialized: - self._setup_from_flags() + self.setup_from_flags() return logging.Logger.isEnabledFor(self, level) def _log(self, level, msg, args, exc_info=None, extra=None, context=None): @@ -276,18 +276,24 @@ class NovaRootLogger(NovaLogger): NovaLogger.__init__(self, name, level) self.addHandler(_streamlog) - def _setup_from_flags(self): + def setup_from_flags(self): """Setup logger from flags""" global _filelog if FLAGS.use_syslog: self.addHandler(_syslog) + else: + self.removeHandler(_syslog) logpath = _get_log_file_path() if logpath: if not _filelog: _filelog = WatchedFileHandler(logpath) self.addHandler(_filelog) self.removeHandler(_streamlog) - return NovaLogger._setup_from_flags(self) + else: + self.removeHandler(_filelog) + self.addHandler(_streamlog) + + return NovaLogger.setup_from_flags(self) if not isinstance(logging.root, NovaRootLogger): @@ -296,6 +302,7 @@ if not isinstance(logging.root, NovaRootLogger): logging.root = NovaRootLogger("nova") NovaLogger.root = logging.root NovaLogger.manager.root = logging.root +root=logging.root def audit(msg, *args, **kwargs): diff --git a/nova/twistd.py b/nova/twistd.py index 60ff7879..0e4db022 100644 --- a/nova/twistd.py +++ b/nova/twistd.py @@ -258,7 +258,6 @@ def serve(filename): print 'usage: %s [options] [start|stop|restart]' % argv[0] sys.exit(1) - logging.basicConfig() logging.debug(_("Full set of FLAGS:")) for flag in FLAGS: logging.debug("%s : %s" % (flag, FLAGS.get(flag, None))) From af334e57396433eef1abd39c90ca826a526f0454 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Sun, 20 Feb 2011 23:45:43 -0800 Subject: [PATCH 048/111] clean up location of method --- nova/log.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/nova/log.py b/nova/log.py index 0a863c92..57a550a0 100644 --- a/nova/log.py +++ b/nova/log.py @@ -117,21 +117,6 @@ def _get_binary_name(): return os.path.basename(inspect.stack()[-1][1]) -def _get_level_from_flags(name): - # if exactly "nova", or a child logger, honor the verbose flag - if (name == "nova" or name.startswith("nova.")) and FLAGS.verbose: - return 'DEBUG' - for pair in FLAGS.default_log_levels: - logger, _sep, level = pair.partition('=') - # NOTE(todd): if we set a.b, we want a.b.c to have the same level - # (but not a.bc, so we check the dot) - if name == logger: - return level - if name.startswith(logger) and name[len(logger)] == '.': - return level - return 'INFO' - - def _get_log_file_path(binary=None): if FLAGS.logfile: return FLAGS.logfile @@ -162,9 +147,24 @@ class NovaLogger(logging.Logger): if flags.FlagValues.initialized: self.setup_from_flags() + @staticmethod + def _get_level_from_flags(name): + # if exactly "nova", or a child logger, honor the verbose flag + if (name == "nova" or name.startswith("nova.")) and FLAGS.verbose: + return 'DEBUG' + for pair in FLAGS.default_log_levels: + logger, _sep, level = pair.partition('=') + # NOTE(todd): if we set a.b, we want a.b.c to have the same level + # (but not a.bc, so we check the dot) + if name == logger: + return level + if name.startswith(logger) and name[len(logger)] == '.': + return level + return 'INFO' + def setup_from_flags(self): """Setup logger from flags""" - level_name = _get_level_from_flags(self.name) + level_name = self._get_level_from_flags(self.name) self.setLevel(globals()[level_name]) self.initialized = True if not logging.root.initialized: @@ -302,7 +302,7 @@ if not isinstance(logging.root, NovaRootLogger): logging.root = NovaRootLogger("nova") NovaLogger.root = logging.root NovaLogger.manager.root = logging.root -root=logging.root +root = logging.root def audit(msg, *args, **kwargs): From 2fe1c738907575f04d5bcc5201877e635bc0eda8 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 21 Feb 2011 00:15:49 -0800 Subject: [PATCH 049/111] get rid of initialized flag --- nova/flags.py | 4 ++-- nova/log.py | 16 ++++------------ nova/tests/fake_flags.py | 2 -- nova/tests/test_log.py | 6 ++---- 4 files changed, 8 insertions(+), 20 deletions(-) diff --git a/nova/flags.py b/nova/flags.py index 2f3bdd67..72d123e2 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -29,7 +29,6 @@ import sys import gflags - class FlagValues(gflags.FlagValues): """Extension of gflags.FlagValues that allows undefined and runtime flags. @@ -93,7 +92,8 @@ class FlagValues(gflags.FlagValues): self.__dict__['__stored_argv'] = original_argv self.__dict__['__was_already_parsed'] = True self.ClearDirty() - FlagValues.initialized = True + from nova import log as logging + logging.reset() return args def Reset(self): diff --git a/nova/log.py b/nova/log.py index 57a550a0..8d240782 100644 --- a/nova/log.py +++ b/nova/log.py @@ -143,9 +143,7 @@ class NovaLogger(logging.Logger): """ def __init__(self, name, level=NOTSET): logging.Logger.__init__(self, name, level) - self.initialized = False - if flags.FlagValues.initialized: - self.setup_from_flags() + self.setup_from_flags() @staticmethod def _get_level_from_flags(name): @@ -166,15 +164,6 @@ class NovaLogger(logging.Logger): """Setup logger from flags""" level_name = self._get_level_from_flags(self.name) self.setLevel(globals()[level_name]) - self.initialized = True - if not logging.root.initialized: - logging.root.setup_from_flags() - - def isEnabledFor(self, level): - """Reset level after flags have been loaded""" - if not self.initialized and flags.FlagValues.initialized: - self.setup_from_flags() - return logging.Logger.isEnabledFor(self, level) def _log(self, level, msg, args, exc_info=None, extra=None, context=None): """Extract context from any log call""" @@ -304,6 +293,9 @@ if not isinstance(logging.root, NovaRootLogger): NovaLogger.manager.root = logging.root root = logging.root +def reset(): + root.setup_from_flags() + def audit(msg, *args, **kwargs): """Shortcut for logging to root log with sevrity 'AUDIT'.""" diff --git a/nova/tests/fake_flags.py b/nova/tests/fake_flags.py index 0a1011d8..59839b09 100644 --- a/nova/tests/fake_flags.py +++ b/nova/tests/fake_flags.py @@ -42,5 +42,3 @@ FLAGS.verbose = True FLAGS.sql_connection = 'sqlite:///nova.sqlite' FLAGS.use_ipv6 = True FLAGS.logfile = 'run_tests.err' -# NOTE(vish): pretend like we've loaded flags from command line -flags.FlagValues.initialized = True diff --git a/nova/tests/test_log.py b/nova/tests/test_log.py index ada8d0a5..122351ff 100644 --- a/nova/tests/test_log.py +++ b/nova/tests/test_log.py @@ -46,14 +46,12 @@ class RootLoggerTestCase(test.TestCase): def test_will_be_verbose_if_verbose_flag_set(self): self.flags(verbose=True) - self.log.initialized = False - log.audit("foo", context=_fake_context()) + log.reset() self.assertEqual(log.DEBUG, self.log.level) def test_will_not_be_verbose_if_verbose_flag_not_set(self): self.flags(verbose=False) - self.log.initialized = False - log.audit("foo", context=_fake_context()) + log.reset() self.assertEqual(log.INFO, self.log.level) From d4560d54769851ab16a98592cb181af70ce28cbe Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 21 Feb 2011 00:17:58 -0800 Subject: [PATCH 050/111] fix nova-api as well --- bin/nova-api | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nova-api b/bin/nova-api index 8b367488..5937f774 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -70,7 +70,7 @@ def run_app(paste_config_file): return # NOTE(todd): redo logging config, verbose could be set in paste config - logging.root.setup_from_flags() + logging.reset() server = wsgi.Server() for app in apps: From 0f9699dad51eda8bd6231b68ddfc3086f4702851 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 21 Feb 2011 00:22:45 -0800 Subject: [PATCH 051/111] removed extra comments and initialized from flags --- nova/flags.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/nova/flags.py b/nova/flags.py index 72d123e2..e2f7960e 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -37,7 +37,6 @@ class FlagValues(gflags.FlagValues): defined after the initial parsing. """ - initialized = False def __init__(self, extra_context=None): gflags.FlagValues.__init__(self) @@ -45,8 +44,6 @@ class FlagValues(gflags.FlagValues): self.__dict__['__was_already_parsed'] = False self.__dict__['__stored_argv'] = [] self.__dict__['__extra_context'] = extra_context - # NOTE(vish): force a pseudo flag to keep track of whether - # flags have been parsed already def __call__(self, argv): # We're doing some hacky stuff here so that we don't have to copy From 869f4437ec997b9e10cb091568bf9c9b9e30fc94 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 21 Feb 2011 00:24:35 -0800 Subject: [PATCH 052/111] add docstring to reset method --- nova/log.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/log.py b/nova/log.py index 8d240782..94eeecce 100644 --- a/nova/log.py +++ b/nova/log.py @@ -294,6 +294,7 @@ if not isinstance(logging.root, NovaRootLogger): root = logging.root def reset(): + """Resets logging handlers. Should be called if FLAGS changes.""" root.setup_from_flags() From 66fffaf8d301503455d6a41459957b2c31029bf3 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 21 Feb 2011 00:48:33 -0800 Subject: [PATCH 053/111] reset all loggers on flag change, not just root --- nova/log.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nova/log.py b/nova/log.py index 94eeecce..2b43f731 100644 --- a/nova/log.py +++ b/nova/log.py @@ -295,6 +295,9 @@ root = logging.root def reset(): """Resets logging handlers. Should be called if FLAGS changes.""" + for logger in logging.Logger.manager.loggerDict.itervalues(): + if isinstance(logger, NovaLogger): + logger.setup_from_flags() root.setup_from_flags() From dcb6dfb3b72ff36f5527aff07941ad261084c4a3 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 21 Feb 2011 01:07:46 -0800 Subject: [PATCH 054/111] simplify logic for parsing log level flags --- nova/log.py | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/nova/log.py b/nova/log.py index 2b43f731..0cd42d00 100644 --- a/nova/log.py +++ b/nova/log.py @@ -145,25 +145,14 @@ class NovaLogger(logging.Logger): logging.Logger.__init__(self, name, level) self.setup_from_flags() - @staticmethod - def _get_level_from_flags(name): - # if exactly "nova", or a child logger, honor the verbose flag - if (name == "nova" or name.startswith("nova.")) and FLAGS.verbose: - return 'DEBUG' + def setup_from_flags(self): + """Setup logger from flags""" for pair in FLAGS.default_log_levels: logger, _sep, level = pair.partition('=') # NOTE(todd): if we set a.b, we want a.b.c to have the same level # (but not a.bc, so we check the dot) - if name == logger: - return level - if name.startswith(logger) and name[len(logger)] == '.': - return level - return 'INFO' - - def setup_from_flags(self): - """Setup logger from flags""" - level_name = self._get_level_from_flags(self.name) - self.setLevel(globals()[level_name]) + if self.name == logger or self.name.startswith("%s." % logger): + self.setLevel(globals()[level]) def _log(self, level, msg, args, exc_info=None, extra=None, context=None): """Extract context from any log call""" @@ -281,8 +270,10 @@ class NovaRootLogger(NovaLogger): else: self.removeHandler(_filelog) self.addHandler(_streamlog) - - return NovaLogger.setup_from_flags(self) + if FLAGS.verbose: + self.setLevel(DEBUG) + else: + self.setLevel(INFO) if not isinstance(logging.root, NovaRootLogger): From 6cba789b7b5f1c932f0979e69881dd4713925746 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 21 Feb 2011 01:26:15 -0800 Subject: [PATCH 055/111] move exception hook into appropriate location and remove extra stuff from module namespace --- bin/nova-manage | 1 - nova/log.py | 45 +++++++++++++++++++++++---------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 878a9afa..86179871 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -85,7 +85,6 @@ from nova.auth import manager from nova.cloudpipe import pipelib from nova.db import migration - FLAGS = flags.FLAGS flags.DECLARE('fixed_range', 'nova.network.manager') flags.DECLARE('num_networks', 'nova.network.manager') diff --git a/nova/log.py b/nova/log.py index 0cd42d00..5ffb52cd 100644 --- a/nova/log.py +++ b/nova/log.py @@ -130,9 +130,6 @@ def basicConfig(): logging.basicConfig = basicConfig -_syslog = SysLogHandler(address='/dev/log') -_filelog = None -_streamlog = StreamHandler() class NovaLogger(logging.Logger): @@ -193,16 +190,6 @@ class NovaLogger(logging.Logger): self.error(message, **kwargs) -def handle_exception(type, value, tb): - if len(logging.root.handlers) == 0: - logging.root.addHandler(_streamlog) - logging.root.critical(str(value), exc_info=(type, value, tb)) - - -sys.excepthook = handle_exception -logging.setLoggerClass(NovaLogger) - - class NovaFormatter(logging.Formatter): """ A nova.context.RequestContext aware formatter configured through flags. @@ -251,25 +238,30 @@ _formatter = NovaFormatter() class NovaRootLogger(NovaLogger): def __init__(self, name, level=NOTSET): + self.logpath = None + self.filelog = None + self.syslog = SysLogHandler(address='/dev/log') + self.streamlog = StreamHandler() NovaLogger.__init__(self, name, level) - self.addHandler(_streamlog) def setup_from_flags(self): """Setup logger from flags""" global _filelog if FLAGS.use_syslog: - self.addHandler(_syslog) + self.addHandler(self.syslog) else: - self.removeHandler(_syslog) + self.removeHandler(self.syslog) logpath = _get_log_file_path() if logpath: - if not _filelog: - _filelog = WatchedFileHandler(logpath) - self.addHandler(_filelog) - self.removeHandler(_streamlog) + self.removeHandler(self.streamlog) + if logpath != self.logpath: + self.removeHandler(self.filelog) + self.filelog = WatchedFileHandler(logpath) + self.addHandler(self.filelog) + self.logpath = logpath else: - self.removeHandler(_filelog) - self.addHandler(_streamlog) + self.removeHandler(self.filelog) + self.addHandler(self.streamlog) if FLAGS.verbose: self.setLevel(DEBUG) else: @@ -284,6 +276,15 @@ if not isinstance(logging.root, NovaRootLogger): NovaLogger.manager.root = logging.root root = logging.root + +def handle_exception(type, value, tb): + root.critical(str(value), exc_info=(type, value, tb)) + + +sys.excepthook = handle_exception +logging.setLoggerClass(NovaLogger) + + def reset(): """Resets logging handlers. Should be called if FLAGS changes.""" for logger in logging.Logger.manager.loggerDict.itervalues(): From dfbe673ad368311e67b7b4aeff6096209bc87fe7 Mon Sep 17 00:00:00 2001 From: "jaypipes@gmail.com" <> Date: Mon, 21 Feb 2011 13:10:45 -0500 Subject: [PATCH 056/111] PEP8 errors and remove check in authors file for nova-core, since nova-core owns the translation export branch --- nova/tests/test_misc.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nova/tests/test_misc.py b/nova/tests/test_misc.py index 33c1777d..7a4d512a 100644 --- a/nova/tests/test_misc.py +++ b/nova/tests/test_misc.py @@ -46,6 +46,8 @@ class ProjectTestCase(test.TestCase): missing = set() for contributor in contributors: + if contributor == 'nova-core': + pass if not contributor in authors_file: missing.add(contributor) From 77cf11431361341d0b81b7fc3d3711f58e16d802 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 21 Feb 2011 10:52:28 -0800 Subject: [PATCH 057/111] reset to notset if level isn't in flags --- nova/log.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nova/log.py b/nova/log.py index 5ffb52cd..61a27988 100644 --- a/nova/log.py +++ b/nova/log.py @@ -144,12 +144,14 @@ class NovaLogger(logging.Logger): def setup_from_flags(self): """Setup logger from flags""" + level = NOTSET for pair in FLAGS.default_log_levels: - logger, _sep, level = pair.partition('=') + logger, _sep, level_name = pair.partition('=') # NOTE(todd): if we set a.b, we want a.b.c to have the same level # (but not a.bc, so we check the dot) if self.name == logger or self.name.startswith("%s." % logger): - self.setLevel(globals()[level]) + level = globals()[level_name] + self.setLevel(level) def _log(self, level, msg, args, exc_info=None, extra=None, context=None): """Extract context from any log call""" From f9225c5395db668c76363af680fd17e7ad48b09c Mon Sep 17 00:00:00 2001 From: "jaypipes@gmail.com" <> Date: Mon, 21 Feb 2011 13:55:25 -0500 Subject: [PATCH 058/111] Duh, continue skips iteration, not pass. #iamanidiot --- nova/tests/test_misc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/tests/test_misc.py b/nova/tests/test_misc.py index 7a4d512a..e6da6112 100644 --- a/nova/tests/test_misc.py +++ b/nova/tests/test_misc.py @@ -47,7 +47,7 @@ class ProjectTestCase(test.TestCase): missing = set() for contributor in contributors: if contributor == 'nova-core': - pass + continue if not contributor in authors_file: missing.add(contributor) From ebab256ce008fd4522253bdee73e41e8bc9fbc78 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 21 Feb 2011 11:07:50 -0800 Subject: [PATCH 059/111] cleanup from review --- nova/log.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/nova/log.py b/nova/log.py index 61a27988..3a48c97f 100644 --- a/nova/log.py +++ b/nova/log.py @@ -125,13 +125,6 @@ def _get_log_file_path(binary=None): return '%s.log' % (os.path.join(FLAGS.logdir, binary),) -def basicConfig(): - pass - - -logging.basicConfig = basicConfig - - class NovaLogger(logging.Logger): """ NovaLogger manages request context and formatting. @@ -176,7 +169,7 @@ class NovaLogger(logging.Logger): """Logging.exception doesn't handle kwargs, so breaks context""" if not kwargs.get('exc_info'): kwargs['exc_info'] = 1 - return self.error(msg, *args, **kwargs) + self.error(msg, *args, **kwargs) # NOTE(todd): does this really go here, or in _log ? extra = kwargs.get('extra') if not extra: @@ -271,11 +264,16 @@ class NovaRootLogger(NovaLogger): if not isinstance(logging.root, NovaRootLogger): + logging._acquireLock() for handler in logging.root.handlers: logging.root.removeHandler(handler) logging.root = NovaRootLogger("nova") + for logger in NovaLogger.manager.loggerDict.itervalues(): + logger.root = logging.root NovaLogger.root = logging.root NovaLogger.manager.root = logging.root + NovaLogger.manager.loggerDict["nova"] = logging.root + logging._releaseLock() root = logging.root @@ -289,14 +287,11 @@ logging.setLoggerClass(NovaLogger) def reset(): """Resets logging handlers. Should be called if FLAGS changes.""" - for logger in logging.Logger.manager.loggerDict.itervalues(): + for logger in NovaLogger.manager.loggerDict.itervalues(): if isinstance(logger, NovaLogger): logger.setup_from_flags() - root.setup_from_flags() def audit(msg, *args, **kwargs): """Shortcut for logging to root log with sevrity 'AUDIT'.""" - if len(logging.root.handlers) == 0: - basicConfig() logging.root.log(AUDIT, msg, *args, **kwargs) From 6543a1927577e6d5d0afba75688338902c060388 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 21 Feb 2011 11:42:46 -0800 Subject: [PATCH 060/111] use tests.sqlite so it doesn't conflict with running db --- nova/tests/fake_flags.py | 4 ++-- run_tests.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nova/tests/fake_flags.py b/nova/tests/fake_flags.py index 59839b09..575fefff 100644 --- a/nova/tests/fake_flags.py +++ b/nova/tests/fake_flags.py @@ -39,6 +39,6 @@ FLAGS.num_shelves = 2 FLAGS.blades_per_shelf = 4 FLAGS.iscsi_num_targets = 8 FLAGS.verbose = True -FLAGS.sql_connection = 'sqlite:///nova.sqlite' +FLAGS.sql_connection = 'sqlite:///tests.sqlite' FLAGS.use_ipv6 = True -FLAGS.logfile = 'run_tests.err' +FLAGS.logfile = 'tests.log' diff --git a/run_tests.py b/run_tests.py index bf12c62c..274dc4a9 100644 --- a/run_tests.py +++ b/run_tests.py @@ -58,8 +58,8 @@ class NovaTestRunner(core.TextTestRunner): if __name__ == '__main__': - if os.path.exists("nova.sqlite"): - os.unlink("nova.sqlite") + if os.path.exists("tests.sqlite"): + os.unlink("tests.sqlite") c = config.Config(stream=sys.stdout, env=os.environ, verbosity=3, From d5bb6b9ca556aa6cf43698bbaa28a0dcc7cf7b7f Mon Sep 17 00:00:00 2001 From: Anne Gentle Date: Mon, 21 Feb 2011 14:30:20 -0600 Subject: [PATCH 062/111] Updated to remove built docs --- test/.Python | 1 + test/bin/activate | 76 + test/bin/activate.csh | 32 + test/bin/activate.fish | 79 + test/bin/activate_this.py | 32 + test/bin/easy_install | 9 + test/bin/easy_install-2.6 | 9 + test/bin/pip | 9 + test/bin/pip-2.6 | 9 + test/bin/python | Bin 0 -> 50720 bytes test/bin/python2.6 | 1 + test/include/python2.6 | 1 + test/lib/python2.6/UserDict.py | 1 + test/lib/python2.6/_abcoll.py | 1 + test/lib/python2.6/abc.py | 1 + test/lib/python2.6/codecs.py | 1 + test/lib/python2.6/config | 1 + test/lib/python2.6/copy_reg.py | 1 + test/lib/python2.6/distutils/__init__.py | 91 ++ test/lib/python2.6/distutils/distutils.cfg | 6 + test/lib/python2.6/encodings | 1 + test/lib/python2.6/fnmatch.py | 1 + test/lib/python2.6/genericpath.py | 1 + test/lib/python2.6/lib-dynload | 1 + test/lib/python2.6/linecache.py | 1 + test/lib/python2.6/locale.py | 1 + test/lib/python2.6/ntpath.py | 1 + test/lib/python2.6/orig-prefix.txt | 1 + test/lib/python2.6/os.py | 1 + test/lib/python2.6/posixpath.py | 1 + test/lib/python2.6/re.py | 1 + .../python2.6/site-packages/easy-install.pth | 4 + .../pip-0.8.1-py2.6.egg/EGG-INFO/PKG-INFO | 348 ++++ .../pip-0.8.1-py2.6.egg/EGG-INFO/SOURCES.txt | 57 + .../EGG-INFO/dependency_links.txt | 1 + .../EGG-INFO/entry_points.txt | 4 + .../pip-0.8.1-py2.6.egg/EGG-INFO/not-zip-safe | 1 + .../EGG-INFO/top_level.txt | 1 + .../pip-0.8.1-py2.6.egg/pip/__init__.py | 261 +++ .../pip-0.8.1-py2.6.egg/pip/_pkgutil.py | 589 +++++++ .../pip-0.8.1-py2.6.egg/pip/backwardcompat.py | 55 + .../pip-0.8.1-py2.6.egg/pip/basecommand.py | 203 +++ .../pip-0.8.1-py2.6.egg/pip/baseparser.py | 231 +++ .../pip/commands/__init__.py | 1 + .../pip/commands/bundle.py | 33 + .../pip/commands/completion.py | 60 + .../pip/commands/freeze.py | 109 ++ .../pip-0.8.1-py2.6.egg/pip/commands/help.py | 32 + .../pip/commands/install.py | 247 +++ .../pip/commands/search.py | 116 ++ .../pip/commands/uninstall.py | 42 + .../pip-0.8.1-py2.6.egg/pip/commands/unzip.py | 9 + .../pip-0.8.1-py2.6.egg/pip/commands/zip.py | 346 ++++ .../pip-0.8.1-py2.6.egg/pip/download.py | 470 ++++++ .../pip-0.8.1-py2.6.egg/pip/exceptions.py | 17 + .../pip-0.8.1-py2.6.egg/pip/index.py | 686 ++++++++ .../pip-0.8.1-py2.6.egg/pip/locations.py | 45 + .../pip-0.8.1-py2.6.egg/pip/log.py | 181 +++ .../pip-0.8.1-py2.6.egg/pip/req.py | 1432 +++++++++++++++++ .../pip-0.8.1-py2.6.egg/pip/runner.py | 18 + .../pip-0.8.1-py2.6.egg/pip/util.py | 479 ++++++ .../pip-0.8.1-py2.6.egg/pip/vcs/__init__.py | 238 +++ .../pip-0.8.1-py2.6.egg/pip/vcs/bazaar.py | 138 ++ .../pip-0.8.1-py2.6.egg/pip/vcs/git.py | 204 +++ .../pip-0.8.1-py2.6.egg/pip/vcs/mercurial.py | 162 ++ .../pip-0.8.1-py2.6.egg/pip/vcs/subversion.py | 260 +++ .../pip-0.8.1-py2.6.egg/pip/venv.py | 53 + .../site-packages/setuptools-0.6c11-py2.6.egg | Bin 0 -> 333447 bytes .../python2.6/site-packages/setuptools.pth | 1 + test/lib/python2.6/site.py | 713 ++++++++ test/lib/python2.6/sre.py | 1 + test/lib/python2.6/sre_compile.py | 1 + test/lib/python2.6/sre_constants.py | 1 + test/lib/python2.6/sre_parse.py | 1 + test/lib/python2.6/stat.py | 1 + test/lib/python2.6/types.py | 1 + test/lib/python2.6/warnings.py | 1 + 77 files changed, 8226 insertions(+) create mode 120000 test/.Python create mode 100644 test/bin/activate create mode 100644 test/bin/activate.csh create mode 100644 test/bin/activate.fish create mode 100644 test/bin/activate_this.py create mode 100755 test/bin/easy_install create mode 100755 test/bin/easy_install-2.6 create mode 100755 test/bin/pip create mode 100755 test/bin/pip-2.6 create mode 100755 test/bin/python create mode 120000 test/bin/python2.6 create mode 120000 test/include/python2.6 create mode 120000 test/lib/python2.6/UserDict.py create mode 120000 test/lib/python2.6/_abcoll.py create mode 120000 test/lib/python2.6/abc.py create mode 120000 test/lib/python2.6/codecs.py create mode 120000 test/lib/python2.6/config create mode 120000 test/lib/python2.6/copy_reg.py create mode 100644 test/lib/python2.6/distutils/__init__.py create mode 100644 test/lib/python2.6/distutils/distutils.cfg create mode 120000 test/lib/python2.6/encodings create mode 120000 test/lib/python2.6/fnmatch.py create mode 120000 test/lib/python2.6/genericpath.py create mode 120000 test/lib/python2.6/lib-dynload create mode 120000 test/lib/python2.6/linecache.py create mode 120000 test/lib/python2.6/locale.py create mode 120000 test/lib/python2.6/ntpath.py create mode 100644 test/lib/python2.6/orig-prefix.txt create mode 120000 test/lib/python2.6/os.py create mode 120000 test/lib/python2.6/posixpath.py create mode 120000 test/lib/python2.6/re.py create mode 100644 test/lib/python2.6/site-packages/easy-install.pth create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/PKG-INFO create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/SOURCES.txt create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/dependency_links.txt create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/entry_points.txt create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/not-zip-safe create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/top_level.txt create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/__init__.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/_pkgutil.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/backwardcompat.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/basecommand.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/baseparser.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/__init__.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/bundle.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/completion.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/freeze.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/help.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/install.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/search.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/uninstall.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/unzip.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/zip.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/download.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/exceptions.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/index.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/locations.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/log.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/req.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/runner.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/util.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/__init__.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/bazaar.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/git.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/mercurial.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/subversion.py create mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/venv.py create mode 100644 test/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg create mode 100644 test/lib/python2.6/site-packages/setuptools.pth create mode 100644 test/lib/python2.6/site.py create mode 120000 test/lib/python2.6/sre.py create mode 120000 test/lib/python2.6/sre_compile.py create mode 120000 test/lib/python2.6/sre_constants.py create mode 120000 test/lib/python2.6/sre_parse.py create mode 120000 test/lib/python2.6/stat.py create mode 120000 test/lib/python2.6/types.py create mode 120000 test/lib/python2.6/warnings.py diff --git a/test/.Python b/test/.Python new file mode 120000 index 00000000..6cce156b --- /dev/null +++ b/test/.Python @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/Python \ No newline at end of file diff --git a/test/bin/activate b/test/bin/activate new file mode 100644 index 00000000..588b5410 --- /dev/null +++ b/test/bin/activate @@ -0,0 +1,76 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "$_OLD_VIRTUAL_PATH" ] ; then + PATH="$_OLD_VIRTUAL_PATH" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then + PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then + hash -r + fi + + if [ -n "$_OLD_VIRTUAL_PS1" ] ; then + PS1="$_OLD_VIRTUAL_PS1" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + if [ ! "$1" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelavent variables +deactivate nondestructive + +VIRTUAL_ENV="/Users/anne.gentle/src/nova/docslice/test" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "$PYTHONHOME" ] ; then + _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME" + unset PYTHONHOME +fi + +if [ -z "$VIRTUAL_ENV_DISABLE_PROMPT" ] ; then + _OLD_VIRTUAL_PS1="$PS1" + if [ "x" != x ] ; then + PS1="$PS1" + else + if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" + else + PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" + fi + fi + export PS1 +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then + hash -r +fi diff --git a/test/bin/activate.csh b/test/bin/activate.csh new file mode 100644 index 00000000..d29ac339 --- /dev/null +++ b/test/bin/activate.csh @@ -0,0 +1,32 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelavent variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/Users/anne.gentle/src/nova/docslice/test" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if ("" != "") then + set env_name = "" +else + if (`basename "$VIRTUAL_ENV"` == "__") then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` + else + set env_name = `basename "$VIRTUAL_ENV"` + endif +endif +set prompt = "[$env_name] $prompt" +unset env_name + +rehash + diff --git a/test/bin/activate.fish b/test/bin/activate.fish new file mode 100644 index 00000000..de3a8901 --- /dev/null +++ b/test/bin/activate.fish @@ -0,0 +1,79 @@ +# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) +# you cannot run it directly + +function deactivate -d "Exit virtualenv and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + functions -e fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE + end + + set -e VIRTUAL_ENV + if test "$argv[1]" != "nondestructive" + # Self destruct! + functions -e deactivate + end +end + +# unset irrelavent variables +deactivate nondestructive + +set -gx VIRTUAL_ENV "/Users/anne.gentle/src/nova/docslice/test" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# unset PYTHONHOME if set +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish shell uses a function, instead of env vars, + # to produce the prompt. Overriding the existing function is easy. + # However, adding to the current prompt, instead of clobbering it, + # is a little more work. + set -l oldpromptfile (tempfile) + if test $status + # save the current fish_prompt function... + echo "function _old_fish_prompt" >> $oldpromptfile + echo -n \# >> $oldpromptfile + functions fish_prompt >> $oldpromptfile + # we've made the "_old_fish_prompt" file, source it. + . $oldpromptfile + rm -f $oldpromptfile + + if test -n "" + # We've been given us a prompt override. + # + # FIXME: Unsure how to handle this *safely*. We could just eval() + # whatever is given, but the risk is a bit much. + echo "activate.fish: Alternative prompt prefix is not supported under fish-shell." 1>&2 + echo "activate.fish: Alter the fish_prompt in this file as needed." 1>&2 + end + + # with the original prompt function renamed, we can override with our own. + function fish_prompt + set -l _checkbase (basename "$VIRTUAL_ENV") + if test $_checkbase = "__" + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + printf "%s[%s]%s %s" (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) (_old_fish_prompt) + else + printf "%s(%s)%s%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) (_old_fish_prompt) + end + end + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + end +end + diff --git a/test/bin/activate_this.py b/test/bin/activate_this.py new file mode 100644 index 00000000..aff6927d --- /dev/null +++ b/test/bin/activate_this.py @@ -0,0 +1,32 @@ +"""By using execfile(this_file, dict(__file__=this_file)) you will +activate this virtualenv environment. + +This can be used when you must use an existing Python interpreter, not +the virtualenv bin/python +""" + +try: + __file__ +except NameError: + raise AssertionError( + "You must run this like execfile('path/to/activate_this.py', dict(__file__='path/to/activate_this.py'))") +import sys +import os + +base = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +if sys.platform == 'win32': + site_packages = os.path.join(base, 'Lib', 'site-packages') +else: + site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages') +prev_sys_path = list(sys.path) +import site +site.addsitedir(site_packages) +sys.real_prefix = sys.prefix +sys.prefix = base +# Move the added items to the front of the path: +new_sys_path = [] +for item in list(sys.path): + if item not in prev_sys_path: + new_sys_path.append(item) + sys.path.remove(item) +sys.path[:0] = new_sys_path diff --git a/test/bin/easy_install b/test/bin/easy_install new file mode 100755 index 00000000..8544573f --- /dev/null +++ b/test/bin/easy_install @@ -0,0 +1,9 @@ +#!/Users/anne.gentle/src/nova/docslice/test/bin/python +# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install' +__requires__ = 'setuptools==0.6c11' +import sys +from pkg_resources import load_entry_point + +sys.exit( + load_entry_point('setuptools==0.6c11', 'console_scripts', 'easy_install')() +) diff --git a/test/bin/easy_install-2.6 b/test/bin/easy_install-2.6 new file mode 100755 index 00000000..bad01d2d --- /dev/null +++ b/test/bin/easy_install-2.6 @@ -0,0 +1,9 @@ +#!/Users/anne.gentle/src/nova/docslice/test/bin/python +# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install-2.6' +__requires__ = 'setuptools==0.6c11' +import sys +from pkg_resources import load_entry_point + +sys.exit( + load_entry_point('setuptools==0.6c11', 'console_scripts', 'easy_install-2.6')() +) diff --git a/test/bin/pip b/test/bin/pip new file mode 100755 index 00000000..a3d2ed31 --- /dev/null +++ b/test/bin/pip @@ -0,0 +1,9 @@ +#!/Users/anne.gentle/src/nova/docslice/test/bin/python +# EASY-INSTALL-ENTRY-SCRIPT: 'pip==0.8.1','console_scripts','pip' +__requires__ = 'pip==0.8.1' +import sys +from pkg_resources import load_entry_point + +sys.exit( + load_entry_point('pip==0.8.1', 'console_scripts', 'pip')() +) diff --git a/test/bin/pip-2.6 b/test/bin/pip-2.6 new file mode 100755 index 00000000..4ad06add --- /dev/null +++ b/test/bin/pip-2.6 @@ -0,0 +1,9 @@ +#!/Users/anne.gentle/src/nova/docslice/test/bin/python +# EASY-INSTALL-ENTRY-SCRIPT: 'pip==0.8.1','console_scripts','pip-2.6' +__requires__ = 'pip==0.8.1' +import sys +from pkg_resources import load_entry_point + +sys.exit( + load_entry_point('pip==0.8.1', 'console_scripts', 'pip-2.6')() +) diff --git a/test/bin/python b/test/bin/python new file mode 100755 index 0000000000000000000000000000000000000000..271b6ca305f3044e23a2dff6649454a456723438 GIT binary patch literal 50720 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 literal 0 HcmV?d00001 diff --git a/test/bin/python2.6 b/test/bin/python2.6 new file mode 120000 index 00000000..d8654aa0 --- /dev/null +++ b/test/bin/python2.6 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/test/include/python2.6 b/test/include/python2.6 new file mode 120000 index 00000000..788ac55b --- /dev/null +++ b/test/include/python2.6 @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/include/python2.6 \ No newline at end of file diff --git a/test/lib/python2.6/UserDict.py b/test/lib/python2.6/UserDict.py new file mode 120000 index 00000000..93e0864b --- /dev/null +++ b/test/lib/python2.6/UserDict.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/UserDict.py \ No newline at end of file diff --git a/test/lib/python2.6/_abcoll.py b/test/lib/python2.6/_abcoll.py new file mode 120000 index 00000000..ff176924 --- /dev/null +++ b/test/lib/python2.6/_abcoll.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/_abcoll.py \ No newline at end of file diff --git a/test/lib/python2.6/abc.py b/test/lib/python2.6/abc.py new file mode 120000 index 00000000..79fa108b --- /dev/null +++ b/test/lib/python2.6/abc.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/abc.py \ No newline at end of file diff --git a/test/lib/python2.6/codecs.py b/test/lib/python2.6/codecs.py new file mode 120000 index 00000000..9e4bfb7f --- /dev/null +++ b/test/lib/python2.6/codecs.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/codecs.py \ No newline at end of file diff --git a/test/lib/python2.6/config b/test/lib/python2.6/config new file mode 120000 index 00000000..eef498c6 --- /dev/null +++ b/test/lib/python2.6/config @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/config \ No newline at end of file diff --git a/test/lib/python2.6/copy_reg.py b/test/lib/python2.6/copy_reg.py new file mode 120000 index 00000000..7285fda0 --- /dev/null +++ b/test/lib/python2.6/copy_reg.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/copy_reg.py \ No newline at end of file diff --git a/test/lib/python2.6/distutils/__init__.py b/test/lib/python2.6/distutils/__init__.py new file mode 100644 index 00000000..7ebb41c0 --- /dev/null +++ b/test/lib/python2.6/distutils/__init__.py @@ -0,0 +1,91 @@ +import os +import sys +import warnings +import opcode # opcode is not a virtualenv module, so we can use it to find the stdlib + # Important! To work on pypy, this must be a module that resides in the + # lib-python/modified-x.y.z directory + +dirname = os.path.dirname + +distutils_path = os.path.join(os.path.dirname(opcode.__file__), 'distutils') +if os.path.normpath(distutils_path) == os.path.dirname(os.path.normpath(__file__)): + warnings.warn( + "The virtualenv distutils package at %s appears to be in the same location as the system distutils?") +else: + __path__.insert(0, distutils_path) + exec open(os.path.join(distutils_path, '__init__.py')).read() + +import dist +import sysconfig + + +## patch build_ext (distutils doesn't know how to get the libs directory +## path on windows - it hardcodes the paths around the patched sys.prefix) + +if sys.platform == 'win32': + from distutils.command.build_ext import build_ext as old_build_ext + class build_ext(old_build_ext): + def finalize_options (self): + if self.library_dirs is None: + self.library_dirs = [] + elif isinstance(self.library_dirs, basestring): + self.library_dirs = self.library_dirs.split(os.pathsep) + + self.library_dirs.insert(0, os.path.join(sys.real_prefix, "Libs")) + old_build_ext.finalize_options(self) + + from distutils.command import build_ext as build_ext_module + build_ext_module.build_ext = build_ext + +## distutils.dist patches: + +old_find_config_files = dist.Distribution.find_config_files +def find_config_files(self): + found = old_find_config_files(self) + system_distutils = os.path.join(distutils_path, 'distutils.cfg') + #if os.path.exists(system_distutils): + # found.insert(0, system_distutils) + # What to call the per-user config file + if os.name == 'posix': + user_filename = ".pydistutils.cfg" + else: + user_filename = "pydistutils.cfg" + user_filename = os.path.join(sys.prefix, user_filename) + if os.path.isfile(user_filename): + for item in list(found): + if item.endswith('pydistutils.cfg'): + found.remove(item) + found.append(user_filename) + return found +dist.Distribution.find_config_files = find_config_files + +## distutils.sysconfig patches: + +old_get_python_inc = sysconfig.get_python_inc +def sysconfig_get_python_inc(plat_specific=0, prefix=None): + if prefix is None: + prefix = sys.real_prefix + return old_get_python_inc(plat_specific, prefix) +sysconfig_get_python_inc.__doc__ = old_get_python_inc.__doc__ +sysconfig.get_python_inc = sysconfig_get_python_inc + +old_get_python_lib = sysconfig.get_python_lib +def sysconfig_get_python_lib(plat_specific=0, standard_lib=0, prefix=None): + if standard_lib and prefix is None: + prefix = sys.real_prefix + return old_get_python_lib(plat_specific, standard_lib, prefix) +sysconfig_get_python_lib.__doc__ = old_get_python_lib.__doc__ +sysconfig.get_python_lib = sysconfig_get_python_lib + +old_get_config_vars = sysconfig.get_config_vars +def sysconfig_get_config_vars(*args): + real_vars = old_get_config_vars(*args) + if sys.platform == 'win32': + lib_dir = os.path.join(sys.real_prefix, "libs") + if isinstance(real_vars, dict) and 'LIBDIR' not in real_vars: + real_vars['LIBDIR'] = lib_dir # asked for all + elif isinstance(real_vars, list) and 'LIBDIR' in args: + real_vars = real_vars + [lib_dir] # asked for list + return real_vars +sysconfig_get_config_vars.__doc__ = old_get_config_vars.__doc__ +sysconfig.get_config_vars = sysconfig_get_config_vars diff --git a/test/lib/python2.6/distutils/distutils.cfg b/test/lib/python2.6/distutils/distutils.cfg new file mode 100644 index 00000000..1af230ec --- /dev/null +++ b/test/lib/python2.6/distutils/distutils.cfg @@ -0,0 +1,6 @@ +# This is a config file local to this virtualenv installation +# You may include options that will be used by all distutils commands, +# and by easy_install. For instance: +# +# [easy_install] +# find_links = http://mylocalsite diff --git a/test/lib/python2.6/encodings b/test/lib/python2.6/encodings new file mode 120000 index 00000000..89f28f82 --- /dev/null +++ b/test/lib/python2.6/encodings @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/encodings \ No newline at end of file diff --git a/test/lib/python2.6/fnmatch.py b/test/lib/python2.6/fnmatch.py new file mode 120000 index 00000000..cce0594f --- /dev/null +++ b/test/lib/python2.6/fnmatch.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/fnmatch.py \ No newline at end of file diff --git a/test/lib/python2.6/genericpath.py b/test/lib/python2.6/genericpath.py new file mode 120000 index 00000000..b14e1bc2 --- /dev/null +++ b/test/lib/python2.6/genericpath.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/genericpath.py \ No newline at end of file diff --git a/test/lib/python2.6/lib-dynload b/test/lib/python2.6/lib-dynload new file mode 120000 index 00000000..4644b707 --- /dev/null +++ b/test/lib/python2.6/lib-dynload @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-dynload \ No newline at end of file diff --git a/test/lib/python2.6/linecache.py b/test/lib/python2.6/linecache.py new file mode 120000 index 00000000..783624da --- /dev/null +++ b/test/lib/python2.6/linecache.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/linecache.py \ No newline at end of file diff --git a/test/lib/python2.6/locale.py b/test/lib/python2.6/locale.py new file mode 120000 index 00000000..4e674c7b --- /dev/null +++ b/test/lib/python2.6/locale.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/locale.py \ No newline at end of file diff --git a/test/lib/python2.6/ntpath.py b/test/lib/python2.6/ntpath.py new file mode 120000 index 00000000..9b6b40f4 --- /dev/null +++ b/test/lib/python2.6/ntpath.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ntpath.py \ No newline at end of file diff --git a/test/lib/python2.6/orig-prefix.txt b/test/lib/python2.6/orig-prefix.txt new file mode 100644 index 00000000..535eb0f0 --- /dev/null +++ b/test/lib/python2.6/orig-prefix.txt @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6 \ No newline at end of file diff --git a/test/lib/python2.6/os.py b/test/lib/python2.6/os.py new file mode 120000 index 00000000..92e6e9a7 --- /dev/null +++ b/test/lib/python2.6/os.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/os.py \ No newline at end of file diff --git a/test/lib/python2.6/posixpath.py b/test/lib/python2.6/posixpath.py new file mode 120000 index 00000000..c095d16a --- /dev/null +++ b/test/lib/python2.6/posixpath.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/posixpath.py \ No newline at end of file diff --git a/test/lib/python2.6/re.py b/test/lib/python2.6/re.py new file mode 120000 index 00000000..b4710c5f --- /dev/null +++ b/test/lib/python2.6/re.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/re.py \ No newline at end of file diff --git a/test/lib/python2.6/site-packages/easy-install.pth b/test/lib/python2.6/site-packages/easy-install.pth new file mode 100644 index 00000000..7a6ae2b6 --- /dev/null +++ b/test/lib/python2.6/site-packages/easy-install.pth @@ -0,0 +1,4 @@ +import sys; sys.__plen = len(sys.path) +./setuptools-0.6c11-py2.6.egg +./pip-0.8.1-py2.6.egg +import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/PKG-INFO b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/PKG-INFO new file mode 100644 index 00000000..29c30cb8 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/PKG-INFO @@ -0,0 +1,348 @@ +Metadata-Version: 1.0 +Name: pip +Version: 0.8.1 +Summary: pip installs packages. Python packages. An easy_install replacement +Home-page: http://pip.openplans.org +Author: Ian Bicking +Author-email: python-virtualenv@groups.google.com +License: MIT +Description: The main website for pip is `pip.openplans.org + `_. You can also install + the `in-development version `_ + of pip with ``easy_install pip==dev``. + + + Introduction + ------------ + + pip installs packages. Python packages. + + If you use `virtualenv `__ -- a tool + for installing libraries in a local and isolated manner -- you'll + automatically get a copy of pip. Free bonus! + + Once you have pip, you can use it like this:: + + $ pip install SomePackage + + SomePackage is some package you'll find on `PyPI + `_. This installs the package and all + its dependencies. + + pip does other stuff too, with packages, but install is the biggest + one. You can ``pip uninstall`` too. + + You can also install from a URL (that points to a tar or zip file), + install from some version control system (use URLs like + ``hg+http://domain/repo`` -- or prefix ``git+``, ``svn+`` etc). pip + knows a bunch of stuff about revisions and stuff, so if you need to do + things like install a very specific revision from a repository pip can + do that too. + + If you've ever used ``python setup.py develop``, you can do something + like that with ``pip install -e ./`` -- this works with packages that + use ``distutils`` too (usually this only works with Setuptools + projects). + + You can use ``pip install --upgrade SomePackage`` to upgrade to a + newer version, or ``pip install SomePackage==1.0.4`` to install a very + specific version. + + Pip Compared To easy_install + ---------------------------- + + pip is a replacement for `easy_install + `_. It uses mostly the + same techniques for finding packages, so packages that were made + easy_installable should be pip-installable as well. + + pip is meant to improve on easy_install. Some of the improvements: + + * All packages are downloaded before installation. Partially-completed + installation doesn't occur as a result. + + * Care is taken to present useful output on the console. + + * The reasons for actions are kept track of. For instance, if a package is + being installed, pip keeps track of why that package was required. + + * Error messages should be useful. + + * The code is relatively concise and cohesive, making it easier to use + programmatically. + + * Packages don't have to be installed as egg archives, they can be installed + flat (while keeping the egg metadata). + + * Native support for other version control systems (Git, Mercurial and Bazaar) + + * Uninstallation of packages. + + * Simple to define fixed sets of requirements and reliably reproduce a + set of packages. + + pip doesn't do everything that easy_install does. Specifically: + + * It cannot install from eggs. It only installs from source. (In the + future it would be good if it could install binaries from Windows ``.exe`` + or ``.msi`` -- binary install on other platforms is not a priority.) + + * It doesn't understand Setuptools extras (like ``package[test]``). This should + be added eventually. + + * It is incompatible with some packages that extensively customize distutils + or setuptools in their ``setup.py`` files. + + pip is complementary with `virtualenv + `__, and it is encouraged that you use + virtualenv to isolate your installation. + + Community + --------- + + The homepage for pip is temporarily located `on PyPI + `_ -- a more proper homepage will + follow. Bugs can go on the `pip issue tracker + `_. Discussion should happen on the + `virtualenv email group + `_. + + Uninstall + --------- + + pip is able to uninstall most installed packages with ``pip uninstall + package-name``. + + Known exceptions include pure-distutils packages installed with + ``python setup.py install`` (such packages leave behind no metadata allowing + determination of what files were installed), and script wrappers installed + by develop-installs (``python setup.py develop``). + + pip also performs an automatic uninstall of an old version of a package + before upgrading to a newer version, so outdated files (and egg-info data) + from conflicting versions aren't left hanging around to cause trouble. The + old version of the package is automatically restored if the new version + fails to download or install. + + .. _`requirements file`: + + Requirements Files + ------------------ + + When installing software, and Python packages in particular, it's common that + you get a lot of libraries installed. You just did ``easy_install MyPackage`` + and you get a dozen packages. Each of these packages has its own version. + + Maybe you ran that installation and it works. Great! Will it keep working? + Did you have to provide special options to get it to find everything? Did you + have to install a bunch of other optional pieces? Most of all, will you be able + to do it again? Requirements files give you a way to create an *environment*: + a *set* of packages that work together. + + If you've ever tried to setup an application on a new system, or with slightly + updated pieces, and had it fail, pip requirements are for you. If you + haven't had this problem then you will eventually, so pip requirements are + for you too -- requirements make explicit, repeatable installation of packages. + + So what are requirements files? They are very simple: lists of packages to + install. Instead of running something like ``pip MyApp`` and getting + whatever libraries come along, you can create a requirements file something like:: + + MyApp + Framework==0.9.4 + Library>=0.2 + + Then, regardless of what MyApp lists in ``setup.py``, you'll get a + specific version of Framework (0.9.4) and at least the 0.2 version of + Library. (You might think you could list these specific versions in + MyApp's ``setup.py`` -- but if you do that you'll have to edit MyApp + if you want to try a new version of Framework, or release a new + version of MyApp if you determine that Library 0.3 doesn't work with + your application.) You can also add optional libraries and support + tools that MyApp doesn't strictly require, giving people a set of + recommended libraries. + + You can also include "editable" packages -- packages that are checked out from + Subversion, Git, Mercurial and Bazaar. These are just like using the ``-e`` + option to pip. They look like:: + + -e svn+http://myrepo/svn/MyApp#egg=MyApp + + You have to start the URL with ``svn+`` (``git+``, ``hg+`` or ``bzr+``), and + you have to include ``#egg=Package`` so pip knows what to expect at that URL. + You can also include ``@rev`` in the URL, e.g., ``@275`` to check out + revision 275. + + Requirement files are mostly *flat*. Maybe ``MyApp`` requires + ``Framework``, and ``Framework`` requires ``Library``. I encourage + you to still list all these in a single requirement file; it is the + nature of Python programs that there are implicit bindings *directly* + between MyApp and Library. For instance, Framework might expose one + of Library's objects, and so if Library is updated it might directly + break MyApp. If that happens you can update the requirements file to + force an earlier version of Library, and you can do that without + having to re-release MyApp at all. + + Read the `requirements file format `_ to + learn about other features. + + Freezing Requirements + --------------------- + + So you have a working set of packages, and you want to be able to install them + elsewhere. `Requirements files`_ let you install exact versions, but it won't + tell you what all the exact versions are. + + To create a new requirements file from a known working environment, use:: + + $ pip freeze > stable-req.txt + + This will write a listing of *all* installed libraries to ``stable-req.txt`` + with exact versions for every library. You may want to edit the file down after + generating (e.g., to eliminate unnecessary libraries), but it'll give you a + stable starting point for constructing your requirements file. + + You can also give it an existing requirements file, and it will use that as a + sort of template for the new file. So if you do:: + + $ pip freeze -r devel-req.txt > stable-req.txt + + it will keep the packages listed in ``devel-req.txt`` in order and preserve + comments. + + Bundles + ------- + + Another way to distribute a set of libraries is a bundle format (specific to + pip). This format is not stable at this time (there simply hasn't been + any feedback, nor a great deal of thought). A bundle file contains all the + source for your package, and you can have pip install them all together. + Once you have the bundle file further network access won't be necessary. To + build a bundle file, do:: + + $ pip bundle MyApp.pybundle MyApp + + (Using a `requirements file`_ would be wise.) Then someone else can get the + file ``MyApp.pybundle`` and run:: + + $ pip install MyApp.pybundle + + This is *not* a binary format. This only packages source. If you have binary + packages, then the person who installs the files will have to have a compiler, + any necessary headers installed, etc. Binary packages are hard, this is + relatively easy. + + Using pip with virtualenv + ------------------------- + + pip is most nutritious when used with `virtualenv + `__. One of the reasons pip + doesn't install "multi-version" eggs is that virtualenv removes much of the need + for it. Because pip is installed by virtualenv, just use + ``path/to/my/environment/bin/pip`` to install things into that + specific environment. + + To tell pip to only run if there is a virtualenv currently activated, + and to bail if not, use:: + + export PIP_REQUIRE_VIRTUALENV=true + + To tell pip to automatically use the currently active virtualenv:: + + export PIP_RESPECT_VIRTUALENV=true + + Providing an environment with ``-E`` will be ignored. + + Using pip with virtualenvwrapper + --------------------------------- + + If you are using `virtualenvwrapper + `_, you might + want pip to automatically create its virtualenvs in your + ``$WORKON_HOME``. + + You can tell pip to do so by defining ``PIP_VIRTUALENV_BASE`` in your + environment and setting it to the same value as that of + ``$WORKON_HOME``. + + Do so by adding the line:: + + export PIP_VIRTUALENV_BASE=$WORKON_HOME + + in your .bashrc under the line starting with ``export WORKON_HOME``. + + Using pip with buildout + ----------------------- + + If you are using `zc.buildout + `_ you should look at + `gp.recipe.pip `_ as an + option to use pip and virtualenv in your buildouts. + + Command line completion + ----------------------- + + pip comes with support for command line completion in bash and zsh and + allows you tab complete commands and options. To enable it you simply + need copy the required shell script to the your shell startup file + (e.g. ``.profile`` or ``.zprofile``) by running the special ``completion`` + command, e.g. for bash:: + + $ pip completion --bash >> ~/.profile + + And for zsh:: + + $ pip completion --zsh >> ~/.zprofile + + Alternatively, you can use the result of the ``completion`` command + directly with the eval function of you shell, e.g. by adding:: + + eval "`pip completion --bash`" + + to your startup file. + + Searching for packages + ---------------------- + + pip can search the `Python Package Index `_ (PyPI) + for packages using the ``pip search`` command. To search, run:: + + $ pip search "query" + + The query will be used to search the names and summaries of all packages + indexed. + + pip searches http://pypi.python.org/pypi by default but alternative indexes + can be searched by using the ``--index`` flag. + + Mirror support + -------------- + + The `PyPI mirroring infrastructure `_ as + described in `PEP 381 `_ can be + used by passing the ``--use-mirrors`` option to the install command. + Alternatively, you can use the other ways to configure pip, e.g.:: + + $ export PIP_USE_MIRRORS=true + + If enabled, pip will automatically query the DNS entry of the mirror index URL + to find the list of mirrors to use. In case you want to override this list, + please use the ``--mirrors`` option of the install command, or add to your pip + configuration file:: + + [install] + use-mirrors = true + mirrors = + http://d.pypi.python.org + http://b.pypi.python.org + +Keywords: easy_install distutils setuptools egg virtualenv +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Topic :: Software Development :: Build Tools +Classifier: Programming Language :: Python :: 2.4 +Classifier: Programming Language :: Python :: 2.5 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/SOURCES.txt b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/SOURCES.txt new file mode 100644 index 00000000..3a068547 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/SOURCES.txt @@ -0,0 +1,57 @@ +MANIFEST.in +setup.cfg +setup.py +docs/branches.txt +docs/ci-server-step-by-step.txt +docs/configuration.txt +docs/how-to-contribute.txt +docs/index.txt +docs/license.txt +docs/news.txt +docs/requirement-format.txt +docs/running-tests.txt +docs/_build/branches.html +docs/_build/ci-server-step-by-step.html +docs/_build/configuration.html +docs/_build/how-to-contribute.html +docs/_build/index.html +docs/_build/license.html +docs/_build/news.html +docs/_build/requirement-format.html +docs/_build/running-tests.html +docs/_build/search.html +pip/__init__.py +pip/_pkgutil.py +pip/backwardcompat.py +pip/basecommand.py +pip/baseparser.py +pip/download.py +pip/exceptions.py +pip/index.py +pip/locations.py +pip/log.py +pip/req.py +pip/runner.py +pip/util.py +pip/venv.py +pip.egg-info/PKG-INFO +pip.egg-info/SOURCES.txt +pip.egg-info/dependency_links.txt +pip.egg-info/entry_points.txt +pip.egg-info/not-zip-safe +pip.egg-info/top_level.txt +pip/commands/__init__.py +pip/commands/bundle.py +pip/commands/completion.py +pip/commands/freeze.py +pip/commands/help.py +pip/commands/install.py +pip/commands/search.py +pip/commands/uninstall.py +pip/commands/unzip.py +pip/commands/zip.py +pip/vcs/__init__.py +pip/vcs/bazaar.py +pip/vcs/git.py +pip/vcs/mercurial.py +pip/vcs/subversion.py \ No newline at end of file diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/dependency_links.txt b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/dependency_links.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/entry_points.txt b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/entry_points.txt new file mode 100644 index 00000000..2b0afba7 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/entry_points.txt @@ -0,0 +1,4 @@ +[console_scripts] +pip = pip:main +pip-2.6 = pip:main + diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/not-zip-safe b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/not-zip-safe new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/not-zip-safe @@ -0,0 +1 @@ + diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/top_level.txt b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/top_level.txt new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/top_level.txt @@ -0,0 +1 @@ +pip diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/__init__.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/__init__.py new file mode 100644 index 00000000..c5de5c9a --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/__init__.py @@ -0,0 +1,261 @@ +#!/usr/bin/env python +import os +import optparse + +import subprocess +import sys +import re +import difflib + +from pip.basecommand import command_dict, load_command, load_all_commands, command_names +from pip.baseparser import parser +from pip.exceptions import InstallationError +from pip.log import logger +from pip.util import get_installed_distributions +from pip.backwardcompat import walk_packages + + +def autocomplete(): + """Command and option completion for the main option parser (and options) + and its subcommands (and options). + + Enable by sourcing one of the completion shell scripts (bash or zsh). + """ + # Don't complete if user hasn't sourced bash_completion file. + if 'PIP_AUTO_COMPLETE' not in os.environ: + return + cwords = os.environ['COMP_WORDS'].split()[1:] + cword = int(os.environ['COMP_CWORD']) + try: + current = cwords[cword-1] + except IndexError: + current = '' + load_all_commands() + subcommands = [cmd for cmd, cls in command_dict.items() if not cls.hidden] + options = [] + # subcommand + try: + subcommand_name = [w for w in cwords if w in subcommands][0] + except IndexError: + subcommand_name = None + # subcommand options + if subcommand_name: + # special case: 'help' subcommand has no options + if subcommand_name == 'help': + sys.exit(1) + # special case: list locally installed dists for uninstall command + if subcommand_name == 'uninstall' and not current.startswith('-'): + installed = [] + lc = current.lower() + for dist in get_installed_distributions(local_only=True): + if dist.key.startswith(lc) and dist.key not in cwords[1:]: + installed.append(dist.key) + # if there are no dists installed, fall back to option completion + if installed: + for dist in installed: + print dist + sys.exit(1) + subcommand = command_dict.get(subcommand_name) + options += [(opt.get_opt_string(), opt.nargs) + for opt in subcommand.parser.option_list + if opt.help != optparse.SUPPRESS_HELP] + # filter out previously specified options from available options + prev_opts = [x.split('=')[0] for x in cwords[1:cword-1]] + options = filter(lambda (x, v): x not in prev_opts, options) + # filter options by current input + options = [(k, v) for k, v in options if k.startswith(current)] + for option in options: + opt_label = option[0] + # append '=' to options which require args + if option[1]: + opt_label += '=' + print opt_label + else: + # show options of main parser only when necessary + if current.startswith('-') or current.startswith('--'): + subcommands += [opt.get_opt_string() + for opt in parser.option_list + if opt.help != optparse.SUPPRESS_HELP] + print ' '.join(filter(lambda x: x.startswith(current), subcommands)) + sys.exit(1) + + +def version_control(): + # Import all the version control support modules: + from pip import vcs + for importer, modname, ispkg in \ + walk_packages(path=vcs.__path__, prefix=vcs.__name__+'.'): + __import__(modname) + + +def main(initial_args=None): + if initial_args is None: + initial_args = sys.argv[1:] + autocomplete() + version_control() + options, args = parser.parse_args(initial_args) + if options.help and not args: + args = ['help'] + if not args: + parser.error('You must give a command (use "pip help" to see a list of commands)') + command = args[0].lower() + load_command(command) + if command not in command_dict: + close_commands = difflib.get_close_matches(command, command_names()) + if close_commands: + guess = close_commands[0] + if args[1:]: + guess = "%s %s" % (guess, " ".join(args[1:])) + else: + guess = 'install %s' % command + error_dict = {'arg': command, 'guess': guess, + 'script': os.path.basename(sys.argv[0])} + parser.error('No command by the name %(script)s %(arg)s\n ' + '(maybe you meant "%(script)s %(guess)s")' % error_dict) + command = command_dict[command] + return command.main(initial_args, args[1:], options) + + +############################################################ +## Writing freeze files + + +class FrozenRequirement(object): + + def __init__(self, name, req, editable, comments=()): + self.name = name + self.req = req + self.editable = editable + self.comments = comments + + _rev_re = re.compile(r'-r(\d+)$') + _date_re = re.compile(r'-(20\d\d\d\d\d\d)$') + + @classmethod + def from_dist(cls, dist, dependency_links, find_tags=False): + location = os.path.normcase(os.path.abspath(dist.location)) + comments = [] + from pip.vcs import vcs, get_src_requirement + if vcs.get_backend_name(location): + editable = True + req = get_src_requirement(dist, location, find_tags) + if req is None: + logger.warn('Could not determine repository location of %s' % location) + comments.append('## !! Could not determine repository location') + req = dist.as_requirement() + editable = False + else: + editable = False + req = dist.as_requirement() + specs = req.specs + assert len(specs) == 1 and specs[0][0] == '==' + version = specs[0][1] + ver_match = cls._rev_re.search(version) + date_match = cls._date_re.search(version) + if ver_match or date_match: + svn_backend = vcs.get_backend('svn') + if svn_backend: + svn_location = svn_backend( + ).get_location(dist, dependency_links) + if not svn_location: + logger.warn( + 'Warning: cannot find svn location for %s' % req) + comments.append('## FIXME: could not find svn URL in dependency_links for this package:') + else: + comments.append('# Installing as editable to satisfy requirement %s:' % req) + if ver_match: + rev = ver_match.group(1) + else: + rev = '{%s}' % date_match.group(1) + editable = True + req = '%s@%s#egg=%s' % (svn_location, rev, cls.egg_name(dist)) + return cls(dist.project_name, req, editable, comments) + + @staticmethod + def egg_name(dist): + name = dist.egg_name() + match = re.search(r'-py\d\.\d$', name) + if match: + name = name[:match.start()] + return name + + def __str__(self): + req = self.req + if self.editable: + req = '-e %s' % req + return '\n'.join(list(self.comments)+[str(req)])+'\n' + +############################################################ +## Requirement files + + +def call_subprocess(cmd, show_stdout=True, + filter_stdout=None, cwd=None, + raise_on_returncode=True, + command_level=logger.DEBUG, command_desc=None, + extra_environ=None): + if command_desc is None: + cmd_parts = [] + for part in cmd: + if ' ' in part or '\n' in part or '"' in part or "'" in part: + part = '"%s"' % part.replace('"', '\\"') + cmd_parts.append(part) + command_desc = ' '.join(cmd_parts) + if show_stdout: + stdout = None + else: + stdout = subprocess.PIPE + logger.log(command_level, "Running command %s" % command_desc) + env = os.environ.copy() + if extra_environ: + env.update(extra_environ) + try: + proc = subprocess.Popen( + cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout, + cwd=cwd, env=env) + except Exception, e: + logger.fatal( + "Error %s while executing command %s" % (e, command_desc)) + raise + all_output = [] + if stdout is not None: + stdout = proc.stdout + while 1: + line = stdout.readline() + if not line: + break + line = line.rstrip() + all_output.append(line + '\n') + if filter_stdout: + level = filter_stdout(line) + if isinstance(level, tuple): + level, line = level + logger.log(level, line) + if not logger.stdout_level_matches(level): + logger.show_progress() + else: + logger.info(line) + else: + returned_stdout, returned_stderr = proc.communicate() + all_output = [returned_stdout or ''] + proc.wait() + if proc.returncode: + if raise_on_returncode: + if all_output: + logger.notify('Complete output from command %s:' % command_desc) + logger.notify('\n'.join(all_output) + '\n----------------------------------------') + raise InstallationError( + "Command %s failed with error code %s" + % (command_desc, proc.returncode)) + else: + logger.warn( + "Command %s had error code %s" + % (command_desc, proc.returncode)) + if stdout is not None: + return ''.join(all_output) + + +if __name__ == '__main__': + exit = main() + if exit: + sys.exit(exit) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/_pkgutil.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/_pkgutil.py new file mode 100644 index 00000000..f8fb8aa6 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/_pkgutil.py @@ -0,0 +1,589 @@ +"""Utilities to support packages.""" + +# NOTE: This module must remain compatible with Python 2.3, as it is shared +# by setuptools for distribution with Python 2.3 and up. + +import os +import sys +import imp +import os.path +from types import ModuleType + +__all__ = [ + 'get_importer', 'iter_importers', 'get_loader', 'find_loader', + 'walk_packages', 'iter_modules', + 'ImpImporter', 'ImpLoader', 'read_code', 'extend_path', +] + + +def read_code(stream): + # This helper is needed in order for the PEP 302 emulation to + # correctly handle compiled files + import marshal + + magic = stream.read(4) + if magic != imp.get_magic(): + return None + + stream.read(4) # Skip timestamp + return marshal.load(stream) + + +def simplegeneric(func): + """Make a trivial single-dispatch generic function""" + registry = {} + + def wrapper(*args, **kw): + ob = args[0] + try: + cls = ob.__class__ + except AttributeError: + cls = type(ob) + try: + mro = cls.__mro__ + except AttributeError: + try: + + class cls(cls, object): + pass + + mro = cls.__mro__[1:] + except TypeError: + mro = object, # must be an ExtensionClass or some such :( + for t in mro: + if t in registry: + return registry[t](*args, **kw) + else: + return func(*args, **kw) + try: + wrapper.__name__ = func.__name__ + except (TypeError, AttributeError): + pass # Python 2.3 doesn't allow functions to be renamed + + def register(typ, func=None): + if func is None: + return lambda f: register(typ, f) + registry[typ] = func + return func + + wrapper.__dict__ = func.__dict__ + wrapper.__doc__ = func.__doc__ + wrapper.register = register + return wrapper + + +def walk_packages(path=None, prefix='', onerror=None): + """Yields (module_loader, name, ispkg) for all modules recursively + on path, or, if path is None, all accessible modules. + + 'path' should be either None or a list of paths to look for + modules in. + + 'prefix' is a string to output on the front of every module name + on output. + + Note that this function must import all *packages* (NOT all + modules!) on the given path, in order to access the __path__ + attribute to find submodules. + + 'onerror' is a function which gets called with one argument (the + name of the package which was being imported) if any exception + occurs while trying to import a package. If no onerror function is + supplied, ImportErrors are caught and ignored, while all other + exceptions are propagated, terminating the search. + + Examples: + + # list all modules python can access + walk_packages() + + # list all submodules of ctypes + walk_packages(ctypes.__path__, ctypes.__name__+'.') + """ + + def seen(p, m={}): + if p in m: + return True + m[p] = True + + for importer, name, ispkg in iter_modules(path, prefix): + yield importer, name, ispkg + + if ispkg: + try: + __import__(name) + except ImportError: + if onerror is not None: + onerror(name) + except Exception: + if onerror is not None: + onerror(name) + else: + raise + else: + path = getattr(sys.modules[name], '__path__', None) or [] + + # don't traverse path items we've seen before + path = [p for p in path if not seen(p)] + + for item in walk_packages(path, name+'.', onerror): + yield item + + +def iter_modules(path=None, prefix=''): + """Yields (module_loader, name, ispkg) for all submodules on path, + or, if path is None, all top-level modules on sys.path. + + 'path' should be either None or a list of paths to look for + modules in. + + 'prefix' is a string to output on the front of every module name + on output. + """ + + if path is None: + importers = iter_importers() + else: + importers = map(get_importer, path) + + yielded = {} + for i in importers: + for name, ispkg in iter_importer_modules(i, prefix): + if name not in yielded: + yielded[name] = 1 + yield i, name, ispkg + + +#@simplegeneric +def iter_importer_modules(importer, prefix=''): + if not hasattr(importer, 'iter_modules'): + return [] + return importer.iter_modules(prefix) + +iter_importer_modules = simplegeneric(iter_importer_modules) + + +class ImpImporter: + """PEP 302 Importer that wraps Python's "classic" import algorithm + + ImpImporter(dirname) produces a PEP 302 importer that searches that + directory. ImpImporter(None) produces a PEP 302 importer that searches + the current sys.path, plus any modules that are frozen or built-in. + + Note that ImpImporter does not currently support being used by placement + on sys.meta_path. + """ + + def __init__(self, path=None): + self.path = path + + def find_module(self, fullname, path=None): + # Note: we ignore 'path' argument since it is only used via meta_path + subname = fullname.split(".")[-1] + if subname != fullname and self.path is None: + return None + if self.path is None: + path = None + else: + path = [os.path.realpath(self.path)] + try: + file, filename, etc = imp.find_module(subname, path) + except ImportError: + return None + return ImpLoader(fullname, file, filename, etc) + + def iter_modules(self, prefix=''): + if self.path is None or not os.path.isdir(self.path): + return + + yielded = {} + import inspect + + filenames = os.listdir(self.path) + filenames.sort() # handle packages before same-named modules + + for fn in filenames: + modname = inspect.getmodulename(fn) + if modname=='__init__' or modname in yielded: + continue + + path = os.path.join(self.path, fn) + ispkg = False + + if not modname and os.path.isdir(path) and '.' not in fn: + modname = fn + for fn in os.listdir(path): + subname = inspect.getmodulename(fn) + if subname=='__init__': + ispkg = True + break + else: + continue # not a package + + if modname and '.' not in modname: + yielded[modname] = 1 + yield prefix + modname, ispkg + + +class ImpLoader: + """PEP 302 Loader that wraps Python's "classic" import algorithm + """ + code = source = None + + def __init__(self, fullname, file, filename, etc): + self.file = file + self.filename = filename + self.fullname = fullname + self.etc = etc + + def load_module(self, fullname): + self._reopen() + try: + mod = imp.load_module(fullname, self.file, self.filename, self.etc) + finally: + if self.file: + self.file.close() + # Note: we don't set __loader__ because we want the module to look + # normal; i.e. this is just a wrapper for standard import machinery + return mod + + def get_data(self, pathname): + return open(pathname, "rb").read() + + def _reopen(self): + if self.file and self.file.closed: + mod_type = self.etc[2] + if mod_type==imp.PY_SOURCE: + self.file = open(self.filename, 'rU') + elif mod_type in (imp.PY_COMPILED, imp.C_EXTENSION): + self.file = open(self.filename, 'rb') + + def _fix_name(self, fullname): + if fullname is None: + fullname = self.fullname + elif fullname != self.fullname: + raise ImportError("Loader for module %s cannot handle " + "module %s" % (self.fullname, fullname)) + return fullname + + def is_package(self, fullname): + fullname = self._fix_name(fullname) + return self.etc[2]==imp.PKG_DIRECTORY + + def get_code(self, fullname=None): + fullname = self._fix_name(fullname) + if self.code is None: + mod_type = self.etc[2] + if mod_type==imp.PY_SOURCE: + source = self.get_source(fullname) + self.code = compile(source, self.filename, 'exec') + elif mod_type==imp.PY_COMPILED: + self._reopen() + try: + self.code = read_code(self.file) + finally: + self.file.close() + elif mod_type==imp.PKG_DIRECTORY: + self.code = self._get_delegate().get_code() + return self.code + + def get_source(self, fullname=None): + fullname = self._fix_name(fullname) + if self.source is None: + mod_type = self.etc[2] + if mod_type==imp.PY_SOURCE: + self._reopen() + try: + self.source = self.file.read() + finally: + self.file.close() + elif mod_type==imp.PY_COMPILED: + if os.path.exists(self.filename[:-1]): + f = open(self.filename[:-1], 'rU') + self.source = f.read() + f.close() + elif mod_type==imp.PKG_DIRECTORY: + self.source = self._get_delegate().get_source() + return self.source + + def _get_delegate(self): + return ImpImporter(self.filename).find_module('__init__') + + def get_filename(self, fullname=None): + fullname = self._fix_name(fullname) + mod_type = self.etc[2] + if self.etc[2]==imp.PKG_DIRECTORY: + return self._get_delegate().get_filename() + elif self.etc[2] in (imp.PY_SOURCE, imp.PY_COMPILED, imp.C_EXTENSION): + return self.filename + return None + + +try: + import zipimport + from zipimport import zipimporter + + def iter_zipimport_modules(importer, prefix=''): + dirlist = zipimport._zip_directory_cache[importer.archive].keys() + dirlist.sort() + _prefix = importer.prefix + plen = len(_prefix) + yielded = {} + import inspect + for fn in dirlist: + if not fn.startswith(_prefix): + continue + + fn = fn[plen:].split(os.sep) + + if len(fn)==2 and fn[1].startswith('__init__.py'): + if fn[0] not in yielded: + yielded[fn[0]] = 1 + yield fn[0], True + + if len(fn)!=1: + continue + + modname = inspect.getmodulename(fn[0]) + if modname=='__init__': + continue + + if modname and '.' not in modname and modname not in yielded: + yielded[modname] = 1 + yield prefix + modname, False + + iter_importer_modules.register(zipimporter, iter_zipimport_modules) + +except ImportError: + pass + + +def get_importer(path_item): + """Retrieve a PEP 302 importer for the given path item + + The returned importer is cached in sys.path_importer_cache + if it was newly created by a path hook. + + If there is no importer, a wrapper around the basic import + machinery is returned. This wrapper is never inserted into + the importer cache (None is inserted instead). + + The cache (or part of it) can be cleared manually if a + rescan of sys.path_hooks is necessary. + """ + try: + importer = sys.path_importer_cache[path_item] + except KeyError: + for path_hook in sys.path_hooks: + try: + importer = path_hook(path_item) + break + except ImportError: + pass + else: + importer = None + sys.path_importer_cache.setdefault(path_item, importer) + + if importer is None: + try: + importer = ImpImporter(path_item) + except ImportError: + importer = None + return importer + + +def iter_importers(fullname=""): + """Yield PEP 302 importers for the given module name + + If fullname contains a '.', the importers will be for the package + containing fullname, otherwise they will be importers for sys.meta_path, + sys.path, and Python's "classic" import machinery, in that order. If + the named module is in a package, that package is imported as a side + effect of invoking this function. + + Non PEP 302 mechanisms (e.g. the Windows registry) used by the + standard import machinery to find files in alternative locations + are partially supported, but are searched AFTER sys.path. Normally, + these locations are searched BEFORE sys.path, preventing sys.path + entries from shadowing them. + + For this to cause a visible difference in behaviour, there must + be a module or package name that is accessible via both sys.path + and one of the non PEP 302 file system mechanisms. In this case, + the emulation will find the former version, while the builtin + import mechanism will find the latter. + + Items of the following types can be affected by this discrepancy: + imp.C_EXTENSION, imp.PY_SOURCE, imp.PY_COMPILED, imp.PKG_DIRECTORY + """ + if fullname.startswith('.'): + raise ImportError("Relative module names not supported") + if '.' in fullname: + # Get the containing package's __path__ + pkg = '.'.join(fullname.split('.')[:-1]) + if pkg not in sys.modules: + __import__(pkg) + path = getattr(sys.modules[pkg], '__path__', None) or [] + else: + for importer in sys.meta_path: + yield importer + path = sys.path + for item in path: + yield get_importer(item) + if '.' not in fullname: + yield ImpImporter() + + +def get_loader(module_or_name): + """Get a PEP 302 "loader" object for module_or_name + + If the module or package is accessible via the normal import + mechanism, a wrapper around the relevant part of that machinery + is returned. Returns None if the module cannot be found or imported. + If the named module is not already imported, its containing package + (if any) is imported, in order to establish the package __path__. + + This function uses iter_importers(), and is thus subject to the same + limitations regarding platform-specific special import locations such + as the Windows registry. + """ + if module_or_name in sys.modules: + module_or_name = sys.modules[module_or_name] + if isinstance(module_or_name, ModuleType): + module = module_or_name + loader = getattr(module, '__loader__', None) + if loader is not None: + return loader + fullname = module.__name__ + else: + fullname = module_or_name + return find_loader(fullname) + + +def find_loader(fullname): + """Find a PEP 302 "loader" object for fullname + + If fullname contains dots, path must be the containing package's __path__. + Returns None if the module cannot be found or imported. This function uses + iter_importers(), and is thus subject to the same limitations regarding + platform-specific special import locations such as the Windows registry. + """ + for importer in iter_importers(fullname): + loader = importer.find_module(fullname) + if loader is not None: + return loader + + return None + + +def extend_path(path, name): + """Extend a package's path. + + Intended use is to place the following code in a package's __init__.py: + + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) + + This will add to the package's __path__ all subdirectories of + directories on sys.path named after the package. This is useful + if one wants to distribute different parts of a single logical + package as multiple directories. + + It also looks for *.pkg files beginning where * matches the name + argument. This feature is similar to *.pth files (see site.py), + except that it doesn't special-case lines starting with 'import'. + A *.pkg file is trusted at face value: apart from checking for + duplicates, all entries found in a *.pkg file are added to the + path, regardless of whether they are exist the filesystem. (This + is a feature.) + + If the input path is not a list (as is the case for frozen + packages) it is returned unchanged. The input path is not + modified; an extended copy is returned. Items are only appended + to the copy at the end. + + It is assumed that sys.path is a sequence. Items of sys.path that + are not (unicode or 8-bit) strings referring to existing + directories are ignored. Unicode items of sys.path that cause + errors when used as filenames may cause this function to raise an + exception (in line with os.path.isdir() behavior). + """ + + if not isinstance(path, list): + # This could happen e.g. when this is called from inside a + # frozen package. Return the path unchanged in that case. + return path + + pname = os.path.join(*name.split('.')) # Reconstitute as relative path + # Just in case os.extsep != '.' + sname = os.extsep.join(name.split('.')) + sname_pkg = sname + os.extsep + "pkg" + init_py = "__init__" + os.extsep + "py" + + path = path[:] # Start with a copy of the existing path + + for dir in sys.path: + if not isinstance(dir, basestring) or not os.path.isdir(dir): + continue + subdir = os.path.join(dir, pname) + # XXX This may still add duplicate entries to path on + # case-insensitive filesystems + initfile = os.path.join(subdir, init_py) + if subdir not in path and os.path.isfile(initfile): + path.append(subdir) + # XXX Is this the right thing for subpackages like zope.app? + # It looks for a file named "zope.app.pkg" + pkgfile = os.path.join(dir, sname_pkg) + if os.path.isfile(pkgfile): + try: + f = open(pkgfile) + except IOError, msg: + sys.stderr.write("Can't open %s: %s\n" % + (pkgfile, msg)) + else: + for line in f: + line = line.rstrip('\n') + if not line or line.startswith('#'): + continue + path.append(line) # Don't check for existence! + f.close() + + return path + + +def get_data(package, resource): + """Get a resource from a package. + + This is a wrapper round the PEP 302 loader get_data API. The package + argument should be the name of a package, in standard module format + (foo.bar). The resource argument should be in the form of a relative + filename, using '/' as the path separator. The parent directory name '..' + is not allowed, and nor is a rooted name (starting with a '/'). + + The function returns a binary string, which is the contents of the + specified resource. + + For packages located in the filesystem, which have already been imported, + this is the rough equivalent of + + d = os.path.dirname(sys.modules[package].__file__) + data = open(os.path.join(d, resource), 'rb').read() + + If the package cannot be located or loaded, or it uses a PEP 302 loader + which does not support get_data(), then None is returned. + """ + + loader = get_loader(package) + if loader is None or not hasattr(loader, 'get_data'): + return None + mod = sys.modules.get(package) or loader.load_module(package) + if mod is None or not hasattr(mod, '__file__'): + return None + + # Modify the resource name to be compatible with the loader.get_data + # signature - an os.path format "filename" starting with the dirname of + # the package's __file__ + parts = resource.split('/') + parts.insert(0, os.path.dirname(mod.__file__)) + resource_name = os.path.join(*parts) + return loader.get_data(resource_name) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/backwardcompat.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/backwardcompat.py new file mode 100644 index 00000000..e7c11f1d --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/backwardcompat.py @@ -0,0 +1,55 @@ +"""Stuff that isn't in some old versions of Python""" + +import sys +import os +import shutil + +__all__ = ['any', 'WindowsError', 'md5', 'copytree'] + +try: + WindowsError = WindowsError +except NameError: + WindowsError = None +try: + from hashlib import md5 +except ImportError: + import md5 as md5_module + md5 = md5_module.new + +try: + from pkgutil import walk_packages +except ImportError: + # let's fall back as long as we can + from _pkgutil import walk_packages + +try: + any = any +except NameError: + + def any(seq): + for item in seq: + if item: + return True + return False + + +def copytree(src, dst): + if sys.version_info < (2, 5): + before_last_dir = os.path.dirname(dst) + if not os.path.exists(before_last_dir): + os.makedirs(before_last_dir) + shutil.copytree(src, dst) + shutil.copymode(src, dst) + else: + shutil.copytree(src, dst) + + +def product(*args, **kwds): + # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy + # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 + pools = map(tuple, args) * kwds.get('repeat', 1) + result = [[]] + for pool in pools: + result = [x+[y] for x in result for y in pool] + for prod in result: + yield tuple(prod) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/basecommand.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/basecommand.py new file mode 100644 index 00000000..f450e839 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/basecommand.py @@ -0,0 +1,203 @@ +"""Base Command class, and related routines""" + +from cStringIO import StringIO +import getpass +import os +import socket +import sys +import traceback +import time +import urllib +import urllib2 + +from pip import commands +from pip.log import logger +from pip.baseparser import parser, ConfigOptionParser, UpdatingDefaultsHelpFormatter +from pip.download import urlopen +from pip.exceptions import BadCommand, InstallationError, UninstallationError +from pip.venv import restart_in_venv +from pip.backwardcompat import walk_packages + +__all__ = ['command_dict', 'Command', 'load_all_commands', + 'load_command', 'command_names'] + +command_dict = {} + +# for backwards compatibiliy +get_proxy = urlopen.get_proxy + + +class Command(object): + name = None + usage = None + hidden = False + + def __init__(self): + assert self.name + self.parser = ConfigOptionParser( + usage=self.usage, + prog='%s %s' % (sys.argv[0], self.name), + version=parser.version, + formatter=UpdatingDefaultsHelpFormatter(), + name=self.name) + for option in parser.option_list: + if not option.dest or option.dest == 'help': + # -h, --version, etc + continue + self.parser.add_option(option) + command_dict[self.name] = self + + def merge_options(self, initial_options, options): + # Make sure we have all global options carried over + for attr in ['log', 'venv', 'proxy', 'venv_base', 'require_venv', + 'respect_venv', 'log_explicit_levels', 'log_file', + 'timeout', 'default_vcs', 'skip_requirements_regex', + 'no_input']: + setattr(options, attr, getattr(initial_options, attr) or getattr(options, attr)) + options.quiet += initial_options.quiet + options.verbose += initial_options.verbose + + def setup_logging(self): + pass + + def main(self, complete_args, args, initial_options): + options, args = self.parser.parse_args(args) + self.merge_options(initial_options, options) + + level = 1 # Notify + level += options.verbose + level -= options.quiet + level = logger.level_for_integer(4-level) + complete_log = [] + logger.consumers.extend( + [(level, sys.stdout), + (logger.DEBUG, complete_log.append)]) + if options.log_explicit_levels: + logger.explicit_levels = True + + self.setup_logging() + + if options.require_venv and not options.venv: + # If a venv is required check if it can really be found + if not os.environ.get('VIRTUAL_ENV'): + logger.fatal('Could not find an activated virtualenv (required).') + sys.exit(3) + # Automatically install in currently activated venv if required + options.respect_venv = True + + if args and args[-1] == '___VENV_RESTART___': + ## FIXME: We don't do anything this this value yet: + args = args[:-2] + options.venv = None + else: + # If given the option to respect the activated environment + # check if no venv is given as a command line parameter + if options.respect_venv and os.environ.get('VIRTUAL_ENV'): + if options.venv and os.path.exists(options.venv): + # Make sure command line venv and environmental are the same + if (os.path.realpath(os.path.expanduser(options.venv)) != + os.path.realpath(os.environ.get('VIRTUAL_ENV'))): + logger.fatal("Given virtualenv (%s) doesn't match " + "currently activated virtualenv (%s)." + % (options.venv, os.environ.get('VIRTUAL_ENV'))) + sys.exit(3) + else: + options.venv = os.environ.get('VIRTUAL_ENV') + logger.info('Using already activated environment %s' % options.venv) + if options.venv: + logger.info('Running in environment %s' % options.venv) + site_packages=False + if options.site_packages: + site_packages=True + restart_in_venv(options.venv, options.venv_base, site_packages, + complete_args) + # restart_in_venv should actually never return, but for clarity... + return + + ## FIXME: not sure if this sure come before or after venv restart + if options.log: + log_fp = open_logfile(options.log, 'a') + logger.consumers.append((logger.DEBUG, log_fp)) + else: + log_fp = None + + socket.setdefaulttimeout(options.timeout or None) + + urlopen.setup(proxystr=options.proxy, prompting=not options.no_input) + + exit = 0 + try: + self.run(options, args) + except (InstallationError, UninstallationError), e: + logger.fatal(str(e)) + logger.info('Exception information:\n%s' % format_exc()) + exit = 1 + except BadCommand, e: + logger.fatal(str(e)) + logger.info('Exception information:\n%s' % format_exc()) + exit = 1 + except: + logger.fatal('Exception:\n%s' % format_exc()) + exit = 2 + + if log_fp is not None: + log_fp.close() + if exit: + log_fn = options.log_file + text = '\n'.join(complete_log) + logger.fatal('Storing complete log in %s' % log_fn) + log_fp = open_logfile(log_fn, 'w') + log_fp.write(text) + log_fp.close() + return exit + + + + +def format_exc(exc_info=None): + if exc_info is None: + exc_info = sys.exc_info() + out = StringIO() + traceback.print_exception(*exc_info, **dict(file=out)) + return out.getvalue() + + +def open_logfile(filename, mode='a'): + """Open the named log file in append mode. + + If the file already exists, a separator will also be printed to + the file to separate past activity from current activity. + """ + filename = os.path.expanduser(filename) + filename = os.path.abspath(filename) + dirname = os.path.dirname(filename) + if not os.path.exists(dirname): + os.makedirs(dirname) + exists = os.path.exists(filename) + + log_fp = open(filename, mode) + if exists: + print >> log_fp, '-'*60 + print >> log_fp, '%s run on %s' % (sys.argv[0], time.strftime('%c')) + return log_fp + + +def load_command(name): + full_name = 'pip.commands.%s' % name + if full_name in sys.modules: + return + try: + __import__(full_name) + except ImportError: + pass + + +def load_all_commands(): + for name in command_names(): + load_command(name) + + +def command_names(): + names = set((pkg[1] for pkg in walk_packages(path=commands.__path__))) + return list(names) + diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/baseparser.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/baseparser.py new file mode 100644 index 00000000..a8bd6ce4 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/baseparser.py @@ -0,0 +1,231 @@ +"""Base option parser setup""" + +import sys +import optparse +import pkg_resources +import ConfigParser +import os +from distutils.util import strtobool +from pip.locations import default_config_file, default_log_file + + +class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter): + """Custom help formatter for use in ConfigOptionParser that updates + the defaults before expanding them, allowing them to show up correctly + in the help listing""" + + def expand_default(self, option): + if self.parser is not None: + self.parser.update_defaults(self.parser.defaults) + return optparse.IndentedHelpFormatter.expand_default(self, option) + + +class ConfigOptionParser(optparse.OptionParser): + """Custom option parser which updates its defaults by by checking the + configuration files and environmental variables""" + + def __init__(self, *args, **kwargs): + self.config = ConfigParser.RawConfigParser() + self.name = kwargs.pop('name') + self.files = self.get_config_files() + self.config.read(self.files) + assert self.name + optparse.OptionParser.__init__(self, *args, **kwargs) + + def get_config_files(self): + config_file = os.environ.get('PIP_CONFIG_FILE', False) + if config_file and os.path.exists(config_file): + return [config_file] + return [default_config_file] + + def update_defaults(self, defaults): + """Updates the given defaults with values from the config files and + the environ. Does a little special handling for certain types of + options (lists).""" + # Then go and look for the other sources of configuration: + config = {} + # 1. config files + for section in ('global', self.name): + config.update(dict(self.get_config_section(section))) + # 2. environmental variables + config.update(dict(self.get_environ_vars())) + # Then set the options with those values + for key, val in config.iteritems(): + key = key.replace('_', '-') + if not key.startswith('--'): + key = '--%s' % key # only prefer long opts + option = self.get_option(key) + if option is not None: + # ignore empty values + if not val: + continue + # handle multiline configs + if option.action == 'append': + val = val.split() + else: + option.nargs = 1 + if option.action in ('store_true', 'store_false', 'count'): + val = strtobool(val) + try: + val = option.convert_value(key, val) + except optparse.OptionValueError, e: + print ("An error occured during configuration: %s" % e) + sys.exit(3) + defaults[option.dest] = val + return defaults + + def get_config_section(self, name): + """Get a section of a configuration""" + if self.config.has_section(name): + return self.config.items(name) + return [] + + def get_environ_vars(self, prefix='PIP_'): + """Returns a generator with all environmental vars with prefix PIP_""" + for key, val in os.environ.iteritems(): + if key.startswith(prefix): + yield (key.replace(prefix, '').lower(), val) + + def get_default_values(self): + """Overridding to make updating the defaults after instantiation of + the option parser possible, update_defaults() does the dirty work.""" + if not self.process_default_values: + # Old, pre-Optik 1.5 behaviour. + return optparse.Values(self.defaults) + + defaults = self.update_defaults(self.defaults.copy()) # ours + for option in self._get_all_options(): + default = defaults.get(option.dest) + if isinstance(default, basestring): + opt_str = option.get_opt_string() + defaults[option.dest] = option.check_value(opt_str, default) + return optparse.Values(defaults) + +try: + pip_dist = pkg_resources.get_distribution('pip') + version = '%s from %s (python %s)' % ( + pip_dist, pip_dist.location, sys.version[:3]) +except pkg_resources.DistributionNotFound: + # when running pip.py without installing + version=None + +parser = ConfigOptionParser( + usage='%prog COMMAND [OPTIONS]', + version=version, + add_help_option=False, + formatter=UpdatingDefaultsHelpFormatter(), + name='global') + +parser.add_option( + '-h', '--help', + dest='help', + action='store_true', + help='Show help') +parser.add_option( + '-E', '--environment', + dest='venv', + metavar='DIR', + help='virtualenv environment to run pip in (either give the ' + 'interpreter or the environment base directory)') +parser.add_option( + '-s', '--enable-site-packages', + dest='site_packages', + action='store_true', + help='Include site-packages in virtualenv if one is to be ' + 'created. Ignored if --environment is not used or ' + 'the virtualenv already exists.') +parser.add_option( + # Defines a default root directory for virtualenvs, relative + # virtualenvs names/paths are considered relative to it. + '--virtualenv-base', + dest='venv_base', + type='str', + default='', + help=optparse.SUPPRESS_HELP) +parser.add_option( + # Run only if inside a virtualenv, bail if not. + '--require-virtualenv', '--require-venv', + dest='require_venv', + action='store_true', + default=False, + help=optparse.SUPPRESS_HELP) +parser.add_option( + # Use automatically an activated virtualenv instead of installing + # globally. -E will be ignored if used. + '--respect-virtualenv', '--respect-venv', + dest='respect_venv', + action='store_true', + default=False, + help=optparse.SUPPRESS_HELP) + +parser.add_option( + '-v', '--verbose', + dest='verbose', + action='count', + default=0, + help='Give more output') +parser.add_option( + '-q', '--quiet', + dest='quiet', + action='count', + default=0, + help='Give less output') +parser.add_option( + '--log', + dest='log', + metavar='FILENAME', + help='Log file where a complete (maximum verbosity) record will be kept') +parser.add_option( + # Writes the log levels explicitely to the log' + '--log-explicit-levels', + dest='log_explicit_levels', + action='store_true', + default=False, + help=optparse.SUPPRESS_HELP) +parser.add_option( + # The default log file + '--local-log', '--log-file', + dest='log_file', + metavar='FILENAME', + default=default_log_file, + help=optparse.SUPPRESS_HELP) +parser.add_option( + # Don't ask for input + '--no-input', + dest='no_input', + action='store_true', + default=False, + help=optparse.SUPPRESS_HELP) + +parser.add_option( + '--proxy', + dest='proxy', + type='str', + default='', + help="Specify a proxy in the form user:passwd@proxy.server:port. " + "Note that the user:password@ is optional and required only if you " + "are behind an authenticated proxy. If you provide " + "user@proxy.server:port then you will be prompted for a password.") +parser.add_option( + '--timeout', '--default-timeout', + metavar='SECONDS', + dest='timeout', + type='float', + default=15, + help='Set the socket timeout (default %default seconds)') +parser.add_option( + # The default version control system for editables, e.g. 'svn' + '--default-vcs', + dest='default_vcs', + type='str', + default='', + help=optparse.SUPPRESS_HELP) +parser.add_option( + # A regex to be used to skip requirements + '--skip-requirements-regex', + dest='skip_requirements_regex', + type='str', + default='', + help=optparse.SUPPRESS_HELP) + +parser.disable_interspersed_args() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/__init__.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/__init__.py new file mode 100644 index 00000000..792d6005 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/__init__.py @@ -0,0 +1 @@ +# diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/bundle.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/bundle.py new file mode 100644 index 00000000..fb0f7570 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/bundle.py @@ -0,0 +1,33 @@ +from pip.locations import build_prefix, src_prefix +from pip.util import display_path, backup_dir +from pip.log import logger +from pip.exceptions import InstallationError +from pip.commands.install import InstallCommand + + +class BundleCommand(InstallCommand): + name = 'bundle' + usage = '%prog [OPTIONS] BUNDLE_NAME.pybundle PACKAGE_NAMES...' + summary = 'Create pybundles (archives containing multiple packages)' + bundle = True + + def __init__(self): + super(BundleCommand, self).__init__() + + def run(self, options, args): + if not args: + raise InstallationError('You must give a bundle filename') + if not options.build_dir: + options.build_dir = backup_dir(build_prefix, '-bundle') + if not options.src_dir: + options.src_dir = backup_dir(src_prefix, '-bundle') + # We have to get everything when creating a bundle: + options.ignore_installed = True + logger.notify('Putting temporary build files in %s and source/develop files in %s' + % (display_path(options.build_dir), display_path(options.src_dir))) + self.bundle_filename = args.pop(0) + requirement_set = super(BundleCommand, self).run(options, args) + return requirement_set + + +BundleCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/completion.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/completion.py new file mode 100644 index 00000000..d003b9ae --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/completion.py @@ -0,0 +1,60 @@ +import sys +from pip.basecommand import Command + +BASE_COMPLETION = """ +# pip %(shell)s completion start%(script)s# pip %(shell)s completion end +""" + +COMPLETION_SCRIPTS = { + 'bash': """ +_pip_completion() +{ + COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \\ + COMP_CWORD=$COMP_CWORD \\ + PIP_AUTO_COMPLETE=1 $1 ) ) +} +complete -o default -F _pip_completion pip +""", 'zsh': """ +function _pip_completion { + local words cword + read -Ac words + read -cn cword + reply=( $( COMP_WORDS="$words[*]" \\ + COMP_CWORD=$(( cword-1 )) \\ + PIP_AUTO_COMPLETE=1 $words[1] ) ) +} +compctl -K _pip_completion pip +"""} + + +class CompletionCommand(Command): + name = 'completion' + summary = 'A helper command to be used for command completion' + hidden = True + + def __init__(self): + super(CompletionCommand, self).__init__() + self.parser.add_option( + '--bash', '-b', + action='store_const', + const='bash', + dest='shell', + help='Emit completion code for bash') + self.parser.add_option( + '--zsh', '-z', + action='store_const', + const='zsh', + dest='shell', + help='Emit completion code for zsh') + + def run(self, options, args): + """Prints the completion code of the given shell""" + shells = COMPLETION_SCRIPTS.keys() + shell_options = ['--'+shell for shell in sorted(shells)] + if options.shell in shells: + script = COMPLETION_SCRIPTS.get(options.shell, '') + print BASE_COMPLETION % {'script': script, 'shell': options.shell} + else: + sys.stderr.write('ERROR: You must pass %s\n' % ' or '.join(shell_options)) + +CompletionCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/freeze.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/freeze.py new file mode 100644 index 00000000..01b5df93 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/freeze.py @@ -0,0 +1,109 @@ +import re +import sys +import pkg_resources +import pip +from pip.req import InstallRequirement +from pip.log import logger +from pip.basecommand import Command +from pip.util import get_installed_distributions + + +class FreezeCommand(Command): + name = 'freeze' + usage = '%prog [OPTIONS]' + summary = 'Output all currently installed packages (exact versions) to stdout' + + def __init__(self): + super(FreezeCommand, self).__init__() + self.parser.add_option( + '-r', '--requirement', + dest='requirement', + action='store', + default=None, + metavar='FILENAME', + help='Use the given requirements file as a hint about how to generate the new frozen requirements') + self.parser.add_option( + '-f', '--find-links', + dest='find_links', + action='append', + default=[], + metavar='URL', + help='URL for finding packages, which will be added to the frozen requirements file') + self.parser.add_option( + '-l', '--local', + dest='local', + action='store_true', + default=False, + help='If in a virtualenv, do not report globally-installed packages') + + def setup_logging(self): + logger.move_stdout_to_stderr() + + def run(self, options, args): + requirement = options.requirement + find_links = options.find_links or [] + local_only = options.local + ## FIXME: Obviously this should be settable: + find_tags = False + skip_match = None + + skip_regex = options.skip_requirements_regex + if skip_regex: + skip_match = re.compile(skip_regex) + + dependency_links = [] + + f = sys.stdout + + for dist in pkg_resources.working_set: + if dist.has_metadata('dependency_links.txt'): + dependency_links.extend(dist.get_metadata_lines('dependency_links.txt')) + for link in find_links: + if '#egg=' in link: + dependency_links.append(link) + for link in find_links: + f.write('-f %s\n' % link) + installations = {} + for dist in get_installed_distributions(local_only=local_only): + req = pip.FrozenRequirement.from_dist(dist, dependency_links, find_tags=find_tags) + installations[req.name] = req + if requirement: + req_f = open(requirement) + for line in req_f: + if not line.strip() or line.strip().startswith('#'): + f.write(line) + continue + if skip_match and skip_match.search(line): + f.write(line) + continue + elif line.startswith('-e') or line.startswith('--editable'): + if line.startswith('-e'): + line = line[2:].strip() + else: + line = line[len('--editable'):].strip().lstrip('=') + line_req = InstallRequirement.from_editable(line, default_vcs=options.default_vcs) + elif (line.startswith('-r') or line.startswith('--requirement') + or line.startswith('-Z') or line.startswith('--always-unzip') + or line.startswith('-f') or line.startswith('-i') + or line.startswith('--extra-index-url')): + f.write(line) + continue + else: + line_req = InstallRequirement.from_line(line) + if not line_req.name: + logger.notify("Skipping line because it's not clear what it would install: %s" + % line.strip()) + logger.notify(" (add #egg=PackageName to the URL to avoid this warning)") + continue + if line_req.name not in installations: + logger.warn("Requirement file contains %s, but that package is not installed" + % line.strip()) + continue + f.write(str(installations[line_req.name])) + del installations[line_req.name] + f.write('## The following requirements were added by pip --freeze:\n') + for installation in sorted(installations.values(), key=lambda x: x.name): + f.write(str(installation)) + + +FreezeCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/help.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/help.py new file mode 100644 index 00000000..b0b36611 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/help.py @@ -0,0 +1,32 @@ +from pip.basecommand import Command, command_dict, load_all_commands +from pip.exceptions import InstallationError +from pip.baseparser import parser + + +class HelpCommand(Command): + name = 'help' + usage = '%prog' + summary = 'Show available commands' + + def run(self, options, args): + load_all_commands() + if args: + ## FIXME: handle errors better here + command = args[0] + if command not in command_dict: + raise InstallationError('No command with the name: %s' % command) + command = command_dict[command] + command.parser.print_help() + return + parser.print_help() + print + print 'Commands available:' + commands = list(set(command_dict.values())) + commands.sort(key=lambda x: x.name) + for command in commands: + if command.hidden: + continue + print ' %s: %s' % (command.name, command.summary) + + +HelpCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/install.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/install.py new file mode 100644 index 00000000..861c332b --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/install.py @@ -0,0 +1,247 @@ +import os, sys +from pip.req import InstallRequirement, RequirementSet +from pip.req import parse_requirements +from pip.log import logger +from pip.locations import build_prefix, src_prefix +from pip.basecommand import Command +from pip.index import PackageFinder +from pip.exceptions import InstallationError + + +class InstallCommand(Command): + name = 'install' + usage = '%prog [OPTIONS] PACKAGE_NAMES...' + summary = 'Install packages' + bundle = False + + def __init__(self): + super(InstallCommand, self).__init__() + self.parser.add_option( + '-e', '--editable', + dest='editables', + action='append', + default=[], + metavar='VCS+REPOS_URL[@REV]#egg=PACKAGE', + help='Install a package directly from a checkout. Source will be checked ' + 'out into src/PACKAGE (lower-case) and installed in-place (using ' + 'setup.py develop). You can run this on an existing directory/checkout (like ' + 'pip install -e src/mycheckout). This option may be provided multiple times. ' + 'Possible values for VCS are: svn, git, hg and bzr.') + self.parser.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='FILENAME', + help='Install all the packages listed in the given requirements file. ' + 'This option can be used multiple times.') + self.parser.add_option( + '-f', '--find-links', + dest='find_links', + action='append', + default=[], + metavar='URL', + help='URL to look for packages at') + self.parser.add_option( + '-i', '--index-url', '--pypi-url', + dest='index_url', + metavar='URL', + default='http://pypi.python.org/simple/', + help='Base URL of Python Package Index (default %default)') + self.parser.add_option( + '--extra-index-url', + dest='extra_index_urls', + metavar='URL', + action='append', + default=[], + help='Extra URLs of package indexes to use in addition to --index-url') + self.parser.add_option( + '--no-index', + dest='no_index', + action='store_true', + default=False, + help='Ignore package index (only looking at --find-links URLs instead)') + self.parser.add_option( + '-M', '--use-mirrors', + dest='use_mirrors', + action='store_true', + default=False, + help='Use the PyPI mirrors as a fallback in case the main index is down.') + self.parser.add_option( + '--mirrors', + dest='mirrors', + metavar='URL', + action='append', + default=[], + help='Specific mirror URLs to query when --use-mirrors is used') + + self.parser.add_option( + '-b', '--build', '--build-dir', '--build-directory', + dest='build_dir', + metavar='DIR', + default=None, + help='Unpack packages into DIR (default %s) and build from there' % build_prefix) + self.parser.add_option( + '-d', '--download', '--download-dir', '--download-directory', + dest='download_dir', + metavar='DIR', + default=None, + help='Download packages into DIR instead of installing them') + self.parser.add_option( + '--download-cache', + dest='download_cache', + metavar='DIR', + default=None, + help='Cache downloaded packages in DIR') + self.parser.add_option( + '--src', '--source', '--source-dir', '--source-directory', + dest='src_dir', + metavar='DIR', + default=None, + help='Check out --editable packages into DIR (default %s)' % src_prefix) + + self.parser.add_option( + '-U', '--upgrade', + dest='upgrade', + action='store_true', + help='Upgrade all packages to the newest available version') + self.parser.add_option( + '-I', '--ignore-installed', + dest='ignore_installed', + action='store_true', + help='Ignore the installed packages (reinstalling instead)') + self.parser.add_option( + '--no-deps', '--no-dependencies', + dest='ignore_dependencies', + action='store_true', + default=False, + help='Ignore package dependencies') + self.parser.add_option( + '--no-install', + dest='no_install', + action='store_true', + help="Download and unpack all packages, but don't actually install them") + self.parser.add_option( + '--no-download', + dest='no_download', + action="store_true", + help="Don't download any packages, just install the ones already downloaded " + "(completes an install run with --no-install)") + + self.parser.add_option( + '--install-option', + dest='install_options', + action='append', + help="Extra arguments to be supplied to the setup.py install " + "command (use like --install-option=\"--install-scripts=/usr/local/bin\"). " + "Use multiple --install-option options to pass multiple options to setup.py install. " + "If you are using an option with a directory path, be sure to use absolute path.") + + self.parser.add_option( + '--global-option', + dest='global_options', + action='append', + help="Extra global options to be supplied to the setup.py" + "call before the install command") + + self.parser.add_option( + '--user', + dest='use_user_site', + action='store_true', + help='Install to user-site') + + def _build_package_finder(self, options, index_urls): + """ + Create a package finder appropriate to this install command. + This method is meant to be overridden by subclasses, not + called directly. + """ + return PackageFinder(find_links=options.find_links, + index_urls=index_urls, + use_mirrors=options.use_mirrors, + mirrors=options.mirrors) + + def run(self, options, args): + if not options.build_dir: + options.build_dir = build_prefix + if not options.src_dir: + options.src_dir = src_prefix + if options.download_dir: + options.no_install = True + options.ignore_installed = True + options.build_dir = os.path.abspath(options.build_dir) + options.src_dir = os.path.abspath(options.src_dir) + install_options = options.install_options or [] + if options.use_user_site: + install_options.append('--user') + global_options = options.global_options or [] + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.notify('Ignoring indexes: %s' % ','.join(index_urls)) + index_urls = [] + + finder = self._build_package_finder(options, index_urls) + + requirement_set = RequirementSet( + build_dir=options.build_dir, + src_dir=options.src_dir, + download_dir=options.download_dir, + download_cache=options.download_cache, + upgrade=options.upgrade, + ignore_installed=options.ignore_installed, + ignore_dependencies=options.ignore_dependencies) + for name in args: + requirement_set.add_requirement( + InstallRequirement.from_line(name, None)) + for name in options.editables: + requirement_set.add_requirement( + InstallRequirement.from_editable(name, default_vcs=options.default_vcs)) + for filename in options.requirements: + for req in parse_requirements(filename, finder=finder, options=options): + requirement_set.add_requirement(req) + + if not requirement_set.has_requirements: + if options.find_links: + raise InstallationError('You must give at least one ' + 'requirement to %s (maybe you meant "pip install %s"?)' + % (self.name, " ".join(options.find_links))) + raise InstallationError('You must give at least one requirement ' + 'to %(name)s (see "pip help %(name)s")' % dict(name=self.name)) + + if (options.use_user_site and + sys.version_info < (2, 6)): + raise InstallationError('--user is only supported in Python version 2.6 and newer') + + import setuptools + if (options.use_user_site and + requirement_set.has_editables and + not getattr(setuptools, '_distribute', False)): + + raise InstallationError('--user --editable not supported with setuptools, use distribute') + + if not options.no_download: + requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle) + else: + requirement_set.locate_files() + + if not options.no_install and not self.bundle: + requirement_set.install(install_options, global_options) + installed = ' '.join([req.name for req in + requirement_set.successfully_installed]) + if installed: + logger.notify('Successfully installed %s' % installed) + elif not self.bundle: + downloaded = ' '.join([req.name for req in + requirement_set.successfully_downloaded]) + if downloaded: + logger.notify('Successfully downloaded %s' % downloaded) + elif self.bundle: + requirement_set.create_bundle(self.bundle_filename) + logger.notify('Created bundle in %s' % self.bundle_filename) + # Clean up + if not options.no_install: + requirement_set.cleanup_files(bundle=self.bundle) + return requirement_set + + +InstallCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/search.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/search.py new file mode 100644 index 00000000..73da58ac --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/search.py @@ -0,0 +1,116 @@ +import sys +import xmlrpclib +import textwrap +import pkg_resources +import pip.download +from pip.basecommand import Command +from pip.util import get_terminal_size +from pip.log import logger +from distutils.version import StrictVersion, LooseVersion + + +class SearchCommand(Command): + name = 'search' + usage = '%prog QUERY' + summary = 'Search PyPI' + + def __init__(self): + super(SearchCommand, self).__init__() + self.parser.add_option( + '--index', + dest='index', + metavar='URL', + default='http://pypi.python.org/pypi', + help='Base URL of Python Package Index (default %default)') + + def run(self, options, args): + if not args: + logger.warn('ERROR: Missing required argument (search query).') + return + query = ' '.join(args) + index_url = options.index + + pypi_hits = self.search(query, index_url) + hits = transform_hits(pypi_hits) + + terminal_width = None + if sys.stdout.isatty(): + terminal_width = get_terminal_size()[0] + + print_results(hits, terminal_width=terminal_width) + + def search(self, query, index_url): + pypi = xmlrpclib.ServerProxy(index_url, pip.download.xmlrpclib_transport) + hits = pypi.search({'name': query, 'summary': query}, 'or') + return hits + + +def transform_hits(hits): + """ + The list from pypi is really a list of versions. We want a list of + packages with the list of versions stored inline. This converts the + list from pypi into one we can use. + """ + packages = {} + for hit in hits: + name = hit['name'] + summary = hit['summary'] + version = hit['version'] + score = hit['_pypi_ordering'] + + if name not in packages.keys(): + packages[name] = {'name': name, 'summary': summary, 'versions': [version], 'score': score} + else: + packages[name]['versions'].append(version) + + # if this is the highest version, replace summary and score + if version == highest_version(packages[name]['versions']): + packages[name]['summary'] = summary + packages[name]['score'] = score + + # each record has a unique name now, so we will convert the dict into a list sorted by score + package_list = sorted(packages.values(), lambda x, y: cmp(y['score'], x['score'])) + return package_list + + +def print_results(hits, name_column_width=25, terminal_width=None): + installed_packages = [p.project_name for p in pkg_resources.working_set] + for hit in hits: + name = hit['name'] + summary = hit['summary'] or '' + if terminal_width is not None: + # wrap and indent summary to fit terminal + summary = textwrap.wrap(summary, terminal_width - name_column_width - 5) + summary = ('\n' + ' ' * (name_column_width + 3)).join(summary) + line = '%s - %s' % (name.ljust(name_column_width), summary) + try: + logger.notify(line) + if name in installed_packages: + dist = pkg_resources.get_distribution(name) + logger.indent += 2 + try: + latest = highest_version(hit['versions']) + if dist.version == latest: + logger.notify('INSTALLED: %s (latest)' % dist.version) + else: + logger.notify('INSTALLED: %s' % dist.version) + logger.notify('LATEST: %s' % latest) + finally: + logger.indent -= 2 + except UnicodeEncodeError: + pass + + +def compare_versions(version1, version2): + try: + return cmp(StrictVersion(version1), StrictVersion(version2)) + # in case of abnormal version number, fall back to LooseVersion + except ValueError: + return cmp(LooseVersion(version1), LooseVersion(version2)) + + +def highest_version(versions): + return reduce((lambda v1, v2: compare_versions(v1, v2) == 1 and v1 or v2), versions) + + +SearchCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/uninstall.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/uninstall.py new file mode 100644 index 00000000..7effd844 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/uninstall.py @@ -0,0 +1,42 @@ +from pip.req import InstallRequirement, RequirementSet, parse_requirements +from pip.basecommand import Command +from pip.exceptions import InstallationError + +class UninstallCommand(Command): + name = 'uninstall' + usage = '%prog [OPTIONS] PACKAGE_NAMES ...' + summary = 'Uninstall packages' + + def __init__(self): + super(UninstallCommand, self).__init__() + self.parser.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='FILENAME', + help='Uninstall all the packages listed in the given requirements file. ' + 'This option can be used multiple times.') + self.parser.add_option( + '-y', '--yes', + dest='yes', + action='store_true', + help="Don't ask for confirmation of uninstall deletions.") + + def run(self, options, args): + requirement_set = RequirementSet( + build_dir=None, + src_dir=None, + download_dir=None) + for name in args: + requirement_set.add_requirement( + InstallRequirement.from_line(name)) + for filename in options.requirements: + for req in parse_requirements(filename, options=options): + requirement_set.add_requirement(req) + if not requirement_set.has_requirements: + raise InstallationError('You must give at least one requirement ' + 'to %(name)s (see "pip help %(name)s")' % dict(name=self.name)) + requirement_set.uninstall(auto_confirm=options.yes) + +UninstallCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/unzip.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/unzip.py new file mode 100644 index 00000000..f83e1820 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/unzip.py @@ -0,0 +1,9 @@ +from pip.commands.zip import ZipCommand + + +class UnzipCommand(ZipCommand): + name = 'unzip' + summary = 'Unzip individual packages' + + +UnzipCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/zip.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/zip.py new file mode 100644 index 00000000..346fc051 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/zip.py @@ -0,0 +1,346 @@ +import sys +import re +import fnmatch +import os +import shutil +import zipfile +from pip.util import display_path, backup_dir +from pip.log import logger +from pip.exceptions import InstallationError +from pip.basecommand import Command + + +class ZipCommand(Command): + name = 'zip' + usage = '%prog [OPTIONS] PACKAGE_NAMES...' + summary = 'Zip individual packages' + + def __init__(self): + super(ZipCommand, self).__init__() + if self.name == 'zip': + self.parser.add_option( + '--unzip', + action='store_true', + dest='unzip', + help='Unzip (rather than zip) a package') + else: + self.parser.add_option( + '--zip', + action='store_false', + dest='unzip', + default=True, + help='Zip (rather than unzip) a package') + self.parser.add_option( + '--no-pyc', + action='store_true', + dest='no_pyc', + help='Do not include .pyc files in zip files (useful on Google App Engine)') + self.parser.add_option( + '-l', '--list', + action='store_true', + dest='list', + help='List the packages available, and their zip status') + self.parser.add_option( + '--sort-files', + action='store_true', + dest='sort_files', + help='With --list, sort packages according to how many files they contain') + self.parser.add_option( + '--path', + action='append', + dest='paths', + help='Restrict operations to the given paths (may include wildcards)') + self.parser.add_option( + '-n', '--simulate', + action='store_true', + help='Do not actually perform the zip/unzip operation') + + def paths(self): + """All the entries of sys.path, possibly restricted by --path""" + if not self.select_paths: + return sys.path + result = [] + match_any = set() + for path in sys.path: + path = os.path.normcase(os.path.abspath(path)) + for match in self.select_paths: + match = os.path.normcase(os.path.abspath(match)) + if '*' in match: + if re.search(fnmatch.translate(match+'*'), path): + result.append(path) + match_any.add(match) + break + else: + if path.startswith(match): + result.append(path) + match_any.add(match) + break + else: + logger.debug("Skipping path %s because it doesn't match %s" + % (path, ', '.join(self.select_paths))) + for match in self.select_paths: + if match not in match_any and '*' not in match: + result.append(match) + logger.debug("Adding path %s because it doesn't match anything already on sys.path" + % match) + return result + + def run(self, options, args): + self.select_paths = options.paths + self.simulate = options.simulate + if options.list: + return self.list(options, args) + if not args: + raise InstallationError( + 'You must give at least one package to zip or unzip') + packages = [] + for arg in args: + module_name, filename = self.find_package(arg) + if options.unzip and os.path.isdir(filename): + raise InstallationError( + 'The module %s (in %s) is not a zip file; cannot be unzipped' + % (module_name, filename)) + elif not options.unzip and not os.path.isdir(filename): + raise InstallationError( + 'The module %s (in %s) is not a directory; cannot be zipped' + % (module_name, filename)) + packages.append((module_name, filename)) + last_status = None + for module_name, filename in packages: + if options.unzip: + last_status = self.unzip_package(module_name, filename) + else: + last_status = self.zip_package(module_name, filename, options.no_pyc) + return last_status + + def unzip_package(self, module_name, filename): + zip_filename = os.path.dirname(filename) + if not os.path.isfile(zip_filename) and zipfile.is_zipfile(zip_filename): + raise InstallationError( + 'Module %s (in %s) isn\'t located in a zip file in %s' + % (module_name, filename, zip_filename)) + package_path = os.path.dirname(zip_filename) + if not package_path in self.paths(): + logger.warn( + 'Unpacking %s into %s, but %s is not on sys.path' + % (display_path(zip_filename), display_path(package_path), + display_path(package_path))) + logger.notify('Unzipping %s (in %s)' % (module_name, display_path(zip_filename))) + if self.simulate: + logger.notify('Skipping remaining operations because of --simulate') + return + logger.indent += 2 + try: + ## FIXME: this should be undoable: + zip = zipfile.ZipFile(zip_filename) + to_save = [] + for name in zip.namelist(): + if name.startswith(module_name + os.path.sep): + content = zip.read(name) + dest = os.path.join(package_path, name) + if not os.path.exists(os.path.dirname(dest)): + os.makedirs(os.path.dirname(dest)) + if not content and dest.endswith(os.path.sep): + if not os.path.exists(dest): + os.makedirs(dest) + else: + f = open(dest, 'wb') + f.write(content) + f.close() + else: + to_save.append((name, zip.read(name))) + zip.close() + if not to_save: + logger.info('Removing now-empty zip file %s' % display_path(zip_filename)) + os.unlink(zip_filename) + self.remove_filename_from_pth(zip_filename) + else: + logger.info('Removing entries in %s/ from zip file %s' % (module_name, display_path(zip_filename))) + zip = zipfile.ZipFile(zip_filename, 'w') + for name, content in to_save: + zip.writestr(name, content) + zip.close() + finally: + logger.indent -= 2 + + def zip_package(self, module_name, filename, no_pyc): + orig_filename = filename + logger.notify('Zip %s (in %s)' % (module_name, display_path(filename))) + logger.indent += 2 + if filename.endswith('.egg'): + dest_filename = filename + else: + dest_filename = filename + '.zip' + try: + ## FIXME: I think this needs to be undoable: + if filename == dest_filename: + filename = backup_dir(orig_filename) + logger.notify('Moving %s aside to %s' % (orig_filename, filename)) + if not self.simulate: + shutil.move(orig_filename, filename) + try: + logger.info('Creating zip file in %s' % display_path(dest_filename)) + if not self.simulate: + zip = zipfile.ZipFile(dest_filename, 'w') + zip.writestr(module_name + '/', '') + for dirpath, dirnames, filenames in os.walk(filename): + if no_pyc: + filenames = [f for f in filenames + if not f.lower().endswith('.pyc')] + for fns, is_dir in [(dirnames, True), (filenames, False)]: + for fn in fns: + full = os.path.join(dirpath, fn) + dest = os.path.join(module_name, dirpath[len(filename):].lstrip(os.path.sep), fn) + if is_dir: + zip.writestr(dest+'/', '') + else: + zip.write(full, dest) + zip.close() + logger.info('Removing old directory %s' % display_path(filename)) + if not self.simulate: + shutil.rmtree(filename) + except: + ## FIXME: need to do an undo here + raise + ## FIXME: should also be undone: + self.add_filename_to_pth(dest_filename) + finally: + logger.indent -= 2 + + def remove_filename_from_pth(self, filename): + for pth in self.pth_files(): + f = open(pth, 'r') + lines = f.readlines() + f.close() + new_lines = [ + l for l in lines if l.strip() != filename] + if lines != new_lines: + logger.info('Removing reference to %s from .pth file %s' + % (display_path(filename), display_path(pth))) + if not filter(None, new_lines): + logger.info('%s file would be empty: deleting' % display_path(pth)) + if not self.simulate: + os.unlink(pth) + else: + if not self.simulate: + f = open(pth, 'wb') + f.writelines(new_lines) + f.close() + return + logger.warn('Cannot find a reference to %s in any .pth file' % display_path(filename)) + + def add_filename_to_pth(self, filename): + path = os.path.dirname(filename) + dest = os.path.join(path, filename + '.pth') + if path not in self.paths(): + logger.warn('Adding .pth file %s, but it is not on sys.path' % display_path(dest)) + if not self.simulate: + if os.path.exists(dest): + f = open(dest) + lines = f.readlines() + f.close() + if lines and not lines[-1].endswith('\n'): + lines[-1] += '\n' + lines.append(filename+'\n') + else: + lines = [filename + '\n'] + f = open(dest, 'wb') + f.writelines(lines) + f.close() + + def pth_files(self): + for path in self.paths(): + if not os.path.exists(path) or not os.path.isdir(path): + continue + for filename in os.listdir(path): + if filename.endswith('.pth'): + yield os.path.join(path, filename) + + def find_package(self, package): + for path in self.paths(): + full = os.path.join(path, package) + if os.path.exists(full): + return package, full + if not os.path.isdir(path) and zipfile.is_zipfile(path): + zip = zipfile.ZipFile(path, 'r') + try: + zip.read(os.path.join(package, '__init__.py')) + except KeyError: + pass + else: + zip.close() + return package, full + zip.close() + ## FIXME: need special error for package.py case: + raise InstallationError( + 'No package with the name %s found' % package) + + def list(self, options, args): + if args: + raise InstallationError( + 'You cannot give an argument with --list') + for path in sorted(self.paths()): + if not os.path.exists(path): + continue + basename = os.path.basename(path.rstrip(os.path.sep)) + if os.path.isfile(path) and zipfile.is_zipfile(path): + if os.path.dirname(path) not in self.paths(): + logger.notify('Zipped egg: %s' % display_path(path)) + continue + if (basename != 'site-packages' and basename != 'dist-packages' + and not path.replace('\\', '/').endswith('lib/python')): + continue + logger.notify('In %s:' % display_path(path)) + logger.indent += 2 + zipped = [] + unzipped = [] + try: + for filename in sorted(os.listdir(path)): + ext = os.path.splitext(filename)[1].lower() + if ext in ('.pth', '.egg-info', '.egg-link'): + continue + if ext == '.py': + logger.info('Not displaying %s: not a package' % display_path(filename)) + continue + full = os.path.join(path, filename) + if os.path.isdir(full): + unzipped.append((filename, self.count_package(full))) + elif zipfile.is_zipfile(full): + zipped.append(filename) + else: + logger.info('Unknown file: %s' % display_path(filename)) + if zipped: + logger.notify('Zipped packages:') + logger.indent += 2 + try: + for filename in zipped: + logger.notify(filename) + finally: + logger.indent -= 2 + else: + logger.notify('No zipped packages.') + if unzipped: + if options.sort_files: + unzipped.sort(key=lambda x: -x[1]) + logger.notify('Unzipped packages:') + logger.indent += 2 + try: + for filename, count in unzipped: + logger.notify('%s (%i files)' % (filename, count)) + finally: + logger.indent -= 2 + else: + logger.notify('No unzipped packages.') + finally: + logger.indent -= 2 + + def count_package(self, path): + total = 0 + for dirpath, dirnames, filenames in os.walk(path): + filenames = [f for f in filenames + if not f.lower().endswith('.pyc')] + total += len(filenames) + return total + + +ZipCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/download.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/download.py new file mode 100644 index 00000000..f1b63936 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/download.py @@ -0,0 +1,470 @@ +import xmlrpclib +import re +import getpass +import urllib +import urllib2 +import urlparse +import os +import mimetypes +import shutil +import tempfile +from pip.backwardcompat import md5, copytree +from pip.exceptions import InstallationError +from pip.util import (splitext, + format_size, display_path, backup_dir, ask, + unpack_file, create_download_cache_folder, cache_download) +from pip.vcs import vcs +from pip.log import logger + + +__all__ = ['xmlrpclib_transport', 'get_file_content', 'urlopen', + 'is_url', 'url_to_path', 'path_to_url', 'path_to_url2', + 'geturl', 'is_archive_file', 'unpack_vcs_link', + 'unpack_file_url', 'is_vcs_url', 'is_file_url', 'unpack_http_url'] + + +xmlrpclib_transport = xmlrpclib.Transport() + + +def get_file_content(url, comes_from=None): + """Gets the content of a file; it may be a filename, file: URL, or + http: URL. Returns (location, content)""" + match = _scheme_re.search(url) + if match: + scheme = match.group(1).lower() + if (scheme == 'file' and comes_from + and comes_from.startswith('http')): + raise InstallationError( + 'Requirements file %s references URL %s, which is local' + % (comes_from, url)) + if scheme == 'file': + path = url.split(':', 1)[1] + path = path.replace('\\', '/') + match = _url_slash_drive_re.match(path) + if match: + path = match.group(1) + ':' + path.split('|', 1)[1] + path = urllib.unquote(path) + if path.startswith('/'): + path = '/' + path.lstrip('/') + url = path + else: + ## FIXME: catch some errors + resp = urlopen(url) + return geturl(resp), resp.read() + try: + f = open(url) + content = f.read() + except IOError, e: + raise InstallationError('Could not open requirements file: %s' % str(e)) + else: + f.close() + return url, content + + +_scheme_re = re.compile(r'^(http|https|file):', re.I) +_url_slash_drive_re = re.compile(r'/*([a-z])\|', re.I) + +class URLOpener(object): + """ + pip's own URL helper that adds HTTP auth and proxy support + """ + def __init__(self): + self.passman = urllib2.HTTPPasswordMgrWithDefaultRealm() + + def __call__(self, url): + """ + If the given url contains auth info or if a normal request gets a 401 + response, an attempt is made to fetch the resource using basic HTTP + auth. + + """ + url, username, password = self.extract_credentials(url) + if username is None: + try: + response = urllib2.urlopen(self.get_request(url)) + except urllib2.HTTPError, e: + if e.code != 401: + raise + response = self.get_response(url) + else: + response = self.get_response(url, username, password) + return response + + def get_request(self, url): + """ + Wraps the URL to retrieve to protects against "creative" + interpretation of the RFC: http://bugs.python.org/issue8732 + """ + if isinstance(url, basestring): + url = urllib2.Request(url, headers={'Accept-encoding': 'identity'}) + return url + + def get_response(self, url, username=None, password=None): + """ + does the dirty work of actually getting the rsponse object using urllib2 + and its HTTP auth builtins. + """ + scheme, netloc, path, query, frag = urlparse.urlsplit(url) + pass_url = urlparse.urlunsplit(('_none_', netloc, path, query, frag)).replace('_none_://', '', 1) + req = self.get_request(url) + + stored_username, stored_password = self.passman.find_user_password(None, netloc) + # see if we have a password stored + if stored_username is None: + if username is None and self.prompting: + username = urllib.quote(raw_input('User for %s: ' % netloc)) + password = urllib.quote(getpass.getpass('Password: ')) + if username and password: + self.passman.add_password(None, netloc, username, password) + stored_username, stored_password = self.passman.find_user_password(None, netloc) + authhandler = urllib2.HTTPBasicAuthHandler(self.passman) + opener = urllib2.build_opener(authhandler) + # FIXME: should catch a 401 and offer to let the user reenter credentials + return opener.open(req) + + def setup(self, proxystr='', prompting=True): + """ + Sets the proxy handler given the option passed on the command + line. If an empty string is passed it looks at the HTTP_PROXY + environment variable. + """ + self.prompting = prompting + proxy = self.get_proxy(proxystr) + if proxy: + proxy_support = urllib2.ProxyHandler({"http": proxy, "ftp": proxy}) + opener = urllib2.build_opener(proxy_support, urllib2.CacheFTPHandler) + urllib2.install_opener(opener) + + def parse_credentials(self, netloc): + if "@" in netloc: + userinfo = netloc.rsplit("@", 1)[0] + if ":" in userinfo: + return userinfo.split(":", 1) + return userinfo, None + return None, None + + def extract_credentials(self, url): + """ + Extracts user/password from a url. + + Returns a tuple: + (url-without-auth, username, password) + """ + if isinstance(url, urllib2.Request): + result = urlparse.urlsplit(url.get_full_url()) + else: + result = urlparse.urlsplit(url) + scheme, netloc, path, query, frag = result + + username, password = self.parse_credentials(netloc) + if username is None: + return url, None, None + elif password is None and self.prompting: + # remove the auth credentials from the url part + netloc = netloc.replace('%s@' % username, '', 1) + # prompt for the password + prompt = 'Password for %s@%s: ' % (username, netloc) + password = urllib.quote(getpass.getpass(prompt)) + else: + # remove the auth credentials from the url part + netloc = netloc.replace('%s:%s@' % (username, password), '', 1) + + target_url = urlparse.urlunsplit((scheme, netloc, path, query, frag)) + return target_url, username, password + + def get_proxy(self, proxystr=''): + """ + Get the proxy given the option passed on the command line. + If an empty string is passed it looks at the HTTP_PROXY + environment variable. + """ + if not proxystr: + proxystr = os.environ.get('HTTP_PROXY', '') + if proxystr: + if '@' in proxystr: + user_password, server_port = proxystr.split('@', 1) + if ':' in user_password: + user, password = user_password.split(':', 1) + else: + user = user_password + prompt = 'Password for %s@%s: ' % (user, server_port) + password = urllib.quote(getpass.getpass(prompt)) + return '%s:%s@%s' % (user, password, server_port) + else: + return proxystr + else: + return None + +urlopen = URLOpener() + + +def is_url(name): + """Returns true if the name looks like a URL""" + if ':' not in name: + return False + scheme = name.split(':', 1)[0].lower() + return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes + + +def url_to_path(url): + """ + Convert a file: URL to a path. + """ + assert url.startswith('file:'), ( + "You can only turn file: urls into filenames (not %r)" % url) + path = url[len('file:'):].lstrip('/') + path = urllib.unquote(path) + if _url_drive_re.match(path): + path = path[0] + ':' + path[2:] + else: + path = '/' + path + return path + + +_drive_re = re.compile('^([a-z]):', re.I) +_url_drive_re = re.compile('^([a-z])[:|]', re.I) + + +def path_to_url(path): + """ + Convert a path to a file: URL. The path will be made absolute. + """ + path = os.path.normcase(os.path.abspath(path)) + if _drive_re.match(path): + path = path[0] + '|' + path[2:] + url = urllib.quote(path) + url = url.replace(os.path.sep, '/') + url = url.lstrip('/') + return 'file:///' + url + + +def path_to_url2(path): + """ + Convert a path to a file: URL. The path will be made absolute and have + quoted path parts. + """ + path = os.path.normpath(os.path.abspath(path)) + drive, path = os.path.splitdrive(path) + filepath = path.split(os.path.sep) + url = '/'.join([urllib.quote(part) for part in filepath]) + if not drive: + url = url.lstrip('/') + return 'file:///' + drive + url + + +def geturl(urllib2_resp): + """ + Use instead of urllib.addinfourl.geturl(), which appears to have + some issues with dropping the double slash for certain schemes + (e.g. file://). This implementation is probably over-eager, as it + always restores '://' if it is missing, and it appears some url + schemata aren't always followed by '//' after the colon, but as + far as I know pip doesn't need any of those. + The URI RFC can be found at: http://tools.ietf.org/html/rfc1630 + + This function assumes that + scheme:/foo/bar + is the same as + scheme:///foo/bar + """ + url = urllib2_resp.geturl() + scheme, rest = url.split(':', 1) + if rest.startswith('//'): + return url + else: + # FIXME: write a good test to cover it + return '%s://%s' % (scheme, rest) + + +def is_archive_file(name): + """Return True if `name` is a considered as an archive file.""" + archives = ('.zip', '.tar.gz', '.tar.bz2', '.tgz', '.tar', '.pybundle') + ext = splitext(name)[1].lower() + if ext in archives: + return True + return False + + +def unpack_vcs_link(link, location, only_download=False): + vcs_backend = _get_used_vcs_backend(link) + if only_download: + vcs_backend.export(location) + else: + vcs_backend.unpack(location) + + +def unpack_file_url(link, location): + source = url_to_path(link.url) + content_type = mimetypes.guess_type(source)[0] + if os.path.isdir(source): + # delete the location since shutil will create it again :( + if os.path.isdir(location): + shutil.rmtree(location) + copytree(source, location) + else: + unpack_file(source, location, content_type, link) + + +def _get_used_vcs_backend(link): + for backend in vcs.backends: + if link.scheme in backend.schemes: + vcs_backend = backend(link.url) + return vcs_backend + + +def is_vcs_url(link): + return bool(_get_used_vcs_backend(link)) + + +def is_file_url(link): + return link.url.lower().startswith('file:') + + +def _check_md5(download_hash, link): + download_hash = download_hash.hexdigest() + if download_hash != link.md5_hash: + logger.fatal("MD5 hash of the package %s (%s) doesn't match the expected hash %s!" + % (link, download_hash, link.md5_hash)) + raise InstallationError('Bad MD5 hash for package %s' % link) + + +def _get_md5_from_file(target_file, link): + download_hash = md5() + fp = open(target_file, 'rb') + while 1: + chunk = fp.read(4096) + if not chunk: + break + download_hash.update(chunk) + fp.close() + return download_hash + + +def _download_url(resp, link, temp_location): + fp = open(temp_location, 'wb') + download_hash = None + if link.md5_hash: + download_hash = md5() + try: + total_length = int(resp.info()['content-length']) + except (ValueError, KeyError): + total_length = 0 + downloaded = 0 + show_progress = total_length > 40*1000 or not total_length + show_url = link.show_url + try: + if show_progress: + ## FIXME: the URL can get really long in this message: + if total_length: + logger.start_progress('Downloading %s (%s): ' % (show_url, format_size(total_length))) + else: + logger.start_progress('Downloading %s (unknown size): ' % show_url) + else: + logger.notify('Downloading %s' % show_url) + logger.debug('Downloading from URL %s' % link) + + while 1: + chunk = resp.read(4096) + if not chunk: + break + downloaded += len(chunk) + if show_progress: + if not total_length: + logger.show_progress('%s' % format_size(downloaded)) + else: + logger.show_progress('%3i%% %s' % (100*downloaded/total_length, format_size(downloaded))) + if link.md5_hash: + download_hash.update(chunk) + fp.write(chunk) + fp.close() + finally: + if show_progress: + logger.end_progress('%s downloaded' % format_size(downloaded)) + return download_hash + + +def _copy_file(filename, location, content_type, link): + copy = True + download_location = os.path.join(location, link.filename) + if os.path.exists(download_location): + response = ask('The file %s exists. (i)gnore, (w)ipe, (b)ackup ' + % display_path(download_location), ('i', 'w', 'b')) + if response == 'i': + copy = False + elif response == 'w': + logger.warn('Deleting %s' % display_path(download_location)) + os.remove(download_location) + elif response == 'b': + dest_file = backup_dir(download_location) + logger.warn('Backing up %s to %s' + % (display_path(download_location), display_path(dest_file))) + shutil.move(download_location, dest_file) + if copy: + shutil.copy(filename, download_location) + logger.indent -= 2 + logger.notify('Saved %s' % display_path(download_location)) + + +def unpack_http_url(link, location, download_cache, only_download): + temp_dir = tempfile.mkdtemp('-unpack', 'pip-') + target_url = link.url.split('#', 1)[0] + target_file = None + download_hash = None + if download_cache: + target_file = os.path.join(download_cache, + urllib.quote(target_url, '')) + if not os.path.isdir(download_cache): + create_download_cache_folder(download_cache) + if (target_file + and os.path.exists(target_file) + and os.path.exists(target_file+'.content-type')): + fp = open(target_file+'.content-type') + content_type = fp.read().strip() + fp.close() + if link.md5_hash: + download_hash = _get_md5_from_file(target_file, link) + temp_location = target_file + logger.notify('Using download cache from %s' % target_file) + else: + resp = _get_response_from_url(target_url, link) + content_type = resp.info()['content-type'] + filename = link.filename + ext = splitext(filename)[1] + if not ext: + ext = mimetypes.guess_extension(content_type) + if ext: + filename += ext + if not ext and link.url != geturl(resp): + ext = os.path.splitext(geturl(resp))[1] + if ext: + filename += ext + temp_location = os.path.join(temp_dir, filename) + download_hash = _download_url(resp, link, temp_location) + if link.md5_hash: + _check_md5(download_hash, link) + if only_download: + _copy_file(temp_location, location, content_type, link) + else: + unpack_file(temp_location, location, content_type, link) + if target_file and target_file != temp_location: + cache_download(target_file, temp_location, content_type) + if target_file is None: + os.unlink(temp_location) + os.rmdir(temp_dir) + + +def _get_response_from_url(target_url, link): + try: + resp = urlopen(target_url) + except urllib2.HTTPError, e: + logger.fatal("HTTP error %s while getting %s" % (e.code, link)) + raise + except IOError, e: + # Typically an FTP error + logger.fatal("Error %s while getting %s" % (e, link)) + raise + return resp + +class Urllib2HeadRequest(urllib2.Request): + def get_method(self): + return "HEAD" diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/exceptions.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/exceptions.py new file mode 100644 index 00000000..1ad1a616 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/exceptions.py @@ -0,0 +1,17 @@ +"""Exceptions used throughout package""" + + +class InstallationError(Exception): + """General exception during installation""" + + +class UninstallationError(Exception): + """General exception during uninstallation""" + + +class DistributionNotFound(InstallationError): + """Raised when a distribution cannot be found to satisfy a requirement""" + + +class BadCommand(Exception): + """Raised when virtualenv or a command is not found""" diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/index.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/index.py new file mode 100644 index 00000000..e42d8c86 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/index.py @@ -0,0 +1,686 @@ +"""Routines related to PyPI, indexes""" + +import sys +import os +import re +import mimetypes +import threading +import posixpath +import pkg_resources +import urllib +import urllib2 +import urlparse +import httplib +import random +import socket +import string +from Queue import Queue +from Queue import Empty as QueueEmpty +from pip.log import logger +from pip.util import Inf +from pip.util import normalize_name, splitext +from pip.exceptions import DistributionNotFound +from pip.backwardcompat import WindowsError, product +from pip.download import urlopen, path_to_url2, url_to_path, geturl, Urllib2HeadRequest + +__all__ = ['PackageFinder'] + + +DEFAULT_MIRROR_URL = "last.pypi.python.org" + + +class PackageFinder(object): + """This finds packages. + + This is meant to match easy_install's technique for looking for + packages, by reading pages and looking for appropriate links + """ + + def __init__(self, find_links, index_urls, + use_mirrors=False, mirrors=None, main_mirror_url=None): + self.find_links = find_links + self.index_urls = index_urls + self.dependency_links = [] + self.cache = PageCache() + # These are boring links that have already been logged somehow: + self.logged_links = set() + if use_mirrors: + self.mirror_urls = self._get_mirror_urls(mirrors, main_mirror_url) + logger.info('Using PyPI mirrors: %s' % ', '.join(self.mirror_urls)) + else: + self.mirror_urls = [] + + def add_dependency_links(self, links): + ## FIXME: this shouldn't be global list this, it should only + ## apply to requirements of the package that specifies the + ## dependency_links value + ## FIXME: also, we should track comes_from (i.e., use Link) + self.dependency_links.extend(links) + + @staticmethod + def _sort_locations(locations): + """ + Sort locations into "files" (archives) and "urls", and return + a pair of lists (files,urls) + """ + files = [] + urls = [] + + # puts the url for the given file path into the appropriate + # list + def sort_path(path): + url = path_to_url2(path) + if mimetypes.guess_type(url, strict=False)[0] == 'text/html': + urls.append(url) + else: + files.append(url) + + for url in locations: + if url.startswith('file:'): + path = url_to_path(url) + if os.path.isdir(path): + path = os.path.realpath(path) + for item in os.listdir(path): + sort_path(os.path.join(path, item)) + elif os.path.isfile(path): + sort_path(path) + else: + urls.append(url) + return files, urls + + def find_requirement(self, req, upgrade): + url_name = req.url_name + # Only check main index if index URL is given: + main_index_url = None + if self.index_urls: + # Check that we have the url_name correctly spelled: + main_index_url = Link(posixpath.join(self.index_urls[0], url_name)) + # This will also cache the page, so it's okay that we get it again later: + page = self._get_page(main_index_url, req) + if page is None: + url_name = self._find_url_name(Link(self.index_urls[0]), url_name, req) or req.url_name + + # Combine index URLs with mirror URLs here to allow + # adding more index URLs from requirements files + all_index_urls = self.index_urls + self.mirror_urls + + def mkurl_pypi_url(url): + loc = posixpath.join(url, url_name) + # For maximum compatibility with easy_install, ensure the path + # ends in a trailing slash. Although this isn't in the spec + # (and PyPI can handle it without the slash) some other index + # implementations might break if they relied on easy_install's behavior. + if not loc.endswith('/'): + loc = loc + '/' + return loc + if url_name is not None: + locations = [ + mkurl_pypi_url(url) + for url in all_index_urls] + self.find_links + else: + locations = list(self.find_links) + locations.extend(self.dependency_links) + for version in req.absolute_versions: + if url_name is not None and main_index_url is not None: + locations = [ + posixpath.join(main_index_url.url, version)] + locations + + file_locations, url_locations = self._sort_locations(locations) + + locations = [Link(url) for url in url_locations] + logger.debug('URLs to search for versions for %s:' % req) + for location in locations: + logger.debug('* %s' % location) + found_versions = [] + found_versions.extend( + self._package_versions( + [Link(url, '-f') for url in self.find_links], req.name.lower())) + page_versions = [] + for page in self._get_pages(locations, req): + logger.debug('Analyzing links from page %s' % page.url) + logger.indent += 2 + try: + page_versions.extend(self._package_versions(page.links, req.name.lower())) + finally: + logger.indent -= 2 + dependency_versions = list(self._package_versions( + [Link(url) for url in self.dependency_links], req.name.lower())) + if dependency_versions: + logger.info('dependency_links found: %s' % ', '.join([link.url for parsed, link, version in dependency_versions])) + file_versions = list(self._package_versions( + [Link(url) for url in file_locations], req.name.lower())) + if not found_versions and not page_versions and not dependency_versions and not file_versions: + logger.fatal('Could not find any downloads that satisfy the requirement %s' % req) + raise DistributionNotFound('No distributions at all found for %s' % req) + if req.satisfied_by is not None: + found_versions.append((req.satisfied_by.parsed_version, Inf, req.satisfied_by.version)) + if file_versions: + file_versions.sort(reverse=True) + logger.info('Local files found: %s' % ', '.join([url_to_path(link.url) for parsed, link, version in file_versions])) + found_versions = file_versions + found_versions + all_versions = found_versions + page_versions + dependency_versions + applicable_versions = [] + for (parsed_version, link, version) in all_versions: + if version not in req.req: + logger.info("Ignoring link %s, version %s doesn't match %s" + % (link, version, ','.join([''.join(s) for s in req.req.specs]))) + continue + applicable_versions.append((link, version)) + applicable_versions = sorted(applicable_versions, key=lambda v: pkg_resources.parse_version(v[1]), reverse=True) + existing_applicable = bool([link for link, version in applicable_versions if link is Inf]) + if not upgrade and existing_applicable: + if applicable_versions[0][1] is Inf: + logger.info('Existing installed version (%s) is most up-to-date and satisfies requirement' + % req.satisfied_by.version) + else: + logger.info('Existing installed version (%s) satisfies requirement (most up-to-date version is %s)' + % (req.satisfied_by.version, applicable_versions[0][1])) + return None + if not applicable_versions: + logger.fatal('Could not find a version that satisfies the requirement %s (from versions: %s)' + % (req, ', '.join([version for parsed_version, link, version in found_versions]))) + raise DistributionNotFound('No distributions matching the version for %s' % req) + if applicable_versions[0][0] is Inf: + # We have an existing version, and its the best version + logger.info('Installed version (%s) is most up-to-date (past versions: %s)' + % (req.satisfied_by.version, ', '.join([version for link, version in applicable_versions[1:]]) or 'none')) + return None + if len(applicable_versions) > 1: + logger.info('Using version %s (newest of versions: %s)' % + (applicable_versions[0][1], ', '.join([version for link, version in applicable_versions]))) + return applicable_versions[0][0] + + def _find_url_name(self, index_url, url_name, req): + """Finds the true URL name of a package, when the given name isn't quite correct. + This is usually used to implement case-insensitivity.""" + if not index_url.url.endswith('/'): + # Vaguely part of the PyPI API... weird but true. + ## FIXME: bad to modify this? + index_url.url += '/' + page = self._get_page(index_url, req) + if page is None: + logger.fatal('Cannot fetch index base URL %s' % index_url) + return + norm_name = normalize_name(req.url_name) + for link in page.links: + base = posixpath.basename(link.path.rstrip('/')) + if norm_name == normalize_name(base): + logger.notify('Real name of requirement %s is %s' % (url_name, base)) + return base + return None + + def _get_pages(self, locations, req): + """Yields (page, page_url) from the given locations, skipping + locations that have errors, and adding download/homepage links""" + pending_queue = Queue() + for location in locations: + pending_queue.put(location) + done = [] + seen = set() + threads = [] + for i in range(min(10, len(locations))): + t = threading.Thread(target=self._get_queued_page, args=(req, pending_queue, done, seen)) + t.setDaemon(True) + threads.append(t) + t.start() + for t in threads: + t.join() + return done + + _log_lock = threading.Lock() + + def _get_queued_page(self, req, pending_queue, done, seen): + while 1: + try: + location = pending_queue.get(False) + except QueueEmpty: + return + if location in seen: + continue + seen.add(location) + page = self._get_page(location, req) + if page is None: + continue + done.append(page) + for link in page.rel_links(): + pending_queue.put(link) + + _egg_fragment_re = re.compile(r'#egg=([^&]*)') + _egg_info_re = re.compile(r'([a-z0-9_.]+)-([a-z0-9_.-]+)', re.I) + _py_version_re = re.compile(r'-py([123]\.[0-9])$') + + def _sort_links(self, links): + "Returns elements of links in order, non-egg links first, egg links second, while eliminating duplicates" + eggs, no_eggs = [], [] + seen = set() + for link in links: + if link not in seen: + seen.add(link) + if link.egg_fragment: + eggs.append(link) + else: + no_eggs.append(link) + return no_eggs + eggs + + def _package_versions(self, links, search_name): + for link in self._sort_links(links): + for v in self._link_package_versions(link, search_name): + yield v + + def _link_package_versions(self, link, search_name): + """ + Return an iterable of triples (pkg_resources_version_key, + link, python_version) that can be extracted from the given + link. + + Meant to be overridden by subclasses, not called by clients. + """ + if link.egg_fragment: + egg_info = link.egg_fragment + else: + egg_info, ext = link.splitext() + if not ext: + if link not in self.logged_links: + logger.debug('Skipping link %s; not a file' % link) + self.logged_links.add(link) + return [] + if egg_info.endswith('.tar'): + # Special double-extension case: + egg_info = egg_info[:-4] + ext = '.tar' + ext + if ext not in ('.tar.gz', '.tar.bz2', '.tar', '.tgz', '.zip'): + if link not in self.logged_links: + logger.debug('Skipping link %s; unknown archive format: %s' % (link, ext)) + self.logged_links.add(link) + return [] + version = self._egg_info_matches(egg_info, search_name, link) + if version is None: + logger.debug('Skipping link %s; wrong project name (not %s)' % (link, search_name)) + return [] + match = self._py_version_re.search(version) + if match: + version = version[:match.start()] + py_version = match.group(1) + if py_version != sys.version[:3]: + logger.debug('Skipping %s because Python version is incorrect' % link) + return [] + logger.debug('Found link %s, version: %s' % (link, version)) + return [(pkg_resources.parse_version(version), + link, + version)] + + def _egg_info_matches(self, egg_info, search_name, link): + match = self._egg_info_re.search(egg_info) + if not match: + logger.debug('Could not parse version from link: %s' % link) + return None + name = match.group(0).lower() + # To match the "safe" name that pkg_resources creates: + name = name.replace('_', '-') + if name.startswith(search_name.lower()): + return match.group(0)[len(search_name):].lstrip('-') + else: + return None + + def _get_page(self, link, req): + return HTMLPage.get_page(link, req, cache=self.cache) + + def _get_mirror_urls(self, mirrors=None, main_mirror_url=None): + """Retrieves a list of URLs from the main mirror DNS entry + unless a list of mirror URLs are passed. + """ + if not mirrors: + mirrors = get_mirrors(main_mirror_url) + # Should this be made "less random"? E.g. netselect like? + random.shuffle(mirrors) + + mirror_urls = set() + for mirror_url in mirrors: + # Make sure we have a valid URL + if not ("http://" or "https://" or "file://") in mirror_url: + mirror_url = "http://%s" % mirror_url + if not mirror_url.endswith("/simple"): + mirror_url = "%s/simple/" % mirror_url + mirror_urls.add(mirror_url) + + return list(mirror_urls) + + +class PageCache(object): + """Cache of HTML pages""" + + failure_limit = 3 + + def __init__(self): + self._failures = {} + self._pages = {} + self._archives = {} + + def too_many_failures(self, url): + return self._failures.get(url, 0) >= self.failure_limit + + def get_page(self, url): + return self._pages.get(url) + + def is_archive(self, url): + return self._archives.get(url, False) + + def set_is_archive(self, url, value=True): + self._archives[url] = value + + def add_page_failure(self, url, level): + self._failures[url] = self._failures.get(url, 0)+level + + def add_page(self, urls, page): + for url in urls: + self._pages[url] = page + + +class HTMLPage(object): + """Represents one page, along with its URL""" + + ## FIXME: these regexes are horrible hacks: + _homepage_re = re.compile(r'\s*home\s*page', re.I) + _download_re = re.compile(r'\s*download\s+url', re.I) + ## These aren't so aweful: + _rel_re = re.compile("""<[^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*>""", re.I) + _href_re = re.compile('href=(?:"([^"]*)"|\'([^\']*)\'|([^>\\s\\n]*))', re.I|re.S) + _base_re = re.compile(r"""]+)""", re.I) + + def __init__(self, content, url, headers=None): + self.content = content + self.url = url + self.headers = headers + + def __str__(self): + return self.url + + @classmethod + def get_page(cls, link, req, cache=None, skip_archives=True): + url = link.url + url = url.split('#', 1)[0] + if cache.too_many_failures(url): + return None + + # Check for VCS schemes that do not support lookup as web pages. + from pip.vcs import VcsSupport + for scheme in VcsSupport.schemes: + if url.lower().startswith(scheme) and url[len(scheme)] in '+:': + logger.debug('Cannot look at %(scheme)s URL %(link)s' % locals()) + return None + + if cache is not None: + inst = cache.get_page(url) + if inst is not None: + return inst + try: + if skip_archives: + if cache is not None: + if cache.is_archive(url): + return None + filename = link.filename + for bad_ext in ['.tar', '.tar.gz', '.tar.bz2', '.tgz', '.zip']: + if filename.endswith(bad_ext): + content_type = cls._get_content_type(url) + if content_type.lower().startswith('text/html'): + break + else: + logger.debug('Skipping page %s because of Content-Type: %s' % (link, content_type)) + if cache is not None: + cache.set_is_archive(url) + return None + logger.debug('Getting page %s' % url) + + # Tack index.html onto file:// URLs that point to directories + (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url) + if scheme == 'file' and os.path.isdir(urllib.url2pathname(path)): + # add trailing slash if not present so urljoin doesn't trim final segment + if not url.endswith('/'): + url += '/' + url = urlparse.urljoin(url, 'index.html') + logger.debug(' file: URL is directory, getting %s' % url) + + resp = urlopen(url) + + real_url = geturl(resp) + headers = resp.info() + inst = cls(resp.read(), real_url, headers) + except (urllib2.HTTPError, urllib2.URLError, socket.timeout, socket.error, OSError, WindowsError), e: + desc = str(e) + if isinstance(e, socket.timeout): + log_meth = logger.info + level =1 + desc = 'timed out' + elif isinstance(e, urllib2.URLError): + log_meth = logger.info + if hasattr(e, 'reason') and isinstance(e.reason, socket.timeout): + desc = 'timed out' + level = 1 + else: + level = 2 + elif isinstance(e, urllib2.HTTPError) and e.code == 404: + ## FIXME: notify? + log_meth = logger.info + level = 2 + else: + log_meth = logger.info + level = 1 + log_meth('Could not fetch URL %s: %s' % (link, desc)) + log_meth('Will skip URL %s when looking for download links for %s' % (link.url, req)) + if cache is not None: + cache.add_page_failure(url, level) + return None + if cache is not None: + cache.add_page([url, real_url], inst) + return inst + + @staticmethod + def _get_content_type(url): + """Get the Content-Type of the given url, using a HEAD request""" + scheme, netloc, path, query, fragment = urlparse.urlsplit(url) + if not scheme in ('http', 'https', 'ftp', 'ftps'): + ## FIXME: some warning or something? + ## assertion error? + return '' + req = Urllib2HeadRequest(url, headers={'Host': netloc}) + resp = urlopen(req) + try: + if hasattr(resp, 'code') and resp.code != 200 and scheme not in ('ftp', 'ftps'): + ## FIXME: doesn't handle redirects + return '' + return resp.info().get('content-type', '') + finally: + resp.close() + + @property + def base_url(self): + if not hasattr(self, "_base_url"): + match = self._base_re.search(self.content) + if match: + self._base_url = match.group(1) + else: + self._base_url = self.url + return self._base_url + + @property + def links(self): + """Yields all links in the page""" + for match in self._href_re.finditer(self.content): + url = match.group(1) or match.group(2) or match.group(3) + url = self.clean_link(urlparse.urljoin(self.base_url, url)) + yield Link(url, self) + + def rel_links(self): + for url in self.explicit_rel_links(): + yield url + for url in self.scraped_rel_links(): + yield url + + def explicit_rel_links(self, rels=('homepage', 'download')): + """Yields all links with the given relations""" + for match in self._rel_re.finditer(self.content): + found_rels = match.group(1).lower().split() + for rel in rels: + if rel in found_rels: + break + else: + continue + match = self._href_re.search(match.group(0)) + if not match: + continue + url = match.group(1) or match.group(2) or match.group(3) + url = self.clean_link(urlparse.urljoin(self.base_url, url)) + yield Link(url, self) + + def scraped_rel_links(self): + for regex in (self._homepage_re, self._download_re): + match = regex.search(self.content) + if not match: + continue + href_match = self._href_re.search(self.content, pos=match.end()) + if not href_match: + continue + url = match.group(1) or match.group(2) or match.group(3) + if not url: + continue + url = self.clean_link(urlparse.urljoin(self.base_url, url)) + yield Link(url, self) + + _clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) + + def clean_link(self, url): + """Makes sure a link is fully encoded. That is, if a ' ' shows up in + the link, it will be rewritten to %20 (while not over-quoting + % or other characters).""" + return self._clean_re.sub( + lambda match: '%%%2x' % ord(match.group(0)), url) + + +class Link(object): + + def __init__(self, url, comes_from=None): + self.url = url + self.comes_from = comes_from + + def __str__(self): + if self.comes_from: + return '%s (from %s)' % (self.url, self.comes_from) + else: + return self.url + + def __repr__(self): + return '' % self + + def __eq__(self, other): + return self.url == other.url + + def __hash__(self): + return hash(self.url) + + @property + def filename(self): + url = self.url + url = url.split('#', 1)[0] + url = url.split('?', 1)[0] + url = url.rstrip('/') + name = posixpath.basename(url) + assert name, ( + 'URL %r produced no filename' % url) + return name + + @property + def scheme(self): + return urlparse.urlsplit(self.url)[0] + + @property + def path(self): + return urlparse.urlsplit(self.url)[2] + + def splitext(self): + return splitext(posixpath.basename(self.path.rstrip('/'))) + + _egg_fragment_re = re.compile(r'#egg=([^&]*)') + + @property + def egg_fragment(self): + match = self._egg_fragment_re.search(self.url) + if not match: + return None + return match.group(1) + + _md5_re = re.compile(r'md5=([a-f0-9]+)') + + @property + def md5_hash(self): + match = self._md5_re.search(self.url) + if match: + return match.group(1) + return None + + @property + def show_url(self): + return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0]) + + +def get_requirement_from_url(url): + """Get a requirement from the URL, if possible. This looks for #egg + in the URL""" + link = Link(url) + egg_info = link.egg_fragment + if not egg_info: + egg_info = splitext(link.filename)[0] + return package_to_requirement(egg_info) + + +def package_to_requirement(package_name): + """Translate a name like Foo-1.2 to Foo==1.3""" + match = re.search(r'^(.*?)(-dev|-\d.*)', package_name) + if match: + name = match.group(1) + version = match.group(2) + else: + name = package_name + version = '' + if version: + return '%s==%s' % (name, version) + else: + return name + + +def get_mirrors(hostname=None): + """Return the list of mirrors from the last record found on the DNS + entry:: + + >>> from pip.index import get_mirrors + >>> get_mirrors() + ['a.pypi.python.org', 'b.pypi.python.org', 'c.pypi.python.org', + 'd.pypi.python.org'] + + Originally written for the distutils2 project by Alexis Metaireau. + """ + if hostname is None: + hostname = DEFAULT_MIRROR_URL + + # return the last mirror registered on PyPI. + try: + hostname = socket.gethostbyname_ex(hostname)[0] + except socket.gaierror: + return [] + end_letter = hostname.split(".", 1) + + # determine the list from the last one. + return ["%s.%s" % (s, end_letter[1]) for s in string_range(end_letter[0])] + + +def string_range(last): + """Compute the range of string between "a" and last. + + This works for simple "a to z" lists, but also for "a to zz" lists. + """ + for k in range(len(last)): + for x in product(string.ascii_lowercase, repeat=k+1): + result = ''.join(x) + yield result + if result == last: + return + diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/locations.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/locations.py new file mode 100644 index 00000000..4254ef2f --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/locations.py @@ -0,0 +1,45 @@ +"""Locations where we look for configs, install stuff, etc""" + +import sys +import os +from distutils import sysconfig + + +def running_under_virtualenv(): + """ + Return True if we're running inside a virtualenv, False otherwise. + + """ + return hasattr(sys, 'real_prefix') + + +if running_under_virtualenv(): + ## FIXME: is build/ a good name? + build_prefix = os.path.join(sys.prefix, 'build') + src_prefix = os.path.join(sys.prefix, 'src') +else: + ## FIXME: this isn't a very good default + build_prefix = os.path.join(os.getcwd(), 'build') + src_prefix = os.path.join(os.getcwd(), 'src') + +# FIXME doesn't account for venv linked to global site-packages + +site_packages = sysconfig.get_python_lib() +user_dir = os.path.expanduser('~') +if sys.platform == 'win32': + bin_py = os.path.join(sys.prefix, 'Scripts') + # buildout uses 'bin' on Windows too? + if not os.path.exists(bin_py): + bin_py = os.path.join(sys.prefix, 'bin') + user_dir = os.environ.get('APPDATA', user_dir) # Use %APPDATA% for roaming + default_storage_dir = os.path.join(user_dir, 'pip') + default_config_file = os.path.join(default_storage_dir, 'pip.ini') + default_log_file = os.path.join(default_storage_dir, 'pip.log') +else: + bin_py = os.path.join(sys.prefix, 'bin') + default_storage_dir = os.path.join(user_dir, '.pip') + default_config_file = os.path.join(default_storage_dir, 'pip.conf') + default_log_file = os.path.join(default_storage_dir, 'pip.log') + # Forcing to use /usr/local/bin for standard Mac OS X framework installs + if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/': + bin_py = '/usr/local/bin' diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/log.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/log.py new file mode 100644 index 00000000..0218ab1a --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/log.py @@ -0,0 +1,181 @@ +"""Logging +""" + +import sys +import logging + + +class Logger(object): + + """ + Logging object for use in command-line script. Allows ranges of + levels, to avoid some redundancy of displayed information. + """ + + VERBOSE_DEBUG = logging.DEBUG-1 + DEBUG = logging.DEBUG + INFO = logging.INFO + NOTIFY = (logging.INFO+logging.WARN)/2 + WARN = WARNING = logging.WARN + ERROR = logging.ERROR + FATAL = logging.FATAL + + LEVELS = [VERBOSE_DEBUG, DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL] + + def __init__(self): + self.consumers = [] + self.indent = 0 + self.explicit_levels = False + self.in_progress = None + self.in_progress_hanging = False + + def debug(self, msg, *args, **kw): + self.log(self.DEBUG, msg, *args, **kw) + + def info(self, msg, *args, **kw): + self.log(self.INFO, msg, *args, **kw) + + def notify(self, msg, *args, **kw): + self.log(self.NOTIFY, msg, *args, **kw) + + def warn(self, msg, *args, **kw): + self.log(self.WARN, msg, *args, **kw) + + def error(self, msg, *args, **kw): + self.log(self.WARN, msg, *args, **kw) + + def fatal(self, msg, *args, **kw): + self.log(self.FATAL, msg, *args, **kw) + + def log(self, level, msg, *args, **kw): + if args: + if kw: + raise TypeError( + "You may give positional or keyword arguments, not both") + args = args or kw + rendered = None + for consumer_level, consumer in self.consumers: + if self.level_matches(level, consumer_level): + if (self.in_progress_hanging + and consumer in (sys.stdout, sys.stderr)): + self.in_progress_hanging = False + sys.stdout.write('\n') + sys.stdout.flush() + if rendered is None: + if args: + rendered = msg % args + else: + rendered = msg + rendered = ' '*self.indent + rendered + if self.explicit_levels: + ## FIXME: should this be a name, not a level number? + rendered = '%02i %s' % (level, rendered) + if hasattr(consumer, 'write'): + consumer.write(rendered+'\n') + else: + consumer(rendered) + + def start_progress(self, msg): + assert not self.in_progress, ( + "Tried to start_progress(%r) while in_progress %r" + % (msg, self.in_progress)) + if self.level_matches(self.NOTIFY, self._stdout_level()): + sys.stdout.write(' '*self.indent + msg) + sys.stdout.flush() + self.in_progress_hanging = True + else: + self.in_progress_hanging = False + self.in_progress = msg + self.last_message = None + + def end_progress(self, msg='done.'): + assert self.in_progress, ( + "Tried to end_progress without start_progress") + if self.stdout_level_matches(self.NOTIFY): + if not self.in_progress_hanging: + # Some message has been printed out since start_progress + sys.stdout.write('...' + self.in_progress + msg + '\n') + sys.stdout.flush() + else: + # These erase any messages shown with show_progress (besides .'s) + logger.show_progress('') + logger.show_progress('') + sys.stdout.write(msg + '\n') + sys.stdout.flush() + self.in_progress = None + self.in_progress_hanging = False + + def show_progress(self, message=None): + """If we are in a progress scope, and no log messages have been + shown, write out another '.'""" + if self.in_progress_hanging: + if message is None: + sys.stdout.write('.') + sys.stdout.flush() + else: + if self.last_message: + padding = ' ' * max(0, len(self.last_message)-len(message)) + else: + padding = '' + sys.stdout.write('\r%s%s%s%s' % (' '*self.indent, self.in_progress, message, padding)) + sys.stdout.flush() + self.last_message = message + + def stdout_level_matches(self, level): + """Returns true if a message at this level will go to stdout""" + return self.level_matches(level, self._stdout_level()) + + def _stdout_level(self): + """Returns the level that stdout runs at""" + for level, consumer in self.consumers: + if consumer is sys.stdout: + return level + return self.FATAL + + def level_matches(self, level, consumer_level): + """ + >>> l = Logger() + >>> l.level_matches(3, 4) + False + >>> l.level_matches(3, 2) + True + >>> l.level_matches(slice(None, 3), 3) + False + >>> l.level_matches(slice(None, 3), 2) + True + >>> l.level_matches(slice(1, 3), 1) + True + >>> l.level_matches(slice(2, 3), 1) + False + """ + if isinstance(level, slice): + start, stop = level.start, level.stop + if start is not None and start > consumer_level: + return False + if stop is not None or stop <= consumer_level: + return False + return True + else: + return level >= consumer_level + + @classmethod + def level_for_integer(cls, level): + levels = cls.LEVELS + if level < 0: + return levels[0] + if level >= len(levels): + return levels[-1] + return levels[level] + + def move_stdout_to_stderr(self): + to_remove = [] + to_add = [] + for consumer_level, consumer in self.consumers: + if consumer == sys.stdout: + to_remove.append((consumer_level, consumer)) + to_add.append((consumer_level, sys.stderr)) + for item in to_remove: + self.consumers.remove(item) + self.consumers.extend(to_add) + +logger = Logger() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/req.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/req.py new file mode 100644 index 00000000..444e7252 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/req.py @@ -0,0 +1,1432 @@ +import sys +import os +import shutil +import re +import zipfile +import pkg_resources +import tempfile +import urlparse +import urllib2 +import urllib +import ConfigParser +from distutils.sysconfig import get_python_version +from email.FeedParser import FeedParser +from pip.locations import bin_py, running_under_virtualenv +from pip.exceptions import InstallationError, UninstallationError +from pip.vcs import vcs +from pip.log import logger +from pip.util import display_path, rmtree +from pip.util import ask, backup_dir +from pip.util import is_installable_dir, is_local, dist_is_local +from pip.util import renames, normalize_path, egg_link_path +from pip.util import make_path_relative +from pip import call_subprocess +from pip.backwardcompat import any, copytree +from pip.index import Link +from pip.locations import build_prefix +from pip.download import (get_file_content, is_url, url_to_path, + path_to_url, is_archive_file, + unpack_vcs_link, is_vcs_url, is_file_url, + unpack_file_url, unpack_http_url) + + +PIP_DELETE_MARKER_FILENAME = 'pip-delete-this-directory.txt' + + +class InstallRequirement(object): + + def __init__(self, req, comes_from, source_dir=None, editable=False, + url=None, update=True): + if isinstance(req, basestring): + req = pkg_resources.Requirement.parse(req) + self.req = req + self.comes_from = comes_from + self.source_dir = source_dir + self.editable = editable + self.url = url + self._egg_info_path = None + # This holds the pkg_resources.Distribution object if this requirement + # is already available: + self.satisfied_by = None + # This hold the pkg_resources.Distribution object if this requirement + # conflicts with another installed distribution: + self.conflicts_with = None + self._temp_build_dir = None + self._is_bundle = None + # True if the editable should be updated: + self.update = update + # Set to True after successful installation + self.install_succeeded = None + # UninstallPathSet of uninstalled distribution (for possible rollback) + self.uninstalled = None + + @classmethod + def from_editable(cls, editable_req, comes_from=None, default_vcs=None): + name, url = parse_editable(editable_req, default_vcs) + if url.startswith('file:'): + source_dir = url_to_path(url) + else: + source_dir = None + return cls(name, comes_from, source_dir=source_dir, editable=True, url=url) + + @classmethod + def from_line(cls, name, comes_from=None): + """Creates an InstallRequirement from a name, which might be a + requirement, directory containing 'setup.py', filename, or URL. + """ + url = None + name = name.strip() + req = name + path = os.path.normpath(os.path.abspath(name)) + + if is_url(name): + url = name + ## FIXME: I think getting the requirement here is a bad idea: + #req = get_requirement_from_url(url) + req = None + elif os.path.isdir(path) and (os.path.sep in name or name.startswith('.')): + if not is_installable_dir(path): + raise InstallationError("Directory %r is not installable. File 'setup.py' not found." + % name) + url = path_to_url(name) + #req = get_requirement_from_url(url) + req = None + elif is_archive_file(path): + if not os.path.isfile(path): + logger.warn('Requirement %r looks like a filename, but the file does not exist' + % name) + url = path_to_url(name) + #req = get_requirement_from_url(url) + req = None + return cls(req, comes_from, url=url) + + def __str__(self): + if self.req: + s = str(self.req) + if self.url: + s += ' from %s' % self.url + else: + s = self.url + if self.satisfied_by is not None: + s += ' in %s' % display_path(self.satisfied_by.location) + if self.comes_from: + if isinstance(self.comes_from, basestring): + comes_from = self.comes_from + else: + comes_from = self.comes_from.from_path() + if comes_from: + s += ' (from %s)' % comes_from + return s + + def from_path(self): + if self.req is None: + return None + s = str(self.req) + if self.comes_from: + if isinstance(self.comes_from, basestring): + comes_from = self.comes_from + else: + comes_from = self.comes_from.from_path() + if comes_from: + s += '->' + comes_from + return s + + def build_location(self, build_dir, unpack=True): + if self._temp_build_dir is not None: + return self._temp_build_dir + if self.req is None: + self._temp_build_dir = tempfile.mkdtemp('-build', 'pip-') + self._ideal_build_dir = build_dir + return self._temp_build_dir + if self.editable: + name = self.name.lower() + else: + name = self.name + # FIXME: Is there a better place to create the build_dir? (hg and bzr need this) + if not os.path.exists(build_dir): + _make_build_dir(build_dir) + return os.path.join(build_dir, name) + + def correct_build_location(self): + """If the build location was a temporary directory, this will move it + to a new more permanent location""" + if self.source_dir is not None: + return + assert self.req is not None + assert self._temp_build_dir + old_location = self._temp_build_dir + new_build_dir = self._ideal_build_dir + del self._ideal_build_dir + if self.editable: + name = self.name.lower() + else: + name = self.name + new_location = os.path.join(new_build_dir, name) + if not os.path.exists(new_build_dir): + logger.debug('Creating directory %s' % new_build_dir) + _make_build_dir(new_build_dir) + if os.path.exists(new_location): + raise InstallationError( + 'A package already exists in %s; please remove it to continue' + % display_path(new_location)) + logger.debug('Moving package %s from %s to new location %s' + % (self, display_path(old_location), display_path(new_location))) + shutil.move(old_location, new_location) + self._temp_build_dir = new_location + self.source_dir = new_location + self._egg_info_path = None + + @property + def name(self): + if self.req is None: + return None + return self.req.project_name + + @property + def url_name(self): + if self.req is None: + return None + return urllib.quote(self.req.unsafe_name) + + @property + def setup_py(self): + return os.path.join(self.source_dir, 'setup.py') + + def run_egg_info(self, force_root_egg_info=False): + assert self.source_dir + if self.name: + logger.notify('Running setup.py egg_info for package %s' % self.name) + else: + logger.notify('Running setup.py egg_info for package from %s' % self.url) + logger.indent += 2 + try: + script = self._run_setup_py + script = script.replace('__SETUP_PY__', repr(self.setup_py)) + script = script.replace('__PKG_NAME__', repr(self.name)) + # We can't put the .egg-info files at the root, because then the source code will be mistaken + # for an installed egg, causing problems + if self.editable or force_root_egg_info: + egg_base_option = [] + else: + egg_info_dir = os.path.join(self.source_dir, 'pip-egg-info') + if not os.path.exists(egg_info_dir): + os.makedirs(egg_info_dir) + egg_base_option = ['--egg-base', 'pip-egg-info'] + call_subprocess( + [sys.executable, '-c', script, 'egg_info'] + egg_base_option, + cwd=self.source_dir, filter_stdout=self._filter_install, show_stdout=False, + command_level=logger.VERBOSE_DEBUG, + command_desc='python setup.py egg_info') + finally: + logger.indent -= 2 + if not self.req: + self.req = pkg_resources.Requirement.parse(self.pkg_info()['Name']) + self.correct_build_location() + + ## FIXME: This is a lame hack, entirely for PasteScript which has + ## a self-provided entry point that causes this awkwardness + _run_setup_py = """ +__file__ = __SETUP_PY__ +from setuptools.command import egg_info +def replacement_run(self): + self.mkpath(self.egg_info) + installer = self.distribution.fetch_build_egg + for ep in egg_info.iter_entry_points('egg_info.writers'): + # require=False is the change we're making: + writer = ep.load(require=False) + if writer: + writer(self, ep.name, egg_info.os.path.join(self.egg_info,ep.name)) + self.find_sources() +egg_info.egg_info.run = replacement_run +execfile(__file__) +""" + + def egg_info_data(self, filename): + if self.satisfied_by is not None: + if not self.satisfied_by.has_metadata(filename): + return None + return self.satisfied_by.get_metadata(filename) + assert self.source_dir + filename = self.egg_info_path(filename) + if not os.path.exists(filename): + return None + fp = open(filename, 'r') + data = fp.read() + fp.close() + return data + + def egg_info_path(self, filename): + if self._egg_info_path is None: + if self.editable: + base = self.source_dir + else: + base = os.path.join(self.source_dir, 'pip-egg-info') + filenames = os.listdir(base) + if self.editable: + filenames = [] + for root, dirs, files in os.walk(base): + for dir in vcs.dirnames: + if dir in dirs: + dirs.remove(dir) + for dir in dirs: + # Don't search in anything that looks like a virtualenv environment + if (os.path.exists(os.path.join(root, dir, 'bin', 'python')) + or os.path.exists(os.path.join(root, dir, 'Scripts', 'Python.exe'))): + dirs.remove(dir) + # Also don't search through tests + if dir == 'test' or dir == 'tests': + dirs.remove(dir) + filenames.extend([os.path.join(root, dir) + for dir in dirs]) + filenames = [f for f in filenames if f.endswith('.egg-info')] + + if not filenames: + raise InstallationError('No files/directores in %s (from %s)' % (base, filename)) + assert filenames, "No files/directories in %s (from %s)" % (base, filename) + + # if we have more than one match, we pick the toplevel one. This can + # easily be the case if there is a dist folder which contains an + # extracted tarball for testing purposes. + if len(filenames) > 1: + filenames.sort(key=lambda x: x.count(os.path.sep) + + (os.path.altsep and + x.count(os.path.altsep) or 0)) + self._egg_info_path = os.path.join(base, filenames[0]) + return os.path.join(self._egg_info_path, filename) + + def egg_info_lines(self, filename): + data = self.egg_info_data(filename) + if not data: + return [] + result = [] + for line in data.splitlines(): + line = line.strip() + if not line or line.startswith('#'): + continue + result.append(line) + return result + + def pkg_info(self): + p = FeedParser() + data = self.egg_info_data('PKG-INFO') + if not data: + logger.warn('No PKG-INFO file found in %s' % display_path(self.egg_info_path('PKG-INFO'))) + p.feed(data or '') + return p.close() + + @property + def dependency_links(self): + return self.egg_info_lines('dependency_links.txt') + + _requirements_section_re = re.compile(r'\[(.*?)\]') + + def requirements(self, extras=()): + in_extra = None + for line in self.egg_info_lines('requires.txt'): + match = self._requirements_section_re.match(line) + if match: + in_extra = match.group(1) + continue + if in_extra and in_extra not in extras: + # Skip requirement for an extra we aren't requiring + continue + yield line + + @property + def absolute_versions(self): + for qualifier, version in self.req.specs: + if qualifier == '==': + yield version + + @property + def installed_version(self): + return self.pkg_info()['version'] + + def assert_source_matches_version(self): + assert self.source_dir + if self.comes_from is None: + # We don't check the versions of things explicitly installed. + # This makes, e.g., "pip Package==dev" possible + return + version = self.installed_version + if version not in self.req: + logger.fatal( + 'Source in %s has the version %s, which does not match the requirement %s' + % (display_path(self.source_dir), version, self)) + raise InstallationError( + 'Source in %s has version %s that conflicts with %s' + % (display_path(self.source_dir), version, self)) + else: + logger.debug('Source in %s has version %s, which satisfies requirement %s' + % (display_path(self.source_dir), version, self)) + + def update_editable(self, obtain=True): + if not self.url: + logger.info("Cannot update repository at %s; repository location is unknown" % self.source_dir) + return + assert self.editable + assert self.source_dir + if self.url.startswith('file:'): + # Static paths don't get updated + return + assert '+' in self.url, "bad url: %r" % self.url + if not self.update: + return + vc_type, url = self.url.split('+', 1) + backend = vcs.get_backend(vc_type) + if backend: + vcs_backend = backend(self.url) + if obtain: + vcs_backend.obtain(self.source_dir) + else: + vcs_backend.export(self.source_dir) + else: + assert 0, ( + 'Unexpected version control type (in %s): %s' + % (self.url, vc_type)) + + def uninstall(self, auto_confirm=False): + """ + Uninstall the distribution currently satisfying this requirement. + + Prompts before removing or modifying files unless + ``auto_confirm`` is True. + + Refuses to delete or modify files outside of ``sys.prefix`` - + thus uninstallation within a virtual environment can only + modify that virtual environment, even if the virtualenv is + linked to global site-packages. + + """ + if not self.check_if_exists(): + raise UninstallationError("Cannot uninstall requirement %s, not installed" % (self.name,)) + dist = self.satisfied_by or self.conflicts_with + + paths_to_remove = UninstallPathSet(dist) + + pip_egg_info_path = os.path.join(dist.location, + dist.egg_name()) + '.egg-info' + easy_install_egg = dist.egg_name() + '.egg' + develop_egg_link = egg_link_path(dist) + if os.path.exists(pip_egg_info_path): + # package installed by pip + paths_to_remove.add(pip_egg_info_path) + if dist.has_metadata('installed-files.txt'): + for installed_file in dist.get_metadata('installed-files.txt').splitlines(): + path = os.path.normpath(os.path.join(pip_egg_info_path, installed_file)) + paths_to_remove.add(path) + if dist.has_metadata('top_level.txt'): + if dist.has_metadata('namespace_packages.txt'): + namespaces = dist.get_metadata('namespace_packages.txt') + else: + namespaces = [] + for top_level_pkg in [p for p + in dist.get_metadata('top_level.txt').splitlines() + if p and p not in namespaces]: + path = os.path.join(dist.location, top_level_pkg) + paths_to_remove.add(path) + paths_to_remove.add(path + '.py') + paths_to_remove.add(path + '.pyc') + + elif dist.location.endswith(easy_install_egg): + # package installed by easy_install + paths_to_remove.add(dist.location) + easy_install_pth = os.path.join(os.path.dirname(dist.location), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) + + elif os.path.isfile(develop_egg_link): + # develop egg + fh = open(develop_egg_link, 'r') + link_pointer = os.path.normcase(fh.readline().strip()) + fh.close() + assert (link_pointer == dist.location), 'Egg-link %s does not match installed location of %s (at %s)' % (link_pointer, self.name, dist.location) + paths_to_remove.add(develop_egg_link) + easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, dist.location) + + # find distutils scripts= scripts + if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'): + for script in dist.metadata_listdir('scripts'): + paths_to_remove.add(os.path.join(bin_py, script)) + if sys.platform == 'win32': + paths_to_remove.add(os.path.join(bin_py, script) + '.bat') + + # find console_scripts + if dist.has_metadata('entry_points.txt'): + config = ConfigParser.SafeConfigParser() + config.readfp(FakeFile(dist.get_metadata_lines('entry_points.txt'))) + if config.has_section('console_scripts'): + for name, value in config.items('console_scripts'): + paths_to_remove.add(os.path.join(bin_py, name)) + if sys.platform == 'win32': + paths_to_remove.add(os.path.join(bin_py, name) + '.exe') + paths_to_remove.add(os.path.join(bin_py, name) + '.exe.manifest') + paths_to_remove.add(os.path.join(bin_py, name) + '-script.py') + + paths_to_remove.remove(auto_confirm) + self.uninstalled = paths_to_remove + + def rollback_uninstall(self): + if self.uninstalled: + self.uninstalled.rollback() + else: + logger.error("Can't rollback %s, nothing uninstalled." + % (self.project_name,)) + + def commit_uninstall(self): + if self.uninstalled: + self.uninstalled.commit() + else: + logger.error("Can't commit %s, nothing uninstalled." + % (self.project_name,)) + + def archive(self, build_dir): + assert self.source_dir + create_archive = True + archive_name = '%s-%s.zip' % (self.name, self.installed_version) + archive_path = os.path.join(build_dir, archive_name) + if os.path.exists(archive_path): + response = ask('The file %s exists. (i)gnore, (w)ipe, (b)ackup ' + % display_path(archive_path), ('i', 'w', 'b')) + if response == 'i': + create_archive = False + elif response == 'w': + logger.warn('Deleting %s' % display_path(archive_path)) + os.remove(archive_path) + elif response == 'b': + dest_file = backup_dir(archive_path) + logger.warn('Backing up %s to %s' + % (display_path(archive_path), display_path(dest_file))) + shutil.move(archive_path, dest_file) + if create_archive: + zip = zipfile.ZipFile(archive_path, 'w', zipfile.ZIP_DEFLATED) + dir = os.path.normcase(os.path.abspath(self.source_dir)) + for dirpath, dirnames, filenames in os.walk(dir): + if 'pip-egg-info' in dirnames: + dirnames.remove('pip-egg-info') + for dirname in dirnames: + dirname = os.path.join(dirpath, dirname) + name = self._clean_zip_name(dirname, dir) + zipdir = zipfile.ZipInfo(self.name + '/' + name + '/') + zipdir.external_attr = 0755 << 16L + zip.writestr(zipdir, '') + for filename in filenames: + if filename == PIP_DELETE_MARKER_FILENAME: + continue + filename = os.path.join(dirpath, filename) + name = self._clean_zip_name(filename, dir) + zip.write(filename, self.name + '/' + name) + zip.close() + logger.indent -= 2 + logger.notify('Saved %s' % display_path(archive_path)) + + def _clean_zip_name(self, name, prefix): + assert name.startswith(prefix+os.path.sep), ( + "name %r doesn't start with prefix %r" % (name, prefix)) + name = name[len(prefix)+1:] + name = name.replace(os.path.sep, '/') + return name + + def install(self, install_options, global_options=()): + if self.editable: + self.install_editable(install_options, global_options) + return + temp_location = tempfile.mkdtemp('-record', 'pip-') + record_filename = os.path.join(temp_location, 'install-record.txt') + try: + + install_args = [ + sys.executable, '-c', + "import setuptools;__file__=%r;"\ + "execfile(__file__)" % self.setup_py] +\ + list(global_options) + [ + 'install', + '--single-version-externally-managed', + '--record', record_filename] + + if running_under_virtualenv(): + ## FIXME: I'm not sure if this is a reasonable location; probably not + ## but we can't put it in the default location, as that is a virtualenv symlink that isn't writable + install_args += ['--install-headers', + os.path.join(sys.prefix, 'include', 'site', + 'python' + get_python_version())] + logger.notify('Running setup.py install for %s' % self.name) + logger.indent += 2 + try: + call_subprocess(install_args + install_options, + cwd=self.source_dir, filter_stdout=self._filter_install, show_stdout=False) + finally: + logger.indent -= 2 + if not os.path.exists(record_filename): + logger.notify('Record file %s not found' % record_filename) + return + self.install_succeeded = True + f = open(record_filename) + for line in f: + line = line.strip() + if line.endswith('.egg-info'): + egg_info_dir = line + break + else: + logger.warn('Could not find .egg-info directory in install record for %s' % self) + ## FIXME: put the record somewhere + ## FIXME: should this be an error? + return + f.close() + new_lines = [] + f = open(record_filename) + for line in f: + filename = line.strip() + if os.path.isdir(filename): + filename += os.path.sep + new_lines.append(make_path_relative(filename, egg_info_dir)) + f.close() + f = open(os.path.join(egg_info_dir, 'installed-files.txt'), 'w') + f.write('\n'.join(new_lines)+'\n') + f.close() + finally: + if os.path.exists(record_filename): + os.remove(record_filename) + os.rmdir(temp_location) + + def remove_temporary_source(self): + """Remove the source files from this requirement, if they are marked + for deletion""" + if self.is_bundle or os.path.exists(self.delete_marker_filename): + logger.info('Removing source in %s' % self.source_dir) + if self.source_dir: + rmtree(self.source_dir) + self.source_dir = None + if self._temp_build_dir and os.path.exists(self._temp_build_dir): + rmtree(self._temp_build_dir) + self._temp_build_dir = None + + def install_editable(self, install_options, global_options=()): + logger.notify('Running setup.py develop for %s' % self.name) + logger.indent += 2 + try: + ## FIXME: should we do --install-headers here too? + call_subprocess( + [sys.executable, '-c', + "import setuptools; __file__=%r; execfile(%r)" % (self.setup_py, self.setup_py)] + + list(global_options) + ['develop', '--no-deps'] + list(install_options), + + cwd=self.source_dir, filter_stdout=self._filter_install, + show_stdout=False) + finally: + logger.indent -= 2 + self.install_succeeded = True + + def _filter_install(self, line): + level = logger.NOTIFY + for regex in [r'^running .*', r'^writing .*', '^creating .*', '^[Cc]opying .*', + r'^reading .*', r"^removing .*\.egg-info' \(and everything under it\)$", + r'^byte-compiling ', + # Not sure what this warning is, but it seems harmless: + r"^warning: manifest_maker: standard file '-c' not found$"]: + if re.search(regex, line.strip()): + level = logger.INFO + break + return (level, line) + + def check_if_exists(self): + """Find an installed distribution that satisfies or conflicts + with this requirement, and set self.satisfied_by or + self.conflicts_with appropriately.""" + if self.req is None: + return False + try: + self.satisfied_by = pkg_resources.get_distribution(self.req) + except pkg_resources.DistributionNotFound: + return False + except pkg_resources.VersionConflict: + self.conflicts_with = pkg_resources.get_distribution(self.req.project_name) + return True + + @property + def is_bundle(self): + if self._is_bundle is not None: + return self._is_bundle + base = self._temp_build_dir + if not base: + ## FIXME: this doesn't seem right: + return False + self._is_bundle = (os.path.exists(os.path.join(base, 'pip-manifest.txt')) + or os.path.exists(os.path.join(base, 'pyinstall-manifest.txt'))) + return self._is_bundle + + def bundle_requirements(self): + for dest_dir in self._bundle_editable_dirs: + package = os.path.basename(dest_dir) + ## FIXME: svnism: + for vcs_backend in vcs.backends: + url = rev = None + vcs_bundle_file = os.path.join( + dest_dir, vcs_backend.bundle_file) + if os.path.exists(vcs_bundle_file): + vc_type = vcs_backend.name + fp = open(vcs_bundle_file) + content = fp.read() + fp.close() + url, rev = vcs_backend().parse_vcs_bundle_file(content) + break + if url: + url = '%s+%s@%s' % (vc_type, url, rev) + else: + url = None + yield InstallRequirement( + package, self, editable=True, url=url, + update=False, source_dir=dest_dir) + for dest_dir in self._bundle_build_dirs: + package = os.path.basename(dest_dir) + yield InstallRequirement( + package, self, + source_dir=dest_dir) + + def move_bundle_files(self, dest_build_dir, dest_src_dir): + base = self._temp_build_dir + assert base + src_dir = os.path.join(base, 'src') + build_dir = os.path.join(base, 'build') + bundle_build_dirs = [] + bundle_editable_dirs = [] + for source_dir, dest_dir, dir_collection in [ + (src_dir, dest_src_dir, bundle_editable_dirs), + (build_dir, dest_build_dir, bundle_build_dirs)]: + if os.path.exists(source_dir): + for dirname in os.listdir(source_dir): + dest = os.path.join(dest_dir, dirname) + dir_collection.append(dest) + if os.path.exists(dest): + logger.warn('The directory %s (containing package %s) already exists; cannot move source from bundle %s' + % (dest, dirname, self)) + continue + if not os.path.exists(dest_dir): + logger.info('Creating directory %s' % dest_dir) + os.makedirs(dest_dir) + shutil.move(os.path.join(source_dir, dirname), dest) + if not os.listdir(source_dir): + os.rmdir(source_dir) + self._temp_build_dir = None + self._bundle_build_dirs = bundle_build_dirs + self._bundle_editable_dirs = bundle_editable_dirs + + @property + def delete_marker_filename(self): + assert self.source_dir + return os.path.join(self.source_dir, PIP_DELETE_MARKER_FILENAME) + + +DELETE_MARKER_MESSAGE = '''\ +This file is placed here by pip to indicate the source was put +here by pip. + +Once this package is successfully installed this source code will be +deleted (unless you remove this file). +''' + + +class RequirementSet(object): + + def __init__(self, build_dir, src_dir, download_dir, download_cache=None, + upgrade=False, ignore_installed=False, + ignore_dependencies=False): + self.build_dir = build_dir + self.src_dir = src_dir + self.download_dir = download_dir + self.download_cache = download_cache + self.upgrade = upgrade + self.ignore_installed = ignore_installed + self.requirements = {} + # Mapping of alias: real_name + self.requirement_aliases = {} + self.unnamed_requirements = [] + self.ignore_dependencies = ignore_dependencies + self.successfully_downloaded = [] + self.successfully_installed = [] + self.reqs_to_cleanup = [] + + def __str__(self): + reqs = [req for req in self.requirements.values() + if not req.comes_from] + reqs.sort(key=lambda req: req.name.lower()) + return ' '.join([str(req.req) for req in reqs]) + + def add_requirement(self, install_req): + name = install_req.name + if not name: + self.unnamed_requirements.append(install_req) + else: + if self.has_requirement(name): + raise InstallationError( + 'Double requirement given: %s (aready in %s, name=%r)' + % (install_req, self.get_requirement(name), name)) + self.requirements[name] = install_req + ## FIXME: what about other normalizations? E.g., _ vs. -? + if name.lower() != name: + self.requirement_aliases[name.lower()] = name + + def has_requirement(self, project_name): + for name in project_name, project_name.lower(): + if name in self.requirements or name in self.requirement_aliases: + return True + return False + + @property + def has_requirements(self): + return self.requirements.values() or self.unnamed_requirements + + @property + def has_editables(self): + if any(req.editable for req in self.requirements.values()): + return True + if any(req.editable for req in self.unnamed_requirements): + return True + return False + + @property + def is_download(self): + if self.download_dir: + self.download_dir = os.path.expanduser(self.download_dir) + if os.path.exists(self.download_dir): + return True + else: + logger.fatal('Could not find download directory') + raise InstallationError( + "Could not find or access download directory '%s'" + % display_path(self.download_dir)) + return False + + def get_requirement(self, project_name): + for name in project_name, project_name.lower(): + if name in self.requirements: + return self.requirements[name] + if name in self.requirement_aliases: + return self.requirements[self.requirement_aliases[name]] + raise KeyError("No project with the name %r" % project_name) + + def uninstall(self, auto_confirm=False): + for req in self.requirements.values(): + req.uninstall(auto_confirm=auto_confirm) + req.commit_uninstall() + + def locate_files(self): + ## FIXME: duplicates code from install_files; relevant code should + ## probably be factored out into a separate method + unnamed = list(self.unnamed_requirements) + reqs = self.requirements.values() + while reqs or unnamed: + if unnamed: + req_to_install = unnamed.pop(0) + else: + req_to_install = reqs.pop(0) + install_needed = True + if not self.ignore_installed and not req_to_install.editable: + req_to_install.check_if_exists() + if req_to_install.satisfied_by: + if self.upgrade: + req_to_install.conflicts_with = req_to_install.satisfied_by + req_to_install.satisfied_by = None + else: + install_needed = False + if req_to_install.satisfied_by: + logger.notify('Requirement already satisfied ' + '(use --upgrade to upgrade): %s' + % req_to_install) + + if req_to_install.editable: + if req_to_install.source_dir is None: + req_to_install.source_dir = req_to_install.build_location(self.src_dir) + elif install_needed: + req_to_install.source_dir = req_to_install.build_location(self.build_dir, not self.is_download) + + if req_to_install.source_dir is not None and not os.path.isdir(req_to_install.source_dir): + raise InstallationError('Could not install requirement %s ' + 'because source folder %s does not exist ' + '(perhaps --no-download was used without first running ' + 'an equivalent install with --no-install?)' + % (req_to_install, req_to_install.source_dir)) + + def prepare_files(self, finder, force_root_egg_info=False, bundle=False): + """Prepare process. Create temp directories, download and/or unpack files.""" + unnamed = list(self.unnamed_requirements) + reqs = self.requirements.values() + while reqs or unnamed: + if unnamed: + req_to_install = unnamed.pop(0) + else: + req_to_install = reqs.pop(0) + install = True + if not self.ignore_installed and not req_to_install.editable: + req_to_install.check_if_exists() + if req_to_install.satisfied_by: + if self.upgrade: + req_to_install.conflicts_with = req_to_install.satisfied_by + req_to_install.satisfied_by = None + else: + install = False + if req_to_install.satisfied_by: + logger.notify('Requirement already satisfied ' + '(use --upgrade to upgrade): %s' + % req_to_install) + if req_to_install.editable: + logger.notify('Obtaining %s' % req_to_install) + elif install: + if req_to_install.url and req_to_install.url.lower().startswith('file:'): + logger.notify('Unpacking %s' % display_path(url_to_path(req_to_install.url))) + else: + logger.notify('Downloading/unpacking %s' % req_to_install) + logger.indent += 2 + try: + is_bundle = False + if req_to_install.editable: + if req_to_install.source_dir is None: + location = req_to_install.build_location(self.src_dir) + req_to_install.source_dir = location + else: + location = req_to_install.source_dir + if not os.path.exists(self.build_dir): + _make_build_dir(self.build_dir) + req_to_install.update_editable(not self.is_download) + if self.is_download: + req_to_install.run_egg_info() + req_to_install.archive(self.download_dir) + else: + req_to_install.run_egg_info() + elif install: + ##@@ if filesystem packages are not marked + ##editable in a req, a non deterministic error + ##occurs when the script attempts to unpack the + ##build directory + + location = req_to_install.build_location(self.build_dir, not self.is_download) + ## FIXME: is the existance of the checkout good enough to use it? I don't think so. + unpack = True + if not os.path.exists(os.path.join(location, 'setup.py')): + ## FIXME: this won't upgrade when there's an existing package unpacked in `location` + if req_to_install.url is None: + url = finder.find_requirement(req_to_install, upgrade=self.upgrade) + else: + ## FIXME: should req_to_install.url already be a link? + url = Link(req_to_install.url) + assert url + if url: + try: + self.unpack_url(url, location, self.is_download) + except urllib2.HTTPError, e: + logger.fatal('Could not install requirement %s because of error %s' + % (req_to_install, e)) + raise InstallationError( + 'Could not install requirement %s because of HTTP error %s for URL %s' + % (req_to_install, e, url)) + else: + unpack = False + if unpack: + is_bundle = req_to_install.is_bundle + url = None + if is_bundle: + req_to_install.move_bundle_files(self.build_dir, self.src_dir) + for subreq in req_to_install.bundle_requirements(): + reqs.append(subreq) + self.add_requirement(subreq) + elif self.is_download: + req_to_install.source_dir = location + if url and url.scheme in vcs.all_schemes: + req_to_install.run_egg_info() + req_to_install.archive(self.download_dir) + else: + req_to_install.source_dir = location + req_to_install.run_egg_info() + if force_root_egg_info: + # We need to run this to make sure that the .egg-info/ + # directory is created for packing in the bundle + req_to_install.run_egg_info(force_root_egg_info=True) + req_to_install.assert_source_matches_version() + #@@ sketchy way of identifying packages not grabbed from an index + if bundle and req_to_install.url: + self.copy_to_build_dir(req_to_install) + if not is_bundle and not self.is_download: + ## FIXME: shouldn't be globally added: + finder.add_dependency_links(req_to_install.dependency_links) + ## FIXME: add extras in here: + if not self.ignore_dependencies: + for req in req_to_install.requirements(): + try: + name = pkg_resources.Requirement.parse(req).project_name + except ValueError, e: + ## FIXME: proper warning + logger.error('Invalid requirement: %r (%s) in requirement %s' % (req, e, req_to_install)) + continue + if self.has_requirement(name): + ## FIXME: check for conflict + continue + subreq = InstallRequirement(req, req_to_install) + reqs.append(subreq) + self.add_requirement(subreq) + if req_to_install.name not in self.requirements: + self.requirements[req_to_install.name] = req_to_install + else: + self.reqs_to_cleanup.append(req_to_install) + if install: + self.successfully_downloaded.append(req_to_install) + if bundle and (req_to_install.url and req_to_install.url.startswith('file:///')): + self.copy_to_build_dir(req_to_install) + finally: + logger.indent -= 2 + + def cleanup_files(self, bundle=False): + """Clean up files, remove builds.""" + logger.notify('Cleaning up...') + logger.indent += 2 + for req in self.reqs_to_cleanup: + req.remove_temporary_source() + + remove_dir = [] + if self._pip_has_created_build_dir(): + remove_dir.append(self.build_dir) + + # The source dir of a bundle can always be removed. + if bundle: + remove_dir.append(self.src_dir) + + for dir in remove_dir: + if os.path.exists(dir): + logger.info('Removing temporary dir %s...' % dir) + rmtree(dir) + + logger.indent -= 2 + + def _pip_has_created_build_dir(self): + return (self.build_dir == build_prefix and + os.path.exists(os.path.join(self.build_dir, PIP_DELETE_MARKER_FILENAME))) + + def copy_to_build_dir(self, req_to_install): + target_dir = req_to_install.editable and self.src_dir or self.build_dir + logger.info("Copying %s to %s" %(req_to_install.name, target_dir)) + dest = os.path.join(target_dir, req_to_install.name) + copytree(req_to_install.source_dir, dest) + call_subprocess(["python", "%s/setup.py"%dest, "clean"]) + + def unpack_url(self, link, location, only_download=False): + if only_download: + location = self.download_dir + if is_vcs_url(link): + return unpack_vcs_link(link, location, only_download) + elif is_file_url(link): + return unpack_file_url(link, location) + else: + if self.download_cache: + self.download_cache = os.path.expanduser(self.download_cache) + return unpack_http_url(link, location, self.download_cache, only_download) + + def install(self, install_options, global_options=()): + """Install everything in this set (after having downloaded and unpacked the packages)""" + to_install = sorted([r for r in self.requirements.values() + if self.upgrade or not r.satisfied_by], + key=lambda p: p.name.lower()) + if to_install: + logger.notify('Installing collected packages: %s' % (', '.join([req.name for req in to_install]))) + logger.indent += 2 + try: + for requirement in to_install: + if requirement.conflicts_with: + logger.notify('Found existing installation: %s' + % requirement.conflicts_with) + logger.indent += 2 + try: + requirement.uninstall(auto_confirm=True) + finally: + logger.indent -= 2 + try: + requirement.install(install_options, global_options) + except: + # if install did not succeed, rollback previous uninstall + if requirement.conflicts_with and not requirement.install_succeeded: + requirement.rollback_uninstall() + raise + else: + if requirement.conflicts_with and requirement.install_succeeded: + requirement.commit_uninstall() + requirement.remove_temporary_source() + finally: + logger.indent -= 2 + self.successfully_installed = to_install + + def create_bundle(self, bundle_filename): + ## FIXME: can't decide which is better; zip is easier to read + ## random files from, but tar.bz2 is smaller and not as lame a + ## format. + + ## FIXME: this file should really include a manifest of the + ## packages, maybe some other metadata files. It would make + ## it easier to detect as well. + zip = zipfile.ZipFile(bundle_filename, 'w', zipfile.ZIP_DEFLATED) + vcs_dirs = [] + for dir, basename in (self.build_dir, 'build'), (self.src_dir, 'src'): + dir = os.path.normcase(os.path.abspath(dir)) + for dirpath, dirnames, filenames in os.walk(dir): + for backend in vcs.backends: + vcs_backend = backend() + vcs_url = vcs_rev = None + if vcs_backend.dirname in dirnames: + for vcs_dir in vcs_dirs: + if dirpath.startswith(vcs_dir): + # vcs bundle file already in parent directory + break + else: + vcs_url, vcs_rev = vcs_backend.get_info( + os.path.join(dir, dirpath)) + vcs_dirs.append(dirpath) + vcs_bundle_file = vcs_backend.bundle_file + vcs_guide = vcs_backend.guide % {'url': vcs_url, + 'rev': vcs_rev} + dirnames.remove(vcs_backend.dirname) + break + if 'pip-egg-info' in dirnames: + dirnames.remove('pip-egg-info') + for dirname in dirnames: + dirname = os.path.join(dirpath, dirname) + name = self._clean_zip_name(dirname, dir) + zip.writestr(basename + '/' + name + '/', '') + for filename in filenames: + if filename == PIP_DELETE_MARKER_FILENAME: + continue + filename = os.path.join(dirpath, filename) + name = self._clean_zip_name(filename, dir) + zip.write(filename, basename + '/' + name) + if vcs_url: + name = os.path.join(dirpath, vcs_bundle_file) + name = self._clean_zip_name(name, dir) + zip.writestr(basename + '/' + name, vcs_guide) + + zip.writestr('pip-manifest.txt', self.bundle_requirements()) + zip.close() + + BUNDLE_HEADER = '''\ +# This is a pip bundle file, that contains many source packages +# that can be installed as a group. You can install this like: +# pip this_file.zip +# The rest of the file contains a list of all the packages included: +''' + + def bundle_requirements(self): + parts = [self.BUNDLE_HEADER] + for req in sorted( + [req for req in self.requirements.values() + if not req.comes_from], + key=lambda x: x.name): + parts.append('%s==%s\n' % (req.name, req.installed_version)) + parts.append('# These packages were installed to satisfy the above requirements:\n') + for req in sorted( + [req for req in self.requirements.values() + if req.comes_from], + key=lambda x: x.name): + parts.append('%s==%s\n' % (req.name, req.installed_version)) + ## FIXME: should we do something with self.unnamed_requirements? + return ''.join(parts) + + def _clean_zip_name(self, name, prefix): + assert name.startswith(prefix+os.path.sep), ( + "name %r doesn't start with prefix %r" % (name, prefix)) + name = name[len(prefix)+1:] + name = name.replace(os.path.sep, '/') + return name + + +def _make_build_dir(build_dir): + os.makedirs(build_dir) + _write_delete_marker_message(os.path.join(build_dir, PIP_DELETE_MARKER_FILENAME)) + + +def _write_delete_marker_message(filepath): + marker_fp = open(filepath, 'w') + marker_fp.write(DELETE_MARKER_MESSAGE) + marker_fp.close() + + +_scheme_re = re.compile(r'^(http|https|file):', re.I) + + +def parse_requirements(filename, finder=None, comes_from=None, options=None): + skip_match = None + skip_regex = options.skip_requirements_regex + if skip_regex: + skip_match = re.compile(skip_regex) + filename, content = get_file_content(filename, comes_from=comes_from) + for line_number, line in enumerate(content.splitlines()): + line_number += 1 + line = line.strip() + if not line or line.startswith('#'): + continue + if skip_match and skip_match.search(line): + continue + if line.startswith('-r') or line.startswith('--requirement'): + if line.startswith('-r'): + req_url = line[2:].strip() + else: + req_url = line[len('--requirement'):].strip().strip('=') + if _scheme_re.search(filename): + # Relative to a URL + req_url = urlparse.urljoin(req_url, filename) + elif not _scheme_re.search(req_url): + req_url = os.path.join(os.path.dirname(filename), req_url) + for item in parse_requirements(req_url, finder, comes_from=filename, options=options): + yield item + elif line.startswith('-Z') or line.startswith('--always-unzip'): + # No longer used, but previously these were used in + # requirement files, so we'll ignore. + pass + elif line.startswith('-f') or line.startswith('--find-links'): + if line.startswith('-f'): + line = line[2:].strip() + else: + line = line[len('--find-links'):].strip().lstrip('=') + ## FIXME: it would be nice to keep track of the source of + ## the find_links: + if finder: + finder.find_links.append(line) + elif line.startswith('-i') or line.startswith('--index-url'): + if line.startswith('-i'): + line = line[2:].strip() + else: + line = line[len('--index-url'):].strip().lstrip('=') + if finder: + finder.index_urls = [line] + elif line.startswith('--extra-index-url'): + line = line[len('--extra-index-url'):].strip().lstrip('=') + if finder: + finder.index_urls.append(line) + else: + comes_from = '-r %s (line %s)' % (filename, line_number) + if line.startswith('-e') or line.startswith('--editable'): + if line.startswith('-e'): + line = line[2:].strip() + else: + line = line[len('--editable'):].strip() + req = InstallRequirement.from_editable( + line, comes_from=comes_from, default_vcs=options.default_vcs) + else: + req = InstallRequirement.from_line(line, comes_from) + yield req + + +def parse_editable(editable_req, default_vcs=None): + """Parses svn+http://blahblah@rev#egg=Foobar into a requirement + (Foobar) and a URL""" + url = editable_req + if os.path.isdir(url) and os.path.exists(os.path.join(url, 'setup.py')): + # Treating it as code that has already been checked out + url = path_to_url(url) + if url.lower().startswith('file:'): + return None, url + for version_control in vcs: + if url.lower().startswith('%s:' % version_control): + url = '%s+%s' % (version_control, url) + if '+' not in url: + if default_vcs: + url = default_vcs + '+' + url + else: + raise InstallationError( + '--editable=%s should be formatted with svn+URL, git+URL, hg+URL or bzr+URL' % editable_req) + vc_type = url.split('+', 1)[0].lower() + if not vcs.get_backend(vc_type): + raise InstallationError( + 'For --editable=%s only svn (svn+URL), Git (git+URL), Mercurial (hg+URL) and Bazaar (bzr+URL) is currently supported' % editable_req) + match = re.search(r'(?:#|#.*?&)egg=([^&]*)', editable_req) + if (not match or not match.group(1)) and vcs.get_backend(vc_type): + parts = [p for p in editable_req.split('#', 1)[0].split('/') if p] + if parts[-2] in ('tags', 'branches', 'tag', 'branch'): + req = parts[-3] + elif parts[-1] == 'trunk': + req = parts[-2] + else: + raise InstallationError( + '--editable=%s is not the right format; it must have #egg=Package' + % editable_req) + else: + req = match.group(1) + ## FIXME: use package_to_requirement? + match = re.search(r'^(.*?)(?:-dev|-\d.*)', req) + if match: + # Strip off -dev, -0.2, etc. + req = match.group(1) + return req, url + + +class UninstallPathSet(object): + """A set of file paths to be removed in the uninstallation of a + requirement.""" + def __init__(self, dist): + self.paths = set() + self._refuse = set() + self.pth = {} + self.dist = dist + self.save_dir = None + self._moved_paths = [] + + def _permitted(self, path): + """ + Return True if the given path is one we are permitted to + remove/modify, False otherwise. + + """ + return is_local(path) + + def _can_uninstall(self): + if not dist_is_local(self.dist): + logger.notify("Not uninstalling %s at %s, outside environment %s" + % (self.dist.project_name, normalize_path(self.dist.location), sys.prefix)) + return False + return True + + def add(self, path): + path = normalize_path(path) + if not os.path.exists(path): + return + if self._permitted(path): + self.paths.add(path) + else: + self._refuse.add(path) + + def add_pth(self, pth_file, entry): + pth_file = normalize_path(pth_file) + if self._permitted(pth_file): + if pth_file not in self.pth: + self.pth[pth_file] = UninstallPthEntries(pth_file) + self.pth[pth_file].add(entry) + else: + self._refuse.add(pth_file) + + def compact(self, paths): + """Compact a path set to contain the minimal number of paths + necessary to contain all paths in the set. If /a/path/ and + /a/path/to/a/file.txt are both in the set, leave only the + shorter path.""" + short_paths = set() + for path in sorted(paths, key=len): + if not any([(path.startswith(shortpath) and + path[len(shortpath.rstrip(os.path.sep))] == os.path.sep) + for shortpath in short_paths]): + short_paths.add(path) + return short_paths + + def _stash(self, path): + return os.path.join( + self.save_dir, os.path.splitdrive(path)[1].lstrip(os.path.sep)) + + def remove(self, auto_confirm=False): + """Remove paths in ``self.paths`` with confirmation (unless + ``auto_confirm`` is True).""" + if not self._can_uninstall(): + return + logger.notify('Uninstalling %s:' % self.dist.project_name) + logger.indent += 2 + paths = sorted(self.compact(self.paths)) + try: + if auto_confirm: + response = 'y' + else: + for path in paths: + logger.notify(path) + response = ask('Proceed (y/n)? ', ('y', 'n')) + if self._refuse: + logger.notify('Not removing or modifying (outside of prefix):') + for path in self.compact(self._refuse): + logger.notify(path) + if response == 'y': + self.save_dir = tempfile.mkdtemp(suffix='-uninstall', + prefix='pip-') + for path in paths: + new_path = self._stash(path) + logger.info('Removing file or directory %s' % path) + self._moved_paths.append(path) + renames(path, new_path) + for pth in self.pth.values(): + pth.remove() + logger.notify('Successfully uninstalled %s' % self.dist.project_name) + + finally: + logger.indent -= 2 + + def rollback(self): + """Rollback the changes previously made by remove().""" + if self.save_dir is None: + logger.error("Can't roll back %s; was not uninstalled" % self.dist.project_name) + return False + logger.notify('Rolling back uninstall of %s' % self.dist.project_name) + for path in self._moved_paths: + tmp_path = self._stash(path) + logger.info('Replacing %s' % path) + renames(tmp_path, path) + for pth in self.pth: + pth.rollback() + + def commit(self): + """Remove temporary save dir: rollback will no longer be possible.""" + if self.save_dir is not None: + shutil.rmtree(self.save_dir) + self.save_dir = None + self._moved_paths = [] + + +class UninstallPthEntries(object): + def __init__(self, pth_file): + if not os.path.isfile(pth_file): + raise UninstallationError("Cannot remove entries from nonexistent file %s" % pth_file) + self.file = pth_file + self.entries = set() + self._saved_lines = None + + def add(self, entry): + entry = os.path.normcase(entry) + # On Windows, os.path.normcase converts the entry to use + # backslashes. This is correct for entries that describe absolute + # paths outside of site-packages, but all the others use forward + # slashes. + if sys.platform == 'win32' and not os.path.splitdrive(entry)[0]: + entry = entry.replace('\\', '/') + self.entries.add(entry) + + def remove(self): + logger.info('Removing pth entries from %s:' % self.file) + fh = open(self.file, 'r') + lines = fh.readlines() + self._saved_lines = lines + fh.close() + try: + for entry in self.entries: + logger.info('Removing entry: %s' % entry) + try: + lines.remove(entry + '\n') + except ValueError: + pass + finally: + pass + fh = open(self.file, 'wb') + fh.writelines(lines) + fh.close() + + def rollback(self): + if self._saved_lines is None: + logger.error('Cannot roll back changes to %s, none were made' % self.file) + return False + logger.info('Rolling %s back to previous state' % self.file) + fh = open(self.file, 'wb') + fh.writelines(self._saved_lines) + fh.close() + return True + + +class FakeFile(object): + """Wrap a list of lines in an object with readline() to make + ConfigParser happy.""" + def __init__(self, lines): + self._gen = (l for l in lines) + + def readline(self): + try: + return self._gen.next() + except StopIteration: + return '' diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/runner.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/runner.py new file mode 100644 index 00000000..be830ad9 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/runner.py @@ -0,0 +1,18 @@ +import sys +import os + + +def run(): + base = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + ## FIXME: this is kind of crude; if we could create a fake pip + ## module, then exec into it and update pip.__path__ properly, we + ## wouldn't have to update sys.path: + sys.path.insert(0, base) + import pip + return pip.main() + + +if __name__ == '__main__': + exit = run() + if exit: + sys.exit(exit) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/util.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/util.py new file mode 100644 index 00000000..1eab34c0 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/util.py @@ -0,0 +1,479 @@ +import sys +import shutil +import os +import stat +import re +import posixpath +import pkg_resources +import zipfile +import tarfile +from pip.exceptions import InstallationError +from pip.backwardcompat import WindowsError +from pip.locations import site_packages, running_under_virtualenv +from pip.log import logger + +__all__ = ['rmtree', 'display_path', 'backup_dir', + 'find_command', 'ask', 'Inf', + 'normalize_name', 'splitext', + 'format_size', 'is_installable_dir', + 'is_svn_page', 'file_contents', + 'split_leading_dir', 'has_leading_dir', + 'make_path_relative', 'normalize_path', + 'renames', 'get_terminal_size', + 'unzip_file', 'untar_file', 'create_download_cache_folder', + 'cache_download', 'unpack_file'] + + +def rmtree(dir): + shutil.rmtree(dir, ignore_errors=True, + onerror=rmtree_errorhandler) + + +def rmtree_errorhandler(func, path, exc_info): + """On Windows, the files in .svn are read-only, so when rmtree() tries to + remove them, an exception is thrown. We catch that here, remove the + read-only attribute, and hopefully continue without problems.""" + exctype, value = exc_info[:2] + # lookin for a windows error + if exctype is not WindowsError or 'Access is denied' not in str(value): + raise + # file type should currently be read only + if ((os.stat(path).st_mode & stat.S_IREAD) != stat.S_IREAD): + raise + # convert to read/write + os.chmod(path, stat.S_IWRITE) + # use the original function to repeat the operation + func(path) + + +def display_path(path): + """Gives the display value for a given path, making it relative to cwd + if possible.""" + path = os.path.normcase(os.path.abspath(path)) + if path.startswith(os.getcwd() + os.path.sep): + path = '.' + path[len(os.getcwd()):] + return path + + +def backup_dir(dir, ext='.bak'): + """Figure out the name of a directory to back up the given dir to + (adding .bak, .bak2, etc)""" + n = 1 + extension = ext + while os.path.exists(dir + extension): + n += 1 + extension = ext + str(n) + return dir + extension + + +def find_command(cmd, paths=None, pathext=None): + """Searches the PATH for the given command and returns its path""" + if paths is None: + paths = os.environ.get('PATH', []).split(os.pathsep) + if isinstance(paths, basestring): + paths = [paths] + # check if there are funny path extensions for executables, e.g. Windows + if pathext is None: + pathext = os.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD') + pathext = [ext for ext in pathext.lower().split(os.pathsep)] + # don't use extensions if the command ends with one of them + if os.path.splitext(cmd)[1].lower() in pathext: + pathext = [''] + # check if we find the command on PATH + for path in paths: + # try without extension first + cmd_path = os.path.join(path, cmd) + for ext in pathext: + # then including the extension + cmd_path_ext = cmd_path + ext + if os.path.exists(cmd_path_ext): + return cmd_path_ext + if os.path.exists(cmd_path): + return cmd_path + return None + + +def ask(message, options): + """Ask the message interactively, with the given possible responses""" + while 1: + if os.environ.get('PIP_NO_INPUT'): + raise Exception('No input was expected ($PIP_NO_INPUT set); question: %s' % message) + response = raw_input(message) + response = response.strip().lower() + if response not in options: + print 'Your response (%r) was not one of the expected responses: %s' % ( + response, ', '.join(options)) + else: + return response + + +class _Inf(object): + """I am bigger than everything!""" + def __cmp__(self, a): + if self is a: + return 0 + return 1 + + def __repr__(self): + return 'Inf' + +Inf = _Inf() +del _Inf + + +_normalize_re = re.compile(r'[^a-z]', re.I) + + +def normalize_name(name): + return _normalize_re.sub('-', name.lower()) + + +def format_size(bytes): + if bytes > 1000*1000: + return '%.1fMb' % (bytes/1000.0/1000) + elif bytes > 10*1000: + return '%iKb' % (bytes/1000) + elif bytes > 1000: + return '%.1fKb' % (bytes/1000.0) + else: + return '%ibytes' % bytes + + +def is_installable_dir(path): + """Return True if `path` is a directory containing a setup.py file.""" + if not os.path.isdir(path): + return False + setup_py = os.path.join(path, 'setup.py') + if os.path.isfile(setup_py): + return True + return False + + +def is_svn_page(html): + """Returns true if the page appears to be the index page of an svn repository""" + return (re.search(r'[^<]*Revision \d+:', html) + and re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I)) + + +def file_contents(filename): + fp = open(filename, 'rb') + try: + return fp.read() + finally: + fp.close() + + +def split_leading_dir(path): + path = str(path) + path = path.lstrip('/').lstrip('\\') + if '/' in path and (('\\' in path and path.find('/') < path.find('\\')) + or '\\' not in path): + return path.split('/', 1) + elif '\\' in path: + return path.split('\\', 1) + else: + return path, '' + + +def has_leading_dir(paths): + """Returns true if all the paths have the same leading path name + (i.e., everything is in one subdirectory in an archive)""" + common_prefix = None + for path in paths: + prefix, rest = split_leading_dir(path) + if not prefix: + return False + elif common_prefix is None: + common_prefix = prefix + elif prefix != common_prefix: + return False + return True + + +def make_path_relative(path, rel_to): + """ + Make a filename relative, where the filename path, and it is + relative to rel_to + + >>> make_relative_path('/usr/share/something/a-file.pth', + ... '/usr/share/another-place/src/Directory') + '../../../something/a-file.pth' + >>> make_relative_path('/usr/share/something/a-file.pth', + ... '/home/user/src/Directory') + '../../../usr/share/something/a-file.pth' + >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/') + 'a-file.pth' + """ + path_filename = os.path.basename(path) + path = os.path.dirname(path) + path = os.path.normpath(os.path.abspath(path)) + rel_to = os.path.normpath(os.path.abspath(rel_to)) + path_parts = path.strip(os.path.sep).split(os.path.sep) + rel_to_parts = rel_to.strip(os.path.sep).split(os.path.sep) + while path_parts and rel_to_parts and path_parts[0] == rel_to_parts[0]: + path_parts.pop(0) + rel_to_parts.pop(0) + full_parts = ['..']*len(rel_to_parts) + path_parts + [path_filename] + if full_parts == ['']: + return '.' + os.path.sep + return os.path.sep.join(full_parts) + + +def normalize_path(path): + """ + Convert a path to its canonical, case-normalized, absolute version. + + """ + return os.path.normcase(os.path.realpath(path)) + + +def splitext(path): + """Like os.path.splitext, but take off .tar too""" + base, ext = posixpath.splitext(path) + if base.lower().endswith('.tar'): + ext = base[-4:] + ext + base = base[:-4] + return base, ext + + +def renames(old, new): + """Like os.renames(), but handles renaming across devices.""" + # Implementation borrowed from os.renames(). + head, tail = os.path.split(new) + if head and tail and not os.path.exists(head): + os.makedirs(head) + + shutil.move(old, new) + + head, tail = os.path.split(old) + if head and tail: + try: + os.removedirs(head) + except OSError: + pass + + +def is_local(path): + """ + Return True if path is within sys.prefix, if we're running in a virtualenv. + + If we're not in a virtualenv, all paths are considered "local." + + """ + if not running_under_virtualenv(): + return True + return normalize_path(path).startswith(normalize_path(sys.prefix)) + + +def dist_is_local(dist): + """ + Return True if given Distribution object is installed locally + (i.e. within current virtualenv). + + Always True if we're not in a virtualenv. + + """ + return is_local(dist_location(dist)) + + +def get_installed_distributions(local_only=True, skip=('setuptools', 'pip', 'python')): + """ + Return a list of installed Distribution objects. + + If ``local_only`` is True (default), only return installations + local to the current virtualenv, if in a virtualenv. + + ``skip`` argument is an iterable of lower-case project names to + ignore; defaults to ('setuptools', 'pip', 'python'). [FIXME also + skip virtualenv?] + + """ + if local_only: + local_test = dist_is_local + else: + local_test = lambda d: True + return [d for d in pkg_resources.working_set if local_test(d) and d.key not in skip] + + +def egg_link_path(dist): + """ + Return the path where we'd expect to find a .egg-link file for + this distribution. (There doesn't seem to be any metadata in the + Distribution object for a develop egg that points back to its + .egg-link and easy-install.pth files). + + This won't find a globally-installed develop egg if we're in a + virtualenv. + + """ + return os.path.join(site_packages, dist.project_name) + '.egg-link' + + +def dist_location(dist): + """ + Get the site-packages location of this distribution. Generally + this is dist.location, except in the case of develop-installed + packages, where dist.location is the source code location, and we + want to know where the egg-link file is. + + """ + egg_link = egg_link_path(dist) + if os.path.exists(egg_link): + return egg_link + return dist.location + + +def get_terminal_size(): + """Returns a tuple (x, y) representing the width(x) and the height(x) + in characters of the terminal window.""" + def ioctl_GWINSZ(fd): + try: + import fcntl + import termios + import struct + cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, + '1234')) + except: + return None + if cr == (0, 0): + return None + if cr == (0, 0): + return None + return cr + cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) + if not cr: + try: + fd = os.open(os.ctermid(), os.O_RDONLY) + cr = ioctl_GWINSZ(fd) + os.close(fd) + except: + pass + if not cr: + cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) + return int(cr[1]), int(cr[0]) + + +def unzip_file(filename, location, flatten=True): + """Unzip the file (zip file located at filename) to the destination + location""" + if not os.path.exists(location): + os.makedirs(location) + zipfp = open(filename, 'rb') + try: + zip = zipfile.ZipFile(zipfp) + leading = has_leading_dir(zip.namelist()) and flatten + for name in zip.namelist(): + data = zip.read(name) + fn = name + if leading: + fn = split_leading_dir(name)[1] + fn = os.path.join(location, fn) + dir = os.path.dirname(fn) + if not os.path.exists(dir): + os.makedirs(dir) + if fn.endswith('/') or fn.endswith('\\'): + # A directory + if not os.path.exists(fn): + os.makedirs(fn) + else: + fp = open(fn, 'wb') + try: + fp.write(data) + finally: + fp.close() + finally: + zipfp.close() + + +def untar_file(filename, location): + """Untar the file (tar file located at filename) to the destination location""" + if not os.path.exists(location): + os.makedirs(location) + if filename.lower().endswith('.gz') or filename.lower().endswith('.tgz'): + mode = 'r:gz' + elif filename.lower().endswith('.bz2') or filename.lower().endswith('.tbz'): + mode = 'r:bz2' + elif filename.lower().endswith('.tar'): + mode = 'r' + else: + logger.warn('Cannot determine compression type for file %s' % filename) + mode = 'r:*' + tar = tarfile.open(filename, mode) + try: + # note: python<=2.5 doesnt seem to know about pax headers, filter them + leading = has_leading_dir([ + member.name for member in tar.getmembers() + if member.name != 'pax_global_header' + ]) + for member in tar.getmembers(): + fn = member.name + if fn == 'pax_global_header': + continue + if leading: + fn = split_leading_dir(fn)[1] + path = os.path.join(location, fn) + if member.isdir(): + if not os.path.exists(path): + os.makedirs(path) + else: + try: + fp = tar.extractfile(member) + except (KeyError, AttributeError), e: + # Some corrupt tar files seem to produce this + # (specifically bad symlinks) + logger.warn( + 'In the tar file %s the member %s is invalid: %s' + % (filename, member.name, e)) + continue + if not os.path.exists(os.path.dirname(path)): + os.makedirs(os.path.dirname(path)) + destfp = open(path, 'wb') + try: + shutil.copyfileobj(fp, destfp) + finally: + destfp.close() + fp.close() + finally: + tar.close() + + +def create_download_cache_folder(folder): + logger.indent -= 2 + logger.notify('Creating supposed download cache at %s' % folder) + logger.indent += 2 + os.makedirs(folder) + + +def cache_download(target_file, temp_location, content_type): + logger.notify('Storing download in cache at %s' % display_path(target_file)) + shutil.copyfile(temp_location, target_file) + fp = open(target_file+'.content-type', 'w') + fp.write(content_type) + fp.close() + os.unlink(temp_location) + + +def unpack_file(filename, location, content_type, link): + if (content_type == 'application/zip' + or filename.endswith('.zip') + or filename.endswith('.pybundle') + or zipfile.is_zipfile(filename)): + unzip_file(filename, location, flatten=not filename.endswith('.pybundle')) + elif (content_type == 'application/x-gzip' + or tarfile.is_tarfile(filename) + or splitext(filename)[1].lower() in ('.tar', '.tar.gz', '.tar.bz2', '.tgz', '.tbz')): + untar_file(filename, location) + elif (content_type and content_type.startswith('text/html') + and is_svn_page(file_contents(filename))): + # We don't really care about this + from pip.vcs.subversion import Subversion + Subversion('svn+' + link.url).unpack(location) + else: + ## FIXME: handle? + ## FIXME: magic signatures? + logger.fatal('Cannot unpack file %s (downloaded from %s, content-type: %s); cannot detect archive format' + % (filename, location, content_type)) + raise InstallationError('Cannot determine archive format of %s' % location) + + + diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/__init__.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/__init__.py new file mode 100644 index 00000000..e110440c --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/__init__.py @@ -0,0 +1,238 @@ +"""Handles all VCS (version control) support""" + +import os +import shutil +import urlparse +import urllib + +from pip.exceptions import BadCommand +from pip.log import logger +from pip.util import display_path, backup_dir, find_command, ask + + +__all__ = ['vcs', 'get_src_requirement', 'import_vcs_support'] + + +class VcsSupport(object): + _registry = {} + schemes = ['ssh', 'git', 'hg', 'bzr', 'sftp'] + + def __init__(self): + # Register more schemes with urlparse for various version control systems + urlparse.uses_netloc.extend(self.schemes) + urlparse.uses_fragment.extend(self.schemes) + super(VcsSupport, self).__init__() + + def __iter__(self): + return self._registry.__iter__() + + @property + def backends(self): + return self._registry.values() + + @property + def dirnames(self): + return [backend.dirname for backend in self.backends] + + @property + def all_schemes(self): + schemes = [] + for backend in self.backends: + schemes.extend(backend.schemes) + return schemes + + def register(self, cls): + if not hasattr(cls, 'name'): + logger.warn('Cannot register VCS %s' % cls.__name__) + return + if cls.name not in self._registry: + self._registry[cls.name] = cls + + def unregister(self, cls=None, name=None): + if name in self._registry: + del self._registry[name] + elif cls in self._registry.values(): + del self._registry[cls.name] + else: + logger.warn('Cannot unregister because no class or name given') + + def get_backend_name(self, location): + """ + Return the name of the version control backend if found at given + location, e.g. vcs.get_backend_name('/path/to/vcs/checkout') + """ + for vc_type in self._registry.values(): + path = os.path.join(location, vc_type.dirname) + if os.path.exists(path): + return vc_type.name + return None + + def get_backend(self, name): + name = name.lower() + if name in self._registry: + return self._registry[name] + + def get_backend_from_location(self, location): + vc_type = self.get_backend_name(location) + if vc_type: + return self.get_backend(vc_type) + return None + + +vcs = VcsSupport() + + +class VersionControl(object): + name = '' + dirname = '' + + def __init__(self, url=None, *args, **kwargs): + self.url = url + self._cmd = None + super(VersionControl, self).__init__(*args, **kwargs) + + def _filter(self, line): + return (logger.INFO, line) + + def _is_local_repository(self, repo): + """ + posix absolute paths start with os.path.sep, + win32 ones ones start with drive (like c:\\folder) + """ + drive, tail = os.path.splitdrive(repo) + return repo.startswith(os.path.sep) or drive + + @property + def cmd(self): + if self._cmd is not None: + return self._cmd + command = find_command(self.name) + if command is None: + raise BadCommand('Cannot find command %r' % self.name) + logger.info('Found command %r at %r' % (self.name, command)) + self._cmd = command + return command + + def get_url_rev(self): + """ + Returns the correct repository URL and revision by parsing the given + repository URL + """ + url = self.url.split('+', 1)[1] + scheme, netloc, path, query, frag = urlparse.urlsplit(url) + rev = None + if '@' in path: + path, rev = path.rsplit('@', 1) + url = urlparse.urlunsplit((scheme, netloc, path, query, '')) + return url, rev + + def get_info(self, location): + """ + Returns (url, revision), where both are strings + """ + assert not location.rstrip('/').endswith(self.dirname), 'Bad directory: %s' % location + return self.get_url(location), self.get_revision(location) + + def normalize_url(self, url): + """ + Normalize a URL for comparison by unquoting it and removing any trailing slash. + """ + return urllib.unquote(url).rstrip('/') + + def compare_urls(self, url1, url2): + """ + Compare two repo URLs for identity, ignoring incidental differences. + """ + return (self.normalize_url(url1) == self.normalize_url(url2)) + + def parse_vcs_bundle_file(self, content): + """ + Takes the contents of the bundled text file that explains how to revert + the stripped off version control data of the given package and returns + the URL and revision of it. + """ + raise NotImplementedError + + def obtain(self, dest): + """ + Called when installing or updating an editable package, takes the + source path of the checkout. + """ + raise NotImplementedError + + def switch(self, dest, url, rev_options): + """ + Switch the repo at ``dest`` to point to ``URL``. + """ + raise NotImplemented + + def update(self, dest, rev_options): + """ + Update an already-existing repo to the given ``rev_options``. + """ + raise NotImplementedError + + def check_destination(self, dest, url, rev_options, rev_display): + """ + Prepare a location to receive a checkout/clone. + + Return True if the location is ready for (and requires) a + checkout/clone, False otherwise. + """ + checkout = True + prompt = False + if os.path.exists(dest): + checkout = False + if os.path.exists(os.path.join(dest, self.dirname)): + existing_url = self.get_url(dest) + if self.compare_urls(existing_url, url): + logger.info('%s in %s exists, and has correct URL (%s)' + % (self.repo_name.title(), display_path(dest), url)) + logger.notify('Updating %s %s%s' + % (display_path(dest), self.repo_name, rev_display)) + self.update(dest, rev_options) + else: + logger.warn('%s %s in %s exists with URL %s' + % (self.name, self.repo_name, display_path(dest), existing_url)) + prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', ('s', 'i', 'w', 'b')) + else: + logger.warn('Directory %s already exists, and is not a %s %s.' + % (dest, self.name, self.repo_name)) + prompt = ('(i)gnore, (w)ipe, (b)ackup ', ('i', 'w', 'b')) + if prompt: + logger.warn('The plan is to install the %s repository %s' + % (self.name, url)) + response = ask('What to do? %s' % prompt[0], prompt[1]) + + if response == 's': + logger.notify('Switching %s %s to %s%s' + % (self.repo_name, display_path(dest), url, rev_display)) + self.switch(dest, url, rev_options) + elif response == 'i': + # do nothing + pass + elif response == 'w': + logger.warn('Deleting %s' % display_path(dest)) + shutil.rmtree(dest) + checkout = True + elif response == 'b': + dest_dir = backup_dir(dest) + logger.warn('Backing up %s to %s' + % (display_path(dest), dest_dir)) + shutil.move(dest, dest_dir) + checkout = True + return checkout + + def unpack(self, location): + raise NotImplementedError + + def get_src_requirement(self, dist, location, find_tags=False): + raise NotImplementedError + + +def get_src_requirement(dist, location, find_tags): + version_control = vcs.get_backend_from_location(location) + if version_control: + return version_control().get_src_requirement(dist, location, find_tags) + logger.warn('cannot determine version of editable source in %s (is not SVN checkout, Git clone, Mercurial clone or Bazaar branch)' % location) + return dist.as_requirement() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/bazaar.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/bazaar.py new file mode 100644 index 00000000..3b6ea8f0 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/bazaar.py @@ -0,0 +1,138 @@ +import os +import shutil +import tempfile +import re +from pip import call_subprocess +from pip.log import logger +from pip.util import rmtree, display_path +from pip.vcs import vcs, VersionControl +from pip.download import path_to_url2 + + +class Bazaar(VersionControl): + name = 'bzr' + dirname = '.bzr' + repo_name = 'branch' + bundle_file = 'bzr-branch.txt' + schemes = ('bzr', 'bzr+http', 'bzr+https', 'bzr+ssh', 'bzr+sftp', 'bzr+ftp') + guide = ('# This was a Bazaar branch; to make it a branch again run:\n' + 'bzr branch -r %(rev)s %(url)s .\n') + + def parse_vcs_bundle_file(self, content): + url = rev = None + for line in content.splitlines(): + if not line.strip() or line.strip().startswith('#'): + continue + match = re.search(r'^bzr\s*branch\s*-r\s*(\d*)', line) + if match: + rev = match.group(1).strip() + url = line[match.end():].strip().split(None, 1)[0] + if url and rev: + return url, rev + return None, None + + def unpack(self, location): + """Get the bzr branch at the url to the destination location""" + url, rev = self.get_url_rev() + logger.notify('Checking out bzr repository %s to %s' % (url, location)) + logger.indent += 2 + try: + if os.path.exists(location): + os.rmdir(location) + call_subprocess( + [self.cmd, 'branch', url, location], + filter_stdout=self._filter, show_stdout=False) + finally: + logger.indent -= 2 + + def export(self, location): + """Export the Bazaar repository at the url to the destination location""" + temp_dir = tempfile.mkdtemp('-export', 'pip-') + self.unpack(temp_dir) + if os.path.exists(location): + # Remove the location to make sure Bazaar can export it correctly + rmtree(location) + try: + call_subprocess([self.cmd, 'export', location], cwd=temp_dir, + filter_stdout=self._filter, show_stdout=False) + finally: + shutil.rmtree(temp_dir) + + def switch(self, dest, url, rev_options): + call_subprocess([self.cmd, 'switch', url], cwd=dest) + + def update(self, dest, rev_options): + call_subprocess( + [self.cmd, 'pull', '-q'] + rev_options, cwd=dest) + + def obtain(self, dest): + url, rev = self.get_url_rev() + if rev: + rev_options = ['-r', rev] + rev_display = ' (to revision %s)' % rev + else: + rev_options = [] + rev_display = '' + if self.check_destination(dest, url, rev_options, rev_display): + logger.notify('Checking out %s%s to %s' + % (url, rev_display, display_path(dest))) + call_subprocess( + [self.cmd, 'branch', '-q'] + rev_options + [url, dest]) + + def get_url_rev(self): + # hotfix the URL scheme after removing bzr+ from bzr+ssh:// readd it + url, rev = super(Bazaar, self).get_url_rev() + if url.startswith('ssh://'): + url = 'bzr+' + url + return url, rev + + def get_url(self, location): + urls = call_subprocess( + [self.cmd, 'info'], show_stdout=False, cwd=location) + for line in urls.splitlines(): + line = line.strip() + for x in ('checkout of branch: ', + 'parent branch: '): + if line.startswith(x): + repo = line.split(x)[1] + if self._is_local_repository(repo): + return path_to_url2(repo) + return repo + return None + + def get_revision(self, location): + revision = call_subprocess( + [self.cmd, 'revno'], show_stdout=False, cwd=location) + return revision.splitlines()[-1] + + def get_tag_revs(self, location): + tags = call_subprocess( + [self.cmd, 'tags'], show_stdout=False, cwd=location) + tag_revs = [] + for line in tags.splitlines(): + tags_match = re.search(r'([.\w-]+)\s*(.*)$', line) + if tags_match: + tag = tags_match.group(1) + rev = tags_match.group(2) + tag_revs.append((rev.strip(), tag.strip())) + return dict(tag_revs) + + def get_src_requirement(self, dist, location, find_tags): + repo = self.get_url(location) + if not repo.lower().startswith('bzr:'): + repo = 'bzr+' + repo + egg_project_name = dist.egg_name().split('-', 1)[0] + if not repo: + return None + current_rev = self.get_revision(location) + tag_revs = self.get_tag_revs(location) + + if current_rev in tag_revs: + # It's a tag + full_egg_name = '%s-%s' % (egg_project_name, tag_revs[current_rev]) + else: + full_egg_name = '%s-dev_r%s' % (dist.egg_name(), current_rev) + return '%s@%s#egg=%s' % (repo, current_rev, full_egg_name) + + +vcs.register(Bazaar) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/git.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/git.py new file mode 100644 index 00000000..0701e49e --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/git.py @@ -0,0 +1,204 @@ +import os +import shutil +import tempfile +import re +from pip import call_subprocess +from pip.util import display_path +from pip.vcs import vcs, VersionControl +from pip.log import logger +from urllib import url2pathname +from urlparse import urlsplit, urlunsplit + + +class Git(VersionControl): + name = 'git' + dirname = '.git' + repo_name = 'clone' + schemes = ('git', 'git+http', 'git+ssh', 'git+git', 'git+file') + bundle_file = 'git-clone.txt' + guide = ('# This was a Git repo; to make it a repo again run:\n' + 'git init\ngit remote add origin %(url)s -f\ngit checkout %(rev)s\n') + + def __init__(self, url=None, *args, **kwargs): + + # Works around an apparent Git bug + # (see http://article.gmane.org/gmane.comp.version-control.git/146500) + if url: + scheme, netloc, path, query, fragment = urlsplit(url) + if scheme.endswith('file'): + initial_slashes = path[:-len(path.lstrip('/'))] + newpath = initial_slashes + url2pathname(path).replace('\\', '/').lstrip('/') + url = urlunsplit((scheme, netloc, newpath, query, fragment)) + after_plus = scheme.find('+')+1 + url = scheme[:after_plus]+ urlunsplit((scheme[after_plus:], netloc, newpath, query, fragment)) + + super(Git, self).__init__(url, *args, **kwargs) + + def parse_vcs_bundle_file(self, content): + url = rev = None + for line in content.splitlines(): + if not line.strip() or line.strip().startswith('#'): + continue + url_match = re.search(r'git\s*remote\s*add\s*origin(.*)\s*-f', line) + if url_match: + url = url_match.group(1).strip() + rev_match = re.search(r'^git\s*checkout\s*-q\s*(.*)\s*', line) + if rev_match: + rev = rev_match.group(1).strip() + if url and rev: + return url, rev + return None, None + + def unpack(self, location): + """Clone the Git repository at the url to the destination location""" + url, rev = self.get_url_rev() + logger.notify('Cloning Git repository %s to %s' % (url, location)) + logger.indent += 2 + try: + if os.path.exists(location): + os.rmdir(location) + call_subprocess( + [self.cmd, 'clone', url, location], + filter_stdout=self._filter, show_stdout=False) + finally: + logger.indent -= 2 + + def export(self, location): + """Export the Git repository at the url to the destination location""" + temp_dir = tempfile.mkdtemp('-export', 'pip-') + self.unpack(temp_dir) + try: + if not location.endswith('/'): + location = location + '/' + call_subprocess( + [self.cmd, 'checkout-index', '-a', '-f', '--prefix', location], + filter_stdout=self._filter, show_stdout=False, cwd=temp_dir) + finally: + shutil.rmtree(temp_dir) + + def check_rev_options(self, rev, dest, rev_options): + """Check the revision options before checkout to compensate that tags + and branches may need origin/ as a prefix. + Returns the SHA1 of the branch or tag if found. + """ + revisions = self.get_tag_revs(dest) + revisions.update(self.get_branch_revs(dest)) + inverse_revisions = dict((v, k) for k, v in revisions.iteritems()) + # Check if rev is a branch name + origin_rev = 'origin/%s' % rev + if origin_rev in inverse_revisions: + return [inverse_revisions[origin_rev]] + elif rev in inverse_revisions: + return [inverse_revisions[rev]] + else: + logger.warn("Could not find a tag or branch '%s', assuming commit." % rev) + return rev_options + + def switch(self, dest, url, rev_options): + call_subprocess( + [self.cmd, 'config', 'remote.origin.url', url], cwd=dest) + call_subprocess( + [self.cmd, 'checkout', '-q'] + rev_options, cwd=dest) + + def update(self, dest, rev_options): + call_subprocess([self.cmd, 'pull', '-q'], cwd=dest) + call_subprocess( + [self.cmd, 'checkout', '-q', '-f'] + rev_options, cwd=dest) + + def obtain(self, dest): + url, rev = self.get_url_rev() + if rev: + rev_options = [rev] + rev_display = ' (to %s)' % rev + else: + rev_options = ['master'] + rev_display = '' + if self.check_destination(dest, url, rev_options, rev_display): + logger.notify('Cloning %s%s to %s' % (url, rev_display, display_path(dest))) + call_subprocess([self.cmd, 'clone', '-q', url, dest]) + if rev: + rev_options = self.check_rev_options(rev, dest, rev_options) + # Only do a checkout if rev_options differs from HEAD + if not self.get_revision(dest).startswith(rev_options[0]): + call_subprocess([self.cmd, 'checkout', '-q'] + rev_options, cwd=dest) + + def get_url(self, location): + url = call_subprocess( + [self.cmd, 'config', 'remote.origin.url'], + show_stdout=False, cwd=location) + return url.strip() + + def get_revision(self, location): + current_rev = call_subprocess( + [self.cmd, 'rev-parse', 'HEAD'], show_stdout=False, cwd=location) + return current_rev.strip() + + def get_tag_revs(self, location): + tags = call_subprocess( + [self.cmd, 'tag', '-l'], + show_stdout=False, raise_on_returncode=False, cwd=location) + tag_revs = [] + for line in tags.splitlines(): + tag = line.strip() + rev = call_subprocess( + [self.cmd, 'rev-parse', tag], show_stdout=False, cwd=location) + tag_revs.append((rev.strip(), tag)) + tag_revs = dict(tag_revs) + return tag_revs + + def get_branch_revs(self, location): + branches = call_subprocess( + [self.cmd, 'branch', '-r'], show_stdout=False, cwd=location) + branch_revs = [] + for line in branches.splitlines(): + line = line.split('->')[0].strip() + branch = "".join([b for b in line.split() if b != '*']) + rev = call_subprocess( + [self.cmd, 'rev-parse', branch], show_stdout=False, cwd=location) + branch_revs.append((rev.strip(), branch)) + branch_revs = dict(branch_revs) + return branch_revs + + def get_src_requirement(self, dist, location, find_tags): + repo = self.get_url(location) + if not repo.lower().startswith('git:'): + repo = 'git+' + repo + egg_project_name = dist.egg_name().split('-', 1)[0] + if not repo: + return None + current_rev = self.get_revision(location) + tag_revs = self.get_tag_revs(location) + branch_revs = self.get_branch_revs(location) + + if current_rev in tag_revs: + # It's a tag + full_egg_name = '%s-%s' % (egg_project_name, tag_revs[current_rev]) + elif (current_rev in branch_revs and + branch_revs[current_rev] != 'origin/master'): + # It's the head of a branch + full_egg_name = '%s-%s' % (dist.egg_name(), + branch_revs[current_rev].replace('origin/', '')) + else: + full_egg_name = '%s-dev' % dist.egg_name() + + return '%s@%s#egg=%s' % (repo, current_rev, full_egg_name) + + def get_url_rev(self): + """ + Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. + That's required because although they use SSH they sometimes doesn't + work with a ssh:// scheme (e.g. Github). But we need a scheme for + parsing. Hence we remove it again afterwards and return it as a stub. + """ + if not '://' in self.url: + assert not 'file:' in self.url + self.url = self.url.replace('git+', 'git+ssh://') + url, rev = super(Git, self).get_url_rev() + url = url.replace('ssh://', '') + else: + url, rev = super(Git, self).get_url_rev() + + return url, rev + + +vcs.register(Git) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/mercurial.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/mercurial.py new file mode 100644 index 00000000..70c8c833 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/mercurial.py @@ -0,0 +1,162 @@ +import os +import shutil +import tempfile +import re +import ConfigParser +from pip import call_subprocess +from pip.util import display_path +from pip.log import logger +from pip.vcs import vcs, VersionControl +from pip.download import path_to_url2 + + +class Mercurial(VersionControl): + name = 'hg' + dirname = '.hg' + repo_name = 'clone' + schemes = ('hg', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http') + bundle_file = 'hg-clone.txt' + guide = ('# This was a Mercurial repo; to make it a repo again run:\n' + 'hg init\nhg pull %(url)s\nhg update -r %(rev)s\n') + + def parse_vcs_bundle_file(self, content): + url = rev = None + for line in content.splitlines(): + if not line.strip() or line.strip().startswith('#'): + continue + url_match = re.search(r'hg\s*pull\s*(.*)\s*', line) + if url_match: + url = url_match.group(1).strip() + rev_match = re.search(r'^hg\s*update\s*-r\s*(.*)\s*', line) + if rev_match: + rev = rev_match.group(1).strip() + if url and rev: + return url, rev + return None, None + + def unpack(self, location): + """Clone the Hg repository at the url to the destination location""" + url, rev = self.get_url_rev() + logger.notify('Cloning Mercurial repository %s to %s' % (url, location)) + logger.indent += 2 + try: + if os.path.exists(location): + os.rmdir(location) + call_subprocess( + [self.cmd, 'clone', url, location], + filter_stdout=self._filter, show_stdout=False) + finally: + logger.indent -= 2 + + def export(self, location): + """Export the Hg repository at the url to the destination location""" + temp_dir = tempfile.mkdtemp('-export', 'pip-') + self.unpack(temp_dir) + try: + call_subprocess( + [self.cmd, 'archive', location], + filter_stdout=self._filter, show_stdout=False, cwd=temp_dir) + finally: + shutil.rmtree(temp_dir) + + def switch(self, dest, url, rev_options): + repo_config = os.path.join(dest, self.dirname, 'hgrc') + config = ConfigParser.SafeConfigParser() + try: + config.read(repo_config) + config.set('paths', 'default', url) + config_file = open(repo_config, 'w') + config.write(config_file) + config_file.close() + except (OSError, ConfigParser.NoSectionError), e: + logger.warn( + 'Could not switch Mercurial repository to %s: %s' + % (url, e)) + else: + call_subprocess([self.cmd, 'update', '-q'] + rev_options, cwd=dest) + + def update(self, dest, rev_options): + call_subprocess([self.cmd, 'pull', '-q'], cwd=dest) + call_subprocess( + [self.cmd, 'update', '-q'] + rev_options, cwd=dest) + + def obtain(self, dest): + url, rev = self.get_url_rev() + if rev: + rev_options = [rev] + rev_display = ' (to revision %s)' % rev + else: + rev_options = [] + rev_display = '' + if self.check_destination(dest, url, rev_options, rev_display): + logger.notify('Cloning hg %s%s to %s' + % (url, rev_display, display_path(dest))) + call_subprocess([self.cmd, 'clone', '--noupdate', '-q', url, dest]) + call_subprocess([self.cmd, 'update', '-q'] + rev_options, cwd=dest) + + def get_url(self, location): + url = call_subprocess( + [self.cmd, 'showconfig', 'paths.default'], + show_stdout=False, cwd=location).strip() + if self._is_local_repository(url): + url = path_to_url2(url) + return url.strip() + + def get_tag_revs(self, location): + tags = call_subprocess( + [self.cmd, 'tags'], show_stdout=False, cwd=location) + tag_revs = [] + for line in tags.splitlines(): + tags_match = re.search(r'([\w\d\.-]+)\s*([\d]+):.*$', line) + if tags_match: + tag = tags_match.group(1) + rev = tags_match.group(2) + tag_revs.append((rev.strip(), tag.strip())) + return dict(tag_revs) + + def get_branch_revs(self, location): + branches = call_subprocess( + [self.cmd, 'branches'], show_stdout=False, cwd=location) + branch_revs = [] + for line in branches.splitlines(): + branches_match = re.search(r'([\w\d\.-]+)\s*([\d]+):.*$', line) + if branches_match: + branch = branches_match.group(1) + rev = branches_match.group(2) + branch_revs.append((rev.strip(), branch.strip())) + return dict(branch_revs) + + def get_revision(self, location): + current_revision = call_subprocess( + [self.cmd, 'parents', '--template={rev}'], + show_stdout=False, cwd=location).strip() + return current_revision + + def get_revision_hash(self, location): + current_rev_hash = call_subprocess( + [self.cmd, 'parents', '--template={node}'], + show_stdout=False, cwd=location).strip() + return current_rev_hash + + def get_src_requirement(self, dist, location, find_tags): + repo = self.get_url(location) + if not repo.lower().startswith('hg:'): + repo = 'hg+' + repo + egg_project_name = dist.egg_name().split('-', 1)[0] + if not repo: + return None + current_rev = self.get_revision(location) + current_rev_hash = self.get_revision_hash(location) + tag_revs = self.get_tag_revs(location) + branch_revs = self.get_branch_revs(location) + if current_rev in tag_revs: + # It's a tag + full_egg_name = '%s-%s' % (egg_project_name, tag_revs[current_rev]) + elif current_rev in branch_revs: + # It's the tip of a branch + full_egg_name = '%s-%s' % (dist.egg_name(), branch_revs[current_rev]) + else: + full_egg_name = '%s-dev' % dist.egg_name() + return '%s@%s#egg=%s' % (repo, current_rev_hash, full_egg_name) + +vcs.register(Mercurial) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/subversion.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/subversion.py new file mode 100644 index 00000000..85715d97 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/subversion.py @@ -0,0 +1,260 @@ +import os +import re +from pip import call_subprocess +from pip.index import Link +from pip.util import rmtree, display_path +from pip.log import logger +from pip.vcs import vcs, VersionControl + +_svn_xml_url_re = re.compile('url="([^"]+)"') +_svn_rev_re = re.compile('committed-rev="(\d+)"') +_svn_url_re = re.compile(r'URL: (.+)') +_svn_revision_re = re.compile(r'Revision: (.+)') + + +class Subversion(VersionControl): + name = 'svn' + dirname = '.svn' + repo_name = 'checkout' + schemes = ('svn', 'svn+ssh', 'svn+http', 'svn+https') + bundle_file = 'svn-checkout.txt' + guide = ('# This was an svn checkout; to make it a checkout again run:\n' + 'svn checkout --force -r %(rev)s %(url)s .\n') + + def get_info(self, location): + """Returns (url, revision), where both are strings""" + assert not location.rstrip('/').endswith(self.dirname), 'Bad directory: %s' % location + output = call_subprocess( + [self.cmd, 'info', location], show_stdout=False, extra_environ={'LANG': 'C'}) + match = _svn_url_re.search(output) + if not match: + logger.warn('Cannot determine URL of svn checkout %s' % display_path(location)) + logger.info('Output that cannot be parsed: \n%s' % output) + return None, None + url = match.group(1).strip() + match = _svn_revision_re.search(output) + if not match: + logger.warn('Cannot determine revision of svn checkout %s' % display_path(location)) + logger.info('Output that cannot be parsed: \n%s' % output) + return url, None + return url, match.group(1) + + def parse_vcs_bundle_file(self, content): + for line in content.splitlines(): + if not line.strip() or line.strip().startswith('#'): + continue + match = re.search(r'^-r\s*([^ ])?', line) + if not match: + return None, None + rev = match.group(1) + rest = line[match.end():].strip().split(None, 1)[0] + return rest, rev + return None, None + + def unpack(self, location): + """Check out the svn repository at the url to the destination location""" + url, rev = self.get_url_rev() + logger.notify('Checking out svn repository %s to %s' % (url, location)) + logger.indent += 2 + try: + if os.path.exists(location): + # Subversion doesn't like to check out over an existing directory + # --force fixes this, but was only added in svn 1.5 + rmtree(location) + call_subprocess( + [self.cmd, 'checkout', url, location], + filter_stdout=self._filter, show_stdout=False) + finally: + logger.indent -= 2 + + def export(self, location): + """Export the svn repository at the url to the destination location""" + url, rev = self.get_url_rev() + logger.notify('Exporting svn repository %s to %s' % (url, location)) + logger.indent += 2 + try: + if os.path.exists(location): + # Subversion doesn't like to check out over an existing directory + # --force fixes this, but was only added in svn 1.5 + rmtree(location) + call_subprocess( + [self.cmd, 'export', url, location], + filter_stdout=self._filter, show_stdout=False) + finally: + logger.indent -= 2 + + def switch(self, dest, url, rev_options): + call_subprocess( + [self.cmd, 'switch'] + rev_options + [url, dest]) + + def update(self, dest, rev_options): + call_subprocess( + [self.cmd, 'update'] + rev_options + [dest]) + + def obtain(self, dest): + url, rev = self.get_url_rev() + if rev: + rev_options = ['-r', rev] + rev_display = ' (to revision %s)' % rev + else: + rev_options = [] + rev_display = '' + if self.check_destination(dest, url, rev_options, rev_display): + logger.notify('Checking out %s%s to %s' + % (url, rev_display, display_path(dest))) + call_subprocess( + [self.cmd, 'checkout', '-q'] + rev_options + [url, dest]) + + def get_location(self, dist, dependency_links): + for url in dependency_links: + egg_fragment = Link(url).egg_fragment + if not egg_fragment: + continue + if '-' in egg_fragment: + ## FIXME: will this work when a package has - in the name? + key = '-'.join(egg_fragment.split('-')[:-1]).lower() + else: + key = egg_fragment + if key == dist.key: + return url.split('#', 1)[0] + return None + + def get_revision(self, location): + """ + Return the maximum revision for all files under a given location + """ + # Note: taken from setuptools.command.egg_info + revision = 0 + + for base, dirs, files in os.walk(location): + if self.dirname not in dirs: + dirs[:] = [] + continue # no sense walking uncontrolled subdirs + dirs.remove(self.dirname) + entries_fn = os.path.join(base, self.dirname, 'entries') + if not os.path.exists(entries_fn): + ## FIXME: should we warn? + continue + f = open(entries_fn) + data = f.read() + f.close() + + if data.startswith('8') or data.startswith('9') or data.startswith('10'): + data = map(str.splitlines, data.split('\n\x0c\n')) + del data[0][0] # get rid of the '8' + dirurl = data[0][3] + revs = [int(d[9]) for d in data if len(d)>9 and d[9]]+[0] + if revs: + localrev = max(revs) + else: + localrev = 0 + elif data.startswith('<?xml'): + dirurl = _svn_xml_url_re.search(data).group(1) # get repository URL + revs = [int(m.group(1)) for m in _svn_rev_re.finditer(data)]+[0] + if revs: + localrev = max(revs) + else: + localrev = 0 + else: + logger.warn("Unrecognized .svn/entries format; skipping %s", base) + dirs[:] = [] + continue + if base == location: + base_url = dirurl+'/' # save the root url + elif not dirurl.startswith(base_url): + dirs[:] = [] + continue # not part of the same svn tree, skip it + revision = max(revision, localrev) + return revision + + def get_url_rev(self): + # hotfix the URL scheme after removing svn+ from svn+ssh:// readd it + url, rev = super(Subversion, self).get_url_rev() + if url.startswith('ssh://'): + url = 'svn+' + url + return url, rev + + def get_url(self, location): + # In cases where the source is in a subdirectory, not alongside setup.py + # we have to look up in the location until we find a real setup.py + orig_location = location + while not os.path.exists(os.path.join(location, 'setup.py')): + last_location = location + location = os.path.dirname(location) + if location == last_location: + # We've traversed up to the root of the filesystem without finding setup.py + logger.warn("Could not find setup.py for directory %s (tried all parent directories)" + % orig_location) + return None + f = open(os.path.join(location, self.dirname, 'entries')) + data = f.read() + f.close() + if data.startswith('8') or data.startswith('9') or data.startswith('10'): + data = map(str.splitlines, data.split('\n\x0c\n')) + del data[0][0] # get rid of the '8' + return data[0][3] + elif data.startswith('<?xml'): + match = _svn_xml_url_re.search(data) + if not match: + raise ValueError('Badly formatted data: %r' % data) + return match.group(1) # get repository URL + else: + logger.warn("Unrecognized .svn/entries format in %s" % location) + # Or raise exception? + return None + + def get_tag_revs(self, svn_tag_url): + stdout = call_subprocess( + [self.cmd, 'ls', '-v', svn_tag_url], show_stdout=False) + results = [] + for line in stdout.splitlines(): + parts = line.split() + rev = int(parts[0]) + tag = parts[-1].strip('/') + results.append((tag, rev)) + return results + + def find_tag_match(self, rev, tag_revs): + best_match_rev = None + best_tag = None + for tag, tag_rev in tag_revs: + if (tag_rev > rev and + (best_match_rev is None or best_match_rev > tag_rev)): + # FIXME: Is best_match > tag_rev really possible? + # or is it a sign something is wacky? + best_match_rev = tag_rev + best_tag = tag + return best_tag + + def get_src_requirement(self, dist, location, find_tags=False): + repo = self.get_url(location) + if repo is None: + return None + parts = repo.split('/') + ## FIXME: why not project name? + egg_project_name = dist.egg_name().split('-', 1)[0] + rev = self.get_revision(location) + if parts[-2] in ('tags', 'tag'): + # It's a tag, perfect! + full_egg_name = '%s-%s' % (egg_project_name, parts[-1]) + elif parts[-2] in ('branches', 'branch'): + # It's a branch :( + full_egg_name = '%s-%s-r%s' % (dist.egg_name(), parts[-1], rev) + elif parts[-1] == 'trunk': + # Trunk :-/ + full_egg_name = '%s-dev_r%s' % (dist.egg_name(), rev) + if find_tags: + tag_url = '/'.join(parts[:-1]) + '/tags' + tag_revs = self.get_tag_revs(tag_url) + match = self.find_tag_match(rev, tag_revs) + if match: + logger.notify('trunk checkout %s seems to be equivalent to tag %s' % match) + repo = '%s/%s' % (tag_url, match) + full_egg_name = '%s-%s' % (egg_project_name, match) + else: + # Don't know what it is + logger.warn('svn URL does not fit normal structure (tags/branches/trunk): %s' % repo) + full_egg_name = '%s-dev_r%s' % (egg_project_name, rev) + return 'svn+%s@%s#egg=%s' % (repo, rev, full_egg_name) + +vcs.register(Subversion) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/venv.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/venv.py new file mode 100644 index 00000000..708abb05 --- /dev/null +++ b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/venv.py @@ -0,0 +1,53 @@ +"""Tools for working with virtualenv environments""" + +import os +import sys +import subprocess +from pip.exceptions import BadCommand +from pip.log import logger + + +def restart_in_venv(venv, base, site_packages, args): + """ + Restart this script using the interpreter in the given virtual environment + """ + if base and not os.path.isabs(venv) and not venv.startswith('~'): + base = os.path.expanduser(base) + # ensure we have an abs basepath at this point: + # a relative one makes no sense (or does it?) + if os.path.isabs(base): + venv = os.path.join(base, venv) + + if venv.startswith('~'): + venv = os.path.expanduser(venv) + + if not os.path.exists(venv): + try: + import virtualenv + except ImportError: + print 'The virtual environment does not exist: %s' % venv + print 'and virtualenv is not installed, so a new environment cannot be created' + sys.exit(3) + print 'Creating new virtualenv environment in %s' % venv + virtualenv.logger = logger + logger.indent += 2 + virtualenv.create_environment(venv, site_packages=site_packages) + if sys.platform == 'win32': + python = os.path.join(venv, 'Scripts', 'python.exe') + # check for bin directory which is used in buildouts + if not os.path.exists(python): + python = os.path.join(venv, 'bin', 'python.exe') + else: + python = os.path.join(venv, 'bin', 'python') + if not os.path.exists(python): + python = venv + if not os.path.exists(python): + raise BadCommand('Cannot find virtual environment interpreter at %s' % python) + base = os.path.dirname(os.path.dirname(python)) + file = os.path.join(os.path.dirname(__file__), 'runner.py') + if file.endswith('.pyc'): + file = file[:-1] + proc = subprocess.Popen( + [python, file] + args + [base, '___VENV_RESTART___']) + proc.wait() + sys.exit(proc.returncode) diff --git a/test/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg b/test/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg new file mode 100644 index 0000000000000000000000000000000000000000..3c72d15b5b10eba024ecbb3395507a5ede16de72 GIT binary patch literal 333447 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%0ACVmDdmdD-+s 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 JR*Bmc(Mj*h-TEe?gKs87Apsg`& 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�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 z∋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 literal 0 HcmV?d00001 diff --git a/test/lib/python2.6/site-packages/setuptools.pth b/test/lib/python2.6/site-packages/setuptools.pth new file mode 100644 index 00000000..bf760205 --- /dev/null +++ b/test/lib/python2.6/site-packages/setuptools.pth @@ -0,0 +1 @@ +./setuptools-0.6c11-py2.6.egg diff --git a/test/lib/python2.6/site.py b/test/lib/python2.6/site.py new file mode 100644 index 00000000..a49cfc34 --- /dev/null +++ b/test/lib/python2.6/site.py @@ -0,0 +1,713 @@ +"""Append module search paths for third-party packages to sys.path. + +**************************************************************** +* This module is automatically imported during initialization. * +**************************************************************** + +In earlier versions of Python (up to 1.5a3), scripts or modules that +needed to use site-specific modules would place ``import site'' +somewhere near the top of their code. Because of the automatic +import, this is no longer necessary (but code that does it still +works). + +This will append site-specific paths to the module search path. On +Unix, it starts with sys.prefix and sys.exec_prefix (if different) and +appends lib/python<version>/site-packages as well as lib/site-python. +It also supports the Debian convention of +lib/python<version>/dist-packages. On other platforms (mainly Mac and +Windows), it uses just sys.prefix (and sys.exec_prefix, if different, +but this is unlikely). The resulting directories, if they exist, are +appended to sys.path, and also inspected for path configuration files. + +FOR DEBIAN, this sys.path is augmented with directories in /usr/local. +Local addons go into /usr/local/lib/python<version>/site-packages +(resp. /usr/local/lib/site-python), Debian addons install into +/usr/{lib,share}/python<version>/dist-packages. + +A path configuration file is a file whose name has the form +<package>.pth; its contents are additional directories (one per line) +to be added to sys.path. Non-existing directories (or +non-directories) are never added to sys.path; no directory is added to +sys.path more than once. Blank lines and lines beginning with +'#' are skipped. Lines starting with 'import' are executed. + +For example, suppose sys.prefix and sys.exec_prefix are set to +/usr/local and there is a directory /usr/local/lib/python2.X/site-packages +with three subdirectories, foo, bar and spam, and two path +configuration files, foo.pth and bar.pth. Assume foo.pth contains the +following: + + # foo package configuration + foo + bar + bletch + +and bar.pth contains: + + # bar package configuration + bar + +Then the following directories are added to sys.path, in this order: + + /usr/local/lib/python2.X/site-packages/bar + /usr/local/lib/python2.X/site-packages/foo + +Note that bletch is omitted because it doesn't exist; bar precedes foo +because bar.pth comes alphabetically before foo.pth; and spam is +omitted because it is not mentioned in either path configuration file. + +After these path manipulations, an attempt is made to import a module +named sitecustomize, which can perform arbitrary additional +site-specific customizations. If this import fails with an +ImportError exception, it is silently ignored. + +""" + +import sys +import os +import __builtin__ +try: + set +except NameError: + from sets import Set as set + +# Prefixes for site-packages; add additional prefixes like /usr/local here +PREFIXES = [sys.prefix, sys.exec_prefix] +# Enable per user site-packages directory +# set it to False to disable the feature or True to force the feature +ENABLE_USER_SITE = None +# for distutils.commands.install +USER_SITE = None +USER_BASE = None + +_is_pypy = hasattr(sys, 'pypy_version_info') +_is_jython = sys.platform[:4] == 'java' +if _is_jython: + ModuleType = type(os) + +def makepath(*paths): + dir = os.path.join(*paths) + if _is_jython and (dir == '__classpath__' or + dir.startswith('__pyclasspath__')): + return dir, dir + dir = os.path.abspath(dir) + return dir, os.path.normcase(dir) + +def abs__file__(): + """Set all module' __file__ attribute to an absolute path""" + for m in sys.modules.values(): + if ((_is_jython and not isinstance(m, ModuleType)) or + hasattr(m, '__loader__')): + # only modules need the abspath in Jython. and don't mess + # with a PEP 302-supplied __file__ + continue + f = getattr(m, '__file__', None) + if f is None: + continue + m.__file__ = os.path.abspath(f) + +def removeduppaths(): + """ Remove duplicate entries from sys.path along with making them + absolute""" + # This ensures that the initial path provided by the interpreter contains + # only absolute pathnames, even if we're running from the build directory. + L = [] + known_paths = set() + for dir in sys.path: + # Filter out duplicate paths (on case-insensitive file systems also + # if they only differ in case); turn relative paths into absolute + # paths. + dir, dircase = makepath(dir) + if not dircase in known_paths: + L.append(dir) + known_paths.add(dircase) + sys.path[:] = L + return known_paths + +# XXX This should not be part of site.py, since it is needed even when +# using the -S option for Python. See http://www.python.org/sf/586680 +def addbuilddir(): + """Append ./build/lib.<platform> in case we're running in the build dir + (especially for Guido :-)""" + from distutils.util import get_platform + s = "build/lib.%s-%.3s" % (get_platform(), sys.version) + if hasattr(sys, 'gettotalrefcount'): + s += '-pydebug' + s = os.path.join(os.path.dirname(sys.path[-1]), s) + sys.path.append(s) + +def _init_pathinfo(): + """Return a set containing all existing directory entries from sys.path""" + d = set() + for dir in sys.path: + try: + if os.path.isdir(dir): + dir, dircase = makepath(dir) + d.add(dircase) + except TypeError: + continue + return d + +def addpackage(sitedir, name, known_paths): + """Add a new path to known_paths by combining sitedir and 'name' or execute + sitedir if it starts with 'import'""" + if known_paths is None: + _init_pathinfo() + reset = 1 + else: + reset = 0 + fullname = os.path.join(sitedir, name) + try: + f = open(fullname, "rU") + except IOError: + return + try: + for line in f: + if line.startswith("#"): + continue + if line.startswith("import"): + exec line + continue + line = line.rstrip() + dir, dircase = makepath(sitedir, line) + if not dircase in known_paths and os.path.exists(dir): + sys.path.append(dir) + known_paths.add(dircase) + finally: + f.close() + if reset: + known_paths = None + return known_paths + +def addsitedir(sitedir, known_paths=None): + """Add 'sitedir' argument to sys.path if missing and handle .pth files in + 'sitedir'""" + if known_paths is None: + known_paths = _init_pathinfo() + reset = 1 + else: + reset = 0 + sitedir, sitedircase = makepath(sitedir) + if not sitedircase in known_paths: + sys.path.append(sitedir) # Add path component + try: + names = os.listdir(sitedir) + except os.error: + return + names.sort() + for name in names: + if name.endswith(os.extsep + "pth"): + addpackage(sitedir, name, known_paths) + if reset: + known_paths = None + return known_paths + +def addsitepackages(known_paths, sys_prefix=sys.prefix, exec_prefix=sys.exec_prefix): + """Add site-packages (and possibly site-python) to sys.path""" + prefixes = [os.path.join(sys_prefix, "local"), sys_prefix] + if exec_prefix != sys_prefix: + prefixes.append(os.path.join(exec_prefix, "local")) + + for prefix in prefixes: + if prefix: + if sys.platform in ('os2emx', 'riscos') or _is_jython: + sitedirs = [os.path.join(prefix, "Lib", "site-packages")] + elif _is_pypy: + sitedirs = [os.path.join(prefix, 'site-packages')] + elif sys.platform == 'darwin' and prefix == sys_prefix: + + if prefix.startswith("/System/Library/Frameworks/"): # Apple's Python + + sitedirs = [os.path.join("/Library/Python", sys.version[:3], "site-packages"), + os.path.join(prefix, "Extras", "lib", "python")] + + else: # any other Python distros on OSX work this way + sitedirs = [os.path.join(prefix, "lib", + "python" + sys.version[:3], "site-packages")] + + elif os.sep == '/': + sitedirs = [os.path.join(prefix, + "lib", + "python" + sys.version[:3], + "site-packages"), + os.path.join(prefix, "lib", "site-python"), + os.path.join(prefix, "python" + sys.version[:3], "lib-dynload")] + lib64_dir = os.path.join(prefix, "lib64", "python" + sys.version[:3], "site-packages") + if (os.path.exists(lib64_dir) and + os.path.realpath(lib64_dir) not in [os.path.realpath(p) for p in sitedirs]): + sitedirs.append(lib64_dir) + try: + # sys.getobjects only available in --with-pydebug build + sys.getobjects + sitedirs.insert(0, os.path.join(sitedirs[0], 'debug')) + except AttributeError: + pass + # Debian-specific dist-packages directories: + sitedirs.append(os.path.join(prefix, "lib", + "python" + sys.version[:3], + "dist-packages")) + sitedirs.append(os.path.join(prefix, "local/lib", + "python" + sys.version[:3], + "dist-packages")) + sitedirs.append(os.path.join(prefix, "lib", "dist-python")) + else: + sitedirs = [prefix, os.path.join(prefix, "lib", "site-packages")] + if sys.platform == 'darwin': + # for framework builds *only* we add the standard Apple + # locations. Currently only per-user, but /Library and + # /Network/Library could be added too + if 'Python.framework' in prefix: + home = os.environ.get('HOME') + if home: + sitedirs.append( + os.path.join(home, + 'Library', + 'Python', + sys.version[:3], + 'site-packages')) + for sitedir in sitedirs: + if os.path.isdir(sitedir): + addsitedir(sitedir, known_paths) + return None + +def check_enableusersite(): + """Check if user site directory is safe for inclusion + + The function tests for the command line flag (including environment var), + process uid/gid equal to effective uid/gid. + + None: Disabled for security reasons + False: Disabled by user (command line option) + True: Safe and enabled + """ + if hasattr(sys, 'flags') and getattr(sys.flags, 'no_user_site', False): + return False + + if hasattr(os, "getuid") and hasattr(os, "geteuid"): + # check process uid == effective uid + if os.geteuid() != os.getuid(): + return None + if hasattr(os, "getgid") and hasattr(os, "getegid"): + # check process gid == effective gid + if os.getegid() != os.getgid(): + return None + + return True + +def addusersitepackages(known_paths): + """Add a per user site-package to sys.path + + Each user has its own python directory with site-packages in the + home directory. + + USER_BASE is the root directory for all Python versions + + USER_SITE is the user specific site-packages directory + + USER_SITE/.. can be used for data. + """ + global USER_BASE, USER_SITE, ENABLE_USER_SITE + env_base = os.environ.get("PYTHONUSERBASE", None) + + def joinuser(*args): + return os.path.expanduser(os.path.join(*args)) + + #if sys.platform in ('os2emx', 'riscos'): + # # Don't know what to put here + # USER_BASE = '' + # USER_SITE = '' + if os.name == "nt": + base = os.environ.get("APPDATA") or "~" + if env_base: + USER_BASE = env_base + else: + USER_BASE = joinuser(base, "Python") + USER_SITE = os.path.join(USER_BASE, + "Python" + sys.version[0] + sys.version[2], + "site-packages") + else: + if env_base: + USER_BASE = env_base + else: + USER_BASE = joinuser("~", ".local") + USER_SITE = os.path.join(USER_BASE, "lib", + "python" + sys.version[:3], + "site-packages") + + if ENABLE_USER_SITE and os.path.isdir(USER_SITE): + addsitedir(USER_SITE, known_paths) + if ENABLE_USER_SITE: + for dist_libdir in ("lib", "local/lib"): + user_site = os.path.join(USER_BASE, dist_libdir, + "python" + sys.version[:3], + "dist-packages") + if os.path.isdir(user_site): + addsitedir(user_site, known_paths) + return known_paths + + + +def setBEGINLIBPATH(): + """The OS/2 EMX port has optional extension modules that do double duty + as DLLs (and must use the .DLL file extension) for other extensions. + The library search path needs to be amended so these will be found + during module import. Use BEGINLIBPATH so that these are at the start + of the library search path. + + """ + dllpath = os.path.join(sys.prefix, "Lib", "lib-dynload") + libpath = os.environ['BEGINLIBPATH'].split(';') + if libpath[-1]: + libpath.append(dllpath) + else: + libpath[-1] = dllpath + os.environ['BEGINLIBPATH'] = ';'.join(libpath) + + +def setquit(): + """Define new built-ins 'quit' and 'exit'. + These are simply strings that display a hint on how to exit. + + """ + if os.sep == ':': + eof = 'Cmd-Q' + elif os.sep == '\\': + eof = 'Ctrl-Z plus Return' + else: + eof = 'Ctrl-D (i.e. EOF)' + + class Quitter(object): + def __init__(self, name): + self.name = name + def __repr__(self): + return 'Use %s() or %s to exit' % (self.name, eof) + def __call__(self, code=None): + # Shells like IDLE catch the SystemExit, but listen when their + # stdin wrapper is closed. + try: + sys.stdin.close() + except: + pass + raise SystemExit(code) + __builtin__.quit = Quitter('quit') + __builtin__.exit = Quitter('exit') + + +class _Printer(object): + """interactive prompt objects for printing the license text, a list of + contributors and the copyright notice.""" + + MAXLINES = 23 + + def __init__(self, name, data, files=(), dirs=()): + self.__name = name + self.__data = data + self.__files = files + self.__dirs = dirs + self.__lines = None + + def __setup(self): + if self.__lines: + return + data = None + for dir in self.__dirs: + for filename in self.__files: + filename = os.path.join(dir, filename) + try: + fp = file(filename, "rU") + data = fp.read() + fp.close() + break + except IOError: + pass + if data: + break + if not data: + data = self.__data + self.__lines = data.split('\n') + self.__linecnt = len(self.__lines) + + def __repr__(self): + self.__setup() + if len(self.__lines) <= self.MAXLINES: + return "\n".join(self.__lines) + else: + return "Type %s() to see the full %s text" % ((self.__name,)*2) + + def __call__(self): + self.__setup() + prompt = 'Hit Return for more, or q (and Return) to quit: ' + lineno = 0 + while 1: + try: + for i in range(lineno, lineno + self.MAXLINES): + print self.__lines[i] + except IndexError: + break + else: + lineno += self.MAXLINES + key = None + while key is None: + key = raw_input(prompt) + if key not in ('', 'q'): + key = None + if key == 'q': + break + +def setcopyright(): + """Set 'copyright' and 'credits' in __builtin__""" + __builtin__.copyright = _Printer("copyright", sys.copyright) + if _is_jython: + __builtin__.credits = _Printer( + "credits", + "Jython is maintained by the Jython developers (www.jython.org).") + elif _is_pypy: + __builtin__.credits = _Printer( + "credits", + "PyPy is maintained by the PyPy developers: http://codespeak.net/pypy") + else: + __builtin__.credits = _Printer("credits", """\ + Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information.""") + here = os.path.dirname(os.__file__) + __builtin__.license = _Printer( + "license", "See http://www.python.org/%.3s/license.html" % sys.version, + ["LICENSE.txt", "LICENSE"], + [os.path.join(here, os.pardir), here, os.curdir]) + + +class _Helper(object): + """Define the built-in 'help'. + This is a wrapper around pydoc.help (with a twist). + + """ + + def __repr__(self): + return "Type help() for interactive help, " \ + "or help(object) for help about object." + def __call__(self, *args, **kwds): + import pydoc + return pydoc.help(*args, **kwds) + +def sethelper(): + __builtin__.help = _Helper() + +def aliasmbcs(): + """On Windows, some default encodings are not provided by Python, + while they are always available as "mbcs" in each locale. Make + them usable by aliasing to "mbcs" in such a case.""" + if sys.platform == 'win32': + import locale, codecs + enc = locale.getdefaultlocale()[1] + if enc.startswith('cp'): # "cp***" ? + try: + codecs.lookup(enc) + except LookupError: + import encodings + encodings._cache[enc] = encodings._unknown + encodings.aliases.aliases[enc] = 'mbcs' + +def setencoding(): + """Set the string encoding used by the Unicode implementation. The + default is 'ascii', but if you're willing to experiment, you can + change this.""" + encoding = "ascii" # Default value set by _PyUnicode_Init() + if 0: + # Enable to support locale aware default string encodings. + import locale + loc = locale.getdefaultlocale() + if loc[1]: + encoding = loc[1] + if 0: + # Enable to switch off string to Unicode coercion and implicit + # Unicode to string conversion. + encoding = "undefined" + if encoding != "ascii": + # On Non-Unicode builds this will raise an AttributeError... + sys.setdefaultencoding(encoding) # Needs Python Unicode build ! + + +def execsitecustomize(): + """Run custom site specific code, if available.""" + try: + import sitecustomize + except ImportError: + pass + +def virtual_install_main_packages(): + f = open(os.path.join(os.path.dirname(__file__), 'orig-prefix.txt')) + sys.real_prefix = f.read().strip() + f.close() + pos = 2 + if sys.path[0] == '': + pos += 1 + if sys.platform == 'win32': + paths = [os.path.join(sys.real_prefix, 'Lib'), os.path.join(sys.real_prefix, 'DLLs')] + elif _is_jython: + paths = [os.path.join(sys.real_prefix, 'Lib')] + elif _is_pypy: + cpyver = '%d.%d.%d' % sys.version_info[:3] + paths = [os.path.join(sys.real_prefix, 'lib_pypy'), + os.path.join(sys.real_prefix, 'lib-python', 'modified-%s' % cpyver), + os.path.join(sys.real_prefix, 'lib-python', cpyver)] + else: + paths = [os.path.join(sys.real_prefix, 'lib', 'python'+sys.version[:3])] + lib64_path = os.path.join(sys.real_prefix, 'lib64', 'python'+sys.version[:3]) + if os.path.exists(lib64_path): + paths.append(lib64_path) + # This is hardcoded in the Python executable, but relative to sys.prefix: + plat_path = os.path.join(sys.real_prefix, 'lib', 'python'+sys.version[:3], + 'plat-%s' % sys.platform) + if os.path.exists(plat_path): + paths.append(plat_path) + # This is hardcoded in the Python executable, but + # relative to sys.prefix, so we have to fix up: + for path in list(paths): + tk_dir = os.path.join(path, 'lib-tk') + if os.path.exists(tk_dir): + paths.append(tk_dir) + + # These are hardcoded in the Apple's Python executable, + # but relative to sys.prefix, so we have to fix them up: + if sys.platform == 'darwin': + hardcoded_paths = [os.path.join(sys.real_prefix, 'lib', 'python'+sys.version[:3], module) + for module in ('plat-darwin', 'plat-mac', 'plat-mac/lib-scriptpackages')] + + for path in hardcoded_paths: + if os.path.exists(path): + paths.append(path) + + sys.path.extend(paths) + +def force_global_eggs_after_local_site_packages(): + """ + Force easy_installed eggs in the global environment to get placed + in sys.path after all packages inside the virtualenv. This + maintains the "least surprise" result that packages in the + virtualenv always mask global packages, never the other way + around. + + """ + egginsert = getattr(sys, '__egginsert', 0) + for i, path in enumerate(sys.path): + if i > egginsert and path.startswith(sys.prefix): + egginsert = i + sys.__egginsert = egginsert + 1 + +def virtual_addsitepackages(known_paths): + force_global_eggs_after_local_site_packages() + return addsitepackages(known_paths, sys_prefix=sys.real_prefix) + +def fixclasspath(): + """Adjust the special classpath sys.path entries for Jython. These + entries should follow the base virtualenv lib directories. + """ + paths = [] + classpaths = [] + for path in sys.path: + if path == '__classpath__' or path.startswith('__pyclasspath__'): + classpaths.append(path) + else: + paths.append(path) + sys.path = paths + sys.path.extend(classpaths) + +def execusercustomize(): + """Run custom user specific code, if available.""" + try: + import usercustomize + except ImportError: + pass + + +def main(): + global ENABLE_USER_SITE + virtual_install_main_packages() + abs__file__() + paths_in_sys = removeduppaths() + if (os.name == "posix" and sys.path and + os.path.basename(sys.path[-1]) == "Modules"): + addbuilddir() + if _is_jython: + fixclasspath() + GLOBAL_SITE_PACKAGES = not os.path.exists(os.path.join(os.path.dirname(__file__), 'no-global-site-packages.txt')) + if not GLOBAL_SITE_PACKAGES: + ENABLE_USER_SITE = False + if ENABLE_USER_SITE is None: + ENABLE_USER_SITE = check_enableusersite() + paths_in_sys = addsitepackages(paths_in_sys) + paths_in_sys = addusersitepackages(paths_in_sys) + if GLOBAL_SITE_PACKAGES: + paths_in_sys = virtual_addsitepackages(paths_in_sys) + if sys.platform == 'os2emx': + setBEGINLIBPATH() + setquit() + setcopyright() + sethelper() + aliasmbcs() + setencoding() + execsitecustomize() + if ENABLE_USER_SITE: + execusercustomize() + # Remove sys.setdefaultencoding() so that users cannot change the + # encoding after initialization. The test for presence is needed when + # this module is run as a script, because this code is executed twice. + if hasattr(sys, "setdefaultencoding"): + del sys.setdefaultencoding + +main() + +def _script(): + help = """\ + %s [--user-base] [--user-site] + + Without arguments print some useful information + With arguments print the value of USER_BASE and/or USER_SITE separated + by '%s'. + + Exit codes with --user-base or --user-site: + 0 - user site directory is enabled + 1 - user site directory is disabled by user + 2 - uses site directory is disabled by super user + or for security reasons + >2 - unknown error + """ + args = sys.argv[1:] + if not args: + print "sys.path = [" + for dir in sys.path: + print " %r," % (dir,) + print "]" + def exists(path): + if os.path.isdir(path): + return "exists" + else: + return "doesn't exist" + print "USER_BASE: %r (%s)" % (USER_BASE, exists(USER_BASE)) + print "USER_SITE: %r (%s)" % (USER_SITE, exists(USER_BASE)) + print "ENABLE_USER_SITE: %r" % ENABLE_USER_SITE + sys.exit(0) + + buffer = [] + if '--user-base' in args: + buffer.append(USER_BASE) + if '--user-site' in args: + buffer.append(USER_SITE) + + if buffer: + print os.pathsep.join(buffer) + if ENABLE_USER_SITE: + sys.exit(0) + elif ENABLE_USER_SITE is False: + sys.exit(1) + elif ENABLE_USER_SITE is None: + sys.exit(2) + else: + sys.exit(3) + else: + import textwrap + print textwrap.dedent(help % (sys.argv[0], os.pathsep)) + sys.exit(10) + +if __name__ == '__main__': + _script() diff --git a/test/lib/python2.6/sre.py b/test/lib/python2.6/sre.py new file mode 120000 index 00000000..3ade4e80 --- /dev/null +++ b/test/lib/python2.6/sre.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/sre.py \ No newline at end of file diff --git a/test/lib/python2.6/sre_compile.py b/test/lib/python2.6/sre_compile.py new file mode 120000 index 00000000..fc13a37d --- /dev/null +++ b/test/lib/python2.6/sre_compile.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/sre_compile.py \ No newline at end of file diff --git a/test/lib/python2.6/sre_constants.py b/test/lib/python2.6/sre_constants.py new file mode 120000 index 00000000..98b0d554 --- /dev/null +++ b/test/lib/python2.6/sre_constants.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/sre_constants.py \ No newline at end of file diff --git a/test/lib/python2.6/sre_parse.py b/test/lib/python2.6/sre_parse.py new file mode 120000 index 00000000..76b24c68 --- /dev/null +++ b/test/lib/python2.6/sre_parse.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/sre_parse.py \ No newline at end of file diff --git a/test/lib/python2.6/stat.py b/test/lib/python2.6/stat.py new file mode 120000 index 00000000..68d61e66 --- /dev/null +++ b/test/lib/python2.6/stat.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/stat.py \ No newline at end of file diff --git a/test/lib/python2.6/types.py b/test/lib/python2.6/types.py new file mode 120000 index 00000000..72b00ba3 --- /dev/null +++ b/test/lib/python2.6/types.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/types.py \ No newline at end of file diff --git a/test/lib/python2.6/warnings.py b/test/lib/python2.6/warnings.py new file mode 120000 index 00000000..1af4e283 --- /dev/null +++ b/test/lib/python2.6/warnings.py @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/warnings.py \ No newline at end of file From 5982659d1aa88bdfb39b7c283acb0d64a431ba65 Mon Sep 17 00:00:00 2001 From: Anne Gentle <anne@openstack.org> Date: Mon, 21 Feb 2011 14:35:30 -0600 Subject: [PATCH 063/111] Removing pesky DS_Store files too. Begone. --- .bzrignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.bzrignore b/.bzrignore index b271561a..d22b6262 100644 --- a/.bzrignore +++ b/.bzrignore @@ -13,3 +13,4 @@ CA/serial* CA/newcerts/*.pem CA/private/cakey.pem nova/vcsversion.py +*.DS_Store From 46ac21b783b799ffe975de3463fbf790f837dabe Mon Sep 17 00:00:00 2001 From: Ken Pepple <ken.pepple@gmail.com> Date: Mon, 21 Feb 2011 12:41:15 -0800 Subject: [PATCH 064/111] make sure that ec2 response times are xs:dateTime parsable --- nova/tests/test_api.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/nova/tests/test_api.py b/nova/tests/test_api.py index fa27825c..d5c54a1c 100644 --- a/nova/tests/test_api.py +++ b/nova/tests/test_api.py @@ -20,6 +20,7 @@ import boto from boto.ec2 import regioninfo +import datetime import httplib import random import StringIO @@ -127,6 +128,28 @@ class ApiEc2TestCase(test.TestCase): self.ec2.new_http_connection(host, is_secure).AndReturn(self.http) return self.http + def test_return_valid_isoformat(self): + """ + Ensure that the ec2 api returns datetime in xs:dateTime + (which apparently isn't datetime.isoformat()) + NOTE(ken-pepple): https://bugs.launchpad.net/nova/+bug/721297 + """ + conv = apirequest._database_to_isoformat + # sqlite database representation with microseconds + time_to_convert = datetime.datetime.strptime( + "2011-02-21 20:14:10.634276", + "%Y-%m-%d %H:%M:%S.%f") + self.assertEqual( + conv(time_to_convert), + '2011-02-21T20:14:10Z') + # mysqlite database representation + time_to_convert = datetime.datetime.strptime( + "2011-02-21 19:56:18", + "%Y-%m-%d %H:%M:%S") + self.assertEqual( + conv(time_to_convert), + '2011-02-21T19:56:18Z') + def test_xmlns_version_matches_request_version(self): self.expect_http(api_version='2010-10-30') self.mox.ReplayAll() From 832cb02195d025a47c0ea9bea5d9b0845c6a5cda Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Mon, 21 Feb 2011 13:46:41 -0800 Subject: [PATCH 065/111] switch to explicit call to logging.setup() --- bin/nova-ajax-console-proxy | 2 +- bin/nova-api | 2 +- bin/nova-combined | 1 + bin/nova-compute | 5 ++++ bin/nova-console | 4 +++ bin/nova-dhcpbridge | 3 +- bin/nova-direct-api | 2 ++ bin/nova-import-canonical-imagestore | 2 ++ bin/nova-instancemonitor | 3 -- bin/nova-manage | 2 ++ bin/nova-network | 4 +++ bin/nova-scheduler | 4 +++ bin/nova-volume | 4 +++ nova/log.py | 44 ++++++++++++++++------------ nova/twistd.py | 1 + run_tests.py | 2 ++ 16 files changed, 60 insertions(+), 25 deletions(-) diff --git a/bin/nova-ajax-console-proxy b/bin/nova-ajax-console-proxy index 2bc40765..392b328b 100755 --- a/bin/nova-ajax-console-proxy +++ b/bin/nova-ajax-console-proxy @@ -25,7 +25,6 @@ from eventlet.green import urllib2 import exceptions import gettext -import logging import os import sys import time @@ -130,6 +129,7 @@ class AjaxConsoleProxy(object): if __name__ == '__main__': utils.default_flagfile() FLAGS(sys.argv) + logging.setup() server = wsgi.Server() acp = AjaxConsoleProxy() acp.register_listeners() diff --git a/bin/nova-api b/bin/nova-api index 5937f774..61a4c740 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -40,7 +40,6 @@ from nova import version from nova import wsgi LOG = logging.getLogger('nova.api') -LOG.setLevel(logging.DEBUG) FLAGS = flags.FLAGS @@ -80,6 +79,7 @@ def run_app(paste_config_file): if __name__ == '__main__': FLAGS(sys.argv) + logging.setup() LOG.audit(_("Starting nova-api node (version %s)"), version.version_string_with_vcs()) conf = wsgi.paste_config_file('nova-api.conf') diff --git a/bin/nova-combined b/bin/nova-combined index 5911d901..6ae8400d 100755 --- a/bin/nova-combined +++ b/bin/nova-combined @@ -49,6 +49,7 @@ FLAGS = flags.FLAGS if __name__ == '__main__': utils.default_flagfile() FLAGS(sys.argv) + logging.setup() compute = service.Service.create(binary='nova-compute') network = service.Service.create(binary='nova-network') diff --git a/bin/nova-compute b/bin/nova-compute index d2d352da..e412598c 100755 --- a/bin/nova-compute +++ b/bin/nova-compute @@ -36,10 +36,15 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): gettext.install('nova', unicode=1) +from nova import flags +from nova import log as logging from nova import service from nova import utils if __name__ == '__main__': utils.default_flagfile() + flags.FLAGS(sys.argv) + logging.setup() + service.serve() service.wait() diff --git a/bin/nova-console b/bin/nova-console index 802cc80b..40608b99 100755 --- a/bin/nova-console +++ b/bin/nova-console @@ -35,10 +35,14 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): gettext.install('nova', unicode=1) +from nova import flags +from nova import log as logging from nova import service from nova import utils if __name__ == '__main__': utils.default_flagfile() + flags.FLAGS(sys.argv) + logging.setup() service.serve() service.wait() diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge index e0e6af82..eda2dc07 100755 --- a/bin/nova-dhcpbridge +++ b/bin/nova-dhcpbridge @@ -102,6 +102,7 @@ def main(): flagfile = os.environ.get('FLAGFILE', FLAGS.dhcpbridge_flagfile) utils.default_flagfile(flagfile) argv = FLAGS(sys.argv) + logging.setup() interface = os.environ.get('DNSMASQ_INTERFACE', 'br0') if int(os.environ.get('TESTING', '0')): FLAGS.fake_rabbit = True @@ -112,7 +113,7 @@ def main(): FLAGS.num_networks = 5 path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', - 'nova.sqlite')) + 'tests.sqlite')) FLAGS.sql_connection = 'sqlite:///%s' % path action = argv[1] if action in ['add', 'del', 'old']: diff --git a/bin/nova-direct-api b/bin/nova-direct-api index 173b39bd..6c63bd26 100755 --- a/bin/nova-direct-api +++ b/bin/nova-direct-api @@ -35,6 +35,7 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): gettext.install('nova', unicode=1) from nova import flags +from nova import log as logging from nova import utils from nova import wsgi from nova.api import direct @@ -48,6 +49,7 @@ flags.DEFINE_string('direct_host', '0.0.0.0', 'Direct API host') if __name__ == '__main__': utils.default_flagfile() FLAGS(sys.argv) + logging.setup() direct.register_service('compute', compute_api.API()) direct.register_service('reflect', direct.Reflection()) diff --git a/bin/nova-import-canonical-imagestore b/bin/nova-import-canonical-imagestore index 036b41e4..404ae37f 100755 --- a/bin/nova-import-canonical-imagestore +++ b/bin/nova-import-canonical-imagestore @@ -41,6 +41,7 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): gettext.install('nova', unicode=1) from nova import flags +from nova import log as logging from nova import utils from nova.objectstore import image @@ -92,6 +93,7 @@ def main(): """Main entry point.""" utils.default_flagfile() argv = FLAGS(sys.argv) + logging.setup() images = get_images() if len(argv) == 2: diff --git a/bin/nova-instancemonitor b/bin/nova-instancemonitor index 7dca0201..24cc9fd2 100755 --- a/bin/nova-instancemonitor +++ b/bin/nova-instancemonitor @@ -41,9 +41,6 @@ from nova import utils from nova import twistd from nova.compute import monitor -# TODO(todd): shouldn't this be done with flags? And what about verbose? -logging.getLogger('boto').setLevel(logging.WARN) - LOG = logging.getLogger('nova.instancemonitor') diff --git a/bin/nova-manage b/bin/nova-manage index 86179871..5189de0e 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -77,6 +77,7 @@ from nova import crypto from nova import db from nova import exception from nova import flags +from nova import log as logging from nova import quota from nova import rpc from nova import utils @@ -707,6 +708,7 @@ def main(): """Parse options and call the appropriate class/method.""" utils.default_flagfile() argv = FLAGS(sys.argv) + logging.setup() script_name = argv.pop(0) if len(argv) < 1: diff --git a/bin/nova-network b/bin/nova-network index 0143846a..101761ef 100755 --- a/bin/nova-network +++ b/bin/nova-network @@ -36,10 +36,14 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): gettext.install('nova', unicode=1) +from nova import flags +from nova import log as logging from nova import service from nova import utils if __name__ == '__main__': utils.default_flagfile() + flags.FLAGS(sys.argv) + logging.setup() service.serve() service.wait() diff --git a/bin/nova-scheduler b/bin/nova-scheduler index f4c0eaed..0c205a80 100755 --- a/bin/nova-scheduler +++ b/bin/nova-scheduler @@ -36,10 +36,14 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): gettext.install('nova', unicode=1) +from nova import flags +from nova import log as logging from nova import service from nova import utils if __name__ == '__main__': utils.default_flagfile() + flags.FLAGS(sys.argv) + logging.setup() service.serve() service.wait() diff --git a/bin/nova-volume b/bin/nova-volume index ad3ddc40..8dcdbc50 100755 --- a/bin/nova-volume +++ b/bin/nova-volume @@ -36,10 +36,14 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): gettext.install('nova', unicode=1) +from nova import flags +from nova import log as logging from nova import service from nova import utils if __name__ == '__main__': utils.default_flagfile() + flags.FLAGS(sys.argv) + logging.setup() service.serve() service.wait() diff --git a/nova/log.py b/nova/log.py index 3a48c97f..10c14d74 100644 --- a/nova/log.py +++ b/nova/log.py @@ -65,6 +65,7 @@ flags.DEFINE_string('logging_exception_prefix', flags.DEFINE_list('default_log_levels', ['amqplib=WARN', 'sqlalchemy=WARN', + 'boto=WARN', 'eventlet.wsgi.server=WARN'], 'list of logger=LEVEL pairs') @@ -263,26 +264,8 @@ class NovaRootLogger(NovaLogger): self.setLevel(INFO) -if not isinstance(logging.root, NovaRootLogger): - logging._acquireLock() - for handler in logging.root.handlers: - logging.root.removeHandler(handler) - logging.root = NovaRootLogger("nova") - for logger in NovaLogger.manager.loggerDict.itervalues(): - logger.root = logging.root - NovaLogger.root = logging.root - NovaLogger.manager.root = logging.root - NovaLogger.manager.loggerDict["nova"] = logging.root - logging._releaseLock() -root = logging.root - - def handle_exception(type, value, tb): - root.critical(str(value), exc_info=(type, value, tb)) - - -sys.excepthook = handle_exception -logging.setLoggerClass(NovaLogger) + logging.root.critical(str(value), exc_info=(type, value, tb)) def reset(): @@ -292,6 +275,29 @@ def reset(): logger.setup_from_flags() +def setup(): + """Setup nova logging.""" + if not isinstance(logging.root, NovaRootLogger): + logging._acquireLock() + for handler in logging.root.handlers: + logging.root.removeHandler(handler) + logging.root = NovaRootLogger("nova") + NovaLogger.root = logging.root + NovaLogger.manager.root = logging.root + for logger in NovaLogger.manager.loggerDict.itervalues(): + logger.root = logging.root + if isinstance(logger, logging.Logger): + NovaLogger.manager._fixupParents(logger) + NovaLogger.manager.loggerDict["nova"] = logging.root + logging._releaseLock() + sys.excepthook = handle_exception + reset() + + +root = logging.root +logging.setLoggerClass(NovaLogger) + + def audit(msg, *args, **kwargs): """Shortcut for logging to root log with sevrity 'AUDIT'.""" logging.root.log(AUDIT, msg, *args, **kwargs) diff --git a/nova/twistd.py b/nova/twistd.py index 0e4db022..c07ed991 100644 --- a/nova/twistd.py +++ b/nova/twistd.py @@ -148,6 +148,7 @@ def WrapTwistedOptions(wrapped): options.insert(0, '') args = FLAGS(options) + logging.setup() argv = args[1:] # ignore subcommands diff --git a/run_tests.py b/run_tests.py index 274dc4a9..82345433 100644 --- a/run_tests.py +++ b/run_tests.py @@ -26,6 +26,7 @@ from nose import config from nose import result from nose import core +from nova import log as logging class NovaTestResult(result.TextTestResult): def __init__(self, *args, **kw): @@ -60,6 +61,7 @@ class NovaTestRunner(core.TextTestRunner): if __name__ == '__main__': if os.path.exists("tests.sqlite"): os.unlink("tests.sqlite") + logging.setup() c = config.Config(stream=sys.stdout, env=os.environ, verbosity=3, From 890a11039fc7b9dd002f532e610098067164a9d8 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Mon, 21 Feb 2011 13:59:46 -0800 Subject: [PATCH 066/111] fix pep8 and remove extra reference to reset --- bin/nova-compute | 1 - nova/flags.py | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/bin/nova-compute b/bin/nova-compute index e412598c..95fa393b 100755 --- a/bin/nova-compute +++ b/bin/nova-compute @@ -45,6 +45,5 @@ if __name__ == '__main__': utils.default_flagfile() flags.FLAGS(sys.argv) logging.setup() - service.serve() service.wait() diff --git a/nova/flags.py b/nova/flags.py index e2f7960e..f64a62da 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -29,6 +29,7 @@ import sys import gflags + class FlagValues(gflags.FlagValues): """Extension of gflags.FlagValues that allows undefined and runtime flags. @@ -89,8 +90,6 @@ class FlagValues(gflags.FlagValues): self.__dict__['__stored_argv'] = original_argv self.__dict__['__was_already_parsed'] = True self.ClearDirty() - from nova import log as logging - logging.reset() return args def Reset(self): From d3c206001acbcb1c2cf0a4efdd5da6723a6b475b Mon Sep 17 00:00:00 2001 From: termie <github@anarkystic.com> Date: Mon, 21 Feb 2011 14:55:06 -0800 Subject: [PATCH 067/111] add a start_service method to our test baseclass --- nova/tests/test_scheduler.py | 100 ++++++----------------------------- 1 file changed, 16 insertions(+), 84 deletions(-) diff --git a/nova/tests/test_scheduler.py b/nova/tests/test_scheduler.py index 9d458244..25017007 100644 --- a/nova/tests/test_scheduler.py +++ b/nova/tests/test_scheduler.py @@ -176,18 +176,8 @@ class SimpleDriverTestCase(test.TestCase): def test_doesnt_report_disabled_hosts_as_up(self): """Ensures driver doesn't find hosts before they are enabled""" - # NOTE(vish): constructing service without create method - # because we are going to use it without queue - compute1 = service.Service('host1', - 'nova-compute', - 'compute', - FLAGS.compute_manager) - compute1.start() - compute2 = service.Service('host2', - 'nova-compute', - 'compute', - FLAGS.compute_manager) - compute2.start() + compute1 = self.start_service('compute', host='host1') + compute2 = self.start_service('compute', host='host2') s1 = db.service_get_by_args(self.context, 'host1', 'nova-compute') s2 = db.service_get_by_args(self.context, 'host2', 'nova-compute') db.service_update(self.context, s1['id'], {'disabled': True}) @@ -199,18 +189,8 @@ class SimpleDriverTestCase(test.TestCase): def test_reports_enabled_hosts_as_up(self): """Ensures driver can find the hosts that are up""" - # NOTE(vish): constructing service without create method - # because we are going to use it without queue - compute1 = service.Service('host1', - 'nova-compute', - 'compute', - FLAGS.compute_manager) - compute1.start() - compute2 = service.Service('host2', - 'nova-compute', - 'compute', - FLAGS.compute_manager) - compute2.start() + compute1 = self.start_service('compute', host='host1') + compute2 = self.start_service('compute', host='host2') hosts = self.scheduler.driver.hosts_up(self.context, 'compute') self.assertEqual(2, len(hosts)) compute1.kill() @@ -218,16 +198,8 @@ class SimpleDriverTestCase(test.TestCase): def test_least_busy_host_gets_instance(self): """Ensures the host with less cores gets the next one""" - compute1 = service.Service('host1', - 'nova-compute', - 'compute', - FLAGS.compute_manager) - compute1.start() - compute2 = service.Service('host2', - 'nova-compute', - 'compute', - FLAGS.compute_manager) - compute2.start() + compute1 = self.start_service('compute', host='host1') + compute2 = self.start_service('compute', host='host2') instance_id1 = self._create_instance() compute1.run_instance(self.context, instance_id1) instance_id2 = self._create_instance() @@ -241,16 +213,8 @@ class SimpleDriverTestCase(test.TestCase): def test_specific_host_gets_instance(self): """Ensures if you set availability_zone it launches on that zone""" - compute1 = service.Service('host1', - 'nova-compute', - 'compute', - FLAGS.compute_manager) - compute1.start() - compute2 = service.Service('host2', - 'nova-compute', - 'compute', - FLAGS.compute_manager) - compute2.start() + compute1 = self.start_service('compute', host='host1') + compute2 = self.start_service('compute', host='host2') instance_id1 = self._create_instance() compute1.run_instance(self.context, instance_id1) instance_id2 = self._create_instance(availability_zone='nova:host1') @@ -263,11 +227,7 @@ class SimpleDriverTestCase(test.TestCase): compute2.kill() def test_wont_sechedule_if_specified_host_is_down(self): - compute1 = service.Service('host1', - 'nova-compute', - 'compute', - FLAGS.compute_manager) - compute1.start() + compute1 = self.start_service('compute', host='host1') s1 = db.service_get_by_args(self.context, 'host1', 'nova-compute') now = datetime.datetime.utcnow() delta = datetime.timedelta(seconds=FLAGS.service_down_time * 2) @@ -282,11 +242,7 @@ class SimpleDriverTestCase(test.TestCase): compute1.kill() def test_will_schedule_on_disabled_host_if_specified(self): - compute1 = service.Service('host1', - 'nova-compute', - 'compute', - FLAGS.compute_manager) - compute1.start() + compute1 = self.start_service('compute', host='host1') s1 = db.service_get_by_args(self.context, 'host1', 'nova-compute') db.service_update(self.context, s1['id'], {'disabled': True}) instance_id2 = self._create_instance(availability_zone='nova:host1') @@ -298,16 +254,8 @@ class SimpleDriverTestCase(test.TestCase): def test_too_many_cores(self): """Ensures we don't go over max cores""" - compute1 = service.Service('host1', - 'nova-compute', - 'compute', - FLAGS.compute_manager) - compute1.start() - compute2 = service.Service('host2', - 'nova-compute', - 'compute', - FLAGS.compute_manager) - compute2.start() + compute1 = self.start_service('compute', host='host1') + compute2 = self.start_service('compute', host='host2') instance_ids1 = [] instance_ids2 = [] for index in xrange(FLAGS.max_cores): @@ -331,16 +279,8 @@ class SimpleDriverTestCase(test.TestCase): def test_least_busy_host_gets_volume(self): """Ensures the host with less gigabytes gets the next one""" - volume1 = service.Service('host1', - 'nova-volume', - 'volume', - FLAGS.volume_manager) - volume1.start() - volume2 = service.Service('host2', - 'nova-volume', - 'volume', - FLAGS.volume_manager) - volume2.start() + volume1 = self.start_service('volume', host='host1') + volume2 = self.start_service('volume', host='host2') volume_id1 = self._create_volume() volume1.create_volume(self.context, volume_id1) volume_id2 = self._create_volume() @@ -354,16 +294,8 @@ class SimpleDriverTestCase(test.TestCase): def test_too_many_gigabytes(self): """Ensures we don't go over max gigabytes""" - volume1 = service.Service('host1', - 'nova-volume', - 'volume', - FLAGS.volume_manager) - volume1.start() - volume2 = service.Service('host2', - 'nova-volume', - 'volume', - FLAGS.volume_manager) - volume2.start() + volume1 = self.start_service('volume', host='host1') + volume2 = self.start_service('volume', host='host2') volume_ids1 = [] volume_ids2 = [] for index in xrange(FLAGS.max_gigabytes): From 1241014a69f7710dd17d853e3c9da45b85fd8192 Mon Sep 17 00:00:00 2001 From: termie <github@anarkystic.com> Date: Mon, 21 Feb 2011 14:55:06 -0800 Subject: [PATCH 068/111] move test_cloud to use start_service, too --- nova/tests/test_cloud.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 445cc6e8..a174ea75 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -65,10 +65,8 @@ class CloudTestCase(test.TestCase): self.cloud = cloud.CloudController() # set up services - self.compute = service.Service.create(binary='nova-compute') - self.compute.start() - self.network = service.Service.create(binary='nova-network') - self.network.start() + self.compute = self.start_service('compute') + self.network = self.start_service('network') self.manager = manager.AuthManager() self.user = self.manager.create_user('admin', 'admin', 'admin', True) From aa71752562b3695aed29e64816907495616dedbc Mon Sep 17 00:00:00 2001 From: termie <github@anarkystic.com> Date: Mon, 21 Feb 2011 15:42:16 -0800 Subject: [PATCH 069/111] modify tests to use specific hosts rather than default --- nova/tests/test_cloud.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index a174ea75..1824d24b 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -100,7 +100,7 @@ class CloudTestCase(test.TestCase): address = "10.10.10.10" db.floating_ip_create(self.context, {'address': address, - 'host': FLAGS.host}) + 'host': self.network.host}) self.cloud.allocate_address(self.context) self.cloud.describe_addresses(self.context) self.cloud.release_address(self.context, @@ -113,9 +113,9 @@ class CloudTestCase(test.TestCase): address = "10.10.10.10" db.floating_ip_create(self.context, {'address': address, - 'host': FLAGS.host}) + 'host': self.network.host}) self.cloud.allocate_address(self.context) - inst = db.instance_create(self.context, {'host': FLAGS.host}) + inst = db.instance_create(self.context, {'host': self.compute.host}) fixed = self.network.allocate_fixed_ip(self.context, inst['id']) ec2_id = cloud.id_to_ec2_id(inst['id']) self.cloud.associate_address(self.context, From fdbd1ac793cfb0262259009387f3a6aba009cb57 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Mon, 21 Feb 2011 15:55:50 -0800 Subject: [PATCH 070/111] pretty colors for logs and a few optimizations --- bin/nova-dhcpbridge | 2 + run_tests.py | 202 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 202 insertions(+), 2 deletions(-) diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge index eda2dc07..04a1771f 100755 --- a/bin/nova-dhcpbridge +++ b/bin/nova-dhcpbridge @@ -113,6 +113,8 @@ def main(): FLAGS.num_networks = 5 path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', + 'nova', + 'tests', 'tests.sqlite')) FLAGS.sql_connection = 'sqlite:///%s' % path action = argv[1] diff --git a/run_tests.py b/run_tests.py index 82345433..43508394 100644 --- a/run_tests.py +++ b/run_tests.py @@ -17,6 +17,29 @@ # 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. + + import gettext import os import unittest @@ -28,14 +51,186 @@ from nose import core from nova import log as logging +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(fd=stream.fileno()) + return curses.tigetnum("colors") > 2 + except: + raise + # 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): + from win32console import GetStdHandle, STD_ERROR_HANDLE, \ + FOREGROUND_RED, FOREGROUND_BLUE, FOREGROUND_GREEN, \ + FOREGROUND_INTENSITY + red, green, blue, bold = (FOREGROUND_RED, FOREGROUND_GREEN, + FOREGROUND_BLUE, FOREGROUND_INTENSITY) + self.stream = stream + self.screenBuffer = GetStdHandle(STD_ERROR_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_ERROR_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) + class NovaTestResult(result.TextTestResult): def __init__(self, *args, **kw): result.TextTestResult.__init__(self, *args, **kw) self._last_case = None + self.colorizer = None + for colorizer in [_Win32Colorizer, _AnsiColorizer, _NullColorizer]: + # NOTE(vish): nose does funky stuff with stdout, so use stderr + # to setup the colorizer + if colorizer.supported(sys.stderr): + self.colorizer = colorizer(self.stream) + break def getDescription(self, test): return str(test) + def addSuccess(self, test): + if self.showAll: + self.colorizer.write("OK", 'green') + self.stream.writeln() + elif self.dots: + self.stream.write('.') + self.stream.flush() + + def addFailure(self, test): + if self.showAll: + self.colorizer.write("FAIL", 'red') + self.stream.writeln() + elif self.dots: + self.stream.write('F') + self.stream.flush() + + def addError(self, test, err): + """Overrides normal addError to add support for + errorClasses. If the exception is a registered class, the + error will be added to the list for that class, not errors. + """ + stream = getattr(self, 'stream', None) + ec, ev, tb = err + try: + exc_info = self._exc_info_to_string(err, test) + except TypeError: + # 2.3 compat + exc_info = self._exc_info_to_string(err) + for cls, (storage, label, isfail) in self.errorClasses.items(): + if result.isclass(ec) and issubclass(ec, cls): + if isfail: + test.passed = False + storage.append((test, exc_info)) + # Might get patched into a streamless result + if stream is not None: + if self.showAll: + message = [label] + detail = result._exception_detail(err[1]) + if detail: + message.append(detail) + stream.writeln(": ".join(message)) + elif self.dots: + stream.write(label[:1]) + return + self.errors.append((test, exc_info)) + test.passed = False + if stream is not None: + if self.showAll: + self.colorizer.write("ERROR", 'red') + self.stream.writeln() + elif self.dots: + stream.write('E') + def startTest(self, test): unittest.TestResult.startTest(self, test) current_case = test.test.__class__.__name__ @@ -59,12 +254,15 @@ class NovaTestRunner(core.TextTestRunner): if __name__ == '__main__': - if os.path.exists("tests.sqlite"): - os.unlink("tests.sqlite") logging.setup() + testdir = os.path.abspath(os.path.join("nova","tests")) + testdb = os.path.join(testdir, "tests.sqlite") + if os.path.exists(testdb): + os.unlink(testdb) c = config.Config(stream=sys.stdout, env=os.environ, verbosity=3, + workingDir=testdir, plugins=core.DefaultPluginManager()) runner = NovaTestRunner(stream=c.stream, From deb0f36f38c947d071f01c1f2cab8d8d40cd617f Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Mon, 21 Feb 2011 16:05:28 -0800 Subject: [PATCH 071/111] remove changes to test db --- bin/nova-dhcpbridge | 2 +- nova/tests/fake_flags.py | 2 +- run_tests.py | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge index eda2dc07..35b837ca 100755 --- a/bin/nova-dhcpbridge +++ b/bin/nova-dhcpbridge @@ -113,7 +113,7 @@ def main(): FLAGS.num_networks = 5 path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', - 'tests.sqlite')) + 'nova.sqlite')) FLAGS.sql_connection = 'sqlite:///%s' % path action = argv[1] if action in ['add', 'del', 'old']: diff --git a/nova/tests/fake_flags.py b/nova/tests/fake_flags.py index 575fefff..cfa65c13 100644 --- a/nova/tests/fake_flags.py +++ b/nova/tests/fake_flags.py @@ -39,6 +39,6 @@ FLAGS.num_shelves = 2 FLAGS.blades_per_shelf = 4 FLAGS.iscsi_num_targets = 8 FLAGS.verbose = True -FLAGS.sql_connection = 'sqlite:///tests.sqlite' +FLAGS.sql_connection = 'sqlite:///nova.sqlite' FLAGS.use_ipv6 = True FLAGS.logfile = 'tests.log' diff --git a/run_tests.py b/run_tests.py index 82345433..cb957da4 100644 --- a/run_tests.py +++ b/run_tests.py @@ -59,8 +59,6 @@ class NovaTestRunner(core.TextTestRunner): if __name__ == '__main__': - if os.path.exists("tests.sqlite"): - os.unlink("tests.sqlite") logging.setup() c = config.Config(stream=sys.stdout, env=os.environ, From 24e0f28457d0c4acb727ed1dbbb1719764f4e495 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Mon, 21 Feb 2011 16:19:48 -0800 Subject: [PATCH 072/111] fixed newline and moved import fake_flags into run_tests where it makes more sense --- run_tests.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/run_tests.py b/run_tests.py index cb957da4..6d96454b 100644 --- a/run_tests.py +++ b/run_tests.py @@ -27,6 +27,8 @@ from nose import result from nose import core from nova import log as logging +from nova.tests import fake_flags + class NovaTestResult(result.TextTestResult): def __init__(self, *args, **kw): From dd135e6402fe594df27479ba7b23689682588f7e Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Mon, 21 Feb 2011 16:22:09 -0800 Subject: [PATCH 073/111] update based on prereq branch --- nova/tests/fake_flags.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/tests/fake_flags.py b/nova/tests/fake_flags.py index cfa65c13..575fefff 100644 --- a/nova/tests/fake_flags.py +++ b/nova/tests/fake_flags.py @@ -39,6 +39,6 @@ FLAGS.num_shelves = 2 FLAGS.blades_per_shelf = 4 FLAGS.iscsi_num_targets = 8 FLAGS.verbose = True -FLAGS.sql_connection = 'sqlite:///nova.sqlite' +FLAGS.sql_connection = 'sqlite:///tests.sqlite' FLAGS.use_ipv6 = True FLAGS.logfile = 'tests.log' From c42a4bc8f75eddd186b19b313ba38a8d8e051dc9 Mon Sep 17 00:00:00 2001 From: Christian Berendt <berendt@b1-systems.de> Date: Tue, 22 Feb 2011 08:22:42 +0100 Subject: [PATCH 074/111] added disabled services to the list of displayed services in bin/nova-manage brontes:~ # nova-manage service list ares nova-scheduler enabled :-) 2011-02-22 07:21:29 ares nova-network enabled :-) 2011-02-22 07:21:29 ares nova-volume enabled XXX 2011-02-16 19:04:29 brontes nova-volume enabled XXX 2011-02-12 18:31:43 brontes nova-network enabled :-) 2011-02-22 07:21:29 ares nova-compute disabled :-) 2011-02-22 07:21:25 brontes nova-compute disabled :-) 2011-02-22 07:21:24 --- bin/nova-manage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nova-manage b/bin/nova-manage index 6d67252b..af843244 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -552,7 +552,7 @@ class ServiceCommands(object): args: [host] [service]""" ctxt = context.get_admin_context() now = datetime.datetime.utcnow() - services = db.service_get_all(ctxt) + services = db.service_get_all(ctxt) + db.service_get_all(ctxt, True) if host: services = [s for s in services if s['host'] == host] if service: From a44befc70a05f9b5f92f04a9c7c11e99f85fdabb Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Mon, 21 Feb 2011 23:26:03 -0800 Subject: [PATCH 075/111] use a different flag for listen port for apis --- bin/nova-api | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/nova-api b/bin/nova-api index 11176a02..cb9b4172 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -44,6 +44,8 @@ LOG = logging.getLogger('nova.api') LOG.setLevel(logging.DEBUG) FLAGS = flags.FLAGS +flags.DEFINE_integer('ec2_listen_port', 8773, 'port for ec2 api to listen') +flags.DEFINE_integer('osapi_listen_port', 8774, 'port for os api to listen') API_ENDPOINTS = ['ec2', 'osapi'] @@ -60,10 +62,10 @@ def run_app(paste_config_file): wsgi.paste_config_to_flags(config, { "verbose": FLAGS.verbose, "%s_host" % api: config.get('host', '0.0.0.0'), - "%s_port" % api: getattr(FLAGS, "%s_port" % api)}) + "%s_listen_port" % api: getattr(FLAGS, "%s_listen_port" % api)}) LOG.info(_("Running %s API"), api) app = wsgi.load_paste_app(paste_config_file, api) - apps.append((app, getattr(FLAGS, "%s_port" % api), + apps.append((app, getattr(FLAGS, "%s_listen_port" % api), getattr(FLAGS, "%s_host" % api))) if len(apps) == 0: LOG.error(_("No known API applications configured in %s."), From bb533c0269670f786b84fff69b80d287d0ff9ac9 Mon Sep 17 00:00:00 2001 From: Thierry Carrez <thierry@openstack.org> Date: Tue, 22 Feb 2011 17:18:04 +0100 Subject: [PATCH 076/111] Get rid of nova-combined, see rationale on ML --- bin/nova-combined | 83 ----------------------------------------------- 1 file changed, 83 deletions(-) delete mode 100755 bin/nova-combined diff --git a/bin/nova-combined b/bin/nova-combined deleted file mode 100755 index 22f0d5cb..00000000 --- a/bin/nova-combined +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# 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. - -"""Combined starter script for Nova services.""" - -import eventlet -eventlet.monkey_patch() - -import gettext -import os -import sys - -# If ../nova/__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, 'nova', '__init__.py')): - sys.path.insert(0, possible_topdir) - -gettext.install('nova', unicode=1) - -from nova import flags -from nova import log as logging -from nova import service -from nova import utils -from nova import wsgi - - -FLAGS = flags.FLAGS - -API_ENDPOINTS = ['ec2', 'osapi'] - -for api in API_ENDPOINTS: - flags.DEFINE_string("%s_listen" % api, "0.0.0.0", - "IP address to listen to for API %s" % api) - flags.DEFINE_integer("%s_listen_port" % api, - getattr(FLAGS, "%s_port" % api), - "Port to listen to for API %s" % api) - -if __name__ == '__main__': - utils.default_flagfile() - FLAGS(sys.argv) - logging.setup() - - compute = service.Service.create(binary='nova-compute') - network = service.Service.create(binary='nova-network') - volume = service.Service.create(binary='nova-volume') - scheduler = service.Service.create(binary='nova-scheduler') - #objectstore = service.Service.create(binary='nova-objectstore') - - service.serve(compute, network, volume, scheduler) - - apps = [] - paste_config_file = wsgi.paste_config_file('nova-api.conf') - for api in API_ENDPOINTS: - config = wsgi.load_paste_configuration(paste_config_file, api) - if config is None: - continue - app = wsgi.load_paste_app(paste_config_file, api) - apps.append((app, getattr(FLAGS, "%s_listen_port" % api), - getattr(FLAGS, "%s_listen" % api))) - if len(apps) > 0: - server = wsgi.Server() - for app in apps: - server.start(*app) - server.wait() From 012dbe554f0cc76c4005c520d3a6c8f0e8a45012 Mon Sep 17 00:00:00 2001 From: termie <github@anarkystic.com> Date: Tue, 22 Feb 2011 17:10:34 -0800 Subject: [PATCH 077/111] don't make a syslog handler if we didn't ask for one --- nova/log.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nova/log.py b/nova/log.py index 10c14d74..591d26c6 100644 --- a/nova/log.py +++ b/nova/log.py @@ -236,16 +236,17 @@ class NovaRootLogger(NovaLogger): def __init__(self, name, level=NOTSET): self.logpath = None self.filelog = None - self.syslog = SysLogHandler(address='/dev/log') self.streamlog = StreamHandler() + self.syslog = None NovaLogger.__init__(self, name, level) def setup_from_flags(self): """Setup logger from flags""" global _filelog if FLAGS.use_syslog: + self.syslog = SysLogHandler(address='/dev/log') self.addHandler(self.syslog) - else: + elif self.syslog: self.removeHandler(self.syslog) logpath = _get_log_file_path() if logpath: From 01eb40f218e38481a9dddd4e013c7af61e4a222f Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Tue, 22 Feb 2011 17:44:07 -0800 Subject: [PATCH 078/111] test that shows error on filtering groups --- nova/tests/test_cloud.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 445cc6e8..2bce6435 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -133,6 +133,20 @@ class CloudTestCase(test.TestCase): db.instance_destroy(self.context, inst['id']) db.floating_ip_destroy(self.context, address) + def test_describe_security_groups(self): + """Makes sure describe_security_groups works and filters results.""" + sec = db.security_group_create(self.context, {'name': 'test'}) + result = self.cloud.describe_security_groups(self.context) + # NOTE(vish): should have the default group as well + self.assertEqual(len(result['securityGroupInfo']), 2) + result = self.cloud.describe_security_groups(self.context, + group_name=[sec['name']]) + self.assertEqual(len(result['securityGroupInfo']), 1) + self.assertEqual( + cloud.ec2_id_to_id(result['securityGroupInfo'][0]['name']), + sec['name']) + db.security_group_destroy(self.context, sec['id']) + def test_describe_volumes(self): """Makes sure describe_volumes works and filters results.""" vol1 = db.volume_create(self.context, {}) @@ -286,19 +300,6 @@ class CloudTestCase(test.TestCase): LOG.debug(_("Terminating instance %s"), instance_id) rv = self.compute.terminate_instance(instance_id) - def test_describe_instances(self): - """Makes sure describe_instances works.""" - instance1 = db.instance_create(self.context, {'host': 'host2'}) - comp1 = db.service_create(self.context, {'host': 'host2', - 'availability_zone': 'zone1', - 'topic': "compute"}) - result = self.cloud.describe_instances(self.context) - self.assertEqual(result['reservationSet'][0] - ['instancesSet'][0] - ['placement']['availabilityZone'], 'zone1') - db.instance_destroy(self.context, instance1['id']) - db.service_destroy(self.context, comp1['id']) - def test_instance_update_state(self): # TODO(termie): what is this code even testing? def instance(num): From 23d0fc6fe4c34bb34ab8ce40c15b5f94781c87e6 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Tue, 22 Feb 2011 17:49:38 -0800 Subject: [PATCH 079/111] fix test --- nova/tests/test_cloud.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 2bce6435..afdbb80a 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -135,7 +135,9 @@ class CloudTestCase(test.TestCase): def test_describe_security_groups(self): """Makes sure describe_security_groups works and filters results.""" - sec = db.security_group_create(self.context, {'name': 'test'}) + sec = db.security_group_create(self.context, + {'project_id': self.context.project_id, + 'name': 'test'}) result = self.cloud.describe_security_groups(self.context) # NOTE(vish): should have the default group as well self.assertEqual(len(result['securityGroupInfo']), 2) @@ -143,7 +145,7 @@ class CloudTestCase(test.TestCase): group_name=[sec['name']]) self.assertEqual(len(result['securityGroupInfo']), 1) self.assertEqual( - cloud.ec2_id_to_id(result['securityGroupInfo'][0]['name']), + result['securityGroupInfo'][0]['groupName'], sec['name']) db.security_group_destroy(self.context, sec['id']) From 860f325d05f05cdb62dc8959a48aa8ea40ad8822 Mon Sep 17 00:00:00 2001 From: Todd Willey <todd@ansolabs.com> Date: Tue, 22 Feb 2011 23:42:49 -0500 Subject: [PATCH 080/111] Update the admin client to deal with VPNs and have a function host list. --- nova/adminclient.py | 63 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/nova/adminclient.py b/nova/adminclient.py index c614b274..fe2aca35 100644 --- a/nova/adminclient.py +++ b/nova/adminclient.py @@ -23,6 +23,8 @@ import base64 import boto import boto.exception import httplib +import re +import string from boto.ec2.regioninfo import RegionInfo @@ -165,19 +167,20 @@ class HostInfo(object): **Fields Include** - * Disk stats - * Running Instances - * Memory stats - * CPU stats - * Network address info - * Firewall info - * Bridge and devices - + * Hostname + * Compute service status + * Volume service status + * Instance count + * Volume count """ def __init__(self, connection=None): self.connection = connection self.hostname = None + self.compute = None + self.volume = None + self.instance_count = 0 + self.volume_count = 0 def __repr__(self): return 'Host:%s' % self.hostname @@ -188,7 +191,39 @@ class HostInfo(object): # this is needed by the sax parser, so ignore the ugly name def endElement(self, name, value, connection): - setattr(self, name, value) + fixed_name = string.lower(re.sub(r'([A-Z])', r'_\1', name)) + setattr(self, fixed_name, value) + + +class Vpn(object): + """ + Information about a Vpn, as parsed through SAX + + **Fields Include** + + * instance_id + * project_id + * public_ip + * public_port + * created_at + * internal_ip + * state + """ + + def __init__(self, connection=None): + self.connection = connection + self.instance_id = None + self.project_id = None + + def __repr__(self): + return 'Vpn:%s:%s' % (self.project_id, self.instance_id) + + def startElement(self, name, attrs, connection): + return None + + def endElement(self, name, value, connection): + fixed_name = string.lower(re.sub(r'([A-Z])', r'_\1', name)) + setattr(self, fixed_name, value) class InstanceType(object): @@ -422,6 +457,16 @@ class NovaAdminClient(object): zip = self.apiconn.get_object('GenerateX509ForUser', params, UserInfo) return zip.file + def start_vpn(self, project): + """ + Starts the vpn for a user + """ + return self.apiconn.get_object('StartVpn', {'Project': project}, Vpn) + + def get_vpns(self): + """Return a list of vpn with project name""" + return self.apiconn.get_list('DescribeVpns', {}, [('item', Vpn)]) + def get_hosts(self): return self.apiconn.get_list('DescribeHosts', {}, [('item', HostInfo)]) From e044c1b2a26669ee10fe2e4703a403906839b9bc Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Tue, 22 Feb 2011 23:21:01 -0800 Subject: [PATCH 081/111] Lots of test fixing --- nova/tests/test_cloud.py | 75 ++++++++---------------------------- nova/tests/test_network.py | 3 ++ nova/tests/test_scheduler.py | 3 ++ nova/tests/test_virt.py | 3 ++ 4 files changed, 26 insertions(+), 58 deletions(-) diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 1824d24b..2c6dc597 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -66,6 +66,7 @@ class CloudTestCase(test.TestCase): # set up services self.compute = self.start_service('compute') + self.scheduter = self.start_service('scheduler') self.network = self.start_service('network') self.manager = manager.AuthManager() @@ -73,8 +74,12 @@ class CloudTestCase(test.TestCase): self.project = self.manager.create_project('proj', 'admin', 'proj') self.context = context.RequestContext(user=self.user, project=self.project) + host = self.network.get_network_host(self.context.elevated()) def tearDown(self): + network_ref = db.project_get_network(self.context, + self.project.id) + db.network_disassociate(self.context, network_ref['id']) self.manager.delete_project(self.project) self.manager.delete_user(self.user) self.compute.kill() @@ -201,27 +206,32 @@ class CloudTestCase(test.TestCase): 'instance_type': instance_type, 'max_count': max_count} rv = self.cloud.run_instances(self.context, **kwargs) + greenthread.sleep(0.3) instance_id = rv['instancesSet'][0]['instanceId'] output = self.cloud.get_console_output(context=self.context, - instance_id=[instance_id]) + instance_id=[instance_id]) self.assertEquals(b64decode(output['output']), 'FAKE CONSOLE OUTPUT') # TODO(soren): We need this until we can stop polling in the rpc code # for unit tests. greenthread.sleep(0.3) rv = self.cloud.terminate_instances(self.context, [instance_id]) + greenthread.sleep(0.3) def test_ajax_console(self): + image_id = FLAGS.default_image kwargs = {'image_id': image_id} - rv = yield self.cloud.run_instances(self.context, **kwargs) + rv = self.cloud.run_instances(self.context, **kwargs) instance_id = rv['instancesSet'][0]['instanceId'] - output = yield self.cloud.get_console_output(context=self.context, - instance_id=[instance_id]) - self.assertEquals(b64decode(output['output']), - 'http://fakeajaxconsole.com/?token=FAKETOKEN') + greenthread.sleep(0.3) + output = self.cloud.get_ajax_console(context=self.context, + instance_id=[instance_id]) + self.assertEquals(output['url'], + '%s/?token=FAKETOKEN' % FLAGS.ajax_console_proxy_url) # TODO(soren): We need this until we can stop polling in the rpc code # for unit tests. greenthread.sleep(0.3) - rv = yield self.cloud.terminate_instances(self.context, [instance_id]) + rv = self.cloud.terminate_instances(self.context, [instance_id]) + greenthread.sleep(0.3) def test_key_generation(self): result = self._create_key('test') @@ -297,57 +307,6 @@ class CloudTestCase(test.TestCase): db.instance_destroy(self.context, instance1['id']) db.service_destroy(self.context, comp1['id']) - def test_instance_update_state(self): - # TODO(termie): what is this code even testing? - def instance(num): - return { - 'reservation_id': 'r-1', - 'instance_id': 'i-%s' % num, - 'image_id': 'ami-%s' % num, - 'private_dns_name': '10.0.0.%s' % num, - 'dns_name': '10.0.0%s' % num, - 'ami_launch_index': str(num), - 'instance_type': 'fake', - 'availability_zone': 'fake', - 'key_name': None, - 'kernel_id': 'fake', - 'ramdisk_id': 'fake', - 'groups': ['default'], - 'product_codes': None, - 'state': 0x01, - 'user_data': ''} - rv = self.cloud._format_describe_instances(self.context) - logging.error(str(rv)) - self.assertEqual(len(rv['reservationSet']), 0) - - # simulate launch of 5 instances - # self.cloud.instances['pending'] = {} - #for i in xrange(5): - # inst = instance(i) - # self.cloud.instances['pending'][inst['instance_id']] = inst - - #rv = self.cloud._format_instances(self.admin) - #self.assert_(len(rv['reservationSet']) == 1) - #self.assert_(len(rv['reservationSet'][0]['instances_set']) == 5) - # report 4 nodes each having 1 of the instances - #for i in xrange(4): - # self.cloud.update_state('instances', - # {('node-%s' % i): {('i-%s' % i): - # instance(i)}}) - - # one instance should be pending still - #self.assert_(len(self.cloud.instances['pending'].keys()) == 1) - - # check that the reservations collapse - #rv = self.cloud._format_instances(self.admin) - #self.assert_(len(rv['reservationSet']) == 1) - #self.assert_(len(rv['reservationSet'][0]['instances_set']) == 5) - - # check that we can get metadata for each instance - #for i in xrange(4): - # data = self.cloud.get_metadata(instance(i)['private_dns_name']) - # self.assert_(data['meta-data']['ami-id'] == 'ami-%s' % i) - @staticmethod def _fake_set_image_description(ctxt, image_id, description): from nova.objectstore import handler diff --git a/nova/tests/test_network.py b/nova/tests/test_network.py index 00f9323f..53cfea27 100644 --- a/nova/tests/test_network.py +++ b/nova/tests/test_network.py @@ -117,6 +117,9 @@ class NetworkTestCase(test.TestCase): utils.to_global_ipv6( network_ref['cidr_v6'], instance_ref['mac_address'])) + self._deallocate_address(0, address) + db.instance_destroy(context.get_admin_context(), + instance_ref['id']) def test_public_network_association(self): """Makes sure that we can allocaate a public ip""" diff --git a/nova/tests/test_scheduler.py b/nova/tests/test_scheduler.py index 25017007..8e4a4daf 100644 --- a/nova/tests/test_scheduler.py +++ b/nova/tests/test_scheduler.py @@ -118,6 +118,7 @@ class ZoneSchedulerTestCase(test.TestCase): arg = IgnoreArg() db.service_get_all_by_topic(arg, arg).AndReturn(service_list) self.mox.StubOutWithMock(rpc, 'cast', use_mock_anything=True) + self.mox.StubOutWithMock(db, 'instance_create', use_mock_anything=True) rpc.cast(ctxt, 'compute.host1', {'method': 'run_instance', @@ -150,6 +151,7 @@ class SimpleDriverTestCase(test.TestCase): def tearDown(self): self.manager.delete_user(self.user) self.manager.delete_project(self.project) + super(SimpleDriverTestCase, self).tearDown() def _create_instance(self, **kwargs): """Create a test instance""" @@ -270,6 +272,7 @@ class SimpleDriverTestCase(test.TestCase): self.scheduler.driver.schedule_run_instance, self.context, instance_id) + db.instance_destroy(self.context, instance_id) for instance_id in instance_ids1: compute1.terminate_instance(self.context, instance_id) for instance_id in instance_ids2: diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 6e5a0114..5b3247df 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -204,6 +204,7 @@ class LibvirtConnTestCase(test.TestCase): conn = libvirt_conn.LibvirtConnection(True) uri = conn.get_uri() self.assertEquals(uri, testuri) + db.instance_destroy(user_context, instance_ref['id']) def tearDown(self): super(LibvirtConnTestCase, self).tearDown() @@ -365,6 +366,7 @@ class IptablesFirewallTestCase(test.TestCase): '--dports 80:81 -j ACCEPT' % security_group_chain \ in self.out_rules, "TCP port 80/81 acceptance rule wasn't added") + db.instance_destroy(admin_ctxt, instance_ref['id']) class NWFilterTestCase(test.TestCase): @@ -514,3 +516,4 @@ class NWFilterTestCase(test.TestCase): self.fw.apply_instance_filter(instance) _ensure_all_called() self.teardown_security_group() + db.instance_destroy(admin_ctxt, instance_ref['id']) From b47d9f73ae2f52a5f9def0db4f62c5f679ccff47 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Tue, 22 Feb 2011 23:30:52 -0800 Subject: [PATCH 082/111] remove unnecessary stubout --- nova/tests/test_scheduler.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nova/tests/test_scheduler.py b/nova/tests/test_scheduler.py index 8e4a4daf..b6888c4d 100644 --- a/nova/tests/test_scheduler.py +++ b/nova/tests/test_scheduler.py @@ -118,7 +118,6 @@ class ZoneSchedulerTestCase(test.TestCase): arg = IgnoreArg() db.service_get_all_by_topic(arg, arg).AndReturn(service_list) self.mox.StubOutWithMock(rpc, 'cast', use_mock_anything=True) - self.mox.StubOutWithMock(db, 'instance_create', use_mock_anything=True) rpc.cast(ctxt, 'compute.host1', {'method': 'run_instance', From a6a844cfd54b0a3a1221837d45227e593988d5c6 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Wed, 23 Feb 2011 00:59:15 -0800 Subject: [PATCH 083/111] fix failures --- run_tests.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/run_tests.py b/run_tests.py index 4084d8d8..01a1cf8b 100644 --- a/run_tests.py +++ b/run_tests.py @@ -181,6 +181,7 @@ class NovaTestResult(result.TextTestResult): return str(test) def addSuccess(self, test): + unittest.TestResult.addSuccess(self, test) if self.showAll: self.colorizer.write("OK", 'green') self.stream.writeln() @@ -188,7 +189,8 @@ class NovaTestResult(result.TextTestResult): self.stream.write('.') self.stream.flush() - def addFailure(self, test): + def addFailure(self, test, err): + unittest.TestResult.addFailure(self, test, err) if self.showAll: self.colorizer.write("FAIL", 'red') self.stream.writeln() From c4259091072c539f0150b7ada5fe7fc1767543aa Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Wed, 23 Feb 2011 01:13:41 -0800 Subject: [PATCH 084/111] move db creation into fixtures and clean db for each test --- nova/tests/objectstore_unittest.py | 1 + nova/tests/test_direct.py | 1 + nova/tests/test_scheduler.py | 1 + nova/tests/test_virt.py | 3 ++- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/nova/tests/objectstore_unittest.py b/nova/tests/objectstore_unittest.py index da86e6e1..5a1be08e 100644 --- a/nova/tests/objectstore_unittest.py +++ b/nova/tests/objectstore_unittest.py @@ -311,4 +311,5 @@ class S3APITestCase(test.TestCase): self.auth_manager.delete_user('admin') self.auth_manager.delete_project('admin') stop_listening = defer.maybeDeferred(self.listening_port.stopListening) + super(S3APITestCase, self).tearDown() return defer.DeferredList([stop_listening]) diff --git a/nova/tests/test_direct.py b/nova/tests/test_direct.py index 7656f539..b6bfab53 100644 --- a/nova/tests/test_direct.py +++ b/nova/tests/test_direct.py @@ -52,6 +52,7 @@ class DirectTestCase(test.TestCase): def tearDown(self): direct.ROUTES = {} + super(DirectTestCase, self).tearDown() def test_delegated_auth(self): req = webob.Request.blank('/fake/context') diff --git a/nova/tests/test_scheduler.py b/nova/tests/test_scheduler.py index 9d458244..1bad364e 100644 --- a/nova/tests/test_scheduler.py +++ b/nova/tests/test_scheduler.py @@ -150,6 +150,7 @@ class SimpleDriverTestCase(test.TestCase): def tearDown(self): self.manager.delete_user(self.user) self.manager.delete_project(self.project) + super(SimpleDriverTestCase, self).tearDown() def _create_instance(self, **kwargs): """Create a test instance""" diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 6e5a0114..7aadd65d 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -206,9 +206,9 @@ class LibvirtConnTestCase(test.TestCase): self.assertEquals(uri, testuri) def tearDown(self): - super(LibvirtConnTestCase, self).tearDown() self.manager.delete_project(self.project) self.manager.delete_user(self.user) + super(LibvirtConnTestCase, self).tearDown() class IptablesFirewallTestCase(test.TestCase): @@ -388,6 +388,7 @@ class NWFilterTestCase(test.TestCase): def tearDown(self): self.manager.delete_project(self.project) self.manager.delete_user(self.user) + super(NWFilterTestCase, self).tearDown() def test_cidr_rule_nwfilter_xml(self): cloud_controller = cloud.CloudController() From 91c62838e2d9b03759787f199b97a6246cddca56 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Wed, 23 Feb 2011 01:52:07 -0800 Subject: [PATCH 085/111] speed up network tests --- nova/tests/fake_flags.py | 4 ++-- nova/tests/test_network.py | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/nova/tests/fake_flags.py b/nova/tests/fake_flags.py index 575fefff..a8291a96 100644 --- a/nova/tests/fake_flags.py +++ b/nova/tests/fake_flags.py @@ -29,8 +29,8 @@ FLAGS.auth_driver = 'nova.auth.dbdriver.DbDriver' flags.DECLARE('network_size', 'nova.network.manager') flags.DECLARE('num_networks', 'nova.network.manager') flags.DECLARE('fake_network', 'nova.network.manager') -FLAGS.network_size = 16 -FLAGS.num_networks = 5 +FLAGS.network_size = 8 +FLAGS.num_networks = 2 FLAGS.fake_network = True flags.DECLARE('num_shelves', 'nova.volume.driver') flags.DECLARE('blades_per_shelf', 'nova.volume.driver') diff --git a/nova/tests/test_network.py b/nova/tests/test_network.py index 00f9323f..ccb5298b 100644 --- a/nova/tests/test_network.py +++ b/nova/tests/test_network.py @@ -42,15 +42,13 @@ class NetworkTestCase(test.TestCase): # flags in the corresponding section in nova-dhcpbridge self.flags(connection_type='fake', fake_call=True, - fake_network=True, - network_size=16, - num_networks=5) + fake_network=True) self.manager = manager.AuthManager() self.user = self.manager.create_user('netuser', 'netuser', 'netuser') self.projects = [] self.network = utils.import_object(FLAGS.network_manager) self.context = context.RequestContext(project=None, user=self.user) - for i in range(5): + for i in range(FLAGS.num_networks): name = 'project%s' % i project = self.manager.create_project(name, 'netuser', name) self.projects.append(project) @@ -192,7 +190,7 @@ class NetworkTestCase(test.TestCase): first = self._create_address(0) lease_ip(first) instance_ids = [] - for i in range(1, 5): + for i in range(1, FLAGS.num_networks): instance_ref = self._create_instance(i, mac=utils.generate_mac()) instance_ids.append(instance_ref['id']) address = self._create_address(i, instance_ref['id']) From 67f0c6828c8f3d28fb44103836c7de4c5bf19a6f Mon Sep 17 00:00:00 2001 From: termie <github@anarkystic.com> Date: Wed, 23 Feb 2011 08:45:27 -0800 Subject: [PATCH 086/111] allow users to omit 'nova.tests' with run_tests --- run_tests.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/run_tests.py b/run_tests.py index 6d96454b..47e3ee31 100644 --- a/run_tests.py +++ b/run_tests.py @@ -17,6 +17,23 @@ # See the License for the specific language governing permissions and # limitations under the License. +"""Unittest runner for Nova. + +To run all tests + python run_tests.py + +To run a single test: + python run_tests.py test_compute:ComputeTestCase.test_run_terminate + +To run a single test module: + python run_tests.py test_compute + + or + + python run_tests.py api.test_wsgi + +""" + import gettext import os import unittest @@ -62,6 +79,15 @@ class NovaTestRunner(core.TextTestRunner): if __name__ == '__main__': logging.setup() + # If any argument looks like a test name but doesn't have "nova.tests" in + # front of it, automatically add that so we don't have to type as much + argv = [] + for x in sys.argv: + if x.startswith('test_'): + argv.append('nova.tests.%s' % x) + else: + argv.append(x) + c = config.Config(stream=sys.stdout, env=os.environ, verbosity=3, @@ -70,4 +96,4 @@ if __name__ == '__main__': runner = NovaTestRunner(stream=c.stream, verbosity=c.verbosity, config=c) - sys.exit(not core.run(config=c, testRunner=runner)) + sys.exit(not core.run(config=c, testRunner=runner, argv=argv)) From 3af66aec2ef5864b4545998362f75d20ab085448 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Wed, 23 Feb 2011 11:20:52 -0800 Subject: [PATCH 087/111] use flags for sqlite db names and fix flags in dhcpbridge --- bin/nova-dhcpbridge | 13 +------------ nova/flags.py | 3 ++- nova/tests/fake_flags.py | 2 +- run_tests.py | 11 ++++++++--- 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge index 04a1771f..3dd9de36 100755 --- a/bin/nova-dhcpbridge +++ b/bin/nova-dhcpbridge @@ -105,18 +105,7 @@ def main(): logging.setup() interface = os.environ.get('DNSMASQ_INTERFACE', 'br0') if int(os.environ.get('TESTING', '0')): - FLAGS.fake_rabbit = True - FLAGS.network_size = 16 - FLAGS.connection_type = 'fake' - FLAGS.fake_network = True - FLAGS.auth_driver = 'nova.auth.dbdriver.DbDriver' - FLAGS.num_networks = 5 - path = os.path.abspath(os.path.join(os.path.dirname(__file__), - '..', - 'nova', - 'tests', - 'tests.sqlite')) - FLAGS.sql_connection = 'sqlite:///%s' % path + from nova.tests import fake_flags action = argv[1] if action in ['add', 'del', 'old']: mac = argv[2] diff --git a/nova/flags.py b/nova/flags.py index f64a62da..ab1adc6e 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -285,8 +285,9 @@ DEFINE_string('state_path', os.path.join(os.path.dirname(__file__), '../'), DEFINE_string('logdir', None, 'output to a per-service log file in named ' 'directory') +DEFINE_string('sqlite_db', 'nova.sqlite', 'file name for sqlite') DEFINE_string('sql_connection', - 'sqlite:///$state_path/nova.sqlite', + 'sqlite:///$state_path/$sqlite_db', 'connection string for sql database') DEFINE_integer('sql_idle_timeout', 3600, diff --git a/nova/tests/fake_flags.py b/nova/tests/fake_flags.py index a8291a96..dcc8a676 100644 --- a/nova/tests/fake_flags.py +++ b/nova/tests/fake_flags.py @@ -39,6 +39,6 @@ FLAGS.num_shelves = 2 FLAGS.blades_per_shelf = 4 FLAGS.iscsi_num_targets = 8 FLAGS.verbose = True -FLAGS.sql_connection = 'sqlite:///tests.sqlite' +FLAGS.sqlite_db = "tests.sqlite" FLAGS.use_ipv6 = True FLAGS.logfile = 'tests.log' diff --git a/run_tests.py b/run_tests.py index 01a1cf8b..88c42bd3 100644 --- a/run_tests.py +++ b/run_tests.py @@ -46,13 +46,17 @@ import unittest import sys from nose import config -from nose import result from nose import core +from nose import result +from nova import flags from nova import log as logging from nova.tests import fake_flags +FLAGS = flags.FLAGS + + class _AnsiColorizer(object): """ A colorizer is an object that loosely wraps around a stream, allowing @@ -259,10 +263,11 @@ class NovaTestRunner(core.TextTestRunner): if __name__ == '__main__': logging.setup() - testdir = os.path.abspath(os.path.join("nova","tests")) - testdb = os.path.join(testdir, "tests.sqlite") + testdb = os.path.join(FLAGS.state_path, + FLAGS.sqlite_db) if os.path.exists(testdb): os.unlink(testdb) + testdir = os.path.abspath(os.path.join("nova","tests")) c = config.Config(stream=sys.stdout, env=os.environ, verbosity=3, From 32ff6a99f040ea2d4de3fd7a0350feaeb9b56d8e Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Wed, 23 Feb 2011 11:44:09 -0800 Subject: [PATCH 088/111] merged trunk --- nova/tests/objectstore_unittest.py | 1 + nova/tests/test_direct.py | 1 + nova/tests/test_scheduler.py | 1 + nova/tests/test_virt.py | 3 ++- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/nova/tests/objectstore_unittest.py b/nova/tests/objectstore_unittest.py index da86e6e1..5a1be08e 100644 --- a/nova/tests/objectstore_unittest.py +++ b/nova/tests/objectstore_unittest.py @@ -311,4 +311,5 @@ class S3APITestCase(test.TestCase): self.auth_manager.delete_user('admin') self.auth_manager.delete_project('admin') stop_listening = defer.maybeDeferred(self.listening_port.stopListening) + super(S3APITestCase, self).tearDown() return defer.DeferredList([stop_listening]) diff --git a/nova/tests/test_direct.py b/nova/tests/test_direct.py index 7656f539..b6bfab53 100644 --- a/nova/tests/test_direct.py +++ b/nova/tests/test_direct.py @@ -52,6 +52,7 @@ class DirectTestCase(test.TestCase): def tearDown(self): direct.ROUTES = {} + super(DirectTestCase, self).tearDown() def test_delegated_auth(self): req = webob.Request.blank('/fake/context') diff --git a/nova/tests/test_scheduler.py b/nova/tests/test_scheduler.py index 9d458244..1bad364e 100644 --- a/nova/tests/test_scheduler.py +++ b/nova/tests/test_scheduler.py @@ -150,6 +150,7 @@ class SimpleDriverTestCase(test.TestCase): def tearDown(self): self.manager.delete_user(self.user) self.manager.delete_project(self.project) + super(SimpleDriverTestCase, self).tearDown() def _create_instance(self, **kwargs): """Create a test instance""" diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 6e5a0114..7aadd65d 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -206,9 +206,9 @@ class LibvirtConnTestCase(test.TestCase): self.assertEquals(uri, testuri) def tearDown(self): - super(LibvirtConnTestCase, self).tearDown() self.manager.delete_project(self.project) self.manager.delete_user(self.user) + super(LibvirtConnTestCase, self).tearDown() class IptablesFirewallTestCase(test.TestCase): @@ -388,6 +388,7 @@ class NWFilterTestCase(test.TestCase): def tearDown(self): self.manager.delete_project(self.project) self.manager.delete_user(self.user) + super(NWFilterTestCase, self).tearDown() def test_cidr_rule_nwfilter_xml(self): cloud_controller = cloud.CloudController() From 3f629194d88d614f2362a99d37fbbf30a7d653c3 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Wed, 23 Feb 2011 11:52:10 -0800 Subject: [PATCH 089/111] put the redirection back in to run_tests.sh and fix terminal colors by using original stdout --- nova/tests/fake_flags.py | 1 - run_tests.py | 16 +++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/nova/tests/fake_flags.py b/nova/tests/fake_flags.py index 575fefff..2b191940 100644 --- a/nova/tests/fake_flags.py +++ b/nova/tests/fake_flags.py @@ -41,4 +41,3 @@ FLAGS.iscsi_num_targets = 8 FLAGS.verbose = True FLAGS.sql_connection = 'sqlite:///tests.sqlite' FLAGS.use_ipv6 = True -FLAGS.logfile = 'tests.log' diff --git a/run_tests.py b/run_tests.py index 01a1cf8b..c78f8883 100644 --- a/run_tests.py +++ b/run_tests.py @@ -82,7 +82,7 @@ class _AnsiColorizer(object): try: return curses.tigetnum("colors") > 2 except curses.error: - curses.setupterm(fd=stream.fileno()) + curses.setupterm() return curses.tigetnum("colors") > 2 except: raise @@ -107,13 +107,13 @@ class _Win32Colorizer(object): See _AnsiColorizer docstring. """ def __init__(self, stream): - from win32console import GetStdHandle, STD_ERROR_HANDLE, \ + from win32console import GetStdHandle, STD_OUT_HANDLE, \ FOREGROUND_RED, FOREGROUND_BLUE, FOREGROUND_GREEN, \ FOREGROUND_INTENSITY red, green, blue, bold = (FOREGROUND_RED, FOREGROUND_GREEN, FOREGROUND_BLUE, FOREGROUND_INTENSITY) self.stream = stream - self.screenBuffer = GetStdHandle(STD_ERROR_HANDLE) + self.screenBuffer = GetStdHandle(STD_OUT_HANDLE) self._colors = { 'normal': red | green | blue, 'red': red | bold, @@ -129,7 +129,7 @@ class _Win32Colorizer(object): try: import win32console screenBuffer = win32console.GetStdHandle( - win32console.STD_ERROR_HANDLE) + win32console.STD_OUT_HANDLE) except ImportError: return False import pywintypes @@ -170,12 +170,14 @@ class NovaTestResult(result.TextTestResult): result.TextTestResult.__init__(self, *args, **kw) self._last_case = None self.colorizer = None + # NOTE(vish): reset stdout for the terminal check + stdout = sys.stdout + sys.stdout = sys.__stdout__ for colorizer in [_Win32Colorizer, _AnsiColorizer, _NullColorizer]: - # NOTE(vish): nose does funky stuff with stdout, so use stderr - # to setup the colorizer - if colorizer.supported(sys.stderr): + if colorizer.supported(): self.colorizer = colorizer(self.stream) break + sys.stdout = stdout def getDescription(self, test): return str(test) From 3fd6a704cce2f3c79588cc76cc58b46d855f44ef Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Wed, 23 Feb 2011 12:00:02 -0800 Subject: [PATCH 090/111] move the deletion of the db into fixtures --- run_tests.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/run_tests.py b/run_tests.py index bb6f0dd1..5fb5ba32 100644 --- a/run_tests.py +++ b/run_tests.py @@ -265,10 +265,6 @@ class NovaTestRunner(core.TextTestRunner): if __name__ == '__main__': logging.setup() - testdb = os.path.join(FLAGS.state_path, - FLAGS.sqlite_db) - if os.path.exists(testdb): - os.unlink(testdb) testdir = os.path.abspath(os.path.join("nova","tests")) c = config.Config(stream=sys.stdout, env=os.environ, From 7686a0afc92214665a275e9931da1d162a216a3b Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara <justin@fathomdb.com> Date: Wed, 23 Feb 2011 12:05:49 -0800 Subject: [PATCH 091/111] Created mini XPath implementation, to simplify mapping logic --- nova/tests/test_minixpath.py | 141 +++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 nova/tests/test_minixpath.py diff --git a/nova/tests/test_minixpath.py b/nova/tests/test_minixpath.py new file mode 100644 index 00000000..7fddcf9e --- /dev/null +++ b/nova/tests/test_minixpath.py @@ -0,0 +1,141 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Justin Santa Barbara +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# 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 nova import test +from nova import utils +from nova import exception + + +class MiniXPathTestCase(test.TestCase): + def test_tolerates_nones(self): + xp = utils.minixpath_select + + input = [] + self.assertEquals([], xp(input, "a")) + self.assertEquals([], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = [None] + self.assertEquals([], xp(input, "a")) + self.assertEquals([], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = [{'a': None}] + self.assertEquals([], xp(input, "a")) + self.assertEquals([], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = [{'a': {'b': None}}] + self.assertEquals([{'b': None}], xp(input, "a")) + self.assertEquals([], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = [{'a': {'b': {'c': None}}}] + self.assertEquals([{'b': {'c': None}}], xp(input, "a")) + self.assertEquals([{'c': None}], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = [{'a': {'b': {'c': None}}}, {'a': None}] + self.assertEquals([{'b': {'c': None}}], xp(input, "a")) + self.assertEquals([{'c': None}], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = [{'a': {'b': {'c': None}}}, {'a': {'b': None}}] + self.assertEquals([{'b': {'c': None}}, {'b': None}], xp(input, "a")) + self.assertEquals([{'c': None}], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + def test_does_select(self): + xp = utils.minixpath_select + + input = [{'a': 'a_1'}] + self.assertEquals(['a_1'], xp(input, "a")) + self.assertEquals([], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = [{'a': {'b': 'b_1'}}] + self.assertEquals([{'b': 'b_1'}], xp(input, "a")) + self.assertEquals(['b_1'], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = [{'a': {'b': {'c': 'c_1'}}}] + self.assertEquals([{'b': {'c': 'c_1'}}], xp(input, "a")) + self.assertEquals([{'c': 'c_1'}], xp(input, "a/b")) + self.assertEquals(['c_1'], xp(input, "a/b/c")) + + input = [{'a': {'b': {'c': 'c_1'}}}, {'a': None}] + self.assertEquals([{'b': {'c': 'c_1'}}], + xp(input, "a")) + self.assertEquals([{'c': 'c_1'}], xp(input, "a/b")) + self.assertEquals(['c_1'], xp(input, "a/b/c")) + + input = [{'a': {'b': {'c': 'c_1'}}}, + {'a': {'b': None}}] + self.assertEquals([{'b': {'c': 'c_1'}}, {'b': None}], + xp(input, "a")) + self.assertEquals([{'c': 'c_1'}], xp(input, "a/b")) + self.assertEquals(['c_1'], xp(input, "a/b/c")) + + input = [{'a': {'b': {'c': 'c_1'}}}, + {'a': {'b': {'c': 'c_2'}}}] + self.assertEquals([{'b': {'c': 'c_1'}}, {'b': {'c': 'c_2'}}], + xp(input, "a")) + self.assertEquals([{'c': 'c_1'}, {'c': 'c_2'}], + xp(input, "a/b")) + self.assertEquals(['c_1', 'c_2'], xp(input, "a/b/c")) + + self.assertEquals([], xp(input, "a/b/c/d")) + self.assertEquals([], xp(input, "c/a/b/d")) + self.assertEquals([], xp(input, "i/r/t")) + + def test_flattens_lists(self): + xp = utils.minixpath_select + + input = [{'a': [1, 2, 3]}] + self.assertEquals([1, 2, 3], xp(input, "a")) + self.assertEquals([], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = [{'a': {'b': [1, 2, 3]}}] + self.assertEquals([{'b': [1, 2, 3]}], xp(input, "a")) + self.assertEquals([1, 2, 3], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = [{'a': {'b': [1, 2, 3]}}, {'a': {'b': [4, 5, 6]}}] + self.assertEquals([1, 2, 3, 4, 5, 6], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = [{'a': [{'b': [1, 2, 3]}, {'b': [4, 5, 6]}]}] + self.assertEquals([1, 2, 3, 4, 5, 6], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = [{'a': [1, 2, {'b': 'b_1'}]}] + self.assertEquals([1, 2, {'b': 'b_1'}], xp(input, "a")) + self.assertEquals(['b_1'], xp(input, "a/b")) + + def test_bad_xpath(self): + xp = utils.minixpath_select + + self.assertRaises(exception.Error, xp, [], None) + self.assertRaises(exception.Error, xp, [], "") + self.assertRaises(exception.Error, xp, [], "/") + self.assertRaises(exception.Error, xp, [], "/a") + self.assertRaises(exception.Error, xp, [], "/a/") + self.assertRaises(exception.Error, xp, [], "//") + self.assertRaises(exception.Error, xp, [], "//a") + self.assertRaises(exception.Error, xp, [], "a//a") + self.assertRaises(exception.Error, xp, [], "a//a/") + self.assertRaises(exception.Error, xp, [], "a/a/") From 4416c7f9e8b734be6dfee75bd32fffe53babb37a Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara <justin@fathomdb.com> Date: Wed, 23 Feb 2011 12:36:09 -0800 Subject: [PATCH 092/111] Cope when we pass a non-list to xpath_select - wrap it in a list --- nova/tests/test_minixpath.py | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/nova/tests/test_minixpath.py b/nova/tests/test_minixpath.py index 7fddcf9e..3b1bdf40 100644 --- a/nova/tests/test_minixpath.py +++ b/nova/tests/test_minixpath.py @@ -139,3 +139,41 @@ class MiniXPathTestCase(test.TestCase): self.assertRaises(exception.Error, xp, [], "a//a") self.assertRaises(exception.Error, xp, [], "a//a/") self.assertRaises(exception.Error, xp, [], "a/a/") + + def test_real_failure1(self): + # Real world failure case... + # We weren't coping when the input was a Dictionary instead of a List + # This led to test_accepts_dictionaries + xp = utils.minixpath_select + + inst = {'fixed_ip': {'floating_ips': [{'address': '1.2.3.4'}], + 'address': '192.168.0.3'}, + 'hostname': ''} + + private_ips = xp(inst, 'fixed_ip/address') + public_ips = xp(inst, 'fixed_ip/floating_ips/address') + self.assertEquals(['192.168.0.3'], private_ips) + self.assertEquals(['1.2.3.4'], public_ips) + + def test_accepts_dictionaries(self): + xp = utils.minixpath_select + + input = {'a': [1, 2, 3]} + self.assertEquals([1, 2, 3], xp(input, "a")) + self.assertEquals([], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = {'a': {'b': [1, 2, 3]}} + self.assertEquals([{'b': [1, 2, 3]}], xp(input, "a")) + self.assertEquals([1, 2, 3], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = {'a': [{'b': [1, 2, 3]}, {'b': [4, 5, 6]}]} + self.assertEquals([1, 2, 3, 4, 5, 6], xp(input, "a/b")) + self.assertEquals([], xp(input, "a/b/c")) + + input = {'a': [1, 2, {'b': 'b_1'}]} + self.assertEquals([1, 2, {'b': 'b_1'}], xp(input, "a")) + self.assertEquals(['b_1'], xp(input, "a/b")) + + From 8a0f7ed91761fb84c015ea4e61b9cccccdb9326e Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara <justin@fathomdb.com> Date: Wed, 23 Feb 2011 12:55:07 -0800 Subject: [PATCH 093/111] Fix pep8 violation (trailing whitespace) --- nova/tests/test_minixpath.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/nova/tests/test_minixpath.py b/nova/tests/test_minixpath.py index 3b1bdf40..cc4a35ef 100644 --- a/nova/tests/test_minixpath.py +++ b/nova/tests/test_minixpath.py @@ -175,5 +175,3 @@ class MiniXPathTestCase(test.TestCase): input = {'a': [1, 2, {'b': 'b_1'}]} self.assertEquals([1, 2, {'b': 'b_1'}], xp(input, "a")) self.assertEquals(['b_1'], xp(input, "a/b")) - - From d6b35abc39171690e9adedc22c186ed80d8d854c Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara <justin@fathomdb.com> Date: Wed, 23 Feb 2011 14:07:08 -0800 Subject: [PATCH 094/111] Rename minixpath_select to get_from_path --- nova/tests/test_minixpath.py | 177 ----------------------------------- 1 file changed, 177 deletions(-) delete mode 100644 nova/tests/test_minixpath.py diff --git a/nova/tests/test_minixpath.py b/nova/tests/test_minixpath.py deleted file mode 100644 index cc4a35ef..00000000 --- a/nova/tests/test_minixpath.py +++ /dev/null @@ -1,177 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2011 Justin Santa Barbara -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# 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 nova import test -from nova import utils -from nova import exception - - -class MiniXPathTestCase(test.TestCase): - def test_tolerates_nones(self): - xp = utils.minixpath_select - - input = [] - self.assertEquals([], xp(input, "a")) - self.assertEquals([], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = [None] - self.assertEquals([], xp(input, "a")) - self.assertEquals([], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = [{'a': None}] - self.assertEquals([], xp(input, "a")) - self.assertEquals([], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = [{'a': {'b': None}}] - self.assertEquals([{'b': None}], xp(input, "a")) - self.assertEquals([], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = [{'a': {'b': {'c': None}}}] - self.assertEquals([{'b': {'c': None}}], xp(input, "a")) - self.assertEquals([{'c': None}], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = [{'a': {'b': {'c': None}}}, {'a': None}] - self.assertEquals([{'b': {'c': None}}], xp(input, "a")) - self.assertEquals([{'c': None}], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = [{'a': {'b': {'c': None}}}, {'a': {'b': None}}] - self.assertEquals([{'b': {'c': None}}, {'b': None}], xp(input, "a")) - self.assertEquals([{'c': None}], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - def test_does_select(self): - xp = utils.minixpath_select - - input = [{'a': 'a_1'}] - self.assertEquals(['a_1'], xp(input, "a")) - self.assertEquals([], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = [{'a': {'b': 'b_1'}}] - self.assertEquals([{'b': 'b_1'}], xp(input, "a")) - self.assertEquals(['b_1'], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = [{'a': {'b': {'c': 'c_1'}}}] - self.assertEquals([{'b': {'c': 'c_1'}}], xp(input, "a")) - self.assertEquals([{'c': 'c_1'}], xp(input, "a/b")) - self.assertEquals(['c_1'], xp(input, "a/b/c")) - - input = [{'a': {'b': {'c': 'c_1'}}}, {'a': None}] - self.assertEquals([{'b': {'c': 'c_1'}}], - xp(input, "a")) - self.assertEquals([{'c': 'c_1'}], xp(input, "a/b")) - self.assertEquals(['c_1'], xp(input, "a/b/c")) - - input = [{'a': {'b': {'c': 'c_1'}}}, - {'a': {'b': None}}] - self.assertEquals([{'b': {'c': 'c_1'}}, {'b': None}], - xp(input, "a")) - self.assertEquals([{'c': 'c_1'}], xp(input, "a/b")) - self.assertEquals(['c_1'], xp(input, "a/b/c")) - - input = [{'a': {'b': {'c': 'c_1'}}}, - {'a': {'b': {'c': 'c_2'}}}] - self.assertEquals([{'b': {'c': 'c_1'}}, {'b': {'c': 'c_2'}}], - xp(input, "a")) - self.assertEquals([{'c': 'c_1'}, {'c': 'c_2'}], - xp(input, "a/b")) - self.assertEquals(['c_1', 'c_2'], xp(input, "a/b/c")) - - self.assertEquals([], xp(input, "a/b/c/d")) - self.assertEquals([], xp(input, "c/a/b/d")) - self.assertEquals([], xp(input, "i/r/t")) - - def test_flattens_lists(self): - xp = utils.minixpath_select - - input = [{'a': [1, 2, 3]}] - self.assertEquals([1, 2, 3], xp(input, "a")) - self.assertEquals([], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = [{'a': {'b': [1, 2, 3]}}] - self.assertEquals([{'b': [1, 2, 3]}], xp(input, "a")) - self.assertEquals([1, 2, 3], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = [{'a': {'b': [1, 2, 3]}}, {'a': {'b': [4, 5, 6]}}] - self.assertEquals([1, 2, 3, 4, 5, 6], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = [{'a': [{'b': [1, 2, 3]}, {'b': [4, 5, 6]}]}] - self.assertEquals([1, 2, 3, 4, 5, 6], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = [{'a': [1, 2, {'b': 'b_1'}]}] - self.assertEquals([1, 2, {'b': 'b_1'}], xp(input, "a")) - self.assertEquals(['b_1'], xp(input, "a/b")) - - def test_bad_xpath(self): - xp = utils.minixpath_select - - self.assertRaises(exception.Error, xp, [], None) - self.assertRaises(exception.Error, xp, [], "") - self.assertRaises(exception.Error, xp, [], "/") - self.assertRaises(exception.Error, xp, [], "/a") - self.assertRaises(exception.Error, xp, [], "/a/") - self.assertRaises(exception.Error, xp, [], "//") - self.assertRaises(exception.Error, xp, [], "//a") - self.assertRaises(exception.Error, xp, [], "a//a") - self.assertRaises(exception.Error, xp, [], "a//a/") - self.assertRaises(exception.Error, xp, [], "a/a/") - - def test_real_failure1(self): - # Real world failure case... - # We weren't coping when the input was a Dictionary instead of a List - # This led to test_accepts_dictionaries - xp = utils.minixpath_select - - inst = {'fixed_ip': {'floating_ips': [{'address': '1.2.3.4'}], - 'address': '192.168.0.3'}, - 'hostname': ''} - - private_ips = xp(inst, 'fixed_ip/address') - public_ips = xp(inst, 'fixed_ip/floating_ips/address') - self.assertEquals(['192.168.0.3'], private_ips) - self.assertEquals(['1.2.3.4'], public_ips) - - def test_accepts_dictionaries(self): - xp = utils.minixpath_select - - input = {'a': [1, 2, 3]} - self.assertEquals([1, 2, 3], xp(input, "a")) - self.assertEquals([], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = {'a': {'b': [1, 2, 3]}} - self.assertEquals([{'b': [1, 2, 3]}], xp(input, "a")) - self.assertEquals([1, 2, 3], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = {'a': [{'b': [1, 2, 3]}, {'b': [4, 5, 6]}]} - self.assertEquals([1, 2, 3, 4, 5, 6], xp(input, "a/b")) - self.assertEquals([], xp(input, "a/b/c")) - - input = {'a': [1, 2, {'b': 'b_1'}]} - self.assertEquals([1, 2, {'b': 'b_1'}], xp(input, "a")) - self.assertEquals(['b_1'], xp(input, "a/b")) From d7ffd5f157d620f742455f6b2c389d7c136b2d0f Mon Sep 17 00:00:00 2001 From: termie <github@anarkystic.com> Date: Wed, 23 Feb 2011 15:14:16 -0800 Subject: [PATCH 095/111] updates to nova.flags to get help working better Fixes some old bugs that were brought up on the mailing list. First step towards moving flags into the places where they belong. Also moves manager import into service's init so that we can get all the dynamically loaded flags shortly after loading. --- nova/flags.py | 49 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/nova/flags.py b/nova/flags.py index f64a62da..24bca0ca 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -160,9 +160,45 @@ class StrWrapper(object): raise KeyError(name) -FLAGS = FlagValues() -gflags.FLAGS = FLAGS -gflags.DEFINE_flag(gflags.HelpFlag(), FLAGS) +# Copied from gflags with small mods to get the naming correct. +# Originally gflags checks for the first module that is not gflags that is +# in the call chain, we want to check for the first module that is not gflags +# and not this module. +def _GetCallingModule(): + """Returns the name of the module that's calling into this module. + + We generally use this function to get the name of the module calling a + DEFINE_foo... function. + """ + # Walk down the stack to find the first globals dict that's not ours. + for depth in range(1, sys.getrecursionlimit()): + if not sys._getframe(depth).f_globals is globals(): + module_name = __GetModuleName(sys._getframe(depth).f_globals) + if module_name == 'gflags': + continue + if module_name is not None: + return module_name + raise AssertionError("No module was found") + + +# Copied from gflags because it is a private function +def __GetModuleName(globals_dict): + """Given a globals dict, returns the name of the module that defines it. + + Args: + globals_dict: A dictionary that should correspond to an environment + providing the values of the globals. + + Returns: + A string (the name of the module) or None (if the module could not + be identified. + """ + for name, module in sys.modules.iteritems(): + if getattr(module, '__dict__', None) is globals_dict: + if name == '__main__': + return sys.argv[0] + return name + return None def _wrapper(func): @@ -173,6 +209,11 @@ def _wrapper(func): return _wrapped +FLAGS = FlagValues() +gflags.FLAGS = FLAGS +gflags._GetCallingModule = _GetCallingModule + + DEFINE = _wrapper(gflags.DEFINE) DEFINE_string = _wrapper(gflags.DEFINE_string) DEFINE_integer = _wrapper(gflags.DEFINE_integer) @@ -185,8 +226,6 @@ DEFINE_spaceseplist = _wrapper(gflags.DEFINE_spaceseplist) DEFINE_multistring = _wrapper(gflags.DEFINE_multistring) DEFINE_multi_int = _wrapper(gflags.DEFINE_multi_int) DEFINE_flag = _wrapper(gflags.DEFINE_flag) - - HelpFlag = gflags.HelpFlag HelpshortFlag = gflags.HelpshortFlag HelpXMLFlag = gflags.HelpXMLFlag From e919d896ea5c8e6d2e03673e9945efe192dd34ca Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Wed, 23 Feb 2011 15:16:56 -0800 Subject: [PATCH 096/111] remove processName from debug output since we aren't using multiprocessing and it doesn't exist in python 2.6.1 --- nova/log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/log.py b/nova/log.py index 10c14d74..7866c34f 100644 --- a/nova/log.py +++ b/nova/log.py @@ -54,7 +54,7 @@ flags.DEFINE_string('logging_default_format_string', 'format string to use for log messages without context') flags.DEFINE_string('logging_debug_format_suffix', - 'from %(processName)s (pid=%(process)d) %(funcName)s' + 'from (pid=%(process)d) %(funcName)s' ' %(pathname)s:%(lineno)d', 'data to append to log format when level is DEBUG') From 18f2d270fb9665f15dd4ced774467d342dc110ac Mon Sep 17 00:00:00 2001 From: termie <github@anarkystic.com> Date: Wed, 23 Feb 2011 15:26:52 -0800 Subject: [PATCH 097/111] add help back to the scripts that don't use service.py --- bin/nova-ajax-console-proxy | 4 +++- bin/nova-api | 3 +++ bin/nova-direct-api | 4 ++++ bin/nova-manage | 3 +++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/bin/nova-ajax-console-proxy b/bin/nova-ajax-console-proxy index 392b328b..1e11c6d5 100755 --- a/bin/nova-ajax-console-proxy +++ b/bin/nova-ajax-console-proxy @@ -47,9 +47,11 @@ from nova import utils from nova import wsgi FLAGS = flags.FLAGS - flags.DEFINE_integer('ajax_console_idle_timeout', 300, 'Seconds before idle connection destroyed') +flags.DEFINE_flag(flags.HelpFlag()) +flags.DEFINE_flag(flags.HelpshortFlag()) +flags.DEFINE_flag(flags.HelpXMLFlag()) LOG = logging.getLogger('nova.ajax_console_proxy') LOG.setLevel(logging.DEBUG) diff --git a/bin/nova-api b/bin/nova-api index d5efb468..cf140570 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -48,6 +48,9 @@ flags.DEFINE_integer('ec2_listen_port', 8773, 'port for ec2 api to listen') flags.DEFINE_string('osapi_listen', "0.0.0.0", 'IP address for OpenStack API to listen') flags.DEFINE_integer('osapi_listen_port', 8774, 'port for os api to listen') +flags.DEFINE_flag(flags.HelpFlag()) +flags.DEFINE_flag(flags.HelpshortFlag()) +flags.DEFINE_flag(flags.HelpXMLFlag()) API_ENDPOINTS = ['ec2', 'osapi'] diff --git a/bin/nova-direct-api b/bin/nova-direct-api index 6c63bd26..bf29d9a5 100755 --- a/bin/nova-direct-api +++ b/bin/nova-direct-api @@ -45,6 +45,10 @@ from nova.compute import api as compute_api FLAGS = flags.FLAGS flags.DEFINE_integer('direct_port', 8001, 'Direct API port') flags.DEFINE_string('direct_host', '0.0.0.0', 'Direct API host') +flags.DEFINE_flag(flags.HelpFlag()) +flags.DEFINE_flag(flags.HelpshortFlag()) +flags.DEFINE_flag(flags.HelpXMLFlag()) + if __name__ == '__main__': utils.default_flagfile() diff --git a/bin/nova-manage b/bin/nova-manage index 5189de0e..b603c8b0 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -93,6 +93,9 @@ flags.DECLARE('network_size', 'nova.network.manager') flags.DECLARE('vlan_start', 'nova.network.manager') flags.DECLARE('vpn_start', 'nova.network.manager') flags.DECLARE('fixed_range_v6', 'nova.network.manager') +flags.DEFINE_flag(flags.HelpFlag()) +flags.DEFINE_flag(flags.HelpshortFlag()) +flags.DEFINE_flag(flags.HelpXMLFlag()) def param2id(object_id): From 8430f45c3bf2c998455c188f58634add6ee079e1 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Wed, 23 Feb 2011 15:29:02 -0800 Subject: [PATCH 098/111] revert logfile redirection and make colors work by temporarily switching stdout --- nova/tests/fake_flags.py | 1 - run_tests.py | 16 +++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/nova/tests/fake_flags.py b/nova/tests/fake_flags.py index 575fefff..2b191940 100644 --- a/nova/tests/fake_flags.py +++ b/nova/tests/fake_flags.py @@ -41,4 +41,3 @@ FLAGS.iscsi_num_targets = 8 FLAGS.verbose = True FLAGS.sql_connection = 'sqlite:///tests.sqlite' FLAGS.use_ipv6 = True -FLAGS.logfile = 'tests.log' diff --git a/run_tests.py b/run_tests.py index 877849ab..2c04a064 100644 --- a/run_tests.py +++ b/run_tests.py @@ -97,7 +97,7 @@ class _AnsiColorizer(object): try: return curses.tigetnum("colors") > 2 except curses.error: - curses.setupterm(fd=stream.fileno()) + curses.setupterm() return curses.tigetnum("colors") > 2 except: raise @@ -122,13 +122,13 @@ class _Win32Colorizer(object): See _AnsiColorizer docstring. """ def __init__(self, stream): - from win32console import GetStdHandle, STD_ERROR_HANDLE, \ + from win32console import GetStdHandle, STD_OUT_HANDLE, \ FOREGROUND_RED, FOREGROUND_BLUE, FOREGROUND_GREEN, \ FOREGROUND_INTENSITY red, green, blue, bold = (FOREGROUND_RED, FOREGROUND_GREEN, FOREGROUND_BLUE, FOREGROUND_INTENSITY) self.stream = stream - self.screenBuffer = GetStdHandle(STD_ERROR_HANDLE) + self.screenBuffer = GetStdHandle(STD_OUT_HANDLE) self._colors = { 'normal': red | green | blue, 'red': red | bold, @@ -144,7 +144,7 @@ class _Win32Colorizer(object): try: import win32console screenBuffer = win32console.GetStdHandle( - win32console.STD_ERROR_HANDLE) + win32console.STD_OUT_HANDLE) except ImportError: return False import pywintypes @@ -185,12 +185,14 @@ class NovaTestResult(result.TextTestResult): result.TextTestResult.__init__(self, *args, **kw) self._last_case = None self.colorizer = None + # NOTE(vish): reset stdout for the terminal check + stdout = sys.stdout + sys.stdout = sys.__stdout__ for colorizer in [_Win32Colorizer, _AnsiColorizer, _NullColorizer]: - # NOTE(vish): nose does funky stuff with stdout, so use stderr - # to setup the colorizer - if colorizer.supported(sys.stderr): + if colorizer.supported(): self.colorizer = colorizer(self.stream) break + sys.stdout = stdout def getDescription(self, test): return str(test) From d4e99b60bb46f92abf135787ab3b5cb31989af29 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Wed, 23 Feb 2011 15:35:30 -0800 Subject: [PATCH 099/111] fix pep8 --- run_tests.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/run_tests.py b/run_tests.py index 2c04a064..eef0120b 100644 --- a/run_tests.py +++ b/run_tests.py @@ -87,7 +87,7 @@ class _AnsiColorizer(object): coloring terminal output using this method. Returns False otherwise. """ if not stream.isatty(): - return False # auto color only on TTYs + return False # auto color only on TTYs try: import curses except ImportError: @@ -180,6 +180,7 @@ class _NullColorizer(object): def write(self, text, color): self.stream.write(text) + class NovaTestResult(result.TextTestResult): def __init__(self, *args, **kw): result.TextTestResult.__init__(self, *args, **kw) @@ -276,7 +277,7 @@ class NovaTestRunner(core.TextTestRunner): if __name__ == '__main__': logging.setup() - testdir = os.path.abspath(os.path.join("nova","tests")) + testdir = os.path.abspath(os.path.join("nova", "tests")) testdb = os.path.join(testdir, "tests.sqlite") if os.path.exists(testdb): os.unlink(testdb) From 96b555773c21c8acac41e512cdbcade434687620 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Wed, 23 Feb 2011 15:42:59 -0800 Subject: [PATCH 100/111] added comments about where code came from --- run_tests.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/run_tests.py b/run_tests.py index eef0120b..8025548e 100644 --- a/run_tests.py +++ b/run_tests.py @@ -198,6 +198,7 @@ class NovaTestResult(result.TextTestResult): def getDescription(self, test): return str(test) + # NOTE(vish): copied from unittest with edit to add color def addSuccess(self, test): unittest.TestResult.addSuccess(self, test) if self.showAll: @@ -207,6 +208,7 @@ class NovaTestResult(result.TextTestResult): self.stream.write('.') self.stream.flush() + # NOTE(vish): copied from unittest with edit to add color def addFailure(self, test, err): unittest.TestResult.addFailure(self, test, err) if self.showAll: @@ -216,6 +218,7 @@ class NovaTestResult(result.TextTestResult): self.stream.write('F') self.stream.flush() + # NOTE(vish): copied from nose with edit to add color def addError(self, test, err): """Overrides normal addError to add support for errorClasses. If the exception is a registered class, the From 28eedfe8c84d56a04e423f67e6ee317fc07c5288 Mon Sep 17 00:00:00 2001 From: Thierry Carrez <thierry@openstack.org> Date: Thu, 24 Feb 2011 15:19:29 +0100 Subject: [PATCH 102/111] Globally exclude .pyc files from tarball contents --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index f0a9cffb..2ceed34f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -38,3 +38,4 @@ include nova/tests/db/nova.austin.sqlite include plugins/xenapi/README include plugins/xenapi/etc/xapi.d/plugins/objectstore include plugins/xenapi/etc/xapi.d/plugins/pluginlib_nova.py +global-exclude *.pyc From 45a619ab0cd3cea0e7182de9929b289e76c5066b Mon Sep 17 00:00:00 2001 From: Salvatore Orlando <salvatore.orlando@eu.citrix.com> Date: Thu, 24 Feb 2011 16:04:13 +0000 Subject: [PATCH 103/111] stubbing out _is_vdi_pv for test purposes --- nova/tests/test_xenapi.py | 1 + nova/tests/xenapi/stubs.py | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 6b8efc9d..2cbe58aa 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -167,6 +167,7 @@ class XenAPIVMTestCase(test.TestCase): stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests) stubs.stubout_get_this_vm_uuid(self.stubs) stubs.stubout_stream_disk(self.stubs) + stubs.stubout_is_vdi_pv(self.stubs) self.stubs.Set(VMOps, 'reset_network', reset_network) glance_stubs.stubout_glance_client(self.stubs, glance_stubs.FakeGlance) diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py index 624995ad..4fec2bd7 100644 --- a/nova/tests/xenapi/stubs.py +++ b/nova/tests/xenapi/stubs.py @@ -130,6 +130,12 @@ def stubout_stream_disk(stubs): stubs.Set(vm_utils, '_stream_disk', f) +def stubout_is_vdi_pv(stubs): + def f(_1): + return False + stubs.Set(vm_utils, '_is_vdi_pv', f) + + class FakeSessionForVMTests(fake.SessionBase): """ Stubs out a XenAPISession for VM tests """ def __init__(self, uri): From 1c7939aa3584de3c791eda4c470ad4bbdaa742ae Mon Sep 17 00:00:00 2001 From: Todd Willey <todd@ansolabs.com> Date: Thu, 24 Feb 2011 14:36:15 -0500 Subject: [PATCH 104/111] Fix copypasta pep8 violation. --- nova/adminclient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/adminclient.py b/nova/adminclient.py index fe2aca35..fc3c5c5f 100644 --- a/nova/adminclient.py +++ b/nova/adminclient.py @@ -198,7 +198,7 @@ class HostInfo(object): class Vpn(object): """ Information about a Vpn, as parsed through SAX - + **Fields Include** * instance_id From 375d66a806f344326a3594b7e4671f3cc4ecb340 Mon Sep 17 00:00:00 2001 From: Christian Berendt <berendt@b1-systems.de> Date: Fri, 25 Feb 2011 19:59:26 +0100 Subject: [PATCH 105/111] check if QUERY_STRING is empty or not before building the request URL --- bin/nova-ajax-console-proxy | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/bin/nova-ajax-console-proxy b/bin/nova-ajax-console-proxy index 1e11c6d5..023e4023 100755 --- a/bin/nova-ajax-console-proxy +++ b/bin/nova-ajax-console-proxy @@ -63,10 +63,16 @@ class AjaxConsoleProxy(object): def __call__(self, env, start_response): try: - req_url = '%s://%s%s?%s' % (env['wsgi.url_scheme'], - env['HTTP_HOST'], - env['PATH_INFO'], - env['QUERY_STRING']) + if env.has_key('QUERY_STRING'): + req_url = '%s://%s%s?%s' % (env['wsgi.url_scheme'], + env['HTTP_HOST'], + env['PATH_INFO'], + env['QUERY_STRING']) + else: + req_url = '%s://%s%s' % (env['wsgi.url_scheme'], + env['HTTP_HOST'], + env['PATH_INFO']) + if 'HTTP_REFERER' in env: auth_url = env['HTTP_REFERER'] else: From f9e68d68a5e355668e87ae18d7326758c3534803 Mon Sep 17 00:00:00 2001 From: "Kevin L. Mitchell" <kevin.mitchell@rackspace.com> Date: Fri, 18 Mar 2011 02:09:46 +0000 Subject: [PATCH 106/111] Copy over to current trunk my tests, the 401/500 fix, and a couple of fixes to the committed fix which was actually brittle around the edges... --- Authors | 1 + 1 file changed, 1 insertion(+) diff --git a/Authors b/Authors index 494e614a..a3c06dcf 100644 --- a/Authors +++ b/Authors @@ -36,6 +36,7 @@ Joshua McKenty <jmckenty@gmail.com> Justin Santa Barbara <justin@fathomdb.com> Kei Masumoto <masumotok@nttdata.co.jp> Ken Pepple <ken.pepple@gmail.com> +Kevin L. Mitchell <kevin.mitchell@rackspace.com> Koji Iida <iida.koji@lab.ntt.co.jp> Lorin Hochstein <lorin@isi.edu> Matt Dietz <matt.dietz@rackspace.com> From 5d64f1974f778669fc398f56edb6fff5189801fd Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya <vishvananda@gmail.com> Date: Fri, 25 Feb 2011 12:16:58 -0800 Subject: [PATCH 107/111] use default flagfile in nova-api --- bin/nova-api | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/nova-api b/bin/nova-api index cf140570..14be4b84 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -36,6 +36,7 @@ gettext.install('nova', unicode=1) from nova import flags from nova import log as logging +from nova import utils from nova import version from nova import wsgi @@ -80,6 +81,7 @@ def run_app(paste_config_file): if __name__ == '__main__': + utils.default_flagfile() FLAGS(sys.argv) logging.setup() LOG.audit(_("Starting nova-api node (version %s)"), From 49ee077a20bf9b4104ef1671178a5a2a3d7e2ccc Mon Sep 17 00:00:00 2001 From: Christian Berendt <berendt@b1-systems.de> Date: Fri, 25 Feb 2011 22:15:51 +0100 Subject: [PATCH 108/111] fixed: bin/nova-ajax-console-proxy:66:19: W601 .has_key() is deprecated, use 'in' --- bin/nova-ajax-console-proxy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nova-ajax-console-proxy b/bin/nova-ajax-console-proxy index 023e4023..bbd60bad 100755 --- a/bin/nova-ajax-console-proxy +++ b/bin/nova-ajax-console-proxy @@ -63,7 +63,7 @@ class AjaxConsoleProxy(object): def __call__(self, env, start_response): try: - if env.has_key('QUERY_STRING'): + if 'QUERY_STRING' in env: req_url = '%s://%s%s?%s' % (env['wsgi.url_scheme'], env['HTTP_HOST'], env['PATH_INFO'], From f446f643360298881536c67f5ba59201794d3f00 Mon Sep 17 00:00:00 2001 From: "Kevin L. Mitchell" <kevin.mitchell@rackspace.com> Date: Sun, 20 Mar 2011 22:58:49 +0000 Subject: [PATCH 109/111] No reason to dump a stack trace just because we can't reach the AMQP servire; it ends up being just noise --- nova/rpc.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nova/rpc.py b/nova/rpc.py index 205bb524..089bf99c 100644 --- a/nova/rpc.py +++ b/nova/rpc.py @@ -95,14 +95,14 @@ class Consumer(messaging.Consumer): fl_host = FLAGS.rabbit_host fl_port = FLAGS.rabbit_port fl_intv = FLAGS.rabbit_retry_interval - LOG.exception(_("AMQP server on %(fl_host)s:%(fl_port)d is" + LOG.error(_("AMQP server on %(fl_host)s:%(fl_port)d is" " unreachable. Trying again in %(fl_intv)d seconds.") % locals()) self.failed_connection = True if self.failed_connection: - LOG.exception(_("Unable to connect to AMQP server " - "after %d tries. Shutting down."), - FLAGS.rabbit_max_retries) + LOG.error(_("Unable to connect to AMQP server " + "after %d tries. Shutting down."), + FLAGS.rabbit_max_retries) sys.exit(1) def fetch(self, no_ack=None, auto_ack=None, enable_callbacks=False): From 044c5e9f40cceecf46ac63e6912b4e3f577fafd3 Mon Sep 17 00:00:00 2001 From: "Kevin L. Mitchell" <kevin.mitchell@rackspace.com> Date: Fri, 25 Mar 2011 05:30:36 +0000 Subject: [PATCH 110/111] Add error message to the error report so we know why the AMQP server is unreachable --- nova/rpc.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nova/rpc.py b/nova/rpc.py index 089bf99c..8fe4565d 100644 --- a/nova/rpc.py +++ b/nova/rpc.py @@ -91,12 +91,13 @@ class Consumer(messaging.Consumer): super(Consumer, self).__init__(*args, **kwargs) self.failed_connection = False break - except: # Catching all because carrot sucks + except Exception as e: # Catching all because carrot sucks fl_host = FLAGS.rabbit_host fl_port = FLAGS.rabbit_port fl_intv = FLAGS.rabbit_retry_interval LOG.error(_("AMQP server on %(fl_host)s:%(fl_port)d is" - " unreachable. Trying again in %(fl_intv)d seconds.") + " unreachable: %(e)s. Trying again in %(fl_intv)d" + " seconds.") % locals()) self.failed_connection = True if self.failed_connection: From c341828a3b126357b935aeca413e97095723dc99 Mon Sep 17 00:00:00 2001 From: Anne Gentle <anne@openstack.org> Date: Sat, 26 Feb 2011 11:13:32 -0600 Subject: [PATCH 111/111] Deleting test dir from a pull from trunk --- test/.Python | 1 - test/bin/activate | 76 - test/bin/activate.csh | 32 - test/bin/activate.fish | 79 - test/bin/activate_this.py | 32 - test/bin/easy_install | 9 - test/bin/easy_install-2.6 | 9 - test/bin/pip | 9 - test/bin/pip-2.6 | 9 - test/bin/python | Bin 50720 -> 0 bytes test/bin/python2.6 | 1 - test/include/python2.6 | 1 - test/lib/python2.6/UserDict.py | 1 - test/lib/python2.6/_abcoll.py | 1 - test/lib/python2.6/abc.py | 1 - test/lib/python2.6/codecs.py | 1 - test/lib/python2.6/config | 1 - test/lib/python2.6/copy_reg.py | 1 - test/lib/python2.6/distutils/__init__.py | 91 -- test/lib/python2.6/distutils/distutils.cfg | 6 - test/lib/python2.6/encodings | 1 - test/lib/python2.6/fnmatch.py | 1 - test/lib/python2.6/genericpath.py | 1 - test/lib/python2.6/lib-dynload | 1 - test/lib/python2.6/linecache.py | 1 - test/lib/python2.6/locale.py | 1 - test/lib/python2.6/ntpath.py | 1 - test/lib/python2.6/orig-prefix.txt | 1 - test/lib/python2.6/os.py | 1 - test/lib/python2.6/posixpath.py | 1 - test/lib/python2.6/re.py | 1 - .../python2.6/site-packages/easy-install.pth | 4 - .../pip-0.8.1-py2.6.egg/EGG-INFO/PKG-INFO | 348 ---- .../pip-0.8.1-py2.6.egg/EGG-INFO/SOURCES.txt | 57 - .../EGG-INFO/dependency_links.txt | 1 - .../EGG-INFO/entry_points.txt | 4 - .../pip-0.8.1-py2.6.egg/EGG-INFO/not-zip-safe | 1 - .../EGG-INFO/top_level.txt | 1 - .../pip-0.8.1-py2.6.egg/pip/__init__.py | 261 --- .../pip-0.8.1-py2.6.egg/pip/_pkgutil.py | 589 ------- .../pip-0.8.1-py2.6.egg/pip/backwardcompat.py | 55 - .../pip-0.8.1-py2.6.egg/pip/basecommand.py | 203 --- .../pip-0.8.1-py2.6.egg/pip/baseparser.py | 231 --- .../pip/commands/__init__.py | 1 - .../pip/commands/bundle.py | 33 - .../pip/commands/completion.py | 60 - .../pip/commands/freeze.py | 109 -- .../pip-0.8.1-py2.6.egg/pip/commands/help.py | 32 - .../pip/commands/install.py | 247 --- .../pip/commands/search.py | 116 -- .../pip/commands/uninstall.py | 42 - .../pip-0.8.1-py2.6.egg/pip/commands/unzip.py | 9 - .../pip-0.8.1-py2.6.egg/pip/commands/zip.py | 346 ---- .../pip-0.8.1-py2.6.egg/pip/download.py | 470 ------ .../pip-0.8.1-py2.6.egg/pip/exceptions.py | 17 - .../pip-0.8.1-py2.6.egg/pip/index.py | 686 -------- .../pip-0.8.1-py2.6.egg/pip/locations.py | 45 - .../pip-0.8.1-py2.6.egg/pip/log.py | 181 --- .../pip-0.8.1-py2.6.egg/pip/req.py | 1432 ----------------- .../pip-0.8.1-py2.6.egg/pip/runner.py | 18 - .../pip-0.8.1-py2.6.egg/pip/util.py | 479 ------ .../pip-0.8.1-py2.6.egg/pip/vcs/__init__.py | 238 --- .../pip-0.8.1-py2.6.egg/pip/vcs/bazaar.py | 138 -- .../pip-0.8.1-py2.6.egg/pip/vcs/git.py | 204 --- .../pip-0.8.1-py2.6.egg/pip/vcs/mercurial.py | 162 -- .../pip-0.8.1-py2.6.egg/pip/vcs/subversion.py | 260 --- .../pip-0.8.1-py2.6.egg/pip/venv.py | 53 - .../site-packages/setuptools-0.6c11-py2.6.egg | Bin 333447 -> 0 bytes .../python2.6/site-packages/setuptools.pth | 1 - test/lib/python2.6/site.py | 713 -------- test/lib/python2.6/sre.py | 1 - test/lib/python2.6/sre_compile.py | 1 - test/lib/python2.6/sre_constants.py | 1 - test/lib/python2.6/sre_parse.py | 1 - test/lib/python2.6/stat.py | 1 - test/lib/python2.6/types.py | 1 - test/lib/python2.6/warnings.py | 1 - 77 files changed, 8226 deletions(-) delete mode 120000 test/.Python delete mode 100644 test/bin/activate delete mode 100644 test/bin/activate.csh delete mode 100644 test/bin/activate.fish delete mode 100644 test/bin/activate_this.py delete mode 100755 test/bin/easy_install delete mode 100755 test/bin/easy_install-2.6 delete mode 100755 test/bin/pip delete mode 100755 test/bin/pip-2.6 delete mode 100755 test/bin/python delete mode 120000 test/bin/python2.6 delete mode 120000 test/include/python2.6 delete mode 120000 test/lib/python2.6/UserDict.py delete mode 120000 test/lib/python2.6/_abcoll.py delete mode 120000 test/lib/python2.6/abc.py delete mode 120000 test/lib/python2.6/codecs.py delete mode 120000 test/lib/python2.6/config delete mode 120000 test/lib/python2.6/copy_reg.py delete mode 100644 test/lib/python2.6/distutils/__init__.py delete mode 100644 test/lib/python2.6/distutils/distutils.cfg delete mode 120000 test/lib/python2.6/encodings delete mode 120000 test/lib/python2.6/fnmatch.py delete mode 120000 test/lib/python2.6/genericpath.py delete mode 120000 test/lib/python2.6/lib-dynload delete mode 120000 test/lib/python2.6/linecache.py delete mode 120000 test/lib/python2.6/locale.py delete mode 120000 test/lib/python2.6/ntpath.py delete mode 100644 test/lib/python2.6/orig-prefix.txt delete mode 120000 test/lib/python2.6/os.py delete mode 120000 test/lib/python2.6/posixpath.py delete mode 120000 test/lib/python2.6/re.py delete mode 100644 test/lib/python2.6/site-packages/easy-install.pth delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/PKG-INFO delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/SOURCES.txt delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/dependency_links.txt delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/entry_points.txt delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/not-zip-safe delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/top_level.txt delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/__init__.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/_pkgutil.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/backwardcompat.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/basecommand.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/baseparser.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/__init__.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/bundle.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/completion.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/freeze.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/help.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/install.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/search.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/uninstall.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/unzip.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/zip.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/download.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/exceptions.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/index.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/locations.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/log.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/req.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/runner.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/util.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/__init__.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/bazaar.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/git.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/mercurial.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/subversion.py delete mode 100644 test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/venv.py delete mode 100644 test/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg delete mode 100644 test/lib/python2.6/site-packages/setuptools.pth delete mode 100644 test/lib/python2.6/site.py delete mode 120000 test/lib/python2.6/sre.py delete mode 120000 test/lib/python2.6/sre_compile.py delete mode 120000 test/lib/python2.6/sre_constants.py delete mode 120000 test/lib/python2.6/sre_parse.py delete mode 120000 test/lib/python2.6/stat.py delete mode 120000 test/lib/python2.6/types.py delete mode 120000 test/lib/python2.6/warnings.py diff --git a/test/.Python b/test/.Python deleted file mode 120000 index 6cce156b..00000000 --- a/test/.Python +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/Python \ No newline at end of file diff --git a/test/bin/activate b/test/bin/activate deleted file mode 100644 index 588b5410..00000000 --- a/test/bin/activate +++ /dev/null @@ -1,76 +0,0 @@ -# This file must be used with "source bin/activate" *from bash* -# you cannot run it directly - -deactivate () { - # reset old environment variables - if [ -n "$_OLD_VIRTUAL_PATH" ] ; then - PATH="$_OLD_VIRTUAL_PATH" - export PATH - unset _OLD_VIRTUAL_PATH - fi - if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then - PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME" - export PYTHONHOME - unset _OLD_VIRTUAL_PYTHONHOME - fi - - # This should detect bash and zsh, which have a hash command that must - # be called to get it to forget past commands. Without forgetting - # past commands the $PATH changes we made may not be respected - if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then - hash -r - fi - - if [ -n "$_OLD_VIRTUAL_PS1" ] ; then - PS1="$_OLD_VIRTUAL_PS1" - export PS1 - unset _OLD_VIRTUAL_PS1 - fi - - unset VIRTUAL_ENV - if [ ! "$1" = "nondestructive" ] ; then - # Self destruct! - unset -f deactivate - fi -} - -# unset irrelavent variables -deactivate nondestructive - -VIRTUAL_ENV="/Users/anne.gentle/src/nova/docslice/test" -export VIRTUAL_ENV - -_OLD_VIRTUAL_PATH="$PATH" -PATH="$VIRTUAL_ENV/bin:$PATH" -export PATH - -# unset PYTHONHOME if set -# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) -# could use `if (set -u; : $PYTHONHOME) ;` in bash -if [ -n "$PYTHONHOME" ] ; then - _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME" - unset PYTHONHOME -fi - -if [ -z "$VIRTUAL_ENV_DISABLE_PROMPT" ] ; then - _OLD_VIRTUAL_PS1="$PS1" - if [ "x" != x ] ; then - PS1="$PS1" - else - if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then - # special case for Aspen magic directories - # see http://www.zetadev.com/software/aspen/ - PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" - else - PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" - fi - fi - export PS1 -fi - -# This should detect bash and zsh, which have a hash command that must -# be called to get it to forget past commands. Without forgetting -# past commands the $PATH changes we made may not be respected -if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then - hash -r -fi diff --git a/test/bin/activate.csh b/test/bin/activate.csh deleted file mode 100644 index d29ac339..00000000 --- a/test/bin/activate.csh +++ /dev/null @@ -1,32 +0,0 @@ -# This file must be used with "source bin/activate.csh" *from csh*. -# You cannot run it directly. -# Created by Davide Di Blasi <davidedb@gmail.com>. - -alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' - -# Unset irrelavent variables. -deactivate nondestructive - -setenv VIRTUAL_ENV "/Users/anne.gentle/src/nova/docslice/test" - -set _OLD_VIRTUAL_PATH="$PATH" -setenv PATH "$VIRTUAL_ENV/bin:$PATH" - -set _OLD_VIRTUAL_PROMPT="$prompt" - -if ("" != "") then - set env_name = "" -else - if (`basename "$VIRTUAL_ENV"` == "__") then - # special case for Aspen magic directories - # see http://www.zetadev.com/software/aspen/ - set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` - else - set env_name = `basename "$VIRTUAL_ENV"` - endif -endif -set prompt = "[$env_name] $prompt" -unset env_name - -rehash - diff --git a/test/bin/activate.fish b/test/bin/activate.fish deleted file mode 100644 index de3a8901..00000000 --- a/test/bin/activate.fish +++ /dev/null @@ -1,79 +0,0 @@ -# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) -# you cannot run it directly - -function deactivate -d "Exit virtualenv and return to normal shell environment" - # reset old environment variables - if test -n "$_OLD_VIRTUAL_PATH" - set -gx PATH $_OLD_VIRTUAL_PATH - set -e _OLD_VIRTUAL_PATH - end - if test -n "$_OLD_VIRTUAL_PYTHONHOME" - set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME - set -e _OLD_VIRTUAL_PYTHONHOME - end - - if test -n "$_OLD_FISH_PROMPT_OVERRIDE" - functions -e fish_prompt - set -e _OLD_FISH_PROMPT_OVERRIDE - end - - set -e VIRTUAL_ENV - if test "$argv[1]" != "nondestructive" - # Self destruct! - functions -e deactivate - end -end - -# unset irrelavent variables -deactivate nondestructive - -set -gx VIRTUAL_ENV "/Users/anne.gentle/src/nova/docslice/test" - -set -gx _OLD_VIRTUAL_PATH $PATH -set -gx PATH "$VIRTUAL_ENV/bin" $PATH - -# unset PYTHONHOME if set -if set -q PYTHONHOME - set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME - set -e PYTHONHOME -end - -if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" - # fish shell uses a function, instead of env vars, - # to produce the prompt. Overriding the existing function is easy. - # However, adding to the current prompt, instead of clobbering it, - # is a little more work. - set -l oldpromptfile (tempfile) - if test $status - # save the current fish_prompt function... - echo "function _old_fish_prompt" >> $oldpromptfile - echo -n \# >> $oldpromptfile - functions fish_prompt >> $oldpromptfile - # we've made the "_old_fish_prompt" file, source it. - . $oldpromptfile - rm -f $oldpromptfile - - if test -n "" - # We've been given us a prompt override. - # - # FIXME: Unsure how to handle this *safely*. We could just eval() - # whatever is given, but the risk is a bit much. - echo "activate.fish: Alternative prompt prefix is not supported under fish-shell." 1>&2 - echo "activate.fish: Alter the fish_prompt in this file as needed." 1>&2 - end - - # with the original prompt function renamed, we can override with our own. - function fish_prompt - set -l _checkbase (basename "$VIRTUAL_ENV") - if test $_checkbase = "__" - # special case for Aspen magic directories - # see http://www.zetadev.com/software/aspen/ - printf "%s[%s]%s %s" (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) (_old_fish_prompt) - else - printf "%s(%s)%s%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) (_old_fish_prompt) - end - end - set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" - end -end - diff --git a/test/bin/activate_this.py b/test/bin/activate_this.py deleted file mode 100644 index aff6927d..00000000 --- a/test/bin/activate_this.py +++ /dev/null @@ -1,32 +0,0 @@ -"""By using execfile(this_file, dict(__file__=this_file)) you will -activate this virtualenv environment. - -This can be used when you must use an existing Python interpreter, not -the virtualenv bin/python -""" - -try: - __file__ -except NameError: - raise AssertionError( - "You must run this like execfile('path/to/activate_this.py', dict(__file__='path/to/activate_this.py'))") -import sys -import os - -base = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -if sys.platform == 'win32': - site_packages = os.path.join(base, 'Lib', 'site-packages') -else: - site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages') -prev_sys_path = list(sys.path) -import site -site.addsitedir(site_packages) -sys.real_prefix = sys.prefix -sys.prefix = base -# Move the added items to the front of the path: -new_sys_path = [] -for item in list(sys.path): - if item not in prev_sys_path: - new_sys_path.append(item) - sys.path.remove(item) -sys.path[:0] = new_sys_path diff --git a/test/bin/easy_install b/test/bin/easy_install deleted file mode 100755 index 8544573f..00000000 --- a/test/bin/easy_install +++ /dev/null @@ -1,9 +0,0 @@ -#!/Users/anne.gentle/src/nova/docslice/test/bin/python -# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install' -__requires__ = 'setuptools==0.6c11' -import sys -from pkg_resources import load_entry_point - -sys.exit( - load_entry_point('setuptools==0.6c11', 'console_scripts', 'easy_install')() -) diff --git a/test/bin/easy_install-2.6 b/test/bin/easy_install-2.6 deleted file mode 100755 index bad01d2d..00000000 --- a/test/bin/easy_install-2.6 +++ /dev/null @@ -1,9 +0,0 @@ -#!/Users/anne.gentle/src/nova/docslice/test/bin/python -# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install-2.6' -__requires__ = 'setuptools==0.6c11' -import sys -from pkg_resources import load_entry_point - -sys.exit( - load_entry_point('setuptools==0.6c11', 'console_scripts', 'easy_install-2.6')() -) diff --git a/test/bin/pip b/test/bin/pip deleted file mode 100755 index a3d2ed31..00000000 --- a/test/bin/pip +++ /dev/null @@ -1,9 +0,0 @@ -#!/Users/anne.gentle/src/nova/docslice/test/bin/python -# EASY-INSTALL-ENTRY-SCRIPT: 'pip==0.8.1','console_scripts','pip' -__requires__ = 'pip==0.8.1' -import sys -from pkg_resources import load_entry_point - -sys.exit( - load_entry_point('pip==0.8.1', 'console_scripts', 'pip')() -) diff --git a/test/bin/pip-2.6 b/test/bin/pip-2.6 deleted file mode 100755 index 4ad06add..00000000 --- a/test/bin/pip-2.6 +++ /dev/null @@ -1,9 +0,0 @@ -#!/Users/anne.gentle/src/nova/docslice/test/bin/python -# EASY-INSTALL-ENTRY-SCRIPT: 'pip==0.8.1','console_scripts','pip-2.6' -__requires__ = 'pip==0.8.1' -import sys -from pkg_resources import load_entry_point - -sys.exit( - load_entry_point('pip==0.8.1', 'console_scripts', 'pip-2.6')() -) diff --git a/test/bin/python b/test/bin/python deleted file mode 100755 index 271b6ca305f3044e23a2dff6649454a456723438..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50720 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 diff --git a/test/bin/python2.6 b/test/bin/python2.6 deleted file mode 120000 index d8654aa0..00000000 --- a/test/bin/python2.6 +++ /dev/null @@ -1 +0,0 @@ -python \ No newline at end of file diff --git a/test/include/python2.6 b/test/include/python2.6 deleted file mode 120000 index 788ac55b..00000000 --- a/test/include/python2.6 +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/include/python2.6 \ No newline at end of file diff --git a/test/lib/python2.6/UserDict.py b/test/lib/python2.6/UserDict.py deleted file mode 120000 index 93e0864b..00000000 --- a/test/lib/python2.6/UserDict.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/UserDict.py \ No newline at end of file diff --git a/test/lib/python2.6/_abcoll.py b/test/lib/python2.6/_abcoll.py deleted file mode 120000 index ff176924..00000000 --- a/test/lib/python2.6/_abcoll.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/_abcoll.py \ No newline at end of file diff --git a/test/lib/python2.6/abc.py b/test/lib/python2.6/abc.py deleted file mode 120000 index 79fa108b..00000000 --- a/test/lib/python2.6/abc.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/abc.py \ No newline at end of file diff --git a/test/lib/python2.6/codecs.py b/test/lib/python2.6/codecs.py deleted file mode 120000 index 9e4bfb7f..00000000 --- a/test/lib/python2.6/codecs.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/codecs.py \ No newline at end of file diff --git a/test/lib/python2.6/config b/test/lib/python2.6/config deleted file mode 120000 index eef498c6..00000000 --- a/test/lib/python2.6/config +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/config \ No newline at end of file diff --git a/test/lib/python2.6/copy_reg.py b/test/lib/python2.6/copy_reg.py deleted file mode 120000 index 7285fda0..00000000 --- a/test/lib/python2.6/copy_reg.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/copy_reg.py \ No newline at end of file diff --git a/test/lib/python2.6/distutils/__init__.py b/test/lib/python2.6/distutils/__init__.py deleted file mode 100644 index 7ebb41c0..00000000 --- a/test/lib/python2.6/distutils/__init__.py +++ /dev/null @@ -1,91 +0,0 @@ -import os -import sys -import warnings -import opcode # opcode is not a virtualenv module, so we can use it to find the stdlib - # Important! To work on pypy, this must be a module that resides in the - # lib-python/modified-x.y.z directory - -dirname = os.path.dirname - -distutils_path = os.path.join(os.path.dirname(opcode.__file__), 'distutils') -if os.path.normpath(distutils_path) == os.path.dirname(os.path.normpath(__file__)): - warnings.warn( - "The virtualenv distutils package at %s appears to be in the same location as the system distutils?") -else: - __path__.insert(0, distutils_path) - exec open(os.path.join(distutils_path, '__init__.py')).read() - -import dist -import sysconfig - - -## patch build_ext (distutils doesn't know how to get the libs directory -## path on windows - it hardcodes the paths around the patched sys.prefix) - -if sys.platform == 'win32': - from distutils.command.build_ext import build_ext as old_build_ext - class build_ext(old_build_ext): - def finalize_options (self): - if self.library_dirs is None: - self.library_dirs = [] - elif isinstance(self.library_dirs, basestring): - self.library_dirs = self.library_dirs.split(os.pathsep) - - self.library_dirs.insert(0, os.path.join(sys.real_prefix, "Libs")) - old_build_ext.finalize_options(self) - - from distutils.command import build_ext as build_ext_module - build_ext_module.build_ext = build_ext - -## distutils.dist patches: - -old_find_config_files = dist.Distribution.find_config_files -def find_config_files(self): - found = old_find_config_files(self) - system_distutils = os.path.join(distutils_path, 'distutils.cfg') - #if os.path.exists(system_distutils): - # found.insert(0, system_distutils) - # What to call the per-user config file - if os.name == 'posix': - user_filename = ".pydistutils.cfg" - else: - user_filename = "pydistutils.cfg" - user_filename = os.path.join(sys.prefix, user_filename) - if os.path.isfile(user_filename): - for item in list(found): - if item.endswith('pydistutils.cfg'): - found.remove(item) - found.append(user_filename) - return found -dist.Distribution.find_config_files = find_config_files - -## distutils.sysconfig patches: - -old_get_python_inc = sysconfig.get_python_inc -def sysconfig_get_python_inc(plat_specific=0, prefix=None): - if prefix is None: - prefix = sys.real_prefix - return old_get_python_inc(plat_specific, prefix) -sysconfig_get_python_inc.__doc__ = old_get_python_inc.__doc__ -sysconfig.get_python_inc = sysconfig_get_python_inc - -old_get_python_lib = sysconfig.get_python_lib -def sysconfig_get_python_lib(plat_specific=0, standard_lib=0, prefix=None): - if standard_lib and prefix is None: - prefix = sys.real_prefix - return old_get_python_lib(plat_specific, standard_lib, prefix) -sysconfig_get_python_lib.__doc__ = old_get_python_lib.__doc__ -sysconfig.get_python_lib = sysconfig_get_python_lib - -old_get_config_vars = sysconfig.get_config_vars -def sysconfig_get_config_vars(*args): - real_vars = old_get_config_vars(*args) - if sys.platform == 'win32': - lib_dir = os.path.join(sys.real_prefix, "libs") - if isinstance(real_vars, dict) and 'LIBDIR' not in real_vars: - real_vars['LIBDIR'] = lib_dir # asked for all - elif isinstance(real_vars, list) and 'LIBDIR' in args: - real_vars = real_vars + [lib_dir] # asked for list - return real_vars -sysconfig_get_config_vars.__doc__ = old_get_config_vars.__doc__ -sysconfig.get_config_vars = sysconfig_get_config_vars diff --git a/test/lib/python2.6/distutils/distutils.cfg b/test/lib/python2.6/distutils/distutils.cfg deleted file mode 100644 index 1af230ec..00000000 --- a/test/lib/python2.6/distutils/distutils.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# This is a config file local to this virtualenv installation -# You may include options that will be used by all distutils commands, -# and by easy_install. For instance: -# -# [easy_install] -# find_links = http://mylocalsite diff --git a/test/lib/python2.6/encodings b/test/lib/python2.6/encodings deleted file mode 120000 index 89f28f82..00000000 --- a/test/lib/python2.6/encodings +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/encodings \ No newline at end of file diff --git a/test/lib/python2.6/fnmatch.py b/test/lib/python2.6/fnmatch.py deleted file mode 120000 index cce0594f..00000000 --- a/test/lib/python2.6/fnmatch.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/fnmatch.py \ No newline at end of file diff --git a/test/lib/python2.6/genericpath.py b/test/lib/python2.6/genericpath.py deleted file mode 120000 index b14e1bc2..00000000 --- a/test/lib/python2.6/genericpath.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/genericpath.py \ No newline at end of file diff --git a/test/lib/python2.6/lib-dynload b/test/lib/python2.6/lib-dynload deleted file mode 120000 index 4644b707..00000000 --- a/test/lib/python2.6/lib-dynload +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-dynload \ No newline at end of file diff --git a/test/lib/python2.6/linecache.py b/test/lib/python2.6/linecache.py deleted file mode 120000 index 783624da..00000000 --- a/test/lib/python2.6/linecache.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/linecache.py \ No newline at end of file diff --git a/test/lib/python2.6/locale.py b/test/lib/python2.6/locale.py deleted file mode 120000 index 4e674c7b..00000000 --- a/test/lib/python2.6/locale.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/locale.py \ No newline at end of file diff --git a/test/lib/python2.6/ntpath.py b/test/lib/python2.6/ntpath.py deleted file mode 120000 index 9b6b40f4..00000000 --- a/test/lib/python2.6/ntpath.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ntpath.py \ No newline at end of file diff --git a/test/lib/python2.6/orig-prefix.txt b/test/lib/python2.6/orig-prefix.txt deleted file mode 100644 index 535eb0f0..00000000 --- a/test/lib/python2.6/orig-prefix.txt +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6 \ No newline at end of file diff --git a/test/lib/python2.6/os.py b/test/lib/python2.6/os.py deleted file mode 120000 index 92e6e9a7..00000000 --- a/test/lib/python2.6/os.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/os.py \ No newline at end of file diff --git a/test/lib/python2.6/posixpath.py b/test/lib/python2.6/posixpath.py deleted file mode 120000 index c095d16a..00000000 --- a/test/lib/python2.6/posixpath.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/posixpath.py \ No newline at end of file diff --git a/test/lib/python2.6/re.py b/test/lib/python2.6/re.py deleted file mode 120000 index b4710c5f..00000000 --- a/test/lib/python2.6/re.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/re.py \ No newline at end of file diff --git a/test/lib/python2.6/site-packages/easy-install.pth b/test/lib/python2.6/site-packages/easy-install.pth deleted file mode 100644 index 7a6ae2b6..00000000 --- a/test/lib/python2.6/site-packages/easy-install.pth +++ /dev/null @@ -1,4 +0,0 @@ -import sys; sys.__plen = len(sys.path) -./setuptools-0.6c11-py2.6.egg -./pip-0.8.1-py2.6.egg -import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/PKG-INFO b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/PKG-INFO deleted file mode 100644 index 29c30cb8..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/PKG-INFO +++ /dev/null @@ -1,348 +0,0 @@ -Metadata-Version: 1.0 -Name: pip -Version: 0.8.1 -Summary: pip installs packages. Python packages. An easy_install replacement -Home-page: http://pip.openplans.org -Author: Ian Bicking -Author-email: python-virtualenv@groups.google.com -License: MIT -Description: The main website for pip is `pip.openplans.org - <http://pip.openplans.org>`_. You can also install - the `in-development version <http://bitbucket.org/ianb/pip/get/tip.gz#egg=pip-dev>`_ - of pip with ``easy_install pip==dev``. - - - Introduction - ------------ - - pip installs packages. Python packages. - - If you use `virtualenv <http://virtualenv.openplans.org>`__ -- a tool - for installing libraries in a local and isolated manner -- you'll - automatically get a copy of pip. Free bonus! - - Once you have pip, you can use it like this:: - - $ pip install SomePackage - - SomePackage is some package you'll find on `PyPI - <http://pypi.python.org/pypi/>`_. This installs the package and all - its dependencies. - - pip does other stuff too, with packages, but install is the biggest - one. You can ``pip uninstall`` too. - - You can also install from a URL (that points to a tar or zip file), - install from some version control system (use URLs like - ``hg+http://domain/repo`` -- or prefix ``git+``, ``svn+`` etc). pip - knows a bunch of stuff about revisions and stuff, so if you need to do - things like install a very specific revision from a repository pip can - do that too. - - If you've ever used ``python setup.py develop``, you can do something - like that with ``pip install -e ./`` -- this works with packages that - use ``distutils`` too (usually this only works with Setuptools - projects). - - You can use ``pip install --upgrade SomePackage`` to upgrade to a - newer version, or ``pip install SomePackage==1.0.4`` to install a very - specific version. - - Pip Compared To easy_install - ---------------------------- - - pip is a replacement for `easy_install - <http://peak.telecommunity.com/DevCenter/EasyInstall>`_. It uses mostly the - same techniques for finding packages, so packages that were made - easy_installable should be pip-installable as well. - - pip is meant to improve on easy_install. Some of the improvements: - - * All packages are downloaded before installation. Partially-completed - installation doesn't occur as a result. - - * Care is taken to present useful output on the console. - - * The reasons for actions are kept track of. For instance, if a package is - being installed, pip keeps track of why that package was required. - - * Error messages should be useful. - - * The code is relatively concise and cohesive, making it easier to use - programmatically. - - * Packages don't have to be installed as egg archives, they can be installed - flat (while keeping the egg metadata). - - * Native support for other version control systems (Git, Mercurial and Bazaar) - - * Uninstallation of packages. - - * Simple to define fixed sets of requirements and reliably reproduce a - set of packages. - - pip doesn't do everything that easy_install does. Specifically: - - * It cannot install from eggs. It only installs from source. (In the - future it would be good if it could install binaries from Windows ``.exe`` - or ``.msi`` -- binary install on other platforms is not a priority.) - - * It doesn't understand Setuptools extras (like ``package[test]``). This should - be added eventually. - - * It is incompatible with some packages that extensively customize distutils - or setuptools in their ``setup.py`` files. - - pip is complementary with `virtualenv - <http://pypi.python.org/pypi/virtualenv>`__, and it is encouraged that you use - virtualenv to isolate your installation. - - Community - --------- - - The homepage for pip is temporarily located `on PyPI - <http://pypi.python.org/pypi/pip>`_ -- a more proper homepage will - follow. Bugs can go on the `pip issue tracker - <http://bitbucket.org/ianb/pip/issues/>`_. Discussion should happen on the - `virtualenv email group - <http://groups.google.com/group/python-virtualenv?hl=en>`_. - - Uninstall - --------- - - pip is able to uninstall most installed packages with ``pip uninstall - package-name``. - - Known exceptions include pure-distutils packages installed with - ``python setup.py install`` (such packages leave behind no metadata allowing - determination of what files were installed), and script wrappers installed - by develop-installs (``python setup.py develop``). - - pip also performs an automatic uninstall of an old version of a package - before upgrading to a newer version, so outdated files (and egg-info data) - from conflicting versions aren't left hanging around to cause trouble. The - old version of the package is automatically restored if the new version - fails to download or install. - - .. _`requirements file`: - - Requirements Files - ------------------ - - When installing software, and Python packages in particular, it's common that - you get a lot of libraries installed. You just did ``easy_install MyPackage`` - and you get a dozen packages. Each of these packages has its own version. - - Maybe you ran that installation and it works. Great! Will it keep working? - Did you have to provide special options to get it to find everything? Did you - have to install a bunch of other optional pieces? Most of all, will you be able - to do it again? Requirements files give you a way to create an *environment*: - a *set* of packages that work together. - - If you've ever tried to setup an application on a new system, or with slightly - updated pieces, and had it fail, pip requirements are for you. If you - haven't had this problem then you will eventually, so pip requirements are - for you too -- requirements make explicit, repeatable installation of packages. - - So what are requirements files? They are very simple: lists of packages to - install. Instead of running something like ``pip MyApp`` and getting - whatever libraries come along, you can create a requirements file something like:: - - MyApp - Framework==0.9.4 - Library>=0.2 - - Then, regardless of what MyApp lists in ``setup.py``, you'll get a - specific version of Framework (0.9.4) and at least the 0.2 version of - Library. (You might think you could list these specific versions in - MyApp's ``setup.py`` -- but if you do that you'll have to edit MyApp - if you want to try a new version of Framework, or release a new - version of MyApp if you determine that Library 0.3 doesn't work with - your application.) You can also add optional libraries and support - tools that MyApp doesn't strictly require, giving people a set of - recommended libraries. - - You can also include "editable" packages -- packages that are checked out from - Subversion, Git, Mercurial and Bazaar. These are just like using the ``-e`` - option to pip. They look like:: - - -e svn+http://myrepo/svn/MyApp#egg=MyApp - - You have to start the URL with ``svn+`` (``git+``, ``hg+`` or ``bzr+``), and - you have to include ``#egg=Package`` so pip knows what to expect at that URL. - You can also include ``@rev`` in the URL, e.g., ``@275`` to check out - revision 275. - - Requirement files are mostly *flat*. Maybe ``MyApp`` requires - ``Framework``, and ``Framework`` requires ``Library``. I encourage - you to still list all these in a single requirement file; it is the - nature of Python programs that there are implicit bindings *directly* - between MyApp and Library. For instance, Framework might expose one - of Library's objects, and so if Library is updated it might directly - break MyApp. If that happens you can update the requirements file to - force an earlier version of Library, and you can do that without - having to re-release MyApp at all. - - Read the `requirements file format <http://pip.openplans.org/requirement-format.html>`_ to - learn about other features. - - Freezing Requirements - --------------------- - - So you have a working set of packages, and you want to be able to install them - elsewhere. `Requirements files`_ let you install exact versions, but it won't - tell you what all the exact versions are. - - To create a new requirements file from a known working environment, use:: - - $ pip freeze > stable-req.txt - - This will write a listing of *all* installed libraries to ``stable-req.txt`` - with exact versions for every library. You may want to edit the file down after - generating (e.g., to eliminate unnecessary libraries), but it'll give you a - stable starting point for constructing your requirements file. - - You can also give it an existing requirements file, and it will use that as a - sort of template for the new file. So if you do:: - - $ pip freeze -r devel-req.txt > stable-req.txt - - it will keep the packages listed in ``devel-req.txt`` in order and preserve - comments. - - Bundles - ------- - - Another way to distribute a set of libraries is a bundle format (specific to - pip). This format is not stable at this time (there simply hasn't been - any feedback, nor a great deal of thought). A bundle file contains all the - source for your package, and you can have pip install them all together. - Once you have the bundle file further network access won't be necessary. To - build a bundle file, do:: - - $ pip bundle MyApp.pybundle MyApp - - (Using a `requirements file`_ would be wise.) Then someone else can get the - file ``MyApp.pybundle`` and run:: - - $ pip install MyApp.pybundle - - This is *not* a binary format. This only packages source. If you have binary - packages, then the person who installs the files will have to have a compiler, - any necessary headers installed, etc. Binary packages are hard, this is - relatively easy. - - Using pip with virtualenv - ------------------------- - - pip is most nutritious when used with `virtualenv - <http://pypi.python.org/pypi/virtualenv>`__. One of the reasons pip - doesn't install "multi-version" eggs is that virtualenv removes much of the need - for it. Because pip is installed by virtualenv, just use - ``path/to/my/environment/bin/pip`` to install things into that - specific environment. - - To tell pip to only run if there is a virtualenv currently activated, - and to bail if not, use:: - - export PIP_REQUIRE_VIRTUALENV=true - - To tell pip to automatically use the currently active virtualenv:: - - export PIP_RESPECT_VIRTUALENV=true - - Providing an environment with ``-E`` will be ignored. - - Using pip with virtualenvwrapper - --------------------------------- - - If you are using `virtualenvwrapper - <http://www.doughellmann.com/projects/virtualenvwrapper/>`_, you might - want pip to automatically create its virtualenvs in your - ``$WORKON_HOME``. - - You can tell pip to do so by defining ``PIP_VIRTUALENV_BASE`` in your - environment and setting it to the same value as that of - ``$WORKON_HOME``. - - Do so by adding the line:: - - export PIP_VIRTUALENV_BASE=$WORKON_HOME - - in your .bashrc under the line starting with ``export WORKON_HOME``. - - Using pip with buildout - ----------------------- - - If you are using `zc.buildout - <http://pypi.python.org/pypi/zc.buildout>`_ you should look at - `gp.recipe.pip <http://pypi.python.org/pypi/gp.recipe.pip>`_ as an - option to use pip and virtualenv in your buildouts. - - Command line completion - ----------------------- - - pip comes with support for command line completion in bash and zsh and - allows you tab complete commands and options. To enable it you simply - need copy the required shell script to the your shell startup file - (e.g. ``.profile`` or ``.zprofile``) by running the special ``completion`` - command, e.g. for bash:: - - $ pip completion --bash >> ~/.profile - - And for zsh:: - - $ pip completion --zsh >> ~/.zprofile - - Alternatively, you can use the result of the ``completion`` command - directly with the eval function of you shell, e.g. by adding:: - - eval "`pip completion --bash`" - - to your startup file. - - Searching for packages - ---------------------- - - pip can search the `Python Package Index <http://pypi.python.org/pypi>`_ (PyPI) - for packages using the ``pip search`` command. To search, run:: - - $ pip search "query" - - The query will be used to search the names and summaries of all packages - indexed. - - pip searches http://pypi.python.org/pypi by default but alternative indexes - can be searched by using the ``--index`` flag. - - Mirror support - -------------- - - The `PyPI mirroring infrastructure <http://pypi.python.org/mirrors>`_ as - described in `PEP 381 <http://www.python.org/dev/peps/pep-0381/>`_ can be - used by passing the ``--use-mirrors`` option to the install command. - Alternatively, you can use the other ways to configure pip, e.g.:: - - $ export PIP_USE_MIRRORS=true - - If enabled, pip will automatically query the DNS entry of the mirror index URL - to find the list of mirrors to use. In case you want to override this list, - please use the ``--mirrors`` option of the install command, or add to your pip - configuration file:: - - [install] - use-mirrors = true - mirrors = - http://d.pypi.python.org - http://b.pypi.python.org - -Keywords: easy_install distutils setuptools egg virtualenv -Platform: UNKNOWN -Classifier: Development Status :: 4 - Beta -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Topic :: Software Development :: Build Tools -Classifier: Programming Language :: Python :: 2.4 -Classifier: Programming Language :: Python :: 2.5 -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 2.7 diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/SOURCES.txt b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/SOURCES.txt deleted file mode 100644 index 3a068547..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/SOURCES.txt +++ /dev/null @@ -1,57 +0,0 @@ -MANIFEST.in -setup.cfg -setup.py -docs/branches.txt -docs/ci-server-step-by-step.txt -docs/configuration.txt -docs/how-to-contribute.txt -docs/index.txt -docs/license.txt -docs/news.txt -docs/requirement-format.txt -docs/running-tests.txt -docs/_build/branches.html -docs/_build/ci-server-step-by-step.html -docs/_build/configuration.html -docs/_build/how-to-contribute.html -docs/_build/index.html -docs/_build/license.html -docs/_build/news.html -docs/_build/requirement-format.html -docs/_build/running-tests.html -docs/_build/search.html -pip/__init__.py -pip/_pkgutil.py -pip/backwardcompat.py -pip/basecommand.py -pip/baseparser.py -pip/download.py -pip/exceptions.py -pip/index.py -pip/locations.py -pip/log.py -pip/req.py -pip/runner.py -pip/util.py -pip/venv.py -pip.egg-info/PKG-INFO -pip.egg-info/SOURCES.txt -pip.egg-info/dependency_links.txt -pip.egg-info/entry_points.txt -pip.egg-info/not-zip-safe -pip.egg-info/top_level.txt -pip/commands/__init__.py -pip/commands/bundle.py -pip/commands/completion.py -pip/commands/freeze.py -pip/commands/help.py -pip/commands/install.py -pip/commands/search.py -pip/commands/uninstall.py -pip/commands/unzip.py -pip/commands/zip.py -pip/vcs/__init__.py -pip/vcs/bazaar.py -pip/vcs/git.py -pip/vcs/mercurial.py -pip/vcs/subversion.py \ No newline at end of file diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/dependency_links.txt b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/dependency_links.txt deleted file mode 100644 index 8b137891..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/entry_points.txt b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/entry_points.txt deleted file mode 100644 index 2b0afba7..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/entry_points.txt +++ /dev/null @@ -1,4 +0,0 @@ -[console_scripts] -pip = pip:main -pip-2.6 = pip:main - diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/not-zip-safe b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/not-zip-safe deleted file mode 100644 index 8b137891..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/not-zip-safe +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/top_level.txt b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/top_level.txt deleted file mode 100644 index a1b589e3..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/EGG-INFO/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/__init__.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/__init__.py deleted file mode 100644 index c5de5c9a..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/__init__.py +++ /dev/null @@ -1,261 +0,0 @@ -#!/usr/bin/env python -import os -import optparse - -import subprocess -import sys -import re -import difflib - -from pip.basecommand import command_dict, load_command, load_all_commands, command_names -from pip.baseparser import parser -from pip.exceptions import InstallationError -from pip.log import logger -from pip.util import get_installed_distributions -from pip.backwardcompat import walk_packages - - -def autocomplete(): - """Command and option completion for the main option parser (and options) - and its subcommands (and options). - - Enable by sourcing one of the completion shell scripts (bash or zsh). - """ - # Don't complete if user hasn't sourced bash_completion file. - if 'PIP_AUTO_COMPLETE' not in os.environ: - return - cwords = os.environ['COMP_WORDS'].split()[1:] - cword = int(os.environ['COMP_CWORD']) - try: - current = cwords[cword-1] - except IndexError: - current = '' - load_all_commands() - subcommands = [cmd for cmd, cls in command_dict.items() if not cls.hidden] - options = [] - # subcommand - try: - subcommand_name = [w for w in cwords if w in subcommands][0] - except IndexError: - subcommand_name = None - # subcommand options - if subcommand_name: - # special case: 'help' subcommand has no options - if subcommand_name == 'help': - sys.exit(1) - # special case: list locally installed dists for uninstall command - if subcommand_name == 'uninstall' and not current.startswith('-'): - installed = [] - lc = current.lower() - for dist in get_installed_distributions(local_only=True): - if dist.key.startswith(lc) and dist.key not in cwords[1:]: - installed.append(dist.key) - # if there are no dists installed, fall back to option completion - if installed: - for dist in installed: - print dist - sys.exit(1) - subcommand = command_dict.get(subcommand_name) - options += [(opt.get_opt_string(), opt.nargs) - for opt in subcommand.parser.option_list - if opt.help != optparse.SUPPRESS_HELP] - # filter out previously specified options from available options - prev_opts = [x.split('=')[0] for x in cwords[1:cword-1]] - options = filter(lambda (x, v): x not in prev_opts, options) - # filter options by current input - options = [(k, v) for k, v in options if k.startswith(current)] - for option in options: - opt_label = option[0] - # append '=' to options which require args - if option[1]: - opt_label += '=' - print opt_label - else: - # show options of main parser only when necessary - if current.startswith('-') or current.startswith('--'): - subcommands += [opt.get_opt_string() - for opt in parser.option_list - if opt.help != optparse.SUPPRESS_HELP] - print ' '.join(filter(lambda x: x.startswith(current), subcommands)) - sys.exit(1) - - -def version_control(): - # Import all the version control support modules: - from pip import vcs - for importer, modname, ispkg in \ - walk_packages(path=vcs.__path__, prefix=vcs.__name__+'.'): - __import__(modname) - - -def main(initial_args=None): - if initial_args is None: - initial_args = sys.argv[1:] - autocomplete() - version_control() - options, args = parser.parse_args(initial_args) - if options.help and not args: - args = ['help'] - if not args: - parser.error('You must give a command (use "pip help" to see a list of commands)') - command = args[0].lower() - load_command(command) - if command not in command_dict: - close_commands = difflib.get_close_matches(command, command_names()) - if close_commands: - guess = close_commands[0] - if args[1:]: - guess = "%s %s" % (guess, " ".join(args[1:])) - else: - guess = 'install %s' % command - error_dict = {'arg': command, 'guess': guess, - 'script': os.path.basename(sys.argv[0])} - parser.error('No command by the name %(script)s %(arg)s\n ' - '(maybe you meant "%(script)s %(guess)s")' % error_dict) - command = command_dict[command] - return command.main(initial_args, args[1:], options) - - -############################################################ -## Writing freeze files - - -class FrozenRequirement(object): - - def __init__(self, name, req, editable, comments=()): - self.name = name - self.req = req - self.editable = editable - self.comments = comments - - _rev_re = re.compile(r'-r(\d+)$') - _date_re = re.compile(r'-(20\d\d\d\d\d\d)$') - - @classmethod - def from_dist(cls, dist, dependency_links, find_tags=False): - location = os.path.normcase(os.path.abspath(dist.location)) - comments = [] - from pip.vcs import vcs, get_src_requirement - if vcs.get_backend_name(location): - editable = True - req = get_src_requirement(dist, location, find_tags) - if req is None: - logger.warn('Could not determine repository location of %s' % location) - comments.append('## !! Could not determine repository location') - req = dist.as_requirement() - editable = False - else: - editable = False - req = dist.as_requirement() - specs = req.specs - assert len(specs) == 1 and specs[0][0] == '==' - version = specs[0][1] - ver_match = cls._rev_re.search(version) - date_match = cls._date_re.search(version) - if ver_match or date_match: - svn_backend = vcs.get_backend('svn') - if svn_backend: - svn_location = svn_backend( - ).get_location(dist, dependency_links) - if not svn_location: - logger.warn( - 'Warning: cannot find svn location for %s' % req) - comments.append('## FIXME: could not find svn URL in dependency_links for this package:') - else: - comments.append('# Installing as editable to satisfy requirement %s:' % req) - if ver_match: - rev = ver_match.group(1) - else: - rev = '{%s}' % date_match.group(1) - editable = True - req = '%s@%s#egg=%s' % (svn_location, rev, cls.egg_name(dist)) - return cls(dist.project_name, req, editable, comments) - - @staticmethod - def egg_name(dist): - name = dist.egg_name() - match = re.search(r'-py\d\.\d$', name) - if match: - name = name[:match.start()] - return name - - def __str__(self): - req = self.req - if self.editable: - req = '-e %s' % req - return '\n'.join(list(self.comments)+[str(req)])+'\n' - -############################################################ -## Requirement files - - -def call_subprocess(cmd, show_stdout=True, - filter_stdout=None, cwd=None, - raise_on_returncode=True, - command_level=logger.DEBUG, command_desc=None, - extra_environ=None): - if command_desc is None: - cmd_parts = [] - for part in cmd: - if ' ' in part or '\n' in part or '"' in part or "'" in part: - part = '"%s"' % part.replace('"', '\\"') - cmd_parts.append(part) - command_desc = ' '.join(cmd_parts) - if show_stdout: - stdout = None - else: - stdout = subprocess.PIPE - logger.log(command_level, "Running command %s" % command_desc) - env = os.environ.copy() - if extra_environ: - env.update(extra_environ) - try: - proc = subprocess.Popen( - cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout, - cwd=cwd, env=env) - except Exception, e: - logger.fatal( - "Error %s while executing command %s" % (e, command_desc)) - raise - all_output = [] - if stdout is not None: - stdout = proc.stdout - while 1: - line = stdout.readline() - if not line: - break - line = line.rstrip() - all_output.append(line + '\n') - if filter_stdout: - level = filter_stdout(line) - if isinstance(level, tuple): - level, line = level - logger.log(level, line) - if not logger.stdout_level_matches(level): - logger.show_progress() - else: - logger.info(line) - else: - returned_stdout, returned_stderr = proc.communicate() - all_output = [returned_stdout or ''] - proc.wait() - if proc.returncode: - if raise_on_returncode: - if all_output: - logger.notify('Complete output from command %s:' % command_desc) - logger.notify('\n'.join(all_output) + '\n----------------------------------------') - raise InstallationError( - "Command %s failed with error code %s" - % (command_desc, proc.returncode)) - else: - logger.warn( - "Command %s had error code %s" - % (command_desc, proc.returncode)) - if stdout is not None: - return ''.join(all_output) - - -if __name__ == '__main__': - exit = main() - if exit: - sys.exit(exit) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/_pkgutil.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/_pkgutil.py deleted file mode 100644 index f8fb8aa6..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/_pkgutil.py +++ /dev/null @@ -1,589 +0,0 @@ -"""Utilities to support packages.""" - -# NOTE: This module must remain compatible with Python 2.3, as it is shared -# by setuptools for distribution with Python 2.3 and up. - -import os -import sys -import imp -import os.path -from types import ModuleType - -__all__ = [ - 'get_importer', 'iter_importers', 'get_loader', 'find_loader', - 'walk_packages', 'iter_modules', - 'ImpImporter', 'ImpLoader', 'read_code', 'extend_path', -] - - -def read_code(stream): - # This helper is needed in order for the PEP 302 emulation to - # correctly handle compiled files - import marshal - - magic = stream.read(4) - if magic != imp.get_magic(): - return None - - stream.read(4) # Skip timestamp - return marshal.load(stream) - - -def simplegeneric(func): - """Make a trivial single-dispatch generic function""" - registry = {} - - def wrapper(*args, **kw): - ob = args[0] - try: - cls = ob.__class__ - except AttributeError: - cls = type(ob) - try: - mro = cls.__mro__ - except AttributeError: - try: - - class cls(cls, object): - pass - - mro = cls.__mro__[1:] - except TypeError: - mro = object, # must be an ExtensionClass or some such :( - for t in mro: - if t in registry: - return registry[t](*args, **kw) - else: - return func(*args, **kw) - try: - wrapper.__name__ = func.__name__ - except (TypeError, AttributeError): - pass # Python 2.3 doesn't allow functions to be renamed - - def register(typ, func=None): - if func is None: - return lambda f: register(typ, f) - registry[typ] = func - return func - - wrapper.__dict__ = func.__dict__ - wrapper.__doc__ = func.__doc__ - wrapper.register = register - return wrapper - - -def walk_packages(path=None, prefix='', onerror=None): - """Yields (module_loader, name, ispkg) for all modules recursively - on path, or, if path is None, all accessible modules. - - 'path' should be either None or a list of paths to look for - modules in. - - 'prefix' is a string to output on the front of every module name - on output. - - Note that this function must import all *packages* (NOT all - modules!) on the given path, in order to access the __path__ - attribute to find submodules. - - 'onerror' is a function which gets called with one argument (the - name of the package which was being imported) if any exception - occurs while trying to import a package. If no onerror function is - supplied, ImportErrors are caught and ignored, while all other - exceptions are propagated, terminating the search. - - Examples: - - # list all modules python can access - walk_packages() - - # list all submodules of ctypes - walk_packages(ctypes.__path__, ctypes.__name__+'.') - """ - - def seen(p, m={}): - if p in m: - return True - m[p] = True - - for importer, name, ispkg in iter_modules(path, prefix): - yield importer, name, ispkg - - if ispkg: - try: - __import__(name) - except ImportError: - if onerror is not None: - onerror(name) - except Exception: - if onerror is not None: - onerror(name) - else: - raise - else: - path = getattr(sys.modules[name], '__path__', None) or [] - - # don't traverse path items we've seen before - path = [p for p in path if not seen(p)] - - for item in walk_packages(path, name+'.', onerror): - yield item - - -def iter_modules(path=None, prefix=''): - """Yields (module_loader, name, ispkg) for all submodules on path, - or, if path is None, all top-level modules on sys.path. - - 'path' should be either None or a list of paths to look for - modules in. - - 'prefix' is a string to output on the front of every module name - on output. - """ - - if path is None: - importers = iter_importers() - else: - importers = map(get_importer, path) - - yielded = {} - for i in importers: - for name, ispkg in iter_importer_modules(i, prefix): - if name not in yielded: - yielded[name] = 1 - yield i, name, ispkg - - -#@simplegeneric -def iter_importer_modules(importer, prefix=''): - if not hasattr(importer, 'iter_modules'): - return [] - return importer.iter_modules(prefix) - -iter_importer_modules = simplegeneric(iter_importer_modules) - - -class ImpImporter: - """PEP 302 Importer that wraps Python's "classic" import algorithm - - ImpImporter(dirname) produces a PEP 302 importer that searches that - directory. ImpImporter(None) produces a PEP 302 importer that searches - the current sys.path, plus any modules that are frozen or built-in. - - Note that ImpImporter does not currently support being used by placement - on sys.meta_path. - """ - - def __init__(self, path=None): - self.path = path - - def find_module(self, fullname, path=None): - # Note: we ignore 'path' argument since it is only used via meta_path - subname = fullname.split(".")[-1] - if subname != fullname and self.path is None: - return None - if self.path is None: - path = None - else: - path = [os.path.realpath(self.path)] - try: - file, filename, etc = imp.find_module(subname, path) - except ImportError: - return None - return ImpLoader(fullname, file, filename, etc) - - def iter_modules(self, prefix=''): - if self.path is None or not os.path.isdir(self.path): - return - - yielded = {} - import inspect - - filenames = os.listdir(self.path) - filenames.sort() # handle packages before same-named modules - - for fn in filenames: - modname = inspect.getmodulename(fn) - if modname=='__init__' or modname in yielded: - continue - - path = os.path.join(self.path, fn) - ispkg = False - - if not modname and os.path.isdir(path) and '.' not in fn: - modname = fn - for fn in os.listdir(path): - subname = inspect.getmodulename(fn) - if subname=='__init__': - ispkg = True - break - else: - continue # not a package - - if modname and '.' not in modname: - yielded[modname] = 1 - yield prefix + modname, ispkg - - -class ImpLoader: - """PEP 302 Loader that wraps Python's "classic" import algorithm - """ - code = source = None - - def __init__(self, fullname, file, filename, etc): - self.file = file - self.filename = filename - self.fullname = fullname - self.etc = etc - - def load_module(self, fullname): - self._reopen() - try: - mod = imp.load_module(fullname, self.file, self.filename, self.etc) - finally: - if self.file: - self.file.close() - # Note: we don't set __loader__ because we want the module to look - # normal; i.e. this is just a wrapper for standard import machinery - return mod - - def get_data(self, pathname): - return open(pathname, "rb").read() - - def _reopen(self): - if self.file and self.file.closed: - mod_type = self.etc[2] - if mod_type==imp.PY_SOURCE: - self.file = open(self.filename, 'rU') - elif mod_type in (imp.PY_COMPILED, imp.C_EXTENSION): - self.file = open(self.filename, 'rb') - - def _fix_name(self, fullname): - if fullname is None: - fullname = self.fullname - elif fullname != self.fullname: - raise ImportError("Loader for module %s cannot handle " - "module %s" % (self.fullname, fullname)) - return fullname - - def is_package(self, fullname): - fullname = self._fix_name(fullname) - return self.etc[2]==imp.PKG_DIRECTORY - - def get_code(self, fullname=None): - fullname = self._fix_name(fullname) - if self.code is None: - mod_type = self.etc[2] - if mod_type==imp.PY_SOURCE: - source = self.get_source(fullname) - self.code = compile(source, self.filename, 'exec') - elif mod_type==imp.PY_COMPILED: - self._reopen() - try: - self.code = read_code(self.file) - finally: - self.file.close() - elif mod_type==imp.PKG_DIRECTORY: - self.code = self._get_delegate().get_code() - return self.code - - def get_source(self, fullname=None): - fullname = self._fix_name(fullname) - if self.source is None: - mod_type = self.etc[2] - if mod_type==imp.PY_SOURCE: - self._reopen() - try: - self.source = self.file.read() - finally: - self.file.close() - elif mod_type==imp.PY_COMPILED: - if os.path.exists(self.filename[:-1]): - f = open(self.filename[:-1], 'rU') - self.source = f.read() - f.close() - elif mod_type==imp.PKG_DIRECTORY: - self.source = self._get_delegate().get_source() - return self.source - - def _get_delegate(self): - return ImpImporter(self.filename).find_module('__init__') - - def get_filename(self, fullname=None): - fullname = self._fix_name(fullname) - mod_type = self.etc[2] - if self.etc[2]==imp.PKG_DIRECTORY: - return self._get_delegate().get_filename() - elif self.etc[2] in (imp.PY_SOURCE, imp.PY_COMPILED, imp.C_EXTENSION): - return self.filename - return None - - -try: - import zipimport - from zipimport import zipimporter - - def iter_zipimport_modules(importer, prefix=''): - dirlist = zipimport._zip_directory_cache[importer.archive].keys() - dirlist.sort() - _prefix = importer.prefix - plen = len(_prefix) - yielded = {} - import inspect - for fn in dirlist: - if not fn.startswith(_prefix): - continue - - fn = fn[plen:].split(os.sep) - - if len(fn)==2 and fn[1].startswith('__init__.py'): - if fn[0] not in yielded: - yielded[fn[0]] = 1 - yield fn[0], True - - if len(fn)!=1: - continue - - modname = inspect.getmodulename(fn[0]) - if modname=='__init__': - continue - - if modname and '.' not in modname and modname not in yielded: - yielded[modname] = 1 - yield prefix + modname, False - - iter_importer_modules.register(zipimporter, iter_zipimport_modules) - -except ImportError: - pass - - -def get_importer(path_item): - """Retrieve a PEP 302 importer for the given path item - - The returned importer is cached in sys.path_importer_cache - if it was newly created by a path hook. - - If there is no importer, a wrapper around the basic import - machinery is returned. This wrapper is never inserted into - the importer cache (None is inserted instead). - - The cache (or part of it) can be cleared manually if a - rescan of sys.path_hooks is necessary. - """ - try: - importer = sys.path_importer_cache[path_item] - except KeyError: - for path_hook in sys.path_hooks: - try: - importer = path_hook(path_item) - break - except ImportError: - pass - else: - importer = None - sys.path_importer_cache.setdefault(path_item, importer) - - if importer is None: - try: - importer = ImpImporter(path_item) - except ImportError: - importer = None - return importer - - -def iter_importers(fullname=""): - """Yield PEP 302 importers for the given module name - - If fullname contains a '.', the importers will be for the package - containing fullname, otherwise they will be importers for sys.meta_path, - sys.path, and Python's "classic" import machinery, in that order. If - the named module is in a package, that package is imported as a side - effect of invoking this function. - - Non PEP 302 mechanisms (e.g. the Windows registry) used by the - standard import machinery to find files in alternative locations - are partially supported, but are searched AFTER sys.path. Normally, - these locations are searched BEFORE sys.path, preventing sys.path - entries from shadowing them. - - For this to cause a visible difference in behaviour, there must - be a module or package name that is accessible via both sys.path - and one of the non PEP 302 file system mechanisms. In this case, - the emulation will find the former version, while the builtin - import mechanism will find the latter. - - Items of the following types can be affected by this discrepancy: - imp.C_EXTENSION, imp.PY_SOURCE, imp.PY_COMPILED, imp.PKG_DIRECTORY - """ - if fullname.startswith('.'): - raise ImportError("Relative module names not supported") - if '.' in fullname: - # Get the containing package's __path__ - pkg = '.'.join(fullname.split('.')[:-1]) - if pkg not in sys.modules: - __import__(pkg) - path = getattr(sys.modules[pkg], '__path__', None) or [] - else: - for importer in sys.meta_path: - yield importer - path = sys.path - for item in path: - yield get_importer(item) - if '.' not in fullname: - yield ImpImporter() - - -def get_loader(module_or_name): - """Get a PEP 302 "loader" object for module_or_name - - If the module or package is accessible via the normal import - mechanism, a wrapper around the relevant part of that machinery - is returned. Returns None if the module cannot be found or imported. - If the named module is not already imported, its containing package - (if any) is imported, in order to establish the package __path__. - - This function uses iter_importers(), and is thus subject to the same - limitations regarding platform-specific special import locations such - as the Windows registry. - """ - if module_or_name in sys.modules: - module_or_name = sys.modules[module_or_name] - if isinstance(module_or_name, ModuleType): - module = module_or_name - loader = getattr(module, '__loader__', None) - if loader is not None: - return loader - fullname = module.__name__ - else: - fullname = module_or_name - return find_loader(fullname) - - -def find_loader(fullname): - """Find a PEP 302 "loader" object for fullname - - If fullname contains dots, path must be the containing package's __path__. - Returns None if the module cannot be found or imported. This function uses - iter_importers(), and is thus subject to the same limitations regarding - platform-specific special import locations such as the Windows registry. - """ - for importer in iter_importers(fullname): - loader = importer.find_module(fullname) - if loader is not None: - return loader - - return None - - -def extend_path(path, name): - """Extend a package's path. - - Intended use is to place the following code in a package's __init__.py: - - from pkgutil import extend_path - __path__ = extend_path(__path__, __name__) - - This will add to the package's __path__ all subdirectories of - directories on sys.path named after the package. This is useful - if one wants to distribute different parts of a single logical - package as multiple directories. - - It also looks for *.pkg files beginning where * matches the name - argument. This feature is similar to *.pth files (see site.py), - except that it doesn't special-case lines starting with 'import'. - A *.pkg file is trusted at face value: apart from checking for - duplicates, all entries found in a *.pkg file are added to the - path, regardless of whether they are exist the filesystem. (This - is a feature.) - - If the input path is not a list (as is the case for frozen - packages) it is returned unchanged. The input path is not - modified; an extended copy is returned. Items are only appended - to the copy at the end. - - It is assumed that sys.path is a sequence. Items of sys.path that - are not (unicode or 8-bit) strings referring to existing - directories are ignored. Unicode items of sys.path that cause - errors when used as filenames may cause this function to raise an - exception (in line with os.path.isdir() behavior). - """ - - if not isinstance(path, list): - # This could happen e.g. when this is called from inside a - # frozen package. Return the path unchanged in that case. - return path - - pname = os.path.join(*name.split('.')) # Reconstitute as relative path - # Just in case os.extsep != '.' - sname = os.extsep.join(name.split('.')) - sname_pkg = sname + os.extsep + "pkg" - init_py = "__init__" + os.extsep + "py" - - path = path[:] # Start with a copy of the existing path - - for dir in sys.path: - if not isinstance(dir, basestring) or not os.path.isdir(dir): - continue - subdir = os.path.join(dir, pname) - # XXX This may still add duplicate entries to path on - # case-insensitive filesystems - initfile = os.path.join(subdir, init_py) - if subdir not in path and os.path.isfile(initfile): - path.append(subdir) - # XXX Is this the right thing for subpackages like zope.app? - # It looks for a file named "zope.app.pkg" - pkgfile = os.path.join(dir, sname_pkg) - if os.path.isfile(pkgfile): - try: - f = open(pkgfile) - except IOError, msg: - sys.stderr.write("Can't open %s: %s\n" % - (pkgfile, msg)) - else: - for line in f: - line = line.rstrip('\n') - if not line or line.startswith('#'): - continue - path.append(line) # Don't check for existence! - f.close() - - return path - - -def get_data(package, resource): - """Get a resource from a package. - - This is a wrapper round the PEP 302 loader get_data API. The package - argument should be the name of a package, in standard module format - (foo.bar). The resource argument should be in the form of a relative - filename, using '/' as the path separator. The parent directory name '..' - is not allowed, and nor is a rooted name (starting with a '/'). - - The function returns a binary string, which is the contents of the - specified resource. - - For packages located in the filesystem, which have already been imported, - this is the rough equivalent of - - d = os.path.dirname(sys.modules[package].__file__) - data = open(os.path.join(d, resource), 'rb').read() - - If the package cannot be located or loaded, or it uses a PEP 302 loader - which does not support get_data(), then None is returned. - """ - - loader = get_loader(package) - if loader is None or not hasattr(loader, 'get_data'): - return None - mod = sys.modules.get(package) or loader.load_module(package) - if mod is None or not hasattr(mod, '__file__'): - return None - - # Modify the resource name to be compatible with the loader.get_data - # signature - an os.path format "filename" starting with the dirname of - # the package's __file__ - parts = resource.split('/') - parts.insert(0, os.path.dirname(mod.__file__)) - resource_name = os.path.join(*parts) - return loader.get_data(resource_name) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/backwardcompat.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/backwardcompat.py deleted file mode 100644 index e7c11f1d..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/backwardcompat.py +++ /dev/null @@ -1,55 +0,0 @@ -"""Stuff that isn't in some old versions of Python""" - -import sys -import os -import shutil - -__all__ = ['any', 'WindowsError', 'md5', 'copytree'] - -try: - WindowsError = WindowsError -except NameError: - WindowsError = None -try: - from hashlib import md5 -except ImportError: - import md5 as md5_module - md5 = md5_module.new - -try: - from pkgutil import walk_packages -except ImportError: - # let's fall back as long as we can - from _pkgutil import walk_packages - -try: - any = any -except NameError: - - def any(seq): - for item in seq: - if item: - return True - return False - - -def copytree(src, dst): - if sys.version_info < (2, 5): - before_last_dir = os.path.dirname(dst) - if not os.path.exists(before_last_dir): - os.makedirs(before_last_dir) - shutil.copytree(src, dst) - shutil.copymode(src, dst) - else: - shutil.copytree(src, dst) - - -def product(*args, **kwds): - # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy - # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 - pools = map(tuple, args) * kwds.get('repeat', 1) - result = [[]] - for pool in pools: - result = [x+[y] for x in result for y in pool] - for prod in result: - yield tuple(prod) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/basecommand.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/basecommand.py deleted file mode 100644 index f450e839..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/basecommand.py +++ /dev/null @@ -1,203 +0,0 @@ -"""Base Command class, and related routines""" - -from cStringIO import StringIO -import getpass -import os -import socket -import sys -import traceback -import time -import urllib -import urllib2 - -from pip import commands -from pip.log import logger -from pip.baseparser import parser, ConfigOptionParser, UpdatingDefaultsHelpFormatter -from pip.download import urlopen -from pip.exceptions import BadCommand, InstallationError, UninstallationError -from pip.venv import restart_in_venv -from pip.backwardcompat import walk_packages - -__all__ = ['command_dict', 'Command', 'load_all_commands', - 'load_command', 'command_names'] - -command_dict = {} - -# for backwards compatibiliy -get_proxy = urlopen.get_proxy - - -class Command(object): - name = None - usage = None - hidden = False - - def __init__(self): - assert self.name - self.parser = ConfigOptionParser( - usage=self.usage, - prog='%s %s' % (sys.argv[0], self.name), - version=parser.version, - formatter=UpdatingDefaultsHelpFormatter(), - name=self.name) - for option in parser.option_list: - if not option.dest or option.dest == 'help': - # -h, --version, etc - continue - self.parser.add_option(option) - command_dict[self.name] = self - - def merge_options(self, initial_options, options): - # Make sure we have all global options carried over - for attr in ['log', 'venv', 'proxy', 'venv_base', 'require_venv', - 'respect_venv', 'log_explicit_levels', 'log_file', - 'timeout', 'default_vcs', 'skip_requirements_regex', - 'no_input']: - setattr(options, attr, getattr(initial_options, attr) or getattr(options, attr)) - options.quiet += initial_options.quiet - options.verbose += initial_options.verbose - - def setup_logging(self): - pass - - def main(self, complete_args, args, initial_options): - options, args = self.parser.parse_args(args) - self.merge_options(initial_options, options) - - level = 1 # Notify - level += options.verbose - level -= options.quiet - level = logger.level_for_integer(4-level) - complete_log = [] - logger.consumers.extend( - [(level, sys.stdout), - (logger.DEBUG, complete_log.append)]) - if options.log_explicit_levels: - logger.explicit_levels = True - - self.setup_logging() - - if options.require_venv and not options.venv: - # If a venv is required check if it can really be found - if not os.environ.get('VIRTUAL_ENV'): - logger.fatal('Could not find an activated virtualenv (required).') - sys.exit(3) - # Automatically install in currently activated venv if required - options.respect_venv = True - - if args and args[-1] == '___VENV_RESTART___': - ## FIXME: We don't do anything this this value yet: - args = args[:-2] - options.venv = None - else: - # If given the option to respect the activated environment - # check if no venv is given as a command line parameter - if options.respect_venv and os.environ.get('VIRTUAL_ENV'): - if options.venv and os.path.exists(options.venv): - # Make sure command line venv and environmental are the same - if (os.path.realpath(os.path.expanduser(options.venv)) != - os.path.realpath(os.environ.get('VIRTUAL_ENV'))): - logger.fatal("Given virtualenv (%s) doesn't match " - "currently activated virtualenv (%s)." - % (options.venv, os.environ.get('VIRTUAL_ENV'))) - sys.exit(3) - else: - options.venv = os.environ.get('VIRTUAL_ENV') - logger.info('Using already activated environment %s' % options.venv) - if options.venv: - logger.info('Running in environment %s' % options.venv) - site_packages=False - if options.site_packages: - site_packages=True - restart_in_venv(options.venv, options.venv_base, site_packages, - complete_args) - # restart_in_venv should actually never return, but for clarity... - return - - ## FIXME: not sure if this sure come before or after venv restart - if options.log: - log_fp = open_logfile(options.log, 'a') - logger.consumers.append((logger.DEBUG, log_fp)) - else: - log_fp = None - - socket.setdefaulttimeout(options.timeout or None) - - urlopen.setup(proxystr=options.proxy, prompting=not options.no_input) - - exit = 0 - try: - self.run(options, args) - except (InstallationError, UninstallationError), e: - logger.fatal(str(e)) - logger.info('Exception information:\n%s' % format_exc()) - exit = 1 - except BadCommand, e: - logger.fatal(str(e)) - logger.info('Exception information:\n%s' % format_exc()) - exit = 1 - except: - logger.fatal('Exception:\n%s' % format_exc()) - exit = 2 - - if log_fp is not None: - log_fp.close() - if exit: - log_fn = options.log_file - text = '\n'.join(complete_log) - logger.fatal('Storing complete log in %s' % log_fn) - log_fp = open_logfile(log_fn, 'w') - log_fp.write(text) - log_fp.close() - return exit - - - - -def format_exc(exc_info=None): - if exc_info is None: - exc_info = sys.exc_info() - out = StringIO() - traceback.print_exception(*exc_info, **dict(file=out)) - return out.getvalue() - - -def open_logfile(filename, mode='a'): - """Open the named log file in append mode. - - If the file already exists, a separator will also be printed to - the file to separate past activity from current activity. - """ - filename = os.path.expanduser(filename) - filename = os.path.abspath(filename) - dirname = os.path.dirname(filename) - if not os.path.exists(dirname): - os.makedirs(dirname) - exists = os.path.exists(filename) - - log_fp = open(filename, mode) - if exists: - print >> log_fp, '-'*60 - print >> log_fp, '%s run on %s' % (sys.argv[0], time.strftime('%c')) - return log_fp - - -def load_command(name): - full_name = 'pip.commands.%s' % name - if full_name in sys.modules: - return - try: - __import__(full_name) - except ImportError: - pass - - -def load_all_commands(): - for name in command_names(): - load_command(name) - - -def command_names(): - names = set((pkg[1] for pkg in walk_packages(path=commands.__path__))) - return list(names) - diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/baseparser.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/baseparser.py deleted file mode 100644 index a8bd6ce4..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/baseparser.py +++ /dev/null @@ -1,231 +0,0 @@ -"""Base option parser setup""" - -import sys -import optparse -import pkg_resources -import ConfigParser -import os -from distutils.util import strtobool -from pip.locations import default_config_file, default_log_file - - -class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter): - """Custom help formatter for use in ConfigOptionParser that updates - the defaults before expanding them, allowing them to show up correctly - in the help listing""" - - def expand_default(self, option): - if self.parser is not None: - self.parser.update_defaults(self.parser.defaults) - return optparse.IndentedHelpFormatter.expand_default(self, option) - - -class ConfigOptionParser(optparse.OptionParser): - """Custom option parser which updates its defaults by by checking the - configuration files and environmental variables""" - - def __init__(self, *args, **kwargs): - self.config = ConfigParser.RawConfigParser() - self.name = kwargs.pop('name') - self.files = self.get_config_files() - self.config.read(self.files) - assert self.name - optparse.OptionParser.__init__(self, *args, **kwargs) - - def get_config_files(self): - config_file = os.environ.get('PIP_CONFIG_FILE', False) - if config_file and os.path.exists(config_file): - return [config_file] - return [default_config_file] - - def update_defaults(self, defaults): - """Updates the given defaults with values from the config files and - the environ. Does a little special handling for certain types of - options (lists).""" - # Then go and look for the other sources of configuration: - config = {} - # 1. config files - for section in ('global', self.name): - config.update(dict(self.get_config_section(section))) - # 2. environmental variables - config.update(dict(self.get_environ_vars())) - # Then set the options with those values - for key, val in config.iteritems(): - key = key.replace('_', '-') - if not key.startswith('--'): - key = '--%s' % key # only prefer long opts - option = self.get_option(key) - if option is not None: - # ignore empty values - if not val: - continue - # handle multiline configs - if option.action == 'append': - val = val.split() - else: - option.nargs = 1 - if option.action in ('store_true', 'store_false', 'count'): - val = strtobool(val) - try: - val = option.convert_value(key, val) - except optparse.OptionValueError, e: - print ("An error occured during configuration: %s" % e) - sys.exit(3) - defaults[option.dest] = val - return defaults - - def get_config_section(self, name): - """Get a section of a configuration""" - if self.config.has_section(name): - return self.config.items(name) - return [] - - def get_environ_vars(self, prefix='PIP_'): - """Returns a generator with all environmental vars with prefix PIP_""" - for key, val in os.environ.iteritems(): - if key.startswith(prefix): - yield (key.replace(prefix, '').lower(), val) - - def get_default_values(self): - """Overridding to make updating the defaults after instantiation of - the option parser possible, update_defaults() does the dirty work.""" - if not self.process_default_values: - # Old, pre-Optik 1.5 behaviour. - return optparse.Values(self.defaults) - - defaults = self.update_defaults(self.defaults.copy()) # ours - for option in self._get_all_options(): - default = defaults.get(option.dest) - if isinstance(default, basestring): - opt_str = option.get_opt_string() - defaults[option.dest] = option.check_value(opt_str, default) - return optparse.Values(defaults) - -try: - pip_dist = pkg_resources.get_distribution('pip') - version = '%s from %s (python %s)' % ( - pip_dist, pip_dist.location, sys.version[:3]) -except pkg_resources.DistributionNotFound: - # when running pip.py without installing - version=None - -parser = ConfigOptionParser( - usage='%prog COMMAND [OPTIONS]', - version=version, - add_help_option=False, - formatter=UpdatingDefaultsHelpFormatter(), - name='global') - -parser.add_option( - '-h', '--help', - dest='help', - action='store_true', - help='Show help') -parser.add_option( - '-E', '--environment', - dest='venv', - metavar='DIR', - help='virtualenv environment to run pip in (either give the ' - 'interpreter or the environment base directory)') -parser.add_option( - '-s', '--enable-site-packages', - dest='site_packages', - action='store_true', - help='Include site-packages in virtualenv if one is to be ' - 'created. Ignored if --environment is not used or ' - 'the virtualenv already exists.') -parser.add_option( - # Defines a default root directory for virtualenvs, relative - # virtualenvs names/paths are considered relative to it. - '--virtualenv-base', - dest='venv_base', - type='str', - default='', - help=optparse.SUPPRESS_HELP) -parser.add_option( - # Run only if inside a virtualenv, bail if not. - '--require-virtualenv', '--require-venv', - dest='require_venv', - action='store_true', - default=False, - help=optparse.SUPPRESS_HELP) -parser.add_option( - # Use automatically an activated virtualenv instead of installing - # globally. -E will be ignored if used. - '--respect-virtualenv', '--respect-venv', - dest='respect_venv', - action='store_true', - default=False, - help=optparse.SUPPRESS_HELP) - -parser.add_option( - '-v', '--verbose', - dest='verbose', - action='count', - default=0, - help='Give more output') -parser.add_option( - '-q', '--quiet', - dest='quiet', - action='count', - default=0, - help='Give less output') -parser.add_option( - '--log', - dest='log', - metavar='FILENAME', - help='Log file where a complete (maximum verbosity) record will be kept') -parser.add_option( - # Writes the log levels explicitely to the log' - '--log-explicit-levels', - dest='log_explicit_levels', - action='store_true', - default=False, - help=optparse.SUPPRESS_HELP) -parser.add_option( - # The default log file - '--local-log', '--log-file', - dest='log_file', - metavar='FILENAME', - default=default_log_file, - help=optparse.SUPPRESS_HELP) -parser.add_option( - # Don't ask for input - '--no-input', - dest='no_input', - action='store_true', - default=False, - help=optparse.SUPPRESS_HELP) - -parser.add_option( - '--proxy', - dest='proxy', - type='str', - default='', - help="Specify a proxy in the form user:passwd@proxy.server:port. " - "Note that the user:password@ is optional and required only if you " - "are behind an authenticated proxy. If you provide " - "user@proxy.server:port then you will be prompted for a password.") -parser.add_option( - '--timeout', '--default-timeout', - metavar='SECONDS', - dest='timeout', - type='float', - default=15, - help='Set the socket timeout (default %default seconds)') -parser.add_option( - # The default version control system for editables, e.g. 'svn' - '--default-vcs', - dest='default_vcs', - type='str', - default='', - help=optparse.SUPPRESS_HELP) -parser.add_option( - # A regex to be used to skip requirements - '--skip-requirements-regex', - dest='skip_requirements_regex', - type='str', - default='', - help=optparse.SUPPRESS_HELP) - -parser.disable_interspersed_args() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/__init__.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/__init__.py deleted file mode 100644 index 792d6005..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/bundle.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/bundle.py deleted file mode 100644 index fb0f7570..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/bundle.py +++ /dev/null @@ -1,33 +0,0 @@ -from pip.locations import build_prefix, src_prefix -from pip.util import display_path, backup_dir -from pip.log import logger -from pip.exceptions import InstallationError -from pip.commands.install import InstallCommand - - -class BundleCommand(InstallCommand): - name = 'bundle' - usage = '%prog [OPTIONS] BUNDLE_NAME.pybundle PACKAGE_NAMES...' - summary = 'Create pybundles (archives containing multiple packages)' - bundle = True - - def __init__(self): - super(BundleCommand, self).__init__() - - def run(self, options, args): - if not args: - raise InstallationError('You must give a bundle filename') - if not options.build_dir: - options.build_dir = backup_dir(build_prefix, '-bundle') - if not options.src_dir: - options.src_dir = backup_dir(src_prefix, '-bundle') - # We have to get everything when creating a bundle: - options.ignore_installed = True - logger.notify('Putting temporary build files in %s and source/develop files in %s' - % (display_path(options.build_dir), display_path(options.src_dir))) - self.bundle_filename = args.pop(0) - requirement_set = super(BundleCommand, self).run(options, args) - return requirement_set - - -BundleCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/completion.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/completion.py deleted file mode 100644 index d003b9ae..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/completion.py +++ /dev/null @@ -1,60 +0,0 @@ -import sys -from pip.basecommand import Command - -BASE_COMPLETION = """ -# pip %(shell)s completion start%(script)s# pip %(shell)s completion end -""" - -COMPLETION_SCRIPTS = { - 'bash': """ -_pip_completion() -{ - COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \\ - COMP_CWORD=$COMP_CWORD \\ - PIP_AUTO_COMPLETE=1 $1 ) ) -} -complete -o default -F _pip_completion pip -""", 'zsh': """ -function _pip_completion { - local words cword - read -Ac words - read -cn cword - reply=( $( COMP_WORDS="$words[*]" \\ - COMP_CWORD=$(( cword-1 )) \\ - PIP_AUTO_COMPLETE=1 $words[1] ) ) -} -compctl -K _pip_completion pip -"""} - - -class CompletionCommand(Command): - name = 'completion' - summary = 'A helper command to be used for command completion' - hidden = True - - def __init__(self): - super(CompletionCommand, self).__init__() - self.parser.add_option( - '--bash', '-b', - action='store_const', - const='bash', - dest='shell', - help='Emit completion code for bash') - self.parser.add_option( - '--zsh', '-z', - action='store_const', - const='zsh', - dest='shell', - help='Emit completion code for zsh') - - def run(self, options, args): - """Prints the completion code of the given shell""" - shells = COMPLETION_SCRIPTS.keys() - shell_options = ['--'+shell for shell in sorted(shells)] - if options.shell in shells: - script = COMPLETION_SCRIPTS.get(options.shell, '') - print BASE_COMPLETION % {'script': script, 'shell': options.shell} - else: - sys.stderr.write('ERROR: You must pass %s\n' % ' or '.join(shell_options)) - -CompletionCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/freeze.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/freeze.py deleted file mode 100644 index 01b5df93..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/freeze.py +++ /dev/null @@ -1,109 +0,0 @@ -import re -import sys -import pkg_resources -import pip -from pip.req import InstallRequirement -from pip.log import logger -from pip.basecommand import Command -from pip.util import get_installed_distributions - - -class FreezeCommand(Command): - name = 'freeze' - usage = '%prog [OPTIONS]' - summary = 'Output all currently installed packages (exact versions) to stdout' - - def __init__(self): - super(FreezeCommand, self).__init__() - self.parser.add_option( - '-r', '--requirement', - dest='requirement', - action='store', - default=None, - metavar='FILENAME', - help='Use the given requirements file as a hint about how to generate the new frozen requirements') - self.parser.add_option( - '-f', '--find-links', - dest='find_links', - action='append', - default=[], - metavar='URL', - help='URL for finding packages, which will be added to the frozen requirements file') - self.parser.add_option( - '-l', '--local', - dest='local', - action='store_true', - default=False, - help='If in a virtualenv, do not report globally-installed packages') - - def setup_logging(self): - logger.move_stdout_to_stderr() - - def run(self, options, args): - requirement = options.requirement - find_links = options.find_links or [] - local_only = options.local - ## FIXME: Obviously this should be settable: - find_tags = False - skip_match = None - - skip_regex = options.skip_requirements_regex - if skip_regex: - skip_match = re.compile(skip_regex) - - dependency_links = [] - - f = sys.stdout - - for dist in pkg_resources.working_set: - if dist.has_metadata('dependency_links.txt'): - dependency_links.extend(dist.get_metadata_lines('dependency_links.txt')) - for link in find_links: - if '#egg=' in link: - dependency_links.append(link) - for link in find_links: - f.write('-f %s\n' % link) - installations = {} - for dist in get_installed_distributions(local_only=local_only): - req = pip.FrozenRequirement.from_dist(dist, dependency_links, find_tags=find_tags) - installations[req.name] = req - if requirement: - req_f = open(requirement) - for line in req_f: - if not line.strip() or line.strip().startswith('#'): - f.write(line) - continue - if skip_match and skip_match.search(line): - f.write(line) - continue - elif line.startswith('-e') or line.startswith('--editable'): - if line.startswith('-e'): - line = line[2:].strip() - else: - line = line[len('--editable'):].strip().lstrip('=') - line_req = InstallRequirement.from_editable(line, default_vcs=options.default_vcs) - elif (line.startswith('-r') or line.startswith('--requirement') - or line.startswith('-Z') or line.startswith('--always-unzip') - or line.startswith('-f') or line.startswith('-i') - or line.startswith('--extra-index-url')): - f.write(line) - continue - else: - line_req = InstallRequirement.from_line(line) - if not line_req.name: - logger.notify("Skipping line because it's not clear what it would install: %s" - % line.strip()) - logger.notify(" (add #egg=PackageName to the URL to avoid this warning)") - continue - if line_req.name not in installations: - logger.warn("Requirement file contains %s, but that package is not installed" - % line.strip()) - continue - f.write(str(installations[line_req.name])) - del installations[line_req.name] - f.write('## The following requirements were added by pip --freeze:\n') - for installation in sorted(installations.values(), key=lambda x: x.name): - f.write(str(installation)) - - -FreezeCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/help.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/help.py deleted file mode 100644 index b0b36611..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/help.py +++ /dev/null @@ -1,32 +0,0 @@ -from pip.basecommand import Command, command_dict, load_all_commands -from pip.exceptions import InstallationError -from pip.baseparser import parser - - -class HelpCommand(Command): - name = 'help' - usage = '%prog' - summary = 'Show available commands' - - def run(self, options, args): - load_all_commands() - if args: - ## FIXME: handle errors better here - command = args[0] - if command not in command_dict: - raise InstallationError('No command with the name: %s' % command) - command = command_dict[command] - command.parser.print_help() - return - parser.print_help() - print - print 'Commands available:' - commands = list(set(command_dict.values())) - commands.sort(key=lambda x: x.name) - for command in commands: - if command.hidden: - continue - print ' %s: %s' % (command.name, command.summary) - - -HelpCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/install.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/install.py deleted file mode 100644 index 861c332b..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/install.py +++ /dev/null @@ -1,247 +0,0 @@ -import os, sys -from pip.req import InstallRequirement, RequirementSet -from pip.req import parse_requirements -from pip.log import logger -from pip.locations import build_prefix, src_prefix -from pip.basecommand import Command -from pip.index import PackageFinder -from pip.exceptions import InstallationError - - -class InstallCommand(Command): - name = 'install' - usage = '%prog [OPTIONS] PACKAGE_NAMES...' - summary = 'Install packages' - bundle = False - - def __init__(self): - super(InstallCommand, self).__init__() - self.parser.add_option( - '-e', '--editable', - dest='editables', - action='append', - default=[], - metavar='VCS+REPOS_URL[@REV]#egg=PACKAGE', - help='Install a package directly from a checkout. Source will be checked ' - 'out into src/PACKAGE (lower-case) and installed in-place (using ' - 'setup.py develop). You can run this on an existing directory/checkout (like ' - 'pip install -e src/mycheckout). This option may be provided multiple times. ' - 'Possible values for VCS are: svn, git, hg and bzr.') - self.parser.add_option( - '-r', '--requirement', - dest='requirements', - action='append', - default=[], - metavar='FILENAME', - help='Install all the packages listed in the given requirements file. ' - 'This option can be used multiple times.') - self.parser.add_option( - '-f', '--find-links', - dest='find_links', - action='append', - default=[], - metavar='URL', - help='URL to look for packages at') - self.parser.add_option( - '-i', '--index-url', '--pypi-url', - dest='index_url', - metavar='URL', - default='http://pypi.python.org/simple/', - help='Base URL of Python Package Index (default %default)') - self.parser.add_option( - '--extra-index-url', - dest='extra_index_urls', - metavar='URL', - action='append', - default=[], - help='Extra URLs of package indexes to use in addition to --index-url') - self.parser.add_option( - '--no-index', - dest='no_index', - action='store_true', - default=False, - help='Ignore package index (only looking at --find-links URLs instead)') - self.parser.add_option( - '-M', '--use-mirrors', - dest='use_mirrors', - action='store_true', - default=False, - help='Use the PyPI mirrors as a fallback in case the main index is down.') - self.parser.add_option( - '--mirrors', - dest='mirrors', - metavar='URL', - action='append', - default=[], - help='Specific mirror URLs to query when --use-mirrors is used') - - self.parser.add_option( - '-b', '--build', '--build-dir', '--build-directory', - dest='build_dir', - metavar='DIR', - default=None, - help='Unpack packages into DIR (default %s) and build from there' % build_prefix) - self.parser.add_option( - '-d', '--download', '--download-dir', '--download-directory', - dest='download_dir', - metavar='DIR', - default=None, - help='Download packages into DIR instead of installing them') - self.parser.add_option( - '--download-cache', - dest='download_cache', - metavar='DIR', - default=None, - help='Cache downloaded packages in DIR') - self.parser.add_option( - '--src', '--source', '--source-dir', '--source-directory', - dest='src_dir', - metavar='DIR', - default=None, - help='Check out --editable packages into DIR (default %s)' % src_prefix) - - self.parser.add_option( - '-U', '--upgrade', - dest='upgrade', - action='store_true', - help='Upgrade all packages to the newest available version') - self.parser.add_option( - '-I', '--ignore-installed', - dest='ignore_installed', - action='store_true', - help='Ignore the installed packages (reinstalling instead)') - self.parser.add_option( - '--no-deps', '--no-dependencies', - dest='ignore_dependencies', - action='store_true', - default=False, - help='Ignore package dependencies') - self.parser.add_option( - '--no-install', - dest='no_install', - action='store_true', - help="Download and unpack all packages, but don't actually install them") - self.parser.add_option( - '--no-download', - dest='no_download', - action="store_true", - help="Don't download any packages, just install the ones already downloaded " - "(completes an install run with --no-install)") - - self.parser.add_option( - '--install-option', - dest='install_options', - action='append', - help="Extra arguments to be supplied to the setup.py install " - "command (use like --install-option=\"--install-scripts=/usr/local/bin\"). " - "Use multiple --install-option options to pass multiple options to setup.py install. " - "If you are using an option with a directory path, be sure to use absolute path.") - - self.parser.add_option( - '--global-option', - dest='global_options', - action='append', - help="Extra global options to be supplied to the setup.py" - "call before the install command") - - self.parser.add_option( - '--user', - dest='use_user_site', - action='store_true', - help='Install to user-site') - - def _build_package_finder(self, options, index_urls): - """ - Create a package finder appropriate to this install command. - This method is meant to be overridden by subclasses, not - called directly. - """ - return PackageFinder(find_links=options.find_links, - index_urls=index_urls, - use_mirrors=options.use_mirrors, - mirrors=options.mirrors) - - def run(self, options, args): - if not options.build_dir: - options.build_dir = build_prefix - if not options.src_dir: - options.src_dir = src_prefix - if options.download_dir: - options.no_install = True - options.ignore_installed = True - options.build_dir = os.path.abspath(options.build_dir) - options.src_dir = os.path.abspath(options.src_dir) - install_options = options.install_options or [] - if options.use_user_site: - install_options.append('--user') - global_options = options.global_options or [] - index_urls = [options.index_url] + options.extra_index_urls - if options.no_index: - logger.notify('Ignoring indexes: %s' % ','.join(index_urls)) - index_urls = [] - - finder = self._build_package_finder(options, index_urls) - - requirement_set = RequirementSet( - build_dir=options.build_dir, - src_dir=options.src_dir, - download_dir=options.download_dir, - download_cache=options.download_cache, - upgrade=options.upgrade, - ignore_installed=options.ignore_installed, - ignore_dependencies=options.ignore_dependencies) - for name in args: - requirement_set.add_requirement( - InstallRequirement.from_line(name, None)) - for name in options.editables: - requirement_set.add_requirement( - InstallRequirement.from_editable(name, default_vcs=options.default_vcs)) - for filename in options.requirements: - for req in parse_requirements(filename, finder=finder, options=options): - requirement_set.add_requirement(req) - - if not requirement_set.has_requirements: - if options.find_links: - raise InstallationError('You must give at least one ' - 'requirement to %s (maybe you meant "pip install %s"?)' - % (self.name, " ".join(options.find_links))) - raise InstallationError('You must give at least one requirement ' - 'to %(name)s (see "pip help %(name)s")' % dict(name=self.name)) - - if (options.use_user_site and - sys.version_info < (2, 6)): - raise InstallationError('--user is only supported in Python version 2.6 and newer') - - import setuptools - if (options.use_user_site and - requirement_set.has_editables and - not getattr(setuptools, '_distribute', False)): - - raise InstallationError('--user --editable not supported with setuptools, use distribute') - - if not options.no_download: - requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle) - else: - requirement_set.locate_files() - - if not options.no_install and not self.bundle: - requirement_set.install(install_options, global_options) - installed = ' '.join([req.name for req in - requirement_set.successfully_installed]) - if installed: - logger.notify('Successfully installed %s' % installed) - elif not self.bundle: - downloaded = ' '.join([req.name for req in - requirement_set.successfully_downloaded]) - if downloaded: - logger.notify('Successfully downloaded %s' % downloaded) - elif self.bundle: - requirement_set.create_bundle(self.bundle_filename) - logger.notify('Created bundle in %s' % self.bundle_filename) - # Clean up - if not options.no_install: - requirement_set.cleanup_files(bundle=self.bundle) - return requirement_set - - -InstallCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/search.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/search.py deleted file mode 100644 index 73da58ac..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/search.py +++ /dev/null @@ -1,116 +0,0 @@ -import sys -import xmlrpclib -import textwrap -import pkg_resources -import pip.download -from pip.basecommand import Command -from pip.util import get_terminal_size -from pip.log import logger -from distutils.version import StrictVersion, LooseVersion - - -class SearchCommand(Command): - name = 'search' - usage = '%prog QUERY' - summary = 'Search PyPI' - - def __init__(self): - super(SearchCommand, self).__init__() - self.parser.add_option( - '--index', - dest='index', - metavar='URL', - default='http://pypi.python.org/pypi', - help='Base URL of Python Package Index (default %default)') - - def run(self, options, args): - if not args: - logger.warn('ERROR: Missing required argument (search query).') - return - query = ' '.join(args) - index_url = options.index - - pypi_hits = self.search(query, index_url) - hits = transform_hits(pypi_hits) - - terminal_width = None - if sys.stdout.isatty(): - terminal_width = get_terminal_size()[0] - - print_results(hits, terminal_width=terminal_width) - - def search(self, query, index_url): - pypi = xmlrpclib.ServerProxy(index_url, pip.download.xmlrpclib_transport) - hits = pypi.search({'name': query, 'summary': query}, 'or') - return hits - - -def transform_hits(hits): - """ - The list from pypi is really a list of versions. We want a list of - packages with the list of versions stored inline. This converts the - list from pypi into one we can use. - """ - packages = {} - for hit in hits: - name = hit['name'] - summary = hit['summary'] - version = hit['version'] - score = hit['_pypi_ordering'] - - if name not in packages.keys(): - packages[name] = {'name': name, 'summary': summary, 'versions': [version], 'score': score} - else: - packages[name]['versions'].append(version) - - # if this is the highest version, replace summary and score - if version == highest_version(packages[name]['versions']): - packages[name]['summary'] = summary - packages[name]['score'] = score - - # each record has a unique name now, so we will convert the dict into a list sorted by score - package_list = sorted(packages.values(), lambda x, y: cmp(y['score'], x['score'])) - return package_list - - -def print_results(hits, name_column_width=25, terminal_width=None): - installed_packages = [p.project_name for p in pkg_resources.working_set] - for hit in hits: - name = hit['name'] - summary = hit['summary'] or '' - if terminal_width is not None: - # wrap and indent summary to fit terminal - summary = textwrap.wrap(summary, terminal_width - name_column_width - 5) - summary = ('\n' + ' ' * (name_column_width + 3)).join(summary) - line = '%s - %s' % (name.ljust(name_column_width), summary) - try: - logger.notify(line) - if name in installed_packages: - dist = pkg_resources.get_distribution(name) - logger.indent += 2 - try: - latest = highest_version(hit['versions']) - if dist.version == latest: - logger.notify('INSTALLED: %s (latest)' % dist.version) - else: - logger.notify('INSTALLED: %s' % dist.version) - logger.notify('LATEST: %s' % latest) - finally: - logger.indent -= 2 - except UnicodeEncodeError: - pass - - -def compare_versions(version1, version2): - try: - return cmp(StrictVersion(version1), StrictVersion(version2)) - # in case of abnormal version number, fall back to LooseVersion - except ValueError: - return cmp(LooseVersion(version1), LooseVersion(version2)) - - -def highest_version(versions): - return reduce((lambda v1, v2: compare_versions(v1, v2) == 1 and v1 or v2), versions) - - -SearchCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/uninstall.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/uninstall.py deleted file mode 100644 index 7effd844..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/uninstall.py +++ /dev/null @@ -1,42 +0,0 @@ -from pip.req import InstallRequirement, RequirementSet, parse_requirements -from pip.basecommand import Command -from pip.exceptions import InstallationError - -class UninstallCommand(Command): - name = 'uninstall' - usage = '%prog [OPTIONS] PACKAGE_NAMES ...' - summary = 'Uninstall packages' - - def __init__(self): - super(UninstallCommand, self).__init__() - self.parser.add_option( - '-r', '--requirement', - dest='requirements', - action='append', - default=[], - metavar='FILENAME', - help='Uninstall all the packages listed in the given requirements file. ' - 'This option can be used multiple times.') - self.parser.add_option( - '-y', '--yes', - dest='yes', - action='store_true', - help="Don't ask for confirmation of uninstall deletions.") - - def run(self, options, args): - requirement_set = RequirementSet( - build_dir=None, - src_dir=None, - download_dir=None) - for name in args: - requirement_set.add_requirement( - InstallRequirement.from_line(name)) - for filename in options.requirements: - for req in parse_requirements(filename, options=options): - requirement_set.add_requirement(req) - if not requirement_set.has_requirements: - raise InstallationError('You must give at least one requirement ' - 'to %(name)s (see "pip help %(name)s")' % dict(name=self.name)) - requirement_set.uninstall(auto_confirm=options.yes) - -UninstallCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/unzip.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/unzip.py deleted file mode 100644 index f83e1820..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/unzip.py +++ /dev/null @@ -1,9 +0,0 @@ -from pip.commands.zip import ZipCommand - - -class UnzipCommand(ZipCommand): - name = 'unzip' - summary = 'Unzip individual packages' - - -UnzipCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/zip.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/zip.py deleted file mode 100644 index 346fc051..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/commands/zip.py +++ /dev/null @@ -1,346 +0,0 @@ -import sys -import re -import fnmatch -import os -import shutil -import zipfile -from pip.util import display_path, backup_dir -from pip.log import logger -from pip.exceptions import InstallationError -from pip.basecommand import Command - - -class ZipCommand(Command): - name = 'zip' - usage = '%prog [OPTIONS] PACKAGE_NAMES...' - summary = 'Zip individual packages' - - def __init__(self): - super(ZipCommand, self).__init__() - if self.name == 'zip': - self.parser.add_option( - '--unzip', - action='store_true', - dest='unzip', - help='Unzip (rather than zip) a package') - else: - self.parser.add_option( - '--zip', - action='store_false', - dest='unzip', - default=True, - help='Zip (rather than unzip) a package') - self.parser.add_option( - '--no-pyc', - action='store_true', - dest='no_pyc', - help='Do not include .pyc files in zip files (useful on Google App Engine)') - self.parser.add_option( - '-l', '--list', - action='store_true', - dest='list', - help='List the packages available, and their zip status') - self.parser.add_option( - '--sort-files', - action='store_true', - dest='sort_files', - help='With --list, sort packages according to how many files they contain') - self.parser.add_option( - '--path', - action='append', - dest='paths', - help='Restrict operations to the given paths (may include wildcards)') - self.parser.add_option( - '-n', '--simulate', - action='store_true', - help='Do not actually perform the zip/unzip operation') - - def paths(self): - """All the entries of sys.path, possibly restricted by --path""" - if not self.select_paths: - return sys.path - result = [] - match_any = set() - for path in sys.path: - path = os.path.normcase(os.path.abspath(path)) - for match in self.select_paths: - match = os.path.normcase(os.path.abspath(match)) - if '*' in match: - if re.search(fnmatch.translate(match+'*'), path): - result.append(path) - match_any.add(match) - break - else: - if path.startswith(match): - result.append(path) - match_any.add(match) - break - else: - logger.debug("Skipping path %s because it doesn't match %s" - % (path, ', '.join(self.select_paths))) - for match in self.select_paths: - if match not in match_any and '*' not in match: - result.append(match) - logger.debug("Adding path %s because it doesn't match anything already on sys.path" - % match) - return result - - def run(self, options, args): - self.select_paths = options.paths - self.simulate = options.simulate - if options.list: - return self.list(options, args) - if not args: - raise InstallationError( - 'You must give at least one package to zip or unzip') - packages = [] - for arg in args: - module_name, filename = self.find_package(arg) - if options.unzip and os.path.isdir(filename): - raise InstallationError( - 'The module %s (in %s) is not a zip file; cannot be unzipped' - % (module_name, filename)) - elif not options.unzip and not os.path.isdir(filename): - raise InstallationError( - 'The module %s (in %s) is not a directory; cannot be zipped' - % (module_name, filename)) - packages.append((module_name, filename)) - last_status = None - for module_name, filename in packages: - if options.unzip: - last_status = self.unzip_package(module_name, filename) - else: - last_status = self.zip_package(module_name, filename, options.no_pyc) - return last_status - - def unzip_package(self, module_name, filename): - zip_filename = os.path.dirname(filename) - if not os.path.isfile(zip_filename) and zipfile.is_zipfile(zip_filename): - raise InstallationError( - 'Module %s (in %s) isn\'t located in a zip file in %s' - % (module_name, filename, zip_filename)) - package_path = os.path.dirname(zip_filename) - if not package_path in self.paths(): - logger.warn( - 'Unpacking %s into %s, but %s is not on sys.path' - % (display_path(zip_filename), display_path(package_path), - display_path(package_path))) - logger.notify('Unzipping %s (in %s)' % (module_name, display_path(zip_filename))) - if self.simulate: - logger.notify('Skipping remaining operations because of --simulate') - return - logger.indent += 2 - try: - ## FIXME: this should be undoable: - zip = zipfile.ZipFile(zip_filename) - to_save = [] - for name in zip.namelist(): - if name.startswith(module_name + os.path.sep): - content = zip.read(name) - dest = os.path.join(package_path, name) - if not os.path.exists(os.path.dirname(dest)): - os.makedirs(os.path.dirname(dest)) - if not content and dest.endswith(os.path.sep): - if not os.path.exists(dest): - os.makedirs(dest) - else: - f = open(dest, 'wb') - f.write(content) - f.close() - else: - to_save.append((name, zip.read(name))) - zip.close() - if not to_save: - logger.info('Removing now-empty zip file %s' % display_path(zip_filename)) - os.unlink(zip_filename) - self.remove_filename_from_pth(zip_filename) - else: - logger.info('Removing entries in %s/ from zip file %s' % (module_name, display_path(zip_filename))) - zip = zipfile.ZipFile(zip_filename, 'w') - for name, content in to_save: - zip.writestr(name, content) - zip.close() - finally: - logger.indent -= 2 - - def zip_package(self, module_name, filename, no_pyc): - orig_filename = filename - logger.notify('Zip %s (in %s)' % (module_name, display_path(filename))) - logger.indent += 2 - if filename.endswith('.egg'): - dest_filename = filename - else: - dest_filename = filename + '.zip' - try: - ## FIXME: I think this needs to be undoable: - if filename == dest_filename: - filename = backup_dir(orig_filename) - logger.notify('Moving %s aside to %s' % (orig_filename, filename)) - if not self.simulate: - shutil.move(orig_filename, filename) - try: - logger.info('Creating zip file in %s' % display_path(dest_filename)) - if not self.simulate: - zip = zipfile.ZipFile(dest_filename, 'w') - zip.writestr(module_name + '/', '') - for dirpath, dirnames, filenames in os.walk(filename): - if no_pyc: - filenames = [f for f in filenames - if not f.lower().endswith('.pyc')] - for fns, is_dir in [(dirnames, True), (filenames, False)]: - for fn in fns: - full = os.path.join(dirpath, fn) - dest = os.path.join(module_name, dirpath[len(filename):].lstrip(os.path.sep), fn) - if is_dir: - zip.writestr(dest+'/', '') - else: - zip.write(full, dest) - zip.close() - logger.info('Removing old directory %s' % display_path(filename)) - if not self.simulate: - shutil.rmtree(filename) - except: - ## FIXME: need to do an undo here - raise - ## FIXME: should also be undone: - self.add_filename_to_pth(dest_filename) - finally: - logger.indent -= 2 - - def remove_filename_from_pth(self, filename): - for pth in self.pth_files(): - f = open(pth, 'r') - lines = f.readlines() - f.close() - new_lines = [ - l for l in lines if l.strip() != filename] - if lines != new_lines: - logger.info('Removing reference to %s from .pth file %s' - % (display_path(filename), display_path(pth))) - if not filter(None, new_lines): - logger.info('%s file would be empty: deleting' % display_path(pth)) - if not self.simulate: - os.unlink(pth) - else: - if not self.simulate: - f = open(pth, 'wb') - f.writelines(new_lines) - f.close() - return - logger.warn('Cannot find a reference to %s in any .pth file' % display_path(filename)) - - def add_filename_to_pth(self, filename): - path = os.path.dirname(filename) - dest = os.path.join(path, filename + '.pth') - if path not in self.paths(): - logger.warn('Adding .pth file %s, but it is not on sys.path' % display_path(dest)) - if not self.simulate: - if os.path.exists(dest): - f = open(dest) - lines = f.readlines() - f.close() - if lines and not lines[-1].endswith('\n'): - lines[-1] += '\n' - lines.append(filename+'\n') - else: - lines = [filename + '\n'] - f = open(dest, 'wb') - f.writelines(lines) - f.close() - - def pth_files(self): - for path in self.paths(): - if not os.path.exists(path) or not os.path.isdir(path): - continue - for filename in os.listdir(path): - if filename.endswith('.pth'): - yield os.path.join(path, filename) - - def find_package(self, package): - for path in self.paths(): - full = os.path.join(path, package) - if os.path.exists(full): - return package, full - if not os.path.isdir(path) and zipfile.is_zipfile(path): - zip = zipfile.ZipFile(path, 'r') - try: - zip.read(os.path.join(package, '__init__.py')) - except KeyError: - pass - else: - zip.close() - return package, full - zip.close() - ## FIXME: need special error for package.py case: - raise InstallationError( - 'No package with the name %s found' % package) - - def list(self, options, args): - if args: - raise InstallationError( - 'You cannot give an argument with --list') - for path in sorted(self.paths()): - if not os.path.exists(path): - continue - basename = os.path.basename(path.rstrip(os.path.sep)) - if os.path.isfile(path) and zipfile.is_zipfile(path): - if os.path.dirname(path) not in self.paths(): - logger.notify('Zipped egg: %s' % display_path(path)) - continue - if (basename != 'site-packages' and basename != 'dist-packages' - and not path.replace('\\', '/').endswith('lib/python')): - continue - logger.notify('In %s:' % display_path(path)) - logger.indent += 2 - zipped = [] - unzipped = [] - try: - for filename in sorted(os.listdir(path)): - ext = os.path.splitext(filename)[1].lower() - if ext in ('.pth', '.egg-info', '.egg-link'): - continue - if ext == '.py': - logger.info('Not displaying %s: not a package' % display_path(filename)) - continue - full = os.path.join(path, filename) - if os.path.isdir(full): - unzipped.append((filename, self.count_package(full))) - elif zipfile.is_zipfile(full): - zipped.append(filename) - else: - logger.info('Unknown file: %s' % display_path(filename)) - if zipped: - logger.notify('Zipped packages:') - logger.indent += 2 - try: - for filename in zipped: - logger.notify(filename) - finally: - logger.indent -= 2 - else: - logger.notify('No zipped packages.') - if unzipped: - if options.sort_files: - unzipped.sort(key=lambda x: -x[1]) - logger.notify('Unzipped packages:') - logger.indent += 2 - try: - for filename, count in unzipped: - logger.notify('%s (%i files)' % (filename, count)) - finally: - logger.indent -= 2 - else: - logger.notify('No unzipped packages.') - finally: - logger.indent -= 2 - - def count_package(self, path): - total = 0 - for dirpath, dirnames, filenames in os.walk(path): - filenames = [f for f in filenames - if not f.lower().endswith('.pyc')] - total += len(filenames) - return total - - -ZipCommand() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/download.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/download.py deleted file mode 100644 index f1b63936..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/download.py +++ /dev/null @@ -1,470 +0,0 @@ -import xmlrpclib -import re -import getpass -import urllib -import urllib2 -import urlparse -import os -import mimetypes -import shutil -import tempfile -from pip.backwardcompat import md5, copytree -from pip.exceptions import InstallationError -from pip.util import (splitext, - format_size, display_path, backup_dir, ask, - unpack_file, create_download_cache_folder, cache_download) -from pip.vcs import vcs -from pip.log import logger - - -__all__ = ['xmlrpclib_transport', 'get_file_content', 'urlopen', - 'is_url', 'url_to_path', 'path_to_url', 'path_to_url2', - 'geturl', 'is_archive_file', 'unpack_vcs_link', - 'unpack_file_url', 'is_vcs_url', 'is_file_url', 'unpack_http_url'] - - -xmlrpclib_transport = xmlrpclib.Transport() - - -def get_file_content(url, comes_from=None): - """Gets the content of a file; it may be a filename, file: URL, or - http: URL. Returns (location, content)""" - match = _scheme_re.search(url) - if match: - scheme = match.group(1).lower() - if (scheme == 'file' and comes_from - and comes_from.startswith('http')): - raise InstallationError( - 'Requirements file %s references URL %s, which is local' - % (comes_from, url)) - if scheme == 'file': - path = url.split(':', 1)[1] - path = path.replace('\\', '/') - match = _url_slash_drive_re.match(path) - if match: - path = match.group(1) + ':' + path.split('|', 1)[1] - path = urllib.unquote(path) - if path.startswith('/'): - path = '/' + path.lstrip('/') - url = path - else: - ## FIXME: catch some errors - resp = urlopen(url) - return geturl(resp), resp.read() - try: - f = open(url) - content = f.read() - except IOError, e: - raise InstallationError('Could not open requirements file: %s' % str(e)) - else: - f.close() - return url, content - - -_scheme_re = re.compile(r'^(http|https|file):', re.I) -_url_slash_drive_re = re.compile(r'/*([a-z])\|', re.I) - -class URLOpener(object): - """ - pip's own URL helper that adds HTTP auth and proxy support - """ - def __init__(self): - self.passman = urllib2.HTTPPasswordMgrWithDefaultRealm() - - def __call__(self, url): - """ - If the given url contains auth info or if a normal request gets a 401 - response, an attempt is made to fetch the resource using basic HTTP - auth. - - """ - url, username, password = self.extract_credentials(url) - if username is None: - try: - response = urllib2.urlopen(self.get_request(url)) - except urllib2.HTTPError, e: - if e.code != 401: - raise - response = self.get_response(url) - else: - response = self.get_response(url, username, password) - return response - - def get_request(self, url): - """ - Wraps the URL to retrieve to protects against "creative" - interpretation of the RFC: http://bugs.python.org/issue8732 - """ - if isinstance(url, basestring): - url = urllib2.Request(url, headers={'Accept-encoding': 'identity'}) - return url - - def get_response(self, url, username=None, password=None): - """ - does the dirty work of actually getting the rsponse object using urllib2 - and its HTTP auth builtins. - """ - scheme, netloc, path, query, frag = urlparse.urlsplit(url) - pass_url = urlparse.urlunsplit(('_none_', netloc, path, query, frag)).replace('_none_://', '', 1) - req = self.get_request(url) - - stored_username, stored_password = self.passman.find_user_password(None, netloc) - # see if we have a password stored - if stored_username is None: - if username is None and self.prompting: - username = urllib.quote(raw_input('User for %s: ' % netloc)) - password = urllib.quote(getpass.getpass('Password: ')) - if username and password: - self.passman.add_password(None, netloc, username, password) - stored_username, stored_password = self.passman.find_user_password(None, netloc) - authhandler = urllib2.HTTPBasicAuthHandler(self.passman) - opener = urllib2.build_opener(authhandler) - # FIXME: should catch a 401 and offer to let the user reenter credentials - return opener.open(req) - - def setup(self, proxystr='', prompting=True): - """ - Sets the proxy handler given the option passed on the command - line. If an empty string is passed it looks at the HTTP_PROXY - environment variable. - """ - self.prompting = prompting - proxy = self.get_proxy(proxystr) - if proxy: - proxy_support = urllib2.ProxyHandler({"http": proxy, "ftp": proxy}) - opener = urllib2.build_opener(proxy_support, urllib2.CacheFTPHandler) - urllib2.install_opener(opener) - - def parse_credentials(self, netloc): - if "@" in netloc: - userinfo = netloc.rsplit("@", 1)[0] - if ":" in userinfo: - return userinfo.split(":", 1) - return userinfo, None - return None, None - - def extract_credentials(self, url): - """ - Extracts user/password from a url. - - Returns a tuple: - (url-without-auth, username, password) - """ - if isinstance(url, urllib2.Request): - result = urlparse.urlsplit(url.get_full_url()) - else: - result = urlparse.urlsplit(url) - scheme, netloc, path, query, frag = result - - username, password = self.parse_credentials(netloc) - if username is None: - return url, None, None - elif password is None and self.prompting: - # remove the auth credentials from the url part - netloc = netloc.replace('%s@' % username, '', 1) - # prompt for the password - prompt = 'Password for %s@%s: ' % (username, netloc) - password = urllib.quote(getpass.getpass(prompt)) - else: - # remove the auth credentials from the url part - netloc = netloc.replace('%s:%s@' % (username, password), '', 1) - - target_url = urlparse.urlunsplit((scheme, netloc, path, query, frag)) - return target_url, username, password - - def get_proxy(self, proxystr=''): - """ - Get the proxy given the option passed on the command line. - If an empty string is passed it looks at the HTTP_PROXY - environment variable. - """ - if not proxystr: - proxystr = os.environ.get('HTTP_PROXY', '') - if proxystr: - if '@' in proxystr: - user_password, server_port = proxystr.split('@', 1) - if ':' in user_password: - user, password = user_password.split(':', 1) - else: - user = user_password - prompt = 'Password for %s@%s: ' % (user, server_port) - password = urllib.quote(getpass.getpass(prompt)) - return '%s:%s@%s' % (user, password, server_port) - else: - return proxystr - else: - return None - -urlopen = URLOpener() - - -def is_url(name): - """Returns true if the name looks like a URL""" - if ':' not in name: - return False - scheme = name.split(':', 1)[0].lower() - return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes - - -def url_to_path(url): - """ - Convert a file: URL to a path. - """ - assert url.startswith('file:'), ( - "You can only turn file: urls into filenames (not %r)" % url) - path = url[len('file:'):].lstrip('/') - path = urllib.unquote(path) - if _url_drive_re.match(path): - path = path[0] + ':' + path[2:] - else: - path = '/' + path - return path - - -_drive_re = re.compile('^([a-z]):', re.I) -_url_drive_re = re.compile('^([a-z])[:|]', re.I) - - -def path_to_url(path): - """ - Convert a path to a file: URL. The path will be made absolute. - """ - path = os.path.normcase(os.path.abspath(path)) - if _drive_re.match(path): - path = path[0] + '|' + path[2:] - url = urllib.quote(path) - url = url.replace(os.path.sep, '/') - url = url.lstrip('/') - return 'file:///' + url - - -def path_to_url2(path): - """ - Convert a path to a file: URL. The path will be made absolute and have - quoted path parts. - """ - path = os.path.normpath(os.path.abspath(path)) - drive, path = os.path.splitdrive(path) - filepath = path.split(os.path.sep) - url = '/'.join([urllib.quote(part) for part in filepath]) - if not drive: - url = url.lstrip('/') - return 'file:///' + drive + url - - -def geturl(urllib2_resp): - """ - Use instead of urllib.addinfourl.geturl(), which appears to have - some issues with dropping the double slash for certain schemes - (e.g. file://). This implementation is probably over-eager, as it - always restores '://' if it is missing, and it appears some url - schemata aren't always followed by '//' after the colon, but as - far as I know pip doesn't need any of those. - The URI RFC can be found at: http://tools.ietf.org/html/rfc1630 - - This function assumes that - scheme:/foo/bar - is the same as - scheme:///foo/bar - """ - url = urllib2_resp.geturl() - scheme, rest = url.split(':', 1) - if rest.startswith('//'): - return url - else: - # FIXME: write a good test to cover it - return '%s://%s' % (scheme, rest) - - -def is_archive_file(name): - """Return True if `name` is a considered as an archive file.""" - archives = ('.zip', '.tar.gz', '.tar.bz2', '.tgz', '.tar', '.pybundle') - ext = splitext(name)[1].lower() - if ext in archives: - return True - return False - - -def unpack_vcs_link(link, location, only_download=False): - vcs_backend = _get_used_vcs_backend(link) - if only_download: - vcs_backend.export(location) - else: - vcs_backend.unpack(location) - - -def unpack_file_url(link, location): - source = url_to_path(link.url) - content_type = mimetypes.guess_type(source)[0] - if os.path.isdir(source): - # delete the location since shutil will create it again :( - if os.path.isdir(location): - shutil.rmtree(location) - copytree(source, location) - else: - unpack_file(source, location, content_type, link) - - -def _get_used_vcs_backend(link): - for backend in vcs.backends: - if link.scheme in backend.schemes: - vcs_backend = backend(link.url) - return vcs_backend - - -def is_vcs_url(link): - return bool(_get_used_vcs_backend(link)) - - -def is_file_url(link): - return link.url.lower().startswith('file:') - - -def _check_md5(download_hash, link): - download_hash = download_hash.hexdigest() - if download_hash != link.md5_hash: - logger.fatal("MD5 hash of the package %s (%s) doesn't match the expected hash %s!" - % (link, download_hash, link.md5_hash)) - raise InstallationError('Bad MD5 hash for package %s' % link) - - -def _get_md5_from_file(target_file, link): - download_hash = md5() - fp = open(target_file, 'rb') - while 1: - chunk = fp.read(4096) - if not chunk: - break - download_hash.update(chunk) - fp.close() - return download_hash - - -def _download_url(resp, link, temp_location): - fp = open(temp_location, 'wb') - download_hash = None - if link.md5_hash: - download_hash = md5() - try: - total_length = int(resp.info()['content-length']) - except (ValueError, KeyError): - total_length = 0 - downloaded = 0 - show_progress = total_length > 40*1000 or not total_length - show_url = link.show_url - try: - if show_progress: - ## FIXME: the URL can get really long in this message: - if total_length: - logger.start_progress('Downloading %s (%s): ' % (show_url, format_size(total_length))) - else: - logger.start_progress('Downloading %s (unknown size): ' % show_url) - else: - logger.notify('Downloading %s' % show_url) - logger.debug('Downloading from URL %s' % link) - - while 1: - chunk = resp.read(4096) - if not chunk: - break - downloaded += len(chunk) - if show_progress: - if not total_length: - logger.show_progress('%s' % format_size(downloaded)) - else: - logger.show_progress('%3i%% %s' % (100*downloaded/total_length, format_size(downloaded))) - if link.md5_hash: - download_hash.update(chunk) - fp.write(chunk) - fp.close() - finally: - if show_progress: - logger.end_progress('%s downloaded' % format_size(downloaded)) - return download_hash - - -def _copy_file(filename, location, content_type, link): - copy = True - download_location = os.path.join(location, link.filename) - if os.path.exists(download_location): - response = ask('The file %s exists. (i)gnore, (w)ipe, (b)ackup ' - % display_path(download_location), ('i', 'w', 'b')) - if response == 'i': - copy = False - elif response == 'w': - logger.warn('Deleting %s' % display_path(download_location)) - os.remove(download_location) - elif response == 'b': - dest_file = backup_dir(download_location) - logger.warn('Backing up %s to %s' - % (display_path(download_location), display_path(dest_file))) - shutil.move(download_location, dest_file) - if copy: - shutil.copy(filename, download_location) - logger.indent -= 2 - logger.notify('Saved %s' % display_path(download_location)) - - -def unpack_http_url(link, location, download_cache, only_download): - temp_dir = tempfile.mkdtemp('-unpack', 'pip-') - target_url = link.url.split('#', 1)[0] - target_file = None - download_hash = None - if download_cache: - target_file = os.path.join(download_cache, - urllib.quote(target_url, '')) - if not os.path.isdir(download_cache): - create_download_cache_folder(download_cache) - if (target_file - and os.path.exists(target_file) - and os.path.exists(target_file+'.content-type')): - fp = open(target_file+'.content-type') - content_type = fp.read().strip() - fp.close() - if link.md5_hash: - download_hash = _get_md5_from_file(target_file, link) - temp_location = target_file - logger.notify('Using download cache from %s' % target_file) - else: - resp = _get_response_from_url(target_url, link) - content_type = resp.info()['content-type'] - filename = link.filename - ext = splitext(filename)[1] - if not ext: - ext = mimetypes.guess_extension(content_type) - if ext: - filename += ext - if not ext and link.url != geturl(resp): - ext = os.path.splitext(geturl(resp))[1] - if ext: - filename += ext - temp_location = os.path.join(temp_dir, filename) - download_hash = _download_url(resp, link, temp_location) - if link.md5_hash: - _check_md5(download_hash, link) - if only_download: - _copy_file(temp_location, location, content_type, link) - else: - unpack_file(temp_location, location, content_type, link) - if target_file and target_file != temp_location: - cache_download(target_file, temp_location, content_type) - if target_file is None: - os.unlink(temp_location) - os.rmdir(temp_dir) - - -def _get_response_from_url(target_url, link): - try: - resp = urlopen(target_url) - except urllib2.HTTPError, e: - logger.fatal("HTTP error %s while getting %s" % (e.code, link)) - raise - except IOError, e: - # Typically an FTP error - logger.fatal("Error %s while getting %s" % (e, link)) - raise - return resp - -class Urllib2HeadRequest(urllib2.Request): - def get_method(self): - return "HEAD" diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/exceptions.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/exceptions.py deleted file mode 100644 index 1ad1a616..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/exceptions.py +++ /dev/null @@ -1,17 +0,0 @@ -"""Exceptions used throughout package""" - - -class InstallationError(Exception): - """General exception during installation""" - - -class UninstallationError(Exception): - """General exception during uninstallation""" - - -class DistributionNotFound(InstallationError): - """Raised when a distribution cannot be found to satisfy a requirement""" - - -class BadCommand(Exception): - """Raised when virtualenv or a command is not found""" diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/index.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/index.py deleted file mode 100644 index e42d8c86..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/index.py +++ /dev/null @@ -1,686 +0,0 @@ -"""Routines related to PyPI, indexes""" - -import sys -import os -import re -import mimetypes -import threading -import posixpath -import pkg_resources -import urllib -import urllib2 -import urlparse -import httplib -import random -import socket -import string -from Queue import Queue -from Queue import Empty as QueueEmpty -from pip.log import logger -from pip.util import Inf -from pip.util import normalize_name, splitext -from pip.exceptions import DistributionNotFound -from pip.backwardcompat import WindowsError, product -from pip.download import urlopen, path_to_url2, url_to_path, geturl, Urllib2HeadRequest - -__all__ = ['PackageFinder'] - - -DEFAULT_MIRROR_URL = "last.pypi.python.org" - - -class PackageFinder(object): - """This finds packages. - - This is meant to match easy_install's technique for looking for - packages, by reading pages and looking for appropriate links - """ - - def __init__(self, find_links, index_urls, - use_mirrors=False, mirrors=None, main_mirror_url=None): - self.find_links = find_links - self.index_urls = index_urls - self.dependency_links = [] - self.cache = PageCache() - # These are boring links that have already been logged somehow: - self.logged_links = set() - if use_mirrors: - self.mirror_urls = self._get_mirror_urls(mirrors, main_mirror_url) - logger.info('Using PyPI mirrors: %s' % ', '.join(self.mirror_urls)) - else: - self.mirror_urls = [] - - def add_dependency_links(self, links): - ## FIXME: this shouldn't be global list this, it should only - ## apply to requirements of the package that specifies the - ## dependency_links value - ## FIXME: also, we should track comes_from (i.e., use Link) - self.dependency_links.extend(links) - - @staticmethod - def _sort_locations(locations): - """ - Sort locations into "files" (archives) and "urls", and return - a pair of lists (files,urls) - """ - files = [] - urls = [] - - # puts the url for the given file path into the appropriate - # list - def sort_path(path): - url = path_to_url2(path) - if mimetypes.guess_type(url, strict=False)[0] == 'text/html': - urls.append(url) - else: - files.append(url) - - for url in locations: - if url.startswith('file:'): - path = url_to_path(url) - if os.path.isdir(path): - path = os.path.realpath(path) - for item in os.listdir(path): - sort_path(os.path.join(path, item)) - elif os.path.isfile(path): - sort_path(path) - else: - urls.append(url) - return files, urls - - def find_requirement(self, req, upgrade): - url_name = req.url_name - # Only check main index if index URL is given: - main_index_url = None - if self.index_urls: - # Check that we have the url_name correctly spelled: - main_index_url = Link(posixpath.join(self.index_urls[0], url_name)) - # This will also cache the page, so it's okay that we get it again later: - page = self._get_page(main_index_url, req) - if page is None: - url_name = self._find_url_name(Link(self.index_urls[0]), url_name, req) or req.url_name - - # Combine index URLs with mirror URLs here to allow - # adding more index URLs from requirements files - all_index_urls = self.index_urls + self.mirror_urls - - def mkurl_pypi_url(url): - loc = posixpath.join(url, url_name) - # For maximum compatibility with easy_install, ensure the path - # ends in a trailing slash. Although this isn't in the spec - # (and PyPI can handle it without the slash) some other index - # implementations might break if they relied on easy_install's behavior. - if not loc.endswith('/'): - loc = loc + '/' - return loc - if url_name is not None: - locations = [ - mkurl_pypi_url(url) - for url in all_index_urls] + self.find_links - else: - locations = list(self.find_links) - locations.extend(self.dependency_links) - for version in req.absolute_versions: - if url_name is not None and main_index_url is not None: - locations = [ - posixpath.join(main_index_url.url, version)] + locations - - file_locations, url_locations = self._sort_locations(locations) - - locations = [Link(url) for url in url_locations] - logger.debug('URLs to search for versions for %s:' % req) - for location in locations: - logger.debug('* %s' % location) - found_versions = [] - found_versions.extend( - self._package_versions( - [Link(url, '-f') for url in self.find_links], req.name.lower())) - page_versions = [] - for page in self._get_pages(locations, req): - logger.debug('Analyzing links from page %s' % page.url) - logger.indent += 2 - try: - page_versions.extend(self._package_versions(page.links, req.name.lower())) - finally: - logger.indent -= 2 - dependency_versions = list(self._package_versions( - [Link(url) for url in self.dependency_links], req.name.lower())) - if dependency_versions: - logger.info('dependency_links found: %s' % ', '.join([link.url for parsed, link, version in dependency_versions])) - file_versions = list(self._package_versions( - [Link(url) for url in file_locations], req.name.lower())) - if not found_versions and not page_versions and not dependency_versions and not file_versions: - logger.fatal('Could not find any downloads that satisfy the requirement %s' % req) - raise DistributionNotFound('No distributions at all found for %s' % req) - if req.satisfied_by is not None: - found_versions.append((req.satisfied_by.parsed_version, Inf, req.satisfied_by.version)) - if file_versions: - file_versions.sort(reverse=True) - logger.info('Local files found: %s' % ', '.join([url_to_path(link.url) for parsed, link, version in file_versions])) - found_versions = file_versions + found_versions - all_versions = found_versions + page_versions + dependency_versions - applicable_versions = [] - for (parsed_version, link, version) in all_versions: - if version not in req.req: - logger.info("Ignoring link %s, version %s doesn't match %s" - % (link, version, ','.join([''.join(s) for s in req.req.specs]))) - continue - applicable_versions.append((link, version)) - applicable_versions = sorted(applicable_versions, key=lambda v: pkg_resources.parse_version(v[1]), reverse=True) - existing_applicable = bool([link for link, version in applicable_versions if link is Inf]) - if not upgrade and existing_applicable: - if applicable_versions[0][1] is Inf: - logger.info('Existing installed version (%s) is most up-to-date and satisfies requirement' - % req.satisfied_by.version) - else: - logger.info('Existing installed version (%s) satisfies requirement (most up-to-date version is %s)' - % (req.satisfied_by.version, applicable_versions[0][1])) - return None - if not applicable_versions: - logger.fatal('Could not find a version that satisfies the requirement %s (from versions: %s)' - % (req, ', '.join([version for parsed_version, link, version in found_versions]))) - raise DistributionNotFound('No distributions matching the version for %s' % req) - if applicable_versions[0][0] is Inf: - # We have an existing version, and its the best version - logger.info('Installed version (%s) is most up-to-date (past versions: %s)' - % (req.satisfied_by.version, ', '.join([version for link, version in applicable_versions[1:]]) or 'none')) - return None - if len(applicable_versions) > 1: - logger.info('Using version %s (newest of versions: %s)' % - (applicable_versions[0][1], ', '.join([version for link, version in applicable_versions]))) - return applicable_versions[0][0] - - def _find_url_name(self, index_url, url_name, req): - """Finds the true URL name of a package, when the given name isn't quite correct. - This is usually used to implement case-insensitivity.""" - if not index_url.url.endswith('/'): - # Vaguely part of the PyPI API... weird but true. - ## FIXME: bad to modify this? - index_url.url += '/' - page = self._get_page(index_url, req) - if page is None: - logger.fatal('Cannot fetch index base URL %s' % index_url) - return - norm_name = normalize_name(req.url_name) - for link in page.links: - base = posixpath.basename(link.path.rstrip('/')) - if norm_name == normalize_name(base): - logger.notify('Real name of requirement %s is %s' % (url_name, base)) - return base - return None - - def _get_pages(self, locations, req): - """Yields (page, page_url) from the given locations, skipping - locations that have errors, and adding download/homepage links""" - pending_queue = Queue() - for location in locations: - pending_queue.put(location) - done = [] - seen = set() - threads = [] - for i in range(min(10, len(locations))): - t = threading.Thread(target=self._get_queued_page, args=(req, pending_queue, done, seen)) - t.setDaemon(True) - threads.append(t) - t.start() - for t in threads: - t.join() - return done - - _log_lock = threading.Lock() - - def _get_queued_page(self, req, pending_queue, done, seen): - while 1: - try: - location = pending_queue.get(False) - except QueueEmpty: - return - if location in seen: - continue - seen.add(location) - page = self._get_page(location, req) - if page is None: - continue - done.append(page) - for link in page.rel_links(): - pending_queue.put(link) - - _egg_fragment_re = re.compile(r'#egg=([^&]*)') - _egg_info_re = re.compile(r'([a-z0-9_.]+)-([a-z0-9_.-]+)', re.I) - _py_version_re = re.compile(r'-py([123]\.[0-9])$') - - def _sort_links(self, links): - "Returns elements of links in order, non-egg links first, egg links second, while eliminating duplicates" - eggs, no_eggs = [], [] - seen = set() - for link in links: - if link not in seen: - seen.add(link) - if link.egg_fragment: - eggs.append(link) - else: - no_eggs.append(link) - return no_eggs + eggs - - def _package_versions(self, links, search_name): - for link in self._sort_links(links): - for v in self._link_package_versions(link, search_name): - yield v - - def _link_package_versions(self, link, search_name): - """ - Return an iterable of triples (pkg_resources_version_key, - link, python_version) that can be extracted from the given - link. - - Meant to be overridden by subclasses, not called by clients. - """ - if link.egg_fragment: - egg_info = link.egg_fragment - else: - egg_info, ext = link.splitext() - if not ext: - if link not in self.logged_links: - logger.debug('Skipping link %s; not a file' % link) - self.logged_links.add(link) - return [] - if egg_info.endswith('.tar'): - # Special double-extension case: - egg_info = egg_info[:-4] - ext = '.tar' + ext - if ext not in ('.tar.gz', '.tar.bz2', '.tar', '.tgz', '.zip'): - if link not in self.logged_links: - logger.debug('Skipping link %s; unknown archive format: %s' % (link, ext)) - self.logged_links.add(link) - return [] - version = self._egg_info_matches(egg_info, search_name, link) - if version is None: - logger.debug('Skipping link %s; wrong project name (not %s)' % (link, search_name)) - return [] - match = self._py_version_re.search(version) - if match: - version = version[:match.start()] - py_version = match.group(1) - if py_version != sys.version[:3]: - logger.debug('Skipping %s because Python version is incorrect' % link) - return [] - logger.debug('Found link %s, version: %s' % (link, version)) - return [(pkg_resources.parse_version(version), - link, - version)] - - def _egg_info_matches(self, egg_info, search_name, link): - match = self._egg_info_re.search(egg_info) - if not match: - logger.debug('Could not parse version from link: %s' % link) - return None - name = match.group(0).lower() - # To match the "safe" name that pkg_resources creates: - name = name.replace('_', '-') - if name.startswith(search_name.lower()): - return match.group(0)[len(search_name):].lstrip('-') - else: - return None - - def _get_page(self, link, req): - return HTMLPage.get_page(link, req, cache=self.cache) - - def _get_mirror_urls(self, mirrors=None, main_mirror_url=None): - """Retrieves a list of URLs from the main mirror DNS entry - unless a list of mirror URLs are passed. - """ - if not mirrors: - mirrors = get_mirrors(main_mirror_url) - # Should this be made "less random"? E.g. netselect like? - random.shuffle(mirrors) - - mirror_urls = set() - for mirror_url in mirrors: - # Make sure we have a valid URL - if not ("http://" or "https://" or "file://") in mirror_url: - mirror_url = "http://%s" % mirror_url - if not mirror_url.endswith("/simple"): - mirror_url = "%s/simple/" % mirror_url - mirror_urls.add(mirror_url) - - return list(mirror_urls) - - -class PageCache(object): - """Cache of HTML pages""" - - failure_limit = 3 - - def __init__(self): - self._failures = {} - self._pages = {} - self._archives = {} - - def too_many_failures(self, url): - return self._failures.get(url, 0) >= self.failure_limit - - def get_page(self, url): - return self._pages.get(url) - - def is_archive(self, url): - return self._archives.get(url, False) - - def set_is_archive(self, url, value=True): - self._archives[url] = value - - def add_page_failure(self, url, level): - self._failures[url] = self._failures.get(url, 0)+level - - def add_page(self, urls, page): - for url in urls: - self._pages[url] = page - - -class HTMLPage(object): - """Represents one page, along with its URL""" - - ## FIXME: these regexes are horrible hacks: - _homepage_re = re.compile(r'<th>\s*home\s*page', re.I) - _download_re = re.compile(r'<th>\s*download\s+url', re.I) - ## These aren't so aweful: - _rel_re = re.compile("""<[^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*>""", re.I) - _href_re = re.compile('href=(?:"([^"]*)"|\'([^\']*)\'|([^>\\s\\n]*))', re.I|re.S) - _base_re = re.compile(r"""<base\s+href\s*=\s*['"]?([^'">]+)""", re.I) - - def __init__(self, content, url, headers=None): - self.content = content - self.url = url - self.headers = headers - - def __str__(self): - return self.url - - @classmethod - def get_page(cls, link, req, cache=None, skip_archives=True): - url = link.url - url = url.split('#', 1)[0] - if cache.too_many_failures(url): - return None - - # Check for VCS schemes that do not support lookup as web pages. - from pip.vcs import VcsSupport - for scheme in VcsSupport.schemes: - if url.lower().startswith(scheme) and url[len(scheme)] in '+:': - logger.debug('Cannot look at %(scheme)s URL %(link)s' % locals()) - return None - - if cache is not None: - inst = cache.get_page(url) - if inst is not None: - return inst - try: - if skip_archives: - if cache is not None: - if cache.is_archive(url): - return None - filename = link.filename - for bad_ext in ['.tar', '.tar.gz', '.tar.bz2', '.tgz', '.zip']: - if filename.endswith(bad_ext): - content_type = cls._get_content_type(url) - if content_type.lower().startswith('text/html'): - break - else: - logger.debug('Skipping page %s because of Content-Type: %s' % (link, content_type)) - if cache is not None: - cache.set_is_archive(url) - return None - logger.debug('Getting page %s' % url) - - # Tack index.html onto file:// URLs that point to directories - (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url) - if scheme == 'file' and os.path.isdir(urllib.url2pathname(path)): - # add trailing slash if not present so urljoin doesn't trim final segment - if not url.endswith('/'): - url += '/' - url = urlparse.urljoin(url, 'index.html') - logger.debug(' file: URL is directory, getting %s' % url) - - resp = urlopen(url) - - real_url = geturl(resp) - headers = resp.info() - inst = cls(resp.read(), real_url, headers) - except (urllib2.HTTPError, urllib2.URLError, socket.timeout, socket.error, OSError, WindowsError), e: - desc = str(e) - if isinstance(e, socket.timeout): - log_meth = logger.info - level =1 - desc = 'timed out' - elif isinstance(e, urllib2.URLError): - log_meth = logger.info - if hasattr(e, 'reason') and isinstance(e.reason, socket.timeout): - desc = 'timed out' - level = 1 - else: - level = 2 - elif isinstance(e, urllib2.HTTPError) and e.code == 404: - ## FIXME: notify? - log_meth = logger.info - level = 2 - else: - log_meth = logger.info - level = 1 - log_meth('Could not fetch URL %s: %s' % (link, desc)) - log_meth('Will skip URL %s when looking for download links for %s' % (link.url, req)) - if cache is not None: - cache.add_page_failure(url, level) - return None - if cache is not None: - cache.add_page([url, real_url], inst) - return inst - - @staticmethod - def _get_content_type(url): - """Get the Content-Type of the given url, using a HEAD request""" - scheme, netloc, path, query, fragment = urlparse.urlsplit(url) - if not scheme in ('http', 'https', 'ftp', 'ftps'): - ## FIXME: some warning or something? - ## assertion error? - return '' - req = Urllib2HeadRequest(url, headers={'Host': netloc}) - resp = urlopen(req) - try: - if hasattr(resp, 'code') and resp.code != 200 and scheme not in ('ftp', 'ftps'): - ## FIXME: doesn't handle redirects - return '' - return resp.info().get('content-type', '') - finally: - resp.close() - - @property - def base_url(self): - if not hasattr(self, "_base_url"): - match = self._base_re.search(self.content) - if match: - self._base_url = match.group(1) - else: - self._base_url = self.url - return self._base_url - - @property - def links(self): - """Yields all links in the page""" - for match in self._href_re.finditer(self.content): - url = match.group(1) or match.group(2) or match.group(3) - url = self.clean_link(urlparse.urljoin(self.base_url, url)) - yield Link(url, self) - - def rel_links(self): - for url in self.explicit_rel_links(): - yield url - for url in self.scraped_rel_links(): - yield url - - def explicit_rel_links(self, rels=('homepage', 'download')): - """Yields all links with the given relations""" - for match in self._rel_re.finditer(self.content): - found_rels = match.group(1).lower().split() - for rel in rels: - if rel in found_rels: - break - else: - continue - match = self._href_re.search(match.group(0)) - if not match: - continue - url = match.group(1) or match.group(2) or match.group(3) - url = self.clean_link(urlparse.urljoin(self.base_url, url)) - yield Link(url, self) - - def scraped_rel_links(self): - for regex in (self._homepage_re, self._download_re): - match = regex.search(self.content) - if not match: - continue - href_match = self._href_re.search(self.content, pos=match.end()) - if not href_match: - continue - url = match.group(1) or match.group(2) or match.group(3) - if not url: - continue - url = self.clean_link(urlparse.urljoin(self.base_url, url)) - yield Link(url, self) - - _clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) - - def clean_link(self, url): - """Makes sure a link is fully encoded. That is, if a ' ' shows up in - the link, it will be rewritten to %20 (while not over-quoting - % or other characters).""" - return self._clean_re.sub( - lambda match: '%%%2x' % ord(match.group(0)), url) - - -class Link(object): - - def __init__(self, url, comes_from=None): - self.url = url - self.comes_from = comes_from - - def __str__(self): - if self.comes_from: - return '%s (from %s)' % (self.url, self.comes_from) - else: - return self.url - - def __repr__(self): - return '<Link %s>' % self - - def __eq__(self, other): - return self.url == other.url - - def __hash__(self): - return hash(self.url) - - @property - def filename(self): - url = self.url - url = url.split('#', 1)[0] - url = url.split('?', 1)[0] - url = url.rstrip('/') - name = posixpath.basename(url) - assert name, ( - 'URL %r produced no filename' % url) - return name - - @property - def scheme(self): - return urlparse.urlsplit(self.url)[0] - - @property - def path(self): - return urlparse.urlsplit(self.url)[2] - - def splitext(self): - return splitext(posixpath.basename(self.path.rstrip('/'))) - - _egg_fragment_re = re.compile(r'#egg=([^&]*)') - - @property - def egg_fragment(self): - match = self._egg_fragment_re.search(self.url) - if not match: - return None - return match.group(1) - - _md5_re = re.compile(r'md5=([a-f0-9]+)') - - @property - def md5_hash(self): - match = self._md5_re.search(self.url) - if match: - return match.group(1) - return None - - @property - def show_url(self): - return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0]) - - -def get_requirement_from_url(url): - """Get a requirement from the URL, if possible. This looks for #egg - in the URL""" - link = Link(url) - egg_info = link.egg_fragment - if not egg_info: - egg_info = splitext(link.filename)[0] - return package_to_requirement(egg_info) - - -def package_to_requirement(package_name): - """Translate a name like Foo-1.2 to Foo==1.3""" - match = re.search(r'^(.*?)(-dev|-\d.*)', package_name) - if match: - name = match.group(1) - version = match.group(2) - else: - name = package_name - version = '' - if version: - return '%s==%s' % (name, version) - else: - return name - - -def get_mirrors(hostname=None): - """Return the list of mirrors from the last record found on the DNS - entry:: - - >>> from pip.index import get_mirrors - >>> get_mirrors() - ['a.pypi.python.org', 'b.pypi.python.org', 'c.pypi.python.org', - 'd.pypi.python.org'] - - Originally written for the distutils2 project by Alexis Metaireau. - """ - if hostname is None: - hostname = DEFAULT_MIRROR_URL - - # return the last mirror registered on PyPI. - try: - hostname = socket.gethostbyname_ex(hostname)[0] - except socket.gaierror: - return [] - end_letter = hostname.split(".", 1) - - # determine the list from the last one. - return ["%s.%s" % (s, end_letter[1]) for s in string_range(end_letter[0])] - - -def string_range(last): - """Compute the range of string between "a" and last. - - This works for simple "a to z" lists, but also for "a to zz" lists. - """ - for k in range(len(last)): - for x in product(string.ascii_lowercase, repeat=k+1): - result = ''.join(x) - yield result - if result == last: - return - diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/locations.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/locations.py deleted file mode 100644 index 4254ef2f..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/locations.py +++ /dev/null @@ -1,45 +0,0 @@ -"""Locations where we look for configs, install stuff, etc""" - -import sys -import os -from distutils import sysconfig - - -def running_under_virtualenv(): - """ - Return True if we're running inside a virtualenv, False otherwise. - - """ - return hasattr(sys, 'real_prefix') - - -if running_under_virtualenv(): - ## FIXME: is build/ a good name? - build_prefix = os.path.join(sys.prefix, 'build') - src_prefix = os.path.join(sys.prefix, 'src') -else: - ## FIXME: this isn't a very good default - build_prefix = os.path.join(os.getcwd(), 'build') - src_prefix = os.path.join(os.getcwd(), 'src') - -# FIXME doesn't account for venv linked to global site-packages - -site_packages = sysconfig.get_python_lib() -user_dir = os.path.expanduser('~') -if sys.platform == 'win32': - bin_py = os.path.join(sys.prefix, 'Scripts') - # buildout uses 'bin' on Windows too? - if not os.path.exists(bin_py): - bin_py = os.path.join(sys.prefix, 'bin') - user_dir = os.environ.get('APPDATA', user_dir) # Use %APPDATA% for roaming - default_storage_dir = os.path.join(user_dir, 'pip') - default_config_file = os.path.join(default_storage_dir, 'pip.ini') - default_log_file = os.path.join(default_storage_dir, 'pip.log') -else: - bin_py = os.path.join(sys.prefix, 'bin') - default_storage_dir = os.path.join(user_dir, '.pip') - default_config_file = os.path.join(default_storage_dir, 'pip.conf') - default_log_file = os.path.join(default_storage_dir, 'pip.log') - # Forcing to use /usr/local/bin for standard Mac OS X framework installs - if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/': - bin_py = '/usr/local/bin' diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/log.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/log.py deleted file mode 100644 index 0218ab1a..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/log.py +++ /dev/null @@ -1,181 +0,0 @@ -"""Logging -""" - -import sys -import logging - - -class Logger(object): - - """ - Logging object for use in command-line script. Allows ranges of - levels, to avoid some redundancy of displayed information. - """ - - VERBOSE_DEBUG = logging.DEBUG-1 - DEBUG = logging.DEBUG - INFO = logging.INFO - NOTIFY = (logging.INFO+logging.WARN)/2 - WARN = WARNING = logging.WARN - ERROR = logging.ERROR - FATAL = logging.FATAL - - LEVELS = [VERBOSE_DEBUG, DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL] - - def __init__(self): - self.consumers = [] - self.indent = 0 - self.explicit_levels = False - self.in_progress = None - self.in_progress_hanging = False - - def debug(self, msg, *args, **kw): - self.log(self.DEBUG, msg, *args, **kw) - - def info(self, msg, *args, **kw): - self.log(self.INFO, msg, *args, **kw) - - def notify(self, msg, *args, **kw): - self.log(self.NOTIFY, msg, *args, **kw) - - def warn(self, msg, *args, **kw): - self.log(self.WARN, msg, *args, **kw) - - def error(self, msg, *args, **kw): - self.log(self.WARN, msg, *args, **kw) - - def fatal(self, msg, *args, **kw): - self.log(self.FATAL, msg, *args, **kw) - - def log(self, level, msg, *args, **kw): - if args: - if kw: - raise TypeError( - "You may give positional or keyword arguments, not both") - args = args or kw - rendered = None - for consumer_level, consumer in self.consumers: - if self.level_matches(level, consumer_level): - if (self.in_progress_hanging - and consumer in (sys.stdout, sys.stderr)): - self.in_progress_hanging = False - sys.stdout.write('\n') - sys.stdout.flush() - if rendered is None: - if args: - rendered = msg % args - else: - rendered = msg - rendered = ' '*self.indent + rendered - if self.explicit_levels: - ## FIXME: should this be a name, not a level number? - rendered = '%02i %s' % (level, rendered) - if hasattr(consumer, 'write'): - consumer.write(rendered+'\n') - else: - consumer(rendered) - - def start_progress(self, msg): - assert not self.in_progress, ( - "Tried to start_progress(%r) while in_progress %r" - % (msg, self.in_progress)) - if self.level_matches(self.NOTIFY, self._stdout_level()): - sys.stdout.write(' '*self.indent + msg) - sys.stdout.flush() - self.in_progress_hanging = True - else: - self.in_progress_hanging = False - self.in_progress = msg - self.last_message = None - - def end_progress(self, msg='done.'): - assert self.in_progress, ( - "Tried to end_progress without start_progress") - if self.stdout_level_matches(self.NOTIFY): - if not self.in_progress_hanging: - # Some message has been printed out since start_progress - sys.stdout.write('...' + self.in_progress + msg + '\n') - sys.stdout.flush() - else: - # These erase any messages shown with show_progress (besides .'s) - logger.show_progress('') - logger.show_progress('') - sys.stdout.write(msg + '\n') - sys.stdout.flush() - self.in_progress = None - self.in_progress_hanging = False - - def show_progress(self, message=None): - """If we are in a progress scope, and no log messages have been - shown, write out another '.'""" - if self.in_progress_hanging: - if message is None: - sys.stdout.write('.') - sys.stdout.flush() - else: - if self.last_message: - padding = ' ' * max(0, len(self.last_message)-len(message)) - else: - padding = '' - sys.stdout.write('\r%s%s%s%s' % (' '*self.indent, self.in_progress, message, padding)) - sys.stdout.flush() - self.last_message = message - - def stdout_level_matches(self, level): - """Returns true if a message at this level will go to stdout""" - return self.level_matches(level, self._stdout_level()) - - def _stdout_level(self): - """Returns the level that stdout runs at""" - for level, consumer in self.consumers: - if consumer is sys.stdout: - return level - return self.FATAL - - def level_matches(self, level, consumer_level): - """ - >>> l = Logger() - >>> l.level_matches(3, 4) - False - >>> l.level_matches(3, 2) - True - >>> l.level_matches(slice(None, 3), 3) - False - >>> l.level_matches(slice(None, 3), 2) - True - >>> l.level_matches(slice(1, 3), 1) - True - >>> l.level_matches(slice(2, 3), 1) - False - """ - if isinstance(level, slice): - start, stop = level.start, level.stop - if start is not None and start > consumer_level: - return False - if stop is not None or stop <= consumer_level: - return False - return True - else: - return level >= consumer_level - - @classmethod - def level_for_integer(cls, level): - levels = cls.LEVELS - if level < 0: - return levels[0] - if level >= len(levels): - return levels[-1] - return levels[level] - - def move_stdout_to_stderr(self): - to_remove = [] - to_add = [] - for consumer_level, consumer in self.consumers: - if consumer == sys.stdout: - to_remove.append((consumer_level, consumer)) - to_add.append((consumer_level, sys.stderr)) - for item in to_remove: - self.consumers.remove(item) - self.consumers.extend(to_add) - -logger = Logger() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/req.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/req.py deleted file mode 100644 index 444e7252..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/req.py +++ /dev/null @@ -1,1432 +0,0 @@ -import sys -import os -import shutil -import re -import zipfile -import pkg_resources -import tempfile -import urlparse -import urllib2 -import urllib -import ConfigParser -from distutils.sysconfig import get_python_version -from email.FeedParser import FeedParser -from pip.locations import bin_py, running_under_virtualenv -from pip.exceptions import InstallationError, UninstallationError -from pip.vcs import vcs -from pip.log import logger -from pip.util import display_path, rmtree -from pip.util import ask, backup_dir -from pip.util import is_installable_dir, is_local, dist_is_local -from pip.util import renames, normalize_path, egg_link_path -from pip.util import make_path_relative -from pip import call_subprocess -from pip.backwardcompat import any, copytree -from pip.index import Link -from pip.locations import build_prefix -from pip.download import (get_file_content, is_url, url_to_path, - path_to_url, is_archive_file, - unpack_vcs_link, is_vcs_url, is_file_url, - unpack_file_url, unpack_http_url) - - -PIP_DELETE_MARKER_FILENAME = 'pip-delete-this-directory.txt' - - -class InstallRequirement(object): - - def __init__(self, req, comes_from, source_dir=None, editable=False, - url=None, update=True): - if isinstance(req, basestring): - req = pkg_resources.Requirement.parse(req) - self.req = req - self.comes_from = comes_from - self.source_dir = source_dir - self.editable = editable - self.url = url - self._egg_info_path = None - # This holds the pkg_resources.Distribution object if this requirement - # is already available: - self.satisfied_by = None - # This hold the pkg_resources.Distribution object if this requirement - # conflicts with another installed distribution: - self.conflicts_with = None - self._temp_build_dir = None - self._is_bundle = None - # True if the editable should be updated: - self.update = update - # Set to True after successful installation - self.install_succeeded = None - # UninstallPathSet of uninstalled distribution (for possible rollback) - self.uninstalled = None - - @classmethod - def from_editable(cls, editable_req, comes_from=None, default_vcs=None): - name, url = parse_editable(editable_req, default_vcs) - if url.startswith('file:'): - source_dir = url_to_path(url) - else: - source_dir = None - return cls(name, comes_from, source_dir=source_dir, editable=True, url=url) - - @classmethod - def from_line(cls, name, comes_from=None): - """Creates an InstallRequirement from a name, which might be a - requirement, directory containing 'setup.py', filename, or URL. - """ - url = None - name = name.strip() - req = name - path = os.path.normpath(os.path.abspath(name)) - - if is_url(name): - url = name - ## FIXME: I think getting the requirement here is a bad idea: - #req = get_requirement_from_url(url) - req = None - elif os.path.isdir(path) and (os.path.sep in name or name.startswith('.')): - if not is_installable_dir(path): - raise InstallationError("Directory %r is not installable. File 'setup.py' not found." - % name) - url = path_to_url(name) - #req = get_requirement_from_url(url) - req = None - elif is_archive_file(path): - if not os.path.isfile(path): - logger.warn('Requirement %r looks like a filename, but the file does not exist' - % name) - url = path_to_url(name) - #req = get_requirement_from_url(url) - req = None - return cls(req, comes_from, url=url) - - def __str__(self): - if self.req: - s = str(self.req) - if self.url: - s += ' from %s' % self.url - else: - s = self.url - if self.satisfied_by is not None: - s += ' in %s' % display_path(self.satisfied_by.location) - if self.comes_from: - if isinstance(self.comes_from, basestring): - comes_from = self.comes_from - else: - comes_from = self.comes_from.from_path() - if comes_from: - s += ' (from %s)' % comes_from - return s - - def from_path(self): - if self.req is None: - return None - s = str(self.req) - if self.comes_from: - if isinstance(self.comes_from, basestring): - comes_from = self.comes_from - else: - comes_from = self.comes_from.from_path() - if comes_from: - s += '->' + comes_from - return s - - def build_location(self, build_dir, unpack=True): - if self._temp_build_dir is not None: - return self._temp_build_dir - if self.req is None: - self._temp_build_dir = tempfile.mkdtemp('-build', 'pip-') - self._ideal_build_dir = build_dir - return self._temp_build_dir - if self.editable: - name = self.name.lower() - else: - name = self.name - # FIXME: Is there a better place to create the build_dir? (hg and bzr need this) - if not os.path.exists(build_dir): - _make_build_dir(build_dir) - return os.path.join(build_dir, name) - - def correct_build_location(self): - """If the build location was a temporary directory, this will move it - to a new more permanent location""" - if self.source_dir is not None: - return - assert self.req is not None - assert self._temp_build_dir - old_location = self._temp_build_dir - new_build_dir = self._ideal_build_dir - del self._ideal_build_dir - if self.editable: - name = self.name.lower() - else: - name = self.name - new_location = os.path.join(new_build_dir, name) - if not os.path.exists(new_build_dir): - logger.debug('Creating directory %s' % new_build_dir) - _make_build_dir(new_build_dir) - if os.path.exists(new_location): - raise InstallationError( - 'A package already exists in %s; please remove it to continue' - % display_path(new_location)) - logger.debug('Moving package %s from %s to new location %s' - % (self, display_path(old_location), display_path(new_location))) - shutil.move(old_location, new_location) - self._temp_build_dir = new_location - self.source_dir = new_location - self._egg_info_path = None - - @property - def name(self): - if self.req is None: - return None - return self.req.project_name - - @property - def url_name(self): - if self.req is None: - return None - return urllib.quote(self.req.unsafe_name) - - @property - def setup_py(self): - return os.path.join(self.source_dir, 'setup.py') - - def run_egg_info(self, force_root_egg_info=False): - assert self.source_dir - if self.name: - logger.notify('Running setup.py egg_info for package %s' % self.name) - else: - logger.notify('Running setup.py egg_info for package from %s' % self.url) - logger.indent += 2 - try: - script = self._run_setup_py - script = script.replace('__SETUP_PY__', repr(self.setup_py)) - script = script.replace('__PKG_NAME__', repr(self.name)) - # We can't put the .egg-info files at the root, because then the source code will be mistaken - # for an installed egg, causing problems - if self.editable or force_root_egg_info: - egg_base_option = [] - else: - egg_info_dir = os.path.join(self.source_dir, 'pip-egg-info') - if not os.path.exists(egg_info_dir): - os.makedirs(egg_info_dir) - egg_base_option = ['--egg-base', 'pip-egg-info'] - call_subprocess( - [sys.executable, '-c', script, 'egg_info'] + egg_base_option, - cwd=self.source_dir, filter_stdout=self._filter_install, show_stdout=False, - command_level=logger.VERBOSE_DEBUG, - command_desc='python setup.py egg_info') - finally: - logger.indent -= 2 - if not self.req: - self.req = pkg_resources.Requirement.parse(self.pkg_info()['Name']) - self.correct_build_location() - - ## FIXME: This is a lame hack, entirely for PasteScript which has - ## a self-provided entry point that causes this awkwardness - _run_setup_py = """ -__file__ = __SETUP_PY__ -from setuptools.command import egg_info -def replacement_run(self): - self.mkpath(self.egg_info) - installer = self.distribution.fetch_build_egg - for ep in egg_info.iter_entry_points('egg_info.writers'): - # require=False is the change we're making: - writer = ep.load(require=False) - if writer: - writer(self, ep.name, egg_info.os.path.join(self.egg_info,ep.name)) - self.find_sources() -egg_info.egg_info.run = replacement_run -execfile(__file__) -""" - - def egg_info_data(self, filename): - if self.satisfied_by is not None: - if not self.satisfied_by.has_metadata(filename): - return None - return self.satisfied_by.get_metadata(filename) - assert self.source_dir - filename = self.egg_info_path(filename) - if not os.path.exists(filename): - return None - fp = open(filename, 'r') - data = fp.read() - fp.close() - return data - - def egg_info_path(self, filename): - if self._egg_info_path is None: - if self.editable: - base = self.source_dir - else: - base = os.path.join(self.source_dir, 'pip-egg-info') - filenames = os.listdir(base) - if self.editable: - filenames = [] - for root, dirs, files in os.walk(base): - for dir in vcs.dirnames: - if dir in dirs: - dirs.remove(dir) - for dir in dirs: - # Don't search in anything that looks like a virtualenv environment - if (os.path.exists(os.path.join(root, dir, 'bin', 'python')) - or os.path.exists(os.path.join(root, dir, 'Scripts', 'Python.exe'))): - dirs.remove(dir) - # Also don't search through tests - if dir == 'test' or dir == 'tests': - dirs.remove(dir) - filenames.extend([os.path.join(root, dir) - for dir in dirs]) - filenames = [f for f in filenames if f.endswith('.egg-info')] - - if not filenames: - raise InstallationError('No files/directores in %s (from %s)' % (base, filename)) - assert filenames, "No files/directories in %s (from %s)" % (base, filename) - - # if we have more than one match, we pick the toplevel one. This can - # easily be the case if there is a dist folder which contains an - # extracted tarball for testing purposes. - if len(filenames) > 1: - filenames.sort(key=lambda x: x.count(os.path.sep) + - (os.path.altsep and - x.count(os.path.altsep) or 0)) - self._egg_info_path = os.path.join(base, filenames[0]) - return os.path.join(self._egg_info_path, filename) - - def egg_info_lines(self, filename): - data = self.egg_info_data(filename) - if not data: - return [] - result = [] - for line in data.splitlines(): - line = line.strip() - if not line or line.startswith('#'): - continue - result.append(line) - return result - - def pkg_info(self): - p = FeedParser() - data = self.egg_info_data('PKG-INFO') - if not data: - logger.warn('No PKG-INFO file found in %s' % display_path(self.egg_info_path('PKG-INFO'))) - p.feed(data or '') - return p.close() - - @property - def dependency_links(self): - return self.egg_info_lines('dependency_links.txt') - - _requirements_section_re = re.compile(r'\[(.*?)\]') - - def requirements(self, extras=()): - in_extra = None - for line in self.egg_info_lines('requires.txt'): - match = self._requirements_section_re.match(line) - if match: - in_extra = match.group(1) - continue - if in_extra and in_extra not in extras: - # Skip requirement for an extra we aren't requiring - continue - yield line - - @property - def absolute_versions(self): - for qualifier, version in self.req.specs: - if qualifier == '==': - yield version - - @property - def installed_version(self): - return self.pkg_info()['version'] - - def assert_source_matches_version(self): - assert self.source_dir - if self.comes_from is None: - # We don't check the versions of things explicitly installed. - # This makes, e.g., "pip Package==dev" possible - return - version = self.installed_version - if version not in self.req: - logger.fatal( - 'Source in %s has the version %s, which does not match the requirement %s' - % (display_path(self.source_dir), version, self)) - raise InstallationError( - 'Source in %s has version %s that conflicts with %s' - % (display_path(self.source_dir), version, self)) - else: - logger.debug('Source in %s has version %s, which satisfies requirement %s' - % (display_path(self.source_dir), version, self)) - - def update_editable(self, obtain=True): - if not self.url: - logger.info("Cannot update repository at %s; repository location is unknown" % self.source_dir) - return - assert self.editable - assert self.source_dir - if self.url.startswith('file:'): - # Static paths don't get updated - return - assert '+' in self.url, "bad url: %r" % self.url - if not self.update: - return - vc_type, url = self.url.split('+', 1) - backend = vcs.get_backend(vc_type) - if backend: - vcs_backend = backend(self.url) - if obtain: - vcs_backend.obtain(self.source_dir) - else: - vcs_backend.export(self.source_dir) - else: - assert 0, ( - 'Unexpected version control type (in %s): %s' - % (self.url, vc_type)) - - def uninstall(self, auto_confirm=False): - """ - Uninstall the distribution currently satisfying this requirement. - - Prompts before removing or modifying files unless - ``auto_confirm`` is True. - - Refuses to delete or modify files outside of ``sys.prefix`` - - thus uninstallation within a virtual environment can only - modify that virtual environment, even if the virtualenv is - linked to global site-packages. - - """ - if not self.check_if_exists(): - raise UninstallationError("Cannot uninstall requirement %s, not installed" % (self.name,)) - dist = self.satisfied_by or self.conflicts_with - - paths_to_remove = UninstallPathSet(dist) - - pip_egg_info_path = os.path.join(dist.location, - dist.egg_name()) + '.egg-info' - easy_install_egg = dist.egg_name() + '.egg' - develop_egg_link = egg_link_path(dist) - if os.path.exists(pip_egg_info_path): - # package installed by pip - paths_to_remove.add(pip_egg_info_path) - if dist.has_metadata('installed-files.txt'): - for installed_file in dist.get_metadata('installed-files.txt').splitlines(): - path = os.path.normpath(os.path.join(pip_egg_info_path, installed_file)) - paths_to_remove.add(path) - if dist.has_metadata('top_level.txt'): - if dist.has_metadata('namespace_packages.txt'): - namespaces = dist.get_metadata('namespace_packages.txt') - else: - namespaces = [] - for top_level_pkg in [p for p - in dist.get_metadata('top_level.txt').splitlines() - if p and p not in namespaces]: - path = os.path.join(dist.location, top_level_pkg) - paths_to_remove.add(path) - paths_to_remove.add(path + '.py') - paths_to_remove.add(path + '.pyc') - - elif dist.location.endswith(easy_install_egg): - # package installed by easy_install - paths_to_remove.add(dist.location) - easy_install_pth = os.path.join(os.path.dirname(dist.location), - 'easy-install.pth') - paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) - - elif os.path.isfile(develop_egg_link): - # develop egg - fh = open(develop_egg_link, 'r') - link_pointer = os.path.normcase(fh.readline().strip()) - fh.close() - assert (link_pointer == dist.location), 'Egg-link %s does not match installed location of %s (at %s)' % (link_pointer, self.name, dist.location) - paths_to_remove.add(develop_egg_link) - easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), - 'easy-install.pth') - paths_to_remove.add_pth(easy_install_pth, dist.location) - - # find distutils scripts= scripts - if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'): - for script in dist.metadata_listdir('scripts'): - paths_to_remove.add(os.path.join(bin_py, script)) - if sys.platform == 'win32': - paths_to_remove.add(os.path.join(bin_py, script) + '.bat') - - # find console_scripts - if dist.has_metadata('entry_points.txt'): - config = ConfigParser.SafeConfigParser() - config.readfp(FakeFile(dist.get_metadata_lines('entry_points.txt'))) - if config.has_section('console_scripts'): - for name, value in config.items('console_scripts'): - paths_to_remove.add(os.path.join(bin_py, name)) - if sys.platform == 'win32': - paths_to_remove.add(os.path.join(bin_py, name) + '.exe') - paths_to_remove.add(os.path.join(bin_py, name) + '.exe.manifest') - paths_to_remove.add(os.path.join(bin_py, name) + '-script.py') - - paths_to_remove.remove(auto_confirm) - self.uninstalled = paths_to_remove - - def rollback_uninstall(self): - if self.uninstalled: - self.uninstalled.rollback() - else: - logger.error("Can't rollback %s, nothing uninstalled." - % (self.project_name,)) - - def commit_uninstall(self): - if self.uninstalled: - self.uninstalled.commit() - else: - logger.error("Can't commit %s, nothing uninstalled." - % (self.project_name,)) - - def archive(self, build_dir): - assert self.source_dir - create_archive = True - archive_name = '%s-%s.zip' % (self.name, self.installed_version) - archive_path = os.path.join(build_dir, archive_name) - if os.path.exists(archive_path): - response = ask('The file %s exists. (i)gnore, (w)ipe, (b)ackup ' - % display_path(archive_path), ('i', 'w', 'b')) - if response == 'i': - create_archive = False - elif response == 'w': - logger.warn('Deleting %s' % display_path(archive_path)) - os.remove(archive_path) - elif response == 'b': - dest_file = backup_dir(archive_path) - logger.warn('Backing up %s to %s' - % (display_path(archive_path), display_path(dest_file))) - shutil.move(archive_path, dest_file) - if create_archive: - zip = zipfile.ZipFile(archive_path, 'w', zipfile.ZIP_DEFLATED) - dir = os.path.normcase(os.path.abspath(self.source_dir)) - for dirpath, dirnames, filenames in os.walk(dir): - if 'pip-egg-info' in dirnames: - dirnames.remove('pip-egg-info') - for dirname in dirnames: - dirname = os.path.join(dirpath, dirname) - name = self._clean_zip_name(dirname, dir) - zipdir = zipfile.ZipInfo(self.name + '/' + name + '/') - zipdir.external_attr = 0755 << 16L - zip.writestr(zipdir, '') - for filename in filenames: - if filename == PIP_DELETE_MARKER_FILENAME: - continue - filename = os.path.join(dirpath, filename) - name = self._clean_zip_name(filename, dir) - zip.write(filename, self.name + '/' + name) - zip.close() - logger.indent -= 2 - logger.notify('Saved %s' % display_path(archive_path)) - - def _clean_zip_name(self, name, prefix): - assert name.startswith(prefix+os.path.sep), ( - "name %r doesn't start with prefix %r" % (name, prefix)) - name = name[len(prefix)+1:] - name = name.replace(os.path.sep, '/') - return name - - def install(self, install_options, global_options=()): - if self.editable: - self.install_editable(install_options, global_options) - return - temp_location = tempfile.mkdtemp('-record', 'pip-') - record_filename = os.path.join(temp_location, 'install-record.txt') - try: - - install_args = [ - sys.executable, '-c', - "import setuptools;__file__=%r;"\ - "execfile(__file__)" % self.setup_py] +\ - list(global_options) + [ - 'install', - '--single-version-externally-managed', - '--record', record_filename] - - if running_under_virtualenv(): - ## FIXME: I'm not sure if this is a reasonable location; probably not - ## but we can't put it in the default location, as that is a virtualenv symlink that isn't writable - install_args += ['--install-headers', - os.path.join(sys.prefix, 'include', 'site', - 'python' + get_python_version())] - logger.notify('Running setup.py install for %s' % self.name) - logger.indent += 2 - try: - call_subprocess(install_args + install_options, - cwd=self.source_dir, filter_stdout=self._filter_install, show_stdout=False) - finally: - logger.indent -= 2 - if not os.path.exists(record_filename): - logger.notify('Record file %s not found' % record_filename) - return - self.install_succeeded = True - f = open(record_filename) - for line in f: - line = line.strip() - if line.endswith('.egg-info'): - egg_info_dir = line - break - else: - logger.warn('Could not find .egg-info directory in install record for %s' % self) - ## FIXME: put the record somewhere - ## FIXME: should this be an error? - return - f.close() - new_lines = [] - f = open(record_filename) - for line in f: - filename = line.strip() - if os.path.isdir(filename): - filename += os.path.sep - new_lines.append(make_path_relative(filename, egg_info_dir)) - f.close() - f = open(os.path.join(egg_info_dir, 'installed-files.txt'), 'w') - f.write('\n'.join(new_lines)+'\n') - f.close() - finally: - if os.path.exists(record_filename): - os.remove(record_filename) - os.rmdir(temp_location) - - def remove_temporary_source(self): - """Remove the source files from this requirement, if they are marked - for deletion""" - if self.is_bundle or os.path.exists(self.delete_marker_filename): - logger.info('Removing source in %s' % self.source_dir) - if self.source_dir: - rmtree(self.source_dir) - self.source_dir = None - if self._temp_build_dir and os.path.exists(self._temp_build_dir): - rmtree(self._temp_build_dir) - self._temp_build_dir = None - - def install_editable(self, install_options, global_options=()): - logger.notify('Running setup.py develop for %s' % self.name) - logger.indent += 2 - try: - ## FIXME: should we do --install-headers here too? - call_subprocess( - [sys.executable, '-c', - "import setuptools; __file__=%r; execfile(%r)" % (self.setup_py, self.setup_py)] - + list(global_options) + ['develop', '--no-deps'] + list(install_options), - - cwd=self.source_dir, filter_stdout=self._filter_install, - show_stdout=False) - finally: - logger.indent -= 2 - self.install_succeeded = True - - def _filter_install(self, line): - level = logger.NOTIFY - for regex in [r'^running .*', r'^writing .*', '^creating .*', '^[Cc]opying .*', - r'^reading .*', r"^removing .*\.egg-info' \(and everything under it\)$", - r'^byte-compiling ', - # Not sure what this warning is, but it seems harmless: - r"^warning: manifest_maker: standard file '-c' not found$"]: - if re.search(regex, line.strip()): - level = logger.INFO - break - return (level, line) - - def check_if_exists(self): - """Find an installed distribution that satisfies or conflicts - with this requirement, and set self.satisfied_by or - self.conflicts_with appropriately.""" - if self.req is None: - return False - try: - self.satisfied_by = pkg_resources.get_distribution(self.req) - except pkg_resources.DistributionNotFound: - return False - except pkg_resources.VersionConflict: - self.conflicts_with = pkg_resources.get_distribution(self.req.project_name) - return True - - @property - def is_bundle(self): - if self._is_bundle is not None: - return self._is_bundle - base = self._temp_build_dir - if not base: - ## FIXME: this doesn't seem right: - return False - self._is_bundle = (os.path.exists(os.path.join(base, 'pip-manifest.txt')) - or os.path.exists(os.path.join(base, 'pyinstall-manifest.txt'))) - return self._is_bundle - - def bundle_requirements(self): - for dest_dir in self._bundle_editable_dirs: - package = os.path.basename(dest_dir) - ## FIXME: svnism: - for vcs_backend in vcs.backends: - url = rev = None - vcs_bundle_file = os.path.join( - dest_dir, vcs_backend.bundle_file) - if os.path.exists(vcs_bundle_file): - vc_type = vcs_backend.name - fp = open(vcs_bundle_file) - content = fp.read() - fp.close() - url, rev = vcs_backend().parse_vcs_bundle_file(content) - break - if url: - url = '%s+%s@%s' % (vc_type, url, rev) - else: - url = None - yield InstallRequirement( - package, self, editable=True, url=url, - update=False, source_dir=dest_dir) - for dest_dir in self._bundle_build_dirs: - package = os.path.basename(dest_dir) - yield InstallRequirement( - package, self, - source_dir=dest_dir) - - def move_bundle_files(self, dest_build_dir, dest_src_dir): - base = self._temp_build_dir - assert base - src_dir = os.path.join(base, 'src') - build_dir = os.path.join(base, 'build') - bundle_build_dirs = [] - bundle_editable_dirs = [] - for source_dir, dest_dir, dir_collection in [ - (src_dir, dest_src_dir, bundle_editable_dirs), - (build_dir, dest_build_dir, bundle_build_dirs)]: - if os.path.exists(source_dir): - for dirname in os.listdir(source_dir): - dest = os.path.join(dest_dir, dirname) - dir_collection.append(dest) - if os.path.exists(dest): - logger.warn('The directory %s (containing package %s) already exists; cannot move source from bundle %s' - % (dest, dirname, self)) - continue - if not os.path.exists(dest_dir): - logger.info('Creating directory %s' % dest_dir) - os.makedirs(dest_dir) - shutil.move(os.path.join(source_dir, dirname), dest) - if not os.listdir(source_dir): - os.rmdir(source_dir) - self._temp_build_dir = None - self._bundle_build_dirs = bundle_build_dirs - self._bundle_editable_dirs = bundle_editable_dirs - - @property - def delete_marker_filename(self): - assert self.source_dir - return os.path.join(self.source_dir, PIP_DELETE_MARKER_FILENAME) - - -DELETE_MARKER_MESSAGE = '''\ -This file is placed here by pip to indicate the source was put -here by pip. - -Once this package is successfully installed this source code will be -deleted (unless you remove this file). -''' - - -class RequirementSet(object): - - def __init__(self, build_dir, src_dir, download_dir, download_cache=None, - upgrade=False, ignore_installed=False, - ignore_dependencies=False): - self.build_dir = build_dir - self.src_dir = src_dir - self.download_dir = download_dir - self.download_cache = download_cache - self.upgrade = upgrade - self.ignore_installed = ignore_installed - self.requirements = {} - # Mapping of alias: real_name - self.requirement_aliases = {} - self.unnamed_requirements = [] - self.ignore_dependencies = ignore_dependencies - self.successfully_downloaded = [] - self.successfully_installed = [] - self.reqs_to_cleanup = [] - - def __str__(self): - reqs = [req for req in self.requirements.values() - if not req.comes_from] - reqs.sort(key=lambda req: req.name.lower()) - return ' '.join([str(req.req) for req in reqs]) - - def add_requirement(self, install_req): - name = install_req.name - if not name: - self.unnamed_requirements.append(install_req) - else: - if self.has_requirement(name): - raise InstallationError( - 'Double requirement given: %s (aready in %s, name=%r)' - % (install_req, self.get_requirement(name), name)) - self.requirements[name] = install_req - ## FIXME: what about other normalizations? E.g., _ vs. -? - if name.lower() != name: - self.requirement_aliases[name.lower()] = name - - def has_requirement(self, project_name): - for name in project_name, project_name.lower(): - if name in self.requirements or name in self.requirement_aliases: - return True - return False - - @property - def has_requirements(self): - return self.requirements.values() or self.unnamed_requirements - - @property - def has_editables(self): - if any(req.editable for req in self.requirements.values()): - return True - if any(req.editable for req in self.unnamed_requirements): - return True - return False - - @property - def is_download(self): - if self.download_dir: - self.download_dir = os.path.expanduser(self.download_dir) - if os.path.exists(self.download_dir): - return True - else: - logger.fatal('Could not find download directory') - raise InstallationError( - "Could not find or access download directory '%s'" - % display_path(self.download_dir)) - return False - - def get_requirement(self, project_name): - for name in project_name, project_name.lower(): - if name in self.requirements: - return self.requirements[name] - if name in self.requirement_aliases: - return self.requirements[self.requirement_aliases[name]] - raise KeyError("No project with the name %r" % project_name) - - def uninstall(self, auto_confirm=False): - for req in self.requirements.values(): - req.uninstall(auto_confirm=auto_confirm) - req.commit_uninstall() - - def locate_files(self): - ## FIXME: duplicates code from install_files; relevant code should - ## probably be factored out into a separate method - unnamed = list(self.unnamed_requirements) - reqs = self.requirements.values() - while reqs or unnamed: - if unnamed: - req_to_install = unnamed.pop(0) - else: - req_to_install = reqs.pop(0) - install_needed = True - if not self.ignore_installed and not req_to_install.editable: - req_to_install.check_if_exists() - if req_to_install.satisfied_by: - if self.upgrade: - req_to_install.conflicts_with = req_to_install.satisfied_by - req_to_install.satisfied_by = None - else: - install_needed = False - if req_to_install.satisfied_by: - logger.notify('Requirement already satisfied ' - '(use --upgrade to upgrade): %s' - % req_to_install) - - if req_to_install.editable: - if req_to_install.source_dir is None: - req_to_install.source_dir = req_to_install.build_location(self.src_dir) - elif install_needed: - req_to_install.source_dir = req_to_install.build_location(self.build_dir, not self.is_download) - - if req_to_install.source_dir is not None and not os.path.isdir(req_to_install.source_dir): - raise InstallationError('Could not install requirement %s ' - 'because source folder %s does not exist ' - '(perhaps --no-download was used without first running ' - 'an equivalent install with --no-install?)' - % (req_to_install, req_to_install.source_dir)) - - def prepare_files(self, finder, force_root_egg_info=False, bundle=False): - """Prepare process. Create temp directories, download and/or unpack files.""" - unnamed = list(self.unnamed_requirements) - reqs = self.requirements.values() - while reqs or unnamed: - if unnamed: - req_to_install = unnamed.pop(0) - else: - req_to_install = reqs.pop(0) - install = True - if not self.ignore_installed and not req_to_install.editable: - req_to_install.check_if_exists() - if req_to_install.satisfied_by: - if self.upgrade: - req_to_install.conflicts_with = req_to_install.satisfied_by - req_to_install.satisfied_by = None - else: - install = False - if req_to_install.satisfied_by: - logger.notify('Requirement already satisfied ' - '(use --upgrade to upgrade): %s' - % req_to_install) - if req_to_install.editable: - logger.notify('Obtaining %s' % req_to_install) - elif install: - if req_to_install.url and req_to_install.url.lower().startswith('file:'): - logger.notify('Unpacking %s' % display_path(url_to_path(req_to_install.url))) - else: - logger.notify('Downloading/unpacking %s' % req_to_install) - logger.indent += 2 - try: - is_bundle = False - if req_to_install.editable: - if req_to_install.source_dir is None: - location = req_to_install.build_location(self.src_dir) - req_to_install.source_dir = location - else: - location = req_to_install.source_dir - if not os.path.exists(self.build_dir): - _make_build_dir(self.build_dir) - req_to_install.update_editable(not self.is_download) - if self.is_download: - req_to_install.run_egg_info() - req_to_install.archive(self.download_dir) - else: - req_to_install.run_egg_info() - elif install: - ##@@ if filesystem packages are not marked - ##editable in a req, a non deterministic error - ##occurs when the script attempts to unpack the - ##build directory - - location = req_to_install.build_location(self.build_dir, not self.is_download) - ## FIXME: is the existance of the checkout good enough to use it? I don't think so. - unpack = True - if not os.path.exists(os.path.join(location, 'setup.py')): - ## FIXME: this won't upgrade when there's an existing package unpacked in `location` - if req_to_install.url is None: - url = finder.find_requirement(req_to_install, upgrade=self.upgrade) - else: - ## FIXME: should req_to_install.url already be a link? - url = Link(req_to_install.url) - assert url - if url: - try: - self.unpack_url(url, location, self.is_download) - except urllib2.HTTPError, e: - logger.fatal('Could not install requirement %s because of error %s' - % (req_to_install, e)) - raise InstallationError( - 'Could not install requirement %s because of HTTP error %s for URL %s' - % (req_to_install, e, url)) - else: - unpack = False - if unpack: - is_bundle = req_to_install.is_bundle - url = None - if is_bundle: - req_to_install.move_bundle_files(self.build_dir, self.src_dir) - for subreq in req_to_install.bundle_requirements(): - reqs.append(subreq) - self.add_requirement(subreq) - elif self.is_download: - req_to_install.source_dir = location - if url and url.scheme in vcs.all_schemes: - req_to_install.run_egg_info() - req_to_install.archive(self.download_dir) - else: - req_to_install.source_dir = location - req_to_install.run_egg_info() - if force_root_egg_info: - # We need to run this to make sure that the .egg-info/ - # directory is created for packing in the bundle - req_to_install.run_egg_info(force_root_egg_info=True) - req_to_install.assert_source_matches_version() - #@@ sketchy way of identifying packages not grabbed from an index - if bundle and req_to_install.url: - self.copy_to_build_dir(req_to_install) - if not is_bundle and not self.is_download: - ## FIXME: shouldn't be globally added: - finder.add_dependency_links(req_to_install.dependency_links) - ## FIXME: add extras in here: - if not self.ignore_dependencies: - for req in req_to_install.requirements(): - try: - name = pkg_resources.Requirement.parse(req).project_name - except ValueError, e: - ## FIXME: proper warning - logger.error('Invalid requirement: %r (%s) in requirement %s' % (req, e, req_to_install)) - continue - if self.has_requirement(name): - ## FIXME: check for conflict - continue - subreq = InstallRequirement(req, req_to_install) - reqs.append(subreq) - self.add_requirement(subreq) - if req_to_install.name not in self.requirements: - self.requirements[req_to_install.name] = req_to_install - else: - self.reqs_to_cleanup.append(req_to_install) - if install: - self.successfully_downloaded.append(req_to_install) - if bundle and (req_to_install.url and req_to_install.url.startswith('file:///')): - self.copy_to_build_dir(req_to_install) - finally: - logger.indent -= 2 - - def cleanup_files(self, bundle=False): - """Clean up files, remove builds.""" - logger.notify('Cleaning up...') - logger.indent += 2 - for req in self.reqs_to_cleanup: - req.remove_temporary_source() - - remove_dir = [] - if self._pip_has_created_build_dir(): - remove_dir.append(self.build_dir) - - # The source dir of a bundle can always be removed. - if bundle: - remove_dir.append(self.src_dir) - - for dir in remove_dir: - if os.path.exists(dir): - logger.info('Removing temporary dir %s...' % dir) - rmtree(dir) - - logger.indent -= 2 - - def _pip_has_created_build_dir(self): - return (self.build_dir == build_prefix and - os.path.exists(os.path.join(self.build_dir, PIP_DELETE_MARKER_FILENAME))) - - def copy_to_build_dir(self, req_to_install): - target_dir = req_to_install.editable and self.src_dir or self.build_dir - logger.info("Copying %s to %s" %(req_to_install.name, target_dir)) - dest = os.path.join(target_dir, req_to_install.name) - copytree(req_to_install.source_dir, dest) - call_subprocess(["python", "%s/setup.py"%dest, "clean"]) - - def unpack_url(self, link, location, only_download=False): - if only_download: - location = self.download_dir - if is_vcs_url(link): - return unpack_vcs_link(link, location, only_download) - elif is_file_url(link): - return unpack_file_url(link, location) - else: - if self.download_cache: - self.download_cache = os.path.expanduser(self.download_cache) - return unpack_http_url(link, location, self.download_cache, only_download) - - def install(self, install_options, global_options=()): - """Install everything in this set (after having downloaded and unpacked the packages)""" - to_install = sorted([r for r in self.requirements.values() - if self.upgrade or not r.satisfied_by], - key=lambda p: p.name.lower()) - if to_install: - logger.notify('Installing collected packages: %s' % (', '.join([req.name for req in to_install]))) - logger.indent += 2 - try: - for requirement in to_install: - if requirement.conflicts_with: - logger.notify('Found existing installation: %s' - % requirement.conflicts_with) - logger.indent += 2 - try: - requirement.uninstall(auto_confirm=True) - finally: - logger.indent -= 2 - try: - requirement.install(install_options, global_options) - except: - # if install did not succeed, rollback previous uninstall - if requirement.conflicts_with and not requirement.install_succeeded: - requirement.rollback_uninstall() - raise - else: - if requirement.conflicts_with and requirement.install_succeeded: - requirement.commit_uninstall() - requirement.remove_temporary_source() - finally: - logger.indent -= 2 - self.successfully_installed = to_install - - def create_bundle(self, bundle_filename): - ## FIXME: can't decide which is better; zip is easier to read - ## random files from, but tar.bz2 is smaller and not as lame a - ## format. - - ## FIXME: this file should really include a manifest of the - ## packages, maybe some other metadata files. It would make - ## it easier to detect as well. - zip = zipfile.ZipFile(bundle_filename, 'w', zipfile.ZIP_DEFLATED) - vcs_dirs = [] - for dir, basename in (self.build_dir, 'build'), (self.src_dir, 'src'): - dir = os.path.normcase(os.path.abspath(dir)) - for dirpath, dirnames, filenames in os.walk(dir): - for backend in vcs.backends: - vcs_backend = backend() - vcs_url = vcs_rev = None - if vcs_backend.dirname in dirnames: - for vcs_dir in vcs_dirs: - if dirpath.startswith(vcs_dir): - # vcs bundle file already in parent directory - break - else: - vcs_url, vcs_rev = vcs_backend.get_info( - os.path.join(dir, dirpath)) - vcs_dirs.append(dirpath) - vcs_bundle_file = vcs_backend.bundle_file - vcs_guide = vcs_backend.guide % {'url': vcs_url, - 'rev': vcs_rev} - dirnames.remove(vcs_backend.dirname) - break - if 'pip-egg-info' in dirnames: - dirnames.remove('pip-egg-info') - for dirname in dirnames: - dirname = os.path.join(dirpath, dirname) - name = self._clean_zip_name(dirname, dir) - zip.writestr(basename + '/' + name + '/', '') - for filename in filenames: - if filename == PIP_DELETE_MARKER_FILENAME: - continue - filename = os.path.join(dirpath, filename) - name = self._clean_zip_name(filename, dir) - zip.write(filename, basename + '/' + name) - if vcs_url: - name = os.path.join(dirpath, vcs_bundle_file) - name = self._clean_zip_name(name, dir) - zip.writestr(basename + '/' + name, vcs_guide) - - zip.writestr('pip-manifest.txt', self.bundle_requirements()) - zip.close() - - BUNDLE_HEADER = '''\ -# This is a pip bundle file, that contains many source packages -# that can be installed as a group. You can install this like: -# pip this_file.zip -# The rest of the file contains a list of all the packages included: -''' - - def bundle_requirements(self): - parts = [self.BUNDLE_HEADER] - for req in sorted( - [req for req in self.requirements.values() - if not req.comes_from], - key=lambda x: x.name): - parts.append('%s==%s\n' % (req.name, req.installed_version)) - parts.append('# These packages were installed to satisfy the above requirements:\n') - for req in sorted( - [req for req in self.requirements.values() - if req.comes_from], - key=lambda x: x.name): - parts.append('%s==%s\n' % (req.name, req.installed_version)) - ## FIXME: should we do something with self.unnamed_requirements? - return ''.join(parts) - - def _clean_zip_name(self, name, prefix): - assert name.startswith(prefix+os.path.sep), ( - "name %r doesn't start with prefix %r" % (name, prefix)) - name = name[len(prefix)+1:] - name = name.replace(os.path.sep, '/') - return name - - -def _make_build_dir(build_dir): - os.makedirs(build_dir) - _write_delete_marker_message(os.path.join(build_dir, PIP_DELETE_MARKER_FILENAME)) - - -def _write_delete_marker_message(filepath): - marker_fp = open(filepath, 'w') - marker_fp.write(DELETE_MARKER_MESSAGE) - marker_fp.close() - - -_scheme_re = re.compile(r'^(http|https|file):', re.I) - - -def parse_requirements(filename, finder=None, comes_from=None, options=None): - skip_match = None - skip_regex = options.skip_requirements_regex - if skip_regex: - skip_match = re.compile(skip_regex) - filename, content = get_file_content(filename, comes_from=comes_from) - for line_number, line in enumerate(content.splitlines()): - line_number += 1 - line = line.strip() - if not line or line.startswith('#'): - continue - if skip_match and skip_match.search(line): - continue - if line.startswith('-r') or line.startswith('--requirement'): - if line.startswith('-r'): - req_url = line[2:].strip() - else: - req_url = line[len('--requirement'):].strip().strip('=') - if _scheme_re.search(filename): - # Relative to a URL - req_url = urlparse.urljoin(req_url, filename) - elif not _scheme_re.search(req_url): - req_url = os.path.join(os.path.dirname(filename), req_url) - for item in parse_requirements(req_url, finder, comes_from=filename, options=options): - yield item - elif line.startswith('-Z') or line.startswith('--always-unzip'): - # No longer used, but previously these were used in - # requirement files, so we'll ignore. - pass - elif line.startswith('-f') or line.startswith('--find-links'): - if line.startswith('-f'): - line = line[2:].strip() - else: - line = line[len('--find-links'):].strip().lstrip('=') - ## FIXME: it would be nice to keep track of the source of - ## the find_links: - if finder: - finder.find_links.append(line) - elif line.startswith('-i') or line.startswith('--index-url'): - if line.startswith('-i'): - line = line[2:].strip() - else: - line = line[len('--index-url'):].strip().lstrip('=') - if finder: - finder.index_urls = [line] - elif line.startswith('--extra-index-url'): - line = line[len('--extra-index-url'):].strip().lstrip('=') - if finder: - finder.index_urls.append(line) - else: - comes_from = '-r %s (line %s)' % (filename, line_number) - if line.startswith('-e') or line.startswith('--editable'): - if line.startswith('-e'): - line = line[2:].strip() - else: - line = line[len('--editable'):].strip() - req = InstallRequirement.from_editable( - line, comes_from=comes_from, default_vcs=options.default_vcs) - else: - req = InstallRequirement.from_line(line, comes_from) - yield req - - -def parse_editable(editable_req, default_vcs=None): - """Parses svn+http://blahblah@rev#egg=Foobar into a requirement - (Foobar) and a URL""" - url = editable_req - if os.path.isdir(url) and os.path.exists(os.path.join(url, 'setup.py')): - # Treating it as code that has already been checked out - url = path_to_url(url) - if url.lower().startswith('file:'): - return None, url - for version_control in vcs: - if url.lower().startswith('%s:' % version_control): - url = '%s+%s' % (version_control, url) - if '+' not in url: - if default_vcs: - url = default_vcs + '+' + url - else: - raise InstallationError( - '--editable=%s should be formatted with svn+URL, git+URL, hg+URL or bzr+URL' % editable_req) - vc_type = url.split('+', 1)[0].lower() - if not vcs.get_backend(vc_type): - raise InstallationError( - 'For --editable=%s only svn (svn+URL), Git (git+URL), Mercurial (hg+URL) and Bazaar (bzr+URL) is currently supported' % editable_req) - match = re.search(r'(?:#|#.*?&)egg=([^&]*)', editable_req) - if (not match or not match.group(1)) and vcs.get_backend(vc_type): - parts = [p for p in editable_req.split('#', 1)[0].split('/') if p] - if parts[-2] in ('tags', 'branches', 'tag', 'branch'): - req = parts[-3] - elif parts[-1] == 'trunk': - req = parts[-2] - else: - raise InstallationError( - '--editable=%s is not the right format; it must have #egg=Package' - % editable_req) - else: - req = match.group(1) - ## FIXME: use package_to_requirement? - match = re.search(r'^(.*?)(?:-dev|-\d.*)', req) - if match: - # Strip off -dev, -0.2, etc. - req = match.group(1) - return req, url - - -class UninstallPathSet(object): - """A set of file paths to be removed in the uninstallation of a - requirement.""" - def __init__(self, dist): - self.paths = set() - self._refuse = set() - self.pth = {} - self.dist = dist - self.save_dir = None - self._moved_paths = [] - - def _permitted(self, path): - """ - Return True if the given path is one we are permitted to - remove/modify, False otherwise. - - """ - return is_local(path) - - def _can_uninstall(self): - if not dist_is_local(self.dist): - logger.notify("Not uninstalling %s at %s, outside environment %s" - % (self.dist.project_name, normalize_path(self.dist.location), sys.prefix)) - return False - return True - - def add(self, path): - path = normalize_path(path) - if not os.path.exists(path): - return - if self._permitted(path): - self.paths.add(path) - else: - self._refuse.add(path) - - def add_pth(self, pth_file, entry): - pth_file = normalize_path(pth_file) - if self._permitted(pth_file): - if pth_file not in self.pth: - self.pth[pth_file] = UninstallPthEntries(pth_file) - self.pth[pth_file].add(entry) - else: - self._refuse.add(pth_file) - - def compact(self, paths): - """Compact a path set to contain the minimal number of paths - necessary to contain all paths in the set. If /a/path/ and - /a/path/to/a/file.txt are both in the set, leave only the - shorter path.""" - short_paths = set() - for path in sorted(paths, key=len): - if not any([(path.startswith(shortpath) and - path[len(shortpath.rstrip(os.path.sep))] == os.path.sep) - for shortpath in short_paths]): - short_paths.add(path) - return short_paths - - def _stash(self, path): - return os.path.join( - self.save_dir, os.path.splitdrive(path)[1].lstrip(os.path.sep)) - - def remove(self, auto_confirm=False): - """Remove paths in ``self.paths`` with confirmation (unless - ``auto_confirm`` is True).""" - if not self._can_uninstall(): - return - logger.notify('Uninstalling %s:' % self.dist.project_name) - logger.indent += 2 - paths = sorted(self.compact(self.paths)) - try: - if auto_confirm: - response = 'y' - else: - for path in paths: - logger.notify(path) - response = ask('Proceed (y/n)? ', ('y', 'n')) - if self._refuse: - logger.notify('Not removing or modifying (outside of prefix):') - for path in self.compact(self._refuse): - logger.notify(path) - if response == 'y': - self.save_dir = tempfile.mkdtemp(suffix='-uninstall', - prefix='pip-') - for path in paths: - new_path = self._stash(path) - logger.info('Removing file or directory %s' % path) - self._moved_paths.append(path) - renames(path, new_path) - for pth in self.pth.values(): - pth.remove() - logger.notify('Successfully uninstalled %s' % self.dist.project_name) - - finally: - logger.indent -= 2 - - def rollback(self): - """Rollback the changes previously made by remove().""" - if self.save_dir is None: - logger.error("Can't roll back %s; was not uninstalled" % self.dist.project_name) - return False - logger.notify('Rolling back uninstall of %s' % self.dist.project_name) - for path in self._moved_paths: - tmp_path = self._stash(path) - logger.info('Replacing %s' % path) - renames(tmp_path, path) - for pth in self.pth: - pth.rollback() - - def commit(self): - """Remove temporary save dir: rollback will no longer be possible.""" - if self.save_dir is not None: - shutil.rmtree(self.save_dir) - self.save_dir = None - self._moved_paths = [] - - -class UninstallPthEntries(object): - def __init__(self, pth_file): - if not os.path.isfile(pth_file): - raise UninstallationError("Cannot remove entries from nonexistent file %s" % pth_file) - self.file = pth_file - self.entries = set() - self._saved_lines = None - - def add(self, entry): - entry = os.path.normcase(entry) - # On Windows, os.path.normcase converts the entry to use - # backslashes. This is correct for entries that describe absolute - # paths outside of site-packages, but all the others use forward - # slashes. - if sys.platform == 'win32' and not os.path.splitdrive(entry)[0]: - entry = entry.replace('\\', '/') - self.entries.add(entry) - - def remove(self): - logger.info('Removing pth entries from %s:' % self.file) - fh = open(self.file, 'r') - lines = fh.readlines() - self._saved_lines = lines - fh.close() - try: - for entry in self.entries: - logger.info('Removing entry: %s' % entry) - try: - lines.remove(entry + '\n') - except ValueError: - pass - finally: - pass - fh = open(self.file, 'wb') - fh.writelines(lines) - fh.close() - - def rollback(self): - if self._saved_lines is None: - logger.error('Cannot roll back changes to %s, none were made' % self.file) - return False - logger.info('Rolling %s back to previous state' % self.file) - fh = open(self.file, 'wb') - fh.writelines(self._saved_lines) - fh.close() - return True - - -class FakeFile(object): - """Wrap a list of lines in an object with readline() to make - ConfigParser happy.""" - def __init__(self, lines): - self._gen = (l for l in lines) - - def readline(self): - try: - return self._gen.next() - except StopIteration: - return '' diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/runner.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/runner.py deleted file mode 100644 index be830ad9..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/runner.py +++ /dev/null @@ -1,18 +0,0 @@ -import sys -import os - - -def run(): - base = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - ## FIXME: this is kind of crude; if we could create a fake pip - ## module, then exec into it and update pip.__path__ properly, we - ## wouldn't have to update sys.path: - sys.path.insert(0, base) - import pip - return pip.main() - - -if __name__ == '__main__': - exit = run() - if exit: - sys.exit(exit) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/util.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/util.py deleted file mode 100644 index 1eab34c0..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/util.py +++ /dev/null @@ -1,479 +0,0 @@ -import sys -import shutil -import os -import stat -import re -import posixpath -import pkg_resources -import zipfile -import tarfile -from pip.exceptions import InstallationError -from pip.backwardcompat import WindowsError -from pip.locations import site_packages, running_under_virtualenv -from pip.log import logger - -__all__ = ['rmtree', 'display_path', 'backup_dir', - 'find_command', 'ask', 'Inf', - 'normalize_name', 'splitext', - 'format_size', 'is_installable_dir', - 'is_svn_page', 'file_contents', - 'split_leading_dir', 'has_leading_dir', - 'make_path_relative', 'normalize_path', - 'renames', 'get_terminal_size', - 'unzip_file', 'untar_file', 'create_download_cache_folder', - 'cache_download', 'unpack_file'] - - -def rmtree(dir): - shutil.rmtree(dir, ignore_errors=True, - onerror=rmtree_errorhandler) - - -def rmtree_errorhandler(func, path, exc_info): - """On Windows, the files in .svn are read-only, so when rmtree() tries to - remove them, an exception is thrown. We catch that here, remove the - read-only attribute, and hopefully continue without problems.""" - exctype, value = exc_info[:2] - # lookin for a windows error - if exctype is not WindowsError or 'Access is denied' not in str(value): - raise - # file type should currently be read only - if ((os.stat(path).st_mode & stat.S_IREAD) != stat.S_IREAD): - raise - # convert to read/write - os.chmod(path, stat.S_IWRITE) - # use the original function to repeat the operation - func(path) - - -def display_path(path): - """Gives the display value for a given path, making it relative to cwd - if possible.""" - path = os.path.normcase(os.path.abspath(path)) - if path.startswith(os.getcwd() + os.path.sep): - path = '.' + path[len(os.getcwd()):] - return path - - -def backup_dir(dir, ext='.bak'): - """Figure out the name of a directory to back up the given dir to - (adding .bak, .bak2, etc)""" - n = 1 - extension = ext - while os.path.exists(dir + extension): - n += 1 - extension = ext + str(n) - return dir + extension - - -def find_command(cmd, paths=None, pathext=None): - """Searches the PATH for the given command and returns its path""" - if paths is None: - paths = os.environ.get('PATH', []).split(os.pathsep) - if isinstance(paths, basestring): - paths = [paths] - # check if there are funny path extensions for executables, e.g. Windows - if pathext is None: - pathext = os.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD') - pathext = [ext for ext in pathext.lower().split(os.pathsep)] - # don't use extensions if the command ends with one of them - if os.path.splitext(cmd)[1].lower() in pathext: - pathext = [''] - # check if we find the command on PATH - for path in paths: - # try without extension first - cmd_path = os.path.join(path, cmd) - for ext in pathext: - # then including the extension - cmd_path_ext = cmd_path + ext - if os.path.exists(cmd_path_ext): - return cmd_path_ext - if os.path.exists(cmd_path): - return cmd_path - return None - - -def ask(message, options): - """Ask the message interactively, with the given possible responses""" - while 1: - if os.environ.get('PIP_NO_INPUT'): - raise Exception('No input was expected ($PIP_NO_INPUT set); question: %s' % message) - response = raw_input(message) - response = response.strip().lower() - if response not in options: - print 'Your response (%r) was not one of the expected responses: %s' % ( - response, ', '.join(options)) - else: - return response - - -class _Inf(object): - """I am bigger than everything!""" - def __cmp__(self, a): - if self is a: - return 0 - return 1 - - def __repr__(self): - return 'Inf' - -Inf = _Inf() -del _Inf - - -_normalize_re = re.compile(r'[^a-z]', re.I) - - -def normalize_name(name): - return _normalize_re.sub('-', name.lower()) - - -def format_size(bytes): - if bytes > 1000*1000: - return '%.1fMb' % (bytes/1000.0/1000) - elif bytes > 10*1000: - return '%iKb' % (bytes/1000) - elif bytes > 1000: - return '%.1fKb' % (bytes/1000.0) - else: - return '%ibytes' % bytes - - -def is_installable_dir(path): - """Return True if `path` is a directory containing a setup.py file.""" - if not os.path.isdir(path): - return False - setup_py = os.path.join(path, 'setup.py') - if os.path.isfile(setup_py): - return True - return False - - -def is_svn_page(html): - """Returns true if the page appears to be the index page of an svn repository""" - return (re.search(r'<title>[^<]*Revision \d+:', html) - and re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I)) - - -def file_contents(filename): - fp = open(filename, 'rb') - try: - return fp.read() - finally: - fp.close() - - -def split_leading_dir(path): - path = str(path) - path = path.lstrip('/').lstrip('\\') - if '/' in path and (('\\' in path and path.find('/') < path.find('\\')) - or '\\' not in path): - return path.split('/', 1) - elif '\\' in path: - return path.split('\\', 1) - else: - return path, '' - - -def has_leading_dir(paths): - """Returns true if all the paths have the same leading path name - (i.e., everything is in one subdirectory in an archive)""" - common_prefix = None - for path in paths: - prefix, rest = split_leading_dir(path) - if not prefix: - return False - elif common_prefix is None: - common_prefix = prefix - elif prefix != common_prefix: - return False - return True - - -def make_path_relative(path, rel_to): - """ - Make a filename relative, where the filename path, and it is - relative to rel_to - - >>> make_relative_path('/usr/share/something/a-file.pth', - ... '/usr/share/another-place/src/Directory') - '../../../something/a-file.pth' - >>> make_relative_path('/usr/share/something/a-file.pth', - ... '/home/user/src/Directory') - '../../../usr/share/something/a-file.pth' - >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/') - 'a-file.pth' - """ - path_filename = os.path.basename(path) - path = os.path.dirname(path) - path = os.path.normpath(os.path.abspath(path)) - rel_to = os.path.normpath(os.path.abspath(rel_to)) - path_parts = path.strip(os.path.sep).split(os.path.sep) - rel_to_parts = rel_to.strip(os.path.sep).split(os.path.sep) - while path_parts and rel_to_parts and path_parts[0] == rel_to_parts[0]: - path_parts.pop(0) - rel_to_parts.pop(0) - full_parts = ['..']*len(rel_to_parts) + path_parts + [path_filename] - if full_parts == ['']: - return '.' + os.path.sep - return os.path.sep.join(full_parts) - - -def normalize_path(path): - """ - Convert a path to its canonical, case-normalized, absolute version. - - """ - return os.path.normcase(os.path.realpath(path)) - - -def splitext(path): - """Like os.path.splitext, but take off .tar too""" - base, ext = posixpath.splitext(path) - if base.lower().endswith('.tar'): - ext = base[-4:] + ext - base = base[:-4] - return base, ext - - -def renames(old, new): - """Like os.renames(), but handles renaming across devices.""" - # Implementation borrowed from os.renames(). - head, tail = os.path.split(new) - if head and tail and not os.path.exists(head): - os.makedirs(head) - - shutil.move(old, new) - - head, tail = os.path.split(old) - if head and tail: - try: - os.removedirs(head) - except OSError: - pass - - -def is_local(path): - """ - Return True if path is within sys.prefix, if we're running in a virtualenv. - - If we're not in a virtualenv, all paths are considered "local." - - """ - if not running_under_virtualenv(): - return True - return normalize_path(path).startswith(normalize_path(sys.prefix)) - - -def dist_is_local(dist): - """ - Return True if given Distribution object is installed locally - (i.e. within current virtualenv). - - Always True if we're not in a virtualenv. - - """ - return is_local(dist_location(dist)) - - -def get_installed_distributions(local_only=True, skip=('setuptools', 'pip', 'python')): - """ - Return a list of installed Distribution objects. - - If ``local_only`` is True (default), only return installations - local to the current virtualenv, if in a virtualenv. - - ``skip`` argument is an iterable of lower-case project names to - ignore; defaults to ('setuptools', 'pip', 'python'). [FIXME also - skip virtualenv?] - - """ - if local_only: - local_test = dist_is_local - else: - local_test = lambda d: True - return [d for d in pkg_resources.working_set if local_test(d) and d.key not in skip] - - -def egg_link_path(dist): - """ - Return the path where we'd expect to find a .egg-link file for - this distribution. (There doesn't seem to be any metadata in the - Distribution object for a develop egg that points back to its - .egg-link and easy-install.pth files). - - This won't find a globally-installed develop egg if we're in a - virtualenv. - - """ - return os.path.join(site_packages, dist.project_name) + '.egg-link' - - -def dist_location(dist): - """ - Get the site-packages location of this distribution. Generally - this is dist.location, except in the case of develop-installed - packages, where dist.location is the source code location, and we - want to know where the egg-link file is. - - """ - egg_link = egg_link_path(dist) - if os.path.exists(egg_link): - return egg_link - return dist.location - - -def get_terminal_size(): - """Returns a tuple (x, y) representing the width(x) and the height(x) - in characters of the terminal window.""" - def ioctl_GWINSZ(fd): - try: - import fcntl - import termios - import struct - cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, - '1234')) - except: - return None - if cr == (0, 0): - return None - if cr == (0, 0): - return None - return cr - cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) - if not cr: - try: - fd = os.open(os.ctermid(), os.O_RDONLY) - cr = ioctl_GWINSZ(fd) - os.close(fd) - except: - pass - if not cr: - cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) - return int(cr[1]), int(cr[0]) - - -def unzip_file(filename, location, flatten=True): - """Unzip the file (zip file located at filename) to the destination - location""" - if not os.path.exists(location): - os.makedirs(location) - zipfp = open(filename, 'rb') - try: - zip = zipfile.ZipFile(zipfp) - leading = has_leading_dir(zip.namelist()) and flatten - for name in zip.namelist(): - data = zip.read(name) - fn = name - if leading: - fn = split_leading_dir(name)[1] - fn = os.path.join(location, fn) - dir = os.path.dirname(fn) - if not os.path.exists(dir): - os.makedirs(dir) - if fn.endswith('/') or fn.endswith('\\'): - # A directory - if not os.path.exists(fn): - os.makedirs(fn) - else: - fp = open(fn, 'wb') - try: - fp.write(data) - finally: - fp.close() - finally: - zipfp.close() - - -def untar_file(filename, location): - """Untar the file (tar file located at filename) to the destination location""" - if not os.path.exists(location): - os.makedirs(location) - if filename.lower().endswith('.gz') or filename.lower().endswith('.tgz'): - mode = 'r:gz' - elif filename.lower().endswith('.bz2') or filename.lower().endswith('.tbz'): - mode = 'r:bz2' - elif filename.lower().endswith('.tar'): - mode = 'r' - else: - logger.warn('Cannot determine compression type for file %s' % filename) - mode = 'r:*' - tar = tarfile.open(filename, mode) - try: - # note: python<=2.5 doesnt seem to know about pax headers, filter them - leading = has_leading_dir([ - member.name for member in tar.getmembers() - if member.name != 'pax_global_header' - ]) - for member in tar.getmembers(): - fn = member.name - if fn == 'pax_global_header': - continue - if leading: - fn = split_leading_dir(fn)[1] - path = os.path.join(location, fn) - if member.isdir(): - if not os.path.exists(path): - os.makedirs(path) - else: - try: - fp = tar.extractfile(member) - except (KeyError, AttributeError), e: - # Some corrupt tar files seem to produce this - # (specifically bad symlinks) - logger.warn( - 'In the tar file %s the member %s is invalid: %s' - % (filename, member.name, e)) - continue - if not os.path.exists(os.path.dirname(path)): - os.makedirs(os.path.dirname(path)) - destfp = open(path, 'wb') - try: - shutil.copyfileobj(fp, destfp) - finally: - destfp.close() - fp.close() - finally: - tar.close() - - -def create_download_cache_folder(folder): - logger.indent -= 2 - logger.notify('Creating supposed download cache at %s' % folder) - logger.indent += 2 - os.makedirs(folder) - - -def cache_download(target_file, temp_location, content_type): - logger.notify('Storing download in cache at %s' % display_path(target_file)) - shutil.copyfile(temp_location, target_file) - fp = open(target_file+'.content-type', 'w') - fp.write(content_type) - fp.close() - os.unlink(temp_location) - - -def unpack_file(filename, location, content_type, link): - if (content_type == 'application/zip' - or filename.endswith('.zip') - or filename.endswith('.pybundle') - or zipfile.is_zipfile(filename)): - unzip_file(filename, location, flatten=not filename.endswith('.pybundle')) - elif (content_type == 'application/x-gzip' - or tarfile.is_tarfile(filename) - or splitext(filename)[1].lower() in ('.tar', '.tar.gz', '.tar.bz2', '.tgz', '.tbz')): - untar_file(filename, location) - elif (content_type and content_type.startswith('text/html') - and is_svn_page(file_contents(filename))): - # We don't really care about this - from pip.vcs.subversion import Subversion - Subversion('svn+' + link.url).unpack(location) - else: - ## FIXME: handle? - ## FIXME: magic signatures? - logger.fatal('Cannot unpack file %s (downloaded from %s, content-type: %s); cannot detect archive format' - % (filename, location, content_type)) - raise InstallationError('Cannot determine archive format of %s' % location) - - - diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/__init__.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/__init__.py deleted file mode 100644 index e110440c..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/__init__.py +++ /dev/null @@ -1,238 +0,0 @@ -"""Handles all VCS (version control) support""" - -import os -import shutil -import urlparse -import urllib - -from pip.exceptions import BadCommand -from pip.log import logger -from pip.util import display_path, backup_dir, find_command, ask - - -__all__ = ['vcs', 'get_src_requirement', 'import_vcs_support'] - - -class VcsSupport(object): - _registry = {} - schemes = ['ssh', 'git', 'hg', 'bzr', 'sftp'] - - def __init__(self): - # Register more schemes with urlparse for various version control systems - urlparse.uses_netloc.extend(self.schemes) - urlparse.uses_fragment.extend(self.schemes) - super(VcsSupport, self).__init__() - - def __iter__(self): - return self._registry.__iter__() - - @property - def backends(self): - return self._registry.values() - - @property - def dirnames(self): - return [backend.dirname for backend in self.backends] - - @property - def all_schemes(self): - schemes = [] - for backend in self.backends: - schemes.extend(backend.schemes) - return schemes - - def register(self, cls): - if not hasattr(cls, 'name'): - logger.warn('Cannot register VCS %s' % cls.__name__) - return - if cls.name not in self._registry: - self._registry[cls.name] = cls - - def unregister(self, cls=None, name=None): - if name in self._registry: - del self._registry[name] - elif cls in self._registry.values(): - del self._registry[cls.name] - else: - logger.warn('Cannot unregister because no class or name given') - - def get_backend_name(self, location): - """ - Return the name of the version control backend if found at given - location, e.g. vcs.get_backend_name('/path/to/vcs/checkout') - """ - for vc_type in self._registry.values(): - path = os.path.join(location, vc_type.dirname) - if os.path.exists(path): - return vc_type.name - return None - - def get_backend(self, name): - name = name.lower() - if name in self._registry: - return self._registry[name] - - def get_backend_from_location(self, location): - vc_type = self.get_backend_name(location) - if vc_type: - return self.get_backend(vc_type) - return None - - -vcs = VcsSupport() - - -class VersionControl(object): - name = '' - dirname = '' - - def __init__(self, url=None, *args, **kwargs): - self.url = url - self._cmd = None - super(VersionControl, self).__init__(*args, **kwargs) - - def _filter(self, line): - return (logger.INFO, line) - - def _is_local_repository(self, repo): - """ - posix absolute paths start with os.path.sep, - win32 ones ones start with drive (like c:\\folder) - """ - drive, tail = os.path.splitdrive(repo) - return repo.startswith(os.path.sep) or drive - - @property - def cmd(self): - if self._cmd is not None: - return self._cmd - command = find_command(self.name) - if command is None: - raise BadCommand('Cannot find command %r' % self.name) - logger.info('Found command %r at %r' % (self.name, command)) - self._cmd = command - return command - - def get_url_rev(self): - """ - Returns the correct repository URL and revision by parsing the given - repository URL - """ - url = self.url.split('+', 1)[1] - scheme, netloc, path, query, frag = urlparse.urlsplit(url) - rev = None - if '@' in path: - path, rev = path.rsplit('@', 1) - url = urlparse.urlunsplit((scheme, netloc, path, query, '')) - return url, rev - - def get_info(self, location): - """ - Returns (url, revision), where both are strings - """ - assert not location.rstrip('/').endswith(self.dirname), 'Bad directory: %s' % location - return self.get_url(location), self.get_revision(location) - - def normalize_url(self, url): - """ - Normalize a URL for comparison by unquoting it and removing any trailing slash. - """ - return urllib.unquote(url).rstrip('/') - - def compare_urls(self, url1, url2): - """ - Compare two repo URLs for identity, ignoring incidental differences. - """ - return (self.normalize_url(url1) == self.normalize_url(url2)) - - def parse_vcs_bundle_file(self, content): - """ - Takes the contents of the bundled text file that explains how to revert - the stripped off version control data of the given package and returns - the URL and revision of it. - """ - raise NotImplementedError - - def obtain(self, dest): - """ - Called when installing or updating an editable package, takes the - source path of the checkout. - """ - raise NotImplementedError - - def switch(self, dest, url, rev_options): - """ - Switch the repo at ``dest`` to point to ``URL``. - """ - raise NotImplemented - - def update(self, dest, rev_options): - """ - Update an already-existing repo to the given ``rev_options``. - """ - raise NotImplementedError - - def check_destination(self, dest, url, rev_options, rev_display): - """ - Prepare a location to receive a checkout/clone. - - Return True if the location is ready for (and requires) a - checkout/clone, False otherwise. - """ - checkout = True - prompt = False - if os.path.exists(dest): - checkout = False - if os.path.exists(os.path.join(dest, self.dirname)): - existing_url = self.get_url(dest) - if self.compare_urls(existing_url, url): - logger.info('%s in %s exists, and has correct URL (%s)' - % (self.repo_name.title(), display_path(dest), url)) - logger.notify('Updating %s %s%s' - % (display_path(dest), self.repo_name, rev_display)) - self.update(dest, rev_options) - else: - logger.warn('%s %s in %s exists with URL %s' - % (self.name, self.repo_name, display_path(dest), existing_url)) - prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', ('s', 'i', 'w', 'b')) - else: - logger.warn('Directory %s already exists, and is not a %s %s.' - % (dest, self.name, self.repo_name)) - prompt = ('(i)gnore, (w)ipe, (b)ackup ', ('i', 'w', 'b')) - if prompt: - logger.warn('The plan is to install the %s repository %s' - % (self.name, url)) - response = ask('What to do? %s' % prompt[0], prompt[1]) - - if response == 's': - logger.notify('Switching %s %s to %s%s' - % (self.repo_name, display_path(dest), url, rev_display)) - self.switch(dest, url, rev_options) - elif response == 'i': - # do nothing - pass - elif response == 'w': - logger.warn('Deleting %s' % display_path(dest)) - shutil.rmtree(dest) - checkout = True - elif response == 'b': - dest_dir = backup_dir(dest) - logger.warn('Backing up %s to %s' - % (display_path(dest), dest_dir)) - shutil.move(dest, dest_dir) - checkout = True - return checkout - - def unpack(self, location): - raise NotImplementedError - - def get_src_requirement(self, dist, location, find_tags=False): - raise NotImplementedError - - -def get_src_requirement(dist, location, find_tags): - version_control = vcs.get_backend_from_location(location) - if version_control: - return version_control().get_src_requirement(dist, location, find_tags) - logger.warn('cannot determine version of editable source in %s (is not SVN checkout, Git clone, Mercurial clone or Bazaar branch)' % location) - return dist.as_requirement() diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/bazaar.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/bazaar.py deleted file mode 100644 index 3b6ea8f0..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/bazaar.py +++ /dev/null @@ -1,138 +0,0 @@ -import os -import shutil -import tempfile -import re -from pip import call_subprocess -from pip.log import logger -from pip.util import rmtree, display_path -from pip.vcs import vcs, VersionControl -from pip.download import path_to_url2 - - -class Bazaar(VersionControl): - name = 'bzr' - dirname = '.bzr' - repo_name = 'branch' - bundle_file = 'bzr-branch.txt' - schemes = ('bzr', 'bzr+http', 'bzr+https', 'bzr+ssh', 'bzr+sftp', 'bzr+ftp') - guide = ('# This was a Bazaar branch; to make it a branch again run:\n' - 'bzr branch -r %(rev)s %(url)s .\n') - - def parse_vcs_bundle_file(self, content): - url = rev = None - for line in content.splitlines(): - if not line.strip() or line.strip().startswith('#'): - continue - match = re.search(r'^bzr\s*branch\s*-r\s*(\d*)', line) - if match: - rev = match.group(1).strip() - url = line[match.end():].strip().split(None, 1)[0] - if url and rev: - return url, rev - return None, None - - def unpack(self, location): - """Get the bzr branch at the url to the destination location""" - url, rev = self.get_url_rev() - logger.notify('Checking out bzr repository %s to %s' % (url, location)) - logger.indent += 2 - try: - if os.path.exists(location): - os.rmdir(location) - call_subprocess( - [self.cmd, 'branch', url, location], - filter_stdout=self._filter, show_stdout=False) - finally: - logger.indent -= 2 - - def export(self, location): - """Export the Bazaar repository at the url to the destination location""" - temp_dir = tempfile.mkdtemp('-export', 'pip-') - self.unpack(temp_dir) - if os.path.exists(location): - # Remove the location to make sure Bazaar can export it correctly - rmtree(location) - try: - call_subprocess([self.cmd, 'export', location], cwd=temp_dir, - filter_stdout=self._filter, show_stdout=False) - finally: - shutil.rmtree(temp_dir) - - def switch(self, dest, url, rev_options): - call_subprocess([self.cmd, 'switch', url], cwd=dest) - - def update(self, dest, rev_options): - call_subprocess( - [self.cmd, 'pull', '-q'] + rev_options, cwd=dest) - - def obtain(self, dest): - url, rev = self.get_url_rev() - if rev: - rev_options = ['-r', rev] - rev_display = ' (to revision %s)' % rev - else: - rev_options = [] - rev_display = '' - if self.check_destination(dest, url, rev_options, rev_display): - logger.notify('Checking out %s%s to %s' - % (url, rev_display, display_path(dest))) - call_subprocess( - [self.cmd, 'branch', '-q'] + rev_options + [url, dest]) - - def get_url_rev(self): - # hotfix the URL scheme after removing bzr+ from bzr+ssh:// readd it - url, rev = super(Bazaar, self).get_url_rev() - if url.startswith('ssh://'): - url = 'bzr+' + url - return url, rev - - def get_url(self, location): - urls = call_subprocess( - [self.cmd, 'info'], show_stdout=False, cwd=location) - for line in urls.splitlines(): - line = line.strip() - for x in ('checkout of branch: ', - 'parent branch: '): - if line.startswith(x): - repo = line.split(x)[1] - if self._is_local_repository(repo): - return path_to_url2(repo) - return repo - return None - - def get_revision(self, location): - revision = call_subprocess( - [self.cmd, 'revno'], show_stdout=False, cwd=location) - return revision.splitlines()[-1] - - def get_tag_revs(self, location): - tags = call_subprocess( - [self.cmd, 'tags'], show_stdout=False, cwd=location) - tag_revs = [] - for line in tags.splitlines(): - tags_match = re.search(r'([.\w-]+)\s*(.*)$', line) - if tags_match: - tag = tags_match.group(1) - rev = tags_match.group(2) - tag_revs.append((rev.strip(), tag.strip())) - return dict(tag_revs) - - def get_src_requirement(self, dist, location, find_tags): - repo = self.get_url(location) - if not repo.lower().startswith('bzr:'): - repo = 'bzr+' + repo - egg_project_name = dist.egg_name().split('-', 1)[0] - if not repo: - return None - current_rev = self.get_revision(location) - tag_revs = self.get_tag_revs(location) - - if current_rev in tag_revs: - # It's a tag - full_egg_name = '%s-%s' % (egg_project_name, tag_revs[current_rev]) - else: - full_egg_name = '%s-dev_r%s' % (dist.egg_name(), current_rev) - return '%s@%s#egg=%s' % (repo, current_rev, full_egg_name) - - -vcs.register(Bazaar) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/git.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/git.py deleted file mode 100644 index 0701e49e..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/git.py +++ /dev/null @@ -1,204 +0,0 @@ -import os -import shutil -import tempfile -import re -from pip import call_subprocess -from pip.util import display_path -from pip.vcs import vcs, VersionControl -from pip.log import logger -from urllib import url2pathname -from urlparse import urlsplit, urlunsplit - - -class Git(VersionControl): - name = 'git' - dirname = '.git' - repo_name = 'clone' - schemes = ('git', 'git+http', 'git+ssh', 'git+git', 'git+file') - bundle_file = 'git-clone.txt' - guide = ('# This was a Git repo; to make it a repo again run:\n' - 'git init\ngit remote add origin %(url)s -f\ngit checkout %(rev)s\n') - - def __init__(self, url=None, *args, **kwargs): - - # Works around an apparent Git bug - # (see http://article.gmane.org/gmane.comp.version-control.git/146500) - if url: - scheme, netloc, path, query, fragment = urlsplit(url) - if scheme.endswith('file'): - initial_slashes = path[:-len(path.lstrip('/'))] - newpath = initial_slashes + url2pathname(path).replace('\\', '/').lstrip('/') - url = urlunsplit((scheme, netloc, newpath, query, fragment)) - after_plus = scheme.find('+')+1 - url = scheme[:after_plus]+ urlunsplit((scheme[after_plus:], netloc, newpath, query, fragment)) - - super(Git, self).__init__(url, *args, **kwargs) - - def parse_vcs_bundle_file(self, content): - url = rev = None - for line in content.splitlines(): - if not line.strip() or line.strip().startswith('#'): - continue - url_match = re.search(r'git\s*remote\s*add\s*origin(.*)\s*-f', line) - if url_match: - url = url_match.group(1).strip() - rev_match = re.search(r'^git\s*checkout\s*-q\s*(.*)\s*', line) - if rev_match: - rev = rev_match.group(1).strip() - if url and rev: - return url, rev - return None, None - - def unpack(self, location): - """Clone the Git repository at the url to the destination location""" - url, rev = self.get_url_rev() - logger.notify('Cloning Git repository %s to %s' % (url, location)) - logger.indent += 2 - try: - if os.path.exists(location): - os.rmdir(location) - call_subprocess( - [self.cmd, 'clone', url, location], - filter_stdout=self._filter, show_stdout=False) - finally: - logger.indent -= 2 - - def export(self, location): - """Export the Git repository at the url to the destination location""" - temp_dir = tempfile.mkdtemp('-export', 'pip-') - self.unpack(temp_dir) - try: - if not location.endswith('/'): - location = location + '/' - call_subprocess( - [self.cmd, 'checkout-index', '-a', '-f', '--prefix', location], - filter_stdout=self._filter, show_stdout=False, cwd=temp_dir) - finally: - shutil.rmtree(temp_dir) - - def check_rev_options(self, rev, dest, rev_options): - """Check the revision options before checkout to compensate that tags - and branches may need origin/ as a prefix. - Returns the SHA1 of the branch or tag if found. - """ - revisions = self.get_tag_revs(dest) - revisions.update(self.get_branch_revs(dest)) - inverse_revisions = dict((v, k) for k, v in revisions.iteritems()) - # Check if rev is a branch name - origin_rev = 'origin/%s' % rev - if origin_rev in inverse_revisions: - return [inverse_revisions[origin_rev]] - elif rev in inverse_revisions: - return [inverse_revisions[rev]] - else: - logger.warn("Could not find a tag or branch '%s', assuming commit." % rev) - return rev_options - - def switch(self, dest, url, rev_options): - call_subprocess( - [self.cmd, 'config', 'remote.origin.url', url], cwd=dest) - call_subprocess( - [self.cmd, 'checkout', '-q'] + rev_options, cwd=dest) - - def update(self, dest, rev_options): - call_subprocess([self.cmd, 'pull', '-q'], cwd=dest) - call_subprocess( - [self.cmd, 'checkout', '-q', '-f'] + rev_options, cwd=dest) - - def obtain(self, dest): - url, rev = self.get_url_rev() - if rev: - rev_options = [rev] - rev_display = ' (to %s)' % rev - else: - rev_options = ['master'] - rev_display = '' - if self.check_destination(dest, url, rev_options, rev_display): - logger.notify('Cloning %s%s to %s' % (url, rev_display, display_path(dest))) - call_subprocess([self.cmd, 'clone', '-q', url, dest]) - if rev: - rev_options = self.check_rev_options(rev, dest, rev_options) - # Only do a checkout if rev_options differs from HEAD - if not self.get_revision(dest).startswith(rev_options[0]): - call_subprocess([self.cmd, 'checkout', '-q'] + rev_options, cwd=dest) - - def get_url(self, location): - url = call_subprocess( - [self.cmd, 'config', 'remote.origin.url'], - show_stdout=False, cwd=location) - return url.strip() - - def get_revision(self, location): - current_rev = call_subprocess( - [self.cmd, 'rev-parse', 'HEAD'], show_stdout=False, cwd=location) - return current_rev.strip() - - def get_tag_revs(self, location): - tags = call_subprocess( - [self.cmd, 'tag', '-l'], - show_stdout=False, raise_on_returncode=False, cwd=location) - tag_revs = [] - for line in tags.splitlines(): - tag = line.strip() - rev = call_subprocess( - [self.cmd, 'rev-parse', tag], show_stdout=False, cwd=location) - tag_revs.append((rev.strip(), tag)) - tag_revs = dict(tag_revs) - return tag_revs - - def get_branch_revs(self, location): - branches = call_subprocess( - [self.cmd, 'branch', '-r'], show_stdout=False, cwd=location) - branch_revs = [] - for line in branches.splitlines(): - line = line.split('->')[0].strip() - branch = "".join([b for b in line.split() if b != '*']) - rev = call_subprocess( - [self.cmd, 'rev-parse', branch], show_stdout=False, cwd=location) - branch_revs.append((rev.strip(), branch)) - branch_revs = dict(branch_revs) - return branch_revs - - def get_src_requirement(self, dist, location, find_tags): - repo = self.get_url(location) - if not repo.lower().startswith('git:'): - repo = 'git+' + repo - egg_project_name = dist.egg_name().split('-', 1)[0] - if not repo: - return None - current_rev = self.get_revision(location) - tag_revs = self.get_tag_revs(location) - branch_revs = self.get_branch_revs(location) - - if current_rev in tag_revs: - # It's a tag - full_egg_name = '%s-%s' % (egg_project_name, tag_revs[current_rev]) - elif (current_rev in branch_revs and - branch_revs[current_rev] != 'origin/master'): - # It's the head of a branch - full_egg_name = '%s-%s' % (dist.egg_name(), - branch_revs[current_rev].replace('origin/', '')) - else: - full_egg_name = '%s-dev' % dist.egg_name() - - return '%s@%s#egg=%s' % (repo, current_rev, full_egg_name) - - def get_url_rev(self): - """ - Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. - That's required because although they use SSH they sometimes doesn't - work with a ssh:// scheme (e.g. Github). But we need a scheme for - parsing. Hence we remove it again afterwards and return it as a stub. - """ - if not '://' in self.url: - assert not 'file:' in self.url - self.url = self.url.replace('git+', 'git+ssh://') - url, rev = super(Git, self).get_url_rev() - url = url.replace('ssh://', '') - else: - url, rev = super(Git, self).get_url_rev() - - return url, rev - - -vcs.register(Git) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/mercurial.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/mercurial.py deleted file mode 100644 index 70c8c833..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/mercurial.py +++ /dev/null @@ -1,162 +0,0 @@ -import os -import shutil -import tempfile -import re -import ConfigParser -from pip import call_subprocess -from pip.util import display_path -from pip.log import logger -from pip.vcs import vcs, VersionControl -from pip.download import path_to_url2 - - -class Mercurial(VersionControl): - name = 'hg' - dirname = '.hg' - repo_name = 'clone' - schemes = ('hg', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http') - bundle_file = 'hg-clone.txt' - guide = ('# This was a Mercurial repo; to make it a repo again run:\n' - 'hg init\nhg pull %(url)s\nhg update -r %(rev)s\n') - - def parse_vcs_bundle_file(self, content): - url = rev = None - for line in content.splitlines(): - if not line.strip() or line.strip().startswith('#'): - continue - url_match = re.search(r'hg\s*pull\s*(.*)\s*', line) - if url_match: - url = url_match.group(1).strip() - rev_match = re.search(r'^hg\s*update\s*-r\s*(.*)\s*', line) - if rev_match: - rev = rev_match.group(1).strip() - if url and rev: - return url, rev - return None, None - - def unpack(self, location): - """Clone the Hg repository at the url to the destination location""" - url, rev = self.get_url_rev() - logger.notify('Cloning Mercurial repository %s to %s' % (url, location)) - logger.indent += 2 - try: - if os.path.exists(location): - os.rmdir(location) - call_subprocess( - [self.cmd, 'clone', url, location], - filter_stdout=self._filter, show_stdout=False) - finally: - logger.indent -= 2 - - def export(self, location): - """Export the Hg repository at the url to the destination location""" - temp_dir = tempfile.mkdtemp('-export', 'pip-') - self.unpack(temp_dir) - try: - call_subprocess( - [self.cmd, 'archive', location], - filter_stdout=self._filter, show_stdout=False, cwd=temp_dir) - finally: - shutil.rmtree(temp_dir) - - def switch(self, dest, url, rev_options): - repo_config = os.path.join(dest, self.dirname, 'hgrc') - config = ConfigParser.SafeConfigParser() - try: - config.read(repo_config) - config.set('paths', 'default', url) - config_file = open(repo_config, 'w') - config.write(config_file) - config_file.close() - except (OSError, ConfigParser.NoSectionError), e: - logger.warn( - 'Could not switch Mercurial repository to %s: %s' - % (url, e)) - else: - call_subprocess([self.cmd, 'update', '-q'] + rev_options, cwd=dest) - - def update(self, dest, rev_options): - call_subprocess([self.cmd, 'pull', '-q'], cwd=dest) - call_subprocess( - [self.cmd, 'update', '-q'] + rev_options, cwd=dest) - - def obtain(self, dest): - url, rev = self.get_url_rev() - if rev: - rev_options = [rev] - rev_display = ' (to revision %s)' % rev - else: - rev_options = [] - rev_display = '' - if self.check_destination(dest, url, rev_options, rev_display): - logger.notify('Cloning hg %s%s to %s' - % (url, rev_display, display_path(dest))) - call_subprocess([self.cmd, 'clone', '--noupdate', '-q', url, dest]) - call_subprocess([self.cmd, 'update', '-q'] + rev_options, cwd=dest) - - def get_url(self, location): - url = call_subprocess( - [self.cmd, 'showconfig', 'paths.default'], - show_stdout=False, cwd=location).strip() - if self._is_local_repository(url): - url = path_to_url2(url) - return url.strip() - - def get_tag_revs(self, location): - tags = call_subprocess( - [self.cmd, 'tags'], show_stdout=False, cwd=location) - tag_revs = [] - for line in tags.splitlines(): - tags_match = re.search(r'([\w\d\.-]+)\s*([\d]+):.*$', line) - if tags_match: - tag = tags_match.group(1) - rev = tags_match.group(2) - tag_revs.append((rev.strip(), tag.strip())) - return dict(tag_revs) - - def get_branch_revs(self, location): - branches = call_subprocess( - [self.cmd, 'branches'], show_stdout=False, cwd=location) - branch_revs = [] - for line in branches.splitlines(): - branches_match = re.search(r'([\w\d\.-]+)\s*([\d]+):.*$', line) - if branches_match: - branch = branches_match.group(1) - rev = branches_match.group(2) - branch_revs.append((rev.strip(), branch.strip())) - return dict(branch_revs) - - def get_revision(self, location): - current_revision = call_subprocess( - [self.cmd, 'parents', '--template={rev}'], - show_stdout=False, cwd=location).strip() - return current_revision - - def get_revision_hash(self, location): - current_rev_hash = call_subprocess( - [self.cmd, 'parents', '--template={node}'], - show_stdout=False, cwd=location).strip() - return current_rev_hash - - def get_src_requirement(self, dist, location, find_tags): - repo = self.get_url(location) - if not repo.lower().startswith('hg:'): - repo = 'hg+' + repo - egg_project_name = dist.egg_name().split('-', 1)[0] - if not repo: - return None - current_rev = self.get_revision(location) - current_rev_hash = self.get_revision_hash(location) - tag_revs = self.get_tag_revs(location) - branch_revs = self.get_branch_revs(location) - if current_rev in tag_revs: - # It's a tag - full_egg_name = '%s-%s' % (egg_project_name, tag_revs[current_rev]) - elif current_rev in branch_revs: - # It's the tip of a branch - full_egg_name = '%s-%s' % (dist.egg_name(), branch_revs[current_rev]) - else: - full_egg_name = '%s-dev' % dist.egg_name() - return '%s@%s#egg=%s' % (repo, current_rev_hash, full_egg_name) - -vcs.register(Mercurial) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/subversion.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/subversion.py deleted file mode 100644 index 85715d97..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/vcs/subversion.py +++ /dev/null @@ -1,260 +0,0 @@ -import os -import re -from pip import call_subprocess -from pip.index import Link -from pip.util import rmtree, display_path -from pip.log import logger -from pip.vcs import vcs, VersionControl - -_svn_xml_url_re = re.compile('url="([^"]+)"') -_svn_rev_re = re.compile('committed-rev="(\d+)"') -_svn_url_re = re.compile(r'URL: (.+)') -_svn_revision_re = re.compile(r'Revision: (.+)') - - -class Subversion(VersionControl): - name = 'svn' - dirname = '.svn' - repo_name = 'checkout' - schemes = ('svn', 'svn+ssh', 'svn+http', 'svn+https') - bundle_file = 'svn-checkout.txt' - guide = ('# This was an svn checkout; to make it a checkout again run:\n' - 'svn checkout --force -r %(rev)s %(url)s .\n') - - def get_info(self, location): - """Returns (url, revision), where both are strings""" - assert not location.rstrip('/').endswith(self.dirname), 'Bad directory: %s' % location - output = call_subprocess( - [self.cmd, 'info', location], show_stdout=False, extra_environ={'LANG': 'C'}) - match = _svn_url_re.search(output) - if not match: - logger.warn('Cannot determine URL of svn checkout %s' % display_path(location)) - logger.info('Output that cannot be parsed: \n%s' % output) - return None, None - url = match.group(1).strip() - match = _svn_revision_re.search(output) - if not match: - logger.warn('Cannot determine revision of svn checkout %s' % display_path(location)) - logger.info('Output that cannot be parsed: \n%s' % output) - return url, None - return url, match.group(1) - - def parse_vcs_bundle_file(self, content): - for line in content.splitlines(): - if not line.strip() or line.strip().startswith('#'): - continue - match = re.search(r'^-r\s*([^ ])?', line) - if not match: - return None, None - rev = match.group(1) - rest = line[match.end():].strip().split(None, 1)[0] - return rest, rev - return None, None - - def unpack(self, location): - """Check out the svn repository at the url to the destination location""" - url, rev = self.get_url_rev() - logger.notify('Checking out svn repository %s to %s' % (url, location)) - logger.indent += 2 - try: - if os.path.exists(location): - # Subversion doesn't like to check out over an existing directory - # --force fixes this, but was only added in svn 1.5 - rmtree(location) - call_subprocess( - [self.cmd, 'checkout', url, location], - filter_stdout=self._filter, show_stdout=False) - finally: - logger.indent -= 2 - - def export(self, location): - """Export the svn repository at the url to the destination location""" - url, rev = self.get_url_rev() - logger.notify('Exporting svn repository %s to %s' % (url, location)) - logger.indent += 2 - try: - if os.path.exists(location): - # Subversion doesn't like to check out over an existing directory - # --force fixes this, but was only added in svn 1.5 - rmtree(location) - call_subprocess( - [self.cmd, 'export', url, location], - filter_stdout=self._filter, show_stdout=False) - finally: - logger.indent -= 2 - - def switch(self, dest, url, rev_options): - call_subprocess( - [self.cmd, 'switch'] + rev_options + [url, dest]) - - def update(self, dest, rev_options): - call_subprocess( - [self.cmd, 'update'] + rev_options + [dest]) - - def obtain(self, dest): - url, rev = self.get_url_rev() - if rev: - rev_options = ['-r', rev] - rev_display = ' (to revision %s)' % rev - else: - rev_options = [] - rev_display = '' - if self.check_destination(dest, url, rev_options, rev_display): - logger.notify('Checking out %s%s to %s' - % (url, rev_display, display_path(dest))) - call_subprocess( - [self.cmd, 'checkout', '-q'] + rev_options + [url, dest]) - - def get_location(self, dist, dependency_links): - for url in dependency_links: - egg_fragment = Link(url).egg_fragment - if not egg_fragment: - continue - if '-' in egg_fragment: - ## FIXME: will this work when a package has - in the name? - key = '-'.join(egg_fragment.split('-')[:-1]).lower() - else: - key = egg_fragment - if key == dist.key: - return url.split('#', 1)[0] - return None - - def get_revision(self, location): - """ - Return the maximum revision for all files under a given location - """ - # Note: taken from setuptools.command.egg_info - revision = 0 - - for base, dirs, files in os.walk(location): - if self.dirname not in dirs: - dirs[:] = [] - continue # no sense walking uncontrolled subdirs - dirs.remove(self.dirname) - entries_fn = os.path.join(base, self.dirname, 'entries') - if not os.path.exists(entries_fn): - ## FIXME: should we warn? - continue - f = open(entries_fn) - data = f.read() - f.close() - - if data.startswith('8') or data.startswith('9') or data.startswith('10'): - data = map(str.splitlines, data.split('\n\x0c\n')) - del data[0][0] # get rid of the '8' - dirurl = data[0][3] - revs = [int(d[9]) for d in data if len(d)>9 and d[9]]+[0] - if revs: - localrev = max(revs) - else: - localrev = 0 - elif data.startswith('<?xml'): - dirurl = _svn_xml_url_re.search(data).group(1) # get repository URL - revs = [int(m.group(1)) for m in _svn_rev_re.finditer(data)]+[0] - if revs: - localrev = max(revs) - else: - localrev = 0 - else: - logger.warn("Unrecognized .svn/entries format; skipping %s", base) - dirs[:] = [] - continue - if base == location: - base_url = dirurl+'/' # save the root url - elif not dirurl.startswith(base_url): - dirs[:] = [] - continue # not part of the same svn tree, skip it - revision = max(revision, localrev) - return revision - - def get_url_rev(self): - # hotfix the URL scheme after removing svn+ from svn+ssh:// readd it - url, rev = super(Subversion, self).get_url_rev() - if url.startswith('ssh://'): - url = 'svn+' + url - return url, rev - - def get_url(self, location): - # In cases where the source is in a subdirectory, not alongside setup.py - # we have to look up in the location until we find a real setup.py - orig_location = location - while not os.path.exists(os.path.join(location, 'setup.py')): - last_location = location - location = os.path.dirname(location) - if location == last_location: - # We've traversed up to the root of the filesystem without finding setup.py - logger.warn("Could not find setup.py for directory %s (tried all parent directories)" - % orig_location) - return None - f = open(os.path.join(location, self.dirname, 'entries')) - data = f.read() - f.close() - if data.startswith('8') or data.startswith('9') or data.startswith('10'): - data = map(str.splitlines, data.split('\n\x0c\n')) - del data[0][0] # get rid of the '8' - return data[0][3] - elif data.startswith('<?xml'): - match = _svn_xml_url_re.search(data) - if not match: - raise ValueError('Badly formatted data: %r' % data) - return match.group(1) # get repository URL - else: - logger.warn("Unrecognized .svn/entries format in %s" % location) - # Or raise exception? - return None - - def get_tag_revs(self, svn_tag_url): - stdout = call_subprocess( - [self.cmd, 'ls', '-v', svn_tag_url], show_stdout=False) - results = [] - for line in stdout.splitlines(): - parts = line.split() - rev = int(parts[0]) - tag = parts[-1].strip('/') - results.append((tag, rev)) - return results - - def find_tag_match(self, rev, tag_revs): - best_match_rev = None - best_tag = None - for tag, tag_rev in tag_revs: - if (tag_rev > rev and - (best_match_rev is None or best_match_rev > tag_rev)): - # FIXME: Is best_match > tag_rev really possible? - # or is it a sign something is wacky? - best_match_rev = tag_rev - best_tag = tag - return best_tag - - def get_src_requirement(self, dist, location, find_tags=False): - repo = self.get_url(location) - if repo is None: - return None - parts = repo.split('/') - ## FIXME: why not project name? - egg_project_name = dist.egg_name().split('-', 1)[0] - rev = self.get_revision(location) - if parts[-2] in ('tags', 'tag'): - # It's a tag, perfect! - full_egg_name = '%s-%s' % (egg_project_name, parts[-1]) - elif parts[-2] in ('branches', 'branch'): - # It's a branch :( - full_egg_name = '%s-%s-r%s' % (dist.egg_name(), parts[-1], rev) - elif parts[-1] == 'trunk': - # Trunk :-/ - full_egg_name = '%s-dev_r%s' % (dist.egg_name(), rev) - if find_tags: - tag_url = '/'.join(parts[:-1]) + '/tags' - tag_revs = self.get_tag_revs(tag_url) - match = self.find_tag_match(rev, tag_revs) - if match: - logger.notify('trunk checkout %s seems to be equivalent to tag %s' % match) - repo = '%s/%s' % (tag_url, match) - full_egg_name = '%s-%s' % (egg_project_name, match) - else: - # Don't know what it is - logger.warn('svn URL does not fit normal structure (tags/branches/trunk): %s' % repo) - full_egg_name = '%s-dev_r%s' % (egg_project_name, rev) - return 'svn+%s@%s#egg=%s' % (repo, rev, full_egg_name) - -vcs.register(Subversion) diff --git a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/venv.py b/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/venv.py deleted file mode 100644 index 708abb05..00000000 --- a/test/lib/python2.6/site-packages/pip-0.8.1-py2.6.egg/pip/venv.py +++ /dev/null @@ -1,53 +0,0 @@ -"""Tools for working with virtualenv environments""" - -import os -import sys -import subprocess -from pip.exceptions import BadCommand -from pip.log import logger - - -def restart_in_venv(venv, base, site_packages, args): - """ - Restart this script using the interpreter in the given virtual environment - """ - if base and not os.path.isabs(venv) and not venv.startswith('~'): - base = os.path.expanduser(base) - # ensure we have an abs basepath at this point: - # a relative one makes no sense (or does it?) - if os.path.isabs(base): - venv = os.path.join(base, venv) - - if venv.startswith('~'): - venv = os.path.expanduser(venv) - - if not os.path.exists(venv): - try: - import virtualenv - except ImportError: - print 'The virtual environment does not exist: %s' % venv - print 'and virtualenv is not installed, so a new environment cannot be created' - sys.exit(3) - print 'Creating new virtualenv environment in %s' % venv - virtualenv.logger = logger - logger.indent += 2 - virtualenv.create_environment(venv, site_packages=site_packages) - if sys.platform == 'win32': - python = os.path.join(venv, 'Scripts', 'python.exe') - # check for bin directory which is used in buildouts - if not os.path.exists(python): - python = os.path.join(venv, 'bin', 'python.exe') - else: - python = os.path.join(venv, 'bin', 'python') - if not os.path.exists(python): - python = venv - if not os.path.exists(python): - raise BadCommand('Cannot find virtual environment interpreter at %s' % python) - base = os.path.dirname(os.path.dirname(python)) - file = os.path.join(os.path.dirname(__file__), 'runner.py') - if file.endswith('.pyc'): - file = file[:-1] - proc = subprocess.Popen( - [python, file] + args + [base, '___VENV_RESTART___']) - proc.wait() - sys.exit(proc.returncode) diff --git a/test/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg b/test/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg deleted file mode 100644 index 3c72d15b5b10eba024ecbb3395507a5ede16de72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 333447 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%0ACVmDdmdD-+s zPfDUNPM04iBoKcT@frkB43$1{4M||z2f?IALFO^L$!WO3=#YxD`ye6B7x8$FKWUn% z^|E4rhZr7DPjBdwLYA|r;hh@kn2$YxycF|{0oHc|WIqi-)P2M6BV?LE?M=owSCoZ_ zS6I!ds)-CoTSi#6943$G85u|JB1^Ooe(6$6-w7Q7-|Q;Ot2!H!%iw3R6b{i*O~!O4 zX<8S6SYtek!BCzeSo=T>N;?QNl}7}os7R2PsH3R%KwXf^r#!yUM!G68;#`R4DiYcL zmdGL5NgQQ94?*ELEkOqiN!;kLbe!srsg%5GMEA#a`uq|9Lfjz8hb!k;r4dZ%5{F|E z=ayY|sxuHE21!VRaRR;yTLT4Zj~N=E!x#vsO!kx+;7HC)RTl34)%mK1d@<1!$QSBk zZE^7A5%C-|6{`E55T4)q7LM*DVX*C!R)O@MUL&r+M0pWzLqP-ifH${YN9OH*e|4+? zdOAcO)GI$wv?0OTVX9$%TeI}V$8(SrnJzsgymw8hia%Q6g<z}eL?SD<DDnkoGkHZD zd2v&AK%AstSR?wdh{QnoLrs9@pc8SMS~EVy$PR&eab2UD0i;relLwzorlRWi*wq}t zI(%7>alqfnC#`{ANvvI?FhLCZMB+mX4ev@iT0B!RaG6jR>)^8yrB;DIf~tzDz<vCi zA9t<#;I=#84?7MXq-%K)4W}kYaP-E<a8WNzYDG$|Q^X4uL&1$>;+)Fp(BuibC)2@+ zreg?Ue&-3*lEX=VL23Tj_v!W-N$Pm>Dp?*9LIN!iUa`$m<gR_UylEb4kZcfbPe@fE zN%r2d0K%q+=PAf{T!cI|nw$fnJt+>lGIVYlS+0IM0ngF&;hZu;l)Ct0{vwx-BQO!n z;=asS6<xEcBt~g3PNS_LX{$O)?23;hns4Tf*F~Wu?(WkdG5d-Hhl@tBhI9vw?QyRB z6`6@A|3l=Y!K<{uuxJWuUl$Ub9H$X(X$7kx(?=5fLpJ{pXGS+qU{8s@!qH>teVg!= zYJv<-8!jo^QPPu^lJvwG`mn5r&x{o)-rx9QUIL0@m*S3KS~>^sXotu;eZOBv{9FQ^ zF->=v`Xra3uzPeloB;*~<n5}x2NUwS94*Kx#K?9ViK4FZdWM!Vk!D?Bq_Ap^ilWk7 z%vsqk8a6Ry?lpX6-)r;0IbBmH#%7@*UCH$EU2<5~qMiq;97xy5b(c}nGWDAUbfwo` zZN%_=G$3<p0^~p&W;3ZFxa5~|jqDT%N1%+xD0|UYiX9WYg7NSZP~azF?EmCOPO=Nk zeD2K*&e>N`Hx?)dgu*i>nYY{L_(!mO5{5Xsa2ON7aJoTXLK#&RwrPi>9gzFEP!>Rm z72=5xdETB|Er?8rh=o&NKi@Kn0f5d)i|&{~0c{+-mMS8ny`@YKyjt5aw2s67eX28R z|AM=V%N!t-eBrgc%p?7w;iM~c*eY4bS#3FjF5GwcK(ksg+t~^p03(X&V76a=)R{+m z!ts}?idahsT2>hZA5gO7se*{p?xJ0Q+Ah1oV;1Y(Il+@ozL24HKExy8F=ssNhTAAw z-Z@H$YS$!g&>9z`w<a$^|1=Y+IA%-o4oi`g79k<#yznG0_s|ML@E^+QE)GWBy$XSA zh^-3y($^vIz&XpT6J8SIG?bn4NI|;lp90Ayz1d)u(osM|IAWvu7ibI1NPfr!wXoEB zAb)Uj_FHcQQH5oed2j8;g6BD_rGVNgX`Jt+>+b-Ss5d|~64shGO`1iZ6YZrC1Tas= zfubCdU2}tP4Xk8ID|2(6!a4Mvm)!H1hUoC;RM|*Dt-Bbltejjq+MMb0^FUNP$)HmG z0)=}cc7dQPhbfl%dB=`fhv&A?q8`F^j%phBS;b6X{hL4MdaFVK8I<NvL%Wa@xfcAt z@o*u4_GAO}t=yp(`fl^FKi#QsChql5pqYQyqtlIAn0Mv&w1lFJvRg5RN&MsHihjL^ z*)I8I<>A9ahFUNE)Cpe;<hx2hdeuSQ*+J}WqM>N%hE(E40H(nx8!hL=jVa6HE;x&R z%BSa(zLhhAQk!yRlMv$NoMZcDX-B@FqRi!4lTu*1K?F0)%u*DSQYM5tit{5^C~H3h z$Rs>-$$)6HW5SUik1hm<kPT9|-HEVCx{?wPYRtH1Fo*0Ir-st8Mzgcflvc3vml;Kb z+Y^=((kC+1tI=<GJ8QdyKtq(4LP?Q5)#2|zhv5v<o4#YGEyZ|QpefDt6)PTk9Uy7R zO#$c|1x7g`9lYF?q#?_$i8YI&QL!r90M*C<Q5cH^bSvn+OMAE|;7|sovfTVAGvNaQ z;;<I%qz>phD1m1%=D!X>oZvqPY;|pSGH0V?PsSp-wL(3kx=WWN-32NNHtDab`F&Br zf@+gT`1ucmX~}^Te`bgZsP7f!d!ZE#<7!BpYox|OVm=F;-Lupi2$U(o#ia~QFZe@# zpaxB}>M8rJz^y7EPx$Rg%`^H{xmUMse3D5sQ5w>4xoRyd2zVUJD5+7Cjk#dWQZyJb z5HQIM-ocRlIcK(^^=spQpq5-OD3}+Yw7J@evYH9sX6tnxchSNIxmJtr>6K&j!<>0h zbvIfhSK3m+;BHw2;1}jIfsU@2ZobQ?Pv8rVa<l*~8A6d%3V@D=)eo%dw5quHs6hQ+ z1{F{K6}9;X6lPr}H)~w>5RvU`?w-TY53snH$5@neRQXV&i5IsQped_wdhk)g**=*W z_4I=0;M{q2py#+snk5)qe=w;0$|$|iN-W$(;fuwZ5;EC5YUaDsj&zMO^A(s>Yi^g> zxMXyZf#&{<U2w~`yqb5Zv3&Z-;htVe_+&+AO>vt(7xobMbhF8TiX0OZ=$yu8EhuK- zeNcrvVzFJ?Yl^F}?wAn1u4ygXdDIQ~$;HQt9YKTy;0PFs?Kz7ZY>lf`fIk;PC;Y8% zw~wVW06hj%muC0><d_<}@T*)HvY%5r(k1K$sxXzM51@_qM#Et#OBpmA;K?>~<C_vp z^giGTy*u_|zuy|2VGhHY^H8fSR>Q7UG9AE(ysdxpA`;HyM%p#Lf5&Hnd0zuNqfy?d zWuU$TUVm8`{|F6vIgX#Gr|!j{?2j}IJ$ST7{I;9hzZaCIRROkQlv|nAAL`eq(07J# z@c;oGw6nt(%H?@JD|rp%o1wqmW&e!c{OtC+x8H?-rNhUAxPNbZZdWo#kUq_kaNF!~ zlR^ifv&{9j57XvB#Ll%(sJ1}aVLV)E9BKv%4ik_)Qnf0p(ez(YE&*fO7?^&PoVCcx z9ax{8pNRj^e{S*TRUKly#OHfdxPpg78uVISZh2{D-ul2<q;qNhSAcs~h{tcm&)~EW zC2yPJl2?EO5yeyoZHt8&kWs&QMwq=6-__&aGtimI+f6*^d{Oo(V>Nm&%+0rw#$qiM zCaU+@A<%PbR5i?I$qO!bt)bTI)|?;m&Q4Q;1ysNhjZiArFrJCZcAo&62PEETL#q>| zd0@(w9qvk0m%XJoVnSX)31D<>DT*9E1Qa)^!N)Q<9kY~1(s+R_QS;FQ#Q-1!42`vj z-iDuy-F8!FxE+T3yg#hAnl%~7G2OlPaJ#a`_5Ih>x|f@gO_@0Xl+oBdD7@r8+*V8k zh`Hb#-SKl}%@WDq1x&s&YVDvIx8C2sWa+aSoZS^6%woQ-53IM%-;G|j<`p!vb#Ch~ zwxZ@-p=q{@sN6A3DJGIGlb7;I8LmA*)+9~_7$g3edcqxvz;_RFh_BAqM~K(Rx2lN1 z(05+jZHz(e{tv`XK!D4x@9(#^$260_P!mkV=Sp!!0NJ0Xjc!9|e?VKXgA&R^qmXMd zQ|F%1$Atr()>WUH&iVK`3SC7?eVP7<%^C~>PnX#+b{sxDz84bMg7Iy3XVGT>&CEF# zlj{r<S~%;9=L&EUiN&Kp_v<}nMGmYen(wM}6<s#<Ifmw|)ak$q3cI21TWR#7C=t4n zF;Wmouk`~aA2KOH@$xBFB2mmk&F%yzUkBK5e401C1(~YHoH=`W;wm+#xV&a6*cXc= zT&|H3Fh)6ec=xEzlp)w}TYCE5l2?<1czS*Ry<UN+)O%aM6Y4mg1@F@_Dgo=wb+02k zdF|;E;?N?!<~e%al)(uxtNV*b)4?zRWhgZoar>d{4zsJs;a7sk;U7$$166%*o}tzY z2%r3SOZhFrno)Ru+$4GMk3|-&aq$BwPc`dPSkY*~!3bWa7TERZAVvWR(~v+g`aXPG zOlL~8#2mEgn#+X)z~(6}9u<`D!lts6ezDmYig{`((gGnhPXac|?%}z$Ex(aq><K_= z-i^fhJU1pRx6oWx#uWL5v#R?rIB<r~?EWuxp>wFj3Tqy>dyGg0`tIC|X=8Qk-GS6h zvB42$Nm3ma>l*XQ9JnbxgSrQ_-!kj3Dn>jhDXg-kj2b*wl)7p!vCxaiDEEZ@5~}nv z&ZoKWM+7GZI{K~$BM@|cUVn|>qw&}RNbgf?1|<(RJWrt5{B>o|@1TVw^uh<DG6JxN z31%P91AEYPu1!Qbe9bP+#;B7iI*o-a@g#83;3hXdSznxNt4e;#nrd*4&kdxG`%TOX zDXh<7NuJUz_(9H2P<N!uC*~kopO4j`-`U<|{KvYBd4rudP#9i<AZbO<A=jA+^bDPx zMVeD~!=8rf-E%Y}7{DKqa3o*eK`{e@!Bl>S{O|+B_a-RL_}+U$_Ba2xetl5)WohLu zOrfRlJjs@4i60xuq&F5NOg<%8;<<Zy9JTW!c@jW8iynvis!((;VsX>bL6Pfm!oW=% z6hyx-{=x|^A;m{q{vVMjjmBOZn3ONf4}9i@_uGK0ci9BpMVMW=x#^ZBVjkRrv>QHb zC9HYfxhU})V^<FR=xSaSJOgiugE;ojwd8B3K_9^OW?$KhkN8^iF?5!S-0}Vg*!p_{ z$o`LFpDrlgw)~d{K@cLB%uPqd&#c+c#r>!+2^#ioP4TGw{8UelghHzAsz1vO8eOEt z#@Egr=qs0L#%H~T0>U&#<n4lz{t{?y;F5*r;7Hmg<E)WZ0gDLRRT}r$cxdF|TM+gT zV&rE&!i^aEu?ALOn)!Kj*;3^MHxK0ATMq+2Vmm*qHOuR%RAxvCd;+gqEqtR3B*;R* z87Hju5xgVaGIs`>XzCCxc!ocA_20eF;=Wk|sc+Kg@o17wdrJ^{u(T-o=SRN(k5~Oa zl9g6}3eq$b001Wg007Q^Ct2z1Ti94Q>FfV<sZV2#+iXg_+|=$-fG5C4+%tJ&z&l|K z!5Q>r!yTA7Fu)Xuq>#k42h)rs{9~fI*P=B<M2fT@<{%<z{v$9|t5>aCzoe^GHK@5; z)WbGkMKp96xaX*}sK(vJSDjn4acd^KTP|x(Vfbm=YaNj`B0Sf`U_QT%x)ue<Q@R&9 zFcwfNk;C|QPD_eRB8OuPqgHBWsraO&Lah176Zco@7W_$1O+IihUh$>Z$TC}fD_pJd zk%0i#RqFZIW{+DzgK#8YjmUG|7@Gt#?V_mYDGymGz40gfgEH=twonsPD0hzbAMG@N zVU|ja=|t0NB7i0KB8V+=W#A*u%mCNxw&9srYmUZp?RVkNS9Z#n)VI&*1c%8lT4auM z<|%6OZb#Z%&71%l!B9Xzovd*dt_EqXSC0!2UyB6F@EJ@32nJsAp<a&0ozl*Xu+B@y z+djV<260}Y)>Edr0}h-YefWj`@%|?VqW$tu1brq-{oX|*Z6ojDXx8W$72&02zJ%`X z&W=}CXZxdy8~xRRJ#JFd#3fUaYG}}=kF#$6GL-BdI@3bc@IXWE!PUW5kF`L%1K%2G zvIAJNKvo{qWSc?1vSdU+iVpC2F^GC<Isr-56f!h$-}^DTQVq3*$=HlM5Sp&W$Rw6? zOPjJN8@1bJV~$bFxRvQVEi53Nc3|jYk^q5Wf}@A&)dwIsq6!T?P=iquNa{3+5|WvU zQFndK!<4C-kh>p42Gs<bP(PP@(?QfR+UxQz2a?n=u(u{Tj&=s{>fhU)7)Hc|As;(X zWVIVDWNP4MN<)gteKp1*lLEr@3E1<IL|A=8p^AwPB#V*AqQVFq4ZSp|u7C@jNGG4r z@JkgI&30PxuoN2cz)Vcv@+0s`)mVE&|H%fPOnTR-5O)z;RJ~<MYMwgnY)&kDuj)iE zNhGVw>n^jyP+AYD;Y`d)ZVexs@E(5<8vkRi$XpAPKP1I}Q39#>Gytjko?A0W<kX?f zoKI>mXkZjfW`DpC+4vnrhaH^pWMzRZ@3{)+Bi*f0;qx>4gKeNCjP+iASaP!ufNi;A zW2$*>w)v;8+l@JiyLLu3pRjLXxAzv-yol^YsZT>vb=FY{zlhgWc_wEb+*L!deP`I> z-daAHsI+<vyB26oP^QzwY>rX&U<6C{Ik~Xt0a`xgt&T$>n+Qi)mr*Mwvalpe{axHe z#8?xsqUD<_3F5k$Ax6F}N(}U|Ms3bEa;oE-`p1QFz_uBa(N%Qzh{B1$trZ?F<qzhb z@u@()qp3;wEwW%jeF}Cj+O9xv<*TAdzrg@Y-`3PK&S$@re}R5lZsr!+%^(PlBAZsi zt{8C!*vk=Rhy8w8*Mh~U-~cqo+yUYl=J(<=5tTpZ)tnPR%2Ez5BBoJibK?=lz=_2J zxJ=VrL3H9d-V;a_Dmin2Ch>7?LVe3*<NWO!F93ndeA!UjX7C!nD24C37lu^*{(?kg zFpI1Q!CW>Z#eo;jcX06X1}pF+`!+-Q-^;8C?WW+HbjwSW_fYOhM=vdt=kouB$lRS$ zmST!GDx3bYz?)sPp~+alp?yq4$Q4CQKu(~wN@yNe*4oSQX)&y7^ZHD&k<=nVY4JS2 zQb@7GFGJ&Dg(nw)FZu+bVYUeF0ar+R0oYa7pLN99reZkl#yK=-pyjL_I3@=KwO;<m z)hs1&OT!Awx_C-b+?!Uz9!>S~DutyzlV)rKE-=fJX4d6?Nl4-wHoVL6g|YWzK%9{c z`e&xz>F!3ZBV#C`^lLp#ou@rU(4@Wj3&di5K!1#%2a5m3o@XhSJS^9uF{J$wAC0{U z2V<V+=hscl`kVw-!%iX&kOOkY?_+LkWyVc;-9;VJnwT+o5Fu}%NkPy~+BM@I=36YA zZIinC%qDXY=7TZ-`*0{y<_BGb2Dj!QU)Ab1@o~me*Tj3!!}ooB|MY3d60rD&R^NhL z&teO#wYrYn3>CX_L9c$^pH}i_VI;Zu#qIw?0gqW35OPly0x6xf+l2kX2EN_%pj~Bm zP#n4^JF;&=;v#$(y(dSTU^p=T*sl1G;vfetTa2!CxYYy}PDE|Gg2WO4#6uvO)g6IC zHN`bk&gPyiV$=sZUeNJx#WH;Gqgc1qsDML97A9LzOm?ZomA`-a#?eOaSoFK-{`G{N zVD+)gGH$8>uU!nX`_t!r3V&lF20X$S6Q6(C$upQ3Y<Oy^Tfw>?qQW8OPzCV9*cIKT z3}sfkJqCL&xIv#_$*EYOmzY7Y{4lH(j9h%dnhvRCzwtc*qskxif`0b1ztrc5?MS^u zE$t?eTAo-Tz>*9~a`ICcf4DBG{H=P0b)Dh$3EZZ$!TmW}Y4P$=g;o88b^j58d+@?V zH+appG-UfSXys`gr+i9!!thS=NE)~ne`?2DJ~~>Ji~!|jOmjG?ciiq>KICG0=X|oi zh7`}F<wa+8kt|e@mmd(g-*`=#kIyxTLJnP6D2LWF!xOhmP!;Pte7GT=70OpVGkFzS z1Vb@cLg7+i6h2#fm=tpCy>f(`42a?mCMu#yG=9K))fI~3zEc|JrZ5_da3tJ$L7NA1 z&zE0KqL)$>6(4Rqi0+gXdgBTGyN@q3bu-9FB`$AY@p*P}Ic=MV{SJp4PJ>*Ll$aul zJiI(|6ZbJcp8rBff?>>;IxBN}rk!@28JZCI*vb$N1qv`4TXuQ|2p}FOxTh&K)NKa% z`Z>#m*YT$^{cG59<sKK+$v*JfoFP2awwnf7ZD&Jo6d0_hvcjNl3-n^XmRs$&X?ilx z9GoP5>MFXxyqFcG0M<V}F5uL{f|t*bri@}>625r3nnE1y?{L*4hBD`c{(zS~(yQyI zH&}>ni0wd>GbHIxw?uL1h?f0Hvw`tFNiqVvy@w(xv`6lQUhhFSL`%A(J&#X^m2^7I zl+EUFp``9ho~Hx@qaO&djCFRZb!JxT@tB{zFPplew9K`^`7;LF^W+jzYRt*MlpL6z z*s7n$E(6LRd5Wl9eJOF4<rO>nVq&4KMIdXpxOoizP2Nk0ifoxTCB<|Y@e)CKw<B0) z<(q6=r9|NX-mb;)xLMu|DZ_OiEZxl;mVi7gok+sXT{jiB%?M*VF3(6X)tXr2m>YU5 zq-oQmxaX(9^lowioQ_S5B~7^9KNqD|?9`XxT16g5@;Y;|ZZG7sTMEcllEO;rDE((> zvpYs9R|;;{Rq<j_cMnneyGyq^vKEpfq*C5OiVvPf_&hpqy+S(Ugg?l)(c&)^+&+p| z9@xya+pnI}dic4<dn6@VyuF`=TAwp6(f2Y_bY41$Y-_%MpjU0FAU9C40RtGKryA*g z+_bSc#!`Rn-;_u5u@-#23MgD^IzE&DT8(!%d9(wq-bDLr@g3T2FT*vnF_AK`)#<Xp zKh?h&PG2F=(|`|ZNPcT_WuT1id=zAZ{I|(hgnWA8ZiP5K7l8KLf0El!tzC;Tc8Vjk z6L^znVUx8xpnJYq$K>XYz9eL4WMw^Qz**m^Y*@Z?x}^)XC8m0m&<_J|^Fm&F!bLgx zP@CnA%!T_wI(2X?QlSk~PpD)jU7<2qO7SqSJyy$Z?}Th|4vv@Oqsc3O_-tnFwJlbf zuiT5Z<%=f~*|M~p1lMw^xv_l5#2xlmiJ?&paL!ltVZqBM!|y)m|Lb%6pU9>$K8Z&c zA^-pk8vp?A|8NEycWX;K;%KV%q(8?=!Cx*X(6)9~vkhr{Q;gfdo0_IsnBD=y;6)QJ z^M+iAyHqeqPpGX7CTq4F#e;(h0|?6Wg#e%lAc!D<V53!O^k=~Kr{wkr5Ew9K-DY{( znwCplhtM55Y)|mKdheWWRr-FvzNhbw{amMJNd0OT+_s))`dm<;QZ45#DCSqf;U>3L z>{k>OVUZ>$sTNixL|CdM1)`BUYp6z37Uz~uJ8I&ts4x{`F;k_hMr&H=8lL_0eXj33 zRxsLn<TB5y_9cQYYs9%Ir;%!^M2mXptK!c`q^KGPZ^~5;sxN)IRg@2^CRde@WJt|a zj<}z57sAn(ndq{vTxX%H9u}lOsxG$`4QM`VH=VDlaE!v&R{k@|kuDdoodUSmEY-5o zRoe9npwl`D2TOx>Sm)c8*$oTm*UwR>Ik-B)ru7I7e=24aV^`bw5_5;K)s!f*o&DLi zNzmIq1Dzf;;E(VX`emD3Vyird>kQ<GY_Rxtq0ZAQvjh)~SMg6XT!I3V3_*MC6vTLT zWz&UufI@9OWWhGEPw=Tt9p0YF_UYZ6U5P-2Par5%ZEm+*6dX-9`ldtED$6Q3ut6~i z^dSMDIh#>Lb5_a_5TMve5S>!4&wM^KefchnMO()aym9TcC<0snoilBH<hU^Np&x@w z)0KW2zH9Xx%0UuSy-+AOds$bU#c@6;TT>;M8YZ=4GQ^wxb4SK_;5bUU!SfFtJwZiP z6L87rsQOyqAg6;WpPr*^F7lflGsxPRDew)4Og1bRpm$|PaHQsv^rsQzoJmhxvM!g& zl7-fNw|mgL7r%I0uvgNX3d9}B)ut=6W;`*M?bDwAG50A@kN(0~A}4kfvQt)Os0rWc z0ERw?DXnAs?@n|gg;^~3>+P;*ou@53@WjGll0UDk79InHu-zCLmYV^#EoPyiDrLy} z(4I~azx419f!x4#cifr*bvSomp@-L_6?<#p_xE*{b1NqLW)J=%l(%oCYZmQ<3S%7- zNkA1SOa#=ij$Or9yMmSz9hZzrT(8uwzF_4oL_BjrXyKP(!VU6YonszdB~8s?)TQsV zv`fP=rxLoKqz_e(jqM}Z?GZeS^6wcim-*ONFpVX#%H6+K@0(ti)p@<SJ?_uh(d70n zbGRnh^NLGFF4^DFrmfp>T!s@SEA&C(VY{s7bD8znt_w603Als=Zfq<-Ny+WL`a#R5 z;omHmFJF1dh@G<rZ4`@2)_SZV!F*p4hAtf}zZH14CKT}`O@kd|A_|qZb7!hiY=Z@y z>RR^FGYQmR7|%pPsFxg8=5-nR0->&DVG_#?eL|-ld5m~zO>Pu{eQsqGwyDkr$lLis zRAPW%h%Vwfu#O^5t|l-N{EpD7;aCVZ?s@~(25F1Sf0T7GwRKsSi|dz_2Lp{s3rIs= zx~(*F&@k)7V04E6))(WFDVYw%KOZBe%D3~(SiBxXhCynt)*50=RcuuZCh{0HpL9bq z_S5WaQtS+5b#YbkaZP*(GCxW(Bm26F9D`a&S$m$&6G)_SYX!<BY6Zo=DxY0pk;xPm z9d|RgN7GnlZO4ml4`f_mJmDC7OQ~*YJv%_+o8~n9Fg<P+0u`B9n@#zNh?qefF;O7D z*e{8bGN7+VnURwDK!)f-%ruNWx^z7MLxZnXn1L6uEIbM?bS|H}T+Ac>Ww|h!f(z!_ z$;<PYF<OQ`U_nZDtlcKorbWZPt!_j9xVGVtAX<T%4zi|reXYSJv$S77WXeI<n6+ry zEq?EvTx?X3XI@Z0YvdAB<1TEl<ef5$+3OBM3$jF#NGL)cjmT6{A&3A$`opio4yupf zysQJ!A7NA>3J+w~^Q(~sv-_$CT=FmOi$Y=bSC=z|X{+yb9PaanEN7jTXtKt_;7<X= zT?^*+Cs~9oro91>eIn$%iR7ZlSw83iI^#t{Jg8ax)D;xuCzf~S$e0`^5U)chqzDZ$ z3(|E-b44X4|5P|}o`WJURM`L!3rL0K2AY5}0#UVlzGW$b1PN=HX8tmaR`${0G?P<I zIUOEW-XoY6Hgq<n(4Qbj3|EXM1A)FingXD@Bc7+-$ArRrhLYDWyW4waGaMBK3Pd`z zI<DV=`8iw2mw*8nC_0L&u~i}rEjlgs$m_+t2?_~_IwvS9M+Ea+C$e*HC_EeAu9}?W zWytQT3OCu|(`8A_N^Kvf^>4zzB}_pXi4znZ=uiqN^Qvq<aVpsQMRS;|tu=qQ$3Vk* z#Wo9On%hmJkr%HozeIYqS2az*vj^o~B}0=Nag7c~nypqftn?1a!+>}W2@+klKN158 zDt9Ye3-c0FOwN+N?>-VebZi~<U2NYZSwK|w1Y2>R$M((oxyKrI*jri)3-h+63uqm% z*y#=WwZ-<`<_iV4Vl@=&qOU-%!_*5=xj{PRqs_l4SSBJ7(M%2o#5PXI!eeJR7c}+- z`P2387PSPkyyheeSdP^TVLL+ufGWCI4>CBOJy9y-vYBe91$*Ud@k0Jg-U!;exiT)Z zT#5}@^vuGEsc-2Bka&fEYHXV>XOt#f$)rTI{DiLZzx0$i!35+aI%t})2D7y6j=J4y z;v25(+8;HZ&~aHk08Vx1<xk4}h}}NvlqS3uxW;tP&zQZ5ZUXOmqGx`CMdXUlV=TPt zduZ>dUVOGNcB{6wXjLwqxHs-S`n<y2e)@mxy6qO#-75sgj0~bwG2oTtSKccGhQ^TA zDfX|1oRw>MGm;?H#53JxZ_S+wpwkeF=}mE3*ehjyq80|9F84rRQ^K{CRir@w@$f^D z#tcjvE)DtKF|^-?{?I;ZYLM%5Obl*scb@7U)s}^fB9)L|mxpSjTH833dy<X@*gb3* z7rDW;qAJ~Tv!yoaO^=sfOqcRm4g4el!U^-hK@yTExO{l5c||1#F#uAuTqPf&AT#~S zd%c|S7_FS4dIzkW$!fgP7|^`MIQXk;D9EZ9I+1qWy1aYVMBKU2k0zpOceiOFw!=rY zqd+F97}i1FBYv1{xx#-V+8ax#yK{90=4-@`(O77Fm1LF2HXg@~yRd@0xnfEjLN&n| z39lYjUgf~a$|Y{Gh4Xpw%iv!_Oy^4{oa%VsZ_S+pFXR<LBml@}x|$xIO3NV3o+ya% zo)JG>`3*9R2W5^yFElR%sFuUwoSF>z>_!Q1Lh9>hxSBQ)IYX+nbNSRhAmz2)u7Xwk zv724ckq5(}6ca;6V<e9e3A)9^*Q-FjJ@DP2`}hSwoL&e=IH@9sCivY_EHb$?id*Ar z(bPtMXqE8wZx<v{qqmWB&8;f+jrfO_QV<A%k<n=ub)}tB>j#};da91>kf(H~&wEdv zp%v<l8rj2`$>W4l8^3dYd;S4Fm!2A8i)*pRN=%JKamv^npRQyrH!L2rBsD7&K8JSV zi00lsI8qM87-tdK=&nKaF{nq_zmbPCW(}-&q38Yy#gS(<OYBLRmjaXjwZ@eF3SL{b z+%f;BDO|ihXu?Jkw-pk%8H?M^V&$`N30Yi06z2<+^N6XRx~L}sb>##Sh!O=nO7n@b z=mlJW(+7s0vWVK8pZ_SXI}LK3A3C$s)4J1Ot7jvE4>FxNuG-73Ci9oZD7y8vL~CvF z6n;i#)IGirDC#X06@9C(2pWr1sGW`*tyE;&jFNzRbBZTe(?srVsu2fMT%-Wn<dtcO zt~5JvSOnB+5C3vV9N206{z8lG&JndAOuQQ1YgZ^zh#o-U&wnBei&MZU^wGHeMd4U} z#LGV`98=&?ON7nhQ}Z&QfOLn-I<Y+7c;E1<mdX`9vGUGy7Xt}iyPp(M$T?G^Mm>#E z`D&#al1^}2yhp-U#z}g_2rmGIOcXKhGq%&I=m<w+T{HsgM}F!Yk|+BFd2yUriqe)R z#ugO>(xSH~mSehpymx*JvEZexo~^tCYAuOhabJkMFnz0lqA$N=g`0O<xO4V7aWBWs zp(o~z+*%D`o42;6BKJ}lEwBr2-fC4P%qG?(h*{7QN=i}&ueM3`4`Ug~!*6)Gl=i!Y zZ{C8=x!C2CMj8$79{i>SFj(Yx7Nqw{x;N&xbj24RzKb_Q3WrG$`YpXOA79s>@K5&H zDfx%)Ub7^<*W*7MZOW+VnqOE~F4+D1vEUoQkiTck-}S0He$4}SK(Z!H)ZJ8S??JG? zpV)SNpN~D0c<Jmdr8%lbhx#fO*w8Qrtj{<(o9wa}k=O|J5J&fdM`gUkIULQodkcT$ zw@-J?dvK--^BMFEZ58l4Kv3J*RL!MYdZc4d7q>w%uRWdaO5g4X$5&VmRyAg+jhHv} zmO_GtIb{JkZ<S+Q9c3Z)#j{lgWu~>U&rr69agVvKi~><9s{G4_(2wC^V0ZRS7qJV> zmVel+eshca`4OZ})3$s-KP|VLa=rjM>UI&Zr?lM8L#EbIF;h2pxgl%s7$gz(z->83 zq6$;!CO%OF_H=SMKKgsYaK}x=WshVwT5D9Q+Npdgv&s9DxLwH0N)}Bj_h7ahkcl=E z8=Qj;t&0(yBKy)^vSN?5mjfh^*v14!hsXi%R54enR2WJ}(n$a@2j*M`K~^jF0@eft z9M!Og29fCuGEU3J#>(9@9>WSR>Orha8zpiZY}y!1IPcKHP~gt~tl;jV(FNn`Gcmd| z=(&cu9>l`cotQnl9`QtRV|IE4D|x8gxxv|8Ei^Xf5GjLcCfPJSAEQl0`Ry1SA=f1D zd=S~2gfI?rvf&<&t#^)%5D-ZN!ip3q+WN+OyT?q0@ykesLC(g~kV+tD4Z;FKg|5wr zK53yMh_^<auviM@lyNx6I7cOHRhq~AVQwe!0gyp^0*m7fL0)PZ+||!H2kRW^Wnk`v zdDe~m=+7B<@~r^d2_yQ*KXMe?TDQY2{QTsY<u^?_sXfITV()!;bq8IY|Ms9F0}Fnd ztI_g>7_qBDX7c9G)RL|0xXw_mIF=!<52sIO-t$Ee&0<xe52~y;Cu0$#I%PJjNgs># z)`8VtCz!9HHlZvrOPRM|s7crhc}P5xKFu;fA*s8?pl0!!CRFp1O-z*Y>_ujiO9u;m zDom6UQ^@1Oe#>#f2M1Z+hEQrma@5$3U-%}B()NAyU7ulX@)Y#(Q)+0yr<75cW?tMf z^pbp=H8I@!8#-n#LAXyL+n~Xw|666pBxpplDs*r$_a4MS))#qpU5ha?+FsT(c<TE4 zFJA56C*9T`DsmmS?b&^(!=~}!$DNxY^9BTd=Rv=$yff==<Q|pKQy5YxI^;Joz8Fx` zk7Q-DrMf_ACXSD@MpG^UbpSP@3T0ZoTA#zU3;K<=l(^-1?8+C*4~je+3wkD>+)lS5 zY51<i7%Y3gNP*JKW;{p!kIM3}-TL$qq~M__@7TM!POd%XYK(v5)QtVrS5G;lYSy1V zes855rcZy6%3vjLIx}KHXiJaT*{ksJ0%TMN)DlD<s(A9<&ctc%ge^GLiR_ZhN`}F> zJF9yPEo!nBv>jTSCObgYFqPHjdi`%Gw3VaXSZlVrzD*S6RjP@o`%~BFcw|=6-WJ!w z*c<s*SD5Xs?10UMHXYh~8w<7hIAg5B9|x?wa<y*kf43ofpRECFZUyL(S#b!z*rI&j zW{3Yo7|OavDMdjG@i|M4L7z3Pp&5LD9&x*pU^Ej$d|d<~w3S$=v?mYAZVj!({7sX# zOHONH6AQ2{t5-AT@vT@iv!N+4t4C~<_33YJd(KV2YfjFli##)H52Hg)&3Zxnff?2> zc%w$)h<*G48{VxL|A6on^7dUH_YPumhe+0{Rzq#Nwtm<q*m6GVrP$+Fx?9UO5@C$# zdw3E0LZhpV+|I@iX(g>r6(-v9kqy31!%ye&8ua@uBj{}m=S%QSXA3&8Qpb~Ccqkun z(AE9%7?CTX7kAI9%fZ!UlY*BRqmOf0q}9=Rup1uJZmkN`filZp?>B;xdk|xHd6S(t zy#<^<mk(r0;BrJO*D0FCxrgZ`-0f~Vss1*Y{>1<PWuGlmu)r}O0Dx^!006T8PWJh~ zq%J!{V=F_mKNdD7f8729>uOf%x7-v!$WAulbV(qKLz99gd@2&QV&^Q%4^qMcIwu7g zo>N07l*aZn)<oJ+yz&DMeggNrHhTj9=MY|6iZiBe95gp|d71X4_Wf<&`HtY1Givkf zXxdp^U}l085Kt2^>K73pz}gMyv-H9S>b%E=$QrQ~oU`;o2Wq|FM5q!l3Um^1-U|qT z^8#)IeM53;KiINj^cyvqDR4uIKAIV&iGR%YUn=XoK<6!OleB=_N=}R5SBB8SZyRT3 zLV|JFQ?^{YTHDL@L@PF?b1`qWz`ZY_W`f8Ap@_8KPHVTNY1;_^1^ug`kVVAiHQ}+B z2b`)qrtgP<f&{&>ae(AxXy~~Ae*k$vhQFoDR%FjXe6F+D<`k|l1-GV|Ab>TXQ~i?c z7_oTU@9*xt>Aj}kZa>R2sjGP0N18e;>ajz`b9<~Bve6Q&0`ol8xK6K2Rk(J~sG*CF z2gnPVg;kkihhC27u`E#K88R7>*0RJ9ZElREIY4QZX^gU1niATWs^Om5d@>lE9hYTZ zddwy|22Of`tY!_su6H0ae&w-H#%R89!%C$|f0!tZy;Nn@{FT~2*ze2HsDD3{nO!e2 zU^@4TYcsD&45Nex(yQG1k+}{V!WFjI5}RV%GJ4y0nj5_j{?<D&7xESat8TOEte9<t zcZ{m7CB=BUQ#0c@Cv19yyxDBllk;d=q_P+1Q@u^G3zbUJvyao_Aq5%KLwh}!Vm@bm zz8gLR_c?}cO=g%+4Aq0OlAg)(+&*jVuQv?;Lz-6`n(MQlaN`w2@|x&auBgT5NEl|( zRED9sH(@x<lPaZGpQrS<mZ1GRd_H&L+o&0bYjwJwLEJVNk~}6nOeAT=1nO~xDm8FX zP74;vyi}P&Ztrue`cs;W!cywIDr1U2UHaB~OIjMWOc(xtI*PRP;Xh4lPC2ZZeP=aN zxb`85v1a`SP)h>@6aWAK2mk_6R6ClxNN=WU001;V0RS8T0047kbailaZ*OdKFLY&d zbaO9cZ)0?2b963nd1LIod3+pMejoO#8)%?$5C`u$mNn#11UMju<Xk)83}<+N9PW@H zx4~J?a>!{Ex(Z+o8{J@6g9K)Q&1yM{9A{VhNR}NPk&`%z?0kGAa+Je~lvw`g4@XXv zNVcUUb}X%JN&e)p9XnQJ`A~k}-|xLwueuu~XSY|@$Daj>Ms?MDuip8)k6-#n!vnwf zXU1kLO8*?8-?!;E`R6@KZS<>1Dep$@fa-}n_0fQ;?^GWBL^&1Z)lyE~RH~L!-uo!o zgObnKlA~NQRO%C@ZuUsA&{H>iRhUy@UWGj>r0aqT`&8Jk!lDWXR5+-@Ar%g*aEA&< zR5+@_F%^!haHk4)sc^Rn_o#5M3iqjSzY3pH;nOO7MupF+@G~krph91T&#CaBT7FL5 zq?Qk<@OgE&Pu=V@*Zt~dzqu}|n?-Xypl%MB>p^vM&|D9xn?vS$Slt{p*E`hB9p-vO z-5fF3qw40UxgJwD$ISJ(x;bvHcdDB^`TDTByGvDfshhi$7wuFr4ez@!@@S8WXpl$L z!(Qdxq3NUHPVhYLSJ8e<-b0$mr}(;uub<}YUcP>YuM2$rEMNEW^=DK>Ri0L7qi5*% zS^E8qI(zc~mnd=xpRWh_`Z>NH<m-ccJ;c|CR7Ay|quK}Q_Yk%4yb34P&BH1@s%}#E zU*L`&QQ;I{OsMdf3a8a4RCiK^FRJi3UmsQB2`=!03QwwNms;{v_!90sRO*X2r&Rbd zKc>pB@Wr$WUschVieKcSui2u<RrpyhaROUrNvZI4`|KpP5N^%bTQ6Zt;npd8>t$>) z+<L>_dIeh!x8Ah3Ud0x~t<(0_YuJ*}XSqXf*}Jb}m+HH3+q*N^xY4V8_l&)JN=0v| z;7xpH{-4J3<Kiv+56`MkXotRy``Z?K87+qAxa1kGbsmqXKsc*D=}|Y&;<#V{7wqfL z;c;+Yg%^1SXI1!)ibhm?fxCIhmb;jFZTLBE?;RDstD=is^s+5_$?2qY=?a(roC@do zCGV>6Dqmby;WfUv!u_XqKd(L^m@;R+miX&c9?LxMnrkY&&O><5zVGwuPC-SV$AeeH zFR1Va{dr%7U!*@bRrmq@xuwF}^yfnrmes2_ODbI8x6bn+3)DwBRUf1SIFI(cnx{NE zr1KMt1O+P|ec+dXp*jb!xSu|n^xsp>oZ3`467(MzIjV!Aa}#-#!N<q(YO|OAHiFu6 z#CNJujSKOYB)T^Nn9Co@tMswB7FWX;7sEJdPFLgF+WN8h)z7~AVzj*cViGmiR-5&D zHF>caCC%i;uwKE%^y)^lNL8cS+Dg<2nsh>_u^gK8lAU;YG~aBjRhny!D7+r6H~pyA zl>5u{ny68(uQua)ZK)b8H}}x}^H=Atm(QF#H+$`R`FiQS+46;}rSgg9?v_VqFQ1uv z_wuE=+2$?``fBOQnah`M&X#YybLsl*{IxUZW}E%=VD|FmOV{Qv%{TYbmrEC^+-!OF zeY9}t>RkE!?DaF3E;mOpyH~GVJ5#zePj@d|K67!tIYc*0v)8Vcu9x3Cf9b*n_r|%_ z8*_YPe|qEU+~qHpFI+0kUoT&vSG-r6ZI0Ndm*y_&mkiLoI4Q3-;`=mp%|7&aJy=<- z%Junr<vPuAb2z=e7BrHm;oi9r*TU?b(ps&i?_6DLuC6uD-H9r9>CO(PRuETdNq8yV zt3~Up5iMspyIzTSIhung8ZE9Z>&DO>toKSi<cY=gQcV5Cnl;vHW!eu(vk}*p%aM#A zX%^@a-bK}i(l^hq#WYlX;{r7yH}>(4Y?jw*aTAS~8_{aL(Zs$;c#V@vgZ6WIsZn1^ zUooJ&lGN84m56s@h+dbIMuqo2e~W*Qe&%H7qx19J(Mwmkhw*Z)-iTsl&Kve_-ki73 zpb1YOIXY>lx9GHa_(Esy4Z512K>4{CHTklH51!VmyvcZ>%V)n>o;!18mP<5onrp#I z#1|M~SB_x`!~HtiDDdeU^#;5I%lL*pE2k3-Y<haSlG6k2H3NND01J&HWY{7^(!-qR z(I5%S`-I&Ash(GSBTqL9swa<IJLFcMIzZou&dPa1^Anin<Zsa{RvXb$ygubG21(=} zJM9xNi2QhI$;S-%^3;F9KRA7mKDkhw_y_fgI5<5p;M31FDYg=9_=}Mr)cj~=wYlNT zhMS@rp;Qg)QR3I?O}|20IEZV0;IBrFxE@Zs&Cm;E(L;YCs5bA^*Ou@2OKY_Xc7Eb- z)Ytq64ce1vWvSj+p?CPry5GDLC)~_xqu#7n>Q(N~N^m#w*XZ5#B|mOX%8N?0OpRJP zR_@#)K|E^yLEOB9Axs2KzZwNe)34W}Nq-HeIH^#tXs*_p+>9O0Vx8)6eI9E>zub&% zW72Ovs5@;Wdg4x>KJBLfX5wHly?AiSKe)0{#&{1-a-j=BHHkVFFVhdom$MbF)3`d8 zPwFdCr5Yp&S1QMJmZ^cqy#=+J8>@Av(&JvVKD{yhF_(W_$#Pos@jXGYgOk30$WNkL z5)p(+uo&0~39wbI+0sDrg$xA8)(Ruq)D`*?o}vxmKM0cAktTM?(pvSD56BhQB0mGX zr<dr@#H3%PchKIf(VK#hVO!D+DtD{V{iqt_xH6b&;-lQecbct#NuW(oK91ajpi!gk znlNa=m*zMFa_JIn?;BD;01*I%oIoy*UD_Q`1R~(SwV-HUF*od03>{-Z&JBUB1X0&N zr(w_e+i$5YCTwW9n+%1Bu-VG1%{;&+724!GAN8yH7=s;p5cjI9)W|*J_~`cr17)Uf zzK1?C$MFu1^vWvXoW?OmEIw`3dL_nU$$>(Vr8N*M{!$d+Z$kG1S@t`@eVpQ`=Ep0* zO;jnaF<^-N<@i3`2TV&=gG%I2ELZD`i3SIZT;?V)8N90Hvb>{QZepf_YPGE2R^}F% zJR_2gS7naC1EXKM5j2~E*Ud1>j6P6|u^qpZuLN)M6{8w7px@CQq7MWa;o)W@s5H%R z_@#dX4TI89y#;ST6})k8kGI?7{o9UrzT4s*p=RsEa?;hjC-iNT*L{f>z5cB7XhfU5 zafw!@F+JoRv`nbEhpNyM!c^EB&rr#tiU$-v2Z6Dv>39hHY5#s|dss8EUuE1jKY{Kf z-|Mw+7b17os*#@%c@!_jwBU;y{({_GnD+fkHGef|G~>!zHE7ImW#2#MUs|$-01*P+ z%oLie`3-4a?oDrB$zV6GBs-3wf5Uc9*Y!;|^%f?ifHmK?Y3!(MU-)FuHUy^2_KP5E z+cWN7k`Tck0xuFqcBZPnWNYFs12BK70c218N{<SGN$PBzzFUgQdl|$XWr$YhBT+6V z2bnk)I@Os{GfVXbk85rMTaULp!BLdvR^mj;Yl<5nHmFsEDWVp*JW-yNdKl>wDicm8 zv`?Qag82+Et99yaQo_-Z>Kh4{kryOPgO=&6@|gMCQrXnUx9c0L(QKnpZ=^6-_f6<k znwIXIP=J;)kvS_tHU2m%%S(RCp3Z?$ua{2dv)-`xOfK$mPp4%!_qtReh`gNIg>#xW zAofcJ#GVO57Y?qiEJh8GL;?*fcLKl(B2Ih_FPWGDCh`fnH8!}7TD^8`u^QCw5+WoN zNqb`<S(s|s^K_Z4RhzO;60Ft4TPu?vPQ3Np^OL-7e3@5#H1q<mEy_KQSDT4`Lc6tQ zcjg(3UzP@cR~hEF!1xX;S}>D&N+y$F))qs%TY2C*LT+0<=$c?W!e^U3dbS_tnfi|N zs3VL<@^K4JGho6{ytoW}K;>u=Cy%g65-bxoqw`_chZ~62E7a>HT8=ehrHGVF^ehXM zqisEHicCyuL?#>yAs$9KrSHOsu&3?&n9C(%sMaLhV0g)XL0<QR>RQC0mhYIxc|GV$ zeXVKl6E!F(3ty<7DN}APc4y6Y3HH)GEZhF)Xw{N_UcjO^;_dh3IM1)v>r2E-TRAn> z;w<{`EIOvtO*$JQY8KYXV{uWBD#<x%XDsJi@SgCM^#e@Q#M}bi9Wu<7r(UBH5Dw9f z2A&g)IKaqqp@*MX!e=hQ>jt>%NqwowXOJhJSFH3!y9Bi`0nXs5z7r%MFG_*ZoGdRk z5y4A5`*Q5MLmr|7BbaGO0hBk=v(MX+2fu0|ke#P#cb;%2a!Qj1q32FPo~Ix*=VVTX zk?vBKSu}`+AzH75WlYCe3hiJCPIhO6OH}n4&*8;Ky*XKdx0EFU1tOQrJRgiuxL(?W zZ@C)_RCNcsfzcJb;xJEeK{*82Tl5(8wvlkqv}%c@OgMdE%8K@+6d;&|J(%OdM2h#S z)jnF29uQL=kyUue1#<%0Hd&Iee~T!$UR8flHaLF)xwlt#G=JI3>%wo|`*FHmQ1iU4 z`7oIJFG>AAQ~zoD-lJ?2pVcq)sEuzpZ7@{*sE5f*-1OFGQSSWhHx(N8Fn(%5$`N`K zmV>(TkxJ`q=F=CwMkVh3uDU@RYo51RQZ|rzHX-J*852pf!63I@qYJ`8%_<0;B$~0T zXE`FWYLz(4@=DOG+?hBM1k=;gL2zWsr_10-E4#{aEMWwBdlb#a1^>vP*T_4|SI(5) zoh>m*k*rqZrii70_|GH|AQIGLBE)c+jix{XRNxnu7ER+|t%Y|Hrn1%){-oYyB>N!Y z!^Lf^)&;#1V8JE8(1Y#(>=6dondv%+jr}si>OJ0Ie#Cn!zms4{ADy)!Z!p)duSap6 z8_xIk_NhY8ZX$Pjy<IsgTF;q-@Vqhy0T`OE>qXkp40-m>d$iZ*!@ODTNt{-Lf{7bj zp(Q8832_m~o|F^<DZ?beA)#syX*ndrRN(Ga`HogmwmZ`W9<i*uRYtS(7O~}qXj+On zVc<kQT#CZDL8LMf57)v)i{#KRMsmJ#klal{Z*-Bz`4{!7#&gMEG>71f@Jvj4hCY#a z3GFyDGt|L5b+7=7Ys<?~Ls*uE?nFWqO<30wFrpR%J&`n5QLy4aU~Y&e8w4e&9m}_` z(Y_|0Y@Ta_M>$%nH;-~NrfsnKsL%L5^g-^UV6+}p*65)SITi`otpOyz$@`$JG^rNn zHR2YWBbpcH!=Ku2Udv^WIGCo@aFPGgP0izoq|8A_cud8+g9iQ$su~zHpuD08WAYjm zTtw?{DuZXO{Dr=jJ@xTkbcXnYxL2d#uMwSbBV<vG6nWp70yJ29$82y}$<iinZsFt0 z1`6>ClxZNV4EgfP#lt~kIbjV%65Nl<(nxn^;;Y!nn27;C3Po=ym-qJOQq)|!qcr<i zhDw8wGbWGgbrCOvZTi5F2Zdh3%smxD_E_dC?`28E)iEZ01R(ACYR(XSF`q*q!(qn5 z1f=vsk(NM5ucapiV9vOo7npVKVJ~4;D!j$$J|2ML9_aslDm<u~Ln<ED#eh6tp}Tww z)xtjYQC`)bbDB*brcK}bEh(@A8>_ZkddNN48y3}G5yI#eMwkQg(3Fe_TWtbMHJ1Qf zwXy#*{^15g)fbZ!^m&DE9&1F^ph+;p2d9#-lpaEK7T*PnNxe#E-KTwbC()-5<>(Az zRrQ?}Vx@@p=XHJo3lczxOEhr3dSBP|?Q1kkYh*>}sXr0pg^=F+rv1qYC>l#|<KqlI zF5_cGX?pMrV2>ClGkwaqwJw5OysvZ@rN7ti)0{nM`o!Gl6IWSl5X|9wAJyZU9IPw& z_?p?+5c5)*E{Xv)A!{b2jQ*}-dq2hSX4D&_-{Jgd?pbd%chq~1uyNiS%UeX#YY@$$ zRz#D>b`M$M1YFajaSfy3S|P<X1YxUC|8T#2tsa~*a(kc&$Rb!tC{Ul(D0(|_BXx$@ zgg+Lv26ln)(-M%k2!-p_YW)Fo*Tf{ni?oH3nE@+dlcs0Vu3QroM^sTW0ur9`gX)7| zBZ2P5Vy(chMGt_TTcmB&Yu1?)&mM$fl9u!1CAy44pep-rP-HV)(F{lr#)q!dC#Hv` z0xXSlW?&+sE<_FcW-ctSmZfQ~6d|rL<%&tPO!Fk>3h!RPm=fDgc4YoqjkPFo^GG6E zyD7Bx;7(k*BW>~%qtdgjh*V?xo0<>^3RaS3Gbg&gRur-v)!0&j#T-p8qPI(&m0jxl zLLumxrL%78bEi$~r!Zv;kU%cD&BRQI0Qx+(1s*HEO5aGOySn4_5OV(jipyX*fDltl z#F!3c`HCxlU9bx{4Z1XNWHMziB@>g7VK3<El4aD(XWQtsj55r}u1z`#9o7g1YIRv6 zet{Ml;`Lf6tW{*~0xoBfXiD^P1!30^Nwm2m3Rg3)?pxw?yM7!s>c<!)PRZB_$YZ72 z1(lk3)!lN&BC<cT-T2){5`CAIZhprRrHB5~bTrKZ`9}&)K_o+u7e!%4_@BOVDJG5r z>S;PkPXENhCINH`V^(qp4JfWxS1~L;_fo_cr5KGIJRj|7`wnIar}VL<$s}5vcXFL5 z`$kOAgkWW`R&APhX?deF&$^ei8fR)7+4ngLdseB*x~5&VZP3p5tI<+ZYZBsyeXZ<$ z$S^ai8h4s9#xXQmsohZmP<D31G&TjKZN`CD68>}acopE#K9@cCIbjcCrKNVOZ9+RD zYgn|GOACo;FDIomEtdz{`=}^o^Q~p`QZ{esKCmMqGo}j`T;QUI<rs89p9OBOpM_*Z z*KQT0YJr~@SlU4seJT~3iR6&2H&_55Y7Qpl8FiFa&38G#rR#>O&=Y2*wggco`V3WH z`ayi4Zt0KW<B#A2RZBnAHJTc9`hN+c;~BJ+AN6*4`{?&G-VP%3<=?OxpwGD$YQOY7 zW}w_g7s-6+-harF`3DQ&ybR4_nd`|`nx~DqCgKMdy_WKc@|N<c5M2`SK>^TcA%HZ{ zNbc0vsv-1rL<{(A6(dxNXkCoXnhwEiK*xJQpOjBU0GT(=aA6oS2(ch{9bm*NYJruG zwmi5S_*zLeDV=r@aH2<GkFp(!(=HkVgk!U!7@#*^+AwsF0lX8<jnx>+#tjW_QMg58 zSzr7J;Qzs$IvW&et2Tj2rkw`?@HFebA@m^#I_Y!;<i2$0dioBTM0#R|w_S4?f@~^7 zR@gRVkOYQncWd<rwI|1`wz9#NX)m1F1={TJ<}3!Kmk0NQxEd@nRKM;5`<9ZQ2FGUB z0^M~6XIDeUXIG|myF9?yvg<Qt+ie?`Zl+~KA__9F-s&ShP|TEz4Ir`AL#qRZD<`Jg zfaSc>K$fM^aW6!QEihMu>wW{Si#YFEiUwBA_V-*PVp0)gmEAFpwl5Vm+SA6ASu5fr zl&4P^BQ;2zjCf9y?3McJ26pNKpV5VsK1n{StobI8W3^s`*e<AmnuNTraf(ggGB&El zj%kh=_|jR!=VBkol$WZ8;kNdiY`|$&nYmbWs`NTqm^7u$CT29^Aeny$AGT=eM=hrL z;jSW?Zvdi?GT*ujqEru>!lIF?Wvp9P^=@G)PO4m?Eklb9+Tdl{Jnr+necr>*chOaE zrindtJ1iIzDWwIGaSyiSQjgj*&l57oqzapV(t4TcW%IEFb9}<yLy^Ow{mR($4YSsV z6Cn=|Co^<8aX6VgEyy!x=Q}&qsRWasc1Ok_BAG_C+9;R*foJR&ygl9kesep$e5yF? zGgJS5%Ryc3WmEJ~+M;e0j=TFAD<6B)A(OD0u6_4HFVv=^ISXk%piVRM&Y^UHGE z%F1fXw6HKI4juU}X0Z<byNfmmWqNVB{LieU--Ct6bDqd#TgV-jYW^5L{=M$fJeY<5 z-gKd`muQ|H#UV@e^cbq=S6ir_h-J*QKoJ}C;j^I5(q!N4GtYARu9P^7KmAgqXo|2= zS3JNDRP5gcE&LG93kaxTzS+k&cR&b<n<J)fQ8$bRN8yHqr(@>np!0Mb&PaH=6Ru*o z*af#KT<ivo23=KhUZpe|EMhIov<m2`kxt?Q@>b$ao4EY0=OBYa{=5<4uw*L%ybk<p z^Ctx73Y8|z53nw<-AbLn{k8d%qKZnP`ovq;-Vmz(w7n<yXFkL;VPH@DANaSAPO`p| zex~V?`(a+$TJ=`V`Hrf-e`^~5Q1$4fRMma4b#K+)a)x*#s5P?#tZlRy2WiSStTXe- zx<|oc)UE6YA)z{rj!nGv9J=$o?*AOs3;eXj%s89@aU~l3WLk-5n%`+9dGy-O4NM<> zo(5-!c6P1Fqv4~!-Fs=8Qq=ov+2z032o@RTr^2~Agk)Lsbv|BNBFcv*PwU%w^0Xup z(r>4oB#1*|u}uXKhqN2(HBELwj*z|~E28AhaVKn?_OF`~xBOcZts8;%UDCYeLts&( zzo5Er`E(MRnSz`28-pX4(rwQt{acg%jJ=gk%&p|8|9tDr9ijt9M~!+Ov%TVjJ8@I9 z7<y=Wva*K&hKHwVsot72&4hKx`xmK^yECjaXe`o-uPrSRjo6H<)6>p$a2v$#p7w7& zctIbKL;Of@m7}6xKdR}h>gt_<Xk&-Gf*H(**k==msQO#aGwggrK*Z?^Pzo^Ks6lO? zct+k}ZOLL!V<>I7;IY2u6w?_*CoB`>-7=U>R4eCikFn`PkG6X_Fn;f>`f`u9MS`4Q znI#4UJ8u!K(x<li)%yRZk!IYhUw8iY-%(pdP`feX$W0<_i_qmz&z^&JbhAHI=(rCb z=GALkMiE7KA;##(-CIQX45+O^wKb%+hLvcgHrXk3^(+f7=uOQ*+}a#cn{3HTH3_oA zJY$I8Fs%Jj>Hl6r0-J->a2~y>wf4w#2Nyfsewpty@Oytq-EaqZ;GqangwjghbPwqH z_&%gzDNSye3)qQU{shVgR$)^KCgF)!Ng0%^z2k}>B)pM?qYkQ6trjrknRVOK2qoQB zms1`rvF3ki6~YO}g(uU3ToK>|RY%&kyav^UzW`!e8zpyOuj3@+h!ZDl@nV}{yodKk z&}|uEw$o7|Rax-VDj2e+E@JO8Vt9yXeU)C-q=U(7;_^yd(-xSe??+|m%H+xH`)96P zyF6Pi&1%-67RGQ$15FgHu13@f+sNRA@>QiyC!AH(WyaLT*Gx<XFU^bRVfkvQeD3O% zE3<RgS;`~kHEe?4s1t33GfQo=F|rVRq7G-aXVMHK?KZPI<quBWW^Ja}JBkuVw0d`f zMy)QSBnqsEKn-)0O4YhUNn#8<@K<O^2{+e2lpFDey;He@H<a6{3c06p2lCJ5M!nr$ z!Q1cc$Q{m&=El4VOSxPc{IGJ^A92=r=vcXK3KS`5<ALO$dy-~_efMD*-X_*!rlj?d z@%FRzwO~w+5Ffw5k!*>O$BGtw!}Ct*%}##}m#Hm~7eunMz$YgafnjH7L>A!E+uq~* z^N~OW8VVmO(F@>M*utsc#}I9CP4qU<4y70?XPFJ)jpe9m-64h2XYT7ytIoV|cQ(nO zezCrFD`#v=in~3=SG~$LF+^!#pu9G)!d74d*7LWY)7H;0;uD+JL1V5res8bx==aNc zvq65T3mZg(R(H)>Ky0c2meqqiB?C-p2iWSzja+Lnssw9Boe5%wt-?h2qr0bxR-#z% zxLPd61d(W|0g~wO8EPc~v}GD1fWks!i$+YnJ9cla-i)$XBdI&&o7=3YN)sl+2pS*c z?<Wqj4~TOJTr}`0z<-O<HiHHp5B|kO;m<3>MgyFRkRjd3yodj+fqv`V;Z*-Ks(Q!n z+`(tP3NC<S2F%X=Bc2f=hzo?!6q=IqG$j@1G~>C|Ya|OoS23J>*dwMj4DN_5IS}&0 zT|`&yO-qE#T=F3)py2u2yFq$DipZiu;#&6-g?3+knFDKV^_w2_^H(OJ(tZqZr<rC7 z#q9N<vC<(nmmUyzyWgBO{`MwQM$*jzrMoEIYbtH>y0@jHOoK5QIRp|5)L0M5$OGP& z2TiXO2(6guzSPKlr<g5yI=%-{d9^-j*`@dT&FtmX)(-x<gQ>(}h+yU?VBVPgj0+7e z@;MLabT7jf3+i^-{A_f{#-aid794tD!Jk-IS(r>uP{WvWt_CrI<q6@9r`Wz?a$!n~ z%opS~p9i-3LF<mxKGnu%j4hb-7tO4p|5EiZn}M!I;pC~zan{xq`bBBOt!5t5xYJ<f zKyt$_rnAR66@F8rxZ8s1bP-3GpBi~sWxFww5FY20xGDojKK9@Xo%e&5_+#m0>6$s^ z)9jPP<PE#6`$wN=i5t^a#BR+^3>w0#^dDQI4|uU$LA-;q%yyYsd~Fb`@5AF&2*uAE zvW=HfN~Q53O0%N><l7(}b+C$rDN%t>KV{*QrCk{>%j&c3Z6ctH{dcOVDwIh;EU^^Q zB;d*0VpUxgO=<V^qkodB-p^@6XEn6DXP>vnJLsM49q~rIqu!vm(;M@q^W$Ehw=-AB z@6IJpQ@KOLXX{30=yKwN4{z0O9XWXW=;ZSZE+I_rH{kLg0ir6v$Mv7msNOQB=WqYG z5*vQ&-6FgwhZz9idC2_cdIG3-{`Osle|-R8`(b|A$M%o7;i&^nzM*Xo!-8gc8J_m3 zrM%iBW`)KEQY!5S)YJ|3LCy{s-LKxbcTwHAx1V@Cf|JJt3ijzvYokfnE9SLrVz%{7 zKqL0E8FitNwG4OcEgVUowtg_i6Ro<$R8=MAv=Q<BC^3d4nyL{1W2{O3;GOW)U44qr zwQzda-Y*<WUQ=R3;2&-n^{64^(B|QU?I!~eQ1^ps9O~JyCZ8{`57iU3&^nJGue5B2 zL1(HWLF;V&Ane{%9Vg~eY4+UpOJ4xmDE)^9;IPoW5v^8(N+i~qIHRRMjE_I1w0nkQ z{*VHRA2NW0`Aq3uSu^m$`thyO(XJi-pP{OMCZ|pLReu3&ocEm9N1tQ#uaJA%+u=Rq z?WL=|UIKXc;RMTlC*FGV*8F6}XtgX&|3yR7=h_eYPVLFl6cp|;CI96dQ~G@Bv?i>F z36N%9-<oIrOsWNizohGmO=o9iZ6$*^JIaQ&<EVDJ?=g_Jd};1HvFnfouroZhL)5S^ z?u=66nnQNZ8;UcvaFG`$-C2<TfU5pN&iZ7$M9_CISHb)HG*snj{tA7pZ)h5nC-*Lk z<9Y!q!8S2DC}u=^Kk8NWcf`Jjy%6{AhdwdSPE$}(_h_aYGO@jzqN6rp7WO_z-=IGf z*miH2Sg&DqBeY_!fp%)kfDWyM$bch%BCb`cYi#T4kUgn|Koo=`7_+N6Ips5ghLVJ% zsw8U-Z7sn*!nz&Tc+XXL1g$1>@Xwe1Vb~w&3Y;n_vDI4Dc*h4ZadfF+wgcI)t>U~P zSXe>c4vO?tXkbKe;%=ff4#5(=1!`5Q5T{|gN<EgO0T@Yj+f1VfEpa^qOBfW!rH!sZ zivNnL{&LRvX7&xMA#aMH!Vb@FPV3P8AvWg?cXM7!Hz#eU`l}+Z^|ZI(Q2ns=V9*;e zXEtJrR_)fazE<C-TyqH7BI&L$N8WY0O0-TWNxg$o$7lQq4R{JBAa;Y8Xgit34>~S? za`6e)8_0(afejsF_k60A=(zkV?aN>KAMkM^i$(rNd~|Q&{{mJ0^_+2y>BYkDqlKS9 zfUj2V@#hUp)Nx4IZsW>(m#<&qkZgGJh1t^CtMjv^KcTen^ZeE8XD(kZ{WqxpUmF}L zeE(151MD~xsimLC2QXIYFXIEClD8#yv5Tr|p!i;l7@;K!`9h&ExM#31_-xO3Zs<sH zXlO_AB{&EbpV^%&_7`_pB{oLGN^Btg7A1DXbZpcMnh~F#`lOfRfA%~7#gn1m81@wb znsLFLH!cQ^%6f?P)vUWNX+rZ2ZyUw3CL&#fH!X1jvDS#H(S0aZQ<pmNdte#Yl<>zf z)kya-NX5*~P9(@xl3MFJO+ZX`-UzxXM0Hix8qh6PIc8Uu!p&L~I*s`7{7+`IFHJI) zhUJ=)(c<1p)Vxy<lPUJDh%4r+SZtw?Er1aa)>wtZt07FSnA+O!;#_GnTI=WM8B494 zG0<`>Y(o?GEdj6A*;30=q7vchu|hVMxi=Q9{W7F&vc8Uh*~~_(U8mUs73qO%DW(_4 zpKzKn_qdf9bnl8NfwjbuMTbkkh=DZ^oNTcwOXB5PAc2y!skcuxnstK6wwJntB7ou6 zO{KIe8KZjFo4}c}OH!!AtPw%KM)Ss;%#zrsGw@!(v@a0!ucrDe7Dt-+TPe0M2LO8o z1Oo6uYK?C8_LFobS_j1wmD!VJn=UzSGS#XtG!pfO4-F>LEDhr=iE@`7zZ3z94YQd2 z$j%WfDZ+@0b%J^PMNf_>vof6%-540cr5FmuRB^yfnpQYIn6xgu4!2kO6{Te&nKrv; zVE0cg78=u*+j%~;0Dpt#(5`q&M+<;~``biVNQ4?TqI<}pRno`L3f+-QgA*)ymfpCc z^}-x#N?Xf^90H*BoS5B9BRg4`5EoKSJF0D*194_02CKtTs^63<D2YTRl)A_?R`nbD zxP=?F{i=sn1W~JpC2F-iL&)mQ9`pL6ZeO%Pe~-HNT^_p%h^HpsstvPT!hVO`InQnd zWAb2!7U+6L%P)HP5hbc|t)FALGri<tAM4CDE%s5NlbFM(PCBC=F(bF`R#{3+HvAC> z@37@D2>RMa8@@5;<A|;Ao{r8imUb{AF%iA(2ElSXHo2qv6)A7g3L&QL(NCjbvGI|0 zIH@<X(X}#7ImkfHe$Z^<+%P^~Yu2IWW6N}!F6yfRQjR{e0qKPa&!xv`CNJ$0P{B+( z6Zkpip8+;8zB1PA9u99t@!2+->6Rw0*FiMjH+Uiwzff?xM)9B=%pPblZW31`7x}Oy zvI(XqkJ&Ox<Npqwz!bW+`>9=hi%qmq@wT;aC#tTd&A6uOx;5hgASUy1`!HOqbVB>B zn^XG^=ryrHJOvHfJ;+0sFr-=R;_g!IcU7yq+r{?XhJB;$v<Ov1nDHb<oKqqn783&7 z)Ci4kjk}eACIiQWC7NOXybkYl=mov2B@|{*<A|id`)kyX%-+?g4k}qQ7p}6Dc_G>_ zCT<+;$c+!c1cW%zy0A)<X?V9fx0WS1@slD-dORVhiB4;EV-kH!qM!k_4C7Rzer*8| z#u}a_m~ebCL`cl{Rs>=ZhqEY~N}rUhiiS76K0*_VF+2CNm^Smoy2+Umj`G*E3j*s5 zlWxWizv*<+5hO#8%XFUOD$+6pfmPcbZ4**3wY1ZqA<4S3!_~7~#+%FK1qK#Q6ZFO} zZKbP$Q~Q7zX8mS&@Y}xLzBUDvb!yaECgwYn JR*Bmc(Mj*h-TEe?gKs87Apsg`& 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�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 z∋An}^k*ceCI&@vke!FXq|JkFP7pFXo9&<=SW9?>9j``7ZFVt%+!EPV1G&qwq7l z;|bvFg&>ZVxD3zXsc~IAa?bM8reaD-EU^2`qC0`sxg3U6$@V2nGTkU6Dkf~-L@M7z zdoO)3f9ggqNn2``V^cT?bsPjdM}kHof<$_NOI3(pBPn_30U%74@>O-I&K8_by-g?e z6oAb(jH^0C7jI*gMzgY>{i9Wr>i+r8>55tibQ=D7vzG2kjYeus%6(2TZ8a2i3wPNd zU%hN2IQ0?IsMn^#0MXSSg^t9qNzC%6w!cy>+Usi-0895n0ALv5$tmvn#MQzVxR}|^ zo8U%5`6a$sBb&Jhaz<>mNN&ZWHDsFU9AmZi6eiZT%||ZwW_#~csl~O;8<UF$Lj4W@ zT3AX~W;iBTEUGU__iej=T^t+noUSn%LdS9O$@uW4L4+Uhr}uUK%x-q&eiRr<eI}Jq z9tyWT{a?F)*C(G(c8qR9_8KntJZ-|4q0hy)a-LNNb}dF7svu4z*kElYLk93qS<g|u zxBk>TUUMHqHHsbV=5>KHc7K1RUZZ(wy8wPu>tZCN_IS`>{nsX3VYEtMQ%ZcnLoi}} zdBLF1G97z=fMICJmuKAZp$+jJo2;F=Bd)V*$aYBD^hWm_3%25~dg!!6(BUAj&n{z4 zxd(izgEGfBTYyXX-8D)ZQL>@Lga;ij0~px@e!BA!rX`6Ef!0d9M01cG?QdX|PJ*o* zCx9NZ0`$-c8KTR+aL|4q@W*xF1mZ(2FxfCkFs42Tt8PHyFxOQ6r2p!WAN!b1wEUJq zsv3VuxMx@I48!4W4dbyH+&U0IEXBF+<sG^VPmD{%apY`%)82BGbeUIKC$5T-ea6?1 z9gTsE@9ks*b2scyko9rxq%oVHE*-0O(BqcAW&-Qql3S5485SL1Z~gfgnJP?Al!sGJ z%U_+Eu0@Xh&Eij&1XyV8AAd_}53%62Wr|UG%h$|5NQ;2CN-zp$wbX^q1_L{Y+a9k8 z*{rpyxJ}NP5h5m;UH83!K2z`h)niYPUrE4W^yFYqNX8xsu=yir`5}1!TF5b3W)fMP zma4(p`=i9SxYGa1BlAo79WZWIYk;YjvO=H+6pn3!Uoz)7MjPOzZGh292!_dbjZr3Z zmhW<ej&3|TOj~~+GYB-PZNs8uu-1UL+#*T@yZOz+e<DIewaj+$Qoq#K%GmTv{`J9F zy;4QK<cWj+<%{|z8qaW#3~~cyGDskc&1M!r2DR$A${Qx^RZV5xphY@DdR&nlw=^an zNE)XtbcO7}uC{aj<*GJ&*fOKwFopg@UFjk+hlltYCWIe=(bYC@@wZhT?j&~&P@5q* zL|h`-8;9T=5@+_{)*|c-cV?k{mq5c|HFg|h{5l1&T|zcj&g|HoDdr^jpRUGj@pE^* zpim;4_O`@`I)UyDt;#CVpjI*W8Bws-8L-lPgo)e6lc*^#nl^4g*i(!vaRqR5%9u`5 zidB^Y0oXs8&Z18kEa<hlcQiDdm?Dw;7!uD%=SPg=;kdFoU>r5vzph23M?ZsuJu-Rs zywLcAQ=+P<9Kyqx6EBI6$VyLDuZ50~gEv$&SL?Ak=C=EzJREVQ-njaj8us17o~a_n zBrLj~T#o;UO{;2102l9A#sa4W#d_=OQ&~11M10QZEFE8-zM!8Hv$e>G;hf6eDda_- zbrh2NLzE?3H<^4pukpqJr|P}@k=JUhA@|8itP&9=1&Xnk*+f_39jKlLHAjgx=|r|k z@C9W|owvgi^Ve~84>YhXx)g7aZjvNc*d~hI9xLV@uI{nTv&jK$Rk>&G{fXf#ZEnq_ zo(c_3l0L&G<=<F4)KGhS4oKUXTJK}-AIjeY8-QN4$SYiNXQJBZSnO7~YsgNLS0}M= zJ>HOOXP%Ogm#ay;gJD3fY->~bPqb22DrLj>X}{vMmpN)pXaL>7!y4%Fgjnm;v9%#l zL66fG#-s3f^52fjwppO0*U)P1ZO0QhkB4lFsq%a-J>P<ZC`|o9k+v{`Bcta-X`f!7 z9A^*(yhK4`lDaLQ724YrpV%hygF@~My6q@1DE8R#WI%=n++TGd?#-Ff6ZHw#^xYXK zG88%SA^#kGyW5lCz~{mULcV}E?MLg#f`uJ-qVQ0d9eP_4anRjFgMklHc3@HB^fS`j zNjO3eu^)`rRP-lkM;;v?<pd^T$w4ZTQwncAUGFk)lE)NQJ*>h9{TUR+r$8ai2#a{j zV;O!I!t!n^3=}lBARnmDOYD?>7NSBc?)#!xp|A~2_2%^ZLMSKeK&!M6qX;zie4jpP zqt-ND9#=ty79EL;4*aa31{Lu12{|g#!|T=_zrEp@AW%5eqz7JIU=L3p$5k#%J(~u& zDaS0Tzf~)f!}tVTBpOeW%aM_v2{@$FAJ}i)9V12?r!ZE#xwhv`;-vRO0;lO`T9JNJ zwl#*RKAzpaR>=a=n<uF2rtvG<gqv_x+B`p(6M;rP)-0pl1CXY%S90wLvvT^fJ*8+P zkI&L43j+}A2&6B%*0O@O6!*23XNT@2ub!qaXyx3-2UN3@RQn>-+}7AP9w^qqJ=w^M zH#06U#Rs?n-|_@YUc+qD$&+cURw%C&ys<Ae-KMB3L+PUlXYbT$cPWtoZ>Tn5#Sa#X zsaAfE!oWKdE~6}O%pucuuo5&7&sr3Q@(u|Gh@FuPM@^thCHmN1W+kMytl<FkAViP@ zOD^0Qm0PM_u_Kcge?qOmr6^Ievnf&R+Bmxw0b(VVE2JUQN9S9vaW#QFQh1iLx=<mH zsDusJyMxn05r)BT)4KOtfkUFA90ovGrZ>Pt%MSi74k`Ex*D{X2@ublqmC>>Sh7KrK z0)EV@Ze7$Fb0KUC*z>oNJwhrX!o|>#prn@fl-Y%g%9hJ_lf%Y9Ul2`-FdeeHnZa2a zq)-jiiXg$|qU|}$I)KAG&3MIbf9;&i%#<u7lhf~AUOLva(SypMawey|XW61{F_^y0 zs)m+uM8F?PkitZuTS6jPIKbpI3uCMw_9oX-bvFs?yQE<$CBbH`&N#dS-_iJ08qj4m zml5P)dOt{vtA68>yI=^~=OoA1(G7GTEtcbMvi|S@yj>Z(^i38{d%Wdx$U+dXb%RjA z&%1o?k_VXM=1;W=zWpdj)Obq2_gg2ERgY<E7P*X~e;oorAa+0W6*+xyTr8y(%poe< zgZqk%AwU<(&B}}R=#B#?C{wgM6QCq8$08;rkLa{1O}3)N?Fl(BQ?x^0Pe3XzfHYpx zi*Qnz#{&Yl6snI~C>c<gVn^fhJ-@~^;@c#mn)4D1|8?eu=P<1?z3<{mSK;@ewU0pw zxuaWz=MRd;zo%m0R{uor@NYCH6OMlLWJKr|%dAe24mYfN>0iP9-BAG4WMZ;D35GVn z5@C{S6vX*tmb!kg_u1rwy8g9MgKj3UnTj53D%xDcP%mnjo4q^SEeL`PrLKf&%_1tw zX&WXrH?_XgZ8<3jQ^c7TFq6XL!+j!F$=>I|@wB7po=sb!MiaF{h(Ie0%UTFjB9Q5M za&~=3V?u4JK1-}$`mKb<#GgQ3m4<7)_#ByyV^nY+P)=wuQ|>y~*2Md&(M$u1EoT@y z2@h}aj)SGYFT)EMDnxHS&xJ-a%->Btp|Ca;`#)l;dl@nuXgCznAxZljkZVE=2G7ut zo%#k~*LX1CAYl9ma3Nzs#{1#%<-$Vap2@oQ^+!#ijeK#9riXJ|WK}d?j|2qJ15o8M zJ0Zi?$yMrX?@0m&ACHyeRkckvZ{GPtp?pHO5&nOvaax!-CmU>=K_I9*$S5B0K=h~p zx9XbndGqC<s7WoCEwyuE=RMk1@;feF&7Vk*a_d=Ms?-o%E5uuFF8H;H{_tg-hh6JK zwDZo%?^de^m@xHl#V4FI_J^ej;JXhpG*YX%I-*lZy}ny!`n1Y{e!NT+h#--El&7WC z*Ui)_Q0b^fDLR)V_@6f%YTO_>O;Cs|FI)CZuq~}<iC8G@Pf7*8@RvI|Q5gvop>ufh z>QYn2aP?_O%}o_j>Pm81ExSe%p3VQ0gIKJt5UG%&pI{DvNKdwv@5_xUjH1S8A_lNm zmGBKN)-d0;B;)KDx0oFka|xS|J@*iNT5M2aRi*BCFWL#dF4-7iIumIk$TQOwMt`$e zLTqb%KG8!Gs&B5^$6nsh>d7$4>s6JnsQfk-YfrXfT@hPEwC_P~$&3JUt-$h@7HZ)Y zXAT-sOmz4v$y%1fjrVO(2_z(GhR=b;W%;Dvz7|PMXqP8GrbELY?HY4rs&wsu;NO~O zw3Fyq*)~s>ay?s!4k6w_TiZ=Vn@nC^=|?YVhBJtBM)OiXHIgi#u28RBXtQdD+={Ue z7Y4g2F#<ifp_KTttsqR)O&20F3dM(j2Mamqt!LoM&qreLSqqrlpHHZD3!JuBxcaH) z8&;H4afkHJM(dQ~#KZVPmC!<&nH3j6N(iM&e4;dAL1ERL?+DIsO*X*-a`T0sXqJ~O zT@Bicar4WYeqo@%tgr^fL6LyzU>{Vv<6y-%Hs}p$9WZ-IGJ*O<6rtD)i3UtUPHW%W zNPS;@Nm76v0Jd5{B!0c4cyW!t;NRXzqf@H*)9B0|31`WJNln8qEM}?gyWKVi%a42* ztmDR|FB8GEQhMLuR<8h>Swn6I#x~pkl^$@E`GQUM)1>G0@1knIA^2e0uVpHre+aFF z-&omj0t-EA1*|@(-(yq2IU_%|H!RY<S+Y8!u%iNWv!dO<p2mz*2@#cP+fZ=4m>m<+ zDV9_YW(A9cnqTWXkSe;IU;)h#N`&J!Y-rK@cJ;<bYJCTbYFR83w4KSh%;s~sSn5{t zaVn$pJ6ZCMAj_Yjn-EON-_??7MZULEE2K-~Oo)mUuWHMr+|g;z_p@9<QvJtkD=5KN zr>D`0rR(8qaW?qYv?%8vQoKQk;(|LawvS|E`Z^gkr|&(|D@5XWcE9}5EkGJF2+pLB zFiTy~0j=YIMB@hzw;M8~ZvSe#iVP?E#?9Lx0Z~k(FJWyy8I&6kM>-&pnN|n&lu(`$ zGIkM#lYSppxTSAz!ni(oPwg-Ffiq9_0{}<QWz^VGd!J9p+ZIeTta;pbG&$}lK&+xm zvzLng&!c7G82tqW;M=2Op9o;DOj22>9rDUvOg=D^W*l*lfQJ_a2LcaHeCW=AEF0xo zWfC%m6F`u1G7Hkfi;5Zcwvf;s9*QSSJ57Rd1$gSZEthrR`R|(U3JNyTcv#MKqU&ng z#I%sC_&Agc9!X>t{=`zXPwFiU$Ymu!!cbE+NW^@K%CN?Vs6j;=qlsN!Y-?sc-9ucx zbPcEMG^9glRM7fchBQ^H*P;ewmy9B7t!ou3D=5a?E>P*1Z1RO_f#Ny5ZV0usU;(vL zRZz^5!+C2qso+BGi0z+x&2=Z?z-&nx7w}e0+&J1H;(>M=s84Pz$H9-QIOK0mW5*MG zu7xS41;!gLtM`Z1JZ3vohSfmIf(m^F*)PdGYE+jYTfGayel=9yl*>GZsVs66&`UR| ztt}#e8^I~A5)LMfyHM-_?d8!<C=YGhKC{6!nfy>*bMfw?Q2`L?<F;paY9uT{+9Ily zP2cPSZ3bhO?N^C^xR^Y^Zi{v_8bHp#(n%Uv{gG0RgDlp=Q8QV~V!Wv>y;7A7T<e_D z_YEg4xq4j?QtvJI)D;`ye<sJx<y<8fuf_Jl#|3CiN?Q^Ragu$3Q}Yifh)*YPZk}EZ znIU!c9bi9&3|JG${J%@$V{+Qm->dPvT=U?RPOcJO?&e)oZ`!EqP$vZ7*8<eU;VA)q z-+GDRf}I)<ONOAHP|Nsj#C0?hE87}|&0P~a1o<7i5O7Nv=SL7}tI4_bp9*GFvTW`9 zq6ctWgErA;4gG^MgI-D5`}y%X2=b|ly2#>v=!~7p%mccbVkkYKuD3x(1=}d4{l7-q z9O`L7JVqxduK3hN(M+NNDZA&FWiAK-N!ynB%-6QAhAv|T6jkw^mUBAgUEcrHf6O>& zpUC|&YVcF1Cfl+KWoc@PN3!(Lm|?qqMy`J1{Ky!KsL8)=|7$0mSa_xGAl0Wei_>hv zskQ=I;#Ma6f)HUxJ)5(i_A$==SkZ%qRkOVy{xsAoe(xMH$<B`^MHyFF%tV}|iW=79 zQZc<AyhGE+f+jK5vlnu*_9HZ)`5NCAL^8;`zONR3f`;Y@2cX!gXIJLo$|z?`7NeHs z59vDo5ZqZOsKn^Dq%n&q1-_`HVTXOeSew#Z#MC>c2YSF&;9`qKJxFcViey^7f4|En z2QLrLV`aEI<DsBnSkt^iM=hv9Q*Nd+3sOWB-}1S;$LJoMQmn0Abu<=q(tK>@u*Q_S zObX=h$q=y6);W~Zcl#cqPN!dy-Pi7%!lXoPeN_=16KVrs<@@)@G(8wJvezIcYU0wi znQ;E|=I-&-{&k-h3|*zz7Zl)t25>l70fLknONf#MDHa0IgCje+FKozx6AqMlp#GC~ zqE9hCZ!qX31RjMf2uq9G+)?DnO;CTwYy-ISJZ4+=D#(MLH_%*j^d|V4u@yzI11W9j z`FRX?-#lhc?!@v8&gA^|+W#*ZNbRD3q;rJ{hFs95JQlnt2;6jbpYO2N*>Z*Im>BA( zqv-=Z)WSXbOe2j@MX;9_Mt2o}*vG!&%W`~6+bm`kZUc)wph?~B$>wT*VqPDgG0h%< zbD*YyBIMz|LC0Hgn9@@G>vw;=9l^^A00}Cy!nTI;Tz^cs|JYU7qjXsIwjqEGQYSIG z^uWoC!FmyQ%2T53NH1u6`#}nD;MJ1CMc;^2*5d{LrX2qjo55nVvI6#TTJ+(n+P2z$ zYkliFiRV<GH4b{}T^RqN)Ct8}^Cv&ocz*kI6@+A6(CEw!)kvQ&{F(1t7{@2DafPpX zN2Pvy21KQTY-btwxnDfiH=8SpwWo|B4+okIIKnMH1R0cZ$XByGCY1F4g1x|XfEo|c z<D22SItM<arD#{$?NEIwc{j_H6t8U-p0*A3!g&wfJ9L?0m#p84+0wMqUA}IW=!2<# ztDa-`4)C||$Ln>yQ?fl+W{3<kCsA1}-4xn!_R5-F1U<$y4nYLLrpUVRsq?-b7Rwc) zO=IRgUkU3xoT!_VHY3@Q=SKt$xqJ2zdujU_%9RyAs>LBQw^Khrm5THV{K2(l{LtrL z?-qUc<f&4KWL+lOHR17Z=uYM}`^F9sX6`|U9S~8$!LF#MD=IXtx216PLVVVmQ<EmX zAX?Aw_aZUU_*}M`bx3*aT{kAhKCHdA><gW~3mo<*0QRS3BLo+T4aF+P_SL_Hj*<-S z*xEcdjl~rFviO%FKrhse=Xz9w2aD}#k@1ZN9rT{sdAjn%eI+T{6NV-)Ip~Df`aw=B zVXYCJ3PwjYt}s>It^UMH5GW(V4F^|wWBbe;pF;2e=hv<jF0-`$l2*%0PM^oP;v`4M z02um)jCoIcb!P&x-I*6EZ#M_~bzJShtg4p0!(BO+lh5>RT=7(Nq`IsGl8b7Ge}r(Z z4nf-qyO+*;*ETFii^Z45;rH%cmfLy_z|#ykf#XOj?ql9L!AV>wz-UC0iPk-+Y3Z+7 z*Z&Uyf<S%00r37i0Fp10>=>ae3&*2$UYQCfgT5e=^F9HL!}6pM91UToGHm}&@mL5Z z!YOMCcr5Ttqqkr|?-g)bfHdT&kzqm{FT?`ulI7xWs`Av`6rxN`oGzu7b6tR^aavtb zlUa8`tXlr4Ukd-TM|Tu8W?bLT?eTbWt*S{(g$|c9p%+PvQx@3AA5jYyU7s7FanJSD zb27Yo(XwauQJ=L7fvrcECSaDKcB~<&ogy*9lJoj;em>MNP-fKpl6MIj>Y@E8)i;&` z^OApMhzi!2MY^ay8?h2;XMJ6ywZNzeWu(S5AJ~G;-?Md(I764NW2<f#m69tulg1Q= zwjU@9*lh`Z5?~De&}xvhp0vAE8Iz8h1JSbEM&qmpMKc~AQ7la(W)N6vnSp(1<&x#Q zxIqf2nQnEGoKs*w7XT#Q8eOAxGs#KF$XSfo4P9~aBK1zh;;K+`h9<;mmvo&#XV~8D zDQU#-ZB%z|Bo(x87Hjk&uF)fb%BLs8J~=CeGr@kCF$%je8IB4=GM-7Py)f+wzqi{$ zW^A7XUG4;xlTIQ{)cR%l!sfKeh+h>pa>So>fRlFUDxaluC3ch=xai$XrmH~n>AePt z|FzWcRG5>4jR;t)VWVONcsUrC0EHfE1Y&nb=p+WACH~=m2hHUX!Z6)NYSSq%9fY#8 zd4h~VZ;7y{L?*9i{V{o(ATC-4f==!)CC#J*wQ@CTB&*fhjup>GRwzz6fioDXchkQr z@0^G(Jiqkj!o^EVSD%07l?7p)7nWWqU%YblY;<xCsByk?T23-?`Fy8Tao9AiRHAdf zT#25~?e*0P(B)RA22&E%vDxxZ`_K*Uo%vFnG~8XOnC8k_X`I}o>AzGAbrYV<xdQX0 z^jq(3{GYnvwv|0iFZEn4GWL)zKVN;ctN!^?d7kT;0s|W2c01+Ya*(2)x`0Ghk+Hvb zv9AemOVlHhJ_~6Xc1t;_1XufCbHsyvt1DEC3SjJbDTo=;585X0<?i@dso^>74%nBO zZ~|7%g4hcEW5Qd>-{M$6bGa^e%#g`RB7V^W3OdyFsn+5c_lb}5Q?MEgwH=(;+;2YD zrwD@DXGM2b_*v+UJ*1YLcSFai4}b%3T$u1P7o_-*y9e9-0rEZtGmUo!sifcMnYBT0 zk2zx5eW%CHwjF|uSY=r=%Cw@Yh^9eIratp1f?*3RIj%gu+o<x!$&?!EI%u*>b08eb z*YAU~p75B8toz@>VHt;iVVpwu$8mu2RxJtFHd=Ac;{@xd{C^oM=aOeh8G`-t9UOoQ zRP3epgs1iz#A0Q?o-LyO;A6qT;1HcYN^~A6DTRck<0+(n7Le_(GiqF>2%XaT4V|nf z1UI=9^pp(qB@4StQi-<PzQJ<LG})t3>a>c~Lno{r<oatq;!PtQDMj;Dz2)dAsh=Rc zm{C%#N3}J>ruA@Md^F=dL!3n5Zo$28YaKII?nJqoz3E+Zzev~Io}zs$U2sOa{iY3N z4DEk+H8iJ;f#WVk=<$Ggr>Ody3D~cE@GFqP51AP&r?ay82jx8)4O>P!$Y~>2jTN{b zq9C4KS|Vit3MD5N)06E)%{baSs#wNC!*T-IKo?3f#Lx|qAFf6$;dU1ZMl~M<1O6&v zFtlMXk}G7%N+lLa4*nz#zv7^7PBhkgy`5xR)H=Zf2$Y8$Sz{x{2?xC@XeCvZD%N-P zMoJeq(txtzx+=yaRZ8aN5B#oYgU~ePH9>)>vMb}E@hN4Sz1oS0Mq^hXfP!uEE^&AH zUl}K=`#odjfJ%{CY}M~>?5&XQ*QAEE&<W{6IMK+j&>uV$ObaA9DBR_AI8!(veCUIM zU<$zl;Utfvg_2OEeW9mEJ)8i%+^s~PRnp4Y?B;F$l~ZXRbnf+ar#HiH2_aln@thTt z1%cy0F$Wi3dP(Sy7cUb9J4wXuzzA=+0lgyg{HhaTe5+ei7gkr@P2z3g8kHj9Q-3A2 z0ks=>B?dSNkX@dW*cCbf@>voEBf%a+@L!i2zBMC~CxhAWK&H#|D8E0vhpWxcfJ*J} z6msls!Ft%KdjQlB-5xu%yz0@aEr&c0nNw-DJAva%J;+`3tm?46H4MjbRqEZQCyjnq zW;uY5f-UXUeaD?MURQMlG#hj@g!R@FAZeSMeO?#gQ)<F9>F~r9{VwVUfMP-cny~%* zk%0H;Vqxz!SG*9im~X`)_Z?Mc3Y2#*eEg695bQs2?{MxzR=d$>2XQ5&y<xwZ-Zf?R z(&;^^!_T=Y9?iFF&|X-XD2Wt?*DAy0oOaZJEU)t1#{F!=I-T(Ff`;poOTGhAi8PXW zUF@QXXzm6jMtLCUA&0P5%l`<6akm}Iui;QMUJ?gBxPmw&3S_@%9M`YWK5Nz5T2hg{ z2<Cqf)x+Va{JU<WF|rTd{y!c3-&iM9pU6NzfUk`mrX-oX^SH_vK)>YxGF)5<i`lq1 zNo537QAr+vwr|JG9`ERaeDpg)=P4oZ7glMb;TWZXr-H+>$B&ab8xN+!DM|^acs?#n zz(DXwIHLO>7-*l{|AV1plI^Z8I5ocd>nb^)r#e_bw^Y68VyT4INY~yW{eUnjAms}n z-uj$FBq=8Ajx|Wa-ZC1MA&RDk%rtCyeffUa*ec7A-5h|Gt?~o_DTBJ3_feHci(b^n z7$o%(t3$NmSx~{KeWU#axiyB1c-WZ%4`GMJBdl<HnO)j%Da`ZNU!)On$=s1Im0;Za zj&;`3x5jW6URw;%4Ckv!2KU(KtZ0JGxd6XqyfBqn_vZUG!Io&-4=5it0$(8oE$6RC z=8m*~BsUmRb`)_pX2_2Hc<?!GeRtYXZT$$gVPVh#8zkj!7}~HQYG6U%)PqEuSg*2= zZP1Epq*hg#`^U17ZmnBs1agmJdLpm#PdIwXg?wayt46g8>wYy?tv5gV_%4#MyV35! z)4aIy8NE<jV6@8N-vukRKN~%^_-KiHUs)jMKE)t(CsWwpmdNH-cw8v|6=Ow=>NgGG zL%WMImA0hgNVCDIr~JM5LNAZ5GxaQC*Jxn5c~Fiw>yQvw3taen$qNdvJjbW8mAc7B zYBd)!L^Xvs-FmlS&3VaE{vpTK(I#+EsMr92Ssw@$=Egi^@>C+_8?}{Hg-8Hc>P99# zkTEZhy4ivlrQTd2%;HdK{JfjW!IInDa{*pazVKfGk|C6Yv097$g&~1xM~V*%3_BqI zV6Qt~m<$Nt49Yx)5ClPg@U&2$M+<~yfMXbZ3UhuW$icGr3)npGQ<U+35pnO{56zc~ z=1YP3lAILGmxMB7e6BCjQB-B3?*-Nz0h|vkH@{-ugAC-`tkng4#YiMsj`fyWE)^|^ zQ07el;*1AZ_WCa4&QI%=RV)i#^d4c;ml=fUJ(cS#FawaxAX^`almT8N7{crPEh~Ha zp7Di7OupurP!IP<`Jtkvri1M}0CDH9Zvo_W>7^<VX@*V{z3<CyKxA;ZC0F-2z#PEm zA{kjgLPBUjzI}K#tMP8&0!sy(-!Gu=G=IwiZkH%Jp>wFEArLesABEeAXY!#dA;ei- zjc!q`x|Jq1=ctb#Hgfv94?Y1kcxbkd1@9H4tJA?-&Kg&x29{v_cO2^5#>$1|*0Je3 z#!|v6z{ptmehy<F=S#IZ`Wdx~8F0$5aWdNV0lO$#FVX|1uJ}#Yf}TAiOX9sS$FKKc z%sFcE=b86ZuVZ6nyy|Nm@J53Lx~m8hI%9%ArmkW}=LXhOcPZGMbWt@lVip}k)Ov^E zG`v6!96$EjB?5;t)@x%Y)|0r=ppQkS$LSFRsN8qyOy=tWkhuJO`O?KpFP*i<qE>Sa z+L6$VY&{7%a?$JeLS!=i8GK}1o61Hj-fF0y0mI-V+g-JU&a_64J6cXfz@1w8_i_7# zyVGjK{M$@!5iBEaLP}4QxIw8RiM}R%>kvjNEiX76&~3FV4H)_<^0RT;i4X)CSlV*0 zbVM5JnWOg40Zbo8y}@uWAi#1QE)D`Lhl5Di^aq3e!2>)F@rj?l@?+9+PF>H0Ib>Wu zi}C*iw9ksHWiW}7G0&w-8WyRi-|4QQQIjZG6H?HU32SshM>rqBy;F-R%f%ZJ(&Gjv z`Nj@|VJeNjKYLzXNxD0gl}1&iKGkNmvGZ<1^!x9O6U=xVoO5L%zQp{M&jrrlKt86C znL0^Yell=jORTOzV|?xq4gZ8&Gcq!YA*t7XCUBK<0H5}w_#cisPf0cZix<Zfh6D9g zI5LG8CQ$DmlzA@&M`Z3t%m_rb@|&dMe>6BM%mG0rM$UTx{*{0@bIHcPF{VMeN`vq+ zunAQPra|CIyyyU;+A76GCyeQbq$nofc>;e1%o8x{dx((L(6SG15raTGf=|=}NO0OS zn=58{dw<Y%0aL8G(GXF``Rjj3x_ckU;_ZJ5g7^IO-!veLOEz-i?GfkUH%dLhC;&1n z`hJFbf_BRUJIBa-jDj3rrBnk=8ACO9#?5l`Afq_IMyW(+#Lb^FoBv4=ym5O>t(V7u zMIFU1-@C2$NBflk7_&_X@XqEp2l%S=4NU-lFzVoR<ciy-kE1zw)jEHCGe3;q^5*vl zZ0_?y@%@=#*28bA3mAPZA7Fuo_VoB^wxWC}ky(Lk3u$+!k<9ui&gvT%I;h6zSr&#m zKb~}Jg<wpBgAjO)<o7(lf=X>ISgE;_mPY@9zutt~DRm(}U&4lXIk2@^Ka`rP$sjFT zPj)oGS*6F1h^aIf%#1R#R0Rs}^kRmO2DU2~DU{P_U*G9qijwj`Fe@+#%B&?dq*A8F z>un-cF9Z(s9$||GvnZ4RiU|S-2zJ`qj=zZm+-b^x-B^);no%Zct+S`pGz2FT1!tIC zC<+J|5Bq~dA^h9Mg3<7>8761|Fc=66!7%{^gY<5r*>Z3?7zn09($naew;T9D<DGDh zc#qZ0H^5mXF9jM?)!R`Xw9>&o+A!Xxgg`;X!6%_B-={bG%#&8&(9bhZdOGQxUYEG* zv_1xZ+-E7EyiW>N&Lu|reZC8$`K}G0paFGyc7a>@XVY&A5HoR){wuw3`O=H8Tzuhb z<OrMHksfqg(e=p3P}h_RE|{XaCRNj1QJ*y^x{;s~9}!Fg)YFpYMiM=8BM~+`c_be+ zsy9}9NplCBN?if~Y@x*{db70^z53eHRTp9cwg;^h8*E?pceUAdp1#evlqbgZlk~81 z&7f{ohF#MFB<}l&;*MehlU$4h>5GPpK%ff33tXg#6f~z%k*w!d)Y)q0(;p#30Air2 zEhM4<+&65Jx@s|khAs$Q3XCzJy{q2v5j9HKR!GT|^=@&#l)e(U2u-dnt}ez==!y2g zNC4WVTw`^TWHd@iosQG$Qg)yA&Mlmuca3g!Y`;D%>XVi|jUL*%?OMN2-|`(}TutPj zVBIY3>pzYB3T-JV<XdA$76*E7gFCF0FbMa5>%NN)lg_{vtu8YRESBhwyLTIoPJ$PE zCgFy9p~qW^4HaR5JN;o8?<!*hu6tsWF|a7e@&U-wZk%*FnZRbHv6ZfA?1o}5qM%ZK z&z()K$kO{bU^)zqY2p-&j!q)vVsRoY^bZ6DM#6y}o{Wb#9;Q})$mGnRzTPkvj#b47 zEPufns}ED*LHFY)?c)$wtn1{pHZatvmMXB+=8~m9La>c@)K-3wJa7o$eTS)wK!g=R z<iJ46+G2oCc{ypcSGF3xdq;p?igYH-vQ`(iO;(LepUdNd$fas=T{=03bQkl&CC<q} zHd?j$RL*D?JfEijy9`>X^r@s)b!ka@O{s5H)7&y$Sm?=Ub2<;tWUo7;BL|9UJjFU) zyJWuuB(#Oitl8Xc9v0eYE~QiVGhI5R@k2BiF08>$`HVTIq8hVp)HmvlD)%YEtF%@S zfhUCvcNMXLWy{q8CgP-{8C@E(XH{4t6derAZKrHho?WI=_G7ar=V%v|&dx{C372Xo z8z5W9pQMI!=T6Sq;;uRlm9)3k{r9Qp*$=45-UIAftFH>QE2ZEfOC>@mW_@wA?*~N% zav_m(QJ4|Q7~$^g8(e%Peo6+E;3|sdlEu}<=*Esky*4<Eo9$EHDkv8h#}}6FX3=j5 zbN!=g9NSPot{FFWG`b9;ISS$_|L2}ZWeA4z#wpJb<4e7U);z)c%N}|i1Gx%zH!~x$ zZ0x4G@z6nBhKcY>P3pOe$j9pIzrELx>^G%`uLUGSV_`{jASjdugcU9HjoH)-{i>G& zknr~C5N7Pkvj7s2ROTJ}ya|X>;G+J>v)KGrlqkdN9lHI>S#kD+s-m2;At~mC{<ye; zkW;c3(<ti^W0`c*9_y3S86^NDX=7ChaW$KB@0<n9NHD3ZElY-SZDvam+h5jQ6GV^; zoHeJmhx7J>GIY*mv{YKMDIs%>>kWOhq9jA)nlT&M>EM$MfHedpS}duhbFX)rt|f%( z(8bf|5ghGK_64?_6?~wTd%8k~<OA;(e00c(U}%U~%o+4@Jv^AVzK<EejT$|FOU-dr z$+yc!K`<BWqvmNCXm9nILsNI?NDbj9HI;&}rpaBObg>WdqEQaqmmADDaEdB=pAKcQ zbm+hx)8L`&j258+I2P~A%p0I-*x3(@b8i<BEH}@XVt16Xh!gOaDpE~}oC-zi8T-vl zE)YWKe40nN4-i-;3+ZCVe9<SZ)Rav3Ja=g<8BD(XXux503bThGx?-T5P5slP0HCZZ z7&`xxn(!&&*O&4(UCDMG+mVFvNy}xE%A$v};#Ox}Z{y0TRB+S*ELilbz6&WotkMey z8dl!*R2*d(sA-8#*B9i&na59VQFA^2o_oN)?&)$yJHCYF9C0~M29qJ=vHOMnhU~S( z@TU(68@^wz3HXLgE)43wHZD!cYR>RR)$DO!Pe@d(9}~**c=rdnke%;|UA=klT8h?+ z6ns&ku}ZDQ_H&RZoxlDhy>Az(3Lb!`?<@(peitB7EpLaco|uBFZ!pW7Ewg+Zu}qJ- zgdxK;8qi!O{mxIs+8sLYd}j%?k9v5z0pIm*`D%i~NY<E1;gn<!5VSAns=vCbce@+y z1$D%zcj&Tzsbv#<L9(M}g2)t*Ta4{aOHjhbbMxwE!YIst=RN?j<<?WVYpjY@(QLN( z$U?v?z5IC`uJmBtU2Du{z)ib8yry&BRY4NGc<J7<*UnDmlC<M1g`93+C^#Z3ZzO<P zRprI|3{3eZ<;lKaP#6r#hx<&<T<;fxyldE?@!qT3cb%^-L9ncw%`CnVvLdN}x_UoB z`gtjDB%WnOGPx*aw|#VyK}t`j9h}u7bzMEofAlba%l32IYEtF699gY+eae3^bpD^4 z4+QR>cX+k$lzixmAlHh4d@J@jr>{V3a)@Bqw7<*Oqk-G3gItkLSUb*vs_vrxs*wzK zxZZbGX>{=#rEyp;xZ9K!l-XDyMHq+JuN};qBv@?PX^*Gbh|Rwd1iPeUSPR~`>!jsu zc1PG%;Q^EkY6{|fyEHR31O%S4LLR`~@p)nE`+OYRFF;0dzxp$`DlTKX;boU7Mz!0m zt}2}7xI?qpxZE?Okbk)cDcB5e5NDM)jpg7~V*F41_Fi`QC9U2}?rW(=3$!f$8f5{@ z4F^MvPST*3i=yQmcA-oFy;s@qo*U->Pg28A6}%DHc+eNZPyPYAg-!;?WCtIlgV?@; z-Z>JM!jW*iaEPJI#)3$3juZBBhci68Guc<P0i1E$r*USc#n)&hmrbdl^U#gE6>Z<x zTFrTXeGE|W_xE}P`lZ%?P_Wtt6HaP>oU0~Px?eUXXZ#Vu)I-faRth<T57Ubw-=m+H zHKurvd$;{b6KtP@TK)X>$LNEgsF!<9RbVp$SUx3y<db)3n+#h5n{DfI&W(<4l08wb zXsiJGTCE6TZv}lj=MXUrSn!_7%%p?n;|f=dwJo5nfnFCK@Q~)_Ua*}ZEo`CPdjuE5 ztpUEvd|g?f3#SJLGIM(1GhWTFkJFa&5me+-N6#(Q@2xtiVh?-Q0M`XIqu%-%I&r$a z?9I~9gy1W`QSecmjth|$k<hAdfTsPOF=xg}T>YGH@U({p!cmbnUAkI%_44@(Wd!=q z`G?Z-6U<1t8QA?z<&Q4$-aeK$_D1J>RI2$$=+qQD)o=R41A{930|tLEbNTc--ETII ziuC&2;N8_+Y7)xx4q1$=k*-y73raH!4O4JY;2+Kvw9L`HWtkPMCj&|`N8AznWU)9o z`s6Y+jg@g=gh`>*K#x`$zzP}1f}>6x2isF$I*-rzSy=K@@!Vch_^9yzz<f+t7+eUa z!eflbhR7u~mmb1XP?64t;%n~^r&_bS8k5|)QvYTF!TB;b&`fC1%EwbKmEKf+ic?8g zL4(g0oX>(?&DG)}H8)$`5;93=5t^w^V%B1tW!lHU2Ih}ufsSXbDhMRQB2tiiV9e{U zVt{dKG(IH0bmZbo=i-dRNxLeaceQj%rI($SJZ)`2#Hv-=xYLxI)LI>M$I1RI_aId~ zLaiCZK!4((<fo(hVzPKTA1zy2(mMn4NgF9P&4r51e-6>$KSac7E#^KT>~`b_2C~hI zU6qJZ3{3&5%0_c9BVAh}R30a@vjqXJT^d{~&<uX4t}n`TeT(z?ZpgewTkSulCoX7i z&%(R0BaP7T?kX71LUvb~IiBkE`VCogu!8tg1Oz`(lTm4HEaV%u;Np;_dl4?2ITTdJ zTlB;x3DExn2iP8emGZEB4+xN=Bb|;GG#t1in+U2N^2{FDydWPu(&CNKr8afmSg~`6 zS5Gade|)4#=Lyuh;zeRE1S*Af<foLcQEy%~34jISfVW7b`Ap`9u=&G2suJRm31fLf zD<6XZF2~Z1oA$@lMm6vr0)g`<P%di1GoD3jt{-HsksA2O^I+t-Dg@<f4N3duSFsWh zV?qsYPBGYjy_-OSYqL0Isg-hxO)k+?-Igq`1a?iN@Eh?_vl&VQC%GC=sxe~c2IV0F zE2B!~Myu7Gn?Fl?+Pv+4wkQ@>ZS;ZI)%A4L*0pRk|Ml)7&G%kF5(XvnmHoOw#{lLL zxgVosT^d!VQ?Y6K{;u(SS0_z!fjb(3WvDc1wxAZJAStSQ-6L|^)_V_WMfivhld)Q= zr)A=5Jyq*GCKXe-zxUkNe<wA31RIDsr3(lWdMG#)^a~d<DY)MT+9`}M+;oYi>!ZO` zr~}bT>)RYK27`DAfke(U>Nn1)Nd2Mqj!yxTt_k2f!vvzvf`jJxB+B*08`7$2fAxw~ z(^H&FL!T|F-)zk#T=KEf<}$es7kNF%Vu7?iucDZOHKX<p+_KA`(d}FJ&X~rfJ1&^* z&v5q+skz@LXp&c?!65C4p++{~wsJm3!}bCACItDr&Y$v5lzOg@n8ql?mBDtZS-989 zi@6%_hPn8oL#B0+@<#90a>s+IK1yN^YG9tR%p*GsTiDx@zs%oqE@0@}SbTroSesc5 zDNh*&EJiDWUeof|f!bsoDp<Y3e$Az9j9rR!ny0}yp}wl`yx_J2z0|OsY{-nt(hDzN zc=f_k&LQO|97%ls!i&$p_R3XTq&(+5Jmix?6L!dhX{c{|13|9Kh`_A-x8VqE-A!1c zD3+E#7r4zO7<EI#MB@pCtv9O;*0HDCN=DecUGy<-Cc+YZLXHF@W;mE(94jz7*iK`z zwGIXvk|tFPXb_R-E~UGJlSTSOOQJi7J=Iz-!;paf<&IW%lyVi2+dA0jTa@<XjRfe_ zN4pc^f5H9EgsbI4r_94;N{eT$+-k3Os&P_2ZfsBrGC7gG4KX!rvV?TFvUBAk=?ANh zcWzDdT30UmBdF+e6gAO9YIkp>MdvS;^{p%%iN17V_e;*VKK~Myp$!?oV4pMYM2dBN zz6G28U9V>!%SFO1W3+5AJi%X8YaEd`PRsEv$ivH8m;@F%VHdVKjdNwlEXhVOIpS;O zS3vq%V)Tmb@kJER+K|QVK1W1AzcwMD>zXDJm4H^I{R9o-R&s`UTFr!UY3K8{TID&{ zm@M<2cIj#1nOvxG*b-<h(20GBCD)~YkE+JqR$K6-@;Sz|Axd!}e$OPT20x>rw}fPn zNqst6NA^aw>q7<|TP3qL*hI$X%D`)BgEN@IfQp9ps=c#?xVO$m3zr|`fXyoQlIvMv z=`KIM>n83pgW=^zX^vS>$(ViCa(Jlc(d*eZ(R9nQnLlbYB0Upg!my5vDR&u4d{Bba zY?Ig($PjO3XorZh<DO-k-|(klEWH6{x)Z@fB3p$%kN3IqX<TBs-RJY>khf@doy&{@ zD-x}Su7lPffe`|!uW|;B8JnCl*UStU;69m+P_wmwn8#(zx9W0xx|9$4m>-Nr>(&BO zhMy}xYAm2_v$sud0&t{wt`?|d3}rBCYuP?v$fJd{S#1k-A`4g`>0^FZp?(eYMxvEk zIA|64k`DoI15+@N7>1-mU&=~_D70eD&gGJsv@3C|Cg;|_ng9j>7&Kt_Fi|CONrm~K zq|p@@_CHn3hknCy%%|E0JQFfmNZzKu#~6jls`{(Q%`yW+q&Qr~fi{BQfCEIznxF+H zs?1u)JS@yLq7gIUBd$TW5hI&{3^n^M;@mQhBc0DRTnJ*AF;o*n?J&xQy1`S~Sfp$b z2YSWB8jyxGw3SfJBvgCU2B_HesFQS&$s?g!{tPa^0f%qI0a!Le+j|)nn@|JHt2(3f z7Yf1s{+a9-nw}>^1=s>1V0M2vbZn?JR317wv~Or|XrBK{ayB?LHasu?P7e*qvw`91 zu?cxHFf=R2Geaka=7*0CjSNi<9T<9OsBdUuXc}*7dxncR4i#$XGAIEb$^U;-s}e7= z)M(nu$<|fb-tS^y7;B)us;Nl_=;_EiHoG<C@Fn}e@r>I~1*BLX4K#Lb>qJ1i_I+^J zhJx~h)17z80K;9~xzOCT>c6ko1e~Lc^Ajq4OTBr|D}&&DQS~?&+-MpV6z?gr54En^ z(2)=OINaeq1^aUaZG(sT^{*AOoTbqESAA|!&2{BM2)Niu`EC{9ARmwC+K7*6=&;Q% z2f^mI$nV?b7aRPRx1WOBI>Y`J8Nk>jYrRbYf^)tx*4dHOd~bl?a(4o;YSn*HojI50 zK($=TL@y+8Tj}G;#<r>p>uIf}{v5(gk@D;1zaDcQ9>TJf-wLR7cBB;x66LY3xZ1fT zI|RsDNtDHvjsQB~0}|6OUw-uhft-A)Q?(%}wIrqB6pE{JUDnDpYb77$N<uAA{(fWi zF1tiY>S*_UIMB|Eyarm0XlNCskyU*YdDehVGVET`c9C}lt*C_{8E|iisIl}0?I-|E zs=J$KY1Uf8LSQ%%3ZP<fUCqA%FTp*9M;Mno;3Z%+X~IW>Vdi@R{{V~W6M^Ox9TkWW zh5f;?aJ)DYAU=k`3Bn>IzDH@{K+J(~Ol4$)7IFZDq!3}OF<;(x1q<-}_2ocgsaiwD z(580678#IbIbv*nc~v+*vn#BBJ1f%-GB=t#E)LpCXkHJte;23cum3YAx$1N7#&~<% zg)fT-{8#m!%%A<73%;QyJYb6l;kBxJ$2za~Ie(k&I~sI*i?R9?0BHEK3a##NYuH8A zWC<IF{2AZTfqX{?d{h6aHg&+*z7E(BHLnMoZv}Xa-?FrRS;l0Ud4#!GkhK2IdLjg^ zx0}tAUnF5R>Z@yAC+xq!zgx~xt-E&r<ihtcLtwx#nsQsO*FWKlG|E$p-QI9h<=?@9 z3e@j#Tdw@J^Ih9PKW)5h%D)C3Pu`)MGe<-l)ocr4rK-y$X{!Aaea~pq>)p;+m$j#B z?rBb~@+E284;H=uS$}AEPcRT78qI+0p?$nJ9u5Q};XvUCBG(jnN6tnVvnH3Ca@1kx zKWpPT7?=DzFz+_3IQn*w?KG@;YnC*ifd!fGm+G~dLz;PV=8*L@>!V4hFRN>i_o)q4 zQ_%H38X4<3)7#kd0qzn8u!&t}4BZ#jp>)8yw`wRCY>4}P>h_?SR^=<RX~1ii2=)p5 z88J_wYbCSu2?mte$8FhfzosD}WbX-3Rg^1e714G^>Fke6mz&e3c$<N4U_&}ce^$2P z4b(?04C{h6@TcC`ujU56ttHs&aZhVd{ooDUr#E*B(>E8hL8Vw*9jm{ocB@MG?~dhw zSTU-4E6alFG{Jejz;~}eKHOO>S8wI7X)%AP)lBpq*#FcSGL_L&xbP_off!Ds5I$3v z|K5H5V-xkSlLK+Q;wu=2XULMVYPch4rmCpazoz!7luiRbTi%dcvT{KXU{X7e$Z(H4 z<R)8g-TDi4wyXo|5(VHFFO#{*_lX5H)KvLaVCCk!`fW{@s_{x&GkgOJ*Va00u_hHq zV-RdVg=$hbA{rpkS>Rv!9Z#Iyi~$`nYJ%m-7RKct#fbbE4nOWaR;#NlUt3vi*sSI^ zHsq{)dauQNSUrCafC4PA=^GPd3z1%5co@fEfA~=F5U&pe56H7m1p5Uk&&rcQ)v1?E zj&%RWawncP@gWn>nD{WVt=@5w&opF)0Ec(0!S*!@vO|?fzY<veQo*6oqE$2jANIMx z>6!!fYv`<vfSE$A;>IWS#y&Fx`-frbwdR!YAHcqiHD3tdiBQid5F4~nS2lmz$9l5g z7y{qGEm)*E#h7kEpvcF3Fw%azSM#^~@TnP<vByV<?l%QtHz^Sh2``*S{`u=mE;<R3 zHPmX8F6ph_9|e^S+<a0yGR7ED`VDyw+k}`V3M8;+1N@eyDQM2}a(pmLyb-*?XjKC$ zqd!L3zk`LaAKq`H!mJ=n)mMVg4Y(jG6W&~M(w!|aHWTd+UrJy_o-90z$S*|u0(zRM z3VBu6T8&nPfo~GZsPKhRq+Tmuc;(`!&Zt@qnD@#n&tJuz_6|c)Ra8Cu(Z{v8eb^ha z1OOp3gR+S-HEagG*+~rKV^%4Ffn5iq`UM)*8+U7$K^15Q+BrAV_WCLbje)G;dakXa z0pwfd?+q+Za56n}5(zuA&*wX<w?C}MxnlXg@4EfrqoCz-4KDv|;JA?=a@vS%_4bQ( z8;}KKL2G`RMv^bN>#3lQqk;&5wh#}!{Cxma0F~tpJe?0r-rS6Y(NB6%jCh<XLxjvc zVT?~3G9dBcH<dYo3P5#@B$A$Vpb+U$viQmv@|`^efZ##@b<ygLO%Z0ALm|N62=ma6 z3HX~54rNIGf>#*`rh|j@+aC`;9_|Z18k9^axYxW08CBp!l7oFq%fj6kyP945FbROJ z3!iyE-x0O)gh1~S^~SH2UpbvApH)CA8!exD2CUrK=wwHY7?`u=CI<KGjMe6<5yM`m zZ7lzi)G*U$g|iSN?H6XQ5Ky>-|Iiii3Mur}iL5|IZoU?pq+qTQ+RHF}Au!j-Kz%_T z(U1)%bX~>CAc!=a41w^&Ny(Hg9|HOB^SN}^6prVEz7j}T_c0$-!Do>D7GrFH^a|Hl z*ClttodPbiK-U__ijW*ny{gqXTZ-GXaE<vtvWjd!YPv4$;a!EoHnf=mr0+6LYIoel z0o$xw?IvdGk`h1Mo0*>>GT!aZW`<n`Jq)}Vum~$qI?z?ZigktP>sBf%jo=;zP^9g( zW)4J<k-TSas;d3Wv-&On=|g+He2{SL;Xcd3nPA9F2)|!42buQQ+r#+1g?y{4CY!E1 z!EWouJ7F#sqt1`u>pzsq_<ge1yrm4x`Ro7K*|(Hj1i2BKrAW1#pElO0#TvqRR|fAi z1B!q_Xois-&|jglf~OL+8kuU_D(7$DIsc-snW5;k)P()UFq4WEoq+EF@6({DxyyKD zl_}TSxX%g|o{<|qYqin9A0TH&a_>+e`j|5>df1f(cV@fgBzpdPo0o$ir+`<(moD)j z;q!?s?ieL}y3#0mr}P^k9CokazQC<8a^8c^w50s~9<^-v^-sS1Z{h*-ViHTV+BP9x zr@NE0N1?K)daI&xg7OdGrT_A)vWEYb)VhE*{J5@RA(JP9gTW*@YRI|Za3(mUPzW9l zj|WIcIS@>Q;I#|pn6C032LQM#>A1I@)mO|Yd0n6C$eC>2b+PYSU6b>pp$`w!s}(i% zYhVL&E0n5h%(^L!gtsrd6=aqdYNDYwWFRU>yf;qhV=q1HLg_(j?W;ZIThgCv$$h^x zp10wmbp&v|rif7Uy*LNkZwRku^_J_G)Cq-j+)~v#&!q78us;4mTRlzLRHf1uY9l%q z$#KpJtL955(^9@<Gr4unJ^XC;+S%(*Ba%n-0gu|}tbGS6K7FbJH!@in!a1Hg{pkGD z*=y~y?d#{{8?H&doV2U`5wuJm&X>yAMx^h~Gd>E`cN^{Qj(67lJAvB;L<;L3oM+Zt z+)LU1x{u$C(rPpUV}37hp{=o>z*FzJt=2ozv`_b0O}z<WtAzmdlL()|F!r(?%&44A zBKXlg8OX00=bND(84%@s)Hz$IITUV1KJ#P21%%W*5Ljk?P6Df_!6hIJEWzcxq@uUc z#kaG7mpNKuquRctS?PY+gSW4EIQ19&4AD^$81}1}JB{_P^jYS>gbxeE842zkI;0NV z{#ftm_2-8w%nucTN2O>s3np0Z_Srb}_ly-iE!0ra4wsF{alZlU?;WtU;GVJiY7P@V z*YFf-STK_^P@{nlR_X_eSu5O-X!--C_TC~8yu(l|&b`8@yZWk%DvWibgjiyL;{@S) zm%t95y*qqWGshLpJADShU44F2yfvqx=muGrYAiGHKO_VDtfXQo*cFJuw@%-;Zi<_4 z%KR~opl2w^Cu{JX3_PrR+<MpHR?45Mjc%H>%irl1w+f}UI`IDec?X1YG1!^NgCW@% z$DN|>YTEVGDMVP{>{#QT&M#nK+Gp)AjF68|UPl4ud7PG?qr$RHg!)ZN=H5d)-pAq3 zc>07(5!5KrIl+~>Cvvr}_cVI1S`O;_xFdf1gZ{8T93B{YVCd*j|Ih$=73^$J{KC(v z$BU@IEiCwcS_Nv1bX>FoHLswJ`>ZYrVQFo6WUA5WYS!n{u8mUIEN2M#zS;6&g%E%- z9%OFX5fzxZ6!p+>_cQ7T!YgaM^paI-gUDuBVuW2RXq2OVCZoq%9&&WD3hfT565BnH z)*WLb{;e$I|BugHn)-cN`1suoxIK`MVoa-Pc!Hcb9zn%&I$Bll74K3qS6_*$&7FA# zT)FgMIb%}h3#oU~E|ousltZFJ<1j!tqeATKfrT!rb!Orn2+U3#M>r&x<qE-(?8oQR zl3IACwR&9@N3=-O*bbQZXknW>wF?u+`vj0+dKza3`1b=x?;^&o>XuMFZH9QZ+G)vR zq<u}dvbojjCd?j>03+O?Tg^J6-B?LAPL=4UqU!)hVY~8<ren)`q?qvk!Qn5tnyiXJ z+tlaAuly@c0_ALd(8;xUZ$mHsTdCpmebx%fgc@}h1o**Vz(A?2hODz8?i?+sMY#9B z^)dn3Qw%|^sB+M>KBAyJbP)cC&yGXcfc0<CeX(Q-3~Q*}qx{OB;#ah&6;j=4Ieb1e znd@iyM@(K*LOG)b_t0UV_P~i!GebZfSf+oea&ftQ@#+ONGWa25i9CYkm91t?GYofD zZN$vlUQPp7Vs*=TlYVz5970~)eZmcq;{i(Y91lcYJ)kY1DN9Cq=!H7`k`gIcKi(7` z=NFpR<HN<AvKfG)nsq~JHM?pVj7Dno9g3>o2C{lPx8or$MOgnVLurL|TvE;wS!c`t zs~hEtO?09mRG?2mbrtt@eN#yrqDKt&yYZe5c6mk`^8<Z$ePGRx+$ZJe8@i&c4a7du z&2oLNc}}edR6!$T;(}@mPMW*{1<ZS7)eq}yp*hEJ6Pq9Dkya59uDXSmkpmn93J2PI z+Hcs3{YWM_8VUA=8dep`Yf{9|sPD_Oo+9?qixB#5XUZzGZDK2syUoL<s4~EnFsG|! zD&;qjOF0g0K4lGdm})dM{Z8akb67iQ1<ude;Iv6iSCBfy*ofI6MwWJ(-RidL62Z$} z-DxKpC6{CgC2^tKx{ROxmf2e}#3jE}<n_}zN?G9Nlu#vJK;a=IJbZWNO}2Cbo7Xk= zb^w7@^4U=(?c6h}FarzTPyqRkA6Ha=K9S9{Ay^FFSq!x0O>%QNBM}87T1?lXIp<B9 zVf%Si1mSSvxb9pszf@k3`TZ^&zT%fF(HDxZv@Pabt?w;R?9)L`*M1HIJZcAcSWwVt zFm+#9XQZ-DRioY^^0`AdW$ed((=HJT>V-9D+^-yQV8ain&EtE9Mp55jRjk(UW>lm8 zYOLSQPph?(21hyJYhmmzp$ey_m>fv0rd;^~5n;aMR93>q#I6TUSPFq8UO8}|R~)4| zd!J|b^hbz3Z*Zb{57SS|;cK=SdeBE&!!n4R5pq<m!A{+JWxI?y@P)&z4x(NuO-D)& zGciPvHLHp~4Zh`<)LXNvnB&UfF7>gjb*=rDHxHs|KQ|cs2uOHwnKf^){=G#7za~}w zLZ4IU7ieu8&ImZ%PkSFYzm3RsNywl5!WPNh-~i9}-$&qr@yG|m$c460NqHa5<Cc2R zw7;oRN-G9G;v>B=L$gfoOr6mJW#N)sQgJdhL=L6`(w$b9fLm)V=)0=B0BbZSPh0JF zE4ASp*OEr#%#CXIOwz3_(on@m&#(c|Z&`?-2BRE$GO)kmAZ__~y-xEV;_#Dhh82mE z(%ozDTmCmv!@uxAp%B@W_v7J_(8hQV)Y8#7RU`ccDXPoxFI&Xodz~MMD_Lo|KSDE6 zt0yr$N}%}A2d&WsVWa8g>A2<Q9I*jHP?eay6}FmIq!ByiTac+j@sUf+P(pdIjoeLN za~t=jMG}DRi&m<FS7W4`(w&$|MgNV{IuH^kz_1ym!k8g+1=-V?#bgEjp8TDpc62fm z(fRP2FB{VnP7%B2F(-_}#Y5bDj762RH4Qe;I~;Iu$!dFS<O-4t?^JJAQ@BO=<Swr@ zT}<$5Ty1x;X>Q1<DzpSa{AunnjUk=IN_QDy)9BLWt2rdhUB>^?BypboH?~&OMdcM2 zTb<Q2^)%f|9((Mu$9tn+b~b1-vPjRiGh1l~PPAu|=1oi<C5Gf(BEKVl-;24Men&D) z=0DkMi4u&N2D5pK3IpN(zG3AQvDWA?icit5!U<Ka^(~dg`M^!cTXj2#4+{?N26y_* z_PUGLPkEjK#q-y%G9^;Kjo56%sUo9Z&RZ5jMIg!p0qu?oMAwV5298h)sA)XZCt{yf z_z1d0)Jsi^JZze>tm31&(llF)$INOW_YO1W`FFCs9>cJrj3>=;ix9H56(}c?0(VAC zbAZ&u9g1{r51DD?=MefKp3($*O!{&D`hMj5(A*%m$ISG^=2OAvM$Jmmyw1eP2h22V zDi1QfRS4s<m4bbANFMP$*iJ~Te6abFIvN-GEwx~N$t;sinUQUQ6qxA+<E)l#rW#H7 zKA%wvvN#%vvt!DOvQMRvJn!tZTXlFf(Q5%q7amW7pqwy<ME&Yk-Cd`MXm}#J@ch!7 z3)YQz;lib><u@19oad~IgWEZMa*kpeo-r0~r&Os}8;`V7iO%_=In7mx;;WuG&X)a+ zU<XiPn=5Q|sRZ2<LV(U;<L-Vu=Nl4bEs0!H=I7>1^QH3fz<OC&Csbn90qrv7ULMr~ zo6S8}pU=s}@Sa}Y;&rK~9#&Ip)O+$)-;=|H;3BIxt0?;pDK+x+<v((mlGza%)q(z* zBlgy!?Em^ok~%x``%Gy0{|%fG)`#?43w&^gG>aCZiI#s02Z*XDUW7}!PQpgDO}BAP zk>r7&D%lft0NJ{c6WvpRw-s13j!L7t)f8U4Q*nLLu$n*T;pA^n>}@P<x|USqq*MM? zCqd$OlC}~#OHRb$DlLE9$rzi-t%`m3H}S5w(ArZFjAV<`0KxE&G~on%LXb|$42Olm zQZOBkFns1r2oCB%_=r%o{lQb=WH1;!P)z?o8diGdx$TXH^VmK&``F^6vk_&Rg3->+ zzIOG+g{NjA4{FBMMyr{eo83v$+2@`uJyT87WaCC-CzAJ@>ABghPV+3C@2ly;M!nW) zrLC3jg0%c>HQiXe`PgjaM*Q{s$DS=kzN(9{%yGTD)6*RMn=QFiYpu@no!XiJrCN8Z zBdvMksVC$iHs86~li0S2Ty}Tba!KRC*)z|U<O|0a79y>EWoLIxbivBCtqwk$vlL4g zqlE>ut=rj3yB8q|`;+zaqwJBZ66dH@dY!~qI`x}Ec&#RB&+Q8&6r>@qAP#oK^hD=o ztLeq&&DMI-nT@vU&)3lRbF(YeMw*~Y(KBa0pxQI}PoMFvmkB%LhWS~qH1VO=z8H}9 zgyjni&B#eNj}VQ5-5t~?p?eZ&O09y~nY4~Nw;ftv7TgK(kYH|*uCq24G`#g(K`Ret zObw-BxBrIv3H>b9gh6JQq;Uxa-|rmceFpfw8`zu;%gv+tZ;hzW038}wt)k@HnHk40 z(Ws9Vx%qh|y#v~9^s66&-2CA7vsh32QO6r{Shf|7y4;5v5!+W3sW>Oh3f(&lGSoKh z#P<VSU?NjyHF0TDdV->Ll4Mcc6Rv_6ggOGWXSceZG&4Q3Wd|Q${8&D!{Hb&es*+Pk zAi>NNtOw;EU;L;qh+t}P)b1n#Z+7S#9(CZYq>N(^x3z5kqjFnRk~GPnwEL~Z!36iV z2<1NiAE{Ag<fTuu){u9;q&O{ea-<K{zYQGn`XP^~yd81F$8$`(a4=6)W5EEAm5WQ~ zFP1fk^O{p0bv6)!V$jt@jH#-!3P&hq%gSF9Sm`>l#1NU`m6feVgI31DUNZ=2B-~y! z?O#9qs7B-m3u1&GQjf(0a&=G`zJ1L4t*qZHS-|}|ojn>52tQ)l#;zNBH{TQHYsL#& zeGKJiGE+wzQcKNIGtOBJ^4NFA*j(u~zWZr6Ru$%Ot5j5#!5A~0)tf5Vf=)!)tra&f zc=+g^3!xD<O9<|2`^%pB3Wv>1Fd|%+*BJq_)6Ms%Os~%9{m`dJ43Qr3{eHcc5iOec zDMNg}&wQy5T!XMIUt~mDjYYe{^ys+5e6H`2v-ncK`O*L%4dRiE>znTnn)iIPr2U@% z88XM-SCQv?159UJG+!D-)OlfMg!%fSg3T;zYfj%pm`K+rZd|0hP9bpGLJA)82BaqE z)9ABSb9z0G%qy)<WvkPO78eP)TAiL(78cf$M!V#P4nO*gffvfGNSp}&J#M1A%;KRC zrD%Fq%g?yAfiOwBBL153(TT`O`A)sI^!!T~_HuEoCd~>*<-7YWJVtT~-?x6(H^j4e zkAliNd-d)#I;M9jYLIU<{Jkca*4uC7;HX!()S!|-7`oMe%0Zx3Bd+-7=rfcmf72fB z2Yd&%?3JXh-}$~wAOX+l;b31#<AA)a`?9>y+Ug>$(+gT}+GB`MCM7bxhWObQU@Ycq z1=!ZJQ{ZvE@&}W8%)S3!kvY3HdAH#@4|>))4UYV`i*9moc#pDI*+(+??}g^iL5xpG z!nMQTBk5WTOh&`142y1SX#9TEy?!f;$G8WhO?_dbx^W|}KKo<+R>-Lz_r{T$pyH@s z4s6g&c>f}MfMkwHH9wl+Tpa~(x<q3RyxOwskma?>yPCH*V^lsYb^Wm0dr&S=E#l{R zuxA6R8$@8E>aG?r-_ww58LQu!q4g2rt}FuS)}J*6H39Bs@v&f}lG<D+3~i$4Hwkt$ zL@_`EI#g>26QDgO^)cp0Lsw5|Cx+d~p6<c8JRo)bRKGLB4Eh=1Kxr0YTYQ?5qMR=} zKE)Z@6;7ED=keZ7gzik&9{V)Z19P-@zDW5%n4f?4cn|ssGT=W&KQ-<(Z0m;m`opo} z#Ne^Mkzju~$IMuN#u0!@$*TRcA`x0o{7anuA`XzAmjB4vt(5;9?ioL9ga#A6!<I_B zZnU;F<PLkztw+`PWY0jRJE=NDGeAanyyu}K9q}#|K=j|A?)?^mkRc8cBV049_MzSa zHikikanUqX5v>b{@6&KQrny`?jKPtY+9`^K4WnwKY09>f=FF{ZBqn4lsgx<(p-DLQ z0logqS$1!DWvLM|8lp-{h@8s5%~gQ|3@B9JMZx;7QAxrn@amGwI6xRqaZEYDVj_LM zKXioul*yCUdkT&<0M)aE25%AMG`Q#xad4bb2oLhS6dWiF2g8M-(!oD6`fu4rDmp$i zc(6KlcxYg#f2cG(B>&A1jlis7G#m}(?%3ET`e(*Y4E6v2P)h>@6aWAK2mk_6R6E4) z$Qru^005Z`001HY0047kbailaZ*OdKFJo_QZDDR?FKKRbbYX04Uu<b&E^v8ctybG^ z+eQ$br6|#I>_kap<kGrPFG19zmJt*PQZxv9aoUFhMnFHfbzu-RxsunSxioj>NQKk_ zb<j9KpW5Fj&~NFl^as+JAt}pw3u?n$E%!2)GiPS_&%euyul~CFB!cp<j?WkPm<Kq- z_%C1pkO<guK+wAbgBtAAAg+OQpeG=9;W@wwzz;iuwzoPYL%qVkj=-6{M6ao_VUh%i z+S~L=&pCx(k-~3rkN_kENE>QKxunVAiAySJQYV%4UrZYC+=ZP6#2)W@;BR#nNZ@BU zZ0Pi!ZHIB(j`U%s5*fF9N!T}StJ^(%O~XTJ+Pc?Hb-MO+Z1;7_>n3vWwp%`5lel9X z`T$c0MhYeZHg-dp)?iWt#W0-+$UG27%a95X6ZBbtUcs3I%AsTE#|=Crs%^&bz<uqI zTO2|$^lVQmKsQYd$8I*Z1Zt!RJD%zenP|ynna1XsvisJfBZb4Zf%7oSaF5UE%&J56 zlPqr0U}Vy>OE}5K!3-0785j1(Rz^COylhx%d8R|^c`%RY;7}#;`d+Mz?ItQ6j@HzJ zhY!|ezrSvz9cEVR#H^!5hhZA8&yj)rc?$&u=Txx;q|IC>6`~<LXo!~Z#G+Wi-&;;Z zo;&5k;dzJyp~_S&;m6rjP^^$q2TjmdE8r&_E{+6lZ81+b3q<ObJM3<0D&w@NQ^`1y ztw9NIhYaw&Dgt_F8LNxLhvJ?OQ-aAXFdmCyNh}u_c;&+w{EfqY;WHzF5FlNVLi&%w zbEhOKLZE*EF`Cfk#%@*-*(H+V{?vuh_b@?jJ_Ui0s0JvHg)Y$Q?|7mPqkEKd8@qR4 z+MqN<P|uFmVbXvT2Ob?AA&Fg3O^(aacObTpK80;g0s%#;Zu-j=o4ba}MG&Y|*&smo z&C>bz==BAy=w63Vdh@%TMN&+w6q{V_4Xx6ty@m@+!YqtrfWsi{V*;#D36K^!nuZDH zP#lyYv+t31mG%=E9LwCGj6ja8%<)_@4)6%xkC|I0OO&<58f}<XS%?WslLM{NbHy@N zIR`(}S;w2vj0QQ1l3^@)H#J#tYS3o|S(sbHS&u6ug5c?0Bq1-CFt8QmtGP{b-zjr- z$+=yle7z!S;E9`@yQ|`c;5c#JipYm%$y^THpOn2w$}7kUWZeS()M1J0sRj5|%q8?o z0jF4Luj7uxsSHFsr141&wnWS=Xy8Iphbi8s_Zkcuka+MCI~W%5mjEvuc!8sU9v9r- zFlCU}UMXm@K(fRsRF!wGm$h&hrbGyej*P6%$Hfl0k?4L@6(zdKDNF4R1)n-_(BN8s z3T4NjDugy+fVOziA=@V`3o}vG%QD5r2uiH7Y;oSyxF@XRxHV8&hTLnHVG4=D)YI;o zc4x-ocFE$8OpBXCHl{0hWbHAI%r9o)voKGYN8f}AQo&_D_OySK2zaX^AUaQyeLBb` zko`A##J{nzY@dIZ2GZxRUL5^MUDo@YWGyk}ma!$&ojdr;)r54NW0z*(mSw{>-mq=k zR)%fcjttwjnPJ<uZQC}pvPONV?jE=Q#NOvwXRkTm-;0@;DF}0q+GoBID_9Xvg4fL= zL=Bv&uHkP&QeN!RB|a}SAT*Fs{)%+$(oTX^W4=@`W*3_l0Y!4xxUWFbqPNhdS-?ed z4?&EsOsmyl80)rk_nM4^L5=r0Aff!Gg}wfvKo10OVo_O-{~J>w|LX&@BK5My2;1wR zV-tn0biayKJ8%<zo%NG=gS?lEA)#rBEwbm(VVCY>#z&6JU5lnCeW!RP5IR;H68}tQ z>=?USpGRwOrw&3u8G)rcDt0Q@t>7#CPi9b?nTR!Kes+$zSp9}pbs6rLhu^B7AH-%z z-E8SC+=mKV)KoXkS|p!iugMNbE5<}LVO`W$AQJ)k)5X1YRT1IcI8I*Sj4$I0?c3BG zYy)7z!?A=_bkLHXt^1@or8O!pXZg3dyA0Mg7Z$BQNgw!L;k9ueJ~|R#Njwg7Wysbi z;{QGRce}VyA;JDRqo9C*2><iw{~yuZ|2U)mN#>?w4@Hq`T5@*B84XF@3=;ah(o=+- zAYSAxz@dN-`V8X}QH5wGjopQ3Ic*Pbre^Ax($+`!qA19=#LR84srE!4A7hOZks zKPo>edg=eZzy93S4qtVGW$I(p*4{DeAI2Z(_kjzN8{GKkn?us;q<7A(;ZN~N>c%6` zg8jko0&4?)bELQM1h^oHe+Tsn=9@xtW*1MamC>q|Do3`#U+;-2PIGWd0tEsM49+cp zA1gAS0=;9hI8vU;{Hg@i+GBytbtk&6n-4mtC8UQAL5JrC&gx8tBquWnDu*!(Q5#A& z%RaH(OISn-v&gFEBc;~TL^r=s$2tyCZD&u_k$0w}3t9Y4nl_n9Ba4|q2SPj=^jrFA zm0Cs~(=Cyzy9Z`DX*M@|uK|_hx})xQZblNRezno|o8p_4BOe)pSFp$&;Y*0){g1(e zhGJjv&cd>N`OgpaGJGt8jZWLWV0;KFLN-r)+8eE4yNW)oq%Q<WQt3N_?E%VU@bRtE zFpfanx2HxY0-D#^4(M`N6D<Et9d_VGkwy$(q3W4m5Q<~_K}XF8?U~|r`gAb$FL3i7 z*c7S33r0~hqlsX=aJ#Bn^z9%Y+!Afo>Ia$eOPgLXDb;aArP7o31_5oD)@1gUmZqYS zN)>bK4auFJHp;n-!F21vpR@*6R@vs+%WZn2A>u<`^-PlNVetzOGEENU1@9O|a&P&V z<|pQ)H0I45T*`;dU=|~;E#w{#iME4W58WpMpeP-o#?b+ojqgoVM%b~}rkYhJEUNA? z(24EDy@}@7Otg#0&Sx0__v1ER<*UQ{wz}Ai&4;YL5xbwwdVW*=rb=MQIT9BdEljl& zrNl8C98D|ot>W-D%<yj&SIKp~<zklm>qdtBi+%_KPq-sR3L(M<#rN(N@f1XCub{Il z=eJ43JMFYULX_ML_&h-7pi8Jj@{Oa#6B;KQthkP)5&8pW22<>4xeg`Wx41*kJCgp) zgKNf^eD236gQUKy$5&xSEjc^=w1oYOrghaNbCTr~fjs~=h2Zjv=1SKw_5I{NYbUfo zF&K#*sGzH%VTscfkJzm%x!m4DB=&cCdoSC!!e4vxt;#mo)@c35`*x;Z64hUKQ!UEg z<T9Ejj>Ohf_zK|a_aV{0h>|+MUD{P~G*?dL&Q<ilztt)igIYR^j<j@cR-pQ<6&oJ< z2eluO<s}4sKBD10TY35y*T2#o5H#-~50GjLFuA+;UuXFGe?PWI6IWQFEfbVjq?BI5 z5xh4t`c#sQ*apZWlkA?fCz(J8ZB!TFcFgqQ@ErCVOzr;u^j%c0FEBG(sLHcheKgu> z;@-TUSv+L^SJOY4wA&ONInX`T|KB0<-$r5jLJjvJ2q2)Ie*#Oq|2#xYOx;Xv>>d8; zc#1V_?f)5te{%I56%{0{Owd2E3H4Xp`uv+|{zYl=;2?DK>^PcBlGG8em+lgg%v6)( z{@7(n;qIeezi--=IizodoLQd4C)CoKw{A68le5o7$hd7aHUrmQm9U`lbZsQ-kvHJP z^YMMW+O^!`bTTT;%}$R#!fcD%QiCemUyKM8G$YuoCTjc{D8C|bRu~6i&i-sPs(np@ zk}R6;2-37VbF?Wb$%5E3jOafJVG!Q$GA)3#RO{&LEYU4uWB-h4ubUf&zfXhjQAi~U zv<DP~<t`)IOd67;sINWF<oAW7*tFH8oKfMog$$X`Rz@H!2*STK?4Or$Thvfns<K^# z+9l7gvu$aDf0&HV#Ry9Qj|=MSf1@(;6!aHwb;ciw<xjP4qMN<~p7|$Zi`c=f+(_-+ z3`ncEey_w|KDCjisJS54AzzzZ?}XHiR5`8WL>c);2mDF;Jhw0w)enJM7|gwlEWZ{U zCwA_wQ*-vGi4UhI!$z<!X_x<oSei4<Y|W~-dqT#^r#N<*zYphsu@PtzSFup)?D#H* z@TF$cETjCP%_HUHZZ=q!AyKQyKMN>C_cE#&eAK(o#M*hg%3niEJqt#z!T36-omdls z3#h=#GupSIm_{r@$?2qGH`TV7Pv<kcM&+@nGVm+2ao!QuDiL&bmJpQiM=;Flh{Ef; z5MmS7ZHq(nCF#HrIR&}i^lIHw(aQuf2`~|gy|*<<49nju)S-Fr>zv3NB~$rDxWw<F z^)6YJD26hQA<8mAxl_*<#u2#z-n)uRBd1H!alLf2c3g0SGd2h8=Ul%hi$6XK<Ig8_ z?ZB~-|9Lz5c-%ox;h5MRsJDbD>d?|eQx$mavU!AUvWjmPAFunG<X+E1(z<60??>-C z-4UJM{HK=IM@Gw%|A1?th%8b2&v9a(if`J$^X(GPS-5O$+yi$G6y>!1H8Kv;W%zk5 zDt`I~P<cXr=UkgmsmJV^*5WK}9qy2E9lm5%Yhy-=n6KDb7IaUd|5zn&*yQH@1P0M( zC*3oM1D%IDjr>m?K@(A~In;3~);(uK@3k(mkAR_E_1>1)4zm&-)Yo{kvvnfR2(I8Y zs#ktzroqeR?~9UHF{O)9H60_Re%df?5!{T<p77idZ83J3?8-{pF5Z>fl&@GKtv9@S zF+Xrax!#xDXzz8I;m_3NY^$o@`hRX0prF5t#WIR|+H$+eW*&55?1?TN8E_mt<A0vz z8IYX_xE?_zY4T@D^yl}E6U9!we?Tp~XFHaF*pQ316^j7Z628#&_W|0~w6tmYoDc)F z`Q$nWW{b0F<9(+V6ZEr}>s{@Eacvod{kIYd$Vr6e*zE(oX5qsjCfK6o5*pYjx3fVO zID500wJq8SXKDaO77<>|>7-#cD)q8#K$-cn-RWAm&c9CgAMZOY%&B>z$#ISw5H=n& z-qCrJ{9=@0wM<*HFYa!Uy$bU>DNTJ@&EX0<M_b0?26gx&7SP)8&udai_i9c6v<8Mv z!=V+=C?W`C*3cZ91Qape{0MW#07qP6WCq#oIH^?ke7t5*6XY2$)q#+DpUh)lG+HSF zx*F}wQYg9NY$t6?8ZVinutSE5MmlY-(Q5qHHrbo8IJ)z8M@pvoyb@uv(8nMKJDwR- z8k@{cTdU0wi&*Tm=8Gt15g4EIc12VlzA%#8o9Qh2U-Lfl=E`rI90zr^{ot{!%W+nS zNaG1^smsQhpd81Rio6~a5A35^3z^a1IrnSzbAET--d_pAi;(Nn(e^Cvl+lj?fmikW z77z=l10>hFEVVZzESQ5P5zGPH>$)nhpCC78F8rW<-?abKvfT+L<MwFz*Fe_?U0fyT zYuLNxzk?FI7#>iSVHlLQw=UBX<Or&!=VV=Z$oKxfMtR{}M8sC^+!_XBPg+GzNTNB^ z<%8>w3yqqvUwD9}lH?y&*6eMz+UL7F2?9o2m7$+w52<B`hnn{EOq9<$_aDHt=-2a# z_c<KmgS1CtBg9z_LH1>VnBV;+!X`=Mc9VHesEmv1;JfRtu{r#8i-QqRA`njszCEwZ zwpKZr6$U#$`~?&1h;CQfY7{TFJcjX{M)5;b?(q!_8U3bt56fL$0&4T(H@s>}aHEs? z?7%2YWX-(0g{|@Yv@D%1eru*qKH7I#JXnd!T7bDmjG1h5YA+%$Z=JWBBIoc%5mR4n zf5WxNy-rn1yy;tMI>_cSU}3eY+6Q}t<D2&5y=P!KCsQgtv+1(hJA?>=Z^&pQb+b#! zHC$Dh#EyZ+Ma}sFCp4P#|NTF_tN$IJJYo6lxBmNn2LHGIaQ^f9b1`*x`M3Lwt2OlP zw?>fj$mCz;xus%h^^4c&jaTo<>g4DmJH(J6#d7{oZcu`wvqty_mW*{Tes~;Zbe?Ji ze9uwq7YYi95WqYsKb7m}$9)5d=|{PkxxLDzDid0eWmw-_IheWs{HXbTn%92T_Wm57 zVzuS5^9u}12#gYq`hk!Gh4_;I2c7``0-+S<gt_JomI95%p4#*uhw&D+r(v`do)0Vn zpxJU-k=XyckrW4c0C<BtK-|46LO!rd_Aku@Zjcp(1<~6H`osu;2H2N`3=Udx%T8{g z)EwOPESTA;6bR&EsiqJtxvCPZnPTtYgFQ(n@+WM3RY*H)W<ki6mQzo2_u!gYYF0Se ztOCsPYyHH{+5&^XxcTs5-969*y~nVb6T1&`!-hUZNaKL@!0vSXjW+oZ3OaxfegjGS z_cMX9($eRFJA?x0?)%}1fZ?N>DsD5RhG4LcK(xnf{J`$75DhZ*l!MA{|Gv22fuINH zYaM}nHF%;Phxm__=3MO!J+$V_AF+#mW584P#vN?R0p@w;DCjmZ-ZEN&55{2~vP3al z_kIVd%=0_$EALpRVa6xAYu<Ci2(PG0@cm&qsjPEOuPrF`GU)<fGo+g7r72>cw=*+W zh%0KLB?zsaQ_3_C)l<WF$ekomlQ<I>)q7G;T4)_V3cGbCe7+BdW6*IaVT;Wy*d)dt zcb5su^JEltWNM+qn#l&HVEthH!|P8_7fHk|@T#LZStis~NyHV-cTI)6AihR2rwGmP z3Xg=)qNr@L@XJQENB<gTO|4TY?-hX%>d7dt5JtRq(ldQBVt2eRbQ7`6B5hpCCXFZn zS|LIhTrbx<MpvayBIP{o!mRK!);nkO-WF&rv5=i#g#^`dR+@C7R<ufbnlWpbGETH@ zaUj%IGCN0{Pb8?1;8dLdRnFx4YxgeHy1ept&iJ3c=xNpILdE1C;SAJ9$6OJ9WtT!4 zjA4R3b~sCVlX0qPp@%xjW_$%0Cp~M;Xphnr{ZNcG;U;b+$&0(v(Nsgh(qo~2kfp<R z>WA+`Tz5uV6)wM)(wo0WKRvi{uW3JPvo=^86#W)0={Cbky%K?1vh`GUU|EH6vjEm% z_<Gdf1FO22!)XJVDo9Xn@vY}(Dyb{8#9%SH*QdXB(Q@)Pb1D^?z?=Rn0MnZN$t{V~ zN!%4qT3wC3NBpBpMufJW*7mRJHff)wKU*bf08{4fCg8>lJ#H1^@lww=+6}bJ=dS1z zOk4Wzg@gpQlg*tfNfxYotY_QE5c~etlbHr{+gE>3uL=6_`^V0vREO}b;^Y;UjPitm zf&B;XWxrY87w2lfJ*|*RLAzN{E?mT-&W-`mx;(_$2tOLs8e^~?RPR-G`KsR$cMJi3 z(C5Q1@j*g^5;sDs(y^h%CWo(Q$@Hh-?lb^o{q8>&Otp$HMa!yMWelcDjxx)yQWi;G zMv#6O=C*H*KX`8%k@8<{@XK+w^@v~IlQSZA^d7$c6z73r2F8Y3?;WM8SzA|5cIdqr zg7CxCn9ie8Y8v{B>@xZ6Qs4A0x(XgYExUcL$*aJfkTy}0e247WP5bCO_#`RE#GR2& zXZ|E7*}Gh7{Iw_ZtbDHfu8}??Y>^c&wpaKNRS^>tqN6EX`wtc6T36S6DbJ3@rnt!G z(`nW{&Ip%Yr>5}(W0XBogYejtYjDM&@11I8@ZSIysEap$smuD4i7OYU7?omi&Y_Fn zwzTl7*D?r|vh-cYGD6Sv5nXbD_2Nb;a5a%NP+|;QP#uMF$(L`mKx&&|8v>~XX7>=X znA}{qu=~Wr5VOo<4uN%Wn_*UcvO|(jEy7H}K(Ip7X?g8zu-Q<s;K4RCm}SV>LRW!R zAlK3R_bFngB@%t%oU6aL{1t&#HEIoR<efv6)t>s!x0(X4jv_(jPgT4}h$PJU>vWxX zM*w^kYZ+G{HVL74CDJwFlRe#Ia-Im|Cfgz7Gm^AC$s$3brQzziCE{ArgCTRp9yvq3 z+J6=gd41wGVj%P-Zq6VPZ_a>Kap)~H3{YR$j6bw;X@q?ZH$%-2K&kYr6lj)9TY6D{ z3<uk=XNRf=<UGQfkarj=J*~u88aeKm3T1YtF;w~bf5|vp?8Svhlpw-&qL{Np8;vkG z453-wx8zNs|4UX96i{XUK%3=^Fkr@-g#5Ce>3yfAIIMkhX~YasAgz{8F<Hz$Ry}jx zxv9u%d(@3Ag|b0`kuh_9)-WUQPbv`7Bnnd)`n>_$D$0=mwIzt_jQ7|~;Wlg~_}6}; zMerT_L+AUE_>PgcQdfU~2@gZXuhB914rhHJZ4F!D8zPE%H^v4vf2su|A+@`1&1%M- zab}ppPYY=fd|p?_;fnsqdB>5)j1lR+|5<d}3=?Ud4usUC@hr9n9sc1XIlo`qb2HT8 z9cI=)8+{if%)fpOy9+={FV|EZwO~RKA#=f$dX`JGw(;ngbK2*jQ_kFTZOwKeuTU*} z*igl2W%4z*>ODaP7{oBZ(K*6`E0c-Hn7c?%L_<Nqg?lsL><TTY$J41N62h^6kCzO9 z<=FTQa>UBYqI%lbe9}X=pdy8HL?g1Qe;=3=8aqSx2jytIzSr}m{=zt<*xHG*3X&=Z z;SCWI&MS{Ed>0t9Y5E`zXiH?>W5;yrPRR0NQNO4FzVw2&TGz`A5$VF{Bg`_uh1e0& zEhNwm18RR<3|HLd<<0mOHEJD&>rn673`<|1zMt%#!L|n&)ELS70Nb;W$_-4PT`yqr z{&J6=b{B$98w-Qb`4{|`pU4zo;I8hFgj?z^G%6&u=}5`E*{G^-C6h$qevQaCh`&<? zR7~}kItKsu@phKm{bZ|;4F~8Kya+8)PTk_w6HjLj{EV#^w60`Cf2rrqUuw4GCrGMk z4O(&$N8efU!=YU_woyp^GFx6pmbLDw#WgjXoV(n+dcittc$Q}^hwB$Vp#OdDyV)r7 zV3aFg7>fb{>Ad}ae;55fcGqSfTdz&=#69;Pm|!hDL7YD}=8cUMVdIDOIT3ECo8~-8 zCZ>FFl7T4Vq<z4GQd2u$ua#-O<#w!;TpW|6FwidQ>h9|5>Z{rWKK0wJ>Z)9r2w`~; zwT)&3IVrMP)vH1EZ*UL{g)J2;^A#0ErmD$liY?ZavMT`CHy`bqN}Jz_yUngG7V;;Z zM%~dBs!g<+ZmWPxGv3)uZ>;XamX`Gc?#`(!DKww3y9aifl{-&OI=8GY8(=Hd62+ub zMXwZzbt6UF7R~liGi0%l{XgB-kThi(;y}kG7LlnFf5|6A)tAZRTIM$F8`n)3)29n7 zTefp^vuz%)JQq$basBPxOy_SX?yiqieIHR2#x7BT!6nQUY+6*e#ix4$UNXnot!o#~ zUX3PafwyU{tgxHk%_cSaWqy<f{eYlgmNna}*n?DcZ3`z|+2YVtzGmdJy0&c{t8l(= z$Oxg9zgCkV@MkJ{bgOn!SUe}er`IlDFE5xwN}u8KJWa{xD#cW5B4vUUc4pF9%`S~@ zFlH}1D&UXQKi;E09@u)Mu8Uf=vwuB5EfNOC{g#mD*`Bx<R&`85&Fl!#jbLR_uH{xm z6Pk{6%E-F+7)6}D(}W>a;CQ!*)lJ_9m;$4IGBOHu|22HsKYp$C^WLWF-HVtf!}9Qj z9)$A)ny5IS-n^XD%;8wB(K|Am!-qGRGJn_YS!-VR&XG`-RZVKB;CLeoKta_u3O<5e zf@0;3nX#liB;P!eG<L)u=0duvGKd`Bz1^U}z3524bwI$T9+Xi*?6;}!h*pMZ9*;zc z+M5z7YP5xqzjZ2OZ^ML3eWzZCA=@lHe_20EzCf=$qqc5nsYdOlrd2C~8l@-*{C6)t zbqiDvvF8B%_r4K%S%Ge^G*q!xMtN?~gfP+thh>n8fYzVL@UzH*`#T$ZRvf0a-=Kab zlRU8~x2(7V39{ziSPeu>EW<Q$2v=Su#6nwL5EcFbqpE%?OH6kzF@Ou-7c$uc<k2va z1vG{g^jJC)&b-baXD<()Hc9572)^%4<Msg<eUt4sUnP{AF%*=5)RZz`$hx0$N?&DY z1)tFnaxY%2lJ-Akk*$s{V!_$1h_)UHz!cs^vtFR}z^v6S>Rwil0|>j)?o8edKBZ+7 z!r~mF%@@4!{Z&`-6dFnLj|`8$+vX&<_KC(P#TO{gB5~Z(BBiC137~Fk=Xy71z6HE{ zJWCDKTAZG9If#jIj4Dt&v;*9uo7?MF?FgFX8Cx@Mm#yFPecPy8`@~okqH=pbPhAzO zH371}I<wlo(T7D(Ws`4Z>~2=(4cRb;c{Z&s%?hQzg^jUq{+5-o<Gw}@^#c5-KL-0Z zzTIx*1{z6Bcv1(D8jxWZ{lsM`VHH%)af4vT_zDz-rFb}qJmho`ksjm%irWD@!6A7Q zJ%G;UnHBS`w94R?n&DCF`I?KC9G8U9V(k_dQNa;9Y8k|8M3ZOdYSeX}upPxGYoSR} z0FjqYKl|EyUhO%zgO9+I(2KONP?XsNU-$Gql@xsq&48<oZm3O^WB8Vfe)P?jR&a2L z1D*brj<)iw#iEv2H63ta$?E%=9Qw8x-)iS^2aSwIIAWjoE>;HDuz$Zv!Kq#sGau@L zz$*ayg>;hyiy?L9tI7aBiUhxx$PmD1Y;Ru+lkTE5t--4W>LoFt1O{yqS={|YbFq`s zC*T0}Lo;%GRs}Pzw*W<s1g40zp5I;N8W8X+{m_QZ-|CA<E({x-F9@7AVY9Mprs!X# zE$J@8uJU6eBnedZFn<m|63X(uVf`e^NOcSy5^r_bv5bTMPXji?Bc1JteFtBVIu~uD zlcGzQsqS`cE%h2<#6MX7g!YBIR219?{=PNt7x~6jejX!j6b;5yhnC5uqq5oNNk!nY zqAm$zGDhf<u;`!2MD{U8S<wgB<p}>Q`kKldvQ^j*9!N#X*@?Xwlt=aeI!^CAGUTwo z`y|6%_mu{YM&Lub^Z_A=w7;#!r*gna&4^fu3;j%ep(|mJ6we4<ZhCb;c-efuAa93V z5jLX}2}@()xD|MK69pK@Y~ZbR;;?PhFH?}*?@qyhW-F}yg?pi<GlY_M_YRzCsDv|t zeJ(S32Oc7@KQngn2K<3ev993zTgTqahu(r}Bf`x>WgsT~lTm7_u<}RLnBo)^ySFP7 zdD&S0V1I|7*_E8pLk(7`suoq5Nn!)Yt0J+gI}M&YDztP{$;g1qW~5fspMMP(omFem zk*TQB20OG-G1JWgw?1t;AyN|A_=io$hk=Wmh+A{1M5r(Ss;XcVn`34f7M!s$&-#W- z)2!ot(EAg>|Dogsgv(md3!Gz6|My1%V`wFOl?$ccy$<@sh*V$UA3}9JHI^2?ycj&J zKC5fUc!DlGz3((@JDc>?Tgnp@jT5{LE;2O}mZnE1&|n<aiz}iqju2IpD|~}ZT7ArQ znIHO7yk1X6BYFcw6^Zq&?Uba;6yj;>^jddXm_5fVQxO;5lp+*F3)EQD6M35eO|B56 zRX9G^?!mPg&nT?viEAlXblV098n_BX<$`i|>XD53GlJ);(G>o%1GW}JL*}u939SW9 z;@9^K34<nxDjJKA(frnILT;TLc3H%!QVo!3vjysF7Y{R|c<Ma$KrZNQ7X(5)qs6!K zopy5gpS{AUZ0_{_bT0~3UGrd(s$Fz=X7SG%@W4D*S1zGvL1ym|%!5Fl5mf*3g>qn7 z)XIFt{qgg_X9rqr4Q~*!BPyt)eUA(IZp%wv`H%TQd4$Ub0x;GNn(db>-hMl$ziyn9 zw=HuaqyTMPC|5W4AcCEqpjtLm6f`HaoN9yRWK}LT84f3eF1OtdaH&N}k8-`Uw%FqV zQaI7-7Nc<*YOT&X1Ea5P%oTe2+C_wS$QGM<%l5dhc$}?rR$7!L1+mBO-(B=4si<|L z2xze#D8P^xzzqF={b}hM7rK^~B(Saa>tewRvdS{IQ>uYj@hfHH5zvg4dJoitg{Km^ zW(#-d_)3DJ4Iy<f!iid|hydH++s3K#&<|-QkVZ|BmtQRw3OHFfEqD?AC9yby(!7br z1b%=S@fN;dcTy?N=++SzUbO~=T`(U6x48!XQ6iL!&9RosW&^>%ESs!7dA;JQ5AkDC zU!3+BrQYG0IGfEcIq~ghg9!jF0(fdLko(R)V=5Vmmmr<`!Y_y2HS!{4M>p=o_88gB z>kfZD(imMcxBV|-Ye?0V=MFeIN3*nZdaraU=ATVC1e?J_a%rGD4;#6%A`8u9Ua+Rl zKHs`4rwwme_=$4=l`??;qB6j)d&d7IsN(%knmq#nVrO_o28ddDgaIZPl5nqm(izGu z>1H8js*C3(Qo=f*8P{(@;JnSspA0``Vln0wNQ}~!WWzoR`cjHq)#vvDTGll;foJ6v zwe|qCP<65$$BaCkV*L-SiHk=&lM2<E(8X+ZD_%4=N(6YRMV~|k&z3K=C}Hj9k(5<I z3`9-}wY+e*wJJgK%ry2>YQ8@)pa8FsJ_IxVzUZwmD8;<#d|T<e5fwFpv&MbZUk0;W z$%vbUPMpb9wDf89_znO5UQv(ap`(lHqCzyp=U~v=Cc~!m@BnIu2S=gB;t7lVz9N7$ zn~iHm={MG%`nGe=tElYmS>KYYVYa(@UFCY4{fB{&37OUg=2d|q4-ly~y*Yrx&!wvZ zF+nc)0bsG=ef>b=C+9Mc7EEnVzTvsc!X_-MWU(+m>xqaoo^*Cuu1<i@i<48ay<fZT znbv5irZ#&E;2LXtvBf9{?VNPrWv@;!a>|wHv&mf;e_Cf0+yYJklTLU&C(^0nH}A#i znQB__L-?0vy6fta6wGa(=et9)#w(8KL0dFL8^ApnB3jSsa(qzw=)qbpA-Jhz?SpoI zAxq@RvwCrY)awr9>LlKK2VdNwK!EV@;#=Dw7}z?9#_SM?UCE*Y$Jt(CwGkaCm<hI+ zY3X_e_7FLAjIC}akP?tz>2_{6N3N%{kY}fV8yDj{7B{~cZB))Vc!en8K7jgaHhqc) z)*CNsb~d33Q(T#?VKFVjj@Cq{DDlimi=EdvZQ}rrIu)+##uQ<gV2W0GpLhB-F<xEr zr@HGS9vm5H?Loq^rpQ^L{ZK*Ks|5P`3l{&`Dh<7FE~>iz9p9EI;Ni_Flo6l8^nrUS zd&JGKahGD?F&f5Uk&3;f-cQodaeJB_8LqD{<!r4`LN}CCBeNu1!AV#m4It4R5MR}2 z7Gx6f+Z`CXY%wS}E9bo4z$r-arV^?O!K=7r(#-(K=%zjY<~Jj0i3;yG+CFSIWENDS z)wuc@B7_aTUQH*I7aHp(n*fvy!WU}|4b+MSwKl|>rxZB@zmYMa*8i-2mQ6)weQ}|9 z0t(8yDJyh?5QMM!LE4E6p@Zg|FEKN%49icH#v5zh9L!=H*sO9DH$m_wTOC3x_jV($ zqy+@l05Wc$z;k!HkxEUwq0)_z>tKJwHh+@POmk%2!U}_^ZrUfms;QSAoMW*?T*5I) zim<F-!ww<FptVtwmL;(Gwpi<2Nj5*LayGM*L~z7lCA#7m$qv;mZ`twIii-v}n_NK& zG0==0J3V1ta00~!##EcN9|7<WaFPg<5xp{*Oiyw}x}JZn^$t^iQ8&aAAxdJ>@f?b^ zkd6DBA-d~1X~dI;Hfva8a!bIZr>X^yj}>5mQ^$}65Mtj;S`p4F*khWGWCwUIxcB;g z{ak0cGw}Q75i<;vtt`0Z?%pFRl^JmKG^cZzc}Nx>`-UqQ@hS2g5Kk_))R3@otq7zI z#qPB|(LF@y(0B*1#fKq{3H&JnW0fK?#szI^1<a*)K601AUV|c3S3BSRaY0K!MAJ%{ zQy_bf-{ZTP2Z~Q=;m<3N#UJf@kFGb_D(5jK2~Br5U7qvb)+P2p5n@ROccotXG9-K} zZ>cN2T($JZi6f6<t7;@wc*1wM&`9k1?!zxJw?F^uQ>ux%>^Ac02n#AUm>K;ebu<JC z)lF957!Y{~c7P~*A9iF6h^-En(9+-Du~`IyZeN4>#RKWLijS)jogRS9+xLns`_#!= zhjPpJ3ENi#z109!(wp5(*oI18?*n~mL5QfvN=a?|Q0@FRS0!BDD_mjK2SnNztdl}( zqo2zgS%Ko=-xuvNGiDOdYnVr|$rmjg!ps1LCbNgcl<EJ-efz>|&_S;Mi^sq-RtE!o zSGv^4Xjw28Bxq|9?KR>%stmOPmX@!;Bbg0&sGG`J0;=9Pyox(0faz*}wN6?BjZMl( z1ddM3UK=b>f?;jnAt3^AuF_U+5NF2JM%n4KXW$PqP$8^K^3J?J5Lq#7q&^4{qQ-be zz{u(yW>$5~3<j9?HXPieazASOM|iCYBP5<+q4{u&j`<_z)z*@_f5Iuqw3sUt?MiL0 zScX+Vx4;e?BrM{BOGR-H{+>lq^jL~vsb0Bt?1=x{bqF+V%7GkzQ3X!2uEmFy9Ts~7 zg+md9D}bzLMo~?DF;o}?8?ivnEd!m*^|zyH0gVs@ka}eoJ3hvC{Vxro0AtpYaVK%7 zKIU@^=J)}HG>Qn{uF1<vo6SAae^L@lFA-)!`@TDb7yFH{oSL9JhZb%@lB-PMMo^rG zwhlVy0t=}KcJ}pL407(VKpPkz0u%VrE?N$;2pdl81cytD@Y2-+aTj4*l4w)Yd-N1W z=>ZY%B)S@yr<)boT>w0n`3?&-XaJj%wO$ZhM_fExd=pImeQ;({LA1EC!`v2iD<p@e ztejj@KhU6Wyxt`|BKD6AbDHDEIbp=i^~BT75VV-4%;bTCMjRYYhZV<Vzn~(8lrHOm zcKlL{KhdxE0~l9C_;S)R3En7r;Law%)_A~{!7==ou|EaC4H2}KW3!MR;G)&N9~1zP z4oRctVX;+I?GK7;WG7;{-HXUSl*o_La8FJPC#Yeed8_~+@xPZ*dh|bv#9?xaS^$bJ zw9-~pg%ql5j5YJ+Syf#T&(`LEPq+!=+^i1FL+J83t%7mUB)XN~d=8F@<{R?R!H3V$ zVXwv&Eb}W)xC-2L8ndVD4_p6Y#qp<jD6MWwOX%+ZE*`!(owvGpb6o$4I3wX$qa-~a zG&qQsD|K8SG1SFXfB;A-%7|QG^90cjjXRVe`P*!NKq|tsn8{qx8DWK4gC=$yL)&~4 zKE?oPoAwV|6*!PsJoua4hueS@TB2auRTxPni+n&F$f3U<rA=P6V5G9_%w6U4nCofm zuy@imb0_+`9J_mGW^2z`^7_IXJ$eB9wP-F5VVox^wieg0Wa$xo*T4>udU|nuy?qRh zo^3}V66p1EgPR4=vdvm;1h8V%Us+?Wc%oQIYru8G&UP-ibAhn?22#r`e=e8n66LXQ zzuqT1xYG1SeViE1WjpOPS$<1eO!ay>z64=ACmQT@ePiO@(?6<#j><KgWi4cZX=$V& zCOzbcF1Wl_<Y`J0zt(Jt^6t;P;{bl>V)7d)!_L&(Y^fk!)LqGZxOgF5x!v+r+Q&C- zGMd+;zio`J4UduOu(Z}Jg*#n3mKBY-z<>m1e8-OmhT`&-*Y(nypg~>27BtdV<PSy* z-O{qTXK11qZDVMv*p)?-jLng+H*Jg*k|Y3*5{8$abiZ$(1&Jk!#|%w#{*{)Nx~5lF z3%EOSUCN3*A#weZsYE-!IKT2XIP{8MD{y%g2E0HZ!6j`<Y%{Gi?!p0c#yEb3BG_4= zfa%5ua_vF-f+D7(!;j>ljgWd)9Bm5ew|{9+0kmcs)yyQeQIV(=nMd}Y!?`u_eX$SR zrH~*Bu_oe<rDa9MPUA(q%$m*=9^N5&2qNr7?<V7<yI-5UL`j$4w=@>`{4b-;OjDFn zi9@TWR#*FT$r&ExYJ0&|77^m4@EdzPB<JBDHQy^p*xbnWSyW6q^WAQZrbN2ti0L*p zX>WXr_3d&ReI6E@EA^p0wLieCoP&!BTH80p5UiwfpZGLuQLiiX1RCE8<Dt_O_{ih4 ziY}qlO|-;+sTa|I9VwhM3GLL%$$Wne>aMIAq=Rqv!*GI~w@z%$Toa&iX77u(a;-3B zy0IeVJ|}}E`_qbd2<nqKTP*1rW1;b#6NczjxIKTt>+&x7C%}tfas2c`-sbX83ORpn zUfb28QgTcDQf+|P{|q3yhH31ZpETCVLD=iT%)M9Lp|3Gp(7?L`arqDvR9Vx!sG;A_ zCmN{fXz;%UJ*!84uiV3>{@(B^CibzUO=!dLzbbu!S!dZuinHcrGfESVS{dczm6|&_ zJZF?1F-9)NVp|<<Nr*&2PZHH87)gxn@KWks5KS#y78*d!%y*8C4PiN}T=nz$9^7<q zR5vH!cf03}B%eD;FT_f10*2yiBi8#@-?kDeyk?4bfKF3E6QDScJNJ1*wQ>p7O;opr zob>d8r3=|fG1DdmIq+a?KN|Xg%Ju2+7I$n1Lcx71YBxA_=z|)MsSZ0ohq0+<*Uq!N zlPtwG^1-i=Wt!0?WA01B#;TL<CQ@m3^O%<YLo2atild|kc`w*W1O@XqyTfxYnV)$6 zdl-!vrgauL3~!E*oUojo@{EjWp?c1a7f6A_y9VcliZ_@9iz1MqSHGvX`=%s`8eD(~ z1GM*8PA9ie_~2<{<@ja1bs_<j%*6l}g`}!!ledGuQk%WUl$z5=*wTFuz1m#wQpf68 z=+J7!S|VeLT#hR8ldwnIt?ii$I)vIRWyTsq2zX5M&tf_LFr!QkDEBI&0UVx{f*b!b zohit$GBBcyA?WPAF?#oH^hZW>M<ztm%de>pYX^QtWtrjz*EN9C59!oD2ZOO({Kv0l z#QmW#gb3_uXChwAI6`uxB`?mqYYQD0j7>gFwo`d}?oSbOs;7=S0Rx@rWCfI}+&zMN z&~}Ox#-E|J5Ge96_ehg8@woWZFUIL@w+JG1?IYYjaSo#suYHK<D3#T<l9D3J`oF+3 z@)kRSS@1f-xi{-IaU001_0UK1z{G>X`sQ~PLDe-$mUzi4NA<+yn%t{v9XkXB3s|c0 zLQnuxSv@bFN55PLin1YNTV-kq%Mji_D8|i=Y`&(+7ew%Vm{N}K6!WzH-3TRVAIUKj z!N}B&)ohgmj^MNJ()4|q3hu*0*(-6l-T-`6RwfDP>m6#uD@02e7h!rKk;9S1KW@Vr z5O$S#Pu{J^tb7YC6=)r8ZJAavW@b%=J10!u-BlY1wSgsQ<#PUIqJt3vAOLIgY_^-b zGeL02LPTY3H20S7C0?<TMb0TB;fT0Q{76_kk^Kk&BjVZ@R02%K$E<3M^9PZA(qq)T zD7<6qzbmskw{#>MiM*@enc`9gX)Frek{y+6cg{~s7Y+9{oQMPb6SNYUwD5IBj(_g1 z!Lsj^^XuY`gC9yY^O4T6K@#RHip37n%0u!$;k@CldzjcLTT*RLX*=%8pmLkU7v4F$ zCTGh9V@1_-iWpWHw4CNqEp0++CqX#$OIH|o@s;CklQ*Hxg6G#|P(iS~O=dkJ1aXz# zR9%V$4IWc&vv!j#6Z&W^7iUxo(BYn9sKd_Fq5a3V>#zk+n9AgA>(sBWeeqcG_VT)t zd7xxAryC}pzxhQ<8D0sae)Bfl<vM|1wXh^di-}B@7?<`)WcUbD^w@aQS=EAi_gZbn z9dn;}vu+4{V|xg#o_J~u(tY|0%9t*p=QQA<Cb2Z(K})Wxf96nm2xel?r8~DTj<{Iu zLj)E^)2&pam;b>m6BNS{YCfQhpKduEguSX&9cKs5WT%BGyuTlgC)b6Z^V%4m=r5Kr z!*;4D=z~7YhyVDgU(F+tqfKt4p$%8Oa#laRnkJ_V(jkN8?*wIgacKWEPe!5AOe|`? z(;-v-m#kZIM^Dxmcj>X)s`DIgihpA2=8d;|K^1wM)~!$$fNNXdD<1SW`RLQw<J<E1 z1`kU-935k&(Z$xVY5uhksu%!WgFn|ED;{kg{!7O2nAz>L`fl2?cDcoB#VU!tI@2IV zQ++G_h_Jcs!-M>h&9X%0t1eaOia}ZuE4w*QjEN+zh%2c=NO(?5{B;CV2Jh^>_F8o2 zh!(FATe!-=|HaMk^|*f+Mc|9s>-oKUAC`7IyW_(f6T2?0P&yhR+VG<S0awSuhXQY^ zx8fRP`uWI5gE=c}rVVe72G%sS+F^pIgl0Gfb&h-`1mhD#*_&RoWa$K^gcZ>nbJ$2; zdg15c_A_cOE*r$c(H|%m0d1;kzQJB5hHr<6Gea+Orhj<Pn+oh9M+Q(aQSF8&RMtCL zBr1uW$C@e`r#!1wmNsWqs!PhNd){NhUEfC`?wd7HjdIx3FhEh@y;UO&{?+n{`gY6S z!6zic6XYU()<wg$PD*i(M*-iSRK7+p+;Epsf0W-=<N@OnJf!dLu}wZ?m>5(k+>qTj zc5FK10L6h5y6oC=Y6x3wduii`9ZYM|rSfjd-G#?LlJO!<b*n(4^^Z|fV;4o^U)0b4 zzNoI>elt;n(yA|fvlhShHFD1~ff|n2+jJHgXeLw7`ln8vhih(kM1VittVzUtR1GEh zXV!<!5M|_jz|{S<)nnCt=T56@(n}j{@TqXCF+L>GR(j@Gu!q`~^*WX`5jGMPCB@!3 z5rp90OTJ`zgReEI(0Q|am*e#y#38OpF*|CY{0U{v{P3E@?+!D+()2MjMo~`8ya1ZZ z5yV-cb&H1Wf^{PuEGg`ho#O=R_RW4F`i;xxJfyUOgAMUHAct#M@iAAV<PTyOu>bnM zEPaoTVFAV(%dzS<8)>-1^UGh75SDp~X5zf1=A?%t&EiV&s%ec2h)G6N<JByID?TUs z*~H?EgiUjV@R?k}0)3qi?MMVZcLj5Oo+F@W!+h_P<m1t9wLQq<QGQ^l2y6s%CL}R^ zN2N6#f^5LxDw;Ja^RnU}a}Qo&ZG5&lxz2IuxmOC$TU^Ms|Ggkve*rWQgZLz>`Njp{ zVQ?P*nPWe2cnwRidkTR=8AMR+QP{L|y&R{7SR7S46UZokxa#)~E7`u=9fR0W19Mi( zzyR;y+&eeqJqaF~(^$78B7etd1T|*#CoA)U0r(VQi*Xwn_Ud60H)oF7ReOBj1Qid| zIUmu`!;EXK)zI%f3|a#L^B+76`7%CMXc_&>d$Ha+c_IBg%j$|#8qPCC(<%>5?DOIE zCFn5rK13cB!7e93KCTSp?5<As7!v}w&O7C}UoGd0Q+za)8$NDf-)jiE^>F`i@9Mx@ zot_!<9BZyufH-Wl#vH4%;lox?1<HCvjfz|z!?PTXliP5YPvnJ%lUrdfHsG<K#{S&D zf#@K1<|lr@(s{dAjTbj~YNQo%zM0s6(mIuY@XULqjn8Fj;BXnM(%dP(Yg>K}hp{?$ zdF6Td7kgZohszPmA>|R+&TRWa?1^R*8J_u<vyp@6QR=Fz;JE``nD*|m@NbVdgBPM% zDe$l#VYK}C#9W+LU}dX%;o5~hT|*ycXrLi(A&zCp4UD*$etzRFQQEIrG__Sx&S6Tb z5Y_Rw1kEJ<3pnt}ZL>!A>C|Q180S8nyF@NdxVrmbvI3jxE8m|RLXOoxUP<w+vGRtT zoM|CDCWove81)jt6F7t#db_F2(nZ(Y)=WB{+`;Q_4;i}rGnV_Ns=|0~zZnZ6i@Ar6 zWkxlXl<QyU=4z~d<m|k;>XFo#+f8*O#JodJkV$dDu_yYH)~JN>+x1W@sBy8Ys!XU0 zxDlvBE(mG6PHzNwQn)*N0tZF~vn(ZA!#4jgmvSZX_a9!#)=yo=FG+A(i;DAt_kKM@ zbza?5celV;5~4wwLum4p&U4S}cAid^c%5R={c>RGbu-Q?4@RI|*~X?Z4_G`qKN>Gx zV9;Bhcl8XS0FbJ?0NH`{hjMIOGL$gUq`OcW%b(Q=owW5!id*0rr~V^z*Utd%yh9bM z?=2PpbYseOly>5;=WW@%ABG?G$o`0PP7fl4wJkew;{>WZ_aln^liMruNXM2u)mq4O z!WLbfyL~Q1YF%V$0;rqBx;W<!Tnt^60OnOCx%eCNiw)W|(9P?Gxn}8&QKNznWB?#2 z-I4~ik+|PoxaYc!llv6TF||>KvTgD_<mg0Uj=O2B{Ykm9oy}S>4BCxEB8?7nN;gR+ zhJ#TR?a?yOMhQ#}rMc`@Z52<@*mUqFFg4_ihBYNZbf;pyHAz_D8Qfm3;V6-zKnuf} zA<9YH*4!Gd*`an8IW|X1nPH(O3b_4Z1-AO=s_MzA``6?bfJ%u3PiHR%4ZJ`p?h8)V zP_5(Zg~^+zv?*7kB`Yck0s)x%OC|9xDL4MFKS^l8z64llDL%qlB72YBU$NIzYju&1 z=<^1Q*LxKE{PS5NL5u9Tyu#UX-PmLq*Ou~Bo~|(!3}})-0+z+loVhvw^b#vjl7PQ; z38meFV0h<HnwUopMODc9pV&q-1$BBL#^#mVVM+L@Kk|bcH83$x3+_P61p8=&1eb@L zNXb_SW-M0+cHatqzV|=V>sh_o6@7|$ltV9Mep@Pwu|{u_QS)V6vo204-w$AxW?wNn zE1Xqj`*?mNAJ#y4D?>Pm>X?z!Rom~h#$xR?7PZLN?kdO%q$a=xWDXNP%I!IA@MZ~j zEjS{@t1N-Mb-B&!DI!3>`GO7kT$uRC6R!u>!kG1TCOJAx#{B0D!NdBzHp=biRmpYB zlF#Hy6ZB)6^Sq=>q^rpRz^NwBY5_S-MLU+{+Q<Kh@ml6-QgwsEH*WG203|iE%kSIv z^$N@Evc)1~qk;B@CK<iXxVq*55hrd8K^qN_oCrAJ5j>bB_NT{O#;li`yw^?s;w5H$ zac;f4iX4AQcvCM-Zf&DmEeaAu$;z#sDCRi=sd@2a=#Z@72CFfbx+}ksmBofgliW=r z#(l@dn^gx&_SOr85G&Ck?>YNp+`J-uuF9zAovr5yNW-lgDjyABsq;x}4s;}m#D1*V zqfz=atMOvm<{LFqiZ(Xx*DY;f)q!S)3mZw30qq^hFrS=TO})&ittYI|cn>RyilEKR zEl-lJ<Sljx@AMi>(b&3h`8<$_zE+r?ZxQ&|D`DnH_TghyoNDJ^)#5}zoht?APfLO< z-WxZq;&vR%d~B?&z6gFES<Zd&bJh=5cXZ;U&>Z9Kwc@=VxMTh6uBu*wC-BV6$1@*H zpAY@kXD&asnZ<W7iZn2Sc+!<Bi8(lO7k@(ZFsZZ^oqB1Jq_dBs{kug8k8zd@k^<GZ z3M5@(bNC7Es9xV$h_`Zi7>*#n=_8$1<KFgRAMTv>)rfnma?Oqd@OzpWpXSM)LtS^L zeaqgutuy#lx$$vD<AD<34wa|1+|ty$Z9i?fZ8m8^7)D`Hbn4Wb5Y#Zu_B9QLzGH>N zDedr{tYls%`|uLJ-={wV)AgFhth7^1RL&7dL05l$x?rM_26=`H-u}v6k`KBUxMcBo zf0=d{$nO5av_xK;EuV;r`0|=sUQG^N*m4_)=Cu}`51`_nMGlWhGl*j4s+xT~o9Bg8 zix)`L{Mn{yf%N9`fy+YEr;~3&6YEv$JR8m9_g)&;IVWFB!9gtCN|-nnv;uCEnwTq^ z&#y)<iLDKsb^Y|%W(Ne(X`cR&QujgkC)cHCKXV4=5cty66Ea$7=Hh3g?UFNmvr2Np z_efKSs`(@wpgdY0EF<B@2T`#E{eIxmM6#?&SIQ8V5||N5ot72e0*+pd7-IzyVaF=3 zsW^gD`?lrS2K@(OgWr;~Am#LsF9FN<&f3D7mm$YW&l1v8u=_O=igsqf?8~;$U2Vli z7)B4e*Fg1d#AMU#2^vH!5uCUsLKZ4p4DSu|ws}C-Ls)kepi=+(Z+Tex2O-s<>wriG zCi4S01$NYK$w^X-zh)1iVoA>Mm-#2VYEr<iOs<ja)h~6OkM%w+;9mTmh$&pllats$ z$U_$L>D}9<F(w(qbe%I$7p)Jn*-l3-rpja7a5|jcU*A1DH>!0X!01=^R5_`gY&vJg zqU3kugVdGSf1diTys6_*ZETlBM?LI-0ZdkVI3aSenTBD?!KfjXX#5o-K2f%eZ_Yhq z=?RJeV=SaBw!ndr>{ef!0~K)NU{h{|#IBR`3u>jQ+58V}Lc8=YWOBiGOw5vs1w6!q zcpi51Q=9h>D%P#x4Rv2MiF9}lt4P`U8H<Pn(Vl@n>+mP2Q+H<K((E8INY`xXE+~sY zl|Xx41(?!FvI(K%&d+Kw@NuY#!gKg=PVm2+cAAX*(W1iy)8*n&Rds@j3P8Luu1|qJ zN+9FOA-cwJV`+Y0S1FliA-}JEDj#P>Jr0zIveF@67Shsv1aG9ZYU{s}-@pt9<Fny& zax|GhEFq`U9~dhpA0<sf>lsX;1Wrs>SyI_?ztWYqFv68|d4VNiT&S-*l{4E~vz~a# z-9)#7-K&w)rPN{jES5P7FEa#f=H>!a#pPH7O34uH4>8Ff4mZ{9<)2+;uVf@{Q3q4F z<v=(wh==+d+F}`U@78Y|uT*+q4{*!6v9e)SN`#!${dx>Sh;I0b8~XE)HO(1V!8#ZA zv9G)f8oy!%eYr(m!AyYRNw(FNGatWNV-9&UwAO_}9-Krs3@8)j;i;%W%s(5H3OSLh zFV|tgBHF#>T_eAPKe?=`POAgCF!NzU?#E4!wvvx%0L;WOBMQ5-zwFt^WanQv6%UjR z@R=^a3NEp(96f%GTTm)H?3pS|W!!7gyG972;OIw2444?HcsW`vdlv}+Nop$@8^X3K z(POcdCKK`Rzj5R-QEeV@%<7~%2TdN5$Ks34Tzk%QdS2kCB2{$vv*VA(+4Jr?YyP#a z#p-?8J){p68Wrv>WK9ioCPUn1i7Dv)SN$5Q%Eb{delhX+dU_&`G4k<s2)hxa29x4S zG}8f+ZoLm^XzuP23ERsG3)dm|6XlBVe8&urHn|?e)t*5a<;IP&gzL1&C%PP%i~gQH zny6!p^stYi_eDq#RszB&#hO!79-YZV9!|n}ZN?KzHF*7G$a~lKhN@|SlQJ;&x+E^X z%Oaaod<~*r&$(0Gf7(GLpH&>0>(0P7+5}EnLgfLx%aZ^ml*T<;#bvmS(!+i-q_7tw zsZMdig^4Ao!82g%@V!4;p|zu;6X(KxrBn+d%-TG_5C1uPvZ*M4aDQh~z71!nU2IEP zpF5F?5$ZG>Qa}jmf3|wi;{O1Z9Q#YEGg8!uOpBjS3I}2L?dbHhnPY3RgIy}I;gRk# zlH_ylv3Lx}ZwF))70f1QqUTPu{7%P7A@3fBU#%4OF9<icmoXr}reone^x^kE(B)j6 zZN1lA^*KaW7ng3Ufx$D_U%av7o72e4DTrN9SA(IzGU_mCJO>FQ)^q%5sL%}^dlST} zm>Jkz3En?jElD3n?JCNV+$lZK*MD4@gX|y%Nx=rE{3prQtHuauI7estCPeA-1eOEK zcR4mg4PCK%&n1$!kC-1DhA`E3T(Gt8nfLS@!FYh$87pu|s?)cOco=CJryZVvso;ms zbThV19GoB!-o${=DsGl-Q@xqenMTS6Yl$=Ld0an}R6Onp3OOzi#`|1;C&04{Djc1k zaj0VYNmzeJ*oy%4uPx8ypni`ozh}ZN?6A_X*kQ!CENReRiwjvvmFhX%z??^X%cUr; zF3x*6yPp3SUFX=GSr}!}*yz}{ZQHhOTOHfBZQFQbn;qMBCz+o4GBr~(|KZlH^PGM5 zS^^O=mYH)N=@WMpUyI%~u=98(;Y=UO^oU`+VX<yCy%3yc3^o8Ol7Qx4ACK?3Nc+IK z1qF_{5vL<BIrxS(jU6dE98G%9oE7`lg87F5uZix*NO=~cJO0QIXI=rINIpEB@JR+3 zc4jw^WfwMJJR4i0l=7>t{G=XlxS@|`tSO5#y$TC1h%oYsFeYDuw@Cn7Ib-P;^GWV1 zZ-RN;{dXU1GRucxESuz&Gu$76_dBPTfB%kp2JwZT*u3A*D;mXT{$dK>Pv!M}7Xf>M z&uA8$2@<f80!w9Qp<*N58jwHM>0r=B26Y09jT<LJj5QXxjwvu5k>7nZ&YIKtMBn$3 ztCjOCG*la8>?61DPf}5!{o~~d1jqxWWUP98dkBO&a5v#Xthg2Er47HF#@#giX?OBn zwmOhXyvkx2^)S+*#H5!%8Q!ht{#{wBC&a5+&#+_*jaes9d!26^-qGMdwu;GE<+`>` zTTU)KkQba?J{b<e3+f`Roh8~mRcY#q*}k-3pcT1d+=JU>C4*KfoEabXMMM8U-j<RE zuLsHik@!LvbTA;}Q7~KTi&R1e-?omSh+h@gB?wkc0Y@IwR$+G+vkhOkLK5O9LSwoG zA@=Dq$3{u<OC6_%1w`_IW&|ZTs3Kzsb2M?GiX&1ErS5voZAT<xVJ-*cx7Kh_s6bV2 zXa&<#?+(!*-#apUkx?xYY74Qv3ISRrg9NZ9>?zw{0DKGSGF%}X5=c4q=cb1-y&6a) zoH#EdR40NiXA3Wo_IAA50~M;-jiR<Sp)Du*PUR#trYIiCDb82E9%zUe(Qa6={^wC+ zMg{u>a+=6qf0f)_PA7MC|A5_W|LiD%zIlK^0xs{NN@v5TjIk<ZHb>;3?Z|>Kp$~e4 z{8&{vVe`=sSE}iBSz7qh(jz6gc?x9&k_!1K;3R|$qnr}PrV69OFn0y@#mMBcyXjqg zGovtVOY_}6PmX7qJm(98vt<sw@lAF%Y%{@Hb*j=xI*Gle%^$0*lNYQc8~(<SqA<rS zA{@Udn}xBY3kt-ywP<z?PJxMc&!Jw2(8CqZg1g&reR~V`WmG}mPGB>Y49F&X>(8iI zHXzvia0~enNxo^lySVZQxKfk;LBxAGTB<|!ovqb<yYKhK2twpFFJvyN+)C!Bl+fha z)=4nE;a0F(&Y@{P^cTXroaoBPZ=kz0C~%`Y9I)!QSNK)h=w212*C-b<t7Z6DggTPa z+;Q<QJ=yJjI}eYCxkU&PI`RWL`bdBxz7qn!<f2>pFdEZxgYXQg>tCb~`z9PYz9O%l zfd@aUlMyD5sB`TTvr$K;;Wa{v=GOb3d`R>ce+!t_f|e`-P@HIs@`hRNPacya1RY?A z{Uft=UtK<8j*;~-zT&tEaWuT!%MugE_gJE+V04$M4&;v6>tZ6<d5fgWP|i~$v*P|h z-!(!gz^#<_q<(2&BTeQ?&lmJ;mHlw8U7g5HC7+ncjlz+_%`IlsatY3{OO0^TMsjbb z!)*vRVUpevrZ%sXKO3WAD{|4@<XKXO*?Vx6cs$WbTiPNZ5GiO62UiGm*p6H1`6OLp z@h(0HiM#8h9Iel#BX=nw{gv9-E|c~dxxagblAwN(a4Y<mynv7%kj_o;1^YE`z+mJ& zuqqBFw+v<|yVtOynnXBPJE<HQ%^C&;#*R?K(AkBCA^^s^q;%Ql9%k^cNiU1ERQF{> zR|G?Q^Hzv#pnf}6gx~>S!ixj^VAv?%(<I4IT`jap=041v@vZ44bqD7hV?BMvy>=|a z7EG||S~qg?{k-nE1bdV?b=i3HY`F4bmc}{aAmGuzfgrZ{Il>P=aX7ZmAe!9VSd)ev zqtdl}bwUn~<2A3<LAM0!soEMi7D$$#_=kR@e=tUQu!E%h>)Ca~>t6VxW-cv}dRxgK zl`!s{JY#Oiz|3z!wO??XSY!faBy)I0XJi<|Hjz)e9D1mQY8p&itVW(o*=m?&K<le* zuJ18s-R^$Bb^XXY)+`gC?lUZeFX0S*!A-`k><#CuNW6FYi>C_oJsE4D<3OiDn{uge z7lS+XQ=F@udxZEv{pyQy)sQOO7dlvW^|f)uvrAWbbll8D(o>cKGJb^aV9Z+klMz>{ zh`7>s8lr_prjJ?U4O)I~5RGfO_69vk2&|0gWSF6>gBLes^U!lN@S7!Nb06VrqhddS zA<rK&+c_>7K(S{?L+_hyNa_SJG3BB*2H*AqLg*GY%bk$j44bAVAb;_R(By-y@XWcA z#R4i65(W{pg6f{DTDm`eU3_Md+U+L<v)<XYr*U!hmwRx4&Q_f$b-1sW`zDJ;q#~zL zpx-WQ;xz5g=T?{YYw<xY%}#OJ+IbjF+9hZmAonT2he++M(5I+H2VX9}i`#l7TX_T! zu@<3}`|s>i|EA3q(wa-Xs6!3Q*#}qP!W%gu5o_l_P^EH@2!sk~SGqNF@{I2adWozc zH&j&68U|fKy!R7)g>47qdozhZTTSz?<9E;=GQb)#Nqp~gCqr0Y8;UAbCP5HK-NOKz z0r2KJi^|`4WnKC{(vrgJ;YW{#TA#_dgOV;5dn{A+iID2`eB|p+<6k~%Ux{s6R#CY& zV<niyO1+197y!BKsun11%97bjpMLu|LK6d}&xNau#<vG`jHM)WSK#BS$dT-L{rKaH z6pL2!SWhqhGS;s*-e$W}UtB&XuNF{^Pl+w8dhv2lkY6j<H&>4WYXA2sbGfOK#a`!@ zv3MAAu_&)sE?0@8bnA+FL{^TmfN<DuwFS*d&n#3v%m71-Nmiq#F{CXA7!1f8i&Wtz zkN@+*p#P&?pjVRQ@oR2hb=}nj+b=FB#J)BeY2cQ!<vSx0P12FPON2G`Z~H{DJ2t4v zi;LXIy#PXojWIsW)rWQV*<j8YLnJm@XbN`^eci>;1XKuttnT7{g&QM07<_n{u1y#) zTF+jEP_w$)<goTf*Sb8?!`StN#7#?K9xxDD#M`Rc;2Ga@KyoXTzw7&`f%6l@?AWd$ zHd#`pDL3hAzi9dh{4c`NQW6gaI^qdHzYs;_?$^`zGopq6zg;Ao`9Ls*K+ju*LYvQI zAcqO)Z2Fukw3bHdRUZ?yjc5>5ZSE45l&9Vgz2>w(+SV;)c=eTUI-8LIRX<)$`mWTP z+-EfhpY%{MP=FzVNG@%tXkMNz6*UvvDOIL?KPd}(IiHt1Q|@Mt=iqe;EPwBv^7)e6 zhObvljQhx24~aUrH_m=8e>diY(KCzxrNV2IPC18xY`&GZf5E(mWB|&_m|1gg-(Ouq zZm9*+aE>!lk~AnZH;{g%7IY9PND56jMUhF(eij|0#u|$TDu%<f#hRoF<K{iz53tx5 zGJtZ8>E(%q+Mqimi>g;wGuYBy?m&M^h(f$j*U0agmI`qr_J?j0(nJ}a&ZUWv#on$R zlGqnzXpjBnOjgW1E^m8+Wy@Rk1~iE!2Q&aNNl{NHl**Y?&VrT4AT_2Q4XIjz@dxsV zZSNGHpI^V4{acuOfBw!-g0_;^2t8}7ixTnn77pH;sc)Gl9hM!VW=(Th<W8#wGq_c9 z1R>B=j6npi8)`Pu<u4EQM%6IT;NkTmqqS~42X@f&(%hL87_C2Q1+$Ac+srwMgCD^c z^>elF(bU`irX2J0ErTz_3Ng1~RuOFy_$gRB4*@BpVKxVDH-Cvs;gf%07)VnKMhpP9 zHiL~%&BGR3qUE1*T$kgEnJhPq+TW%TaEE8_VC&+4DC5YxbE%{h6|!oR(sP%&X5V-~ z@;nS8cw+Pf1bh`uOsZ(%7QGYtD*($DjwIzSvv_e2OFoRsRCc*8`sE3Dn#qk*Qn&OC z6z*AC;<!{nj4@g-R~7Xty=VA|DD-$)kwSzFgu|3cUV%HbXa7_M^J2luzi4ZJG=VnB zX*|Xgxi~;_#;NStHKzD&ine}ltMUB%)B#0{)n3)~>#YN589mlZcNzSwz!)oW!w;7N z5z*&=)Hx;G4WsS<1XUJp;3H$L2#&z%o1`9&%(!wb*x|2r9>klu;pB$3Z||IwJp&zM zIY07a(J(7SzgV)D5RAJm4W?}q6g=$cS}mz}kEpq(X3Cr{_xh`!y7`F3?FP2xcCIbs z4T!`vcc`$dXjFvVV4KWUm#(Ls2==ESms{4Et+yV&1b*@1_LSUAHB79*J-YpVR~f9) zgQs4;bwm6}*w(~A3uoYFLq!M-Ir*sRbI41k_hR3AfX*T2bIb9)gXucFn{h=p&fJw} zOK^exemd|fAa05~+b?ZbF@f9Vu;K+!@~3?qK24l;hPLo+>&pTs6QbIWs)~8NFuCJR zLNZJj!#(vqU5ka_ZWi2`07MaFGu<GaJsRRP5?-K+c$D+PT?-4dnGp6V&o0qQH-%oC zXWF)RWh{F6TuMXnl@Nl<goT1B>FLuK9NykIvaz+sqZ>+k&^8HF%(x~4J80~V&JSq^ z8LLnA@GUQ7Drc|Dr=txSylxN%eO}yDiVKjlaPc8eius&;wjKEv1n`*N!avr|!yOsj z4$~_l(kF^dH&AAgb6foLMDsj39{1AdGt$?O#f+g!+c+iOgf+!Hz-?)D+V6b1Ljg1k zP~QYgvdI#`91X)1P~i?`Ro8WDP`e7{$eHvage4)j|4t@7aJlTbUPGt^$Vs-;EqVVK zLrS#Mz;b06k!7|NoO08K5dU@mu-BCv+0N^bn!cJ-tu84aCc3Iz&`ooC3T39yZ3^zc z?@}<F7Fx%=2SJ*_;_JIiF+-M9eCqGKmMupB-_My<W+_E2r|3wA8OL=WGZ{anU+z-A zms_Q;J4>Mgk~^~!p7Z2nd&sahD}V}z*|={NI~zG_s&n5uqMFEaqUFk`_M$Enzc+c7 z3Dy9mrA2=!TB&qTEX<aL*q(5oOuN3i?XH@U3OCwyoU2Roq{qkib)q$38;caS2w@KK zN3;uM@&zaFkt*=RwwNiRJYYSM)nz*IDoei@fzqojD2UMxdA!fqp%!yECJU0HIy3w& zfz{wBG#CkC@)VeoHE-zd{@V|q*C1Bpl!goIkcR~id*EG#VeBswqF2jyYQ_zXMrCh0 z+Iv5sOm^C!5N?RIPLcHQmaV^GsJA8@cXB87jk&)`JJcs{;$a!ZO}s+AF^Xb(r)b-f zkk^E@20djd7&Bxo900fI4wud}btjXvo2Q!;q?ul)P}p1%EadRj+(MvV;FB^(6b%9j zZ3+u7YXYOC0E`LSV6k9OWSLGJ+Rw{dXm>?}Gn79rsc<qQsEg?WQds;NdaQ!`H8_$E z5k8ApJd0R+8QyzASgd4VFg97e$S%M6A))M$Bjhm~urUq(J1g8MdG+(RIN^Q7*Qc{k zt2qo?=|kXH@w^M2+#IVjoRr%f&2;_r)p;`$AG#kY;mr~WzYoM)4EKGwyRXJ8T0q_A z%Vk{Ik|S&HK-nc&`J5{%aj`?Pf+xn3@D1yC)}dJ6!ll3Gs$&Va00+7_8pw#wcss9G z+~^vZ8aI52QcN_hyK3J=xbKF!N6D&Oar`IUrGK|lpgQPjT%-4l{CAcAOsei|n7o0} z^jTPo4KAA*;1LXE&=p~!q%#T`kJ;k&GO<i;jktBi0?+?*V2-?-*3qo4%{I}K{KW5) z^5Hq*-{myG=|w#@R4U<s9AwFAvIBT8Qo>-E7h*Oq>~cM3@Ml9wnJbw(Iwe*y=)qd- zUzK)622HB+7F5KHkH3mZE>+3mQLjwhEGkiUxvZFuZb9REqCf?tV<rK21egOAIBCCp zm3RJfRyCnHw$?h39{-}|7PY40g2#T8mocB;i=2DlveA{Skc2!P&s!`$!2ddd(J)`{ zh?TQK>)$xmGs)#b8BS)tK=ImhO#~}xm{;rkeYOFGN&gq$Tf&G<8=cDk2OyLQNt`YW zpZZuAaLqPf+pTzb&bGWY04Seab{b6?x;6~f_5pa`hR|%rr^-h~d)dE+Em3u@r|xt^ zxX;|Y`G#G7zf=hq5<PnArwnXacZar4Z6MS?Jb#$xwNiL>XIOfgzutC&=^AYA_<G=Y zU==7!RZYor7W*uleug<<nS!|`r%e!CxL|Sz+9c31Y=WQ!-Qe}rXa5S&d;W`o{9b$p z$D&f?9d&Jr)kx*`VMUz^4&IxBwa-bNavbCO&>klcpXa91;=14%&v>#(B*iqGjmgr4 zljg(MZjp1uWuTf)X4?@QX!Jmusd}P0!o?l{qIrSyble~i^&L!f=$Fwtf;--`jiVNn zghk-wEM(X$2XLL5(?Ttjg@co?XqDWkUJO=&Ymin`hF_9gzO+|sMzHOCEa>NO7&gY^ znK2&IXwZE;rlMJD0ef~F+=@_JMA|JZ=r`lYloncS&U`%k)?HcClItA*1{_gS|} zP~DzlS;t4DfdA6$a>10fa|4A2e&hY?M(0^*vaIx!G|QU7k*XrFjUA%wRt&Cq-&0rT z!T~9=cT$`$oeROIW6p?%pxx2!gt+8LTKNtKjhM}^zq_;}>agR7`XD0tSPOKfkbKJR zh)dp|d3PmW_3=<*nWgvrbiQN}vC)f}DVsw$u^77nfTT1!NY+y^Aw81P-x19)`|6PR zi=@D#jpNe1OQ5vc@L2l~BhQhLh?cs!t#0u&flEgIi^y!UC>mBy+!~c_gCQX`NsHu* zq9vWyCNssSzuF5M!HfWIk=-+ZmD=?Yal97ZR!18rL|-$#d+4vLUZo`STqQA)_^f5b z58O2`m@6s*A8HPVZ8lewe*fFurRIomoI(Hl+xHsNXISn<Pm7y(4fdcz3&)C3^R#Td z#=k9=OV<Y<dCs1V@u@tu<;=!{fZ%gp8G|O@Tf)2i0{LLO(lT&v25`g`l&Ck9xYW8i zTFW`-CiK@m=9MdUvH*cqFwZ2*7gy9yn)Z!=QmHc8ALHphG~NU*i^&DY+`;?zNtv-? z$AUbeLnDwB0%S#2%H_M5PToin*`amq*DR*LhO45ohSH&ccD%Ir>*<<$?tIp6FJy{c zbdqYC7!@+DKMxG_J7~q9w;5dX&{qKCuLgb~Vpo6V$#jaZLWFH@K4%`(EULKy^TK=q zo)MWHO0MXF3I<lO=a7U%>lxwq7@?yozLj;1{Im%ZY&*)YbtLCQ^sp>@2%q0$^o~bz z&H4~^M9T9+hf}Ya3j=P>*5f^a?xQ|Kl!sot%<b*_Xu@KV3qF+ocvl2${DCgsjgvT6 zE3zD{ONdH3612ZX@%$y9$mkxTZnoxKHWH%H!4%iG-q0~%`i#>dU5P4)C-Dgao;hR- z0epvw<J&plzFv>ZM~WOOY%9*_fuf+k$31Tb{yyzm*)+Z33KR-qNLI_h8|QcB@w>4< zz7@jEYigMa;h#NNexEaYHfIKXnZY#>&r{~yVCVZO#+S|JJyhs!E2`D#k1x6AGv>~Z zu9)X(Kh!v%=D)BMEo2PO3I9>%_5=n>SI838zCe~nTHis2(FRV^{eL(-rLf!gor+~q zul=$wb;cC>0-xWXF%F%E=QVr;_yoqyqxE8EV6ciZMGu({R#zFxEGkTVH3j-h@U0Tw z@Ct?NACJ4cI)IISm>qJ)>ZK5XMg0nBoX(v)&KYfHCvg(oE{$4f^l2Mzm-b=IsIQct zo~01iQ8u0;2l2_TL=hi3O588r6V5YHKp#8Bw>^a=GQ&!_rFla8%hh!p$a-HR1VuPT z&uA=jVvK;ihj<@J$Zm#3FzUkLz<g{b)W^mxlKoTPUk^`U=-e`Xa_b@XMX*x*+20pY zhh<GX(<)rJ9aK7)Y6s((2hVd<#p_)$o+B5vTwJ?M^At0ZwhMAU2NLK4TfHv61xvqO z<TF2VBT}2BZ*R1k(aRXNJ8G*GTI$RIlfB#l^WD@AtvdB0Tq;-@9(XMT4MomW#K<|) zO28r_8`DNx`VK*cHAC>B%w~)4cNbT_#PYA^A(=^T(fDjQ-2AQ~Fgx28vI=c1H~LPF z+8|5+NV4O`*jYr77&Wb2lJG*p1>C--f>Q*|-216nI@!9x>eQQ!>oz5Y)pm@D{8cvB zCtneDZsBVgugObQ3zg0LG%rt5Ln;1o6a(25z8GGPH5V~4Y|U5@4EN`V38UV3K-S11 zrzeH#_KSxLF6*uVvTnLWUjrN}?m2!>XCLmQEy~OkjRS0|hC`Jnohhyw>3peq;H?jK zALoGR{+_sHISroa0jV(#`L$iqQ)wP&B9CG%wK?}^?kw4e;KAuh>ce}rz8!=b2VT6b zDJ)=)S?Ihn<#Xn%@nQiO#9qqVOBk&8!wBXPC=0R_C3CMqIr7C)WYUpLG4l)fiQ%3L z3j$xZGsD|8^p3h=Ec%ShM<7E;n;Y^mmhsGQEN;DP?H+?mGMs=c(LN7nE<5&AaE6{H zNskR(HOh_pm2IjPjglbF=P|q!x3)}%W);Zt31H3DfdH9;ZoP%2N<ICvP{uR6Rb}LD zXe4FxjBLhH|L|fI@sdkbV^@+<x!?DgI56b*%H6TLmuG(tK+a_;<QAXuqz>F1E++qm z|NJkkF?4n3$~YDf(1Rcl5W)YAWHYm{FtD;Wclb{%TdR(aE$*5Zf3wDobGk=jmli%v zS*NP(q!KQf(t!@`R^s9OIb$2H_M~$sONlrSPjgmg>UfIl7Nf6~QUSDfiR31#T_XQe z9E8xXr$UF`9#qPxzUNZG-H+9DezfzSuOF`FZq%jK5pmRT7K>Rfmy^FgKVNI_V?Pxd zKK^$M4sEI58s)p`=Nz3TRL9h<ViGc)Tq}*sX=bx7)-+?MUMmyT1qE#|lS6JoZc!Ig zoHSMPQs8E-YH2)VE18NyVs>grT{YZlXtGtcQk{8<xmhq5*46ZDXe*h@gDsm`>Vq+x zSxSR7n^|guIh$E3gFTyB8iPTb+KPi%t#0Dr(bhIf;_7PUML}e(t)gqmlQb22*0q%m zlx{W48f~-G?R7oe?eb=|ZpZR8^+UBRT9;hMvj@hPJ<g|ZM?ub~??*+>7;i_=$9en7 zGLw2o$rPy;G#*mE!7o=-$9c!2Q<HpS6a<6l_UyAJ>AQo2GM~MyQ9-7?cy8Ub^Lno@ zFIj#aIBM1Pqxv+@S83NDQrMq7U(4}Bsl(#wY_5ekjcfA7Zv$nC?mRFm46-Oc6i*Jt zLZYfxnF#fh(~AKBG_IK?qKKEHqKK6}A!n^((3#iy=q2;|)Scv2XzrdH$Q_-t@MzaK zgkJR=&zW_f`SN4e#-Ns<4ef4y7F)O8mOQtjcVutqyu91&Fez)!yWRmi2){EjtJFFJ z*rm5UnM8uJb6UNRN(>IZ7B(MCSx-f5HV-Q?&soFccx|C@^rwd0QDBBmTkFwF%fGnj z_acAPrgx*bKBbP4fg@c-S&7${tm{kK9t^b)?s{?8zw{AKho#mQxQpu?(BLgn;4D($ zEo1|l2XKdfshz-qkFMn?vE&HxdgdvVrT7FYl%@J4DwwByg5^(Bzar;PQ&}`O#vJ>j zx_<OON+~DKXl_}N?Z8gM=|7<3LFRzbTfY|)+~hI`-jcZkp51l62z!mnmFD8yub=WP zD3k>3ecZ8qcC48}xm#XVlfw70l?E+f4z-*fXz>i3^mxv1Ef=@S!hJ8vXDqW%8g{n} zm!SF5W$MRWIwoAa5m+~*HZNYT!rJ@V?G1cxIu&?dBW?1v`ONaF@+``4A?teH<(tIE zX7bivJP>Ui`Z3<@1X?RGM%&Mz;}uxsNQTbtIb4!xTzjNG^B%_YAN+1Fd%Lq!%!;mB z?a9-dq5n4EJ?S~Tfj0-*xsEy@B-uHJc)luDmYK;rpO8Ap!<>{r-Hl33<fIU-b5>^X ztL50T-$lR^94s0t(d==<^vafKc2PWsBAL0M(4H9fW5Qc%WcR#Qp2U$~8?kJO$eobi zLN=T|s|)T$?DIG+-w&1j6V-hte2^30f`=^_whvwo6TP#F?`vsz5F%fKQGI=}{d|<y z8I)?(Aqc)!L2Or>KRoXMi(udTU$le#tIM)n2<2q-K-*JQJ0FzC`hsMn!Am*LUnCK( zDob#g;hiiOmfkG<@VZg}kGuV)s=91B^h4kdM<x4p{K4dA0V2x?40QTX*RxWW&n_kD z@x@0T>jE4e%_&%W7st_%)j|prra#bW>mKzA?}4`k)D@_3!`h~oV;16{LBzZJ28LbT z6Um~U=bw@Ph@I&5=qE}?^;qa|9?R9n%2M1IfWB|4n>KBxg~uDqLF|q)`cmqzb$zl- zEGP6+yS1;TMtJSqUsV)O8U4LbhMX&Z{_Q3cDjM-RuNf@(Ctq<vjktu?RvJ&Mz%qV1 z-)ET>z6#mpv-u+9)Mi!HQtFi}0ViJJ^f@_hLsnb39h^)dq4D*Rx=R-C{2=B5<CzZ^ zW4Z^Hmw_o-)~&y!h{|gg`DKV%fi9bmw>s-|`rV81kmwNb6&1B(IQqnJ*7-L&W8Y6+ z>~aH_Yvs3aY5LPi0P6BXNf=C4lb8M~XjmwiEvaG8@lhy7TJjNg?hXt=5@jdJ#RSCI zhEmSHjkBP&#ZOpoP7NIe70U~kBWMH3l1NO74SYkL3j3s=r?&YSAA^~xbK3l^6>gsB zDb@ZD-yEClc@CR1(mW}`>P*^LcWuFKFZ!5L4n0unIk_AGsRIl89lU;Svt>!snze_v zkA5;L*_K*M7;3{WGTN|fzZf3PKn(J)44wz<OL22AEXLNiBYxT(7EG@>8;>jsreF0^ z^IOCnwvDkC0~kw#hQ&tqC_I4bb5BUPY@w$JIBvLE_kchTZSlm=G`pE!lBmP{l5e5j zH|vDPVS^O7fg5tNKCws#HEecrrvXR`$7Pr_^hXvoS<i{O+uAKBwNtAxS=6(s)~hVb z+!n3(VQ+Mpq*7;&k`FDUJvD@N0Y=FEypfS2#-mW66LW#h#Tb<q_?|#o?dL@W)(ct} z8esDsX?ef^qj5x0u%Q`cphtY2^uHON&+f9~)xGf4c7Tj^cFk`1Rgd0*;;rwxYd4>B zp;qfl|91BoOo2uKrS9S9TvDOfnv-Y^rgz6k7{*aW>iX7J{2e2E7*6%p)@AwJD9Z*Z zEvticaKUVQ`|~nInQc1=@tHpR!b@9?W}cD0nVZkoFiV)l^N{TYI-fJ$h1t?GU_d5m zpYQ%9GBU|x;=7Sx`*G{l5*+$!Q=&HGS}Bj>+^24Pvruo~X~S0OPxl(kIeJ+$PD|xh zH&SLvPmvxbO7$E9`!?SON$ls&h2dOMIo6P8azu0^vH1yvT+mFhPSZNPQ!o&A@RtWa z#D>?-nc?|_=KfKP;C?P9SJ-O{C$UTXO{=m6SF&IPH}_r97<mZn#$<5^S4*0REIhPY zYE!G|f%_=6*0V0t8hs9GGXtgidLJ7#q4DZdUBXkt??lT45FTnuWNPJu@ER~8BR?h; zof2UV9NUGj#1DcI$Rkjv@pGblvYYT~cbjxvQRfgq1wmV;-eRDnoe4|kqAv*7e6v~d zt&K+{ICMKx_id63v;vUcg3B0yb{*Hbx;e9gA_PnZ>mVJgHx^T9S|~RSoPprlmQ|W0 z#R3S@d}%Vf#o0c_`{}Nz5Iny%m=env`jicK0Aco0n&-iU#XDES@~PfpRm*Cp3i)Go zq=oH-4(0O#+8Cg|l9Fd89o(`?<@rWMsVvlkC^trmg1WH_zkyCW?S%r_Kq!L;i%S$u z;J)sgSgWIc*le4d&HB;K1dm_p%+jKksgh>5<n^3^M1#JHd_7IB^N2Hjh5(0ap=QMc z(iW{W!>HXs(LcPt8lNzDYm$Xqt)<V?#`37|S7O>|{yvsQ#8jIfv-1Vd*fhmqzvHWg zlR`Q|-_1ET$vr93V+FS<6CwPLGFgB2UUILgcraMi<$J&%7yuM%Uk}1mkZWOvm;Axa z;%XB^U>ndBJ-L|C%PgZx%S0tW>cI^aL$WLF`=AKoPobsox+K2MsMroF5;Mb01V8J} z*Hkqe9!hkw93u#+G<A%^e#U&|v3Jc0#mqF-P%C{Bx0RwP#Z0=1a1)HHAD_=4bCSl0 ziL)HcB{kF+pNXFF!dU(fDl)p%{N5aL-`qKkH#Pso6Xm->BJ&8QGN}7IDGMHL__uVX z3>26ydzAMhKo0J`p&WrrKSn9$D;n^avd%(s8v(UR#o_@yCp#ci2HiB9cF&oER)Z>| zuYezh%kr^^v7_1DdjGNYrwg4yMl}UMZ!=|}bwl3`pT_%=$$<IxYbem%Hdh!s9DsUd z9!+rVK?Wz>H%3nn@zMlZ;&KzGVrmro*HEwxS!kB_i(iD@d8Mk749U3TPjZ;84wndf z?5Zrn<}_<EQ`dC$7ln&30WK`@Vsa;s*Z8iI5?*SCqL^F%wEjunkl5iMMJR|Ey3h4i znkPb<7P6wKWb`j5-f-I^X0RMfU)I4>wX_WYbVPFk+a{7hO3ya5?x!1=9#a>{Zfu?| zXBCLX_(~c+$F07qL<oeM;-#ZAW6<{;-<!s>5SmVd1=GJkhUeR1lACibmttMvl#V+* z+s%!qh6I04elJM>hVSA~ecAWmP3FnjWinsF4|qPArxVdsEU{Uf#dt^TSpI?7`EMP{ zU$_t7!JO6Q&O(hW;q+_|f!eq-wXPC`axQj7jaS%%K-t3sUDq)Aa?kU{f%><xG_igH z+1NgEI;99`0sO>3m?S(I2^Q+#N%a8*EVQ}tN-65#R@L_xbYivb=QF=fD3@lMxiOnJ zfC!~68G)@|4);Q*Vqg2c-)|%|7$~mVk#PWy&PWucJ|4P%n20A|5RKpYHw*>_=lWW9 z;eR_aO;yenwT^c2zHBb&OY#@ln4GEcO_TF<Y)K24P~i2ip>z`l{!;(PyYcr$;4z-8 zj&*@BG>IpWtG>h%(aSy*8tXK_6L{%b5SjC`0h{bJxN6n45V1<mPm#(YkN@qwNw&Tk zwe`C0xkbWJI~K8JcYVpIbH-ftxH+Useg^J0iG|2yPT1w05<~8pxD3ZFJvy2^0Mt;q zh7>anRK;YY7?GbDsu3+*tVt_lUB=RbFlK3>%KZb{OzX6xJ~}+ilX$2A+UfH66~BG_ zb@gy0B#J;RM^^ux;3Bqoy{Tt0OAD-Exd>+h7~*05AYh!4iw%uHo~F^PHv6d5Ntdit zo1o>f>CK#~epJ_2t8|0#aKWgNvYFg0s;07PJb|QUVA(NLE*o`5X`X3q5iQBwY=Wq& z)G`KFLzgvC3l-cB!OrN1s_WYi)sM;eKH0kEtnX`sE(VlgJbCnzn#BjfZx?ps6qU%Y zqvFzM8Pg{=&e&HUju=<T!nN|;W~0l-VXi4^TDW_Hm?SnQxOSTqui9aM<xjq$aSgjt zj~b2^GqW7(Ok(D?tjKI`Hl&=9gNZRj5e?oHwUNNfVRjtpOYsma$Se<6MMw%x+6OK# zB=PGlp2(27sL*g<5^-du3JIbZH!@*|xHd5GGZMaw49tk9cynCUCn#C8e>%w?cv*+N z=))2vq_(1Q<{vFOf<3XQ#l`VH1P5#vNGSbj+)|1W0`@8jp?xviG2WEjddBw_TJG-A zul1w4`-KykX_+||S&UC-l&+6^4W{qWI|+>o9g#Q1d6DJ)M|H+fvSwFiFL*l97>Kyt z)Aq_KSNuoREHjmRqX6T)T{WZqqBD!Eh$X4n)i6Dl&x{I@o6h0fk@yf$MrYQy|A&m^ z;D^SI$|d%MA=j()`7m7CU{baGh!GDnjet3nDjEKmDVGJ}?E96~++>GPCE4V8hWrv> z-i*`v1(bg9Kykf(I?mXw@HHGQSEA`0JglWpGrc)a_4G1aFLH26)o{bY*%Jdm;rxvc z3C6q5VB((<sH_Y=&j6=0odYUQ0NHIa(Hw>-txlCsp`!d?_@*<Fe9}~fk~%S2I%#cJ zs9c>w{XVIBENs@wyzi(edHxSnN^ck-8;{DUsY{$75eWpwF&JHJ34r)UIc<;Vxn}pu zio^>Y3<P7Aa?fk^5uyoI69YN&=3@{QoDQSNF{PT7l_0*9b)@oyAIL?nr!Th+9#0!J z=ENHXUv_!{AJmJhLX?<GRZqu(-l?aroNF>d(?-J4kr%2={?2+-w2CfW0W2yUF^oT4 zIG;8yJZK2X*ihzkiMfyUkO}2F?A=XCW9+eJ+b`R*dyRWy!O$|9S?#7{QlI{Iq)z^Q zU(N)*084R|eHhZqr8ln38cIv1H!eJjCQofh$39O~Z1CIcaP_j@&d)1%_^WXftf#n+ zd0d{>C5eUNecu^0=2VUqd3QM@u_1Od`m<0K)vOJ+BV&drE`~$ybB@pzg4JttaoipT zxT(EuTF0eB-^_^L@8b;vw6o7RcJyAH{l^0}yK$_H-IOq7G~ik;GhxbcXMK`Z3mg>2 zf<%NSvxnwzEW0pygY%z;=t+#Pn-adrtx13o&!y=xx_tbZfzs|uI_)2X1ss-NjRq=1 zMbZqOGnB1<4ZHxldBDNOoNg&Bas9>)1hX`bG^%t}7I&a*D_ptsA9^9cPm#-}V3&BQ z-kc6OWLXM$k3l!BYaSJL%D6c`g(=w=`sS#`0|e#W>*WOYAkEQ{wEi*I&uBi`_M{V% z<|26772RD@h8v(@;^9(8UQ~n5wUK#j_N|=R6EhJMp-)uo4sOPIIl83Th|{|+^Rc~( zK!wHZcP>6q`EO<4<YHJ4mt5P}H53{{L$X}7s+R1A<&@UsWhmIei&H<~s*QDIkz-dH z{6H?n!kpaOlv5)~t>AfAXe8=1B&C&>Nn<Hw7fI;(so$-@K1UNK0seMv`^1mn5T9(c zN4!1GD&Hv1ed={NO~r-HYpcoeiY{CBshF7~S7wjphJq@b5Gj6udWlN?Cvm%ipo>E^ z_2yu}!gCZlzaaZ6_L`09%SOChsF5E(`CG*d_eq2;D{mfLm?Aq$E2ODLL{quP1P;k* z!)?<#(_1~jHX=E55aQOF#8YF9=QrtMl89D<XJ!NlVTuL(G1+kGfpi@*NkaSOEr)qi z>{o2ek0BLjzm?`x;OD+<rqhm}G{o$Lr(2jamT(qjVr8Raws$wyPm5ceapH0`KxjKd zG4;K7h6&oMV%OGVO#O4P-g|12c+>IkNv&12Egj=uIm7}6k`IQ;La0Hfv_!`9RuYt| z`_5%0XC*~;(V%1w=Ref<z(lQJfM&mN-Qspp|1?+JtzXDKje}`W{XLI-rF>Okj~6HV z)wlNeJ3=YWscH%NtR@ceaJKB$>)=0pX3o-VB6)tl98aK9EEYXKi%a&Yi>tg!P}SR* z?IkyB^W=GaEl|S~&auGu$BEJq4vY5Nt)6%ajAE@g<pfS6yj}h=Px00VhQ_ZVduw9q zpXq{0hn{!U57}dlptjOpE@V2D<9sW*-_=8<ubuo)4kt-%-6|B4vaS~1xMJaBXyB-A zhfJmKPnn`Chs>Xj#^EKf)&*Xr1e{7BE@I)ad`40(lZ$K{i==xXeHm<hpcD&A=>Euf z;-_>Girb>FxJsohQOawQd{kO;o}!}z<5yplFiX@KJ;|6_kR)H50gzA557m_B!wgzw z?RyyIuIAZCax>u{58-<CsL-)ee*M;fH+>!#<hV*tnq0^?kGzx^mYops?sNmmtg5GT zOeRgNR=zrSwm)nz?3zHmElnn`nsQ4p-6NbC(U&Z@Pf}CyE&?o8^rgTxQ@thjfZm?1 z{nba=WsO*xRP-+r1UA0?jSN|#GlAkPd85Z>e3;eH2j)E$gc1VYNC<pjB#T>8xS^YB z<mu@>{|8>%M>#blmtuaFFhI$CgEnY^1V(rGddhhc$?(K7Yw|tX$$2z?;mp(Uy2u&? z{kAA|j^PO1`QPK!8Yd9fi2yS2Er$vuff{8EI~FH`C^)NstDY05oqeans9q8?xcQSt zSvFl7_!m}mF!<J7t$}~lhdeQRZ5<LLK?|vd)b42Qux_?6V>epz?;;keZ8xctd`G<| z&8l&HS&P$uTF$Yw)$l9{HZ7HYTb4~J;^mFsd?=zJs$##U06}j$la|XQFL0zg2vn0U zS}d1*e|MV+Jw6?*HHK1nU2eWlwrwut<xis!xxf(7ba1m8O3D{PS5|}PDz}J-jVTkO zLaD~waeQzxi_jDgp&VO3zMY-hyJ&^__UmIgKN+^T5+kt=@gd~`e<=QCwH+j`X1Q^U zO2n%eMIpG}|C+*j2-zh`Bs5u(uHJV-%&Uk<qD|quFB%Zo?Z$d-X{s|_#4U92OYRIP zc<#`T)Xm|U<_e4nCvJ3kzpEXm!!A2JAx~EzliC=p!Q8nVPo+ERETh&Wq((9a-K6#( zrdT}1dRu|CU|0Pj6I4LFn_{n37gd~=uRS3nHN|D5{jb?{H)o6vh9gs;cY=nLwK=2- zUwS;*@G2{Bu43cKgPo<k+5A|v);J)Q3X!!M*B-Gl(BQ?=QW_aatt4f5>0`izoguc5 zp}`pcf*8bo?#!VI?Qx5iKs1f{c~I7<&gZ1|h6{j9(ymk52==Dk_anfH*P~-WAL#^> z(L>@kD9Y0<d==KCWlSMx?OX5w77UFjjq)Oq3R1CgNynt1as}pw{h0s(b3d%?ULsb< z(hSp4@dC8M$3N>SJG+Z#xA4Zp(MPpwwWTTvZ@VjwniTa$oX5f)`g&1|$Dk?H2J`0O z{n>0wJATO`0zl{d!7X7Yy}+!nzb>irEi5p7^p_!Kk<#0v1yY(;NCtaMDsiZxb7B5c z$;u;6-ThYCc7N=;In8hzNeHG@r5hNSsL<vGzQNwCR;xS$>A6qOYx{k^fvI|6);=v! zu&ym&6hN`1^@p^{Z8!j(|BVLs4VL{~71W@}IWWvo5+nTIU=YD&C<)2wUoNi!HtWOL zW8Xn}zZpPvsxV5INu1hsar~JUXF^q-<`V=6A*-(Y1)D`;=Lq}^C!GtG{s$*bGq>)Y zi@o@t>{!|Qhpb_5rkh~R3}N7_N2;m$J=9XlS{kq90(L}D7cgP2$+WZuAoEoAd_+hG z@1?;S!MW5}HLip1O4jxAE?||HY|l`-nr`TaZ96|WL@y6!?@0$D$-(@>Q#j-L;T1>b zM6`TDj3uaq!7bfOnrL!cuy&lhTWb<~r0#5>$VP3=H4f=GVJUJ$H25VYX1z)YeqbRn zYEBUPn7)BaYCL7eh!U5BU}9r5Z(r1atC5b_Fi}Z3C1I`bu0ru05+wkXM0`|*ghFqZ z%8<;-KDP+zuZ_we>jfz`G;45p$HDoR4<Sbn{DkW#1OUoro}V}P-JC?^mk8QCu9^N| zv5}jxAi&|w(mC>@oul)+u}LwrQdV^`)tbzJM#KCY=f64i|LNt4#yQ1Yf&>Ekiv$Ej z@qdRvR`xEgMz*#F|04|2oN>SvL-$|dTY5C&VJB?_w=ID%;tjsS`lqkWY?va~wqoFF zAtU~0{_f~D*OgW9D6i&jRQfF_K4ACL)?1g>4{R0hv*CNI=HYWdC_g%pa{0LO`L=S~ zdoS?Qyzp~u@bj$$wxWP2;6E78zCQeBFaSb`#E3*_c{MN;I2;;jGe%FVozP;m7&aUn zX<?z$a5hi^s@4yiY`=XwSOV#UQxcFFupUeRL=W7T^<?#KIX@V^@^fcF*kED#MyNwy zZe>ehZ=_Q8&Z-@<M9i%=cQjDwg^^8~olQ?w7uCQ@?Pb~~sa-Y0DkaR7A5NWX7Tf50 zRBw8<wk}DCqcjl-sD-`9o?f^^KM$2I3awyw>yfr&ZUEr5)J@^B){fz|l+ER`LB&B_ zx=ul5_v`5WwYrE`%m-Z@lW;RLZ94dqZx-qxU#f5-cdA@(Q0X7geS_mHRO3+-yF!%w zzJh-x-V)4zlmh8`9Ts~88<23#V=Tbmq;I3dAycZQ<AfU3)>o!Rm%I_sGZOm^lAWwf zcK=4Iz8Qm@nq~ocai}1GU(9DhCzqK`EAzzJq=aMO@k1%VQU7Q+Sz%Swmu!@VlUnMX zOi$P<*nowa?`}8xI>1gjN(ynX2rOhGgxQ1YNHoA%pgW3Xk5;hx$J=qE=$q`&;dE$! z1A(UmwhXcg(K^<w9snB-wzLQ_XZs7x(sQb7mc+mJs75pw3``k9->$gKV;L+%ueRRn z?ZZ=WHM{%D2_?;n)`B|K=^95r^AKjXY3ZQBxuFo~G}=p3GB;I>w3TR`clZqTqNHRg zu)WHVTW`~IX)lwO^}3+3&`v#!D3xUfYP|d;g=g2Cy0xvT$13pS4s=F3IsIQT$WW+# zhfocZ&ZO_fw2Dm6=TNZdRnMoy9W7ACfhneKxa@9Nr-)>=G4{e^f2H8V4NVoQ2u2A$ zO%?VEuFi}gu)=&xqxo`!FXx3?5D6QLzbZOfxFny$!kZ@P<x0%A&#YEEgDJ_*{}lP0 zt@i0$*bj1~1_c`jYsNbN)P5m3qP8u&RS>dG3L&-)>iYm@h<yjOyMq%kn%Qg^!a0*q z<@}GuE8qBo3-*<DQHGvf@GCZ6$&zP9m|=rlxPyvIc-r{_b!>q-E@f<^9+<sLf_-8k zRSDdV^?-92;e1UZZ?cjVsX{tcKH1`_=9FrBC>+j%iK|!zrA+a-#vkKC;fy88GUZ1c zQ`@E{4g}FP?;{0Lr|iadBJTsiKPX$q3Qr?=q6cwH4b2ru>sG%sADLT$nR>3>exU5u zsF^GAZ$8%|)+!^?V-`hh{XoLX0|){MAP45)n5;7u7`9>bT%VMVRKux4z+k`N*)0f= zBnj|u0ih}zvaU3Q{_u$1tm}j44t(RA>RFzffnzTSzl9lS@8Fv|N4(uwzN;K-rLGhG z(&E^dR)ZPhM{`)l`eQB0Pc-5iXqU>xOu35lX<R08C!LH8<sWs4?{cwk8hNQsWdq>A z^+f;jtd5#5gih9vJcbExG%lvgXvI{@D1d9@-3@O+4bVC1XlkEK893beKjV(V4`6@U zi?{CSr8o;7jDzmkzF_HYtATtwfd0scql+`w2ge6igCL3yV}91-1<itsfDgV&g%-1u zdBKteehUtfBD-fH7ec-ZIF`<h>1Op=4r+;~^YP{Z#Iill#j+p#r(YGh_K`FhxZzsZ zgPk#+A1q~guawSD55>29g2&N4SZLZa;v3u6NvqqWYRfV1GEV3a%Zt3}_(o}guL)N& z01};C$3eAKD0G@!SONk@gz>DczT}4@{*j@kS0<cgqo|<1brMsw^eC12SLkD(-}a5S z4B@`?<<FRiRc3i;qhqn3mB0J)&qV}YZ$C5fm68aQf-I<rk^nUYAzy=ztgy+nS>zuR zdFtZC&o_l<uO5&UmkpTsAOEa84ZQrGQpSD#7-6b6p+rN*4xFSTx1Uz#XS6zwrSDL+ zgPRuG<mLe$v?qWd*V?p8sx+Z0#5DfZX@$6OS_>{1CJs^8g(%FP+!Sa)ukRnvGel<} zk0|0Qm-li0Ga>#zcp1i3$Xal%a_%XM<3vOjsCcU*@6tnu63G;2c`PQ$L`Y(SJ=m;n z?0m4<ca|ypZqvALDaaFiX}|u|QXP90R?%91%_S=(S#h1MGNejD6auiP6>aEmbZ3jg zfLRWaxM#jcmE&kQZ4Trp(hM<5aT7VwqtrAYH#NPUjbJM);<*wc&goZ8apGupoOt)$ zIdV0kzg%qPGk?wY)w}^W%k6+LjZMD1!OjvQECknXIeM~}WM0|**2+nA6zW8y`7Q3F z^Y<yw59;84iDSRfN&|YN3Bgw`fI2yWIz9+7fI;l10Z>sEr(tbf$CCAN0E3#ZXnC_* zIMGO6YDrNg5BB!`ukEpykR<?^DSz7&>B7sh9!Bw)f6N{VMJNl|!p!WGgRB2N28S8d z|A>~{Kf}ByOy4k+pkju(Nf8A=Ks=-!`o^Y^z(b3wc6l+WG*i;J1jfj7P=3T`^I29r zF{Ew8(&+1yf^4ngEjb7G8FJxmm-zYU)miUb>*m<Q&a4g)Hx`7+$W1>HU)d#kQ$WbE zkgErQov}0rqW8~ax@xac*^!;dLVFjHJ;L-gFMi-UFSQENKWOt@dl&ehbAhiP?KuM+ z5YPbT|EsHYbF_6ZGW{=OAEurPjzp6OI0!WKaC_*Wz6pvcMbPjlr`SRF6nKM_ts`AY z&e?%7`ZZy#)-^p3$yP~8I_IlH-9_Gm=k2R^{i~+{k=w1uHea{!%W;*no4Doj(h|$k zlED(6|7T~$kJ8td5ol7s)!%P~{)hba4j?vLct<%-w!Me~xSXs#i-I)Z;13Z;Zm@60 z<uEsYO!?-$ctJa`m`AL<oX{nuI~T>Nz<bsX1QBAyxyN6#!T*e6V)Ug@vW$J?M^HI& zLUwS-9YC$ZFc^jEvinXIvE_GQ%jC)(V6Dn93c_~(EHMS_@HdnZa5;qJkOCk*5N~Dd zB7pEz-rR2<?p_Kt39mj~n~>`^ln$HRaYQ_h{9PM~KFer9DVf%g)?8%m>MY}xq})T( zB(()j8fWZsc@<6Smb@H+jqc8qFW4Vyh?|m%&eB07TmCf_Hsg%9$ei@R8}o*Hz=>G- z_0G127T6QNuN?BlD{DF<2%A*{zg!Y1HKJNnm*{gL?uq=bED(%iX3!a;MY0Q|(goJS zH1KvwX5rATL%5hAo<Tu`Kggh74Tv<&EgQ=DNSEudId6ZjU8bfa7nG?twGHBDNgU|7 zHEJ0(VGqe)k1^xMh+#_0hu;43Pm!l-SZ%Mj520Kd&wm8d$mhh>x7DD%%c4gHs=qa1 z!(xR7qCW7|j*ffG)+Wc@>YPWE4%3+B4jXMH5&IDtvxz46nh$(Rd6AuKQ{*v_GUew~ zk@OZ=u@#q16GfgDp?OjpEt#+r@Ol}RdXi$$&-7_l3#B}<NiDU^pf@DD0blqINCGFb ziU~p_NPvV%#e>ECa?~UuS=T6Wj?bE;)Pi8^@WAD?8_XR~d@#f8rv3^0tw!DAO^wao zp*NO3M6P2xcoiO~PsW$dE|8Xar$F7q!1jR8K882vu@*n!zxtcutf$I5o4}zi+S~;% z{Z^D3&bKq~ZLBMeCUX$g?w9AJ%kNtsB}9^AB9ZDA+dy;<=PyLqL<Ig6n0u4p&>&(c zhG3xt;LrxJFym-{y8%Q9Fo+kHJ@`NlS!XfZH^kV<APx|3ILOH}oO-!4tb~|Y;dBh> zpBjw0#7jc!8#cO3NCw1OI3GE5_SVO{IZ9h%F+?@XAdWQJAsSRdYLbvMVlkqU-?eCZ zhU}51f9aBJrI~jqGCiYBNy#z;nz;a+I*c)U#(<<SY0%FG=tQ}zDK=XIj}qeI)+#l- zCZia`-JFFaomp6;)=-oJf(CG2Ue6wq3Dwnc|HH7JkUNbl@}oO+aT<pCzBXdJ%}H{C zcByiArj<H(05ysRxm5%X`yiI>htNyFj4?$VKr<0GG|8k4O5f87lktzU>6dB_i$`Ly zHXJWvZ@^)RXQ+%6y9EW*ko^3we~2Rv&igEd98L0lLiD&PIOiNY7`H)=t&5l08w&$I z?y4;w1q6iGID{*QbqqUflhp$VhxNVC-NfV+#~WzzRUr(maxpI}lhtudF_%qE*0NYB z*A%3`sQ1YnlM}DlejC1L5rE21T%im8GmZs@j+tsihSBzXIzT(t0|M)nei$UP>6T@< zo-3{_{H*<;3Oil0oK0$Qgjo48r6rqU2aE`bc9^5_E=pr+POI?mM&StVmpC3*aRi-^ z3YTB4=S@l`UsGX?yecyOAtSSwR8dO{T-fO)ZsJ;geFXz=ajL@7@jQd{waFHAsIf^( zA<)G_xC?4Y3deu9_Wd%vYf#Ah!j-H&Z(leEiUR=PxH3GR&>rEOEpUKO+(B02?D4PG zLf@Raa9Lzv#vUX2B^-zmr`VzY;OiZjL<zSw&9ZIVw!O=?&0V%_+qP}nwr$()eeOg@ z-<jw;5gGXl65orp9&|(@dMW=BcA<#@yZf!6J5{VXhM;|%9WJ?sVY}l4U%>hi9NBzc z&B7#DeZ0DGN&wxT%yDHRAlHUndIw*q&#_~Mth6L;tA!Hgx4>?VHRVH=AZY^x;tS5T zEBiF()AV{+o&^k0Y8(>FNkMve-l%*|2(!3xDG=w!CXRa77crDSpzwjvN$!AL;{(3j z66hv=q3tlaWEXkYJ18lg5Rc*Vh(w|q6>a#_+5vK$KDvOckUJ>Uz{q8l403Z(ISf+B zC!T3-nsa~pbpmY=KiwRrG*S^W09e6ya4ai9YU64Z?oP@(zpu>R(6%j+Je2b8>Xe3% zfn*5w+`$Hj666FI37}r)dl8mj8gqBD0v0fW?GW9&Whq|4l1@DqVbJoV9U0Zg8`Hp= z<D`YGT0wS943lhWZrZ5lvX@+SnYeg4K6V7e=>L2LPktTN98_x>3`@V5Z5bCd-b#P) z@oKT=k~NZpt#+^9(vSrZA=3MMMkf8aLu~<aM&*f|+Ld4J>r9E-+p=w(%ltRp_H>fR z4&N;`NBzfDmmFeS>Ww?1*Mvft0<u|}arVrR_l~cTJG$+1Z`<#NCejozfR*>BfA4Lg z?~Q~0P!+KJ#Ft_HTvYIJwG-wP_l(Z(6)$^);4kVH>)8zB?NY5@C)`b_F|8wTTdcU? z1zGtCEBL8@{pK9)(`V}kb#E?$(Xlgj$P)OTO8Z+!%&?lR!sidtrFVQZsD}2T355r? z-XhW^%@gSvo&PIgo9o+L<+-veF=pONVe1pZ)>-2Aw+K@=di++%9o0<-<PC3{yMXeQ zHN4`~pij#KBYBq>xe=Bux>NH7)G>=@R-<@_Lj{}}s){rPR*YV;@*4AEW`FeTB}Uyd zuJ;rr<Sr7<$0f#XJ4F7afQEse2K4C=lr6$O=K1iSRB;_Wpsa5zPS~EZusvc{!BknC z3emIG#mavhl4eH3c|<NUspQl2pKr;W@gOsANPC{^`YJnhmBd;5jB%Qeg>xk)7F0<X zGj5gIvR@b{_2Y_s85Qp(zp6MJ`dI-Y8e|t7mBFb2>F{vRS!wuYQ@RERaK1e6?(QbH z>09u5*Z8_zT@Pn&(DnE>y#L;Ab#}JfV`q9|yV~q-#}yUxoFr5wR^W{0$}L>J{yaoz zpJa&a5H-v;V^pMF*t-WDtP}NYs;nx^kgNK_)uzlk0@8-}61BQZ)S`!GAGVaD6z5WF zx9yjo7b!b7;6cVoZ$KK8M=-<=2@A7n7F?@KN1SiPODhVUgrN}8E`XwC>K+YQc>C2F zO%dwQIN#Qa^XYRz%dHO`B^G^ZfJbhveeUG{arZ4IR!Z?2leiU8(bR}%FHcE!OcJ^b zcpMV6Z~rD-5nKLDU`pjS52<oANr?CcBnj5Q2=6P|8Y~&UVj@x5uP4^{c!3>|COKzH z`Bz{(b75#*I4-!Q;39Hmc&={Tk0H$-a=Xr7a@0IfF)a8aku#D`f8E^PKb{4Fl}}BP z51j$*&eCf`z;qA|=k9jvH=l!KUCo8m>mvBX-k%fei1ElI+K@Dk9<z)1LPX*moGoEe z-`eY$Cv~tEOVO`ZR60vy^6_nGNKy~G%YCvRDkdf;pX@*9!yBIm2W}VssF=!2e^I8M z<*cYSYy)ixu@$6e9W-MovS(2x4fS_QK|-C$Dhq136ln@Ukh{fOztrJ2^-Q{EPK7iu zO-gDBj8UgO;iQl4cne45Dzp4%d_232^13sqBxq?z(nPq$>K4%gIN@X1(S4}j=<lKg zjLvxgZAGttpQAQGNZQu&IODRR6UGXBtyh5*<FykEn2<r4se>|7p}dl;)~Ie0C7mP_ zZ+JGD82zV@2UQiO_r1{D71lsW`7K#v>-qN?BJBgY=EM}Xk~$Bqz6NVfx(J6QjRF0j zh-$c^Psqs>QHlZa2<a6)hI<yPwf1C{X#)qlElM2&MVd)LFilJp_MvG?oq7%GyW=>; zqiugv1A9~@gv{b94UrC<>*S#<rxA=)7t%l?hbCKtDWIo`cI8y(l_Tj#F1_LB?_gq@ zE|E8Sqr^h*frj*~$D#F9$xf|1R%KK%RkdSR`RcmCg@o|{9il#pxqM$9fH32FNkSTJ zoXvX^nW-<YXg3tOxIG)F_a_&t(|(-?J<ahiJ9>jMR7--8{K^nKHLkq*({ws0GkZqn ztjT+IQlVJ)O$aQHIwTl=*7`50Sbo3SnfjV2Rulc*7sph8E^ZNj-k{zC-oijx$slXE zU9C(jUMR0Ox0l#79P5*xC4cb=v_+3(s&!HQx{vhRzAH7C>PM;Obgu!lrYYjddaWcy z7v@uv##16Y-%0O(BZKFMv9LyT1zmLiBZJH0007|q-yKLpXLBoKJv;Y*TBBQIJNB>z z(f3ua|IIG0skE&9Um(-!Bc5oDK+;y?3i(l|1JNYDJ~dH5sMzWp@pGHKpDHfV=?RYV z97r3VwQqOAuGhq&ca#^dyc~R?B(bEDTy#CF%w8(PJ;rPxbgmF7s}jwVYd%{sNWrD5 zS0k)`a3_me{ymw6(aS4H{2A*t$7*A~ip%YO*Z9`8&Vs8#RW}2?YuHM7w{Fwg`W^lP zYew?uh-puR<Xw;v)^jd8f@+|wv=9M@hab!r4{eQi7GD`{@cbA)N`2NB-f<_|1mxz6 zk|dwN8G*HGQg_6W<6aw{LZYM{o7y!-HFyPlY9lTMIVuXOygRT;0G9`}ZdQ~G%qg`N zY%in0sv1?xO)7<;O#w8aP?t1@w)4L6{&#g;Or*v^7_+KP%^~g|%R5=8=2@cwaRzu{ zz{3~74Yk{#;taD#UY>~FE003!SjEx@(^im__j<^-D+OIU&tbT8B^`jjpJw@Eq7GrV zLOs&hc2vD6(^yb);@8AVqj${Enegw|?k^;ah!hh}O>}>>C`@jLX~Dd6cVMCG`J9fl zT`%MZ=7>)XlKifoJmnB(9*iAzG$j^f4$?mCm01!*57V9K<o*Thp7C|D%LTM3YgCE- zsBZ!wKk%B%89QSsW~x(ndee#1qkFwjcZZtrCHm1YG<B580j+L)@AEb)p%36N!p2#= z3&>G(1l4$%urG-N&X_-ytaK2-C8O-T65jl=0n-7wm^bG0(W**B`Jl?<hBZ5A+Qpc& zH6?AB6u!6x$zPJg&)NvX0RbIg&}EM@%TBypVgbJkJLBG1#-=~-TpyWs<ao|FK`9lP z;(*UTt3oKp*(Hw$ax+iNsy239ryX1K?WR$w9KSKI7@QpEeZccz8aGi|75RXxn3A2? ze1wU30WnleKnma-BOL5v`3OQa2touy;VIO(24nA^+uj)c3>PlYcvt<QaJlG|qI&W8 zCV>MUM4<ZSZ$~cW3)Nq`<7E+kT8wW-qG!!oUWd}>uW9Zs4P0elZ1(T1A1V=iz2mn; zuIEGhIbHWS)XwKYGmTW#5yLn94?hs+urU5p(x!fWZiHmREe=6>^+D+B1>lf-+^(T? zJ6+k1Kl*P$j&X5K@LLZoDKcRL6dAPX_l>S?&o?{jNV|cUgsF8H?s&>ORKo$=-b?{S zsNLFbvknb;bmY^iiAkW8CpCr*@>x*pTew12xx!L7N8d+bs;G#68;j`t3(aCg&^|#g zFj&**kthtAW*d;a49npGrnm&-(96ggNb=ln8&9?6x35q5%2-4H3_wQJIo5U-PgBxx zDP-QY)dB+Y-N^z5D+9Marq(=JzyzWDDaP%xW}voCAlE{!L|0C3S!<&V4|GZB+{0|p zh%2LDsy(bRariJ#J{I`$E&gF!WW(r6<kf?Aq$l8Ln{`TALfe_OW2J*j>IC&+Nov!c z1zwz}kvh|W;l;T2v>@moZa2~55e!O>kN<=m4B?d`$4?_!GmhsrMbq$S!@1oWP}9T; zX`rH{_J%~j_HN#R`qU^_nfU!pXj;NW5j_J02CqfJcmJ`1qrMRoeQl6<20gaE){Nmf z95tf-P&G|_Z!61Wj!Z1F1zu}(qO-}82Tu_TM(bxP&;+ET-h_x?1D=TuQ)1TF0sFDP zk$sED{o`ZJ^yW4IGbC*?-Lr<R`Dg{;-{LT#!xgz1N=v3Lv8L$I66DMM$^uqiEVBy8 zvi|4*k@-p;77O*MU51orMl;2@@r@VTO)>y4EKU0nfA~mE#8O0dv5~rf!+$>db-JZG z#~*MzU%%+yhu29@DE0PaImP6DZXp4w_@@${o8K=IaKu;dyPp7L!blG%^JS@_U-qbi zYL)oc9lElWoBCZ&%{!n4^W2=>ZlZ>5UtccT`BPbjOF@_7ad)Q6e&UQmWwdZ&6$~Xz zf54Q*s{V9XZ{X7GUx!0p|5P@r-K#ZV4tl(Bs4`h>$N4RCGK0pzRMQJ1B?m`q>)k$2 z1xN>mxE5l3`o#?H14zC&SZkJZumX-o-v(c}mgSm@Mz|0fO(G4XjN+k^#}9lDSID&) zw<ZO$x9}E;LLR;h=0F{*5(z)4(y-<#`Aw3qRE|0iMl&TRH+MmIqJOq{PsOxS!>zas z)@L!x?QyU0wd*M=;G+sekjgM^Fe6Sl&%B0^2wG=V6l)|u8P5$DZKPs#(3y6&xV)0> z!QSN*tON@2g4$>P2;8R|7mTy0YVNj>8Y~IIqQu+yP>%2QLS#{qPXDGwqK3^XtaUR` zXhq5|FUM}Qz9J3OH!vskFerM~AcFCGzis#P%hp|Gk1w!AaA&%!KgAAn2Oa?opUl!J z!na^9EuJ9Y)TU%AM6UqEre^M>ZrrOPXaF$awkt(~KIq%pmOOTx%B>dfeD3tI(CYX8 z`O|f`_tQp9mpaPW3DW9G!a5*flzj(}aeSHo^Ex0`!s?NE?|IzGTdJqxM;s4yX#2I* z_xJeowUsQ@tA2oX^8RF1yGnKmVf_vY`oo4V?z)rUMs8+FD=^xMFufOpPQMV~(O5-U zQbmRwbr$_v#!xYekb@wnds^o?+grIuHs&3rG5YgOM(v~Wd1T#HLjvHl@+{BubN6}H zGIcO_NsM2jZAT8DLaVdNqecM?X?K%ODdd|UOv-4lE{omrA6T1{_C7%F9%SUo{*J6m zh}>sSEqPEK$7vc@F$e{GfaSA=?ft#VYyt(}%RVt!pu_<dl*1-~_zfX7$NIgc?;#da z9?9U4bfP%!4|@r(wk5htPu>u2*GW(TIO?p}D5NV=BY!K$NejY4&+{QZ14>$#Sr`}< zieBb4`<rXZc<c>5<}wV>Ldh>a)TJPh;rNU$-NoWe$C~9>?hSm|T`kH`He$pA_6F}l z<-av+DZAd~Z^4F$BQVWGx`;KZ&C=3MPsbJ#HXd+g?Go&&s8IiU$sG`Uz3X4-|8I*m zgL?}Y`Csh1|1WnX`2Rcjn7BFpm&>X-?MNb~>Z|d+ouFB5Yu=-6#Dh1UVr+}RfyQjP zV(DJr9aB#UOQ^+wQeBgvT&Sp0S>Yj?F~<Qk0uBd_=ye4o7O>Zs1KEZE*pExZ(O`E1 zzbB3Wc>BuK*r9cDSTL_lMg3@^dNTQX?@9kG_sh44_qE>Zvq1iM%f`QZO#WL=1ohTi zfLx$H-}C3faGp)2s9e&5UZc=Ly^!2m(oFomcTP}j;7HGJEkBX#dUbpWyJ<JhBUm;A zrS)&G2-K|#m$?#;$fwdrw<!4{%Iw@vluzxVMCgIWMs9JN)TfT3L23Y4w{k}><+o!K zf9bB46O-IM&^7(pD_b_rLZMywODg0s6zEsI3KTX<wE}~T9FF8B&n4^=DgT~kc0ne} z)LbG|@$JKnj)q&Ptc`+K=8LVRVUBFbRkn8#4LQ~Tq>a2DiTW;$w@j07XaHTX3YRj< zRQ@sPeClV!04kQ#XzwVsd!iU8%e}A9gR_5+&0>$#I9no}A@%R9A1SlnW#{Fj*T}r@ zeXld08I`6s4oo4(-QeTFepz)c9NpI-1)Q@|V5D4OU{$KlS%^7Z!d?2VoE*4xay9qg z?9nj;-GBX<$GR(Ot}QPVw5>QCQL&#zT~!vw{h1rFTTlF(C{vumF=xx*NDkfwdWs#2 zi@1eDT{JL7SdaBa3d+0hqB*CuEzhU(nBTj`Za&ScN5BvlL7}7-aUG;<Dzr--jh{iF z2!?}x`&;ufGZCDqo}5}}$cQhU$&OaI01En+Lki3sTajC@&+OKL!ot>vIt;i7mgvXU zG{n;GpmUnSR&aC?SaAC@@cPK{I%Gvy6(u~2Vok%}UEuy)JH!SW$}ys#34gu<MgPBo zKblE9h~@{be3z+kGJjY#4h2>S;>RkwSn|!vn)39^n(~#(qy>xR(?jU;nSe=!ih-8} zO;Yj#7oVB~HrzWenbnywj?%<9qJx<ui5YQcpo7u%I50WO{shxoQ>!h+;7BO@2T*9x z38V3h`2t1({A!=*r5!0`9N8qb4JfgPHPq=9tq+%I;e>`m-#ZunakZqD1hcQj7u7!* ze6Bz>UDR$ObUtnmYcm-vQg5VU_(;<$^2vc~^eHpJRXR5CQkS+TJ-#=cuuMd-jSuY& zcdrw7KwFBks1Jk4onLD3`kA%oV^&IEJpCo3jc~#Hh3-bM2|SHqNTsA&P%M`Erb;d& zGaRf{48L&F2<R~`ivf$gY*76H~oYYr-_YCUg=&`s$=pJoL5Sx9oS_k_;ySudC* zljiR*C5S9@O6yZlKcp#kZKiNy{PvrsGR+(WTN~@DisRBsG>dIEaP6ks*rc(>tVB<1 zq79Lq`7}?%Et;}h3cMOP{iCbb$4G~{>4ZVromQ>7m)VFgkAdqu&l<FKgb#Pfah@GQ z1frOJW>QEVEr0KYAQn8wE3qy;jnyGo>$|`W<&CDzsAEpY5~yom^*TTKj6)2JD+Z3| za=a~Ij~p3#_AY?|)}D(#2(0nYNJAy`{ckOQ);@OHmjWBis^CFCq+8`mkI>!yw1e7% zAv<79c8Pyg6`@p8@?`6%D<CpL(EHkp!Te*D9-DTq>E4_V+T#{tBWLA?vfAU9rz-88 zqgwR})z^;8hU5xs+t`3(VYmA(qYEm}JLyzIIj;~&$(iDjt32xBP{z=xl1ts&Hv*bO zIAcFf4n+Lb6DBv^BjkG-K8#q32r|9aqtUrt2c;H`OO@E_sa99+;XZ#Kk4im`Wz1E( z%?l0NA$@PVSsJ7X&2S=Dac`xHyyohfVO?EaGKFyLqKxV|RueXxVAV)1XC3iKL)cB@ zM58#<bB&=rU{XMGddbtZ!`;-{9@a?aOUxQxFr}(7kXxYCsK*7)70f~PvxX;Fj-@*^ zD$g~nFlGUd;qo=<_uL@IEi20Fm_Eq7j5t4lq|X!-+W?LHnL06^uMm1$eH+H#VVo1q z#Ro$;@R?F4A|IkQ{fDyK?cr11;qn!!=1rmcXrUpvNiOLjZO~P60R0iV6Acv5bTu6p zJe}qWv}K&sR%OUYNi*Jj5HRgQX0<bMwF;*yYF4De%H%v<D!@LyBw-N}mnAvy;58ZX ztw9#ZZg7GME!oqZ*+f9Cfz-=QZkI!&oRTYC*~a46$V2MvlidpH&*cWVVRq~l-9|$e zAd)QwZvz$M(|esV7+VD0axzWEV!-G>k7l>^z8<kX3wNU2{T|_VSfm4-zTH_jCC*DS z_Di&03DiEBGd`g&Go{I-$``>e$JPq$qaJHeybQVL7qimX*8?SMWGZ@Nn%{6sR5}MO z8XEI&XeEMk$(W}wTxAWW1<pAUpb==4nhnV&`C9%pJxgQxbV|J=xwVr}YUdJx3nKG6 zKKo%(z!255(jT<l5$td1v+jSuwvz;@J?3O!7Q8WBU(_D1qQm#96+t==+7ciEpAgm~ zGH>xizZ30+(HouI<Jhcm_&^9zL`kM{Ss?JVqhF!KL6`?LJ{X{gMn|-zD|+94Z(k31 zo_Zqtd&3O7n^Zioa<t@_nPdVK3Zyj+c)C7UM%4p{y4%YXZ5bdE`#cA0aMoD4V887L zo<+|+@*;m~eJ<<M@al!R`lx{F#hFOqj}=x+V|K|QwVV9?x#;Q$HI-jgw48@*YbDkd znP<FTwk9uFn+LvKn<rLARbFzNC%`83H~S7Y@`TuI$}m8mtEml=!rMGzL8}0l4Tp`c z-FqOH#%XbWc=pD?o5@x+6)hKmTW(W<N>GJi|7;dCmdRi?9}wiC`Usb+#Ec_G&_+=D z5ht!Fo<QEM%-MnX{*axQWRJEEL92p9Q~URz24*a;%bCx{<TMuE-k+&Om)!8^`T-BO zxhsg3O;k{U(`sw15S_2wo6zdy&u?_I2sSzdn=Y&S*=ICUv#^V|YGwqee5CASrvAuW z%K=cZhS59A3eYv3F_^R+`4jnOMi%<)Zf``gx6W+S7FyA?+^jG_3a$Lc0Sj$kjGB8e z;kX^R<Ov==JygT<%}GG~!!HCvHw|K4`Lw_d?nBym3WM2u_68jIt7Lr<rAlzzQM-kg z>JD0928h*Kr0&KJ>XL1+;(&Au{W+vK9~~6vbG*4$Cmy&sihVu93B8gOJ*NWB@=2N4 zYA_RIaCt3hRKbcGBT$^uX>o%e<>xfeV6Z0h^IdlOm2(+ZFFG2MgU_*h%8r#`Tj8)R zcbXY#ij05s4ifso;P5c!)XIWusvp+Oc{#|BDKR!%HOu59x_?UQC2uLOx#84dt){|Z z-zy#LJ<V<b_FQ(}V40pPr(Us;uv%MFI^UcU8`h+*szb2Sf#{OW)WijWQzLn68Qb(= zva&ylJCYxK6wE;N@v-;l+r%KG#kGogg=AW>+A6vPQ3l5QIaMYr@2DuBz^Jfs^^|1; z2fX~aTzf1Aky~?LJ#lub5Q`E(eGf?h9>4^ns~Hx<0zdZ>U20GcuOG#Fyi?W-JC92f z0Mf+W<;&PBJgYp}qKPi%W`&u<a|a%#y|faW&j34@FIM<B_k`g&GUyxNeiB?yt733+ zP&!@UCKjn|lr^rGI9wGVoQ=fgLW@x4H~DB5`IKyg#62}2&W)12j~LT%>a=c-M;TK? zvg_!R`vlns+Z{Ir58RCE!XE}=dGPA8yly*(hux(!UU(c}<`$`OfVR#c+;h!$d(}fN zFh;A`YIa=*{fI*<KGV*5h_z}A$3wC~B6TRZwyL$_0|t}pghwPLCpQqOJ(vE<nC>ST zsw$r7As+7@<{~B_c9^NxGBUK`@dGQLEOoedG&bV6nwj+$6#C10(jQay(&C{bJ%W=? zQDln8Ip3Q%PEiy^7j>kTCwtm!-r&p~n>!&mDNz#YMTO)`tWPkX0HqIgh@3t8nctvp zh$RpJ?=@VcE%RrYg#!sTYQwVQ`%3QJT`8wq%H+|iz|6r8Dflskbh@wivn4@NNWF3^ ziBa{u4g)4qJ4sp=_zmY31Zb`qEd|3Z$n!aV(%d%$xni9;Ww0@kk6s0pTHxX8W9Bg+ z^q2QU1C2IY#4voeaazDR#uw|N<>Ih%ZLxrNwU@eZQXqgMTSV|cG4rR)^g$w?M04_S z0Q20+%A>c)I<1Qe0JYJ^$)UG+ET9Gr_9xAA^W;lck}tR!V?Z8#7(EDE{3jWZE>;(^ zWXwx&fkC{FN)xWc9v#&w$WFCN1pQUDzpDwt6b8+{I%w6z-9)`jvL6d~TIvVgvI1~v zg982Y9kP5643z!6DDsnwjR}cF)gU-P3uUWh56(;LE+YOU)e0Wg#aRRsE#9@q%I^s> zG^SQg)-T3ZmZ0YZ3fopAMW)oT!*$%Lys=l|;{ebGRPmL;Rf1fl@Muh=VKjPC7r~Sc znC~?wt=;pzhzp>tt(ybdvp*O+r*Z1ob$b>Q_#_`Y$X-2YGvUrXMT$x<fdyt;dzW8a zDMVVswy*5(;WiFp#$|_?y~kW6c_;h3N`P4TIqAEPk6dh+tUrwQNNJ|c1Uxo3KeWt> zJ@R%zMWzixq{kfsclKwt#D%pM_OZQpxcd9#YXhtX5B#aO44wR2NO7GS2JIbRm*0+D z3@)8HQEOKI*7)oh-c}XPNOxh@>hR{esS?r<rC9euTTgs#%o#>9lM0paw;7--o0D0* zP8YSCG~W=&x6x3WHsHiITmMUkN&krGPX_4-`{TGR*nLa4&KAb>1kd)!f%Oyrfg-0h zUvW682;yUc?l*srqK(%dnAzmy%Waz@02Z|&QJ(WPRC@i7ei4P8(TMt_PX^rSBzDLI zs%RrWuXeJRjFmjmaf1rjdsJvx*mwvLsdj=D+#1+OiW&Z?hNU4pmHJl$A_83-3LazW z?o|aZNt3i7>Wr8+U*=IZ$=k|>S!iKTn_ezy0M?bvV!6Mme1KQ;cz{g$Ep!5KTr}iF zTyACLzOt*~Y5ruth>u=GbVeH6O6(l6e;Xh7&H{W*-!$ShMf7*iTItNP;J8z2NNi5i zJ#xf$6)qoFTs7AhBuIW)U_;^<+L@9z5wnqfM{j=HQePv85+eb}`6N=59hi|oAV<)7 zsP06(a`dUzC&Cz42XLqSqf}xdt2!)LwI*G&(oHQpRBWr8*fg70q%A90X^A$#<N6ls zbDlSifnl>j7HpJDC0Q&?#O&6SxJ6$=l$<za=*^-;Rt;3$eWA}0-4{6leivhVPrGlu z%jYK{jMKzhn33p!vATE3B83oTJaY@ht2w~;`|reoY<JvN9>K2=8Va|9oEH)rM)J$8 zIWN%n&jp$gal?u|$LF8xe<0z1;TzN@mboH{eVjCV&QKNfFk%FH3@~GOnLOhc%`Ym| z0r4v0CXdRvTmlFGI)_Me;}1t!-_Av9Bm%Oxwfrjrk_>VC@zydVgEGr-F2`h9D8bd4 z!pYkp3)|0j6G}*%4}fJ00ov})J~I5dQNzxQA4ft7=O?-AF^UF#(>t0iI8d*#`|uKW z@PtwgBfQd7xbuM@zAb#)mEHaXM)3_h5To#kI*1+Hc@3-Y+?m5UT~}sXNz+uW{AyG^ z=Wr%HEB1TF#Z+P*b>R#>D_}zwV8}hpaq48*GjbwL`c;n`#xUy@m>n208`=)vM*~+b zSu!EsEF9Z>KbiAM|E%<COzbZD0VW);az}y^AE{=QE!kFeH8c);KG`T3PtG5z8T)Y4 zOL(SDupP(<SVM+pFdLS9^XgWWpLzqfZre@drw!P@u83$X<Fc60U@iAEdBI9R+9N*3 zFQvW}M_D2b+;PynKK4~FS3b(HY*%r0y8iD;(to<_u7krcJ)i&p5&wE?|H32yM-wM! zJ11LPD@S@GTWf0r8)JF{D{}+K|1wilb!@kUQMwPOeK^<In&Mbc<tr5;wak%0REB^F zpeU>3AO_4;>MfcdZe-bHyIw|^=^!oe2)>|n-$l9}C-C>+`*>Gh$jlMxWn5lOd%R9( z+E2Ic@qJyl&ToBvn2R1}k9X0(n0xCn@73n{6l_;imy{M<{_f_tiFRXAK3O*Li`i#; zJQwhXo*sZbV~O<2e#&@6sRq7ip|qB-maG-$NZs>1pSY_e`W#oI{aqruUVyt@92tY0 zhwp}q)=uvUVrcnxhok=p{cZ6Ymf19ZRN+bw8ZX08*JqYaMCWS!Hvj7yIggdefs2lt z*2xz_vvsau{P{H|%aY>5)vS>51fD;?Kwt8~txy%}wzR*C(*mlkW%ZA5la@KVTWTai z|1Q<EnwJ!73Ym=zr;W>UPT5Kv>}YRP^|$urg6OCBntksTFZ1?s$%0<Givjx-Ia}S9 ze7cLHiR-b%z_h^l3O0tP5&LqGl{uRDayNc(8|BmA-<#}O1s@SyfckHLuQaH23*U?p zWA?eZ>17(Ko-8PiExl|AUmDSfRUPJ$0*@ws6p_*D0mV3c=llpc_N51puG!f`xy<5P z6@27XRj55mM)P@m(bN^*o*mKzDTh<Wl00rlRmxIV0)g>&RBqUzRFzLal*0H(4zMZ% z>N5_+7>J>|b6^1(?Q6z@g?|H2$Cf3bRGuQXw(wwag6AWO)hEE9*OaN!tuQ3;>{v-U z?#W7HXZ~}+kw`~vbm{}nsX>D21~t6dRA}7v<!te>((ikmHN;usQ!ttrv!gZJ-n;t% z!Onj5dZB<nDe7;KXQg<Ye8nF8(@3>X^u!1b)~3)0Eq)pp!wVEkk}#WLFaNnuzbi4y z+5ty#KPP)X(Lyzq2L|q~HUuyb$Q_;+0DvOyvTAMa%}-@%pa+hmZKI(DM&t<t50z7s zxIS!YMyQWM63Snz$ca`W4mQ2UcQ*DFW+mPzmlz)Jf0zR=lJ<0osa(Jt(tY9Gd!Mc4 z@YKk)j%^}NqIn=Gfguh4(4sxnB%Evz+d|;Raf)NMh-ue`E5VfF^gQe?CI63+F*?ET zyLqbkXXWZXG)ya%HJ2m=5+pZFL9lCeJ5#?>d`2fYUaz6z@BP9*@Tk_0@2p%d@>}>o zp5R90>W*{8rF|NVe<DWX6S%JJ3v!exJxlHwHk>7OB&O`6;eHO>?}H56rv_`?(Pyhv z@HDABBw8INCUgYFX~VW###$x;++MNCk-%*YbuhC_b%JlD?0fskclz#tvX>-t1irKs zGeD%Qr;ZmhhdX^ut2}??CQ^%n?&-sn=BAN3la&(|5D2fe2OVF+Bz>qO%Q|9tdX=_y z$K26i9jaQ^?5nILs(&c3HUbpX$7RX#uP6V7F=-$tplZ~^H^mA>JXt}D0QO)Q&9wV8 zj*0KIVt6KE-!yU&+(5=Ks`_=UQ>iSSX%De(ZjGIG#4}5%qbklndr<0%&Sny{6si2U z&cUA6%MM%@A;gMorKHSm(BHq6X+J{F8$S4E*RR#o*%Dk6MoyUvxW#{LW~D&c2WgPX zK>J2DYObG^K<+a1+ho&xROqD@!0ME2oY<&K`fU0D&KS~@L6dkD{?>WO-q}`pSdsnJ z4-K*4_^M=0x}@Q{_UL4-+EKSi{_!<c>ME<^aU_^ALJTQxz!2!ENdnA~!V8nH?z+lO z&q|c=Wz*p2UXL3;xQ2TW0gS_{n~Kme#idir_#--M&jn%BNbx|$wSCY$naBg6iKy8c zd13{(HhRtwRV}a<kBZvN-<b@$T8T~5$0lTFALdTjZe_c`gMG1g5=;t`x*14CScJB$ zQsVe-)bLqQ<x=k4j!ff_ghhB(ekyP=SlkG`st?SWprj*EnuwJeQBQr^Rh4{SeUIR% z5aBncDnJPZOq5VZACpqhB?n#YO-G7YuWQ6|XTRJj+u7}OtM`A5^eQ7c4k%({&ORUj z0RMk;Or-z!@BaUuVRAHbFt>C1&mSOIMJ9HU0ipX;4Mw9ngHB<{Bsi$46%`4b#0CdI z#D-}c3y1rGBkAE1liZ%Kt9q<D$KAGPM;hCbtBkb0UqVF0q(k<sBQ7ILzM^PiVh3@o zhJ8iw>x&og7czi}i8PvAR4`Q^5{I^9y&R>b80Sog^rzp#?x2Vv^rD#gIq256xmbiL zu-Z=IAic5qVF(gCdk}qJm#+}H*^UT&iA9~p(!AbbL^lD`=p-mb5;&d7Izd?yVR+cY zUSbs9sM$P&4|{IJMX28xY7WPP6#>E<&`N8B9c)JRiFac?5hFW_g_R8^Q5K5y*U;QU z56&d0A|3dhekQ*SR0H8hEng;_m#1GWAEMhF(i|Lj6a(=~cV=*QA<nB~VZ!vGl6{)~ zq)4@*l9HYf@W#vQZxJc@3`1dHes0+G9#(lA8r{*->l8PC&CO=4+Ie*Ft%9pOwzs<J z5R&~1P<Q-BKauV9I*K-%+YLK+mk7K1^gs4ZqRH}dRv*T~WqZ6wmV|e8D6@tCCmNF* z^`RBI{lV*b61ia8s@uy%hx;91>^m(JZAbT~ZPQWeU%;wIzWHBEo-DBP3x?A{DBad{ zNDS(%#`U2zeAPq3-P#{fYvmk`a}O(J0=Md5>}vjZIPid{w84C1Ayqv7rckf#h_aIr z^*i$LV+6hODW#J-UM0(zQEDb$t#domF+84OM$BFXz^*WEaQJaE))}LUC>I))o>(u~ zdrD_>IQWL+&cJ6fg5AX0obcG0mTTP+pTR9?IwHN8f?h$u+1J{;itz=xMIXD!y_^99 zqX<vQ!le<Q!4&4p4Z+dig531{0<(EEe)s8yHD57wotnCx;NA?Lsqp(WD|Q`hc6?&b zd!y}E{vT*{iWb@E*?8co5gy)BTkl-rTJtE4G!d)nB*Lke+QVM8Jnz?^d;6Tv>RbH( z^9uBND{+%ubqz>E0s!RxJNID!-(LYoV{^y<<Ve|=n>I%+&)z)&@%8yj$;ZxfXu+M0 zk@}aQ0ftHhvJVH@s2oVFg)ySa5)&^hW4*692_5nY-HT`a#PO#yj>XWFF(mZKHqIL5 zB*>%0m5;*vNR+YBaT#myCE^x4s=={=zT9)tOYqtkO$HwP{+9w&^^M$}l2)A}UV81W z`G!R9(o2xK8H04m+Tp6E+SRIEE5&r}M3xS{M0Y{`t;s*02;jDX6eG2`KJk0mpI>s+ zQ$Vm~I{MM_U;#kFVgb0=jW5;+)ohh2Gtdhw+9p-|1~V*?HZaD7B#0__t6%X+tmi@X znQsI%VIlnCM>4}qcw9ka01`D?8rT4nq7O|Jmsyht(k1Oxf+qP+#3C&}3QJq|qVhq| zkBTc-5G#}u5r<kVcJzMDf8B6hJQ<UF=l)XZ02b8q;H*TFR0bU!qRKywIkkwfX6r*f z(C=GY#ozQlf-QiNuS?9c?K>X{CW+Lh#c~PV0?eU#;(seYP?7(lnM8YbV}c2oX`n1< zwuD-f&`*@AH-mn0v<qfv{xxg`bH_o1<|3n34roFm;Ua9iz(4vJs{rP>`cq=EEYV)F zR1X`lM+_mZu96O{yk~0n(s!J%TwKQJ(}aTB_Y60R?FezmA%2IUXvgm^i5(|i8ApZC zG%q9|KxA^N5)tzaTn2bD|7Me@4Ah;6?BI~MvIAlLEV&PFN&VerBaUm0f;@@U&Or#a zaFeIUA?C`J-7giqp&oiidi4hD<z?YW&mCE13y?TkqSf_40l1n95navKcmVAtRoa)! zfTU5p5I(Z#G{>#!O{C1b#Li0=97W?^5*#$e`iA*Nm^CQ|u;*ezm};d%Cm3DPa8ed8 z0l`+dheV=z2M*FffLU2iR(%jt=>Khc1f^(%C)Om)s#5-E7TC}FuYSSv2luWpxIAsh zclI<E#L@L<INSkoQ{OxdDPi$*#!q5Eu|puZUQhQ)>7vG^*}8-6B1Z`EdnKv4KDzjn zqRp$7;K|^GqLLR%7c)#|hH4`*<MJp5ikdRUc9ykcV{a0KDWIj`?XDHWuK^j5t)xyd z09b+%^}K$RgvEm}!j3N_TWukM*YEUqs%z#dXKmZbJJ+242tk4RQzAam=~>Ky+SXTb zM62?(7jeMAiYk_~JB=Xk$IJI(eFoWd4~i^`cRdN8QCm;#on^73%<oh`Vt%Hkp6)Ak z+`a7<(^*IkFSoTLS+^LUN!L8Pou*_o{6>P?C%c~U-{}M~vP*`)mSO7km6N{@StJ17 z$I4=!en)?!)Sxs=YCPPWwC8c~W;4V!PQ>@eGUUxUk@)f4ZN>Rlb8~l$b1kv9^>(eu zUYtp{6#o2z^VjLkcRuUMJgv`u_FAo6_I+qE#EMk4n`}FH^%7jjvkkqUX!!5BMOF7` zwhyp3l^>396yf`HcXl*`71uyFyIkV<;PCgS&c@!>5_r}8yMU0%bNdVqNGA>(2Vz#? zi_q-^a;46?u_9T^na%ceY|;-V+eWJ3S=(iQqPCyU#;NY4xb=cu+AuCwx8t81Lw5ov z2|0sNWo{=uz-2T84}soJUz*kgFoooOjH$3-JqOJ(bjqHMn?t4ovtR6BNbIymbgXAh zPB1iVw2Fd4{5a1Q?Z*OOM9So!^qrCjdF^(zg^q3f_;}|S-M4_U$%LDavKY)GpsD-9 zNCKCN6;}Pa@ba0{uP4E65)8`7tm2PIaiA(h9AmB3-sFU#7n(N0>WXrV0Gb#j0};bL zSNpawf~M1+N3gn1xZ~da3+MaydcS)vz%kZW@()xPp^U$z^?98G&BWhrQd67>MIE8( z7q7xVR|Rg{L}v|APfF15VK}fL<-q4?vwci3=?q{|l6aoDd_vdn!_K#RecsOpuXPG? zS)$2s8hK~!!1UkkwQIyY#cD85+Rty|aoxE1AOSE+*wy8(=jzDxK_~<l(wH%ghMfEg z@4rWK&+RZ{m-5<`TIzf>otlwLpo&6rgsrc$S>?fy9vRs1cu(CEa9_B9GZQ!+;Of*O z_7w#MWVS&jbHo<NB8>sfH9vTopn;y*_~Use;V?i-uo(>I5bMdH_`QD*;qh&6ePk!N zGUWZP3hnH?{FW*p%q~Fq0BMC)6vkw+AkE*JSwRBP$FVEiE*S|^auI-}l6P96poo(2 zLxDO}f}|*mLJMW70GFfih3bE863?tP|11pe3JFO_Ml>N|lI(eIn2WGSewP@NHhof4 zPk`Iy(-tu~vJ>Ym!LqZbkLAz#cjE=~I8j2;3wp(=m=VnFutEDJK#Mbq$qE}R!a|4x zlvCUZog*T}hRwTTNY9W*MkwUr(AG(i3MZz`?x?Bf`~&zAH6|7GXGx!sZHGRUZr=Xh zpQGul^{mH5kJC6HC671EQ>s2sPrzqxfXIlst%RN-KRJrPt|KYiWJb(>=c<(4(_O63 z$euL~Jw2Hk%$>Ore>|jdV2QjVmlev#osv)FY(6&<M4s1`ofb;IuEm>}Z;cG;bJ9r} ztFOm2HrBwR3O5xZD|pTau-{-R^H40FiR*G|d);+eUx-f1oc!zW;e~tF5YD#DF_ogT zme%SE-!8+CQ3nKhVznguPXWxp?pHsd{=6$KWXYR2LM9mx$Jm6JHhJ2klbH$ur(RIV z*r;gx`|D*{etjmaZ7sU6CqJ5hq;K73LVx~YK_7@g`F99HOYj71RE4&_S2(gho^5!u z+H9CuJb6mq$pbFz8H#jpt_w-Aj<MQ?Ds(IYrJ{$11~8MDWR%IKrYrg7C$mjaJyvC! zTA6$>t@BOkgK+B^g7^j(X>tF+wBJ6_K;m9|40eH-ba-7Jzx*W|9#8gXs2hg(J!MEL z)?fIyWb`MPr#Y@<>sbDkQ%?8~P{#gGZ@XK96|aZUVA_kSkQPXyVZ>rgy{xpILr{y_ z2AWcIlfCs$dsyJ3b{uySVl97XNp{;}>#Om$IK-oY4VNHJbDQ<em2W$jA}9M`AUixv zlo;h|rv$JVD{O~6BWMUXRyv)ngM&DCMoXD>G{nu%0Tc2xWJhvC2q7%gYyH+W>$-zJ z!J`z&k$Y4fGEqt6z~`!%s%7C`&N4S2-n)LnX#DygkarqS>WwWUd7Q(ieeuUM^}oIu z?-zL~6dZ+1;Re{6Vxzq1mB0V3$^0MxiCjZcKk=UqIS2V47iv2ixR}`fKLW(4T1n4x zNdO^tdos60vx2A?N=QDa>*=OilY*$F2d!PPq95rdq5IO~-ErDR61u(g@$hX=?Y{C2 z^kRxc?YWyUJv)0l{e9Y&tk=iZX6wi8i_!n){@yb-_dSYeSgj9+pkonKIKUZ_8Bznj z01sm0RsTfbMCeH9MDQqo8SuCtq_*=8S0D0@^nr3r;>^I#J95^ZLcTfaxo+xFAwDDl z2422Qd6R=OGCb#@Cre8Q?cU8eNryPBkUE&nF*IAqJ1-FZ2o`riTv0YCJPuLxsPB&C zYQ9;GLY6^1uBqIWS*I*d#t29YtWdvz*<{CQ97t*QG+p()*A+pU_m(`-TwYbsoL(8V zDQ%sdP#PqKim!-+Ux7uPw@*lbSm2O4JS#W|I*GTfCO_WJDQ9rNe}wR9mn4ZVY;si| z0%0|GtzIltN*Tw2pKCX?772|`3LcG*1#elpXI7A<?bhFA9P*Kdl!XpQJI8QIiDPig zY{f|5D>jK$y`|gwoC}Z19A3f63v@`WP4=6}vLd?rsg2CyYGv2bel*2-j!lU@1io~_ z1>C*@*-{4!veLnbog%uSJR|C23eH_1Oz5By<2a&}wA$vNf=-BQuTRtjSrr0o_jV!E zMLnsxBMnPRgv5P<`s8$38M0Qbkfun`(BMTO$}+n+ka76RsQLN1X2-LWU4HT058HN< zi8+vNQJ?i6ejRr7kDvAwoZM;08dA<ve`4l9>gJuWRYWS2liKqzqYC<{v;fYjiKbc8 zvwLO=<i!(y(F94d=|zZ~+TUB~e_u`l%nWsSK+gtJ_wGZq&rD1yUvu}>O1izchfTBJ z^$(o{z6=KNR!8xjtaIIZ=16c_+uNav5ZrrltI7X11N@(6K1|(f=gq(8`S_o%{vZ5Q z2U{ltCzF4wB3VVoc9Q|-pPWVjgOaK|#Fr;1bslwY)d?Vwx7wJukjf#cwe<ZK=lro) zFjyq4mwvd9_eyZy)IiT$;(HQg=L5cEPi~}jgYibMvgSGKKX0_wGMVV-5jpze?m$`j z5<-v3hB|fiDU>q0e1$m6a!wp9oi6#C^txvy4>(L(?X?C_O(KC;-|wfNiKHWJ{~;`} z;>KiCpcdX^*KwFy7g+SgKon>;B%6tq)3*ox0g!AnM~+zXdKSYr;5M*6n%X72Q6Zn@ zYCh80RQwxc0e3dWs2-+@0O$L%VL*wTPHULn-?9`lxR_vM9w<_GgQ`1ohA@D+$|K0B z9msGi<s+VpIrMZLe$lubmlLUJguobsWe@kKR+hy`*;M1y;K~qm<1A05aM#WW0Wb4{ z30AjjIyAub&KS0aR(fCjd7FhPd!C`Vs_ETQNQc(Z0)NnqnZC41%nb+ig%-%$AU!-; zPkCuIr{sp4#_1Uf1aw8v(j2Nl|J<6_Wg;F)%02y(<@^XsT3`1x?!>l33X@{GzDBA2 zB}uJ$Nc78=((>f-tuWx!oW76jXis<5JmqkXEX<tWad;Qh1+b^GWK?`_H{7NbvBRW? z9K?hJeB~@bg}P~V1l$A)<uQnvgEF?tNNEzgNbLN&Hl)5QS~!(in7k+`;zVehE%I&4 zH5!g+TCqKVv+7wg^`M@eMA5n~>nS}){m7gx%L>htXYH^tsj)@J)+Ptv!<Qx`QkJAB zt&lBQhlPA6&Dluqkam2wF&P?5xSh^&yJp^mJ$LHfVa&2(sthf-OOC(z6@69Zji6FT znzm}Tz4{%#GBlzjFh|F*xC^s8SBTOCo29tQSQS=j|I_r2M;rV!2MV2C-Z7NLOm2&v zn%LXI;igdhX5x&pE9-WIJJ)zF4-xT?sgbA6V$AR7xiU}Jq1cwl9+l`1yqZPU`Vjn@ zaDIYXjT1@~Y$|2@DslNCRxEmR1A8>v?9$+L=;eO{DY#fEam(Dh1jz#f095}I;Qxd8 z{@=Mn_y2L71S?6JqSq{o@eu4lf`+P<<1@K*{uqL9YEV>u-$wN!mEs2=a~4IPzE4kO z-lsWt$6>)qpZ`Nf(h8Op#TNjJJkMDYYJyJr??luPf9*{j#w>IJ7omN{OX@re^Jnb? z6`_tgf>9O65$`Rx|2DY9NNFQ=!*O`%cL;^TavLsnn+B+P7Mvk%87|kQkd6DZ<>C3j z2rXuf8P&@I<g&={XOa@&*g2n3tj<9|(#|Uj$rTxXL3|?LSfAG_KGQC``)^*k1XlUm zk1be1nx`CGUaCF%q;r9v7(@f-2eOJ!i8*|o7e^D{Lww<{=~=bBHD^N9+}uaL;p$5y zEYT`JiBE=25Yv`e?aqhTOQSyu-d_j?`Vf?n`l9TX1NpN}l_Mtvq-q5lUtbES(59P& zz!rr{aqW-SIBFpMnpBj?JE(x3qdNRsdz3QS2PR^2+`tfWT_%<zu@Np7kpXOs<ogA5 z1Uz~}!9aPTJQh(5?FAm$#yyd?)xK$zs4zer%lNa^;b$FYnCfPZC7o>^663oFFokNJ zX;@)0<qpjoFs&ATkfzU9kmDFQyPi3MQAhNP)9-Ax)m~3th1ryJYNWna@rqo3EjfS^ z?7A=Q+t747-9KZ-u^EF8RxJ43WI7FbMz47JV!Ua}6Y;JtzE@NT`sI~}vmjN`pR>3; zA;JZYlE~(;cj}<-Vu8|Po^DUF?!#c8Dpt|WwCumkHOs^Cn50Wg_oQ6Wj@NCRCVF8; z)@A>>XqmSBm2NauWY3i*c%Z(5&g4eM%{=*Y<i`<X=PKrOd=lVI4=lk*pNmVS<j^$y zbV9nDmAdt4O$KRt;tsDfauwR|9vZvz`)5Vr#PRh)vTJ8kY@fK1IBwm4EesHuvA83V za*MNXmq*9LzAHXwbF~vwKY=E&>Wd6xmV4p!$3si@^JcY^$YS}d!U>dBt&meq$_-1) z6ISl!cEi)%NB1L<P!2T*|EMwbTv|sAX~_AUf^lp^caTuib{Ff3PTLC(EK|ly?{vK$ z)pNmgUJzDbOqJS9ryVzr)Tnh!pLy{IEw%oeTZ#HY%OH5#p4UiB@OnCXs*XF0vS)I8 zVn82FeLYysM%7dK|4TISf=H<?{x?H5EAl@#s{iAH{b!Zce}#bm60iS4nsja*)7=({ zM>PD6rkK~>IFPJICcP)Ex0;B-Np%Tnz-%-S8_d>l7}}q4Fr%PVsQ?^ckzFjJ2xt=D zOa&6eeySGGLXokR*bIFsANv#6Lh*s|1oV_oF*hmo;rr`5b5)ZCA}%@3ox#cMNca0r zzw3+X`^hg#RbBgiXz5)1D?N8B@<FOsm-LXlQB+v`m9^2hRPrCL$v+UvqXqNqse7}U z{Jh@=jyzfov_)-MLBa-2`CoZ!ILS-D4eH9W0yb(YEXB+}3!2KFgH%`wnZyn{ik^j3 zSW1~j4!mVABPuNUY~;!;<!t0CEX8c4N4n{^*$SCvM;!$(B`Pe1Y-UFu;@8s^XH^?K zQmca(jZI~o$FX<g|85o2qe=WF0f5VSrK9sc1xwtSrz#A!1Eb0O`2)~@xd@TgCUTG1 z>8X4p<j|6QL*(enb%-XKpy(<uf1;q!mY=7|llUjuQ<HpC<SHg|4--v}7tdIp+>d7~ zvjaA~6yIYHd-o`h_2hf1`J|%N1dg6BM6Sl2aRQ#|l1J>5mM-ppdRCt-H+|BIZ0Z`7 z%DbE}M0<1!9kHXY?LHY`4^5GLa(}8+%;i)x3kD}2ELcNB2)UX9zu$ECO0EgSBb~Z? zS05I1+W93yvk9EF#LjKDoNhs{gFd9iJ~IpLv_57R2_syO3?twwS&%bCld6nv*f+1+ zbf#Zjx}r5YtH-3U?LGN%S8mhROAnV2SP}<a_C5@_%S!D(#XD-}_Dz|s@w+iYr<FIr z+`WD5KFd&@)V@60wqG{HoLTllle=L&b`+-$MkTjtE8emi6pMwVf;m~T8DeL7l`G6C zBe4c}FtRfa6?(|%T031=D}k3bH6s8m2#+MfFh4^T5Ps;d1)KduVerT)X9P`i92O!5 zSk8*P5Lv#De8jQis>={X1s6BrE6$SP$Nw!TUeGatD-$tztZPKl{hfQR90E}5%yLk1 zoLG)hvS>0VU=G`IF!4e71_4o733HyoY89>KB8#Z5z_94{f2VMss@Nkb#Y0MW$U~10 z7Z+_JjEIX%6h`JX6_1l}kr0-kas?A?MV6-m=SmRP;QPy#G=Jq2U_{Cp$P0<pa%nSa zFPZqHS)--n!={ms-C}(!eBXlpyxSv`s&Mr#s5K+Vuqs10fxYiTZBy#vkfdF&<;iWs zEq*ZQ!kZ`6F<ewsI;Hgj{SCi7m7ZxGczJ-2Wl`Uq#bcz)j+_U#a$tIwbq&sMm@$sL zeq{02@tgR9rOK6?9a&R$<ZNDSES`y);m<xoYk(=#Pv<U~=s`(m92CoPAqS-J8JNa~ z3FlOHHE~q`lWi8BtICwHHqy^^<JmpU<4PK<)$#Lgz>h0Qs#n}9`KEBB)>+~2fWtKW zMZ6dkK#+u{Zg(f}q&cP%YoJ*P474}o;SVN=Wc|CMRU6(dlX;&P$NwtqETFPl)`$Os zbPLkm-CfcR(hbtm-6@SAB_JJwfOI#~NJxW(gn)E+gMOQP{^tlB?)|n4-?doG?|o{X znZ5VSGh;m>^Kcn4ZA7fhZz+@x;VnMF#0GmVG0E~8?}v54#f76|v8jDPK=Vc0Gz*pw z4oAe|;Lz`!@>QGyrG~emE*RsTf+*3-;JA`h20cztC+rDuzaxESD{IPa613D^pFBht z2|-tiW!#Unq1@}ph5kUBFTgvN!I7_(;t8L^>(YSxxt5k{8GTrz!Ge5fL)^?9mvft~ zCg5hLwYDR-35_j)LvFA(BAU$QefAV@_^9d57vrQaJnP>+iU?@DOVe%pD0Qgv%Fl{1 z%<3oME@?ULj#~!h<W6dQntsQb|A%V-po8Vpn8Jn#LR<2-Ov2K@0kRw<e!AXZ>&hk< zuc>3}(sxkSDepUwbHMnu=MncH`LqO7z12i@wNSCOLZ}DorL<s$V^5W1dpe%UowiTF z!K)rtHCN4maq2^XC8@FGaupkTjuN%?ms}qA3?ik`w@i913R=m1ov7}YdV$NvX{!a7 zYtmZvY(Pq?992BT(yF2$K>VX%&<PA?aYAV;IGtzycj$yO1BJ0rLbg8irNM+MM;ot1 z)SOX*7j~X(mL#W0MwCKMVbd^@q*lS^>tc%mtr6Ov>9^M1<EoYF*BH^T9jUNMFzIqt zdnEnnG!`>+sC}%W{rkG3seN1(zOehj!v(+l0Ryd1BQ+mPj*is+3S4~om;u{Pk;66$ z4Iy8Ub<u~rQ6TV#q~*w4FMg}^7LlQ-g?7^!yvRd)*{4o1FNDF%W4WSaUggD-q<_o} zxkwKkDW-N#4e>}FKf+x-NRpAZDu6zD6+9r`zZzsd&>EGTMiYyG@}?xQJm%%ZdSjkH z+Ne3XU^L_#jvm(&h6+D8;o9asUUnX54Ewqww&Pg-AEz;`e%?-?XKCDc`kHAm8!1yA z<mJeDuQ#>#nvclRvDrAD!W-rijAG)f@mR5koTReKh8?&xb&_}H9w@iNn|f~Rw1JWA z@)=!r)5&AD8dL`xzEafgQlPTz!WoRvj-7DliCkN^eJ-yqW=TARfb<m!8)|+4>pF3y zw2b?J&Duf(bha5wGF){oe4OzHtQ@g?42e1?gxgz=Z{~ud&dYhrHnD|fftrNAT;)2Y zv#6sE!^t}#xmi?>r4@!%@8tlPQEla_q5M&Yu&Y)#WIA*jg6~Rx=>#3~xi1D7AE$V@ ztT(-aBN(oGzcM8RljmaM;-(I12sZ(O)<j#G3AVwKYS5BL)<oNk#Zudq%2$8UQR3xf z?h$!;AqFtlqi{E&%+zWy`|ZqLO3gQ4=|suZq^vT8dtkPHpzy}_pUskJ3!0e@%@8jw z=Mcya7`AWcW!R1MD@js(WT-2ZV=CuK>xCEb%}iJCQQv|?a5RmT^+@AV=@4P`*ZaxD z_<C3p7YdbqAi<!0j@?`~{KaQ!s+cr^2$7D?nRtnfa+j}2hyu|N^cYs9V$tKSP~n57 z-u^k`%u)kKbUWi&?`V`9zk%81P{_3Fb{QMh!B>b5BC;A4Nk99#A%(xb+HJ#l5;d{| z&NC#p#-Qa`A48*+P^5|41{?*D+{2%gGO$w2I^o5@x)A@AzhBwSyqjcIu#s!CC}Vj$ zEa^JGNMF)YyZlRUX;vRzA;Rey)bZYu+59JwH4>fX@nUYtP&ZF9v_!{9`Vk>1YctB> zQSoTRxC8hRl^!dMKI*wERCpGxFfB6TjIHf#GQzBm;?*WMMk23o?6b|qn8x$OZ$Z`` z-B9Y^J=;cZ>g4K5nqs;7q_3`hu6nEqIlf!uRIWQ%-<(EF>ba`ha&zi6-vl2;dM=$> zo9eo;NwRC8X9_V!25=6QNglUC8>MpDIZUxlZePR48jA9ZxSXEt_64?caIUPJ=3D0n zG+jC$vkvOO{7NAoOd<J&`;?D$q;U5)<$RQBQJg`zEt72SI2_OPfkHG=0G1zCiJ2f2 zqA&UyVi8s(CChrpS8nAz^c}}{@qFcUi#ay(BI~Ql+)R-9NBB9J&}n>h1%rBm`%=Zq zuM4$XhKAmM>kxV$DcmL^<LCsoV{%evI8Ax%4+A1d(A+_0DRSq^h7bVTMmUN25T0If zlA&1a-oS2snKH73S4kfG9^I2CvvHA5zzd^<3<T`U%T5<Khw6pl=k8ugAES82$Xeec z%b&ZRm7pU!eMHg!Y|ybT8#mB{Yqqk};Jip<9Omp-9S?yb<=jh#ymJ#R(bIF7Yi+*g z1;<$%O(VNmv@l_pMrHwhyluJt2-YcsSC=Wvzq<4zmzX}1zcVR{iZ2~0ervXjgkdLc z!}>A@5l?-QoNH*kB04Bcwy?ggKadNnUwdHO3iWNn(76`JY5zwf`JOTP#Kn4eS)&bT z1=Kwi_gIJTM1421CuFmiXi#TU!U$K-@UDN*e~#Iim#%qj9--IrH2{`ZM+8eScSE3y zaxb?0=z4doAgFAawX2P3C<a9;YHu=YJtL$pbs0ONzwr18)U}=}A{cYH06|Eo0oM)H z=o>OgX{`xl2y?C>Y;78$X`T-q5{MRcd(|m|2jRM?X6#Dhy+#Gyh2qEE@xGWLcrc#@ z@pVlY7gh^POJ=n^R}j@ArJC?-Mgu!U`5i|GaL&U|K45u&LjK-*f~ViN2SqQW?3N=H zTaO7kBde~8rJ&#m0?Sj+TffRjdj4wBuD*BD2b4{+=d$jx6kO?IxifCMlatOXWBfL& z$EGX434baCHmPujw6U;Z$Fh10lh&3TECi=Ne5S3<U<xUwa9OIVH*<LM@TGH-9F72< zn@<F+SY)q@EJKu$9ohw<9}!z3gt*xtWFiI`LTatO{@Ae=A&JxTtSUxwlp!}ZXZ0x} zgwD7M`^82O;=U`JoxZTqYcwPXh=C68$dTi7!!n+q(QR*dYQyE6TLT6|BJ!=Ei+c*8 z2fO1U6UV4TRSBHtXW(_P^bq;|kZYrqYTD^7>`|5+e{_P)tOJL;v@V>~IWNbQpJ3JI zmIp}j_<|v6^mCg+!J{Gh{yZ*|;;T(~kw@pY!R~+DV=ejv$?-a%jNF<<Cd;)wrt=D9 zZ->%n81J=EtrJ@OHQSx|__<c+SrP8{Y1rgl8xU{`fE{U{7Rr|<HtR}ct+e$3OnumP z6h2zv76zu4N^>Y^(<EygRR33#Sj-Wum%41D;ie#YJTmLfl)Y@ERH^h9q>x@gc2?)7 z!tsrnK0-#ht+2MU8*S>c;R=(snT5~@uHuKLMa+doUnh(v0@<zKJI1Od@y$JDw@RzV zD6+RG);NL)T6I)b3oQ{Z8u3a>$IEOPbK=kFXd(A05%wNX;1zLgNTy)-B5skqK}4rH z{-N2RT|T(-sklFifT?v86aA9}3-a{ltVE4OfT4au@TCfY-6ru>YTAtNXrXo~D+UA8 z0&1*7+VLf*jCsQu^a^SiB3$W|9QHjJ!pd@Hg}C@c8|(E9SE4#@(I$6T_o8aIS(QXU z;T|HQX&4@E15UKr8;T;eOSaG&&<FvC_&2zAt0+-J4JkX&n0fwl2_#1mg+O@}OjOGF zm7LZh(IT#r7b8dZNE;`=g#{9+Ms=1f`oT2_KFtv(+ytUhC*F9ep0dJ+om;(xL?k^{ zQ#$}*yE)7{eGqm*Zp`Ax<>;s6-kB=mwsyMuMIdJ=Qd>6i;k$sTryL`X2gu*joz!TS z%p{SbS}Q`N@<n%^mEw=j#O4&|*FM8@vAQUXlM>Ddo*tsstn`($#DNyAZulnjM6&&2 z7GSBhDr-gW72oG%84J;9kP*Rfdn0FNqLv>cND%S<hG5p1yVS<tgLTyU`cr_!IJRS; zksSSXn(h$W{7y!;$tk#XBupG*mdf@eBlzc~#wuHrom@Oj)(ss047>gxBe0G5ZnmP; z>Bh#A3opSdmcv0eGX1KJ;ApzvY>2I#bWoY`pDvuPf-O2+TDQ*h76OHEo_y{^vh<(x z)Ewo%GKe`A_t#;5Qv&0V@i|%BX<)y5(XE$!4AX<T>4dK!GbtcZ5q)$1!ri0{9R5TO zZ}-*D8|DswD|2jiGY04UPYg1rqQ>91O(zoEovr7*kCsXswrb}+LW`M~o*+fRmO8{y zS6&Y`)*ZOx`GAEmV$qII<q6^k)=Qyjed%J-?LVU=dTpSgMav!y=tPGbZ}L)uT_v zLdC>)K^(fT;t|naVG{1&Dckd`3Qi|w^rT4Bal4{r#JPdH7I=I|RX`n`ECej*2-Zf2 zEkkJ;LM23E8Cq3n1J77v#effAUCpX+UU&sFDz;n8<fOq?uKb*G(k(LE|9U(622VC# zGf5+T_Ges@`)cMg429|zB98u7KA+qxu8XEah-);5w3Xoa2A1pn{)ieo<`h`ii<evD z25PaaM0j;MpMK<UrgXo7$Z!1s)UBI=Fv^W+-nFiN@+@SEez|RD)6nyKiKpE9v~CpJ zR*c{-c}ijnK3k6nF=a=kbG`Tv$tX8Y!jHP2oenl#ramWctF;H;jGf}6jny*hH5#?( zGt#Na^*L1N+p5B>aqfIT`({lYqghlF3Dd+#c`7~ka=lpUP3)STlE@UWU18e%1SdJ? z%gl>90@IDd>YSC8wN58xTTk9^3A++ddK36hIphl8j&~V6qo*8SS%LIiJbVlPo=Dn1 z%o_S+E|J1I1Xi2iob;p)@ru!1ckub{sICgC(51y{4(CT-abkx9N8);(?AR&pEzQOV z6nvPy9XEs6dB~?Y1md=V==QoqR4?C`bBQPo(tGTX*_}1Tn_>PivC8bzrYe64{v`(7 zKM;(7vdi?tfK!+_JqmhwW9NzVFjqx2aK0;xb(b{UAWVnDE?w9bo2H_c72o`ZvR+XM z1hOvk5@fNr3t0e$e7NiMg^7`4`O~bn=T=?AZ+<&fPk4LG4OYcFrxP)MUz%l`)RbM8 zfWacA;7S`pR(C)L@2<ny5%*!W^v(*OfCHWjQD1DF^W@=Hi0RI0tqt3yw-qc*VtT;m zbLpodZF*w9;QA_YMQ=}l?<6d%+1?4Q`peo0ZLA2nPGNmSl+YCNoq1nDHc3{n#v66k zK2?tEFE5C%NaytFSqbaE`_(b)powe}ZA*G&C(b=@(zO`fsx6|s@`|^DxB3cML2e~b zHd^sLwA8o`R)Pgh^Mh{wmK}+YcK1PcDA;(y_kjfkn)XknV8cZ=O%S?~rr3pWI6~gI z)=RLZ&&cf@{neyBL{`_!HO1*UFKS2Jp%yHix2U^>=S+Po$_7Snh^C{kFQ32OH*t_E zL9JN?+4qF*oFiAn)nxBOsjgXue+bUsD{WOG`l&5Gyd&Dt`Z__B>toSUMfnSKa)qtB ztcdsNetz08!R4OcJk;8q+!G6T*~oV^H$zuK4cPT}STV%AY(+@9v9yRh?8N<z#|nj{ zU7m!Sb|a2PJoRkjP~m_sd0E5#;oZ6x%0%tY2$?j={%d+S>%OuAh}m_qE?1wb(by4O zRtv~q>YU%&!zjb{VozFErXyx*e>89WxL)2#vD~Wtp`o1sLg+)hLYAzQbScYn8V*`p z_ua#z((7`i*nNWERd58qSO1aLNAzvQEO}C=1Ix9kJr{?g@mD^$_1sJK$kgATSlcE< zGSXpU=<?+SAxblAy+&wOyNaoIkY84;Ud*Fg;8xPmrIIVXH_BGPEWSuJ&cEC$#>2H1 zP^=$MK0fQ%{5at=3r@XJQfkw?h+09|XqDeMY_l^uEwAypGZJzymwL{q#?ko(LRUIZ zRaly;$@c<78Tln2nTqiy9v54kTqCaAK+%UMg^sNls7Tj=qir&4m0YbCrl#-T@#9KQ zbo9gOHuIpb3Lm3GC88yL(P1v_xy0B|FYnh39g0(B2$y?Ly8^%BxFYPHw;k8FqU2uk zS%<*bC+}ivkF3V>m*O)Uqpcgd-A;E=geOCEj?4`&#UdRo_|vP0;?He3x8gYc3Ua@# zggv)i9-mP&h4U`5K{R*0vfk1Uu&RJHA!8gh2>6B^_7pkAPA=#oK8DWN{tHw>6+&N% zzLk7lJ|}z`MK!C{LW|8a9W?ThFX1<uYb-?~p^?m!!~TKUmnX0R71qCx3wov~ZL~Gx zox_dr(E`&y&|nF@_uM&sJ(gKnaJB-0eY}<WVR=B(aT;z54GF9FG*!~?0%Y6M;LMc8 zVfOx;(A#9Qovr;dGgjV~b}VV_YghM=-)CbHxAEG2ifwjM>O{pta<!HWg=ljl@q<ss z!hW$11W6DW&0x>4u~Evs8^&7>_ZIpB`C@uZXaD&P2a+($5u`Ql<Yf&fyz;Z<`K#4z zn-_*Izp|N{a9tDXh~Ri*2=)`OWV+yjKJ##9J`uQtn?-n)KC{yyNP-PxSmx2DthFea zy@>oCDF#+n;sYV?cQYQn&NM<4CocYA;kt7y1QS*f;+IX5pr$M+E)V*e9tu^1wF2EY z>0*?>aS%?6UqW3q5w_}g<LU5hSmO<g$sIsr4N1PqWdAZtUX9i1?s^n6)z2(FDyA?m zdQ9V)Psi1AM(%GR@36ecb%aS)VU2}?K-%lG3p+c&mC^ArCUhoV7SA!@2odiWmokFx za)xnN<_Bvqi9|x@QK$;J)thSyq<N)J1oS)~CR@zRNg1@ct>s2m<;HAfBP0=*pHyV( z??A|q4taiI`&JIc7MV0~6FI*1n%SP!5Y@oCxEs1o)CQk72BRUPsQ)Dlxw^u)pxg#g z8(+vDlTY*flgCA{S|YN&Z7>vxy7qV~dNr`V<omzrwHSkf;|q3KbVEIjr64Ke#}jMc zpYqxlLTNgBdPCfUWC31k57vc3#5>`O`qp01Eif`nM@9&WHBHnOdY+u%g5f~&^cdg7 zxkjOVA!=P1GGA$*Qqg`P19(g;@X;mM=bK>V9{##m`vs#`_`yx(YQ*G*;h>IJ9JK@^ zN&hulNK15uz$dHU%&XUqn!nd7VJe({S?j86P`rR%vZuf4YZUSxYHq=ewzt|Ui=7LL zC7X?mj23*+Q|8aB2BT2C{*9PrGXm=M@Hpar*l*CF5v+x6h^B7gMWCo2$i0z)@;hd% z>A(lP8@Oa=9D8QwjV~DA&AOHX4^PfWVv1y&tfi77kAEy<==Q!n+J=&fVZbKK-q=ca zdWvHVE9v+C`AaJ_rez+%8+XkqGM&ESP;-(YYRi~sYzD~rLROyVTG_9y1)P`gd%K?m zubYfxpsl$!KAS#k&)st9j4J*%R((dvJ|}}yt40D|`)<Q_o>%y_4C-j5`e}kwg#Wo| zlo_>`*C-nQTI)riqOwvEw%hYquX#(##+RKDd5O^o)yCbMhq_n`zh2s9!wZHY*f><R z$Vul@F8}((<%J%i7vO+9cs$?O<y&4K8_oSwc`#2ggbyoBKto+xHTalO|10m8m}-Gf zldqq^9l0OJOJKP8UYF3~$r37~SNKAd_WX*7#=*}q`hi0+!}Y?>BM^QjzKHek9ZoiA z?8&k|TX>P3skrAUf<879ns0Gl#9;0VgkqbfHueiV6M0RkE|V^u;{|dKuevs3>eh@w zJ}-5}Snsq32+wu*OY8IaNDcBlX*Ws)lKFT>1C*yhmgBQh6{FF-L?`&o=((YY)QhMR z0%c1(jh(r@$qTx{T;*O@*&P~^bsx?_HNu;Ye506rz8x>m=8Zmb1>YdQnqN_7`t0g4 z^Twdr&pOqhQKF=R#xkTnoDMd+eDrlil$w*4s#OXXQO7}5DAuJvf4GSZcR!WcxX!bN zaoNK!<ga&D=Z><gSm3@Rzb@?M20@&V(^_mLLyIiuLevj%%2j6z*>1qpCTy3F{lt$+ zbbLi*Rbgr4c^V`2gMrw*kHMQAM)U0x2a=3dBB$>Vo=!g_bx3n5pT0m{)MIb7%q1#E zQ^QFT&8V=wq&&XV)4cqMV4^!ntlh`1JBW`*6y*)Mx<FS$pK6qE^i#hs2BUG=ljce? z^)0({A+nb=`00`Kp%4Y64Ciy(@(c3n<B}j>9D}GKYH{3DM3D*0Fh^})0%Ip=Umw|C za#Bct;y_A;G2l1~3A4a1bAHCCa5L8+efSTOgWz26LL&_Az!|9E24rw7WJeV${oOp% z!K{ECTAmjob5Cex`aL-8!9xtmPy-eaPPP46&zG~U8U1|hR1+*}ym{YVt6E*gHVwQt zGFBz}=`%!os(dOOk*@W@bsn5(*eX~EgN;OEq2$Li$Lt6dcB?5eBm)RojT$5OB@FC| z0d3pE6nKv2UZgQnAGJN_1xLMMNyJ|Y3>d%0-;Z=Q<w-BJuCffQs|Ccxr=u|AjY@t0 zpkDW>2GeljJLLi=uTWYG=u<7e;Wro7MKG?EXPh3SAA>pAcO{$k*8&ktD=RgoM-3}F z(N4Vt8iT8HosFImNtL<uCg@{5r<~8Z#=8;`huw(%Jg6#3hb0AP&S-}8R(*vw2JF?# z$c~|xL}rL3yrf_|B+$*!6_*QfG6-HJ5UU>F0%GF&U7HB<m6taoc5ym+z4z2{t_`3> z-f{(Cn6i2waOYTBaW$U$j;Sf3z|Ig)WVFE+G-uOwGB@Go^1i2`4|ivjZU6Q)$rskM z60_GOgE;Cm+$0)9M2KqDC7S3`2cL7Q<5}OzB^7agosH0v$wx`-y)t?-0@q2~mc>~e z6S3gF@s!ffK1-(qs%wmLdnpE6=*N)?%A6V9jDk(3#5=FMZafHc`mOK@2Yv^4v@GnG za(OY1O<=p%NBu7S(JWE=oAQ`rwcu;Vgu5jTrzQnc9IrftnC7&ZO;<rlB4k4e;iRs* zS;z8KB(Z`kovi#Xd4%S7BRB`XZ&^!3j5m*dcV}J+I>e!bn+5XfB=%&$=B)gnTuw<p zXifls(=<5LZohujt}Wc8^P|&CkJ&4Qpn9D_Be11oof^7l6g@RB8eExy_J$k}#m~9< zZO434$@%ZHg=?f~E{ec)_^Ta5TWn6pDzM==Kg1cJP|H$<=VnzgbLH4kR+T`E_oY(5 z9>q4B$m{NnJ@@C4YhQB?-IzI#ysLTm6-wf|`_M(-(Ow)vHfSaFClvpF@@J#R?V7Bl zZ7SDvV1oxb*nh2->R@6DyyG@;0N!wm$x9)15Fva%f|KDVtIs}@_7<M^rDJ;bKBt2C z#z*QsY6f4rm{B*mAEJ^rqN19zQoEHp#k_4N%4nlqke{O9Z$Bl9tRAAZHabp7@2Z+F zW{78Fl?0q8Xc`W!^h3fU`03sZ`>mLMY!rF&Mf=39&782`JA#=tm?DxKg2F>faLWT@ zh>g|7zY;W@I(hT4%P%+mARl89H7y?z$!Gkd+3hYal~9=%(ZKFqEubVC&f{BHoJ{_+ zgQZwQCTfNQrTI#o2@WH!u_pOLEu@!uG6-_IO45@W11ce&Dn&C%MalwgZPGP3i)?dI z4o(!hgTnOr;L%b~&WNdDkfp^ZXOmFA$!V@b@r)rI^g`5Hcyrw)V-r?`aE_*7#<@$v z>R7F&F9WJmm6$U$lTi|{0>>kI#Y!(k8YihXQp-xTf8jR&&UGj54^FLDDO7!FZ`rHI ztu9?))R=%|xYalw)~fs_Mg<tQPw@qRm%PnI%|};-Rrm$n6SGeybqEF=Zf$3Xy8$sm zzNjiTj3wh>)Amh=7MkOYzogi#RP;wLR2tu6k0L#pmhTK`=3v0QpHv_$f|FX`<Mqwc zrZO@8jS5-?N+gXiKEC~|Xe_;#%uy%%f?vf~>Z-uB!IXKT>0n?^HDHXj2s7NqVSZNW z9l>bgg$jMaZ6H0n@{x*fOAcrLGUQ*5$;+c6Gm(YP)6IAs8J&>Lo$hf$z`o>6ukzG{ zp)t86y7+{q2Hd|bjn%xdp17BdN-FNh_wu%o{1=z+MW~F}T`9ZPAwGW#jzb+QmQ<f9 z^0%Qf{xk=Tpr5<B$R*m-%6BEzpe$W^DLnZ+st(Nlm8|e<reIu0ke8Js%$JIk)s6U9 z#~6OQdo=<(rqfv!hS+EbTe_$j<iX~ONEu0mZVU7`%r#z$?!-jDyFZDoY%web%+aZ` zs^g=>VJy_K%y;yf+m2=H(_|`@w)m8L@;~Q2PKQ2zb_A6~CwUg*m=chl(D=GKB$%cu zD{@)fZh`v6vuzM%byZMMo~pB7RLPt=zB!2~j@#!YDYLUOe=mKU6>2W0=ZtAg3ZpX( zKkJD?#MK}VMf5dNa5vluP-DH`S`<!c7$lyCrR#XuDu*@9aFp>jWCAxSH(<UuP)7tx zR?OOOb>dM!+XTg)ybAjn^t5wyfGQpK6^kfsU252N;!_LuZz_4fd1cNa&4eWwMX!2k zFT|YE&!s~Prq<jA!6fEIq%mr)rkgAD++DU$q0yxCF%aMM*;_#9h`(WBD0??+XE^|w zFn37Hg@Wa7HXLK-ncX}asSYAFvWYbl2<0(p+n3t1Gyn2afyK0JnQ*T4jXi9&vtJin zxo;$#NE_7V)YBY%ZZlVDajd7v2;%mR$K=oL9R%b@W0|1&BZjc3V&QnYb4od!8W9hj zfbvcXY;VnVsER+@{Yp<+aS$ODY7i>hb2LO9Kya54eEHLc?>m?Y0(w*}Nnyk<Du?bW zLng(`EiMFSE^sl#^O(=7HOx%>evXi?c-EGi#bes%>>F(QU>N<9`CJ5x4K(Z#4wo_4 z;m^c7O)29}zKy?|fshiN9TxHU6)-af_EBnO+@*AKXo`tSR2-)F&~c<1hAhIFOyM|L z%G4W`+M=~xGIR6GtMijzHUiVT6vJvH*Z$wWC9r`ztg=X1`{IV7U3R2upLsiIePm_Z z0vR29@Q?n^9w0SN5#lzUi;j*I)0Z^D3!b5jMBn&Clc~R6dVZl`_nX0CO`wv9e6*KX z{CY-`RLR50wGmgQ7cq38UDHq`3(|~1_5cEMi<V^|q`3hV=?#Nu1^kt4HnJ^wT~ZzH z9w&Re1<uM^N)~4o!nbe7hMNs8qTi$Wp?{R2P&W>@kX|U&U3Ut<BZzVt#AEH@w(Vy? zoPm8EvLxZQwPy3>z`!~{QMfWntELT?$_?-42eP99$~vtp?r>7@SHI25sEQI|U9t^5 zM_VglrQvST;&O(?^8@0c+2kiIW`)@MBs!(nbV(izaIqVCiS3r7RoT-CC%gMTO(vcc z7H`(IA!iRL1HTCcV9|~)A2HOY{Xp2tx8bedg`yG&|3qBc=!)0QO681Ud=Avuj_d|% zB0S&o<nG$v@hiXC;Tl<bH*&(5A3*-2EYF!)LC^iyoe}DG6}-}i<<xh;3i$WHYDkL5 z^Z37a;~G^1>xY*`QHoE)`Sq|l2n~gz1B9kc0^>z>)Fg=l^$ouGp*tYaiVMeg@5&}0 zOa(NC7!L=^oc06}c9aSV|1`B*@UIhTsz?*{L{gj`E7>h5@i@7>h-&HXc<pm_VlF+P zmyscVUM_GDebABxsaRsR`L4ZD;w{pOZn6vYnfazN!7y9iBu~}4;*U?}8HZqU&~eD- zJVlcYRahfVWX#@L+X~NfHxehoM+wqszIq({uZOLt<hP&3!a6YjKAaal=%4GbG|-J% zE0?3KbZ{9p$6TFe@8Zf|ooMpM;oz9S<k4+3j<;N^q~_O-*W9V@=s+{lHF;%e`c)V~ zk8*dLb|;3;K6J(;fML5~)czGsT0_M&U!kK=;OA5c-)$VAIFY>lE-4pkCK9+E0!aeL z4v1g2!8c6CD-)#e#3E#IDnh0bET%~x%UARkHpQPXsL;#0BYP^)<9U>vy;ks=YK7KD z!FO|IvfO00=OV3~(bPt{W__(RN`oDAyF|rk)XU$q-^%5&`M_$|GP>cK#>`&lEjd8O z6}6s=#mwLgXN8{>bV0l;8kDDO6^4SR7?_|K0v_;*c*ms}dLN{_U$-q8F)Sq-6{(ld zIeMnX_n9aecQcaPS51pPL1GbR!xOY9${r;U@X_AL;IlIkKM#|xRjN72n_a5lHEy7X zf;_TkXf)FE0;loLTn}|SNk&Ns)5)m8GZwU&l4Xiq{~FsH8E(|DIhq54*OT|+?Sz<h z8GiL@O*Mp}(J=qasXT-ctRs><gW(5pt%NpGyZI&4^NUkoh9~w@pR5H192e(*zZlA~ z2g6yj<JDrQvxh%+J`2`pCT_73ME>cxOC7K+KI(|8zU7a2)C=YTLyG$|7vF)hVkQBi zj8j7N=9Ho=BwM*;F2A=r0;Q{ITBlE08782D!-6c;@+gB`O=8`ct=XC(CMVu$|1hA$ z%9AHVHnossm{0iqJB!jIcau~bltg`7h{7i?r#m-T&?2)4$_MDIo-T_l7&2+ul_B#u zOzJ>Ua1Axj*|`^;e)hxhXm*u%{<dY2@%oJU2#HGJg|ti~;{3tYvmY%wz^1+}wOvlf zH1{#Px$}t7$;9FW`mrSM1$9TE%c{#%eyCzZwlg7vSG$&W@Phml*As=_;L+*mTFhx> zl>rL{3*;k~isfhSZjsN+G=exG5QM^q-)HiU6&nUk7SJf2m>^<0GJEN3-xx(ftLbxb zzNUu3h~wX^_9xvYoV#SPlZCd3Q=3qyTW7f_VH0y|$$1hNyAi>pS>1;J#-GEuS0>9^ z_|s+Oy98M!g&T}w@k#Ye3fjaJ7OC%z&r<~0wIZ1uF`UzSdn3(r(o~$*q}_Xjeu!0h zU*OG|KHu>WVON3fugpYUjAk?H<%$eCweJrtar}I`%uYMTh4CG|S$Zl(WsgZuRG0@t z<O8_vF#cz1L>F6j%=fC4wGwjS9}^5EeYJvzpQcU8U7@2X=CKPmpAN^58xp8b$8XV? zL<omi%z@F3h-~A`K3A1Ief^D|{yY!r#%S4mBv^M(0lxr$ck1<@$?0uUQ)B;~i3cP! z(`Wy6+HGv&Vq#@$_n&p88ro5K66htn^*jB8COc`{m+2Iphg?04i+)sONSNIye)?$D zXv9#O#pxT<_It-p)r|$#j9R3fhazr^l*^$Rt!Sm!uw<RM$ctW|8a%s@V2EA1l}om` zRX;T!r70gJv><!@K0ivx=oh<~{IrL>Uie#3O!PNi`7;vx&TmhVrb{#$NX*}uchuk- zet#w<Bdbkf{?=TZ44-*tsytW2CN!HiS9iuH)I{DZQcIhz_KTBt+(~odY2l@yEVQaO zRj$ZW=Rl{<a?&jN15e_?pz{@{z(t8z25XjIVZSJl#t}FeMZ9r3^EnJ+iagh7yeS;f zj5FO?%vG9@jjRvd)DksvW)H9tf9oVO!O58ge|uNpg-&r$nxor$SjMLaKO=ZB_-><B z>o7@HMJ=U5Y#y2^r>h2nPO>|>p^REno<nRF^=X<j8Aizz<&&(!Cuod#7GveL`aC=W z_@2|WL&$~B^}-Ze_Cdy0jzQt$YhNYLqbPV4eBOphjJk=fnk;%@Gi19KIh4+BOXrHu z2cs8%+2pq0oco@*RIEa_hc(qG*;ns%Dm<Tk__kn(Ro-yNTy@z|vv*X39P_Ow)1t)X z%X;D?2-beIAu3ynCgDC9tr2hE?^3A@O-o$w9M{_>bN0Hq#$5BcKJvq7o(73reGp%8 zP=9i6H)_53VSE|Gg1+S44dFo(zTC9RrFLCA1$xF>5ZjZ2qOi_RFaxnCXdMGbP*d-| z>*3N8i9q3s|14iKNLMnA?{haZewK%@K8iuFkYnP&2ll*fcu$#`_9q!nsu)D~6D6h3 zb(k$@zdS>XgGA`%-eKpUdUL54swRqu<a7mW$7LpBZV*765Dji{>zb~grk3LF@J?hJ z(0nSW6J*s4-CUb!8JPhWRy2p_z!JqfuqKq{8E1}Ep((zp**>WVIiCuw@8<}Uv(o*< z=C^UMvBAeT4oWvT1U}kyOg^>Qm#A4$yjIa%`_1`IAook{#OcPUsi0mB^596x_7UeN zaP+kFqJtQ#g*Q`AzmkU6+sRbnn(UR+o|;YU;k}Dl8J-NB(Yi|Fz^kvK3A72VqwN9N zBZs>W!r@iY|7?B(UF1Slgg`QI<JjfE^s@xN#1UJsJt)-**7@VhChZqIwGE61F8zt0 z9QR}zmdo9AG2u!1HCDr7gB6UlPNBGxr?0kRllYxbsuXPss=DojI$hS*7$R|Ws8zew z-G8y~W6F6-1zXw;Ijgy*Ez|^+oI?%SwOU*mC3l@#?VH>D>MkA&bo?Pi?Wz-&OCb4r zj3D>y604Yc=u6L!SH|j~$T6cY$H$t&ilQF%vK{Y_ZPq?e(U`{I5y+x{dYg>DXSRRM z`+<(4A-VAwIp2BjrI^=`f?+68%$Qj+wu8!;Um(v{O<}?x6YDziuAf<O)0x!sWR`$t z3<UVT?Oz83bYRinz%t?Gx`x*h86xtBxg_I3e%58C;|=|^=AMdOSfPU1&N<0LxsT40 zhC)We6{+m9NJYip*UD~Mul1EJPqvFLR6*LFZA9R!<NK?tl+M<f;L@NAVeMewJ@s}= zAJFf3<^TwZ!=RNu_e2MicX>%*nA8K-6i-!NsH7(EAim5U1D@zq6?TP}jL$=U@y+70 z2w@%QgcN%9**!+yUHg<zVT+Sy_X+&LPn}m%TnYUhTCbptSr{GGZS5x%v%5l=DF?zP z&mmY=^Mesc5a-QY6ur(UhGD4BlJ>-(J;gb$UyV%l^Bni?+u-FLM6{5rdp#xU-iOUz zqVU_<u&XwWpCCzn<fA6@vfh_Mgx>yDU#!rvH?@QK-PGN49<wX0mL1^@nvg~_3`R)o z{<-8SNO`DuWP*uQp8J|FtLZC{&81uL$bNtoYs8oI_$3+>RzFovR8}Ho@ps@&_&SWK zx9XsNJcLV*4I-1ksGr+}0tY9acS=2!(|+9u{&qP=C*;jS%_&7{p)c97Zu7tzj)^Te zA2SQJ<Rk;zs|BmhZn^maq9P*^?zIh`SBF8kqL)cZ!G{w}@SA*r*GV^F20OJhsqMTs zyz9v-c2S38z8oDLG^D|;%WK@`l|Eo)TH6$1$C30`{W%jtRqyDp<_jQl;l4+%lC^>3 zNwnl4bVF0}`NvsCuOQ9p!p-wvZgT~6sb2nO@pG9v_u%?XS<`+VzSSRXctHp&#Bt#A z^<|tj)OUYTlyq5B{@;sBx)8&xkueZ*{-Z0O2;a`D*mnz$blu>T#SJLC*o{8jL@cyU zi4B3;|Egd_b}AMeO-r+1@qBF~V?v{vbwbg$leJ(3-&a$&fSqkqQJi(nEL=se<Xh$I z0F@gK#9s(I2oMF<XV5Rx_B|G5SK>MxHr=wruUmOlgAk3kq>dA*%*zlMr$5TjnXMn= zqIE5CDhgu9rh5qy4P(TEl7AZ@4pT@3i5`B&Gwb6}2vszm{B<L(@{XmkLn18vht)E3 z=Q6^8kJQ-7QAtN;;90FuR~}@`<*89gG*fS;|4&N)Pt8;)My&Q?c>d=n1xF>0DMYg* zAid1J#5(ug`2AwyYx466YU;CWOUB0bBWy}N4C&O^pQn1)YE!1jV0@M=S%lADI>7Z{ zQxhlF?ex>LDzw{u9|~1UqO<u(P=20p%w`7uCh#hOz65!ba=gsxZ6yXHg|j^28$GMf zSPH9pvifGt&u}kYIW>@&>p#b-6Q~V^&aot^8~u_my99P^_qM$C*Hf)y5p`L{{v|P9 zjVd7V>udza=8#6Fs<g$!NOr`flY$o4`UMifXO3P4jXEkjFN==_!=4C{_-9I%!&q-Q zz?N8o_MW!|ye=Ou<!kn?`gJvPW!6;X<41V2CvW$Q+HVK1%+KF9jR8iDh6a_5cQ*W6 z>L!y4S#drJt>{X0Hc@E>e~Mp(72iiM-r_OA==P|Nz#^9j?|1YVM4#x@l%V5S(XT6m zqT~*)B4Y`V(6=qDMo&(3TJaa1v{j#3@LDH4k0Uw3;Z@nPalV>soNL-GVMpVr#Bfyz z<DI%T_?m32;qc5f1)7RJog4WjgTKyn-?y#fvE2N*fgq0Az0V{vB<ABB^!(!!=KCK* ze`ACVLZ*cH+0P3vdZrRBVz@+`j@GVy-ueZvAOi;e><KW90>OZ8XI5gq);q_*=DB&O z+u!`Ts{A~FN1Tr4|Jhw?^sp7<4QJ4#CkXV-5DWx7FZ}1K@{0o=A=+7*>N%J=+B!QJ znf#~P-`(c7JN6)H;AIcAL7+xCFc8W=jX|I)zhu9EH^19D3wQ?m6OAIp5)hdOm=FS6 zWB<9T{Oafa5&3STTRngO3`SW2{*)8Y>i$<sErLKM29EA}|94w_JA=I2`t~bz<Qv4y zf!0325Ar`>cq_2Z&wsVP+xYgY;TsxfX@N$!KN$BK9|DcVBqZpiUWm&xI@#LkS=~-z z8Jygl9x^_}r7wO3MCSzDbnCpouPQ&qr8^8|c~vD5G3AGZ8wC~KSg1)Bz-S-<^1x+s zfL;EP!o%E--qGNd$wL9QEq4#>fWnSfqz{|FzS~?u<}Ym?Hm?j6$g>6ZGWP&J!~R=% z;Pb|h;PB43n*h~w-SzBj&24}pVUL*Mt`hinFjan?$9FKsCUzz^#wIpK?s`_{HkOZ~ zxW9Vh;sFMs1}q93vi#3g<p+LpuXZJH{D+B+qq(ik!@#(G9}w@aXpsk)R0w$Dg82{Q zHZWAq|10I8ao)k`8l3}S6-@ImK$tJ@K^%b^nufM+4+XjHQkT2<osfWWNr`}$6ZZts zg#)`=it`WSp%{gAs$ru5LLCUw+kLcuUsZnZ(e5D(9E{A&T}<?xoy@Hs%5od<%0YD; z)N~-w4A5n6H?IGERr!6uzX!52FtRi-H352_vB{%amAFMfRRd{B2=LH-t)58VBmL#^ z+hp@lE0Q_qJx(BS)q$59_j})#(tknR>;5`n%Dmfln!O=_he7ZU8ESg>7<zyz=1zKg zkH{fgUCXNsq$_)*hmrEs_`fmk33BV@q>>8O10Z0@fLObIN%Qwr<(Fi65Awi8ca3t( zsS5n*JWB|q5@!$y^=}C9S>@O6aF6qUMa%BCzct7bhki{tVANap-fe&5HyCrTy^)nU zgNfU{Y;ybkld%#4m&8D9+dK@l(u{lUA4bSsL2g5hpwJgr9Z0P8fFfx36#3b95A=VE z+_UJdCdr=d6-AF~VzF}%VCwuYO>PBfPoKJ}19}UlI?(s-2_SxXul?=IGe^eT|Nr~g zC~MBeeZrm;>j>ENvkVACat|ng0e-h5{}<q03*GXx+Tu|M;6Na5riY#Jkm?cM|A=5C zLNbrfz-W)a@z<I3e+yUTcftC<N%yRNYqi-|Pys!_a4-kV7AXGa0H0NU`(lrv{$sWO z3x!8>#Vs?rQPMWo0t8|c1bdKmt|cE~8rvG(Vjt$OTa&fJ@0n`>N&O6vko=x>vz3pK z9+U2_7jDOilUFWq0>&Vae-PM%-0EKa2=b3`cR{yW2KKLaO9EDV38bR?Bj5q{le^*Z zcgf{{N`%~V!fhwaTcKsT&5R)Wzv|`ut!b5?6XBz%zs>>u>o}~ta=id-29vGp@d3!x z7r^L#Kj*L0J_>WTv$8cXek4&A?{B&sA_7w#qKBk*wns^SS5~~I;H|B=$)3M(1O_xm zAY0zI)voa4Bokl~_OFo8j#TDN>$`5N1;SwqQ1N~@PnCTXW%!?s?ykUaVDq0KyKApo z*<dtKE(QSOPXmGhiTIxjm_f@w4*YWn>%SD09GDq~2Zn`cU~B>Q-~V$}`K9YT3i~fp z-P@=*<ilRI2YR_T=R?+t;iD{IGe0ouy|R7a%J}qD_T7&sDz_7E2f%Xo<%)57l=VNd zk0+>?^Z;PV0CTqc27`3@|FP~F?6x~9cZGZI0llaR7&GoiE34b1Frb$CUy<?9kAfw$ zyTDWglm)1GUo0J;M@e^<hujm(7>tbb#m*5d0w7j6;K%!Eaq0D=u)p8r{TCnH`ZG>L z-$E3aJE@946p%IOQRZKf`&WsEyV~9^68U&k^Tr$yFdCSx-tSRW$&bSR1lnEHZ3lSI zLAP`S_)-w)pk)6<?ClVs@!?U_!ya|ddKZy39Iq)gIiLXI1~ALI?}~`*|3P%Hvwje| zw-G{WS&(H4z-j>Ti0_Fv{OM8H->$GSH+%#)a=q$l0))x(zj}g8;iI@amC7DkPSF&! zZUfvsb1gp1MVQ5pvi{fI?X4?1_j+&|0k0+j`H1A6u3az?kBuq!b-m|^Ti*O<ZZv3M zy1W4-OQL(cHl#;+f4TNAN8F>`#vDVIhHEE~+?s*=-up2Jh4v`z&zqo!mOIAwUaSR# zf&@_a?{FY-9z{JiL%8i!nEA?^Mxr2)4serq-(n{ukAfb!;Gtl!h4te-z{q(h_%L)6 zO&{m|NxJt8c5D8(xNBHrKp(gUvN+{E^QZYe3j5ogce2R8px!=o8;n4Fv;ucx_q|XZ z`Y80D@%<j^wrf2+ar|!)tNaM#A4T0cfBd209v<TPhlQ2#KUjawVeUzGYq^IfSp1=x zmpw}RyROtd(qlEz|Bwu79wq(lgFhA0@2dJ(jp;u~<N8ODf6t5Vf^M~ZSSRrhXrujc z(4DG@cVV~Ad|0IJ53K&nqp*MGqjyQSed=KuuRo;4o<~W48~-loR=<a3i2i^q`X2?| z9r5mY@>aozD?b0w<hCBA-5KETO7_?q%Rem2?MGSvmw)bZZZ&+k#^(=b@8D6+zoYA( np0~`0uh{=EJ5L{F{z<a{3ld1sAkYiopDOT>1rG#_CZPWZsErhz diff --git a/test/lib/python2.6/site-packages/setuptools.pth b/test/lib/python2.6/site-packages/setuptools.pth deleted file mode 100644 index bf760205..00000000 --- a/test/lib/python2.6/site-packages/setuptools.pth +++ /dev/null @@ -1 +0,0 @@ -./setuptools-0.6c11-py2.6.egg diff --git a/test/lib/python2.6/site.py b/test/lib/python2.6/site.py deleted file mode 100644 index a49cfc34..00000000 --- a/test/lib/python2.6/site.py +++ /dev/null @@ -1,713 +0,0 @@ -"""Append module search paths for third-party packages to sys.path. - -**************************************************************** -* This module is automatically imported during initialization. * -**************************************************************** - -In earlier versions of Python (up to 1.5a3), scripts or modules that -needed to use site-specific modules would place ``import site'' -somewhere near the top of their code. Because of the automatic -import, this is no longer necessary (but code that does it still -works). - -This will append site-specific paths to the module search path. On -Unix, it starts with sys.prefix and sys.exec_prefix (if different) and -appends lib/python<version>/site-packages as well as lib/site-python. -It also supports the Debian convention of -lib/python<version>/dist-packages. On other platforms (mainly Mac and -Windows), it uses just sys.prefix (and sys.exec_prefix, if different, -but this is unlikely). The resulting directories, if they exist, are -appended to sys.path, and also inspected for path configuration files. - -FOR DEBIAN, this sys.path is augmented with directories in /usr/local. -Local addons go into /usr/local/lib/python<version>/site-packages -(resp. /usr/local/lib/site-python), Debian addons install into -/usr/{lib,share}/python<version>/dist-packages. - -A path configuration file is a file whose name has the form -<package>.pth; its contents are additional directories (one per line) -to be added to sys.path. Non-existing directories (or -non-directories) are never added to sys.path; no directory is added to -sys.path more than once. Blank lines and lines beginning with -'#' are skipped. Lines starting with 'import' are executed. - -For example, suppose sys.prefix and sys.exec_prefix are set to -/usr/local and there is a directory /usr/local/lib/python2.X/site-packages -with three subdirectories, foo, bar and spam, and two path -configuration files, foo.pth and bar.pth. Assume foo.pth contains the -following: - - # foo package configuration - foo - bar - bletch - -and bar.pth contains: - - # bar package configuration - bar - -Then the following directories are added to sys.path, in this order: - - /usr/local/lib/python2.X/site-packages/bar - /usr/local/lib/python2.X/site-packages/foo - -Note that bletch is omitted because it doesn't exist; bar precedes foo -because bar.pth comes alphabetically before foo.pth; and spam is -omitted because it is not mentioned in either path configuration file. - -After these path manipulations, an attempt is made to import a module -named sitecustomize, which can perform arbitrary additional -site-specific customizations. If this import fails with an -ImportError exception, it is silently ignored. - -""" - -import sys -import os -import __builtin__ -try: - set -except NameError: - from sets import Set as set - -# Prefixes for site-packages; add additional prefixes like /usr/local here -PREFIXES = [sys.prefix, sys.exec_prefix] -# Enable per user site-packages directory -# set it to False to disable the feature or True to force the feature -ENABLE_USER_SITE = None -# for distutils.commands.install -USER_SITE = None -USER_BASE = None - -_is_pypy = hasattr(sys, 'pypy_version_info') -_is_jython = sys.platform[:4] == 'java' -if _is_jython: - ModuleType = type(os) - -def makepath(*paths): - dir = os.path.join(*paths) - if _is_jython and (dir == '__classpath__' or - dir.startswith('__pyclasspath__')): - return dir, dir - dir = os.path.abspath(dir) - return dir, os.path.normcase(dir) - -def abs__file__(): - """Set all module' __file__ attribute to an absolute path""" - for m in sys.modules.values(): - if ((_is_jython and not isinstance(m, ModuleType)) or - hasattr(m, '__loader__')): - # only modules need the abspath in Jython. and don't mess - # with a PEP 302-supplied __file__ - continue - f = getattr(m, '__file__', None) - if f is None: - continue - m.__file__ = os.path.abspath(f) - -def removeduppaths(): - """ Remove duplicate entries from sys.path along with making them - absolute""" - # This ensures that the initial path provided by the interpreter contains - # only absolute pathnames, even if we're running from the build directory. - L = [] - known_paths = set() - for dir in sys.path: - # Filter out duplicate paths (on case-insensitive file systems also - # if they only differ in case); turn relative paths into absolute - # paths. - dir, dircase = makepath(dir) - if not dircase in known_paths: - L.append(dir) - known_paths.add(dircase) - sys.path[:] = L - return known_paths - -# XXX This should not be part of site.py, since it is needed even when -# using the -S option for Python. See http://www.python.org/sf/586680 -def addbuilddir(): - """Append ./build/lib.<platform> in case we're running in the build dir - (especially for Guido :-)""" - from distutils.util import get_platform - s = "build/lib.%s-%.3s" % (get_platform(), sys.version) - if hasattr(sys, 'gettotalrefcount'): - s += '-pydebug' - s = os.path.join(os.path.dirname(sys.path[-1]), s) - sys.path.append(s) - -def _init_pathinfo(): - """Return a set containing all existing directory entries from sys.path""" - d = set() - for dir in sys.path: - try: - if os.path.isdir(dir): - dir, dircase = makepath(dir) - d.add(dircase) - except TypeError: - continue - return d - -def addpackage(sitedir, name, known_paths): - """Add a new path to known_paths by combining sitedir and 'name' or execute - sitedir if it starts with 'import'""" - if known_paths is None: - _init_pathinfo() - reset = 1 - else: - reset = 0 - fullname = os.path.join(sitedir, name) - try: - f = open(fullname, "rU") - except IOError: - return - try: - for line in f: - if line.startswith("#"): - continue - if line.startswith("import"): - exec line - continue - line = line.rstrip() - dir, dircase = makepath(sitedir, line) - if not dircase in known_paths and os.path.exists(dir): - sys.path.append(dir) - known_paths.add(dircase) - finally: - f.close() - if reset: - known_paths = None - return known_paths - -def addsitedir(sitedir, known_paths=None): - """Add 'sitedir' argument to sys.path if missing and handle .pth files in - 'sitedir'""" - if known_paths is None: - known_paths = _init_pathinfo() - reset = 1 - else: - reset = 0 - sitedir, sitedircase = makepath(sitedir) - if not sitedircase in known_paths: - sys.path.append(sitedir) # Add path component - try: - names = os.listdir(sitedir) - except os.error: - return - names.sort() - for name in names: - if name.endswith(os.extsep + "pth"): - addpackage(sitedir, name, known_paths) - if reset: - known_paths = None - return known_paths - -def addsitepackages(known_paths, sys_prefix=sys.prefix, exec_prefix=sys.exec_prefix): - """Add site-packages (and possibly site-python) to sys.path""" - prefixes = [os.path.join(sys_prefix, "local"), sys_prefix] - if exec_prefix != sys_prefix: - prefixes.append(os.path.join(exec_prefix, "local")) - - for prefix in prefixes: - if prefix: - if sys.platform in ('os2emx', 'riscos') or _is_jython: - sitedirs = [os.path.join(prefix, "Lib", "site-packages")] - elif _is_pypy: - sitedirs = [os.path.join(prefix, 'site-packages')] - elif sys.platform == 'darwin' and prefix == sys_prefix: - - if prefix.startswith("/System/Library/Frameworks/"): # Apple's Python - - sitedirs = [os.path.join("/Library/Python", sys.version[:3], "site-packages"), - os.path.join(prefix, "Extras", "lib", "python")] - - else: # any other Python distros on OSX work this way - sitedirs = [os.path.join(prefix, "lib", - "python" + sys.version[:3], "site-packages")] - - elif os.sep == '/': - sitedirs = [os.path.join(prefix, - "lib", - "python" + sys.version[:3], - "site-packages"), - os.path.join(prefix, "lib", "site-python"), - os.path.join(prefix, "python" + sys.version[:3], "lib-dynload")] - lib64_dir = os.path.join(prefix, "lib64", "python" + sys.version[:3], "site-packages") - if (os.path.exists(lib64_dir) and - os.path.realpath(lib64_dir) not in [os.path.realpath(p) for p in sitedirs]): - sitedirs.append(lib64_dir) - try: - # sys.getobjects only available in --with-pydebug build - sys.getobjects - sitedirs.insert(0, os.path.join(sitedirs[0], 'debug')) - except AttributeError: - pass - # Debian-specific dist-packages directories: - sitedirs.append(os.path.join(prefix, "lib", - "python" + sys.version[:3], - "dist-packages")) - sitedirs.append(os.path.join(prefix, "local/lib", - "python" + sys.version[:3], - "dist-packages")) - sitedirs.append(os.path.join(prefix, "lib", "dist-python")) - else: - sitedirs = [prefix, os.path.join(prefix, "lib", "site-packages")] - if sys.platform == 'darwin': - # for framework builds *only* we add the standard Apple - # locations. Currently only per-user, but /Library and - # /Network/Library could be added too - if 'Python.framework' in prefix: - home = os.environ.get('HOME') - if home: - sitedirs.append( - os.path.join(home, - 'Library', - 'Python', - sys.version[:3], - 'site-packages')) - for sitedir in sitedirs: - if os.path.isdir(sitedir): - addsitedir(sitedir, known_paths) - return None - -def check_enableusersite(): - """Check if user site directory is safe for inclusion - - The function tests for the command line flag (including environment var), - process uid/gid equal to effective uid/gid. - - None: Disabled for security reasons - False: Disabled by user (command line option) - True: Safe and enabled - """ - if hasattr(sys, 'flags') and getattr(sys.flags, 'no_user_site', False): - return False - - if hasattr(os, "getuid") and hasattr(os, "geteuid"): - # check process uid == effective uid - if os.geteuid() != os.getuid(): - return None - if hasattr(os, "getgid") and hasattr(os, "getegid"): - # check process gid == effective gid - if os.getegid() != os.getgid(): - return None - - return True - -def addusersitepackages(known_paths): - """Add a per user site-package to sys.path - - Each user has its own python directory with site-packages in the - home directory. - - USER_BASE is the root directory for all Python versions - - USER_SITE is the user specific site-packages directory - - USER_SITE/.. can be used for data. - """ - global USER_BASE, USER_SITE, ENABLE_USER_SITE - env_base = os.environ.get("PYTHONUSERBASE", None) - - def joinuser(*args): - return os.path.expanduser(os.path.join(*args)) - - #if sys.platform in ('os2emx', 'riscos'): - # # Don't know what to put here - # USER_BASE = '' - # USER_SITE = '' - if os.name == "nt": - base = os.environ.get("APPDATA") or "~" - if env_base: - USER_BASE = env_base - else: - USER_BASE = joinuser(base, "Python") - USER_SITE = os.path.join(USER_BASE, - "Python" + sys.version[0] + sys.version[2], - "site-packages") - else: - if env_base: - USER_BASE = env_base - else: - USER_BASE = joinuser("~", ".local") - USER_SITE = os.path.join(USER_BASE, "lib", - "python" + sys.version[:3], - "site-packages") - - if ENABLE_USER_SITE and os.path.isdir(USER_SITE): - addsitedir(USER_SITE, known_paths) - if ENABLE_USER_SITE: - for dist_libdir in ("lib", "local/lib"): - user_site = os.path.join(USER_BASE, dist_libdir, - "python" + sys.version[:3], - "dist-packages") - if os.path.isdir(user_site): - addsitedir(user_site, known_paths) - return known_paths - - - -def setBEGINLIBPATH(): - """The OS/2 EMX port has optional extension modules that do double duty - as DLLs (and must use the .DLL file extension) for other extensions. - The library search path needs to be amended so these will be found - during module import. Use BEGINLIBPATH so that these are at the start - of the library search path. - - """ - dllpath = os.path.join(sys.prefix, "Lib", "lib-dynload") - libpath = os.environ['BEGINLIBPATH'].split(';') - if libpath[-1]: - libpath.append(dllpath) - else: - libpath[-1] = dllpath - os.environ['BEGINLIBPATH'] = ';'.join(libpath) - - -def setquit(): - """Define new built-ins 'quit' and 'exit'. - These are simply strings that display a hint on how to exit. - - """ - if os.sep == ':': - eof = 'Cmd-Q' - elif os.sep == '\\': - eof = 'Ctrl-Z plus Return' - else: - eof = 'Ctrl-D (i.e. EOF)' - - class Quitter(object): - def __init__(self, name): - self.name = name - def __repr__(self): - return 'Use %s() or %s to exit' % (self.name, eof) - def __call__(self, code=None): - # Shells like IDLE catch the SystemExit, but listen when their - # stdin wrapper is closed. - try: - sys.stdin.close() - except: - pass - raise SystemExit(code) - __builtin__.quit = Quitter('quit') - __builtin__.exit = Quitter('exit') - - -class _Printer(object): - """interactive prompt objects for printing the license text, a list of - contributors and the copyright notice.""" - - MAXLINES = 23 - - def __init__(self, name, data, files=(), dirs=()): - self.__name = name - self.__data = data - self.__files = files - self.__dirs = dirs - self.__lines = None - - def __setup(self): - if self.__lines: - return - data = None - for dir in self.__dirs: - for filename in self.__files: - filename = os.path.join(dir, filename) - try: - fp = file(filename, "rU") - data = fp.read() - fp.close() - break - except IOError: - pass - if data: - break - if not data: - data = self.__data - self.__lines = data.split('\n') - self.__linecnt = len(self.__lines) - - def __repr__(self): - self.__setup() - if len(self.__lines) <= self.MAXLINES: - return "\n".join(self.__lines) - else: - return "Type %s() to see the full %s text" % ((self.__name,)*2) - - def __call__(self): - self.__setup() - prompt = 'Hit Return for more, or q (and Return) to quit: ' - lineno = 0 - while 1: - try: - for i in range(lineno, lineno + self.MAXLINES): - print self.__lines[i] - except IndexError: - break - else: - lineno += self.MAXLINES - key = None - while key is None: - key = raw_input(prompt) - if key not in ('', 'q'): - key = None - if key == 'q': - break - -def setcopyright(): - """Set 'copyright' and 'credits' in __builtin__""" - __builtin__.copyright = _Printer("copyright", sys.copyright) - if _is_jython: - __builtin__.credits = _Printer( - "credits", - "Jython is maintained by the Jython developers (www.jython.org).") - elif _is_pypy: - __builtin__.credits = _Printer( - "credits", - "PyPy is maintained by the PyPy developers: http://codespeak.net/pypy") - else: - __builtin__.credits = _Printer("credits", """\ - Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands - for supporting Python development. See www.python.org for more information.""") - here = os.path.dirname(os.__file__) - __builtin__.license = _Printer( - "license", "See http://www.python.org/%.3s/license.html" % sys.version, - ["LICENSE.txt", "LICENSE"], - [os.path.join(here, os.pardir), here, os.curdir]) - - -class _Helper(object): - """Define the built-in 'help'. - This is a wrapper around pydoc.help (with a twist). - - """ - - def __repr__(self): - return "Type help() for interactive help, " \ - "or help(object) for help about object." - def __call__(self, *args, **kwds): - import pydoc - return pydoc.help(*args, **kwds) - -def sethelper(): - __builtin__.help = _Helper() - -def aliasmbcs(): - """On Windows, some default encodings are not provided by Python, - while they are always available as "mbcs" in each locale. Make - them usable by aliasing to "mbcs" in such a case.""" - if sys.platform == 'win32': - import locale, codecs - enc = locale.getdefaultlocale()[1] - if enc.startswith('cp'): # "cp***" ? - try: - codecs.lookup(enc) - except LookupError: - import encodings - encodings._cache[enc] = encodings._unknown - encodings.aliases.aliases[enc] = 'mbcs' - -def setencoding(): - """Set the string encoding used by the Unicode implementation. The - default is 'ascii', but if you're willing to experiment, you can - change this.""" - encoding = "ascii" # Default value set by _PyUnicode_Init() - if 0: - # Enable to support locale aware default string encodings. - import locale - loc = locale.getdefaultlocale() - if loc[1]: - encoding = loc[1] - if 0: - # Enable to switch off string to Unicode coercion and implicit - # Unicode to string conversion. - encoding = "undefined" - if encoding != "ascii": - # On Non-Unicode builds this will raise an AttributeError... - sys.setdefaultencoding(encoding) # Needs Python Unicode build ! - - -def execsitecustomize(): - """Run custom site specific code, if available.""" - try: - import sitecustomize - except ImportError: - pass - -def virtual_install_main_packages(): - f = open(os.path.join(os.path.dirname(__file__), 'orig-prefix.txt')) - sys.real_prefix = f.read().strip() - f.close() - pos = 2 - if sys.path[0] == '': - pos += 1 - if sys.platform == 'win32': - paths = [os.path.join(sys.real_prefix, 'Lib'), os.path.join(sys.real_prefix, 'DLLs')] - elif _is_jython: - paths = [os.path.join(sys.real_prefix, 'Lib')] - elif _is_pypy: - cpyver = '%d.%d.%d' % sys.version_info[:3] - paths = [os.path.join(sys.real_prefix, 'lib_pypy'), - os.path.join(sys.real_prefix, 'lib-python', 'modified-%s' % cpyver), - os.path.join(sys.real_prefix, 'lib-python', cpyver)] - else: - paths = [os.path.join(sys.real_prefix, 'lib', 'python'+sys.version[:3])] - lib64_path = os.path.join(sys.real_prefix, 'lib64', 'python'+sys.version[:3]) - if os.path.exists(lib64_path): - paths.append(lib64_path) - # This is hardcoded in the Python executable, but relative to sys.prefix: - plat_path = os.path.join(sys.real_prefix, 'lib', 'python'+sys.version[:3], - 'plat-%s' % sys.platform) - if os.path.exists(plat_path): - paths.append(plat_path) - # This is hardcoded in the Python executable, but - # relative to sys.prefix, so we have to fix up: - for path in list(paths): - tk_dir = os.path.join(path, 'lib-tk') - if os.path.exists(tk_dir): - paths.append(tk_dir) - - # These are hardcoded in the Apple's Python executable, - # but relative to sys.prefix, so we have to fix them up: - if sys.platform == 'darwin': - hardcoded_paths = [os.path.join(sys.real_prefix, 'lib', 'python'+sys.version[:3], module) - for module in ('plat-darwin', 'plat-mac', 'plat-mac/lib-scriptpackages')] - - for path in hardcoded_paths: - if os.path.exists(path): - paths.append(path) - - sys.path.extend(paths) - -def force_global_eggs_after_local_site_packages(): - """ - Force easy_installed eggs in the global environment to get placed - in sys.path after all packages inside the virtualenv. This - maintains the "least surprise" result that packages in the - virtualenv always mask global packages, never the other way - around. - - """ - egginsert = getattr(sys, '__egginsert', 0) - for i, path in enumerate(sys.path): - if i > egginsert and path.startswith(sys.prefix): - egginsert = i - sys.__egginsert = egginsert + 1 - -def virtual_addsitepackages(known_paths): - force_global_eggs_after_local_site_packages() - return addsitepackages(known_paths, sys_prefix=sys.real_prefix) - -def fixclasspath(): - """Adjust the special classpath sys.path entries for Jython. These - entries should follow the base virtualenv lib directories. - """ - paths = [] - classpaths = [] - for path in sys.path: - if path == '__classpath__' or path.startswith('__pyclasspath__'): - classpaths.append(path) - else: - paths.append(path) - sys.path = paths - sys.path.extend(classpaths) - -def execusercustomize(): - """Run custom user specific code, if available.""" - try: - import usercustomize - except ImportError: - pass - - -def main(): - global ENABLE_USER_SITE - virtual_install_main_packages() - abs__file__() - paths_in_sys = removeduppaths() - if (os.name == "posix" and sys.path and - os.path.basename(sys.path[-1]) == "Modules"): - addbuilddir() - if _is_jython: - fixclasspath() - GLOBAL_SITE_PACKAGES = not os.path.exists(os.path.join(os.path.dirname(__file__), 'no-global-site-packages.txt')) - if not GLOBAL_SITE_PACKAGES: - ENABLE_USER_SITE = False - if ENABLE_USER_SITE is None: - ENABLE_USER_SITE = check_enableusersite() - paths_in_sys = addsitepackages(paths_in_sys) - paths_in_sys = addusersitepackages(paths_in_sys) - if GLOBAL_SITE_PACKAGES: - paths_in_sys = virtual_addsitepackages(paths_in_sys) - if sys.platform == 'os2emx': - setBEGINLIBPATH() - setquit() - setcopyright() - sethelper() - aliasmbcs() - setencoding() - execsitecustomize() - if ENABLE_USER_SITE: - execusercustomize() - # Remove sys.setdefaultencoding() so that users cannot change the - # encoding after initialization. The test for presence is needed when - # this module is run as a script, because this code is executed twice. - if hasattr(sys, "setdefaultencoding"): - del sys.setdefaultencoding - -main() - -def _script(): - help = """\ - %s [--user-base] [--user-site] - - Without arguments print some useful information - With arguments print the value of USER_BASE and/or USER_SITE separated - by '%s'. - - Exit codes with --user-base or --user-site: - 0 - user site directory is enabled - 1 - user site directory is disabled by user - 2 - uses site directory is disabled by super user - or for security reasons - >2 - unknown error - """ - args = sys.argv[1:] - if not args: - print "sys.path = [" - for dir in sys.path: - print " %r," % (dir,) - print "]" - def exists(path): - if os.path.isdir(path): - return "exists" - else: - return "doesn't exist" - print "USER_BASE: %r (%s)" % (USER_BASE, exists(USER_BASE)) - print "USER_SITE: %r (%s)" % (USER_SITE, exists(USER_BASE)) - print "ENABLE_USER_SITE: %r" % ENABLE_USER_SITE - sys.exit(0) - - buffer = [] - if '--user-base' in args: - buffer.append(USER_BASE) - if '--user-site' in args: - buffer.append(USER_SITE) - - if buffer: - print os.pathsep.join(buffer) - if ENABLE_USER_SITE: - sys.exit(0) - elif ENABLE_USER_SITE is False: - sys.exit(1) - elif ENABLE_USER_SITE is None: - sys.exit(2) - else: - sys.exit(3) - else: - import textwrap - print textwrap.dedent(help % (sys.argv[0], os.pathsep)) - sys.exit(10) - -if __name__ == '__main__': - _script() diff --git a/test/lib/python2.6/sre.py b/test/lib/python2.6/sre.py deleted file mode 120000 index 3ade4e80..00000000 --- a/test/lib/python2.6/sre.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/sre.py \ No newline at end of file diff --git a/test/lib/python2.6/sre_compile.py b/test/lib/python2.6/sre_compile.py deleted file mode 120000 index fc13a37d..00000000 --- a/test/lib/python2.6/sre_compile.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/sre_compile.py \ No newline at end of file diff --git a/test/lib/python2.6/sre_constants.py b/test/lib/python2.6/sre_constants.py deleted file mode 120000 index 98b0d554..00000000 --- a/test/lib/python2.6/sre_constants.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/sre_constants.py \ No newline at end of file diff --git a/test/lib/python2.6/sre_parse.py b/test/lib/python2.6/sre_parse.py deleted file mode 120000 index 76b24c68..00000000 --- a/test/lib/python2.6/sre_parse.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/sre_parse.py \ No newline at end of file diff --git a/test/lib/python2.6/stat.py b/test/lib/python2.6/stat.py deleted file mode 120000 index 68d61e66..00000000 --- a/test/lib/python2.6/stat.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/stat.py \ No newline at end of file diff --git a/test/lib/python2.6/types.py b/test/lib/python2.6/types.py deleted file mode 120000 index 72b00ba3..00000000 --- a/test/lib/python2.6/types.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/types.py \ No newline at end of file diff --git a/test/lib/python2.6/warnings.py b/test/lib/python2.6/warnings.py deleted file mode 120000 index 1af4e283..00000000 --- a/test/lib/python2.6/warnings.py +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/warnings.py \ No newline at end of file