From 1b508d80dd76810f6183df50b9d9b324831875be Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Wed, 16 Feb 2011 12:01:22 +0000 Subject: First commit for xenapi-vlan-networking. Totally untested --- nova/network/manager.py | 1 + nova/virt/xenapi/network_utils.py | 17 +++++++++++++++-- nova/virt/xenapi/vm_utils.py | 1 + nova/virt/xenapi/vmops.py | 15 +++++++++++++-- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/nova/network/manager.py b/nova/network/manager.py index 8eb9f041b..6ba0f2e18 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -499,6 +499,7 @@ class VlanManager(NetworkManager): def setup_compute_network(self, context, instance_id): """Sets up matching network for compute hosts.""" network_ref = db.network_get_by_instance(context, instance_id) + #TODO: the xenapi driver will create a xenserver network if necessary here self.driver.ensure_vlan_bridge(network_ref['vlan'], network_ref['bridge']) diff --git a/nova/virt/xenapi/network_utils.py b/nova/virt/xenapi/network_utils.py index c0406d8f0..4c2a81260 100644 --- a/nova/virt/xenapi/network_utils.py +++ b/nova/virt/xenapi/network_utils.py @@ -28,7 +28,20 @@ class NetworkHelper(HelperBase): """ The class that wraps the helper methods together. """ - + + + @classmethod + def find_network_with_name_label(cls,session,name_label): + networks = session.call_xenapi('network.get_by_name_label', name_label) + if len(networks) == 1: + return networks.keys()[0] + elif len(networks) > 1: + raise Exception(_('Found non-unique network' + ' for name_label %s') % name_label) + else: + return None + + @classmethod def find_network_with_bridge(cls, session, bridge): """Return the network on which the bridge is attached, if found.""" @@ -40,4 +53,4 @@ class NetworkHelper(HelperBase): raise Exception(_('Found non-unique network' ' for bridge %s') % bridge) else: - raise Exception(_('Found no network for bridge %s') % bridge) + raise Exception(_('Found no network for bridge %s') % bridge) diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index f5c19099a..76257946e 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -204,6 +204,7 @@ class VMHelper(HelperBase): VIF reference.""" vif_rec = {} vif_rec['device'] = '0' + #network_ref should be the appropriate reference (network with VLAN) vif_rec['network'] = network_ref vif_rec['VM'] = vm_ref vif_rec['MAC'] = mac_address diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index fe95d881b..b5c5e082e 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -67,10 +67,21 @@ class VMOps(object): raise exception.Duplicate(_('Attempted to create' ' non-unique name %s') % instance.name) + #this will return the bridge name in nova db bridge = db.network_get_by_instance(context.get_admin_context(), instance['id'])['bridge'] - network_ref = \ - NetworkHelper.find_network_with_bridge(self._session, bridge) + + #this will return the appropriate network + #TODO: avoid unnecessary call to find_network_with_bridge + #when VLAN manager is being used (and not just use an if) + network_ref = None + try: + network_ref = \ + NetworkHelper.find_network_with_bridge(self._session, bridge) + except: + #try to get name with name_label + network_ref = \ + NetworkHelper.find_network_with_name_label(self._session,bridge) user = AuthManager().get_user(instance.user_id) project = AuthManager().get_project(instance.project_id) -- cgit From 01e340f98765cc434624b3b4da49447f950f07ae Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Wed, 16 Feb 2011 17:16:31 +0000 Subject: First commit of working code --- nova/network/linux_net.py | 1 + nova/virt/xenapi/network_utils.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index c1cbff7d8..f5efac0ae 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -291,6 +291,7 @@ def update_dhcp(context, network_id): if a dnsmasq instance is already running then send a HUP signal causing it to reload, otherwise spawn a new instance """ + LOG.debug("ENTERING update_dhcp - DHCP script:%s",FLAGS.dhcpbridge) network_ref = db.network_get(context, network_id) conffile = _dhcp_file(network_ref['bridge'], 'conf') diff --git a/nova/virt/xenapi/network_utils.py b/nova/virt/xenapi/network_utils.py index 4c2a81260..8f7806e6c 100644 --- a/nova/virt/xenapi/network_utils.py +++ b/nova/virt/xenapi/network_utils.py @@ -34,7 +34,7 @@ class NetworkHelper(HelperBase): def find_network_with_name_label(cls,session,name_label): networks = session.call_xenapi('network.get_by_name_label', name_label) if len(networks) == 1: - return networks.keys()[0] + return networks[0] elif len(networks) > 1: raise Exception(_('Found non-unique network' ' for name_label %s') % name_label) -- cgit From 441beee908d2534c4fa1d85523dbc87770efeb17 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Thu, 17 Feb 2011 16:54:42 +0000 Subject: Supporting networks with multiple PIFs. pep8 fixes unit tests passed --- nova/network/linux_net.py | 1 - nova/network/manager.py | 2 +- nova/network/xenapi_net.py | 130 ++++++++++++++++++++++++++++++++++++++ nova/virt/xenapi/network_utils.py | 12 ++-- nova/virt/xenapi/vmops.py | 11 ++-- 5 files changed, 142 insertions(+), 14 deletions(-) create mode 100644 nova/network/xenapi_net.py diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index f5efac0ae..c1cbff7d8 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -291,7 +291,6 @@ def update_dhcp(context, network_id): if a dnsmasq instance is already running then send a HUP signal causing it to reload, otherwise spawn a new instance """ - LOG.debug("ENTERING update_dhcp - DHCP script:%s",FLAGS.dhcpbridge) network_ref = db.network_get(context, network_id) conffile = _dhcp_file(network_ref['bridge'], 'conf') diff --git a/nova/network/manager.py b/nova/network/manager.py index 6ba0f2e18..85209e69f 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -499,7 +499,7 @@ class VlanManager(NetworkManager): def setup_compute_network(self, context, instance_id): """Sets up matching network for compute hosts.""" network_ref = db.network_get_by_instance(context, instance_id) - #TODO: the xenapi driver will create a xenserver network if necessary here + #xenapi driver will create a xen network if necessary here self.driver.ensure_vlan_bridge(network_ref['vlan'], network_ref['bridge']) diff --git a/nova/network/xenapi_net.py b/nova/network/xenapi_net.py new file mode 100644 index 000000000..289dbd71f --- /dev/null +++ b/nova/network/xenapi_net.py @@ -0,0 +1,130 @@ +# 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. +""" +Implements vlans, bridges, and iptables rules using linux utilities. +""" + +import os + +from nova import db +from nova import exception +from nova import flags +from nova import log as logging +from nova import utils +from nova.virt.xenapi_conn import XenAPISession +from nova.virt.xenapi.network_utils import NetworkHelper + +LOG = logging.getLogger("nova.xenapi_net") + +FLAGS = flags.FLAGS +flags.DEFINE_string('vlan_interface', 'eth0', + 'network device for vlans') + + +def metadata_forward(): + pass + + +def init_host(): + pass + + +def bind_floating_ip(floating_ip, check_exit_code=True): + pass + + +def unbind_floating_ip(floating_ip): + pass + + +def ensure_vlan_forward(public_ip, port, private_ip): + pass + + +def ensure_floating_forward(floating_ip, fixed_ip): + pass + + +def remove_floating_forward(floating_ip, fixed_ip): + pass + + +def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None): + """Create a vlan and bridge unless they already exist""" + #open xenapi session + url = FLAGS.xenapi_connection_url + username = FLAGS.xenapi_connection_username + password = FLAGS.xenapi_connection_password + session = XenAPISession(url, username, password) + #check whether bridge already exists + #retrieve network whose name_label is "bridge" + network_ref = NetworkHelper.find_network_with_name_label(session, bridge) + if network_ref == None: + #if bridge does not exists + #1 - create network + description = "network for nova bridge %s" % bridge + network_rec = { + 'name_label': bridge, + 'name_description': description, + 'other_config': {}, + } + network_ref = session.call_xenapi('network.create', network_rec) + #2 - find PIF for VLAN + expr = 'field "device" = "%s" and \ + field "VLAN" = "-1"' % FLAGS.vlan_interface + pifs = session.call_xenapi('PIF.get_all_records_where', expr) + pif_ref = None + #multiple PIF are ok: we are dealing with a pool + if len(pifs) == 0: + raise Exception( + _('Found no PID for device %s') % FLAGS.vlan_interface) + #3 - create vlan for network + for pif_ref in pifs.keys(): + session.call_xenapi('VLAN.create', pif_ref, + str(vlan_num), network_ref) + else: + #check VLAN tag is appropriate + network_rec = session.call_xenapi('network.get_record', network_ref) + #retrieve PIFs from network + for pif_ref in network_rec['PIFs']: + #retrieve VLAN from PIF + pif_rec = session.call_xenapi('PIF.get_record', pif_ref) + pif_vlan = int(pif_rec['VLAN']) + #raise an exception if VLAN <> vlan_num + if pif_vlan != vlan_num: + raise Exception(_("PIF %(pif_rec['uuid'])s for network " + "%(bridge)s has VLAN id %(pif_vlan)d." + "Expected %(vlan_num)d") % locals()) + + +def ensure_vlan(vlan_num): + pass + + +def ensure_bridge(bridge, interface, net_attrs=None): + pass + + +def get_dhcp_hosts(context, network_id): + pass + + +def update_dhcp(context, network_id): + pass + + +def update_ra(context, network_id): + pass diff --git a/nova/virt/xenapi/network_utils.py b/nova/virt/xenapi/network_utils.py index 8f7806e6c..c4ee8a6be 100644 --- a/nova/virt/xenapi/network_utils.py +++ b/nova/virt/xenapi/network_utils.py @@ -28,10 +28,9 @@ class NetworkHelper(HelperBase): """ The class that wraps the helper methods together. """ - - + @classmethod - def find_network_with_name_label(cls,session,name_label): + def find_network_with_name_label(cls, session, name_label): networks = session.call_xenapi('network.get_by_name_label', name_label) if len(networks) == 1: return networks[0] @@ -39,9 +38,8 @@ class NetworkHelper(HelperBase): raise Exception(_('Found non-unique network' ' for name_label %s') % name_label) else: - return None - - + return None + @classmethod def find_network_with_bridge(cls, session, bridge): """Return the network on which the bridge is attached, if found.""" @@ -53,4 +51,4 @@ class NetworkHelper(HelperBase): raise Exception(_('Found non-unique network' ' for bridge %s') % bridge) else: - raise Exception(_('Found no network for bridge %s') % bridge) + raise Exception(_('Found no network for bridge %s') % bridge) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index b5c5e082e..a0dbd1411 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -70,18 +70,19 @@ class VMOps(object): #this will return the bridge name in nova db bridge = db.network_get_by_instance(context.get_admin_context(), instance['id'])['bridge'] - + #this will return the appropriate network #TODO: avoid unnecessary call to find_network_with_bridge #when VLAN manager is being used (and not just use an if) - network_ref = None - try: + network_ref = None + try: network_ref = \ NetworkHelper.find_network_with_bridge(self._session, bridge) except: - #try to get name with name_label + #try to get name with name_label network_ref = \ - NetworkHelper.find_network_with_name_label(self._session,bridge) + NetworkHelper.find_network_with_name_label(self._session, + bridge) user = AuthManager().get_user(instance.user_id) project = AuthManager().get_project(instance.project_id) -- cgit From e263a37f83ec5f8a1d81b0f4ec7a91464b2bc022 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Mon, 21 Feb 2011 11:02:19 +0000 Subject: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NOVA-CORE DEVELOPERS SHOULD NOT REVIEW THIS MERGE PROPOSAL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is for Citrix OpenStack team only. We propose for merge into a cache of lp:nova to generate diffs for our internal peer review. --- nova/virt/xenapi/vmops.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 9bd671045..09f5a1c94 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -141,6 +141,7 @@ class VMOps(object): #this will return the appropriate network #TODO(salvatore-orlando): avoid unnecessary call to #find_network_with_bridge when VLAN manager is being used + network_ref = None try: network_ref = \ -- cgit From 1278af43c16daea1bcbd2d47cd2d81919fe2c37e Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Sun, 27 Feb 2011 12:51:19 -0500 Subject: Add lxc libvirt driver --- nova/virt/libvirt.xml.template | 14 ++++++++++++++ nova/virt/libvirt_conn.py | 13 +++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index 88bfbc668..87dea9039 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -2,6 +2,12 @@ ${name} ${memory_kb} +#if $type == 'lxc' + #set $disk_prefix = '' + #set $disk_bus = '' + exe + /sbin/init +#else #if $type == 'uml' #set $disk_prefix = 'ubd' #set $disk_bus = 'uml' @@ -37,6 +43,7 @@ #end if #end if + #end if #end if @@ -44,6 +51,12 @@ ${vcpus} +#if $type == 'lxc' + + + + +#else #if $getVar('rescue', False) @@ -68,6 +81,7 @@ #end if + #end if #end if diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 4e0fd106f..f97c10765 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -20,7 +20,7 @@ """ A connection to a hypervisor through libvirt. -Supports KVM, QEMU, UML, and XEN. +Supports KVM, LXC, QEMU, UML, and XEN. **Related Flags** @@ -83,7 +83,7 @@ flags.DEFINE_string('libvirt_xml_template', flags.DEFINE_string('libvirt_type', 'kvm', 'Libvirt domain type (valid options are: ' - 'kvm, qemu, uml, xen)') + 'kvm, lxc, qemu, uml, xen)') flags.DEFINE_string('libvirt_uri', '', 'Override the default libvirt URI (which is dependent' @@ -202,6 +202,8 @@ class LibvirtConnection(object): uri = FLAGS.libvirt_uri or 'uml:///system' elif FLAGS.libvirt_type == 'xen': uri = FLAGS.libvirt_uri or 'xen:///' + elif FLAGS.libvirt_type == 'lxc': + uri = FLAGS.libvirt_uri or 'lxc:///' else: uri = FLAGS.libvirt_uri or 'qemu:///system' return uri @@ -565,6 +567,10 @@ class LibvirtConnection(object): f.write(libvirt_xml) f.close() + if FLAGS.libvirt_type == 'lxc': + container_dir = '%s/rootfs' % basepath(suffix='') + utils.execute('mkdir -p %s' % container_dir) + # NOTE(vish): No need add the suffix to console.log os.close(os.open(basepath('console.log', ''), os.O_CREAT | os.O_WRONLY, 0660)) @@ -622,6 +628,9 @@ class LibvirtConnection(object): if not inst['kernel_id']: target_partition = "1" + if FLAGS.libvirt_type == 'lxc': + target_partition = None + key = str(inst['key_data']) net = None network_ref = db.network_get_by_instance(context.get_admin_context(), -- cgit From 2d6987d8c33477af19179e7664bbedf689bc08dc Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Sun, 27 Feb 2011 13:05:26 -0500 Subject: Add ability to mount containers --- nova/virt/disk.py | 26 ++++++++++++++++++++++++++ nova/virt/libvirt_conn.py | 6 ++++++ 2 files changed, 32 insertions(+) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index 2bded07a4..7cbc4a3be 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -114,6 +114,32 @@ def inject_data(image, key=None, net=None, partition=None, nbd=False): _unlink_device(device, nbd) +def setup_container(image, container_dir=None, partition=None, nbd=False): + """Setup the LXC container + + It will mount the loopback image to the container directory in order + to create the root filesystem for the container + """ + device = _link_device(image, nbd) + try: + if not partition is None: + # create partition + utils.execute('sudo kpartx -a %s' % device) + mapped_device = '/dev/mapper/%p%s' % (device.split('/')[-1], + partition) + else: + mapped_device = device + + utils.execute('sudo mount %s %s' %(mapped_device, container_dir)) + + except Exception as e: + LOG.warn(_('Unable to mount container')) + if not partition is None: + # remove partitions + utils.execute('sudo kpartx -s %s' % device) + _unlink_device(device, nbd) + + def _link_device(image, nbd): """Link image to device using loopback or nbd""" if nbd: diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index f97c10765..f7807a851 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -661,6 +661,12 @@ class LibvirtConnection(object): disk.inject_data(basepath('disk'), key, net, partition=target_partition, nbd=FLAGS.use_cow_images) + + if FLAGS.libvirt_type == 'lxc': + disk.setup_container(basepath('disk'), + container_dir=container_dir, + partition=target_partition, + nbd=FLAGS.use_cow_images) except Exception as e: # This could be a windows image, or a vmdk format disk LOG.warn(_('instance %(inst_name)s: ignoring error injecting' -- cgit From 33d7edb9d02d8f4dcb0b6ee85caf10434f060e1b Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Sun, 27 Feb 2011 13:29:05 -0500 Subject: Clean up the mount points when it shutsdown --- nova/virt/disk.py | 1 - nova/virt/libvirt_conn.py | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index 7cbc4a3be..28a4c11fb 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -139,7 +139,6 @@ def setup_container(image, container_dir=None, partition=None, nbd=False): utils.execute('sudo kpartx -s %s' % device) _unlink_device(device, nbd) - def _link_device(image, nbd): """Link image to device using loopback or nbd""" if nbd: diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index f7807a851..5e76edb0b 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -259,6 +259,8 @@ class LibvirtConnection(object): instance_name = instance['name'] LOG.info(_('instance %(instance_name)s: deleting instance files' ' %(target)s') % locals()) + if FLAGS.libvirt_type == 'lxc': + utils.execute('sudo umount %s/rootfs' % target) if os.path.exists(target): shutil.rmtree(target) -- cgit From 031205a26ae6fe906a47eefa716bbd575687c479 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Sun, 27 Feb 2011 13:35:10 -0500 Subject: Add lxc to the libvirt tests --- nova/tests/test_virt.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index f151ae911..04f943a1f 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -112,12 +112,15 @@ class LibvirtConnTestCase(test.TestCase): 'uml': ('uml:///system', [(lambda t: t.find('.').get('type'), 'uml'), (lambda t: t.find('./os/type').text, 'uml')]), + 'lxc': ('lxc://', + [(lambda t: t.find('.').get('type'), 'lxc'), + (lambda t: t.find('./os/type').text, 'lxc')]), 'xen': ('xen:///', [(lambda t: t.find('.').get('type'), 'xen'), (lambda t: t.find('./os/type').text, 'linux')]), } - for hypervisor_type in ['qemu', 'kvm', 'xen']: + for hypervisor_type in ['qemu', 'kvm', 'lxc', 'xen']: check_list = type_uri_map[hypervisor_type][1] if rescue: -- cgit From 7825b7ce81dec97e997d296c3e30b5d143948abc Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 2 Mar 2011 01:21:54 -0800 Subject: initial commit of vnc support --- nova/api/ec2/cloud.py | 6 ++ nova/compute/api.py | 17 +++++ nova/compute/manager.py | 9 +++ nova/flags.py | 6 ++ nova/virt/libvirt.xml.template | 1 + nova/virt/libvirt_conn.py | 17 +++++ tools/euca-get-vnc-console | 163 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 219 insertions(+) create mode 100755 tools/euca-get-vnc-console diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 844ccbe5e..aa9c6824e 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -539,6 +539,12 @@ class CloudController(object): return self.compute_api.get_ajax_console(context, instance_id=instance_id) + def get_vnc_console(self, context, instance_id, **kwargs): + ec2_id = instance_id + instance_id = ec2_id_to_id(ec2_id) + return self.compute_api.get_vnc_console(context, + instance_id=instance_id) + def describe_volumes(self, context, volume_id=None, **kwargs): if volume_id: volumes = [] diff --git a/nova/compute/api.py b/nova/compute/api.py index 625778b66..cec978d75 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -476,6 +476,23 @@ class API(base.Base): return {'url': '%s/?token=%s' % (FLAGS.ajax_console_proxy_url, output['token'])} + def get_vnc_console(self, context, instance_id): + """Get a url to an AJAX Console""" + instance = self.get(context, instance_id) + output = self._call_compute_message('get_vnc_console', + context, + instance_id) + rpc.cast(context, '%s' % FLAGS.vnc_console_proxy_topic, + {'method': 'authorize_vnc_console', + 'args': {'token': output['token'], 'host': output['host'], + 'port': output['port']}}) + + time.sleep(1) + + return {'url': '%s/vnc_auto.html?token=%s&host=%s&port=%s' % + (FLAGS.vnc_console_proxy_url, + output['token'], 'hostignore', 'portignore')} + def get_console_output(self, context, instance_id): """Get console output for an an instance""" return self._call_compute_message('get_console_output', diff --git a/nova/compute/manager.py b/nova/compute/manager.py index d659712ad..e53b36b34 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -557,6 +557,15 @@ class ComputeManager(manager.Manager): return self.driver.get_ajax_console(instance_ref) + @exception.wrap_exception + def get_vnc_console(self, context, instance_id): + """Return connection information for an vnc console""" + context = context.elevated() + LOG.debug(_("instance %s: getting vnc console"), instance_id) + instance_ref = self.db.instance_get(context, instance_id) + + return self.driver.get_vnc_console(instance_ref) + @checks_instance_lock def attach_volume(self, context, instance_id, volume_id, mountpoint): """Attach a volume to an instance.""" diff --git a/nova/flags.py b/nova/flags.py index 8cf199b2f..4f2be82b6 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -281,6 +281,12 @@ DEFINE_string('ajax_console_proxy_url', in the form "http://127.0.0.1:8000"') DEFINE_string('ajax_console_proxy_port', 8000, 'port that ajax_console_proxy binds') +DEFINE_string('vnc_console_proxy_topic', 'vnc_proxy', + 'the topic vnc proxy nodes listen on') +DEFINE_string('vnc_console_proxy_url', + 'http://127.0.0.1:6080', + 'location of vnc console proxy, \ + in the form "http://127.0.0.1:6080"') DEFINE_bool('verbose', False, 'show debug output') DEFINE_boolean('fake_rabbit', False, 'use a fake rabbit') DEFINE_bool('fake_network', False, diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index 88bfbc668..7b4c23211 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -101,5 +101,6 @@ + diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 4e0fd106f..4fca84639 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -511,6 +511,23 @@ class LibvirtConnection(object): subprocess.Popen(cmd, shell=True) return {'token': token, 'host': host, 'port': port} + @exception.wrap_exception + def get_vnc_console(self, instance): + def get_vnc_port_for_instance(instance_name): + virt_dom = self._conn.lookupByName(instance_name) + xml = virt_dom.XMLDesc(0) + dom = minidom.parseString(xml) + + for graphic in dom.getElementsByTagName('graphics'): + if graphic.getAttribute('type') == 'vnc': + return graphic.getAttribute('port') + + port = get_vnc_port_for_instance(instance['name']) + token = str(uuid.uuid4()) + host = instance['host'] + + return {'token': token, 'host': host, 'port': port} + def _cache_image(self, fn, target, fname, cow=False, *args, **kwargs): """Wrapper for a method that creates an image that caches the image. diff --git a/tools/euca-get-vnc-console b/tools/euca-get-vnc-console new file mode 100755 index 000000000..bd2788f03 --- /dev/null +++ b/tools/euca-get-vnc-console @@ -0,0 +1,163 @@ +#!/usr/bin/env python +# pylint: disable-msg=C0103 +# 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. + +"""Euca add-on to use vnc console""" + +import getopt +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) + +import boto +import nova +from boto.ec2.connection import EC2Connection +from euca2ools import Euca2ool, InstanceValidationError, Util, ConnectionFailed + +usage_string = """ +Retrieves a url to an vnc console terminal + +euca-get-vnc-console [-h, --help] [--version] [--debug] instance_id + +REQUIRED PARAMETERS + +instance_id: unique identifier for the instance show the console output for. + +OPTIONAL PARAMETERS + +""" + + +# This class extends boto to add VNCConsole functionality +class NovaEC2Connection(EC2Connection): + + def get_vnc_console(self, instance_id): + """ + Retrieves a console connection for the specified instance. + + :type instance_id: string + :param instance_id: The instance ID of a running instance on the cloud. + + :rtype: :class:`VNCConsole` + """ + + class VNCConsole: + def __init__(self, parent=None): + self.parent = parent + self.instance_id = None + self.url = None + + def startElement(self, name, attrs, connection): + return None + + def endElement(self, name, value, connection): + if name == 'instanceId': + self.instance_id = value + elif name == 'url': + self.url = value + else: + setattr(self, name, value) + + params = {} + return self.get_object('GetVNCConsole', + {'InstanceId': instance_id}, VNCConsole) + + +def override_connect_ec2(aws_access_key_id=None, + aws_secret_access_key=None, **kwargs): + return NovaEC2Connection(aws_access_key_id, + aws_secret_access_key, **kwargs) + +# override boto's connect_ec2 method, so that we can use NovaEC2Connection +boto.connect_ec2 = override_connect_ec2 + + +def usage(status=1): + print usage_string + Util().usage() + sys.exit(status) + + +def version(): + print Util().version() + sys.exit() + + +def display_console_output(console_output): + print console_output.instance_id + print console_output.timestamp + print console_output.output + + +def display_vnc_console_output(console_output): + print console_output.url + + +def main(): + try: + euca = Euca2ool() + except Exception, e: + print e + usage() + + instance_id = None + + for name, value in euca.opts: + if name in ('-h', '--help'): + usage(0) + elif name == '--version': + version() + elif name == '--debug': + debug = True + + for arg in euca.args: + instance_id = arg + break + + if instance_id: + try: + euca.validate_instance_id(instance_id) + except InstanceValidationError: + print 'Invalid instance id' + sys.exit(1) + + try: + euca_conn = euca.make_connection() + except ConnectionFailed, e: + print e.message + sys.exit(1) + try: + console_output = euca_conn.get_vnc_console(instance_id) + except Exception, ex: + euca.display_error_and_exit('%s' % ex) + + display_vnc_console_output(console_output) + else: + print 'instance_id must be specified' + usage() + +if __name__ == "__main__": + main() -- cgit From cb30c80c922a09ccca18645670ea5b1cdc70f1f2 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Fri, 4 Mar 2011 12:31:59 +0000 Subject: fixed wrong local variable name in vmops --- nova/virt/xenapi/vmops.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index a7838dbba..417f40da8 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -519,7 +519,7 @@ class VMOps(object): NetworkHelper.find_network_with_name_label(self._session, bridge) if network_ref: - VMHelper.create_vif(self._session, vm_ref, + VMHelper.create_vif(self._session, vm_opaque_ref, network_ref, instance.mac_address) -- cgit From c4142835981eb9b2d5a55517d975dbda029986e2 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Tue, 8 Mar 2011 10:09:34 +0000 Subject: Removed excess comment lines --- nova/network/manager.py | 1 - nova/network/xenapi_net.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/nova/network/manager.py b/nova/network/manager.py index 05d677bc9..b36dd59cf 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -518,7 +518,6 @@ class VlanManager(NetworkManager): def setup_compute_network(self, context, instance_id): """Sets up matching network for compute hosts.""" network_ref = db.network_get_by_instance(context, instance_id) - #xenapi driver will create a xen network if necessary here self.driver.ensure_vlan_bridge(network_ref['vlan'], network_ref['bridge']) diff --git a/nova/network/xenapi_net.py b/nova/network/xenapi_net.py index d31a1352f..314638bcd 100644 --- a/nova/network/xenapi_net.py +++ b/nova/network/xenapi_net.py @@ -31,7 +31,7 @@ LOG = logging.getLogger("nova.xenapi_net") FLAGS = flags.FLAGS flags.DEFINE_string('vlan_interface', 'eth0', - 'network device for vlans') + 'Physical network interface for vlans') def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None): -- cgit From e502ad0243962aca98cc28bfa5cf69f8cd08991c Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Wed, 9 Mar 2011 21:43:45 -0500 Subject: Moved umount container to disk.py and try to remove loopback when destroying the container --- nova/virt/disk.py | 8 ++++++++ nova/virt/libvirt_conn.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index e1b0171b5..484317dd8 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -140,6 +140,14 @@ def setup_container(image, container_dir=None, partition=None, nbd=False): utils.execute('sudo kpartx -s %s' % device) _unlink_device(device, nbd) +def destroy_container(target, instance, nbd=False): + """Destroy the container once it terminates""" + try: + utils.execute('sudo umount %s/rootfs' % target) + image = os.path.join(FLAGS.instances_path, instance['name'], '' + 'disk') + except Exception as e: + LOG.warn(_('Unable to umount contianer')) + def _link_device(image, nbd): """Link image to device using loopback or nbd""" if nbd: diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 97997513b..ef0eb20cd 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -260,7 +260,7 @@ class LibvirtConnection(object): LOG.info(_('instance %(instance_name)s: deleting instance files' ' %(target)s') % locals()) if FLAGS.libvirt_type == 'lxc': - utils.execute('sudo umount %s/rootfs' % target) + disk.destroy_container(target, instance, nbd=FLAGS.use_cow_images) if os.path.exists(target): shutil.rmtree(target) -- cgit From 977fc1be4ea8af93b63975c5538462a776fbe168 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Fri, 11 Mar 2011 11:42:42 +0000 Subject: Moved vlan_interface flag in network.manager removed needless carriage return in vm_ops --- nova/network/linux_net.py | 5 ++--- nova/network/manager.py | 3 +++ nova/network/xenapi_net.py | 5 ----- nova/tests/test_xenapi.py | 12 ++++++++++++ nova/virt/xenapi/vmops.py | 3 +-- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index 535ce87bc..6dcecdadb 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -41,13 +41,12 @@ flags.DEFINE_string('dhcpbridge_flagfile', flags.DEFINE_string('dhcp_domain', 'novalocal', 'domain to use for building the hostnames') - +#flags.DEFINE_string('vlan_interface', 'eth0', +# 'network device for vlans') flags.DEFINE_string('networks_path', '$state_path/networks', 'Location to keep network config files') flags.DEFINE_string('public_interface', 'eth0', 'Interface for public IP addresses') -flags.DEFINE_string('vlan_interface', 'eth0', - 'network device for vlans') flags.DEFINE_string('dhcpbridge', _bin_file('nova-dhcpbridge'), 'location of nova-dhcpbridge') flags.DEFINE_string('routing_source_ip', '$my_ip', diff --git a/nova/network/manager.py b/nova/network/manager.py index b36dd59cf..15ce36940 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -85,6 +85,8 @@ flags.DEFINE_string('fixed_range', '10.0.0.0/8', 'Fixed IP address block') flags.DEFINE_string('fixed_range_v6', 'fd00::/48', 'Fixed IPv6 address block') flags.DEFINE_integer('cnt_vpn_clients', 0, 'Number of addresses reserved for vpn clients') +flags.DEFINE_string('vlan_interface', 'eth0', + 'network device for vlans') flags.DEFINE_string('network_driver', 'nova.network.linux_net', 'Driver to use for network creation') flags.DEFINE_bool('update_dhcp_on_disassociate', False, @@ -517,6 +519,7 @@ class VlanManager(NetworkManager): def setup_compute_network(self, context, instance_id): """Sets up matching network for compute hosts.""" + LOG.debug("ENTERING SETUP COMPUTE NETWORK") network_ref = db.network_get_by_instance(context, instance_id) self.driver.ensure_vlan_bridge(network_ref['vlan'], network_ref['bridge']) diff --git a/nova/network/xenapi_net.py b/nova/network/xenapi_net.py index 314638bcd..01889f94d 100644 --- a/nova/network/xenapi_net.py +++ b/nova/network/xenapi_net.py @@ -29,11 +29,6 @@ from nova.virt.xenapi.network_utils import NetworkHelper LOG = logging.getLogger("nova.xenapi_net") -FLAGS = flags.FLAGS -flags.DEFINE_string('vlan_interface', 'eth0', - 'Physical network interface for vlans') - - def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None): """Create a vlan and bridge unless they already exist""" #open xenapi session diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 7f437c2b8..0f3b9ce20 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -38,6 +38,8 @@ from nova.tests.db import fakes as db_fakes from nova.tests.xenapi import stubs from nova.tests.glance import stubs as glance_stubs +from nova import log as LOG + FLAGS = flags.FLAGS @@ -297,6 +299,16 @@ class XenAPIVMTestCase(test.TestCase): glance_stubs.FakeGlance.IMAGE_KERNEL, glance_stubs.FakeGlance.IMAGE_RAMDISK) + def test_spawn_vlanmanager(self): + self.flags(xenapi_image_service = 'glance', + network_manager='nova.network.manager.VlanManager', + network_driver='nova.network.xenapi_net') + LOG.debug("Self.network:%s",self.network) + self._test_spawn(glance_stubs.FakeGlance.IMAGE_MACHINE, + glance_stubs.FakeGlance.IMAGE_KERNEL, + glance_stubs.FakeGlance.IMAGE_RAMDISK) + pass + def tearDown(self): super(XenAPIVMTestCase, self).tearDown() self.manager.delete_project(self.project) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 9140774c5..66df3c28e 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -236,8 +236,7 @@ class VMOps(object): """Create snapshot from a running VM instance :param instance: instance to be snapshotted - :param image_id: id of - image to upload to + :param image_id: id of image to upload to Steps involved in a XenServer snapshot: -- cgit From b76b61dbec03455824b90c427eb816c15e284013 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Fri, 11 Mar 2011 10:32:09 -0800 Subject: Added volume api from previous megapatch --- nova/api/openstack/__init__.py | 6 ++ nova/api/openstack/volumes.py | 160 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 nova/api/openstack/volumes.py diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index ab9dbb780..a7b639669 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -34,6 +34,7 @@ from nova.api.openstack import flavors from nova.api.openstack import images from nova.api.openstack import servers from nova.api.openstack import shared_ip_groups +from nova.api.openstack import volumes from nova.api.openstack import zones @@ -111,6 +112,11 @@ class APIRouter(wsgi.Router): collection={'detail': 'GET'}, controller=shared_ip_groups.Controller()) + #NOTE(justinsb): volumes is not yet part of the official API + mapper.resource("volume", "volumes", + controller=volumes.Controller(), + collection={'detail': 'GET'}) + super(APIRouter, self).__init__(mapper) diff --git a/nova/api/openstack/volumes.py b/nova/api/openstack/volumes.py new file mode 100644 index 000000000..99300421e --- /dev/null +++ b/nova/api/openstack/volumes.py @@ -0,0 +1,160 @@ +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from webob import exc + +from nova import exception +from nova import flags +from nova import log as logging +from nova import volume +from nova import wsgi +from nova.api.openstack import common +from nova.api.openstack import faults + + +LOG = logging.getLogger("nova.api.volumes") + +FLAGS = flags.FLAGS + + +def _translate_detail_view(context, inst): + """ Maps keys for details view""" + + inst_dict = _translate_summary_view(context, inst) + + # No additional data / lookups at the moment + + return inst_dict + + +def _translate_summary_view(context, volume): + """ Maps keys for summary view""" + v = {} + + instance_id = None + # instance_data = None + attached_to = volume.get('instance') + if attached_to: + instance_id = attached_to['id'] + # instance_data = '%s[%s]' % (instance_ec2_id, + # attached_to['host']) + v['id'] = volume['id'] + v['status'] = volume['status'] + v['size'] = volume['size'] + v['availabilityZone'] = volume['availability_zone'] + v['createdAt'] = volume['created_at'] + # if context.is_admin: + # v['status'] = '%s (%s, %s, %s, %s)' % ( + # volume['status'], + # volume['user_id'], + # volume['host'], + # instance_data, + # volume['mountpoint']) + if volume['attach_status'] == 'attached': + v['attachments'] = [{'attachTime': volume['attach_time'], + 'deleteOnTermination': False, + 'mountpoint': volume['mountpoint'], + 'instanceId': instance_id, + 'status': 'attached', + 'volumeId': volume['id']}] + else: + v['attachments'] = [{}] + + v['displayName'] = volume['display_name'] + v['displayDescription'] = volume['display_description'] + return v + + +class Controller(wsgi.Controller): + """ The Volumes API controller for the OpenStack API """ + + _serialization_metadata = { + 'application/xml': { + "attributes": { + "volume": [ + "id", + "status", + "size", + "availabilityZone", + "createdAt", + "displayName", + "displayDescription", + ]}}} + + def __init__(self): + self.volume_api = volume.API() + super(Controller, self).__init__() + + def show(self, req, id): + """Return data about the given volume""" + context = req.environ['nova.context'] + + try: + volume = self.volume_api.get(context, id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + return {'volume': _translate_detail_view(context, volume)} + + def delete(self, req, id): + """ Delete a volume """ + context = req.environ['nova.context'] + + LOG.audit(_("Delete volume with id: %s"), id, context=context) + + try: + self.volume_api.delete(context, volume_id=id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + return exc.HTTPAccepted() + + def index(self, req): + """ Returns a summary list of volumes""" + return self._items(req, entity_maker=_translate_summary_view) + + def detail(self, req): + """ Returns a detailed list of volumes """ + return self._items(req, entity_maker=_translate_detail_view) + + def _items(self, req, entity_maker): + """Returns a list of volumes, transformed through entity_maker""" + context = req.environ['nova.context'] + + volumes = self.volume_api.get_all(context) + limited_list = common.limited(volumes, req) + res = [entity_maker(context, inst) for inst in limited_list] + return {'volumes': res} + + def create(self, req): + """Creates a new volume""" + context = req.environ['nova.context'] + + env = self._deserialize(req.body, req) + if not env: + return faults.Fault(exc.HTTPUnprocessableEntity()) + + vol = env['volume'] + size = vol['size'] + LOG.audit(_("Create volume of %s GB"), size, context=context) + volume = self.volume_api.create(context, size, + vol.get('display_name'), + vol.get('display_description')) + + # Work around problem that instance is lazy-loaded... + volume['instance'] = None + + retval = _translate_detail_view(context, volume) + + return {'volume': retval} -- cgit From 743e82c0acac0fda78a55a8bbb65e601c4cb652c Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Mon, 14 Mar 2011 21:14:39 -0400 Subject: Refactor setup contianer/destroy container --- nova/virt/disk.py | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index f0b391efb..a3db1d882 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -122,31 +122,26 @@ def setup_container(image, container_dir=None, partition=None, nbd=False): to create the root filesystem for the container """ device = _link_device(image, nbd) - try: - if not partition is None: - # create partition - utils.execute('sudo kpartx -a %s' % device) - mapped_device = '/dev/mapper/%p%s' % (device.split('/')[-1], - partition) - else: - mapped_device = device - - utils.execute('sudo mount %s %s' %(mapped_device, container_dir)) - - except Exception as e: - LOG.warn(_('Unable to mount container')) - if not partition is None: - # remove partitions - utils.execute('sudo kpartx -s %s' % device) + err = utils.execute('sudo', 'mount', mapped_device, container_dir) + if err: + raise exception.Error(_('Failed to mount filesystem: %s') + % err) _unlink_device(device, nbd) def destroy_container(target, instance, nbd=False): """Destroy the container once it terminates""" try: - utils.execute('sudo umount %s/rootfs' % target) + container_dir = '%s/rootfs' % target + utils.execute('sudo', 'umount', container_dir) + finally: image = os.path.join(FLAGS.instances_path, instance['name'], '' + 'disk') - except Exception as e: - LOG.warn(_('Unable to umount contianer')) + out, err = utils.execute('sudo', 'losetup', '--find', '--show', image) + device = out.strip() + if err: + raise execption.Error(_('Could not find loopback image: %s') + %err) + utils.execute('sudo', 'losetup', '--detach', device) + def _link_device(image, nbd): """Link image to device using loopback or nbd""" -- cgit From 48d3dd7f9d2633d8955080b6dccc7c97bc8ef7c3 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Tue, 15 Mar 2011 07:56:26 -0400 Subject: Mount the right device --- nova/virt/disk.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index a3db1d882..2c0460f39 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -122,7 +122,7 @@ def setup_container(image, container_dir=None, partition=None, nbd=False): to create the root filesystem for the container """ device = _link_device(image, nbd) - err = utils.execute('sudo', 'mount', mapped_device, container_dir) + err = utils.execute('sudo', 'mount', device, container_dir) if err: raise exception.Error(_('Failed to mount filesystem: %s') % err) -- cgit From f60c9d0da8171b09bd7971fea52e9e032f98a143 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Tue, 15 Mar 2011 08:05:45 -0400 Subject: Add comments about the destroy container function --- nova/virt/disk.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index 2c0460f39..dd4352957 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -129,7 +129,11 @@ def setup_container(image, container_dir=None, partition=None, nbd=False): _unlink_device(device, nbd) def destroy_container(target, instance, nbd=False): - """Destroy the container once it terminates""" + """Destroy the container once it terminates + + It will umount the container that is mounted, try to find the loopback + device associated with the container and delete it. + """ try: container_dir = '%s/rootfs' % target utils.execute('sudo', 'umount', container_dir) -- cgit From 3c10c1ee1bcc3f3aad90e4e28761d1413ab203a9 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Tue, 15 Mar 2011 09:36:02 -0400 Subject: Really delete the loop --- nova/virt/disk.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index dd4352957..a44995613 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -23,6 +23,7 @@ Includes injection of SSH PGP keys into authorized_keys file. """ import os +import string import tempfile import time @@ -138,13 +139,10 @@ def destroy_container(target, instance, nbd=False): container_dir = '%s/rootfs' % target utils.execute('sudo', 'umount', container_dir) finally: - image = os.path.join(FLAGS.instances_path, instance['name'], '' + 'disk') - out, err = utils.execute('sudo', 'losetup', '--find', '--show', image) - device = out.strip() - if err: - raise execption.Error(_('Could not find loopback image: %s') - %err) - utils.execute('sudo', 'losetup', '--detach', device) + for loop in os.popen('sudo losetup -a').readlines(): + if instance['name'] in loop: + device = string.split(loop, ':') + utils.execute('sudo', 'losetup', '--detach', device) def _link_device(image, nbd): -- cgit From ceb8cd14f968aa063bd6a19999340f77c5603568 Mon Sep 17 00:00:00 2001 From: Devin Carlen Date: Tue, 15 Mar 2011 21:04:38 -0700 Subject: Fixed DescribeUser in ec2 admin client --- nova/adminclient.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/nova/adminclient.py b/nova/adminclient.py index fc3c5c5fe..f570e12c2 100644 --- a/nova/adminclient.py +++ b/nova/adminclient.py @@ -324,14 +324,11 @@ class NovaAdminClient(object): def get_user(self, name): """Grab a single user by name.""" - try: - return self.apiconn.get_object('DescribeUser', - {'Name': name}, - UserInfo) - except boto.exception.BotoServerError, e: - if e.status == 400 and e.error_code == 'NotFound': - return None - raise + user = self.apiconn.get_object('DescribeUser', + {'Name': name}, + UserInfo) + if user.username != None: + return user def has_user(self, username): """Determine if user exists.""" -- cgit From bb52b51d0e4f9b297dcc489562f38d1647e10856 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Wed, 16 Mar 2011 12:34:39 +0000 Subject: Adding unit test --- nova/network/manager.py | 2 ++ nova/network/xenapi_net.py | 3 +++ nova/tests/db/fakes.py | 45 +++++++++++++++++++++++++++---- nova/tests/test_xenapi.py | 22 ++++++++++++--- nova/virt/xenapi/fake.py | 67 ++++++++++++++++++++++++++++++++++++++++++---- nova/virt/xenapi/vmops.py | 2 +- 6 files changed, 127 insertions(+), 14 deletions(-) diff --git a/nova/network/manager.py b/nova/network/manager.py index 4baea482b..3b53d5d05 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -115,6 +115,7 @@ class NetworkManager(manager.Manager): timeout_fixed_ips = True def __init__(self, network_driver=None, *args, **kwargs): + LOG.debug("INIT - network driver:%s", network_driver) if not network_driver: network_driver = FLAGS.network_driver self.driver = utils.import_object(network_driver) @@ -520,6 +521,7 @@ class VlanManager(NetworkManager): def setup_compute_network(self, context, instance_id): """Sets up matching network for compute hosts.""" LOG.debug("ENTERING SETUP COMPUTE NETWORK") + LOG.debug("DRIVER:%s",self.driver) network_ref = db.network_get_by_instance(context, instance_id) self.driver.ensure_vlan_bridge(network_ref['vlan'], network_ref['bridge']) diff --git a/nova/network/xenapi_net.py b/nova/network/xenapi_net.py index 01889f94d..49214764e 100644 --- a/nova/network/xenapi_net.py +++ b/nova/network/xenapi_net.py @@ -29,9 +29,12 @@ from nova.virt.xenapi.network_utils import NetworkHelper LOG = logging.getLogger("nova.xenapi_net") +FLAGS = flags.FLAGS + def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None): """Create a vlan and bridge unless they already exist""" #open xenapi session + LOG.debug("ENTERING ensure_vlan_bridge in xenapi net") url = FLAGS.xenapi_connection_url username = FLAGS.xenapi_connection_username password = FLAGS.xenapi_connection_password diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py index d760dc456..88daa82c3 100644 --- a/nova/tests/db/fakes.py +++ b/nova/tests/db/fakes.py @@ -23,8 +23,9 @@ from nova import db from nova import test from nova import utils +from nova import log as LOG -def stub_out_db_instance_api(stubs): +def stub_out_db_instance_api(stubs, injected=True): """ Stubs out the db API for creating Instances """ INSTANCE_TYPES = { @@ -36,6 +37,29 @@ def stub_out_db_instance_api(stubs): 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)} + flat_network_fields = { + 'id': 'fake_flat', + 'bridge': 'xenbr0', + 'label': 'fake_flat_network', + 'netmask': '255.255.255.0', + 'gateway': '10.0.0.1', + 'broadcast': '10.0.0.255', + 'dns': '10.0.0.2', + 'ra_server': None, + 'injected': injected} + + vlan_network_fields = { + 'id': 'fake_vlan', + 'bridge': 'br111', + 'label': 'fake_vlan_network', + 'netmask': '255.255.255.0', + 'gateway': '10.0.0.1', + 'broadcast': '10.0.0.255', + 'dns': '10.0.0.2', + 'ra_server': None, + 'vlan': 111, + 'injected': False} + class FakeModel(object): """ Stubs out for model """ def __init__(self, values): @@ -81,12 +105,23 @@ def stub_out_db_instance_api(stubs): return FakeModel(base_options) def fake_network_get_by_instance(context, instance_id): - fields = { - 'bridge': 'xenbr0', - } - return FakeModel(fields) + #even instance numbers are on vlan networks + if instance_id % 2 == 0: + return FakeModel(vlan_network_fields) + else: + return FakeModel(flat_network_fields) + + def fake_network_get_all_by_instance(context, instance_id): + l = [] + #even instance numbers are on vlan networks + if instance_id % 2 == 0: + l.append(FakeModel(vlan_network_fields)) + else: + l.append(FakeModel(flat_network_fields)) + return l stubs.Set(db, 'instance_create', fake_instance_create) stubs.Set(db, 'network_get_by_instance', fake_network_get_by_instance) + stubs.Set(db, 'network_get_all_by_instance', fake_network_get_all_by_instance) stubs.Set(db, 'instance_type_get_all', fake_instance_type_get_all) stubs.Set(db, 'instance_type_get_by_name', fake_instance_type_get_by_name) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 26fad39d1..2cdc84882 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -165,6 +165,7 @@ class XenAPIVMTestCase(test.TestCase): FLAGS.xenapi_connection_password = 'test_pass' xenapi_fake.reset() xenapi_fake.create_local_srs() + xenapi_fake.create_local_pifs() db_fakes.stub_out_db_instance_api(self.stubs) xenapi_fake.create_network('fake', FLAGS.flat_network_bridge) stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests) @@ -252,6 +253,9 @@ class XenAPIVMTestCase(test.TestCase): # Check that the VM is running according to XenAPI. self.assertEquals(vm['power_state'], 'Running') + + # Check that VM network is consistent with nova network + LOG.debug("VM INFO - NETWORK:%s", vm_info) def _test_spawn(self, image_id, kernel_id, ramdisk_id, instance_type="m1.large"): @@ -301,13 +305,25 @@ class XenAPIVMTestCase(test.TestCase): def test_spawn_vlanmanager(self): self.flags(xenapi_image_service = 'glance', - network_manager='nova.network.manager.VlanManager', - network_driver='nova.network.xenapi_net') + network_manager = 'nova.network.manager.VlanManager', + network_driver = 'nova.network.xenapi_net', + vlan_interface = 'fake0') LOG.debug("Self.network:%s",self.network) + LOG.debug("network driver:%s",FLAGS.network_driver) + fake_instance_id = 2 + network_bk=self.network + #ensure we use xenapi_net driver + self.network = utils.import_object(FLAGS.network_manager) + self.network.setup_compute_network(None, fake_instance_id) self._test_spawn(glance_stubs.FakeGlance.IMAGE_MACHINE, glance_stubs.FakeGlance.IMAGE_KERNEL, glance_stubs.FakeGlance.IMAGE_RAMDISK) - pass + url = FLAGS.xenapi_connection_url + username = FLAGS.xenapi_connection_username + password = FLAGS.xenapi_connection_password + session = xenapi_conn.XenAPISession(url, username, password) + + self.network = network_bk def tearDown(self): super(XenAPIVMTestCase, self).tearDown() diff --git a/nova/virt/xenapi/fake.py b/nova/virt/xenapi/fake.py index ba12d4d3a..2e8cd9c5c 100644 --- a/nova/virt/xenapi/fake.py +++ b/nova/virt/xenapi/fake.py @@ -61,7 +61,7 @@ from nova import log as logging _CLASSES = ['host', 'network', 'session', 'SR', 'VBD',\ - 'PBD', 'VDI', 'VIF', 'VM', 'task'] + 'PBD', 'VDI', 'VIF', 'PIF', 'VM', 'VLAN', 'task'] _db_content = {} @@ -103,7 +103,6 @@ def create_vm(name_label, status, 'is_control_domain': is_control_domain, }) - def destroy_vm(vm_ref): vm_rec = _db_content['VM'][vm_ref] @@ -178,6 +177,12 @@ def create_task(name_label): }) +def create_local_pifs(): + """Adds a PIF for each to the local database with VLAN=-1. + Do this one per host.""" + for host_ref in _db_content['host'].keys(): + _create_local_pif(host_ref) + def create_local_srs(): """Create an SR that looks like the one created on the local disk by default by the XenServer installer. Do this one per host.""" @@ -204,8 +209,18 @@ def _create_local_sr(host_ref): _db_content['SR'][sr_ref]['PBDs'] = [pbd_ref] return sr_ref +def _create_local_pif(host_ref): + pif_ref= _create_object('PIF', { + 'name-label': 'Fake PIF', + 'MAC': '00:11:22:33:44:55', + 'physical': True, + 'VLAN': -1, + 'device': 'fake0', + 'host_uuid': host_ref, + }) def _create_object(table, obj): + LOG.debug("ENTERING _create_object:%s", obj) ref = str(uuid.uuid4()) obj['uuid'] = str(uuid.uuid4()) _db_content[table][ref] = obj @@ -228,6 +243,24 @@ def _create_sr(table, obj): return sr_ref +def _create_vlan(pif_ref, vlan_num, network_ref): + LOG.debug("ENTERING FAKE CREATE VLAN") + pif_rec = get_record('PIF', pif_ref) + vlan_pif_ref = _create_object('PIF', { + 'name-label': 'Fake VLAN PIF', + 'MAC': '00:11:22:33:44:55', + 'physical': True, + 'VLAN': vlan_num, + 'device': pif_rec['device'], + 'host_uuid': pif_rec['host_uuid'], + }) + return _create_object('VLAN', { + 'tagged-pif': pif_ref, + 'untagged-pif': vlan_pif_ref, + 'tag': vlan_num + }) + + def get_all(table): return _db_content[table].keys() @@ -235,7 +268,6 @@ def get_all(table): def get_all_records(table): return _db_content[table] - def get_record(table, ref): if ref in _db_content[table]: return _db_content[table].get(ref) @@ -286,6 +318,26 @@ class SessionBase(object): rec['currently_attached'] = False rec['device'] = '' + def PIF_get_all_records_where(self, _1,_2): + # TODO (salvatore-orlando):filter table on _2 + return _db_content['PIF'] + + def VM_get_xenstore_data(self, _1, vm_ref): + return _db_content['VM'][vm_ref].get('xenstore_data', '') + + def VM_remove_from_xenstore_data(self, _1, vm_ref, key): + db_ref = _db_content['VM'][vm_ref] + if not 'xenstore_data' in db_ref: + return + db_ref['xenstore_data'][key] = None + + + def VM_add_to_xenstore_data(self, _1, vm_ref, key, value): + db_ref = _db_content['VM'][vm_ref] + if not 'xenstore_data' in db_ref: + db_ref['xenstore_data'] = {} + db_ref['xenstore_data'][key] = value + def host_compute_free_memory(self, _1, ref): #Always return 12GB available return 12 * 1024 * 1024 * 1024 @@ -431,12 +483,17 @@ class SessionBase(object): def _create(self, name, params): self._check_session(params) is_sr_create = name == 'SR.create' + LOG.debug("NAME:%s",name) + is_vlan_create = name == 'VLAN.create' # Storage Repositories have a different API - expected = is_sr_create and 10 or 2 + expected = is_sr_create and 10 or is_vlan_create and 4 or 2 self._check_arg_count(params, expected) (cls, _) = name.split('.') ref = is_sr_create and \ - _create_sr(cls, params) or _create_object(cls, params[1]) + _create_sr(cls, params) or \ + is_vlan_create and \ + _create_vlan(params[1],params[2],params[3]) or \ + _create_object(cls, params[1]) # Call hook to provide any fixups needed (ex. creating backrefs) after_hook = 'after_%s_create' % cls diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 0813c3db4..4bfef20f3 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -772,7 +772,7 @@ class VMOps(object): if network_ref: try: device = "1" if instance._rescue else "0" - except AttributeError: + except (AttributeError, KeyError): device = "0" VMHelper.create_vif( -- cgit From 7fbf061666516705e74592c3660155e86d3da895 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Wed, 16 Mar 2011 09:15:46 -0400 Subject: Fix up testsuite for lxc --- nova/tests/test_virt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index c149c9307..b3ca241cb 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -256,9 +256,9 @@ class LibvirtConnTestCase(test.TestCase): 'uml': ('uml:///system', [(lambda t: t.find('.').get('type'), 'uml'), (lambda t: t.find('./os/type').text, 'uml')]), - 'lxc': ('lxc://', + 'lxc': ('lxc://;', [(lambda t: t.find('.').get('type'), 'lxc'), - (lambda t: t.find('./os/type').text, 'lxc')]), + (lambda t: t.find('./os/type').text, 'exe')]), 'xen': ('xen:///', [(lambda t: t.find('.').get('type'), 'xen'), (lambda t: t.find('./os/type').text, 'linux')]), -- cgit From 8f9a5ecb7d3907456b9a77f3321ed09feb5c5f2f Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Wed, 16 Mar 2011 09:24:17 -0400 Subject: More execvp fallout --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index af2cbdce5..a79e0a065 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -599,7 +599,7 @@ class LibvirtConnection(object): if FLAGS.libvirt_type == 'lxc': container_dir = '%s/rootfs' % basepath(suffix='') - utils.execute('mkdir -p %s' % container_dir) + utils.execute('mkdir', '-p', container_dir) # NOTE(vish): No need add the suffix to console.log os.close(os.open(basepath('console.log', ''), -- cgit From a21efc63be6bad3bbde41eb96d6a1752e6d8174d Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Wed, 16 Mar 2011 09:26:37 -0400 Subject: Really fix testcase --- nova/tests/test_virt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index b3ca241cb..fed8ff803 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -256,7 +256,7 @@ class LibvirtConnTestCase(test.TestCase): 'uml': ('uml:///system', [(lambda t: t.find('.').get('type'), 'uml'), (lambda t: t.find('./os/type').text, 'uml')]), - 'lxc': ('lxc://;', + 'lxc': ('lxc:///', [(lambda t: t.find('.').get('type'), 'lxc'), (lambda t: t.find('./os/type').text, 'exe')]), 'xen': ('xen:///', -- cgit From c44ab013f5f5a078b27c4965e2e3c4abbfe30c59 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Wed, 16 Mar 2011 20:42:39 -0400 Subject: Revert testsuite changes --- nova/tests/test_virt.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index fed8ff803..b214f5ce7 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -256,15 +256,12 @@ class LibvirtConnTestCase(test.TestCase): 'uml': ('uml:///system', [(lambda t: t.find('.').get('type'), 'uml'), (lambda t: t.find('./os/type').text, 'uml')]), - 'lxc': ('lxc:///', - [(lambda t: t.find('.').get('type'), 'lxc'), - (lambda t: t.find('./os/type').text, 'exe')]), 'xen': ('xen:///', [(lambda t: t.find('.').get('type'), 'xen'), (lambda t: t.find('./os/type').text, 'linux')]), } - for hypervisor_type in ['qemu', 'kvm', 'lxc', 'xen']: + for hypervisor_type in ['qemu', 'kvm', 'xen']: check_list = type_uri_map[hypervisor_type][1] if rescue: -- cgit From fea850245835f867aa4cc741b612445e56e64236 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Wed, 16 Mar 2011 20:52:14 -0400 Subject: Add basic tests for lxc containers. --- nova/tests/test_virt.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index b214f5ce7..fab05de10 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -227,6 +227,42 @@ class LibvirtConnTestCase(test.TestCase): self._check_xml_and_uri(instance_data, expect_kernel=True, expect_ramdisk=True, rescue=True) + def test_lxc_container_and_uri(self): + instance_data = dict(self.test_instace) + self._check_xml_and_container(instance_data) + + def _check_xml_and_container(self, instance): + user_context = context.RequestContext(project=self.project, + user=self.user) + instance_ref = db.instance_create(user_context,instance) + host = self.network.get_network_host(user_context.elevated()) + network_ref= db.project_get_network(context.get_admin_context(), + self.project.id) + + fixed_ip = {'address': self.test_ip, + 'network_id': network_ref['id']} + + ctxt = context.get_admin_context() + fixed_ip_ref = db.fixed_ip_create(ctxt, fixed_ip) + db.fixed_ip_update(ctxt, self.test_ip, + {'allocated': True, + 'instance_id': instance_ref['id']}) + + FLAGS.libvirt_type = 'lxc' + self.assertEquals(uri, 'lxc:///') + + xml = conn.to_xml(instance_ref) + tree = xml_to_tree(xml) + + check = [ + (lambda t: t.find('.').get('type'), 'lxc'), + (lambda t: t.find('./os/type').text, 'exe') + ] + + for i (check, expected_result) in enumerate(check): + self.aseertEqual(check(time), + expected_result, + '%s failed common check %d' % (xml, i)) def _check_xml_and_uri(self, instance, expect_ramdisk, expect_kernel, rescue=False): user_context = context.RequestContext(project=self.project, -- cgit From 7f837b1f22922cb968b0ffb42bdb4d56c0d9f3c3 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 07:06:58 -0400 Subject: Update Authors and testsuite --- Authors | 1 + nova/tests/test_virt.py | 41 ++++++++++++++++++++++++----------------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Authors b/Authors index 9aad104a7..12d2f02de 100644 --- a/Authors +++ b/Authors @@ -11,6 +11,7 @@ Chiradeep Vittal Chmouel Boudjnah Chris Behrens Christian Berendt +Chuck Short Cory Wright Dan Prince David Pravec diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index fab05de10..92c80272b 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -228,16 +228,16 @@ class LibvirtConnTestCase(test.TestCase): expect_ramdisk=True, rescue=True) def test_lxc_container_and_uri(self): - instance_data = dict(self.test_instace) + instance_data = dict(self.test_instance) self._check_xml_and_container(instance_data) def _check_xml_and_container(self, instance): user_context = context.RequestContext(project=self.project, user=self.user) - instance_ref = db.instance_create(user_context,instance) + instance_ref = db.instance_create(user_context, instance) host = self.network.get_network_host(user_context.elevated()) - network_ref= db.project_get_network(context.get_admin_context(), - self.project.id) + network_ref = db.project_get_network(context.get_admin_context(), + self.project.id) fixed_ip = {'address': self.test_ip, 'network_id': network_ref['id']} @@ -245,24 +245,28 @@ class LibvirtConnTestCase(test.TestCase): ctxt = context.get_admin_context() fixed_ip_ref = db.fixed_ip_create(ctxt, fixed_ip) db.fixed_ip_update(ctxt, self.test_ip, - {'allocated': True, - 'instance_id': instance_ref['id']}) + {'allocated': True, + 'instance_id': instance_ref['id']}) FLAGS.libvirt_type = 'lxc' + conn = libvirt_conn.LibvirtConnection(True) + + uri = conn.get_uri() self.assertEquals(uri, 'lxc:///') xml = conn.to_xml(instance_ref) tree = xml_to_tree(xml) check = [ - (lambda t: t.find('.').get('type'), 'lxc'), - (lambda t: t.find('./os/type').text, 'exe') + (lambda t: t.find('.').get('type'), 'lxc'), + (lambda t: t.find('./os/type').text, 'exe'), ] - for i (check, expected_result) in enumerate(check): - self.aseertEqual(check(time), + for i, (check, expected_result) in enumerate(check): + self.assertEqual(check(tree), expected_result, '%s failed common check %d' % (xml, i)) + def _check_xml_and_uri(self, instance, expect_ramdisk, expect_kernel, rescue=False): user_context = context.RequestContext(project=self.project, @@ -322,6 +326,7 @@ class LibvirtConnTestCase(test.TestCase): check = (lambda t: t.find('./os/initrd'), None) check_list.append(check) + common_checks = [ (lambda t: t.find('.').tag, 'domain'), (lambda t: t.find( @@ -338,8 +343,9 @@ class LibvirtConnTestCase(test.TestCase): (lambda t: t.find('./devices/serial/source').get( 'path').split('/')[1], 'console.log'), (lambda t: t.find('./memory').text, '2097152')] + if rescue: - common_checks += [ + common_checks = [ (lambda t: t.findall('./devices/disk/source')[0].get( 'file').split('/')[1], 'disk.rescue'), (lambda t: t.findall('./devices/disk/source')[1].get( @@ -362,14 +368,15 @@ class LibvirtConnTestCase(test.TestCase): xml = conn.to_xml(instance_ref, rescue) tree = xml_to_tree(xml) for i, (check, expected_result) in enumerate(checks): - self.assertEqual(check(tree), - expected_result, - '%s failed check %d' % (xml, i)) + self.assertEqual(check(tree), + expected_result, + '%s failed check %d' % (xml, i)) + for i, (check, expected_result) in enumerate(common_checks): - self.assertEqual(check(tree), - expected_result, - '%s failed common check %d' % (xml, i)) + self.assertEqual(check(tree), + expected_result, + '%s failed common check %d' % (xml, i)) # This test is supposed to make sure we don't # override a specifically set uri -- cgit From 7701edd34f1fc9fa26b3dfcc77ff87018622bedc Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 07:13:31 -0400 Subject: get_console_output is not supported by lxc and libvirt --- nova/virt/libvirt_conn.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index d08ca8b6a..9bfd3f841 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -490,6 +490,9 @@ class LibvirtConnection(object): instance['name']) data = self._flush_xen_console(virsh_output) fpath = self._append_to_file(data, console_log) + elif FLAGS.libvirt_type == 'lxc': + # LXC is also special + LOG.info(_("Unable to read LXC console")) else: fpath = console_log -- cgit From 70cd1a51ada85f4724190d2562130172e9495e5e Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 07:53:25 -0400 Subject: Update authors again --- Authors | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Authors b/Authors index 12d2f02de..22a9fb8eb 100644 --- a/Authors +++ b/Authors @@ -11,7 +11,7 @@ Chiradeep Vittal Chmouel Boudjnah Chris Behrens Christian Berendt -Chuck Short +Chuck Short Cory Wright Dan Prince David Pravec -- cgit From 9ba500c304595dff037da296f26cb13d02bfbc04 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 07:57:06 -0400 Subject: Fix pep8 errors --- nova/tests/test_virt.py | 2 -- nova/virt/disk.py | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 92c80272b..7d50960a3 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -326,7 +326,6 @@ class LibvirtConnTestCase(test.TestCase): check = (lambda t: t.find('./os/initrd'), None) check_list.append(check) - common_checks = [ (lambda t: t.find('.').tag, 'domain'), (lambda t: t.find( @@ -372,7 +371,6 @@ class LibvirtConnTestCase(test.TestCase): expected_result, '%s failed check %d' % (xml, i)) - for i, (check, expected_result) in enumerate(common_checks): self.assertEqual(check(tree), expected_result, diff --git a/nova/virt/disk.py b/nova/virt/disk.py index a44995613..26976940e 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -129,6 +129,7 @@ def setup_container(image, container_dir=None, partition=None, nbd=False): % err) _unlink_device(device, nbd) + def destroy_container(target, instance, nbd=False): """Destroy the container once it terminates -- cgit From bb6096c51cde91dccaad0e9f584f2dc26057da1f Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 08:49:52 -0400 Subject: Update mailmap --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index ccf2109a7..78cfef53b 100644 --- a/.mailmap +++ b/.mailmap @@ -10,6 +10,7 @@ + -- cgit From c98cead470f33041e928a6f82be801efeb94ccc3 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 08:52:52 -0400 Subject: Remove nbd=FLAGS.use_cow_images for destroy container --- nova/virt/disk.py | 7 +++---- nova/virt/libvirt_conn.py | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index 26976940e..90d3cf499 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -23,7 +23,6 @@ Includes injection of SSH PGP keys into authorized_keys file. """ import os -import string import tempfile import time @@ -130,7 +129,7 @@ def setup_container(image, container_dir=None, partition=None, nbd=False): _unlink_device(device, nbd) -def destroy_container(target, instance, nbd=False): +def destroy_container(target, instance): """Destroy the container once it terminates It will umount the container that is mounted, try to find the loopback @@ -140,9 +139,9 @@ def destroy_container(target, instance, nbd=False): container_dir = '%s/rootfs' % target utils.execute('sudo', 'umount', container_dir) finally: - for loop in os.popen('sudo losetup -a').readlines(): + for loop in utils.popen('sudo losetup -a').readlines(): if instance['name'] in loop: - device = string.split(loop, ':') + device = loop.split(loop, ':') utils.execute('sudo', 'losetup', '--detach', device) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 9bfd3f841..9e0d0538d 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -275,7 +275,7 @@ class LibvirtConnection(object): LOG.info(_('instance %(instance_name)s: deleting instance files' ' %(target)s') % locals()) if FLAGS.libvirt_type == 'lxc': - disk.destroy_container(target, instance, nbd=FLAGS.use_cow_images) + disk.destroy_container(target, instance) if os.path.exists(target): shutil.rmtree(target) -- cgit From 6bd017262a5c61d915ede2e58ef2758f1f190ff3 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 08:54:05 -0400 Subject: Remove target_partition for setup_container but still hardcode because its needed when you inject the keys into the image. --- nova/virt/libvirt_conn.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 9e0d0538d..0ca27d629 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -700,8 +700,7 @@ class LibvirtConnection(object): if FLAGS.libvirt_type == 'lxc': disk.setup_container(basepath('disk'), container_dir=container_dir, - partition=target_partition, - nbd=FLAGS.use_cow_images) + partition=target_partition) except Exception as e: # This could be a windows image, or a vmdk format disk LOG.warn(_('instance %(inst_name)s: ignoring error injecting' -- cgit From cc716f9648355bc3737dd749a35dc327ebda1e6f Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 09:15:33 -0400 Subject: Fixed typo when I was trying to add test cases for lxc --- nova/tests/test_virt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 7d50960a3..c2b8ba0a1 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -344,7 +344,7 @@ class LibvirtConnTestCase(test.TestCase): (lambda t: t.find('./memory').text, '2097152')] if rescue: - common_checks = [ + common_checks += [ (lambda t: t.findall('./devices/disk/source')[0].get( 'file').split('/')[1], 'disk.rescue'), (lambda t: t.findall('./devices/disk/source')[1].get( -- cgit From 174d8ca2da7e2e53c9105ccc5e5d9a97bc12c0b8 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 09:17:42 -0400 Subject: Set nbd to false when mounting the image --- nova/virt/disk.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index 90d3cf499..a84425de7 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -121,6 +121,7 @@ def setup_container(image, container_dir=None, partition=None, nbd=False): It will mount the loopback image to the container directory in order to create the root filesystem for the container """ + nbd=False device = _link_device(image, nbd) err = utils.execute('sudo', 'mount', device, container_dir) if err: -- cgit From bc0ef2c7aead759504eedcb4e2ab6d96dba7c266 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 10:02:40 -0400 Subject: Fix up setup container --- nova/virt/disk.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index a84425de7..2fa7819d7 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -115,7 +115,7 @@ def inject_data(image, key=None, net=None, partition=None, nbd=False): _unlink_device(device, nbd) -def setup_container(image, container_dir=None, partition=None, nbd=False): +def setup_container(image, container_dir=None, partition=None): """Setup the LXC container It will mount the loopback image to the container directory in order -- cgit From abb86555f7417225a72126872beb377268acfdb1 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 10:16:37 -0400 Subject: Remove me from mailmap --- .mailmap | 1 - 1 file changed, 1 deletion(-) diff --git a/.mailmap b/.mailmap index 78cfef53b..ccf2109a7 100644 --- a/.mailmap +++ b/.mailmap @@ -10,7 +10,6 @@ - -- cgit From 36285d3acb940c39dc1827699c1e3c0cc9846529 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 10:22:57 -0400 Subject: Fix more pep8 errors --- nova/tests/test_virt.py | 12 ++++++------ nova/virt/disk.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index c2b8ba0a1..222975adc 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -367,14 +367,14 @@ class LibvirtConnTestCase(test.TestCase): xml = conn.to_xml(instance_ref, rescue) tree = xml_to_tree(xml) for i, (check, expected_result) in enumerate(checks): - self.assertEqual(check(tree), - expected_result, - '%s failed check %d' % (xml, i)) + self.assertEqual(check(tree), + expected_result, + '%s failed check %d' % (xml, i)) for i, (check, expected_result) in enumerate(common_checks): - self.assertEqual(check(tree), - expected_result, - '%s failed common check %d' % (xml, i)) + self.assertEqual(check(tree), + expected_result, + '%s failed common check %d' % (xml, i)) # This test is supposed to make sure we don't # override a specifically set uri diff --git a/nova/virt/disk.py b/nova/virt/disk.py index 2fa7819d7..6c5f126bd 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -121,7 +121,7 @@ def setup_container(image, container_dir=None, partition=None): It will mount the loopback image to the container directory in order to create the root filesystem for the container """ - nbd=False + nbd = False device = _link_device(image, nbd) err = utils.execute('sudo', 'mount', device, container_dir) if err: @@ -132,7 +132,7 @@ def setup_container(image, container_dir=None, partition=None): def destroy_container(target, instance): """Destroy the container once it terminates - + It will umount the container that is mounted, try to find the loopback device associated with the container and delete it. """ -- cgit From a06203c66af05c96c161b80511f4a6607ffe4905 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 10:41:55 -0400 Subject: Fix up tests --- nova/tests/test_virt.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 222975adc..fefc11f0d 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -239,8 +239,8 @@ class LibvirtConnTestCase(test.TestCase): network_ref = db.project_get_network(context.get_admin_context(), self.project.id) - fixed_ip = {'address': self.test_ip, - 'network_id': network_ref['id']} + fixed_ip = {'address': self.test_ip, + 'network_id': network_ref['id']} ctxt = context.get_admin_context() fixed_ip_ref = db.fixed_ip_create(ctxt, fixed_ip) @@ -259,13 +259,13 @@ class LibvirtConnTestCase(test.TestCase): check = [ (lambda t: t.find('.').get('type'), 'lxc'), - (lambda t: t.find('./os/type').text, 'exe'), + (lambda t: t.find('./os/type').text, 'exe') ] for i, (check, expected_result) in enumerate(check): - self.assertEqual(check(tree), - expected_result, - '%s failed common check %d' % (xml, i)) + self.assertEqual(check(tree), + expected_result, + '%s failed common check %d' % (xml, i)) def _check_xml_and_uri(self, instance, expect_ramdisk, expect_kernel, rescue=False): @@ -342,7 +342,6 @@ class LibvirtConnTestCase(test.TestCase): (lambda t: t.find('./devices/serial/source').get( 'path').split('/')[1], 'console.log'), (lambda t: t.find('./memory').text, '2097152')] - if rescue: common_checks += [ (lambda t: t.findall('./devices/disk/source')[0].get( -- cgit From dee8a59b5d575a0327464e27115d0d870cde97be Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 10:43:48 -0400 Subject: more pep8 fixes --- nova/tests/test_virt.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index fefc11f0d..2510525fc 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -263,9 +263,9 @@ class LibvirtConnTestCase(test.TestCase): ] for i, (check, expected_result) in enumerate(check): - self.assertEqual(check(tree), - expected_result, - '%s failed common check %d' % (xml, i)) + self.assertEqual(check(tree), + expected_result, + '%s failed common check %d' % (xml, i)) def _check_xml_and_uri(self, instance, expect_ramdisk, expect_kernel, rescue=False): -- cgit From 4364a158fd31bdfcfa3ae835a2fd9c0f47d3632f Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 10:45:31 -0400 Subject: pep8 fixes --- nova/tests/test_virt.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 2510525fc..45f98fcde 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -259,8 +259,7 @@ class LibvirtConnTestCase(test.TestCase): check = [ (lambda t: t.find('.').get('type'), 'lxc'), - (lambda t: t.find('./os/type').text, 'exe') - ] + (lambda t: t.find('./os/type').text, 'exe')] for i, (check, expected_result) in enumerate(check): self.assertEqual(check(tree), -- cgit From b0e3b8e58a925ebf52fa741883f757ed2bc4383c Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 17 Mar 2011 10:47:19 -0400 Subject: more pep8 fixes --- nova/virt/disk.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index 6c5f126bd..f6e6795d6 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -132,7 +132,7 @@ def setup_container(image, container_dir=None, partition=None): def destroy_container(target, instance): """Destroy the container once it terminates - + It will umount the container that is mounted, try to find the loopback device associated with the container and delete it. """ -- cgit From af67fba36436feeede4dcc5720e51d2b66c3094a Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Thu, 17 Mar 2011 22:30:34 -0400 Subject: Images now v1.1 supported...mostly. --- nova/api/openstack/__init__.py | 11 +- nova/api/openstack/images.py | 214 ++++++++++++++------------------ nova/api/openstack/views/images.py | 63 ++++++++-- nova/tests/api/openstack/test_images.py | 171 +++++++++++++++++++------ 4 files changed, 285 insertions(+), 174 deletions(-) diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 0b50d17d0..0ac67fdba 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -113,8 +113,6 @@ class APIRouter(wsgi.Router): parent_resource=dict(member_name='server', collection_name='servers')) - mapper.resource("image", "images", controller=images.Controller(), - collection={'detail': 'GET'}) mapper.resource("flavor", "flavors", controller=flavors.Controller(), collection={'detail': 'GET'}) mapper.resource("shared_ip_group", "shared_ip_groups", @@ -130,6 +128,10 @@ class APIRouterV10(APIRouter): collection={'detail': 'GET'}, member=self.server_members) + mapper.resource("image", "images", + controller=images.Controller_v1_0(), + collection={'detail': 'GET'}) + class APIRouterV11(APIRouter): def _setup_routes(self, mapper): @@ -139,6 +141,11 @@ class APIRouterV11(APIRouter): collection={'detail': 'GET'}, member=self.server_members) + mapper.resource("image", "images", + controller=images.Controller_v1_1(), + collection={'detail': 'GET'}) + + class Versions(wsgi.Application): @webob.dec.wsgify(RequestClass=wsgi.Request) diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index 98f0dd96b..2357bfd3d 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -1,6 +1,4 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 OpenStack LLC. +# Copyright 2011 OpenStack LLC. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -19,92 +17,19 @@ from webob import exc from nova import compute from nova import flags +from nova import log from nova import utils from nova import wsgi -import nova.api.openstack -from nova.api.openstack import common -from nova.api.openstack import faults -import nova.image.service - - -FLAGS = flags.FLAGS - - -def _translate_keys(item): - """ - Maps key names to Rackspace-like attributes for return - also pares down attributes to those we want - item is a dict - - Note: should be removed when the set of keys expected by the api - and the set of keys returned by the image service are equivalent - - """ - # TODO(tr3buchet): this map is specific to s3 object store, - # replace with a list of keys for _filter_keys later - mapped_keys = {'status': 'imageState', - 'id': 'imageId', - 'name': 'imageLocation'} - - mapped_item = {} - # TODO(tr3buchet): - # this chunk of code works with s3 and the local image service/glance - # when we switch to glance/local image service it can be replaced with - # a call to _filter_keys, and mapped_keys can be changed to a list - try: - for k, v in mapped_keys.iteritems(): - # map s3 fields - mapped_item[k] = item[v] - except KeyError: - # return only the fields api expects - mapped_item = _filter_keys(item, mapped_keys.keys()) - - return mapped_item - - -def _translate_status(item): - """ - Translates status of image to match current Rackspace api bindings - item is a dict +from nova.api.openstack.views import images as images_view - Note: should be removed when the set of statuses expected by the api - and the set of statuses returned by the image service are equivalent +class Controller(wsgi.Controller): """ - status_mapping = { - 'pending': 'queued', - 'decrypting': 'preparing', - 'untarring': 'saving', - 'available': 'active'} - try: - item['status'] = status_mapping[item['status']] - except KeyError: - # TODO(sirp): Performing translation of status (if necessary) here for - # now. Perhaps this should really be done in EC2 API and - # S3ImageService - pass - - return item - - -def _filter_keys(item, keys): - """ - Filters all model attributes except for keys - item is a dict - + Base `wsgi.Controller` for retrieving and displaying images in the + OpenStack API. Version-inspecific code goes here. """ - return dict((k, v) for k, v in item.iteritems() if k in keys) - - -def _convert_image_id_to_hash(image): - if 'imageId' in image: - # Convert EC2-style ID (i-blah) to Rackspace-style (int) - image_id = abs(hash(image['imageId'])) - image['imageId'] = image_id - image['id'] = image_id - -class Controller(wsgi.Controller): + _builder = images_view.Builder_v1_0() _serialization_metadata = { 'application/xml': { @@ -112,55 +37,96 @@ class Controller(wsgi.Controller): "image": ["id", "name", "updated", "created", "status", "serverId", "progress"]}}} - def __init__(self): - self._service = utils.import_object(FLAGS.image_service) + def __init__(self, image_service=None, compute_service=None): + """ + Initialize new `ImageController`. + + @param compute_service: `nova.compute.api:API` + @param image_service: `nova.image.service:BaseImageService` + """ + _default_service = utils.import_object(flags.FLAGS.image_service) + + self.__compute = compute_service or compute.API() + self.__image = image_service or _default_service + self.__log = log.getLogger(self.__class__.__name__) def index(self, req): - """Return all public images in brief""" - items = self._service.index(req.environ['nova.context']) - items = common.limited(items, req) - items = [_filter_keys(item, ('id', 'name')) for item in items] - return dict(images=items) + """ + Return an index listing of images available to the request. + + @param req: `webob.Request` object + """ + context = req.environ['nova.context'] + images = self.__image.index(context) + build = self._builder.build + return dict(images=[build(req, image, False) for image in images]) def detail(self, req): - """Return all public images in detail""" - try: - items = self._service.detail(req.environ['nova.context']) - except NotImplementedError: - items = self._service.index(req.environ['nova.context']) - for image in items: - _convert_image_id_to_hash(image) - - items = common.limited(items, req) - items = [_translate_keys(item) for item in items] - items = [_translate_status(item) for item in items] - return dict(images=items) - - def show(self, req, id): - """Return data about the given image id""" - image_id = common.get_image_id_from_image_hash(self._service, - req.environ['nova.context'], id) - - image = self._service.show(req.environ['nova.context'], image_id) - _convert_image_id_to_hash(image) - return dict(image=image) - - def delete(self, req, id): - # Only public images are supported for now. - raise faults.Fault(exc.HTTPNotFound()) + """ + Return a detailed index listing of images available to the request. + + @param req: `webob.Request` object. + """ + context = req.environ['nova.context'] + images = self.__image.detail(context) + build = self._builder.build + return dict(images=[build(req, image, True) for image in images]) + + def show(self, req, image_id): + """ + Return detailed information about a specific image. + + @param req: `webob.Request` object + @param image_id: Image identifier (integer) + """ + context = req.environ['nova.context'] + image = self.__image.show(context, image_id) + return self._builder.build(req, image, True) + + def delete(self, req, image_id): + """ + Delete an image, if allowed. + + @param req: `webob.Request` object + @param image_id: Image identifier (integer) + """ + context = req.environ['nova.context'] + self.__image.delete(context, image_id) + return exc.HTTPNoContent() def create(self, req): + """ + Snapshot a server instance and save the image. + + @param req: `webob.Request` object + """ context = req.environ['nova.context'] - env = self._deserialize(req.body, req.get_content_type()) - instance_id = env["image"]["serverId"] - name = env["image"]["name"] + body = req.body + content_type = req.get_content_type() + image = self._deserialize(body, content_type) + + if not image: + raise exc.HTTPBadRequest() + + try: + server_id = image["serverId"] + image_name = image["name"] + except KeyError: + raise exc.HTTPBadRequest() + + image = self.__compute.snapshot(context, server_id, image_name) + return self._builder.build(req, image, True) - image_meta = compute.API().snapshot( - context, instance_id, name) - return dict(image=image_meta) +class Controller_v1_0(Controller): + """ + Version 1.0 specific controller logic. + """ + _builder = images_view.Builder_v1_0() + - def update(self, req, id): - # Users may not modify public images, and that's all that - # we support for now. - raise faults.Fault(exc.HTTPNotFound()) +class Controller_v1_1(Controller): + """ + Version 1.1 specific controller logic. + """ + _builder = images_view.Builder_v1_1() diff --git a/nova/api/openstack/views/images.py b/nova/api/openstack/views/images.py index a6c6ad7d1..1631d1fe3 100644 --- a/nova/api/openstack/views/images.py +++ b/nova/api/openstack/views/images.py @@ -15,20 +15,61 @@ # License for the specific language governing permissions and limitations # under the License. -from nova.api.openstack import common +class Builder(object): + """ + Base class for generating responses to OpenStack API requests for + information about images. + """ -class ViewBuilder(object): - def __init__(self): - pass + def build(self, request, image_obj, detail=False): + """ + Return a standardized image structure for display by the API. + """ + image = { + "id": image_obj["id"], + "name": image_obj["name"], + } - def build(self, image_obj): - raise NotImplementedError() + if detail: + image.update({ + "created": image_obj["created_at"], + "updated": image_obj["updated_at"], + "status": image_obj["status"], + }) + return image -class ViewBuilderV11(ViewBuilder): - def __init__(self, base_url): - self.base_url = base_url - def generate_href(self, image_id): - return "%s/images/%s" % (self.base_url, image_id) +class Builder_v1_0(Builder): + pass + + +class Builder_v1_1(Builder): + """ + OpenStack API v1.1 Image Builder + """ + + def build(self, request, image_obj, detail=False): + """ + Return a standardized image structure for display by the API. + """ + image = Builder.build(self, request, image_obj, detail) + href = "%s/images/%s" % (request.application_url, image_obj["id"]) + + image["links"] = [{ + "rel": "self", + "href": href, + }, + { + "rel": "bookmark", + "type": "application/json", + "href": href, + }, + { + "rel": "bookmark", + "type": "application/xml", + "href": href, + }] + + return image diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index 76f758929..c313192b7 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -42,8 +42,9 @@ FLAGS = flags.FLAGS class BaseImageServiceTests(object): - - """Tasks to test for all image services""" + """ + Tasks to test for all image services. + """ def test_create(self): @@ -173,10 +174,9 @@ class GlanceImageServiceTest(test.TestCase, class ImageControllerWithGlanceServiceTest(test.TestCase): - - """Test of the OpenStack API /images application controller""" - - # Registered images at start of each test. + """ + Test of the OpenStack API /images application controller w/Glance. + """ IMAGE_FIXTURES = [ {'id': '23g2ogk23k4hhkk4k42l', @@ -198,7 +198,8 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): 'deleted': False, 'is_public': True, 'status': 'available', - 'image_type': 'ramdisk'}] + 'image_type': 'ramdisk'}, + ] def setUp(self): super(ImageControllerWithGlanceServiceTest, self).setUp() @@ -219,36 +220,132 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): super(ImageControllerWithGlanceServiceTest, self).tearDown() def test_get_image_index(self): - req = webob.Request.blank('/v1.0/images') - res = req.get_response(fakes.wsgi_app()) - res_dict = json.loads(res.body) + request = webob.Request.blank('/v1.0/images') + response = request.get_response(fakes.wsgi_app()) + + response_dict = json.loads(response.body) + response_list = response_dict["images"] + + for image in self.IMAGE_FIXTURES: + test_image = { + "id": image["id"], + "name": image["name"], + } + self.assertTrue(test_image in response_list) + + self.assertEqual(len(response_list), len(self.IMAGE_FIXTURES)) + + def test_get_image_index_v1_1(self): + request = webob.Request.blank('/v1.1/images') + response = request.get_response(fakes.wsgi_app()) + + response_dict = json.loads(response.body) + response_list = response_dict["images"] + + for image in self.IMAGE_FIXTURES: + href = "http://localhost/v1.1/images/%s" % image["id"] + test_image = { + "id": image["id"], + "name": image["name"], + "links": [{ + "rel": "self", + "href": "http://localhost/v1.1/images/%s" % image["id"], + }, + { + "rel": "bookmark", + "type": "application/json", + "href": href, + }, + { + "rel": "bookmark", + "type": "application/xml", + "href": href, + }], + } + print test_image + print + print response_list + self.assertTrue(test_image in response_list) + + self.assertEqual(len(response_list), len(self.IMAGE_FIXTURES)) - fixture_index = [dict(id=f['id'], name=f['name']) for f - in self.IMAGE_FIXTURES] + def test_get_image_details(self): + request = webob.Request.blank('/v1.0/images/detail') + response = request.get_response(fakes.wsgi_app()) + + response_dict = json.loads(response.body) + response_list = response_dict["images"] + + for image in self.IMAGE_FIXTURES: + test_image = { + "id": image["id"], + "name": image["name"], + "updated": image["updated_at"], + "created": image["created_at"], + "status": image["status"], + } + self.assertTrue(test_image in response_list) + + self.assertEqual(len(response_list), len(self.IMAGE_FIXTURES)) + + def test_get_image_details_v1_1(self): + request = webob.Request.blank('/v1.1/images/detail') + response = request.get_response(fakes.wsgi_app()) + + response_dict = json.loads(response.body) + response_list = response_dict["images"] + + for image in self.IMAGE_FIXTURES: + href = "http://localhost/v1.1/images/%s" % image["id"] + test_image = { + "id": image["id"], + "name": image["name"], + "updated": image["updated_at"], + "created": image["created_at"], + "status": image["status"], + "links": [{ + "rel": "self", + "href": href, + }, + { + "rel": "bookmark", + "type": "application/json", + "href": href, + }, + { + "rel": "bookmark", + "type": "application/xml", + "href": href, + }], + } + self.assertTrue(test_image in response_list) + + self.assertEqual(len(response_list), len(self.IMAGE_FIXTURES)) + + def test_get_image_create_empty(self): + request = webob.Request.blank('/v1.1/images') + request.method = "POST" + response = request.get_response(fakes.wsgi_app()) + self.assertEqual(400, response.status_int) + + def test_get_image_create_bad_no_name(self): + request = webob.Request.blank('/v1.1/images') + request.method = "POST" + request.content_type = "application/json" + request.body = json.dumps({ + "serverId": 1, + }) + response = request.get_response(fakes.wsgi_app()) + self.assertEqual(400, response.status_int) + + def test_get_image_create_bad_no_id(self): + request = webob.Request.blank('/v1.1/images') + request.method = "POST" + request.content_type = "application/json" + request.body = json.dumps({ + "name" : "Snapshot Test", + }) + response = request.get_response(fakes.wsgi_app()) + self.assertEqual(400, response.status_int) - for image in res_dict['images']: - self.assertEquals(1, fixture_index.count(image), - "image %s not in fixture index!" % str(image)) - def test_get_image_details(self): - req = webob.Request.blank('/v1.0/images/detail') - res = req.get_response(fakes.wsgi_app()) - res_dict = json.loads(res.body) - - def _is_equivalent_subset(x, y): - if set(x) <= set(y): - for k, v in x.iteritems(): - if x[k] != y[k]: - if x[k] == 'active' and y[k] == 'available': - continue - return False - return True - return False - - for image in res_dict['images']: - for image_fixture in self.IMAGE_FIXTURES: - if _is_equivalent_subset(image, image_fixture): - break - else: - self.assertEquals(1, 2, "image %s not in fixtures!" % - str(image)) -- cgit From febbfd45a0c1dbd16093ab38897e94ddb331e9ea Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Thu, 17 Mar 2011 23:34:12 -0400 Subject: Updated naming, removed some prints, and removed some invalid tests. --- nova/api/openstack/__init__.py | 4 ++-- nova/api/openstack/images.py | 20 +++++++++++--------- nova/api/openstack/views/images.py | 8 ++++---- nova/tests/api/openstack/test_images.py | 31 ------------------------------- 4 files changed, 17 insertions(+), 46 deletions(-) diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 0ac67fdba..1ec943f55 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -129,7 +129,7 @@ class APIRouterV10(APIRouter): member=self.server_members) mapper.resource("image", "images", - controller=images.Controller_v1_0(), + controller=images.ControllerV10(), collection={'detail': 'GET'}) @@ -142,7 +142,7 @@ class APIRouterV11(APIRouter): member=self.server_members) mapper.resource("image", "images", - controller=images.Controller_v1_1(), + controller=images.ControllerV11(), collection={'detail': 'GET'}) diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index 2357bfd3d..bc7338699 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -29,13 +29,15 @@ class Controller(wsgi.Controller): OpenStack API. Version-inspecific code goes here. """ - _builder = images_view.Builder_v1_0() - _serialization_metadata = { 'application/xml': { "attributes": { "image": ["id", "name", "updated", "created", "status", - "serverId", "progress"]}}} + "serverId", "progress"], + "link": ["rel", "type", "href"], + }, + }, + } def __init__(self, image_service=None, compute_service=None): """ @@ -109,8 +111,8 @@ class Controller(wsgi.Controller): raise exc.HTTPBadRequest() try: - server_id = image["serverId"] - image_name = image["name"] + server_id = image["image"]["serverId"] + image_name = image["image"]["name"] except KeyError: raise exc.HTTPBadRequest() @@ -118,15 +120,15 @@ class Controller(wsgi.Controller): return self._builder.build(req, image, True) -class Controller_v1_0(Controller): +class ControllerV10(Controller): """ Version 1.0 specific controller logic. """ - _builder = images_view.Builder_v1_0() + _builder = images_view.ViewBuilderV10() -class Controller_v1_1(Controller): +class ControllerV11(Controller): """ Version 1.1 specific controller logic. """ - _builder = images_view.Builder_v1_1() + _builder = images_view.ViewBuilderV11() diff --git a/nova/api/openstack/views/images.py b/nova/api/openstack/views/images.py index 1631d1fe3..c41e60546 100644 --- a/nova/api/openstack/views/images.py +++ b/nova/api/openstack/views/images.py @@ -16,7 +16,7 @@ # under the License. -class Builder(object): +class ViewBuilder(object): """ Base class for generating responses to OpenStack API requests for information about images. @@ -41,11 +41,11 @@ class Builder(object): return image -class Builder_v1_0(Builder): +class ViewBuilderV10(ViewBuilder): pass -class Builder_v1_1(Builder): +class ViewBuilderV11(ViewBuilder): """ OpenStack API v1.1 Image Builder """ @@ -54,7 +54,7 @@ class Builder_v1_1(Builder): """ Return a standardized image structure for display by the API. """ - image = Builder.build(self, request, image_obj, detail) + image = ViewBuilder.build(self, request, image_obj, detail) href = "%s/images/%s" % (request.application_url, image_obj["id"]) image["links"] = [{ diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index c313192b7..c5a866bc7 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -262,9 +262,6 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): "href": href, }], } - print test_image - print - print response_list self.assertTrue(test_image in response_list) self.assertEqual(len(response_list), len(self.IMAGE_FIXTURES)) @@ -321,31 +318,3 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): self.assertTrue(test_image in response_list) self.assertEqual(len(response_list), len(self.IMAGE_FIXTURES)) - - def test_get_image_create_empty(self): - request = webob.Request.blank('/v1.1/images') - request.method = "POST" - response = request.get_response(fakes.wsgi_app()) - self.assertEqual(400, response.status_int) - - def test_get_image_create_bad_no_name(self): - request = webob.Request.blank('/v1.1/images') - request.method = "POST" - request.content_type = "application/json" - request.body = json.dumps({ - "serverId": 1, - }) - response = request.get_response(fakes.wsgi_app()) - self.assertEqual(400, response.status_int) - - def test_get_image_create_bad_no_id(self): - request = webob.Request.blank('/v1.1/images') - request.method = "POST" - request.content_type = "application/json" - request.body = json.dumps({ - "name" : "Snapshot Test", - }) - response = request.get_response(fakes.wsgi_app()) - self.assertEqual(400, response.status_int) - - -- cgit From fce6b6f8f39378f5f31b8aa432922374c744544e Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Fri, 18 Mar 2011 00:05:58 -0400 Subject: Become compatible with ironcamel and bcwaldon's implementations for standardness. --- nova/api/openstack/images.py | 31 +++++++++++++++++++++++-------- nova/api/openstack/views/images.py | 18 +++++++++++++++--- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index bc7338699..a192883fc 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -17,9 +17,9 @@ from webob import exc from nova import compute from nova import flags -from nova import log from nova import utils from nova import wsgi +from nova.api.openstack import common from nova.api.openstack.views import images as images_view @@ -39,6 +39,11 @@ class Controller(wsgi.Controller): }, } + _builder_dispatch = { + "1.0": images_view.ViewBuilderV10, + "1.1": images_view.ViewBuilderV11, + } + def __init__(self, image_service=None, compute_service=None): """ Initialize new `ImageController`. @@ -50,7 +55,17 @@ class Controller(wsgi.Controller): self.__compute = compute_service or compute.API() self.__image = image_service or _default_service - self.__log = log.getLogger(self.__class__.__name__) + + def get_builder(self, request): + """ + Property to get the ViewBuilder class we need to use. + """ + version = common.get_api_version(request) + base_url = request.application_url + try: + return self._builder_dispatch[version](base_url) + except KeyError: + raise exc.HTTPNotFound() def index(self, req): """ @@ -60,7 +75,7 @@ class Controller(wsgi.Controller): """ context = req.environ['nova.context'] images = self.__image.index(context) - build = self._builder.build + build = self.get_builder(req).build return dict(images=[build(req, image, False) for image in images]) def detail(self, req): @@ -71,7 +86,7 @@ class Controller(wsgi.Controller): """ context = req.environ['nova.context'] images = self.__image.detail(context) - build = self._builder.build + build = self.get_builder(req).build return dict(images=[build(req, image, True) for image in images]) def show(self, req, image_id): @@ -83,7 +98,7 @@ class Controller(wsgi.Controller): """ context = req.environ['nova.context'] image = self.__image.show(context, image_id) - return self._builder.build(req, image, True) + return self.get_builder(req).build(req, image, True) def delete(self, req, image_id): """ @@ -117,18 +132,18 @@ class Controller(wsgi.Controller): raise exc.HTTPBadRequest() image = self.__compute.snapshot(context, server_id, image_name) - return self._builder.build(req, image, True) + return self.get_builder(req).build(req, image, True) class ControllerV10(Controller): """ Version 1.0 specific controller logic. """ - _builder = images_view.ViewBuilderV10() + pass class ControllerV11(Controller): """ Version 1.1 specific controller logic. """ - _builder = images_view.ViewBuilderV11() + pass diff --git a/nova/api/openstack/views/images.py b/nova/api/openstack/views/images.py index c41e60546..313ba2eba 100644 --- a/nova/api/openstack/views/images.py +++ b/nova/api/openstack/views/images.py @@ -22,7 +22,19 @@ class ViewBuilder(object): information about images. """ - def build(self, request, image_obj, detail=False): + def __init__(self, base_url): + """ + Initialize new `ViewBuilder`. + """ + self._url = base_url + + def generate_href(self, image_id): + """ + Return an href string pointing to this object. + """ + return "%s/images/%s" % (self._url, image_id) + + def build(self, image_obj, detail=False): """ Return a standardized image structure for display by the API. """ @@ -50,12 +62,12 @@ class ViewBuilderV11(ViewBuilder): OpenStack API v1.1 Image Builder """ - def build(self, request, image_obj, detail=False): + def build(self, image_obj, detail=False): """ Return a standardized image structure for display by the API. """ image = ViewBuilder.build(self, request, image_obj, detail) - href = "%s/images/%s" % (request.application_url, image_obj["id"]) + href = self.generate_url(image_obj["id"]) image["links"] = [{ "rel": "self", -- cgit From c28ec048a56a3ead96dc7528ca50865945d40646 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Fri, 18 Mar 2011 00:19:53 -0400 Subject: Final touches and bug/pep8 fixes. --- nova/api/openstack/__init__.py | 1 - nova/api/openstack/images.py | 35 ++++++++++++++++++----------------- nova/api/openstack/servers.py | 1 + nova/api/openstack/views/images.py | 4 ++-- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 1ec943f55..14cb6b331 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -146,7 +146,6 @@ class APIRouterV11(APIRouter): collection={'detail': 'GET'}) - class Versions(wsgi.Application): @webob.dec.wsgify(RequestClass=wsgi.Request) def __call__(self, req): diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index a192883fc..4cd989054 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -56,17 +56,6 @@ class Controller(wsgi.Controller): self.__compute = compute_service or compute.API() self.__image = image_service or _default_service - def get_builder(self, request): - """ - Property to get the ViewBuilder class we need to use. - """ - version = common.get_api_version(request) - base_url = request.application_url - try: - return self._builder_dispatch[version](base_url) - except KeyError: - raise exc.HTTPNotFound() - def index(self, req): """ Return an index listing of images available to the request. @@ -76,7 +65,7 @@ class Controller(wsgi.Controller): context = req.environ['nova.context'] images = self.__image.index(context) build = self.get_builder(req).build - return dict(images=[build(req, image, False) for image in images]) + return dict(images=[build(image, False) for image in images]) def detail(self, req): """ @@ -87,7 +76,7 @@ class Controller(wsgi.Controller): context = req.environ['nova.context'] images = self.__image.detail(context) build = self.get_builder(req).build - return dict(images=[build(req, image, True) for image in images]) + return dict(images=[build(image, True) for image in images]) def show(self, req, image_id): """ @@ -98,7 +87,7 @@ class Controller(wsgi.Controller): """ context = req.environ['nova.context'] image = self.__image.show(context, image_id) - return self.get_builder(req).build(req, image, True) + return self.get_builder().build(req, image, True) def delete(self, req, image_id): """ @@ -132,18 +121,30 @@ class Controller(wsgi.Controller): raise exc.HTTPBadRequest() image = self.__compute.snapshot(context, server_id, image_name) - return self.get_builder(req).build(req, image, True) + return self.get_builder(req).build(image, True) class ControllerV10(Controller): """ Version 1.0 specific controller logic. """ - pass + + def get_builder(self, request): + """ + Property to get the ViewBuilder class we need to use. + """ + base_url = request.application_url + return images_view.ViewBuilderV10(base_url) class ControllerV11(Controller): """ Version 1.1 specific controller logic. """ - pass + + def get_builder(self, request): + """ + Property to get the ViewBuilder class we need to use. + """ + base_url = request.application_url + return images_view.ViewBuilderV11(base_url) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 5f6fbd96c..73843f63e 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -516,6 +516,7 @@ class Controller(wsgi.Controller): return kernel_id, ramdisk_id + class ControllerV10(Controller): def _image_id_from_req_data(self, data): return data['server']['imageId'] diff --git a/nova/api/openstack/views/images.py b/nova/api/openstack/views/images.py index 313ba2eba..7daa6fe26 100644 --- a/nova/api/openstack/views/images.py +++ b/nova/api/openstack/views/images.py @@ -66,8 +66,8 @@ class ViewBuilderV11(ViewBuilder): """ Return a standardized image structure for display by the API. """ - image = ViewBuilder.build(self, request, image_obj, detail) - href = self.generate_url(image_obj["id"]) + image = ViewBuilder.build(self, image_obj, detail) + href = self.generate_href(image_obj["id"]) image["links"] = [{ "rel": "self", -- cgit From 00787af795023b6f2104b33b206356442072996e Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 22 Mar 2011 13:25:53 -0700 Subject: add in eventlet version of vnc proxy --- bin/nova-vnc-proxy | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 bin/nova-vnc-proxy diff --git a/bin/nova-vnc-proxy b/bin/nova-vnc-proxy new file mode 100644 index 000000000..5f913a82c --- /dev/null +++ b/bin/nova-vnc-proxy @@ -0,0 +1,203 @@ +#!/usr/bin/env python +# pylint: disable-msg=C0103 +# 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. + +"""VNC Console Proxy Server""" + +from base64 import b64encode, b64decode +import eventlet +from eventlet import wsgi +from eventlet import websocket +import os +import random +import sys +import time +from webob import Request + +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) + +from nova import flags +from nova import log as logging +from nova import rpc +from nova import utils + +FLAGS = flags.FLAGS +flags.DEFINE_string('vnc_novnc_dir', '/code/noVNC/vnclet/noVNC', + 'Full path to noVNC directory') +flags.DEFINE_boolean('vnc_debug', True, + 'Enable debugging features, like token bypassing') +flags.DEFINE_integer('vnc_proxy_port', 7000, + 'Port that the VNC proxy should bind to') +flags.DEFINE_string('vnc_proxy_address', '0.0.0.0', + 'Address that the VNC proxy should bind to') + + +class WebsocketVNCProxy(object): + """Class to proxy from websocket to vnc server""" + + def sock2ws(self, source, dest): + try: + while True: + d = source.recv(32384) + if d == '': + break + d = b64encode(d) + dest.send(d) + except: + source.close() + dest.close() + + def ws2sock(self, source, dest): + try: + while True: + d = source.wait() + if d is None: + break + d = b64decode(d) + dest.sendall(d) + except: + source.close() + dest.close() + + def proxy_connection(self, environ, start_response): + @websocket.WebSocketWSGI + def _handle(client): + server = eventlet.connect((client.environ['vnc_host'], + client.environ['vnc_port'])) + t1 = eventlet.spawn(self.ws2sock, client, server) + t2 = eventlet.spawn(self.sock2ws, server, client) + t1.wait() + t2.wait() + _handle(environ, start_response) + + def serve(self, environ, start_response): + req = Request(environ) + if req.path == '/data': + return self.proxy_connection(environ, start_response) + else: + if req.path == '/': + fname = '/vnc_auto.html' + else: + fname = req.path + + fname = FLAGS.vnc_novnc_dir + fname + + base, ext = os.path.splitext(fname) + if ext == '.js': + mimetype = 'application/javascript' + elif ext == '.css': + mimetype = 'text/css' + elif ext in ['.svg', '.jpg', '.png', '.gif']: + mimetype = 'image' + else: + mimetype = 'text/html' + + start_response('200 OK', [('content-type', mimetype)]) + return [open(os.path.join(fname)).read()] + + +class DebugAuthMiddleware(object): + """ Debug middleware for testing purposes. Skips security check + and allows host and port of vnc endpoint to be specified in + the url. + """ + + def __init__(self, app): + self.app = app + + def __call__(self, environ, start_response): + req = Request(environ) + environ['vnc_host'] = req.params.get('host') + environ['vnc_port'] = int(req.params.get('port')) + resp = req.get_response(self.app) + return resp(environ, start_response) + + +class NovaAuthMiddleware(object): + """Implementation of Middleware to Handle Nova Auth""" + + def __init__(self, app): + self.app = app + self.register_listeners() + + def __call__(self, environ, start_response): + req = Request(environ) + + if req.path == '/data': + token = req.params.get('token') + if not token in self.tokens: + start_response('403 Forbidden', + [('content-type', 'text/html')]) + return 'Not Authorized' + + environ['vnc_host'] = self.tokens[token]['args']['host'] + environ['vnc_port'] = int(self.tokens[token]['args']['port']) + + resp = req.get_response(self.app) + return resp(environ, start_response) + + def register_listeners(self): + middleware = self + middleware.tokens = {} + + class Callback: + def __call__(self, data, message): + if data['method'] == 'authorize_vnc_console': + middleware.tokens[data['args']['token']] = \ + {'args': data['args'], 'last_activity_at': time.time()} + + def delete_expired_tokens(): + now = time.time() + to_delete = [] + for k, v in middleware.tokens.items(): + if now - v['last_activity_at'] > 600: + to_delete.append(k) + + for k in to_delete: + del middleware.tokens[k] + + conn = rpc.Connection.instance(new=True) + consumer = rpc.TopicConsumer( + connection=conn, + topic=FLAGS.vnc_console_proxy_topic) + consumer.register_callback(Callback()) + + utils.LoopingCall(consumer.fetch, auto_ack=True, + enable_callbacks=True).start(0.1) + utils.LoopingCall(delete_expired_tokens).start(1) + + +if __name__ == "__main__": + utils.default_flagfile() + FLAGS(sys.argv) + logging.setup() + + listener = eventlet.listen((FLAGS.vnc_proxy_address, FLAGS.vnc_proxy_port)) + proxy = WebsocketVNCProxy() + + if FLAGS.vnc_debug: + proxy = DebugAuthMiddleware(proxy.serve) + else: + proxy = NovaAuthMiddleware(proxy.serve) + + wsgi.server(listener, proxy, max_size=1000) -- cgit From 4ba57654ca03d687da3b994c127665c7118ab9a5 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 22 Mar 2011 13:26:23 -0700 Subject: intermediate progress on vnc-nova integration. checking in to show vish. --- nova/flags.py | 4 ++++ nova/virt/libvirt.xml.template | 4 +++- nova/virt/libvirt_conn.py | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/nova/flags.py b/nova/flags.py index 4f2be82b6..0360b1e3a 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -287,6 +287,10 @@ DEFINE_string('vnc_console_proxy_url', 'http://127.0.0.1:6080', 'location of vnc console proxy, \ in the form "http://127.0.0.1:6080"') +DEFINE_string('vnc_host_iface', '0.0.0.0', + 'the compute host interface on which vnc server should listen') +DEFINE_bool('vnc_enabled', True, + 'enable vnc related features') DEFINE_bool('verbose', False, 'show debug output') DEFINE_boolean('fake_rabbit', False, 'use a fake rabbit') DEFINE_bool('fake_network', False, diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index 7b4c23211..037cd0902 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -101,6 +101,8 @@ - +#if $getVar('vnc_host_iface', False) + +#end if diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 4fca84639..51f263ce9 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -734,6 +734,8 @@ class LibvirtConnection(object): 'local': instance_type['local_gb'], 'driver_type': driver_type} + if FLAGS.vnc_enabled: + xml_info['vnc_host_iface'] = FLAGS.vnc_host_iface if ra_server: xml_info['ra_server'] = ra_server + "/128" if not rescue: -- cgit From 8048fb9902d80c6a14786f89e672ebff8407d0dd Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 22 Mar 2011 13:28:19 -0700 Subject: make executable --- bin/nova-vnc-proxy | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 bin/nova-vnc-proxy diff --git a/bin/nova-vnc-proxy b/bin/nova-vnc-proxy old mode 100644 new mode 100755 -- cgit From 92f076c981343e09c240533acf49a6fdd0384555 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 22 Mar 2011 16:39:04 -0700 Subject: Set XML namespace when returning XML --- nova/wsgi.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nova/wsgi.py b/nova/wsgi.py index ba0819466..f0a60582d 100644 --- a/nova/wsgi.py +++ b/nova/wsgi.py @@ -478,6 +478,9 @@ class Serializer(object): root_key = data.keys()[0] doc = minidom.Document() node = self._to_xml_node(doc, metadata, root_key, data[root_key]) + node.setAttribute('xmlns', + 'http://docs.rackspacecloud.com/servers/api/v1.0') + return node.toprettyxml(indent=' ') def _to_xml_node(self, doc, metadata, nodename, data): -- cgit From 5c31b423ba5b5347aac62559c4e5c0a02f264213 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 22 Mar 2011 16:59:03 -0700 Subject: Support setting the xmlns intelligently --- nova/wsgi.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/nova/wsgi.py b/nova/wsgi.py index f0a60582d..5d286bb3b 100644 --- a/nova/wsgi.py +++ b/nova/wsgi.py @@ -355,7 +355,8 @@ class Controller(object): if type(result) is dict: content_type = req.best_match_content_type() - body = self._serialize(result, content_type) + default_xmlns = self.get_default_xmlns(req) + body = self._serialize(result, content_type, default_xmlns) response = webob.Response() response.headers["Content-Type"] = content_type @@ -365,14 +366,15 @@ class Controller(object): else: return result - def _serialize(self, data, content_type): + def _serialize(self, data, content_type, default_xmlns): """ Serialize the given dict to the provided content_type. Uses self._serialization_metadata if it exists, which is a dict mapping MIME types to information needed to serialize to that type. """ _metadata = getattr(type(self), "_serialization_metadata", {}) - serializer = Serializer(_metadata) + + serializer = Serializer(_metadata, default_xmlns) try: return serializer.serialize(data, content_type) except exception.InvalidContentType: @@ -388,19 +390,23 @@ class Controller(object): serializer = Serializer(_metadata) return serializer.deserialize(data, content_type) + def get_default_xmlns(self, req): + return 'http://docs.rackspacecloud.com/servers/api/v1.0' + class Serializer(object): """ Serializes and deserializes dictionaries to certain MIME types. """ - def __init__(self, metadata=None): + def __init__(self, metadata=None, default_xmlns=None): """ Create a serializer based on the given WSGI environment. 'metadata' is an optional dict mapping MIME types to information needed to serialize a dictionary to that type. """ self.metadata = metadata or {} + self.default_xmlns = default_xmlns def _get_serialize_handler(self, content_type): handlers = { @@ -478,14 +484,23 @@ class Serializer(object): root_key = data.keys()[0] doc = minidom.Document() node = self._to_xml_node(doc, metadata, root_key, data[root_key]) - node.setAttribute('xmlns', - 'http://docs.rackspacecloud.com/servers/api/v1.0') + + xmlns = node.getAttribute('xmlns') + if not xmlns and self.default_xmlns: + node.setAttribute('xmlns', self.default_xmlns) return node.toprettyxml(indent=' ') def _to_xml_node(self, doc, metadata, nodename, data): """Recursive method to convert data members to XML nodes.""" result = doc.createElement(nodename) + + # Set the xml namespace if one is specified + # TODO(justinsb): We could also use prefixes on the keys + xmlns = metadata.get('xmlns', None) + if xmlns: + result.setAttribute('xmlns', xmlns) + if type(data) is list: singular = metadata.get('plurals', {}).get(nodename, None) if singular is None: -- cgit From 45d28dfb035b4e219845d44e00073d70211e8175 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 22 Mar 2011 21:14:26 -0700 Subject: Fixed up unit tests and direct api that was also calling _serialize (naughty!) --- nova/api/direct.py | 4 +++- nova/tests/api/openstack/test_limits.py | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/nova/api/direct.py b/nova/api/direct.py index dfca250e0..153871e9f 100644 --- a/nova/api/direct.py +++ b/nova/api/direct.py @@ -206,7 +206,9 @@ class ServiceWrapper(wsgi.Controller): params = dict([(str(k), v) for (k, v) in params.iteritems()]) result = method(context, **params) if type(result) is dict or type(result) is list: - return self._serialize(result, req.best_match_content_type()) + content_type = req.best_match_content_type() + default_xmlns = self.get_default_xmlns(req) + return self._serialize(result, content_type, default_xmlns) else: return result diff --git a/nova/tests/api/openstack/test_limits.py b/nova/tests/api/openstack/test_limits.py index 05cfacc60..df367005d 100644 --- a/nova/tests/api/openstack/test_limits.py +++ b/nova/tests/api/openstack/test_limits.py @@ -136,10 +136,17 @@ class LimitsControllerTest(BaseLimitTestSuite): request = self._get_index_request("application/xml") response = request.get_response(self.controller) - expected = "" - body = response.body.replace("\n", "").replace(" ", "") + expected = parseString(""" + + + + + """.replace(" ", "")) - self.assertEqual(expected, body) + body = parseString(response.body.replace(" ", "")) + + self.assertEqual(expected.toxml(), body.toxml()) def test_index_xml(self): """Test getting limit details in XML.""" @@ -148,7 +155,8 @@ class LimitsControllerTest(BaseLimitTestSuite): response = request.get_response(self.controller) expected = parseString(""" - + -- cgit From 9686b3a296c53486a64a949ae2f7430e25df2dcb Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 22 Mar 2011 21:18:31 -0700 Subject: Added note agreeing with Brian Lamar that the namespace doesn't belong in wsgi --- nova/wsgi.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nova/wsgi.py b/nova/wsgi.py index 5d286bb3b..1bcc08f7f 100644 --- a/nova/wsgi.py +++ b/nova/wsgi.py @@ -391,6 +391,10 @@ class Controller(object): return serializer.deserialize(data, content_type) def get_default_xmlns(self, req): + # NOTE(justinsb): This doesn't really belong here.. + # We'll probably end up moving this into a new OpenstackApiController + # class or something like that, once we know what's going to happen + # with v1.1 return 'http://docs.rackspacecloud.com/servers/api/v1.0' -- cgit From 9c75878e5f6f1b90695e725d7bc8e6e9002cabbb Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 23 Mar 2011 01:57:38 -0700 Subject: separating out components of vnc console --- bin/nova-vnc-proxy | 177 ++++++++------------------------------------------- nova/vnc/__init__.py | 0 nova/vnc/auth.py | 83 ++++++++++++++++++++++++ nova/vnc/proxy.py | 111 ++++++++++++++++++++++++++++++++ 4 files changed, 220 insertions(+), 151 deletions(-) create mode 100644 nova/vnc/__init__.py create mode 100644 nova/vnc/auth.py create mode 100644 nova/vnc/proxy.py diff --git a/bin/nova-vnc-proxy b/bin/nova-vnc-proxy index 5f913a82c..52e966090 100755 --- a/bin/nova-vnc-proxy +++ b/bin/nova-vnc-proxy @@ -20,15 +20,10 @@ """VNC Console Proxy Server""" -from base64 import b64encode, b64decode import eventlet -from eventlet import wsgi -from eventlet import websocket +import gettext import os -import random import sys -import time -from webob import Request possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), os.pardir, @@ -36,168 +31,48 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), 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 rpc from nova import utils +from nova import wsgi +from nova.vnc import auth +from nova.vnc import proxy FLAGS = flags.FLAGS -flags.DEFINE_string('vnc_novnc_dir', '/code/noVNC/vnclet/noVNC', +flags.DEFINE_string('vnc_proxy_wwwroot', '/code/noVNC/vnclet/noVNC', 'Full path to noVNC directory') -flags.DEFINE_boolean('vnc_debug', True, +flags.DEFINE_boolean('vnc_debug', False, 'Enable debugging features, like token bypassing') flags.DEFINE_integer('vnc_proxy_port', 7000, 'Port that the VNC proxy should bind to') -flags.DEFINE_string('vnc_proxy_address', '0.0.0.0', +flags.DEFINE_string('vnc_proxy_host', '0.0.0.0', 'Address that the VNC proxy should bind to') - - -class WebsocketVNCProxy(object): - """Class to proxy from websocket to vnc server""" - - def sock2ws(self, source, dest): - try: - while True: - d = source.recv(32384) - if d == '': - break - d = b64encode(d) - dest.send(d) - except: - source.close() - dest.close() - - def ws2sock(self, source, dest): - try: - while True: - d = source.wait() - if d is None: - break - d = b64decode(d) - dest.sendall(d) - except: - source.close() - dest.close() - - def proxy_connection(self, environ, start_response): - @websocket.WebSocketWSGI - def _handle(client): - server = eventlet.connect((client.environ['vnc_host'], - client.environ['vnc_port'])) - t1 = eventlet.spawn(self.ws2sock, client, server) - t2 = eventlet.spawn(self.sock2ws, server, client) - t1.wait() - t2.wait() - _handle(environ, start_response) - - def serve(self, environ, start_response): - req = Request(environ) - if req.path == '/data': - return self.proxy_connection(environ, start_response) - else: - if req.path == '/': - fname = '/vnc_auto.html' - else: - fname = req.path - - fname = FLAGS.vnc_novnc_dir + fname - - base, ext = os.path.splitext(fname) - if ext == '.js': - mimetype = 'application/javascript' - elif ext == '.css': - mimetype = 'text/css' - elif ext in ['.svg', '.jpg', '.png', '.gif']: - mimetype = 'image' - else: - mimetype = 'text/html' - - start_response('200 OK', [('content-type', mimetype)]) - return [open(os.path.join(fname)).read()] - - -class DebugAuthMiddleware(object): - """ Debug middleware for testing purposes. Skips security check - and allows host and port of vnc endpoint to be specified in - the url. - """ - - def __init__(self, app): - self.app = app - - def __call__(self, environ, start_response): - req = Request(environ) - environ['vnc_host'] = req.params.get('host') - environ['vnc_port'] = int(req.params.get('port')) - resp = req.get_response(self.app) - return resp(environ, start_response) - - -class NovaAuthMiddleware(object): - """Implementation of Middleware to Handle Nova Auth""" - - def __init__(self, app): - self.app = app - self.register_listeners() - - def __call__(self, environ, start_response): - req = Request(environ) - - if req.path == '/data': - token = req.params.get('token') - if not token in self.tokens: - start_response('403 Forbidden', - [('content-type', 'text/html')]) - return 'Not Authorized' - - environ['vnc_host'] = self.tokens[token]['args']['host'] - environ['vnc_port'] = int(self.tokens[token]['args']['port']) - - resp = req.get_response(self.app) - return resp(environ, start_response) - - def register_listeners(self): - middleware = self - middleware.tokens = {} - - class Callback: - def __call__(self, data, message): - if data['method'] == 'authorize_vnc_console': - middleware.tokens[data['args']['token']] = \ - {'args': data['args'], 'last_activity_at': time.time()} - - def delete_expired_tokens(): - now = time.time() - to_delete = [] - for k, v in middleware.tokens.items(): - if now - v['last_activity_at'] > 600: - to_delete.append(k) - - for k in to_delete: - del middleware.tokens[k] - - conn = rpc.Connection.instance(new=True) - consumer = rpc.TopicConsumer( - connection=conn, - topic=FLAGS.vnc_console_proxy_topic) - consumer.register_callback(Callback()) - - utils.LoopingCall(consumer.fetch, auto_ack=True, - enable_callbacks=True).start(0.1) - utils.LoopingCall(delete_expired_tokens).start(1) - +flags.DEFINE_flag(flags.HelpFlag()) +flags.DEFINE_flag(flags.HelpshortFlag()) +flags.DEFINE_flag(flags.HelpXMLFlag()) if __name__ == "__main__": utils.default_flagfile() FLAGS(sys.argv) logging.setup() - listener = eventlet.listen((FLAGS.vnc_proxy_address, FLAGS.vnc_proxy_port)) - proxy = WebsocketVNCProxy() + app = proxy.WebsocketVNCProxy(FLAGS.vnc_proxy_wwwroot) if FLAGS.vnc_debug: - proxy = DebugAuthMiddleware(proxy.serve) + app = proxy.DebugMiddleware(app.serve) else: - proxy = NovaAuthMiddleware(proxy.serve) + app = auth.NovaAuthMiddleware(app.serve) + + + listener = eventlet.listen((FLAGS.vnc_proxy_host, FLAGS.vnc_proxy_port)) + + + from eventlet import wsgi + wsgi.server(listener, app, max_size=1000) + - wsgi.server(listener, proxy, max_size=1000) +# server = wsgi.Server() +# server.start(app, FLAGS.vnc_proxy_port, host=FLAGS.vnc_proxy_host) +# server.wait() diff --git a/nova/vnc/__init__.py b/nova/vnc/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/nova/vnc/auth.py b/nova/vnc/auth.py new file mode 100644 index 000000000..2596bdd24 --- /dev/null +++ b/nova/vnc/auth.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# pylint: disable-msg=C0103 +# 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. + +"""Auth Components for VNC Console""" + +import time +from webob import Request +from nova import flags +from nova import log as logging +from nova import rpc +from nova import utils +from nova import wsgi + + +class NovaAuthMiddleware(object): + """Implementation of Middleware to Handle Nova Auth""" + + def __init__(self, app): + self.app = app + self.register_listeners() + + def __call__(self, environ, start_response): + req = Request(environ) + + if req.path == '/data': + token = req.params.get('token') + if not token in self.tokens: + start_response('403 Forbidden', + [('content-type', 'text/html')]) + return 'Not Authorized' + + environ['vnc_host'] = self.tokens[token]['args']['host'] + environ['vnc_port'] = int(self.tokens[token]['args']['port']) + + resp = req.get_response(self.app) + return resp(environ, start_response) + + def register_listeners(self): + middleware = self + middleware.tokens = {} + + class Callback: + def __call__(self, data, message): + if data['method'] == 'authorize_vnc_console': + middleware.tokens[data['args']['token']] = \ + {'args': data['args'], 'last_activity_at': time.time()} + + def delete_expired_tokens(): + now = time.time() + to_delete = [] + for k, v in middleware.tokens.items(): + if now - v['last_activity_at'] > 600: + to_delete.append(k) + + for k in to_delete: + del middleware.tokens[k] + + conn = rpc.Connection.instance(new=True) + consumer = rpc.TopicConsumer( + connection=conn, + topic=FLAGS.vnc_console_proxy_topic) + consumer.register_callback(Callback()) + + utils.LoopingCall(consumer.fetch, auto_ack=True, + enable_callbacks=True).start(0.1) + utils.LoopingCall(delete_expired_tokens).start(1) diff --git a/nova/vnc/proxy.py b/nova/vnc/proxy.py new file mode 100644 index 000000000..3f218e744 --- /dev/null +++ b/nova/vnc/proxy.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python +# pylint: disable-msg=C0103 +# 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. + +"""Eventlet WSGI Services to proxy VNC. No nova deps.""" + +from base64 import b64encode, b64decode +import eventlet +from eventlet import wsgi +from eventlet import websocket +import os +from webob import Request +import webob + + +class WebsocketVNCProxy(object): + """Class to proxy from websocket to vnc server""" + + def __init__(self, wwwroot): + self.wwwroot = wwwroot + + def sock2ws(self, source, dest): + try: + while True: + d = source.recv(32384) + if d == '': + break + d = b64encode(d) + dest.send(d) + except: + source.close() + dest.close() + + def ws2sock(self, source, dest): + try: + while True: + d = source.wait() + if d is None: + break + d = b64decode(d) + dest.sendall(d) + except: + source.close() + dest.close() + + def proxy_connection(self, environ, start_response): + @websocket.WebSocketWSGI + def _handle(client): + server = eventlet.connect((client.environ['vnc_host'], + client.environ['vnc_port'])) + t1 = eventlet.spawn(self.ws2sock, client, server) + t2 = eventlet.spawn(self.sock2ws, server, client) + t1.wait() + t2.wait() + _handle(environ, start_response) + + def serve(self, environ, start_response): + req = Request(environ) + if req.path == '/data': + return self.proxy_connection(environ, start_response) + else: + if req.path == '/': + fname = '/vnc_auto.html' + else: + fname = req.path + + fname = self.wwwroot + fname + + base, ext = os.path.splitext(fname) + if ext == '.js': + mimetype = 'application/javascript' + elif ext == '.css': + mimetype = 'text/css' + elif ext in ['.svg', '.jpg', '.png', '.gif']: + mimetype = 'image' + else: + mimetype = 'text/html' + + start_response('200 OK', [('content-type', mimetype)]) + return open(os.path.join(fname)).read() + + +class DebugMiddleware(object): + """Debug middleware. Skip auth, get vnc port and host from query string""" + + def __init__(self, app): + self.app = app + + def __call__(self, environ, start_response): + req = Request(environ) + if req.path == '/data': + environ['vnc_host'] = req.params.get('host') + environ['vnc_port'] = int(req.params.get('port')) + resp = req.get_response(self.app) + return resp(environ, start_response) -- cgit From e2f085eae874012784e53416f6e6213dcfde4859 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 23 Mar 2011 02:06:16 -0700 Subject: use the nova Server object --- bin/nova-vnc-proxy | 18 +++++------------- nova/vnc/proxy.py | 2 +- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/bin/nova-vnc-proxy b/bin/nova-vnc-proxy index 52e966090..5891652c4 100755 --- a/bin/nova-vnc-proxy +++ b/bin/nova-vnc-proxy @@ -61,18 +61,10 @@ if __name__ == "__main__": app = proxy.WebsocketVNCProxy(FLAGS.vnc_proxy_wwwroot) if FLAGS.vnc_debug: - app = proxy.DebugMiddleware(app.serve) + app = proxy.DebugMiddleware(app) else: - app = auth.NovaAuthMiddleware(app.serve) + app = auth.NovaAuthMiddleware(app) - - listener = eventlet.listen((FLAGS.vnc_proxy_host, FLAGS.vnc_proxy_port)) - - - from eventlet import wsgi - wsgi.server(listener, app, max_size=1000) - - -# server = wsgi.Server() -# server.start(app, FLAGS.vnc_proxy_port, host=FLAGS.vnc_proxy_host) -# server.wait() + server = wsgi.Server() + server.start(app, FLAGS.vnc_proxy_port, host=FLAGS.vnc_proxy_host) + server.wait() diff --git a/nova/vnc/proxy.py b/nova/vnc/proxy.py index 3f218e744..5dc83fcb1 100644 --- a/nova/vnc/proxy.py +++ b/nova/vnc/proxy.py @@ -70,7 +70,7 @@ class WebsocketVNCProxy(object): t2.wait() _handle(environ, start_response) - def serve(self, environ, start_response): + def __call__(self, environ, start_response): req = Request(environ) if req.path == '/data': return self.proxy_connection(environ, start_response) -- cgit From 5cdf8f63fb2dbccea0152d17f00bf80352f8fa1a Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 23 Mar 2011 02:33:11 -0700 Subject: more progress --- bin/nova-vnc-proxy | 14 +++++++++++--- nova/vnc/auth.py | 35 +++++++++++++++++++++++++++-------- nova/vnc/proxy.py | 11 +++++------ 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/bin/nova-vnc-proxy b/bin/nova-vnc-proxy index 5891652c4..838c871d0 100755 --- a/bin/nova-vnc-proxy +++ b/bin/nova-vnc-proxy @@ -37,9 +37,12 @@ from nova import flags from nova import log as logging from nova import utils from nova import wsgi +from nova import version from nova.vnc import auth from nova.vnc import proxy +LOG = logging.getLogger('nova.vnc-proxy') + FLAGS = flags.FLAGS flags.DEFINE_string('vnc_proxy_wwwroot', '/code/noVNC/vnclet/noVNC', 'Full path to noVNC directory') @@ -58,13 +61,18 @@ if __name__ == "__main__": FLAGS(sys.argv) logging.setup() + LOG.audit(_("Starting nova-vnc-proxy node (version %s)"), + version.version_string_with_vcs()) + app = proxy.WebsocketVNCProxy(FLAGS.vnc_proxy_wwwroot) + with_logging = auth.LoggingMiddleware(app) + if FLAGS.vnc_debug: - app = proxy.DebugMiddleware(app) + with_auth = proxy.DebugMiddleware(with_logging) else: - app = auth.NovaAuthMiddleware(app) + with_auth = auth.NovaAuthMiddleware(with_logging) server = wsgi.Server() - server.start(app, FLAGS.vnc_proxy_port, host=FLAGS.vnc_proxy_host) + server.start(with_auth, FLAGS.vnc_proxy_port, host=FLAGS.vnc_proxy_host) server.wait() diff --git a/nova/vnc/auth.py b/nova/vnc/auth.py index 2596bdd24..9b30b08b8 100644 --- a/nova/vnc/auth.py +++ b/nova/vnc/auth.py @@ -27,6 +27,10 @@ from nova import log as logging from nova import rpc from nova import utils from nova import wsgi +import webob + +LOG = logging.getLogger('nova.vnc-proxy') +FLAGS = flags.FLAGS class NovaAuthMiddleware(object): @@ -36,9 +40,8 @@ class NovaAuthMiddleware(object): self.app = app self.register_listeners() - def __call__(self, environ, start_response): - req = Request(environ) - + @webob.dec.wsgify + def __call__(self, req): if req.path == '/data': token = req.params.get('token') if not token in self.tokens: @@ -46,11 +49,10 @@ class NovaAuthMiddleware(object): [('content-type', 'text/html')]) return 'Not Authorized' - environ['vnc_host'] = self.tokens[token]['args']['host'] - environ['vnc_port'] = int(self.tokens[token]['args']['port']) + req.environ['vnc_host'] = self.tokens[token]['args']['host'] + req.environ['vnc_port'] = int(self.tokens[token]['args']['port']) - resp = req.get_response(self.app) - return resp(environ, start_response) + return req.get_response(self.app) def register_listeners(self): middleware = self @@ -59,7 +61,9 @@ class NovaAuthMiddleware(object): class Callback: def __call__(self, data, message): if data['method'] == 'authorize_vnc_console': - middleware.tokens[data['args']['token']] = \ + token = data['args']['token'] + LOG.info(_("Received Token: %s)"), token) + middleware.tokens[token] = \ {'args': data['args'], 'last_activity_at': time.time()} def delete_expired_tokens(): @@ -81,3 +85,18 @@ class NovaAuthMiddleware(object): utils.LoopingCall(consumer.fetch, auto_ack=True, enable_callbacks=True).start(0.1) utils.LoopingCall(delete_expired_tokens).start(1) + + +class LoggingMiddleware(object): + def __init__(self, app): + self.app = app + + @webob.dec.wsgify + def __call__(self, req): + + if req.path == '/data': + LOG.info(_("Received Websocket Request: %s)"), req.url) + else: + LOG.info(_("Received Request: %s)"), req.url) + + return req.get_response(self.app) diff --git a/nova/vnc/proxy.py b/nova/vnc/proxy.py index 5dc83fcb1..354c2405f 100644 --- a/nova/vnc/proxy.py +++ b/nova/vnc/proxy.py @@ -102,10 +102,9 @@ class DebugMiddleware(object): def __init__(self, app): self.app = app - def __call__(self, environ, start_response): - req = Request(environ) + @webob.dec.wsgify + def __call__(self, req): if req.path == '/data': - environ['vnc_host'] = req.params.get('host') - environ['vnc_port'] = int(req.params.get('port')) - resp = req.get_response(self.app) - return resp(environ, start_response) + req.environ['vnc_host'] = req.params.get('host') + req.environ['vnc_port'] = int(req.params.get('port')) + return req.get_response(self.app) -- cgit From f0bb48fc2f2e7d9326c51b4b57e73e0258930909 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Wed, 23 Mar 2011 09:34:34 +0000 Subject: removed excess debug line --- nova/virt/xenapi/network_utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nova/virt/xenapi/network_utils.py b/nova/virt/xenapi/network_utils.py index 52ad0e1a5..546f6bea9 100644 --- a/nova/virt/xenapi/network_utils.py +++ b/nova/virt/xenapi/network_utils.py @@ -28,7 +28,6 @@ class NetworkHelper(HelperBase): """ The class that wraps the helper methods together. """ - @classmethod def find_network_with_name_label(cls, session, name_label): networks = session.call_xenapi('network.get_by_name_label', name_label) -- cgit From ff9e29e3ef56ec8b28f28d328ca010ce25f0c7b0 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Wed, 23 Mar 2011 09:47:22 -0400 Subject: Removed some un-needed code, and started adding tests for show(), which I forgot\! --- nova/api/openstack/images.py | 37 +++++++++++--------- nova/tests/api/openstack/test_images.py | 61 +++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 17 deletions(-) diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index 4cd989054..d8606e3c2 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -13,9 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. -from webob import exc +import webob.exc from nova import compute +from nova import exception from nova import flags from nova import utils from nova import wsgi @@ -39,11 +40,6 @@ class Controller(wsgi.Controller): }, } - _builder_dispatch = { - "1.0": images_view.ViewBuilderV10, - "1.1": images_view.ViewBuilderV11, - } - def __init__(self, image_service=None, compute_service=None): """ Initialize new `ImageController`. @@ -60,7 +56,7 @@ class Controller(wsgi.Controller): """ Return an index listing of images available to the request. - @param req: `webob.Request` object + @param req: `wsgi.Request` object """ context = req.environ['nova.context'] images = self.__image.index(context) @@ -71,31 +67,38 @@ class Controller(wsgi.Controller): """ Return a detailed index listing of images available to the request. - @param req: `webob.Request` object. + @param req: `wsgi.Request` object. """ context = req.environ['nova.context'] images = self.__image.detail(context) build = self.get_builder(req).build return dict(images=[build(image, True) for image in images]) - def show(self, req, image_id): + def show(self, req, id): """ Return detailed information about a specific image. - @param req: `webob.Request` object - @param image_id: Image identifier (integer) + @param req: `wsgi.Request` object + @param id: Image identifier (integer) """ + image_id = id context = req.environ['nova.context'] - image = self.__image.show(context, image_id) - return self.get_builder().build(req, image, True) - def delete(self, req, image_id): + try: + image = self.__image.show(context, image_id) + except exception.NotFound: + raise webob.exc.HTTPNotFound + + return self.get_builder(req).build(image, True) + + def delete(self, req, id): """ Delete an image, if allowed. - @param req: `webob.Request` object - @param image_id: Image identifier (integer) + @param req: `wsgi.Request` object + @param id: Image identifier (integer) """ + image_id = id context = req.environ['nova.context'] self.__image.delete(context, image_id) return exc.HTTPNoContent() @@ -104,7 +107,7 @@ class Controller(wsgi.Controller): """ Snapshot a server instance and save the image. - @param req: `webob.Request` object + @param req: `wsgi.Request` object """ context = req.environ['nova.context'] body = req.body diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index c5a866bc7..8828b0e34 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -235,6 +235,67 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): self.assertEqual(len(response_list), len(self.IMAGE_FIXTURES)) + def test_get_image(self): + request = webob.Request.blank('/v1.0/images/23g2ogk23k4hhkk4k42l') + response = request.get_response(fakes.wsgi_app()) + + actual_image = json.loads(response.body) + + expected = self.IMAGE_FIXTURES[0] + expected_image = { + "id": expected["id"], + "name": expected["name"], + "updated": expected["updated_at"], + "created": expected["created_at"], + "status": expected["status"], + } + + self.assertEqual(expected_image, actual_image) + + def test_get_image_v1_1(self): + request = webob.Request.blank('/v1.1/images/23g2ogk23k4hhkk4k42l') + response = request.get_response(fakes.wsgi_app()) + + actual_image = json.loads(response.body) + + expected = self.IMAGE_FIXTURES[0] + href = "http://localhost/v1.1/images/%s" % expected["id"] + + expected_image = { + "id": expected["id"], + "name": expected["name"], + "updated": expected["updated_at"], + "created": expected["created_at"], + "status": expected["status"], + "links": [{ + "rel": "self", + "href": href, + }, + { + "rel": "bookmark", + "type": "application/json", + "href": href, + }, + { + "rel": "bookmark", + "type": "application/xml", + "href": href, + }], + } + + self.assertEqual(expected_image, actual_image) + + def test_get_image_404(self): + request = webob.Request.blank('/v1.0/images/NonExistantImage') + response = request.get_response(fakes.wsgi_app()) + self.assertEqual(404, response.status_int) + self.assertEqual("", response.body) + + def test_get_image_v1_1_404(self): + request = webob.Request.blank('/v1.1/images/NonExistantImage') + response = request.get_response(fakes.wsgi_app()) + self.assertEqual(404, response.status_int) + def test_get_image_index_v1_1(self): request = webob.Request.blank('/v1.1/images') response = request.get_response(fakes.wsgi_app()) -- cgit From e9800364853078115cfb205bae263c3a55410b02 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Wed, 23 Mar 2011 11:04:20 -0400 Subject: Fixed tests. --- nova/tests/api/openstack/fakes.py | 4 ++-- nova/tests/api/openstack/test_images.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/nova/tests/api/openstack/fakes.py b/nova/tests/api/openstack/fakes.py index 16c7bc163..911eeaaad 100644 --- a/nova/tests/api/openstack/fakes.py +++ b/nova/tests/api/openstack/fakes.py @@ -79,9 +79,9 @@ def wsgi_app(inner_app10=None, inner_app11=None): inner_app11 = openstack.APIRouterV11() mapper = urlmap.URLMap() api10 = openstack.FaultWrapper(auth.AuthMiddleware( - ratelimiting.RateLimitingMiddleware(inner_app10))) + limits.RateLimitingMiddleware(inner_app10))) api11 = openstack.FaultWrapper(auth.AuthMiddleware( - ratelimiting.RateLimitingMiddleware(inner_app11))) + limits.RateLimitingMiddleware(inner_app11))) mapper['/v1.0'] = api10 mapper['/v1.1'] = api11 mapper['/'] = openstack.FaultWrapper(openstack.Versions()) diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index a6ee23e1d..e93a1ea40 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -301,7 +301,6 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): request = webob.Request.blank('/v1.0/images/NonExistantImage') response = request.get_response(fakes.wsgi_app()) self.assertEqual(404, response.status_int) - self.assertEqual("", response.body) def test_get_image_v1_1_404(self): request = webob.Request.blank('/v1.1/images/NonExistantImage') -- cgit From 572b6d30c809af6e117d96de9a5a2d845c1eeda0 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Wed, 23 Mar 2011 11:52:43 -0400 Subject: Testing of XML and JSON for show(), and conformance to API spec for JSON. --- nova/api/openstack/images.py | 6 +- nova/tests/api/openstack/test_images.py | 159 +++++++++++++++++++++++++++----- 2 files changed, 138 insertions(+), 27 deletions(-) diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index d8606e3c2..38c8a7306 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -21,6 +21,7 @@ from nova import flags from nova import utils from nova import wsgi from nova.api.openstack import common +from nova.api.openstack import faults from nova.api.openstack.views import images as images_view @@ -87,9 +88,10 @@ class Controller(wsgi.Controller): try: image = self.__image.show(context, image_id) except exception.NotFound: - raise webob.exc.HTTPNotFound + ex = webob.exc.HTTPNotFound(explanation="Image not found.") + raise faults.Fault(ex) - return self.get_builder(req).build(image, True) + return dict(image=self.get_builder(req).build(image, True)) def delete(self, req, id): """ diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index e93a1ea40..deb8f1744 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -26,6 +26,8 @@ import os import shutil import tempfile +from xml.dom.minidom import parseString + import stubout import webob @@ -255,11 +257,13 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): expected = self.IMAGE_FIXTURES[0] expected_image = { - "id": expected["id"], - "name": expected["name"], - "updated": expected["updated_at"], - "created": expected["created_at"], - "status": expected["status"], + "image": { + "id": expected["id"], + "name": expected["name"], + "updated": expected["updated_at"], + "created": expected["created_at"], + "status": expected["status"], + }, } self.assertEqual(expected_image, actual_image) @@ -274,39 +278,142 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): href = "http://localhost/v1.1/images/%s" % expected["id"] expected_image = { - "id": expected["id"], - "name": expected["name"], - "updated": expected["updated_at"], - "created": expected["created_at"], - "status": expected["status"], - "links": [{ - "rel": "self", - "href": href, - }, - { - "rel": "bookmark", - "type": "application/json", - "href": href, + "image": { + "id": expected["id"], + "name": expected["name"], + "updated": expected["updated_at"], + "created": expected["created_at"], + "status": expected["status"], + "links": [{ + "rel": "self", + "href": href, + }, + { + "rel": "bookmark", + "type": "application/json", + "href": href, + }, + { + "rel": "bookmark", + "type": "application/xml", + "href": href, + }], }, - { - "rel": "bookmark", - "type": "application/xml", - "href": href, - }], } self.assertEqual(expected_image, actual_image) - def test_get_image_404(self): + def test_get_image_xml(self): + request = webob.Request.blank('/v1.0/images/23g2ogk23k4hhkk4k42l') + request.accept = "application/xml" + response = request.get_response(fakes.wsgi_app()) + + actual_image = parseString(response.body.replace(" ", "")) + + expected = self.IMAGE_FIXTURES[0] + expected_image = parseString(""" + + """ % (expected)) + + self.assertEqual(expected_image.toxml(), actual_image.toxml()) + + def test_get_image_v1_1_xml(self): + request = webob.Request.blank('/v1.1/images/23g2ogk23k4hhkk4k42l') + request.accept = "application/xml" + response = request.get_response(fakes.wsgi_app()) + + actual_image = parseString(response.body.replace(" ", "")) + + expected = self.IMAGE_FIXTURES[0] + expected["href"] = "http://localhost/v1.1/images/23g2ogk23k4hhkk4k42l" + expected_image = parseString(""" + + + + + + + + """.replace(" ", "") % (expected)) + + self.assertEqual(expected_image.toxml(), actual_image.toxml()) + + def test_get_image_404_json(self): + request = webob.Request.blank('/v1.0/images/NonExistantImage') + response = request.get_response(fakes.wsgi_app()) + self.assertEqual(404, response.status_int) + + expected = { + "itemNotFound": { + "message": "Image not found.", + "code": 404, + }, + } + + actual = json.loads(response.body) + + self.assertEqual(expected, actual) + + def test_get_image_404_xml(self): request = webob.Request.blank('/v1.0/images/NonExistantImage') + request.accept = "application/xml" response = request.get_response(fakes.wsgi_app()) self.assertEqual(404, response.status_int) - def test_get_image_v1_1_404(self): + expected = parseString(""" + + + Image not found. + + + """.replace(" ", "")) + + actual = parseString(response.body.replace(" ", "")) + + self.assertEqual(expected.toxml(), actual.toxml()) + + def test_get_image_404_v1_1_json(self): request = webob.Request.blank('/v1.1/images/NonExistantImage') response = request.get_response(fakes.wsgi_app()) self.assertEqual(404, response.status_int) + expected = { + "itemNotFound": { + "message": "Image not found.", + "code": 404, + }, + } + + actual = json.loads(response.body) + + self.assertEqual(expected, actual) + + def test_get_image_404_v1_1_xml(self): + request = webob.Request.blank('/v1.1/images/NonExistantImage') + request.accept = "application/xml" + response = request.get_response(fakes.wsgi_app()) + self.assertEqual(404, response.status_int) + + expected = parseString(""" + + + Image not found. + + + """.replace(" ", "")) + + actual = parseString(response.body.replace(" ", "")) + + self.assertEqual(expected.toxml(), actual.toxml()) + def test_get_image_index_v1_1(self): request = webob.Request.blank('/v1.1/images') response = request.get_response(fakes.wsgi_app()) @@ -338,6 +445,8 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): self.assertEqual(len(response_list), len(self.IMAGE_FIXTURES)) + + def test_get_image_details(self): request = webob.Request.blank('/v1.0/images/detail') response = request.get_response(fakes.wsgi_app()) -- cgit From 48c04eb35fae704913e9ed05868d1334ee5458fa Mon Sep 17 00:00:00 2001 From: Mark Washenberger Date: Wed, 23 Mar 2011 12:17:48 -0400 Subject: add changePassword action to os api v1.1 --- nova/api/openstack/servers.py | 13 +++++++++ nova/tests/api/openstack/test_servers.py | 46 ++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 73843f63e..90f709a47 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -256,6 +256,7 @@ class Controller(wsgi.Controller): resize a server""" actions = { + 'changePassword': self._action_change_password, 'reboot': self._action_reboot, 'resize': self._action_resize, 'confirmResize': self._action_confirm_resize, @@ -269,6 +270,9 @@ class Controller(wsgi.Controller): return actions[key](input_dict, req, id) return faults.Fault(exc.HTTPNotImplemented()) + def _action_change_password(self, input_dict, req, id): + return exc.HTTPNotImplemented() + def _action_confirm_resize(self, input_dict, req, id): try: self.compute_api.confirm_resize(req.environ['nova.context'], id) @@ -555,6 +559,15 @@ class ControllerV11(Controller): def _get_addresses_view_builder(self, req): return nova.api.openstack.views.addresses.ViewBuilderV11(req) + def _action_change_password(self, input_dict, req, id): + context = req.environ['nova.context'] + if not 'changePassword' in input_dict \ + or not 'adminPass' in input_dict['changePassword']: + return exc.HTTPBadRequest() + password = input_dict['changePassword']['adminPass'] + self.compute_api.set_admin_password(context, id, password) + return exc.HTTPAccepted() + class ServerCreateRequestXMLDeserializer(object): """ diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index e21637ea4..dc5fedb8c 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -558,6 +558,52 @@ class ServersTest(test.TestCase): res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 404) + def test_server_change_password(self): + body = {'changePassword': {'adminPass': '1234pass'}} + req = webob.Request.blank('/v1.0/servers/1/action') + req.method = 'POST' + req.content_type = 'application/json' + req.body = json.dumps(body) + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 501) + + def test_server_change_password_v1_1(self): + + class MockSetAdminPassword(object): + + def __init__(self): + self.called = False + self.instance_id = None + self.password = None + + def __call__(self, context, instance_id, password): + self.called = True + self.instance_id = instance_id + self.password = password + + mock_method = MockSetAdminPassword() + self.stubs.Set(nova.compute.api.API, 'set_admin_password', mock_method) + + body = {'changePassword': {'adminPass': '1234pass'}} + req = webob.Request.blank('/v1.1/servers/1/action') + req.method = 'POST' + req.content_type = 'application/json' + req.body = json.dumps(body) + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 202) + self.assertTrue(mock_method.called) + self.assertEqual(mock_method.instance_id, '1') + self.assertEqual(mock_method.password, '1234pass') + + def test_server_change_password_bad_request_v1_1(self): + body = {'changePassword': {'pass': '12345'}} + req = webob.Request.blank('/v1.1/servers/1/action') + req.method = 'POST' + req.content_type = 'application/json' + req.body = json.dumps(body) + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 400) + def test_server_reboot(self): body = dict(server=dict( name='server_test', imageId=2, flavorId=2, metadata={}, -- cgit From e0289dd26821545a6ef2ca91eb2dba7c11c2cc9f Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 23 Mar 2011 15:53:46 -0700 Subject: general cleanup, use whitelist for webserver security --- bin/nova-vnc-proxy | 22 ++++++++++++++++++---- nova/flags.py | 2 +- nova/virt/libvirt.xml.template | 2 +- nova/virt/libvirt_conn.py | 2 +- nova/vnc/auth.py | 34 ++++++++++++++++++++++------------ nova/vnc/proxy.py | 28 +++++++++++++++++++++++++--- 6 files changed, 68 insertions(+), 22 deletions(-) diff --git a/bin/nova-vnc-proxy b/bin/nova-vnc-proxy index 838c871d0..4cd1e9082 100755 --- a/bin/nova-vnc-proxy +++ b/bin/nova-vnc-proxy @@ -44,14 +44,16 @@ from nova.vnc import proxy LOG = logging.getLogger('nova.vnc-proxy') FLAGS = flags.FLAGS -flags.DEFINE_string('vnc_proxy_wwwroot', '/code/noVNC/vnclet/noVNC', +flags.DEFINE_string('vnc_proxy_wwwroot', '/code/noVNC/', 'Full path to noVNC directory') flags.DEFINE_boolean('vnc_debug', False, 'Enable debugging features, like token bypassing') -flags.DEFINE_integer('vnc_proxy_port', 7000, +flags.DEFINE_integer('vnc_proxy_port', 6080, 'Port that the VNC proxy should bind to') -flags.DEFINE_string('vnc_proxy_host', '0.0.0.0', +flags.DEFINE_string('vnc_proxy_iface', '0.0.0.0', 'Address that the VNC proxy should bind to') +flags.DEFINE_integer('vnc_token_ttl', 300, + 'How many seconds before deleting tokens') flags.DEFINE_flag(flags.HelpFlag()) flags.DEFINE_flag(flags.HelpshortFlag()) flags.DEFINE_flag(flags.HelpXMLFlag()) @@ -64,8 +66,20 @@ if __name__ == "__main__": LOG.audit(_("Starting nova-vnc-proxy node (version %s)"), version.version_string_with_vcs()) + if not os.path.exists(FLAGS.vnc_proxy_wwwroot): + LOG.info(_("Missing vnc_proxy_wwwroot (version %s)"), + FLAGS.vnc_proxy_wwwroot) + LOG.info(_("You need a slightly modified version of noVNC " + "to work with the nova-vnc-proxy")) + LOG.info(_("Check out the most recent nova noVNC code here: %s"), + "git://github.com/sleepsonthefloor/noVNC.git") + exit(1) + app = proxy.WebsocketVNCProxy(FLAGS.vnc_proxy_wwwroot) + LOG.audit(_("Allowing access to the following files: %s"), + app.get_whitelist()) + with_logging = auth.LoggingMiddleware(app) if FLAGS.vnc_debug: @@ -74,5 +88,5 @@ if __name__ == "__main__": with_auth = auth.NovaAuthMiddleware(with_logging) server = wsgi.Server() - server.start(with_auth, FLAGS.vnc_proxy_port, host=FLAGS.vnc_proxy_host) + server.start(with_auth, FLAGS.vnc_proxy_port, host=FLAGS.vnc_proxy_iface) server.wait() diff --git a/nova/flags.py b/nova/flags.py index 0360b1e3a..a0ea10795 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -287,7 +287,7 @@ DEFINE_string('vnc_console_proxy_url', 'http://127.0.0.1:6080', 'location of vnc console proxy, \ in the form "http://127.0.0.1:6080"') -DEFINE_string('vnc_host_iface', '0.0.0.0', +DEFINE_string('vnc_compute_host_iface', '0.0.0.0', 'the compute host interface on which vnc server should listen') DEFINE_bool('vnc_enabled', True, 'enable vnc related features') diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index 037cd0902..bcc6b3aed 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -101,7 +101,7 @@ -#if $getVar('vnc_host_iface', False) +#if $getVar('vnc_compute_host_iface', False) #end if diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 51f263ce9..c3529f512 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -735,7 +735,7 @@ class LibvirtConnection(object): 'driver_type': driver_type} if FLAGS.vnc_enabled: - xml_info['vnc_host_iface'] = FLAGS.vnc_host_iface + xml_info['vnc_compute_host_iface'] = FLAGS.vnc_compute_host_iface if ra_server: xml_info['ra_server'] = ra_server + "/128" if not rescue: diff --git a/nova/vnc/auth.py b/nova/vnc/auth.py index 9b30b08b8..676cb2360 100644 --- a/nova/vnc/auth.py +++ b/nova/vnc/auth.py @@ -21,13 +21,16 @@ """Auth Components for VNC Console""" import time +import urlparse +import webob from webob import Request + from nova import flags from nova import log as logging from nova import rpc from nova import utils from nova import wsgi -import webob +from nova import vnc LOG = logging.getLogger('nova.vnc-proxy') FLAGS = flags.FLAGS @@ -42,13 +45,19 @@ class NovaAuthMiddleware(object): @webob.dec.wsgify def __call__(self, req): - if req.path == '/data': - token = req.params.get('token') - if not token in self.tokens: - start_response('403 Forbidden', - [('content-type', 'text/html')]) - return 'Not Authorized' + token = req.params.get('token') + + if not token: + referrer = req.environ.get('HTTP_REFERER') + auth_params = urlparse.parse_qs(urlparse.urlparse(referrer).query) + if 'token' in auth_params: + token = auth_params['token'][0] + + if not token in self.tokens: + LOG.audit(_("Unauthorized Access: (%s)"), req.environ) + return webob.exc.HTTPForbidden(detail='Unauthorized') + if req.path == vnc.proxy.WS_ENDPOINT: req.environ['vnc_host'] = self.tokens[token]['args']['host'] req.environ['vnc_port'] = int(self.tokens[token]['args']['port']) @@ -62,7 +71,7 @@ class NovaAuthMiddleware(object): def __call__(self, data, message): if data['method'] == 'authorize_vnc_console': token = data['args']['token'] - LOG.info(_("Received Token: %s)"), token) + LOG.audit(_("Received Token: %s)"), token) middleware.tokens[token] = \ {'args': data['args'], 'last_activity_at': time.time()} @@ -70,10 +79,11 @@ class NovaAuthMiddleware(object): now = time.time() to_delete = [] for k, v in middleware.tokens.items(): - if now - v['last_activity_at'] > 600: + if now - v['last_activity_at'] > FLAGS.vnc_token_ttl: to_delete.append(k) for k in to_delete: + LOG.audit(_("Deleting Token: %s)"), k) del middleware.tokens[k] conn = rpc.Connection.instance(new=True) @@ -94,9 +104,9 @@ class LoggingMiddleware(object): @webob.dec.wsgify def __call__(self, req): - if req.path == '/data': - LOG.info(_("Received Websocket Request: %s)"), req.url) + if req.path == vnc.proxy.WS_ENDPOINT: + LOG.info(_("Received Websocket Request: %s"), req.url) else: - LOG.info(_("Received Request: %s)"), req.url) + LOG.info(_("Received Request: %s"), req.url) return req.get_response(self.app) diff --git a/nova/vnc/proxy.py b/nova/vnc/proxy.py index 354c2405f..70ebd022a 100644 --- a/nova/vnc/proxy.py +++ b/nova/vnc/proxy.py @@ -28,12 +28,30 @@ import os from webob import Request import webob +WS_ENDPOINT = '/data' + class WebsocketVNCProxy(object): """Class to proxy from websocket to vnc server""" def __init__(self, wwwroot): self.wwwroot = wwwroot + self.whitelist = {} + for root, dirs, files in os.walk(wwwroot): + hidden_dirs = [] + for d in dirs: + if d.startswith('.'): + hidden_dirs.append(d) + for d in hidden_dirs: + dirs.remove(d) + for name in files: + if not str(name).startswith('.'): + filename = os.path.join(root, name) + self.whitelist[filename] = True + + + def get_whitelist(self): + return self.whitelist.keys() def sock2ws(self, source, dest): try: @@ -72,7 +90,7 @@ class WebsocketVNCProxy(object): def __call__(self, environ, start_response): req = Request(environ) - if req.path == '/data': + if req.path == WS_ENDPOINT: return self.proxy_connection(environ, start_response) else: if req.path == '/': @@ -80,7 +98,11 @@ class WebsocketVNCProxy(object): else: fname = req.path - fname = self.wwwroot + fname + fname = (self.wwwroot + fname).replace('//','/') + if not fname in self.whitelist: + start_response('404 Not Found', + [('content-type', 'text/html')]) + return "Not Found" base, ext = os.path.splitext(fname) if ext == '.js': @@ -104,7 +126,7 @@ class DebugMiddleware(object): @webob.dec.wsgify def __call__(self, req): - if req.path == '/data': + if req.path == WS_ENDPOINT: req.environ['vnc_host'] = req.params.get('host') req.environ['vnc_port'] = int(req.params.get('port')) return req.get_response(self.app) -- cgit From 3b381792c2cce1e43f68e39f2fc9c73ba2760024 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 23 Mar 2011 15:55:37 -0700 Subject: clean some pep8 issues --- nova/vnc/proxy.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nova/vnc/proxy.py b/nova/vnc/proxy.py index 70ebd022a..dea838e3d 100644 --- a/nova/vnc/proxy.py +++ b/nova/vnc/proxy.py @@ -48,7 +48,6 @@ class WebsocketVNCProxy(object): if not str(name).startswith('.'): filename = os.path.join(root, name) self.whitelist[filename] = True - def get_whitelist(self): return self.whitelist.keys() @@ -98,7 +97,7 @@ class WebsocketVNCProxy(object): else: fname = req.path - fname = (self.wwwroot + fname).replace('//','/') + fname = (self.wwwroot + fname).replace('//', '/') if not fname in self.whitelist: start_response('404 Not Found', [('content-type', 'text/html')]) -- cgit From 85ad729e4448bb4211b79e325cef897fc4e2b0bb Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 23 Mar 2011 16:11:50 -0700 Subject: make missing noVNC error condition a bit more fool-proof --- bin/nova-vnc-proxy | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/bin/nova-vnc-proxy b/bin/nova-vnc-proxy index 4cd1e9082..ea2533dc3 100755 --- a/bin/nova-vnc-proxy +++ b/bin/nova-vnc-proxy @@ -44,7 +44,7 @@ from nova.vnc import proxy LOG = logging.getLogger('nova.vnc-proxy') FLAGS = flags.FLAGS -flags.DEFINE_string('vnc_proxy_wwwroot', '/code/noVNC/', +flags.DEFINE_string('vnc_proxy_wwwroot', '/var/lib/nova/noVNC/', 'Full path to noVNC directory') flags.DEFINE_boolean('vnc_debug', False, 'Enable debugging features, like token bypassing') @@ -66,13 +66,15 @@ if __name__ == "__main__": LOG.audit(_("Starting nova-vnc-proxy node (version %s)"), version.version_string_with_vcs()) - if not os.path.exists(FLAGS.vnc_proxy_wwwroot): + if not (os.path.exists(FLAGS.vnc_proxy_wwwroot) and + os.path.exists(FLAGS.vnc_proxy_wwwroot + '/vnc_auto.html')): LOG.info(_("Missing vnc_proxy_wwwroot (version %s)"), FLAGS.vnc_proxy_wwwroot) LOG.info(_("You need a slightly modified version of noVNC " - "to work with the nova-vnc-proxy")) - LOG.info(_("Check out the most recent nova noVNC code here: %s"), - "git://github.com/sleepsonthefloor/noVNC.git") + "to work with the nova-vnc-proxy")) + LOG.info(_("Check out the most recent nova noVNC code: %s"), + "git://github.com/sleepsonthefloor/noVNC.git") + LOG.info(_("And drop it in %s"), FLAGS.vnc_proxy_wwwroot) exit(1) app = proxy.WebsocketVNCProxy(FLAGS.vnc_proxy_wwwroot) -- cgit From d83ec9a667f7b9787a6ad9d7af78069f6d0f2cda Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Thu, 24 Mar 2011 00:10:28 -0700 Subject: minor tweak from termie feedback --- bin/nova-vnc-proxy | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bin/nova-vnc-proxy b/bin/nova-vnc-proxy index ea2533dc3..e7b647c00 100755 --- a/bin/nova-vnc-proxy +++ b/bin/nova-vnc-proxy @@ -1,5 +1,4 @@ #!/usr/bin/env python -# pylint: disable-msg=C0103 # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2010 United States Government as represented by the @@ -50,7 +49,7 @@ flags.DEFINE_boolean('vnc_debug', False, 'Enable debugging features, like token bypassing') flags.DEFINE_integer('vnc_proxy_port', 6080, 'Port that the VNC proxy should bind to') -flags.DEFINE_string('vnc_proxy_iface', '0.0.0.0', +flags.DEFINE_string('vnc_proxy_host', '0.0.0.0', 'Address that the VNC proxy should bind to') flags.DEFINE_integer('vnc_token_ttl', 300, 'How many seconds before deleting tokens') @@ -90,5 +89,5 @@ if __name__ == "__main__": with_auth = auth.NovaAuthMiddleware(with_logging) server = wsgi.Server() - server.start(with_auth, FLAGS.vnc_proxy_port, host=FLAGS.vnc_proxy_iface) + server.start(with_auth, FLAGS.vnc_proxy_port, host=FLAGS.vnc_proxy_host) server.wait() -- cgit From 1894937e1ef6769a5f76c0a382931480e2547ce8 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 24 Mar 2011 01:03:41 -0700 Subject: Added volume_attachments --- .bzrignore | 2 + nova/api/openstack/__init__.py | 6 ++ nova/api/openstack/volume_attachments.py | 154 +++++++++++++++++++++++++++++++ nova/api/openstack/volumes.py | 60 ++++++------ 4 files changed, 192 insertions(+), 30 deletions(-) create mode 100644 nova/api/openstack/volume_attachments.py diff --git a/.bzrignore b/.bzrignore index d22b62629..f10df621d 100644 --- a/.bzrignore +++ b/.bzrignore @@ -14,3 +14,5 @@ CA/newcerts/*.pem CA/private/cakey.pem nova/vcsversion.py *.DS_Store +.project +.pydevproject diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 474c1d0e6..af3f8c5ce 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -38,6 +38,7 @@ from nova.api.openstack import servers from nova.api.openstack import shared_ip_groups from nova.api.openstack import users from nova.api.openstack import volumes +from nova.api.openstack import volume_attachments from nova.api.openstack import zones @@ -109,6 +110,11 @@ class APIRouter(wsgi.Router): parent_resource=dict(member_name='server', collection_name='servers')) + mapper.resource("volume_attachment", "volume_attachment", + controller=volume_attachments.Controller(), + parent_resource=dict(member_name='server', + collection_name='servers')) + mapper.resource("console", "consoles", controller=consoles.Controller(), parent_resource=dict(member_name='server', diff --git a/nova/api/openstack/volume_attachments.py b/nova/api/openstack/volume_attachments.py new file mode 100644 index 000000000..fbcec7c29 --- /dev/null +++ b/nova/api/openstack/volume_attachments.py @@ -0,0 +1,154 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from webob import exc + +from nova import compute +from nova import exception +from nova import flags +from nova import log as logging +from nova import volume +from nova import wsgi +from nova.api.openstack import common +from nova.api.openstack import faults + + +LOG = logging.getLogger("nova.api.volumes") + +FLAGS = flags.FLAGS + + +def _translate_detail_view(context, volume): + """ Maps keys for details view""" + + v = _translate_summary_view(context, volume) + + # No additional data / lookups at the moment + + return v + + +def _translate_summary_view(context, volume): + """ Maps keys for summary view""" + v = {} + + volume_id = volume['id'] + + # NOTE(justinsb): We use the volume id as the id of the attachment object + v['id'] = volume_id + + v['volumeId'] = volume_id + v['serverId'] = volume['instance_id'] + v['device'] = volume['mountpoint'] + + return v + + +class Controller(wsgi.Controller): + """ The volume attachment API controller for the Openstack API + + A child resource of the server. Note that we use the volume id + as the ID of the attachment (though this is not guaranteed externally)""" + + _serialization_metadata = { + 'application/xml': { + 'attributes': { + 'volumeAttachment': [ 'id', + 'serverId', + 'volumeId', + 'device' ]}}} + + def __init__(self): + self.compute_api = compute.API() + self.volume_api = volume.API() + super(Controller, self).__init__() + + def index(self, req, server_id): + """ Returns the list of volume attachments for a given instance """ + return self._items(req, server_id, + entity_maker=_translate_summary_view) + + def show(self, req, id): + """Return data about the given volume""" + context = req.environ['nova.context'] + + try: + vol = self.volume_api.get(context, id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + return {'volume': _translate_detail_view(context, vol)} + + def create(self, req, server_id): + """ Attach a volume to an instance """ + context = req.environ['nova.context'] + + env = self._deserialize(req.body, req) + if not env: + return faults.Fault(exc.HTTPUnprocessableEntity()) + + instance_id = server_id + volume_id = env['volumeAttachment']['volumeId'] + device = env['volumeAttachment']['device'] + + msg = _("Attach volume %(volume_id)s to instance %(server_id)s" + " at %(device)s") % locals() + LOG.audit(msg, context=context) + + self.compute_api.attach_volume(context, + instance_id=instance_id, + volume_id=volume_id, + device=device) + vol = self.volume_api.get(context, volume_id) + + retval = _translate_detail_view(context, vol) + + return {'volumeAttachment': retval} + + def update(self, _req, _server_id, _id): + """ Update a volume attachment. We don't currently support this.""" + return faults.Fault(exc.HTTPBadRequest()) + + def delete(self, req, server_id, id): + """ Detach a volume from an instance """ + context = req.environ['nova.context'] + + volume_id = id + LOG.audit(_("Detach volume %s"), volume_id, context=context) + + vol = self.volume_api.get(context, volume_id) + if vol['instance_id'] != server_id: + return faults.Fault(exc.HTTPNotFound()) + + self.compute_api.detach_volume(context, + volume_id=volume_id) + + return exc.HTTPAccepted() + + def _items(self, req, server_id, entity_maker): + """Returns a list of attachments, transformed through entity_maker""" + context = req.environ['nova.context'] + + try: + instance = self.compute_api.get(context, server_id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + volumes = instance['volumes'] + limited_list = common.limited(volumes, req) + res = [entity_maker(context, vol) for vol in limited_list] + return {'volumeAttachments': res} diff --git a/nova/api/openstack/volumes.py b/nova/api/openstack/volumes.py index 99300421e..ea2dc4aab 100644 --- a/nova/api/openstack/volumes.py +++ b/nova/api/openstack/volumes.py @@ -29,52 +29,52 @@ LOG = logging.getLogger("nova.api.volumes") FLAGS = flags.FLAGS -def _translate_detail_view(context, inst): +def _translate_detail_view(context, vol): """ Maps keys for details view""" - inst_dict = _translate_summary_view(context, inst) + d = _translate_summary_view(context, vol) # No additional data / lookups at the moment - return inst_dict + return d -def _translate_summary_view(context, volume): +def _translate_summary_view(_context, vol): """ Maps keys for summary view""" - v = {} + d = {} instance_id = None # instance_data = None - attached_to = volume.get('instance') + attached_to = vol.get('instance') if attached_to: instance_id = attached_to['id'] # instance_data = '%s[%s]' % (instance_ec2_id, # attached_to['host']) - v['id'] = volume['id'] - v['status'] = volume['status'] - v['size'] = volume['size'] - v['availabilityZone'] = volume['availability_zone'] - v['createdAt'] = volume['created_at'] + d['id'] = vol['id'] + d['status'] = vol['status'] + d['size'] = vol['size'] + d['availabilityZone'] = vol['availability_zone'] + d['createdAt'] = vol['created_at'] # if context.is_admin: # v['status'] = '%s (%s, %s, %s, %s)' % ( - # volume['status'], - # volume['user_id'], - # volume['host'], + # vol['status'], + # vol['user_id'], + # vol['host'], # instance_data, - # volume['mountpoint']) - if volume['attach_status'] == 'attached': - v['attachments'] = [{'attachTime': volume['attach_time'], + # vol['mountpoint']) + if vol['attach_status'] == 'attached': + d['attachments'] = [{'attachTime': vol['attach_time'], 'deleteOnTermination': False, - 'mountpoint': volume['mountpoint'], + 'mountpoint': vol['mountpoint'], 'instanceId': instance_id, 'status': 'attached', - 'volumeId': volume['id']}] + 'volumeId': vol['id']}] else: - v['attachments'] = [{}] + d['attachments'] = [{}] - v['displayName'] = volume['display_name'] - v['displayDescription'] = volume['display_description'] - return v + d['displayName'] = vol['display_name'] + d['displayDescription'] = vol['display_description'] + return d class Controller(wsgi.Controller): @@ -102,11 +102,11 @@ class Controller(wsgi.Controller): context = req.environ['nova.context'] try: - volume = self.volume_api.get(context, id) + vol = self.volume_api.get(context, id) except exception.NotFound: return faults.Fault(exc.HTTPNotFound()) - return {'volume': _translate_detail_view(context, volume)} + return {'volume': _translate_detail_view(context, vol)} def delete(self, req, id): """ Delete a volume """ @@ -134,7 +134,7 @@ class Controller(wsgi.Controller): volumes = self.volume_api.get_all(context) limited_list = common.limited(volumes, req) - res = [entity_maker(context, inst) for inst in limited_list] + res = [entity_maker(context, vol) for vol in limited_list] return {'volumes': res} def create(self, req): @@ -148,13 +148,13 @@ class Controller(wsgi.Controller): vol = env['volume'] size = vol['size'] LOG.audit(_("Create volume of %s GB"), size, context=context) - volume = self.volume_api.create(context, size, - vol.get('display_name'), - vol.get('display_description')) + new_volume = self.volume_api.create(context, size, + vol.get('display_name'), + vol.get('display_description')) # Work around problem that instance is lazy-loaded... volume['instance'] = None - retval = _translate_detail_view(context, volume) + retval = _translate_detail_view(context, new_volume) return {'volume': retval} -- cgit From 694c2cfd2afdc0ed293f205890bda977968dc079 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 24 Mar 2011 01:13:20 -0700 Subject: Created simple test case for server creation, so that we can have something to attach to... --- .bzrignore | 3 + nova/image/fake.py | 109 ++++++++++++++ nova/tests/integrated/integrated_helpers.py | 22 +++ nova/tests/integrated/test_servers.py | 218 ++++++++++++++++++++++++++++ 4 files changed, 352 insertions(+) create mode 100644 nova/image/fake.py create mode 100644 nova/tests/integrated/test_servers.py diff --git a/.bzrignore b/.bzrignore index f10df621d..b751ad825 100644 --- a/.bzrignore +++ b/.bzrignore @@ -16,3 +16,6 @@ nova/vcsversion.py *.DS_Store .project .pydevproject +clean.sqlite +run_tests.log +tests.sqlite diff --git a/nova/image/fake.py b/nova/image/fake.py new file mode 100644 index 000000000..bc63780d3 --- /dev/null +++ b/nova/image/fake.py @@ -0,0 +1,109 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +"""Implementation of an fake image service""" + +from nova import exception +from nova import flags +from nova import log as logging +from nova.image import service + + +LOG = logging.getLogger('nova.image.fake') + +FLAGS = flags.FLAGS + + +class MockImageService(service.BaseImageService): + """Mock (fake) image service for unit testing""" + + def __init__(self): + self.images = {} + # NOTE(justinsb): The OpenStack API can't upload an image??? + # So, make sure we've got one.. + image = {'id': '123456', + 'status': 'active', + 'type': 'machine', + 'disk_format': 'ami', + 'properties': {'kernel_id': FLAGS.null_kernel, + 'ramdisk_id': FLAGS.null_kernel, + } + } + self.create(None, image) + super(MockImageService, self).__init__() + + def index(self, context): + """Returns list of images""" + return self.images.values() + + def detail(self, context): + """Return list of detailed image information""" + return self.images.values() + + def show(self, context, image_id): + """ + Returns a dict containing image data for the given opaque image id. + """ + image_id = int(image_id) + image = self.images.get(image_id) + if image: + return image + LOG.warn("Unable to find image id %s. Have images: %s", + image_id, self.images) + raise exception.NotFound + + def create(self, context, data): + """ + Store the image data and return the new image id. + + :raises AlreadyExists if the image already exist. + + """ + image_id = int(data['id']) + if self.images.get(image_id): + #TODO(justinsb): Where is this AlreadyExists exception?? + raise exception.Error("AlreadyExists") + + self.images[image_id] = data + + def update(self, context, image_id, data): + """Replace the contents of the given image with the new data. + + :raises NotFound if the image does not exist. + + """ + image_id = int(image_id) + if not self.images.get(image_id): + raise exception.NotFound + self.images[image_id] = data + + def delete(self, context, image_id): + """ + Delete the given image. + + :raises NotFound if the image does not exist. + + """ + image_id = int(image_id) + removed = self.images.pop(image_id, None) + if not removed: + raise exception.NotFound + + def delete_all(self): + """ + Clears out all images + """ + self.images.clear() diff --git a/nova/tests/integrated/integrated_helpers.py b/nova/tests/integrated/integrated_helpers.py index 47093636e..dc6897e08 100644 --- a/nova/tests/integrated/integrated_helpers.py +++ b/nova/tests/integrated/integrated_helpers.py @@ -73,6 +73,28 @@ class TestUser(object): self.secret, self.auth_url) + def get_unused_server_name(self): + servers = self.openstack_api.get_servers() + server_names = [server['name'] for server in servers] + return generate_new_element(server_names, 'server') + + def get_invalid_image(self): + images = self.openstack_api.get_images() + image_ids = [image['id'] for image in images] + return generate_new_element(image_ids, '', numeric=True) + + def get_valid_image(self, create=False): + images = self.openstack_api.get_images() + if create and not images: + # TODO(justinsb): No way to create an image through API??? + #created_image = self.openstack_api.post_image(image) + #images.append(created_image) + raise exception.Error("No way to create an image through API??") + + if images: + return images[0] + return None + class IntegratedUnitTestContext(object): __INSTANCE = None diff --git a/nova/tests/integrated/test_servers.py b/nova/tests/integrated/test_servers.py new file mode 100644 index 000000000..3c38295c5 --- /dev/null +++ b/nova/tests/integrated/test_servers.py @@ -0,0 +1,218 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import time +import unittest + +from nova import flags +from nova import test +from nova.log import logging +from nova.tests.integrated import integrated_helpers +from nova.tests.integrated.api import client + + +LOG = logging.getLogger('nova.tests.integrated') + +FLAGS = flags.FLAGS +FLAGS.verbose = True + + +class ServersTest(test.TestCase): + def setUp(self): + super(ServersTest, self).setUp() + + self.flags(image_service='nova.image.fake.MockImageService') + + context = integrated_helpers.IntegratedUnitTestContext.startup() + self.user = context.test_user + self.api = self.user.openstack_api + + def tearDown(self): + integrated_helpers.IntegratedUnitTestContext.shutdown() + super(ServersTest, self).tearDown() + + def test_get_servers(self): + """Simple check that listing servers works.""" + servers = self.api.get_servers() + for server in servers: + LOG.debug("server: %s" % server) + + def test_create_and_delete_server(self): + """Creates and deletes a server""" + + # Create server + + # Build the server data gradually, checking errors along the way + server = {} + good_server = self._build_minimal_create_server_request() + + post = {'server': server} + + # Without an imageId, this throws 500. + # TODO(justinsb): Check whatever the spec says should be thrown here + self.assertRaises(client.OpenStackApiException, + self.api.post_server, post) + + # With an invalid imageId, this throws 500. + server['imageId'] = self.user.get_invalid_image() + # TODO(justinsb): Check whatever the spec says should be thrown here + self.assertRaises(client.OpenStackApiException, + self.api.post_server, post) + + # Add a valid imageId + server['imageId'] = good_server['imageId'] + + # Without flavorId, this throws 500 + # TODO(justinsb): Check whatever the spec says should be thrown here + self.assertRaises(client.OpenStackApiException, + self.api.post_server, post) + + # Set a valid flavorId + server['flavorId'] = good_server['flavorId'] + + # Without a name, this throws 500 + # TODO(justinsb): Check whatever the spec says should be thrown here + self.assertRaises(client.OpenStackApiException, + self.api.post_server, post) + + # Set a valid server name + server['name'] = good_server['name'] + + created_server = self.api.post_server(post) + LOG.debug("created_server: %s" % created_server) + self.assertTrue(created_server['id']) + created_server_id = created_server['id'] + + # Check it's there + found_server = self.api.get_server(created_server_id) + self.assertEqual(created_server_id, found_server['id']) + + # It should also be in the all-servers list + servers = self.api.get_servers() + server_ids = [server['id'] for server in servers] + self.assertTrue(created_server_id in server_ids) + + # Wait (briefly) for creation + retries = 0 + while found_server['status'] == 'build': + LOG.debug("found server: %s" % found_server) + time.sleep(1) + found_server = self.api.get_server(created_server_id) + retries = retries + 1 + if retries > 5: + break + + # It should be available... + # TODO(justinsb): Mock doesn't yet do this... + #self.assertEqual('available', found_server['status']) + + self._delete_server(created_server_id) + + def _delete_server(self, server_id): + # Delete the server + self.api.delete_server(server_id) + + # Wait (briefly) for deletion + for _retries in range(5): + try: + found_server = self.api.get_server(server_id) + except client.OpenStackApiNotFoundException: + found_server = None + LOG.debug("Got 404, proceeding") + break + + LOG.debug("Found_server=%s" % found_server) + + # TODO(justinsb): Mock doesn't yet do accurate state changes + #if found_server['status'] != 'deleting': + # break + time.sleep(1) + + # Should be gone + self.assertFalse(found_server) + + def _build_minimal_create_server_request(self): + server = {} + + image = self.user.get_valid_image(create=True) + image_id = image['id'] + + #TODO(justinsb): This is FUBAR + image_id = abs(hash(image_id)) + + # We now have a valid imageId + server['imageId'] = image_id + + # Set a valid flavorId + flavor = self.api.get_flavors()[0] + LOG.debug("Using flavor: %s" % flavor) + server['flavorId'] = flavor['id'] + + # Set a valid server name + server_name = self.user.get_unused_server_name() + server['name'] = server_name + + return server + +# TODO(justinsb): Enable this unit test when the metadata bug is fixed +# def test_create_server_with_metadata(self): +# """Creates a server with metadata""" +# +# # Build the server data gradually, checking errors along the way +# server = self._build_minimal_create_server_request() +# +# for metadata_count in range(30): +# metadata = {} +# for i in range(metadata_count): +# metadata['key_%s' % i] = 'value_%s' % i +# server['metadata'] = metadata +# +# post = {'server': server} +# created_server = self.api.post_server(post) +# LOG.debug("created_server: %s" % created_server) +# self.assertTrue(created_server['id']) +# created_server_id = created_server['id'] +# # Reenable when bug fixed +# # self.assertEqual(metadata, created_server.get('metadata')) +# +# # Check it's there +# found_server = self.api.get_server(created_server_id) +# self.assertEqual(created_server_id, found_server['id']) +# self.assertEqual(metadata, found_server.get('metadata')) +# +# # The server should also be in the all-servers details list +# servers = self.api.get_servers(detail=True) +# server_map = dict((server['id'], server) for server in servers) +# found_server = server_map.get(created_server_id) +# self.assertTrue(found_server) +# # Details do include metadata +# self.assertEqual(metadata, found_server.get('metadata')) +# +# # The server should also be in the all-servers summary list +# servers = self.api.get_servers(detail=False) +# server_map = dict((server['id'], server) for server in servers) +# found_server = server_map.get(created_server_id) +# self.assertTrue(found_server) +# # Summary should not include metadata +# self.assertFalse(found_server.get('metadata')) +# +# # Cleanup +# self._delete_server(created_server_id) + + +if __name__ == "__main__": + unittest.main() -- cgit From 699adb4311fdd86525fae022f4119401fd1c0168 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 24 Mar 2011 01:37:14 -0700 Subject: Added simple nova volume tests --- nova/api/openstack/volume_attachments.py | 2 +- nova/api/openstack/volumes.py | 4 +- nova/tests/integrated/api/client.py | 15 +++ nova/tests/integrated/integrated_helpers.py | 17 +++- nova/tests/integrated/test_volumes.py | 137 ++++++++++++++++++++++++++++ nova/volume/driver.py | 67 ++++++++++++++ 6 files changed, 238 insertions(+), 4 deletions(-) create mode 100644 nova/tests/integrated/test_volumes.py diff --git a/nova/api/openstack/volume_attachments.py b/nova/api/openstack/volume_attachments.py index fbcec7c29..1cb2c9494 100644 --- a/nova/api/openstack/volume_attachments.py +++ b/nova/api/openstack/volume_attachments.py @@ -97,7 +97,7 @@ class Controller(wsgi.Controller): """ Attach a volume to an instance """ context = req.environ['nova.context'] - env = self._deserialize(req.body, req) + env = self._deserialize(req.body, req.get_content_type()) if not env: return faults.Fault(exc.HTTPUnprocessableEntity()) diff --git a/nova/api/openstack/volumes.py b/nova/api/openstack/volumes.py index ea2dc4aab..ec3b9a6c8 100644 --- a/nova/api/openstack/volumes.py +++ b/nova/api/openstack/volumes.py @@ -141,7 +141,7 @@ class Controller(wsgi.Controller): """Creates a new volume""" context = req.environ['nova.context'] - env = self._deserialize(req.body, req) + env = self._deserialize(req.body, req.get_content_type()) if not env: return faults.Fault(exc.HTTPUnprocessableEntity()) @@ -153,7 +153,7 @@ class Controller(wsgi.Controller): vol.get('display_description')) # Work around problem that instance is lazy-loaded... - volume['instance'] = None + new_volume['instance'] = None retval = _translate_detail_view(context, new_volume) diff --git a/nova/tests/integrated/api/client.py b/nova/tests/integrated/api/client.py index fc7c344e7..7a4c3198e 100644 --- a/nova/tests/integrated/api/client.py +++ b/nova/tests/integrated/api/client.py @@ -90,6 +90,7 @@ class TestOpenStackClient(object): LOG.info(_("Doing %(method)s on %(relative_url)s") % locals()) if body: LOG.info(_("Body: %s") % body) + headers.setdefault('Content-Type', 'application/json') conn.request(method, relative_url, body, headers) response = conn.getresponse() @@ -208,3 +209,17 @@ class TestOpenStackClient(object): def delete_flavor(self, flavor_id): return self.api_delete('/flavors/%s' % flavor_id) + + def get_volume(self, volume_id): + return self.api_get('/volumes/%s' % volume_id)['volume'] + + def get_volumes(self, detail=True): + rel_url = '/volumes/detail' if detail else '/volumes' + return self.api_get(rel_url)['volumes'] + + def post_volume(self, volume): + return self.api_post('/volumes', volume)['volume'] + + def delete_volume(self, volume_id): + return self.api_delete('/volumes/%s' % volume_id) + diff --git a/nova/tests/integrated/integrated_helpers.py b/nova/tests/integrated/integrated_helpers.py index dc6897e08..f24759032 100644 --- a/nova/tests/integrated/integrated_helpers.py +++ b/nova/tests/integrated/integrated_helpers.py @@ -58,7 +58,7 @@ def generate_new_element(items, prefix, numeric=False): candidate = prefix + generate_random_alphanumeric(8) if not candidate in items: return candidate - print "Random collision on %s" % candidate + LOG.debug("Random collision on %s" % candidate) class TestUser(object): @@ -125,11 +125,26 @@ class IntegratedUnitTestContext(object): self._configure_project(self.project_name, self.test_user) def _start_services(self): + self._start_volume_service() + self._start_scheduler_service() + # WSGI shutdown broken :-( # bug731668 if not self.api_service: self._start_api_service() + def _start_volume_service(self): + volume_service = service.Service.create(binary='nova-volume') + volume_service.start() + self.services.append(volume_service) + return volume_service + + def _start_scheduler_service(self): + scheduler_service = service.Service.create(binary='nova-scheduler') + scheduler_service.start() + self.services.append(scheduler_service) + return scheduler_service + def cleanup(self): for service in self.services: service.kill() diff --git a/nova/tests/integrated/test_volumes.py b/nova/tests/integrated/test_volumes.py new file mode 100644 index 000000000..66b773db2 --- /dev/null +++ b/nova/tests/integrated/test_volumes.py @@ -0,0 +1,137 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import unittest +import time + +from nova import flags +from nova import test +from nova.log import logging +from nova.tests.integrated import integrated_helpers +from nova.tests.integrated.api import client +from nova.volume import driver + + +LOG = logging.getLogger('nova.tests.integrated') + +FLAGS = flags.FLAGS +FLAGS.verbose = True + + +class VolumesTest(test.TestCase): + def setUp(self): + super(VolumesTest, self).setUp() + + self.flags(image_service='nova.image.fake.MockImageService', + volume_driver='nova.volume.driver.LoggingVolumeDriver') + + context = integrated_helpers.IntegratedUnitTestContext.startup() + self.user = context.test_user + self.api = self.user.openstack_api + + def tearDown(self): + integrated_helpers.IntegratedUnitTestContext.shutdown() + super(VolumesTest, self).tearDown() + + def test_get_volumes(self): + """Simple check that listing volumes works""" + volumes = self.api.get_volumes() + for volume in volumes: + LOG.debug("volume: %s" % volume) + + def test_create_and_delete_volume(self): + """Creates and deletes a volume""" + + # Create volume with name + created_volume = self.api.post_volume({'volume': {'size': 1}}) + LOG.debug("created_volume: %s" % created_volume) + self.assertTrue(created_volume['id']) + created_volume_id = created_volume['id'] + + # Check it's there + found_volume = self.api.get_volume(created_volume_id) + self.assertEqual(created_volume_id, found_volume['id']) + + # It should also be in the all-volume list + volumes = self.api.get_volumes() + volume_names = [volume['id'] for volume in volumes] + self.assertTrue(created_volume_id in volume_names) + + # Wait (briefly) for creation. Delay is due to the 'message queue' + retries = 0 + while found_volume['status'] == 'creating': + LOG.debug("Found %s" % found_volume) + time.sleep(1) + found_volume = self.api.get_volume(created_volume_id) + retries = retries + 1 + if retries > 5: + break + + # It should be available... + self.assertEqual('available', found_volume['status']) + + # Delete the volume + self.api.delete_volume(created_volume_id) + + # Wait (briefly) for deletion. Delay is due to the 'message queue' + for retries in range(5): + try: + found_volume = self.api.get_volume(created_volume_id) + except client.OpenStackApiNotFoundException: + found_volume = None + LOG.debug("Got 404, proceeding") + break + + LOG.debug("Found_volume=%s" % found_volume) + if found_volume['status'] != 'deleting': + break + time.sleep(1) + + # Should be gone + self.assertFalse(found_volume) + + LOG.debug("Logs: %s" % driver.LoggingVolumeDriver.all_logs()) + + create_actions = driver.LoggingVolumeDriver.logs_like( + 'create_volume', + id=created_volume_id) + LOG.debug("Create_Actions: %s" % create_actions) + + self.assertEquals(1, len(create_actions)) + create_action = create_actions[0] + self.assertEquals(create_action['id'], created_volume_id) + self.assertEquals(create_action['availability_zone'], 'nova') + self.assertEquals(create_action['size'], 1) + + export_actions = driver.LoggingVolumeDriver.logs_like( + 'create_export', + id=created_volume_id) + self.assertEquals(1, len(export_actions)) + export_action = export_actions[0] + self.assertEquals(export_action['id'], created_volume_id) + self.assertEquals(export_action['availability_zone'], 'nova') + + delete_actions = driver.LoggingVolumeDriver.logs_like( + 'delete_volume', + id=created_volume_id) + self.assertEquals(1, len(delete_actions)) + delete_action = export_actions[0] + self.assertEquals(delete_action['id'], created_volume_id) + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/nova/volume/driver.py b/nova/volume/driver.py index 779b46755..148e5facd 100644 --- a/nova/volume/driver.py +++ b/nova/volume/driver.py @@ -629,3 +629,70 @@ class SheepdogDriver(VolumeDriver): def undiscover_volume(self, volume): """Undiscover volume on a remote host""" pass + + +class LoggingVolumeDriver(VolumeDriver): + """Logs and records calls, for unit tests.""" + + def check_for_setup_error(self): + pass + + def create_volume(self, volume): + self.log_action('create_volume', volume) + + def delete_volume(self, volume): + self.log_action('delete_volume', volume) + + def local_path(self, volume): + print "local_path not implemented" + raise NotImplementedError() + + def ensure_export(self, context, volume): + self.log_action('ensure_export', volume) + + def create_export(self, context, volume): + self.log_action('create_export', volume) + + def remove_export(self, context, volume): + self.log_action('remove_export', volume) + + def discover_volume(self, volume): + self.log_action('discover_volume', volume) + + def undiscover_volume(self, volume): + self.log_action('undiscover_volume', volume) + + def check_for_export(self, context, volume_id): + self.log_action('check_for_export', volume_id) + + _LOGS = [] + + @staticmethod + def log_action(action, parameters): + """Logs the command.""" + LOG.debug(_("LoggingVolumeDriver: %s") % (action)) + log_dictionary = {} + if parameters: + log_dictionary = dict(parameters) + log_dictionary['action'] = action + LOG.debug(_("LoggingVolumeDriver: %s") % (log_dictionary)) + LoggingVolumeDriver._LOGS.append(log_dictionary) + + @staticmethod + def all_logs(): + return LoggingVolumeDriver._LOGS + + @staticmethod + def logs_like(action, **kwargs): + matches = [] + for entry in LoggingVolumeDriver._LOGS: + if entry['action'] != action: + continue + match = True + for k, v in kwargs.iteritems(): + if entry.get(k) != v: + match = False + break + if match: + matches.append(entry) + return matches -- cgit From 230d07e9002371bdb0030c9199df35fc6360a0a2 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 24 Mar 2011 03:26:32 -0700 Subject: Test for attach / detach (and associated fixes) --- nova/api/openstack/__init__.py | 2 +- nova/api/openstack/volume_attachments.py | 77 ++++++---- nova/tests/integrated/api/client.py | 15 ++ nova/tests/integrated/integrated_helpers.py | 49 +++++++ nova/tests/integrated/test_login.py | 12 +- nova/tests/integrated/test_servers.py | 37 +---- nova/tests/integrated/test_volumes.py | 215 +++++++++++++++++++++++----- nova/volume/driver.py | 12 +- 8 files changed, 312 insertions(+), 107 deletions(-) diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 54d8a738d..e8aa4821b 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -134,7 +134,7 @@ class APIRouter(wsgi.Router): controller=volumes.Controller(), collection={'detail': 'GET'}) - mapper.resource("volume_attachment", "volume_attachment", + mapper.resource("volume_attachment", "volume_attachments", controller=volume_attachments.Controller(), parent_resource=dict(member_name='server', collection_name='servers')) diff --git a/nova/api/openstack/volume_attachments.py b/nova/api/openstack/volume_attachments.py index 1cb2c9494..2ce681e19 100644 --- a/nova/api/openstack/volume_attachments.py +++ b/nova/api/openstack/volume_attachments.py @@ -35,27 +35,29 @@ FLAGS = flags.FLAGS def _translate_detail_view(context, volume): """ Maps keys for details view""" - v = _translate_summary_view(context, volume) + d = _translate_summary_view(context, volume) # No additional data / lookups at the moment - return v + return d -def _translate_summary_view(context, volume): +def _translate_summary_view(context, vol): """ Maps keys for summary view""" - v = {} + d = {} + + volume_id = vol['id'] - volume_id = volume['id'] - # NOTE(justinsb): We use the volume id as the id of the attachment object - v['id'] = volume_id - - v['volumeId'] = volume_id - v['serverId'] = volume['instance_id'] - v['device'] = volume['mountpoint'] + d['id'] = volume_id - return v + d['volumeId'] = volume_id + if vol.get('instance_id'): + d['serverId'] = vol['instance_id'] + if vol.get('mountpoint'): + d['device'] = vol['mountpoint'] + + return d class Controller(wsgi.Controller): @@ -82,16 +84,22 @@ class Controller(wsgi.Controller): return self._items(req, server_id, entity_maker=_translate_summary_view) - def show(self, req, id): + def show(self, req, server_id, id): """Return data about the given volume""" context = req.environ['nova.context'] + volume_id = id try: - vol = self.volume_api.get(context, id) + vol = self.volume_api.get(context, volume_id) except exception.NotFound: + LOG.debug("volume_id not found") return faults.Fault(exc.HTTPNotFound()) - return {'volume': _translate_detail_view(context, vol)} + if str(vol['instance_id']) != server_id: + LOG.debug("instance_id != server_id") + return faults.Fault(exc.HTTPNotFound()) + + return {'volumeAttachment': _translate_detail_view(context, vol)} def create(self, req, server_id): """ Attach a volume to an instance """ @@ -109,15 +117,29 @@ class Controller(wsgi.Controller): " at %(device)s") % locals() LOG.audit(msg, context=context) - self.compute_api.attach_volume(context, - instance_id=instance_id, - volume_id=volume_id, - device=device) - vol = self.volume_api.get(context, volume_id) + try: + self.compute_api.attach_volume(context, + instance_id=instance_id, + volume_id=volume_id, + device=device) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + # The attach is async + attachment = {} + attachment['id'] = volume_id + attachment['volumeId'] = volume_id - retval = _translate_detail_view(context, vol) + # NOTE(justinsb): And now, we have a problem... + # The attach is async, so there's a window in which we don't see + # the attachment (until the attachment completes). We could also + # get problems with concurrent requests. I think we need an + # attachment state, and to write to the DB here, but that's a bigger + # change. + # For now, we'll probably have to rely on libraries being smart - return {'volumeAttachment': retval} + # TODO: How do I return "accepted" here?? + return {'volumeAttachment': attachment} def update(self, _req, _server_id, _id): """ Update a volume attachment. We don't currently support this.""" @@ -130,10 +152,15 @@ class Controller(wsgi.Controller): volume_id = id LOG.audit(_("Detach volume %s"), volume_id, context=context) - vol = self.volume_api.get(context, volume_id) - if vol['instance_id'] != server_id: + try: + vol = self.volume_api.get(context, volume_id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + if str(vol['instance_id']) != server_id: + LOG.debug("instance_id != server_id") return faults.Fault(exc.HTTPNotFound()) - + self.compute_api.detach_volume(context, volume_id=volume_id) diff --git a/nova/tests/integrated/api/client.py b/nova/tests/integrated/api/client.py index 7a4c3198e..deb7fd981 100644 --- a/nova/tests/integrated/api/client.py +++ b/nova/tests/integrated/api/client.py @@ -223,3 +223,18 @@ class TestOpenStackClient(object): def delete_volume(self, volume_id): return self.api_delete('/volumes/%s' % volume_id) + def get_server_volume(self, server_id, attachment_id): + return self.api_get('/servers/%s/volume_attachments/%s' % + (server_id, attachment_id))['volumeAttachment'] + + def get_server_volumes(self, server_id): + return self.api_get('/servers/%s/volume_attachments' % + (server_id))['volumeAttachments'] + + def post_server_volume(self, server_id, volume_attachment): + return self.api_post('/servers/%s/volume_attachments' % + (server_id), volume_attachment)['volumeAttachment'] + + def delete_server_volume(self, server_id, attachment_id): + return self.api_delete('/servers/%s/volume_attachments/%s' % + (server_id, attachment_id)) diff --git a/nova/tests/integrated/integrated_helpers.py b/nova/tests/integrated/integrated_helpers.py index f24759032..b520cc5d3 100644 --- a/nova/tests/integrated/integrated_helpers.py +++ b/nova/tests/integrated/integrated_helpers.py @@ -125,6 +125,7 @@ class IntegratedUnitTestContext(object): self._configure_project(self.project_name, self.test_user) def _start_services(self): + self._start_compute_service() self._start_volume_service() self._start_scheduler_service() @@ -133,6 +134,12 @@ class IntegratedUnitTestContext(object): if not self.api_service: self._start_api_service() + def _start_compute_service(self): + compute_service = service.Service.create(binary='nova-compute') + compute_service.start() + self.services.append(compute_service) + return compute_service + def _start_volume_service(self): volume_service = service.Service.create(binary='nova-volume') volume_service.start() @@ -223,3 +230,45 @@ class IntegratedUnitTestContext(object): # WSGI shutdown broken :-( # bug731668 #IntegratedUnitTestContext.__INSTANCE = None + + +class _IntegratedTestBase(test.TestCase): + def setUp(self): + super(_IntegratedTestBase, self).setUp() + + self._setup_flags() + + context = IntegratedUnitTestContext.startup() + self.user = context.test_user + self.api = self.user.openstack_api + + def tearDown(self): + IntegratedUnitTestContext.shutdown() + super(_IntegratedTestBase, self).tearDown() + + def _setup_flags(self): + """An opportunity to setup flags, before the services are started""" + pass + + def _build_minimal_create_server_request(self): + server = {} + + image = self.user.get_valid_image(create=True) + image_id = image['id'] + + #TODO(justinsb): This is FUBAR + image_id = abs(hash(image_id)) + + # We now have a valid imageId + server['imageId'] = image_id + + # Set a valid flavorId + flavor = self.api.get_flavors()[0] + LOG.debug("Using flavor: %s" % flavor) + server['flavorId'] = flavor['id'] + + # Set a valid server name + server_name = self.user.get_unused_server_name() + server['name'] = server_name + + return server diff --git a/nova/tests/integrated/test_login.py b/nova/tests/integrated/test_login.py index 501f8c919..cc3d555d0 100644 --- a/nova/tests/integrated/test_login.py +++ b/nova/tests/integrated/test_login.py @@ -30,17 +30,7 @@ FLAGS = flags.FLAGS FLAGS.verbose = True -class LoginTest(test.TestCase): - def setUp(self): - super(LoginTest, self).setUp() - context = integrated_helpers.IntegratedUnitTestContext.startup() - self.user = context.test_user - self.api = self.user.openstack_api - - def tearDown(self): - integrated_helpers.IntegratedUnitTestContext.shutdown() - super(LoginTest, self).tearDown() - +class LoginTest(integrated_helpers._IntegratedTestBase): def test_login(self): """Simple check - we list flavors - so we know we're logged in""" flavors = self.api.get_flavors() diff --git a/nova/tests/integrated/test_servers.py b/nova/tests/integrated/test_servers.py index 3c38295c5..2b5d3324a 100644 --- a/nova/tests/integrated/test_servers.py +++ b/nova/tests/integrated/test_servers.py @@ -31,20 +31,10 @@ FLAGS = flags.FLAGS FLAGS.verbose = True -class ServersTest(test.TestCase): - def setUp(self): - super(ServersTest, self).setUp() - +class ServersTest(integrated_helpers._IntegratedTestBase): + def _setup_flags(self): self.flags(image_service='nova.image.fake.MockImageService') - context = integrated_helpers.IntegratedUnitTestContext.startup() - self.user = context.test_user - self.api = self.user.openstack_api - - def tearDown(self): - integrated_helpers.IntegratedUnitTestContext.shutdown() - super(ServersTest, self).tearDown() - def test_get_servers(self): """Simple check that listing servers works.""" servers = self.api.get_servers() @@ -145,29 +135,6 @@ class ServersTest(test.TestCase): # Should be gone self.assertFalse(found_server) - def _build_minimal_create_server_request(self): - server = {} - - image = self.user.get_valid_image(create=True) - image_id = image['id'] - - #TODO(justinsb): This is FUBAR - image_id = abs(hash(image_id)) - - # We now have a valid imageId - server['imageId'] = image_id - - # Set a valid flavorId - flavor = self.api.get_flavors()[0] - LOG.debug("Using flavor: %s" % flavor) - server['flavorId'] = flavor['id'] - - # Set a valid server name - server_name = self.user.get_unused_server_name() - server['name'] = server_name - - return server - # TODO(justinsb): Enable this unit test when the metadata bug is fixed # def test_create_server_with_metadata(self): # """Creates a server with metadata""" diff --git a/nova/tests/integrated/test_volumes.py b/nova/tests/integrated/test_volumes.py index 66b773db2..f69361fb0 100644 --- a/nova/tests/integrated/test_volumes.py +++ b/nova/tests/integrated/test_volumes.py @@ -32,20 +32,15 @@ FLAGS = flags.FLAGS FLAGS.verbose = True -class VolumesTest(test.TestCase): +class VolumesTest(integrated_helpers._IntegratedTestBase): def setUp(self): super(VolumesTest, self).setUp() + driver.LoggingVolumeDriver.clear_logs() + def _setup_flags(self): self.flags(image_service='nova.image.fake.MockImageService', volume_driver='nova.volume.driver.LoggingVolumeDriver') - - context = integrated_helpers.IntegratedUnitTestContext.startup() - self.user = context.test_user - self.api = self.user.openstack_api - - def tearDown(self): - integrated_helpers.IntegratedUnitTestContext.shutdown() - super(VolumesTest, self).tearDown() + self.flags(use_local_volumes=False) # Avoids calling local_path def test_get_volumes(self): """Simple check that listing volumes works""" @@ -53,10 +48,34 @@ class VolumesTest(test.TestCase): for volume in volumes: LOG.debug("volume: %s" % volume) + def _poll_while(self, volume_id, continue_states, max_retries=5): + """ Poll (briefly) while the state is in continue_states""" + retries = 0 + while True: + try: + found_volume = self.api.get_volume(volume_id) + except client.OpenStackApiNotFoundException: + found_volume = None + LOG.debug("Got 404, proceeding") + break + + LOG.debug("Found %s" % found_volume) + + self.assertEqual(volume_id, found_volume['id']) + + if not found_volume['status'] in continue_states: + break + + time.sleep(1) + retries = retries + 1 + if retries > max_retries: + break + return found_volume + def test_create_and_delete_volume(self): """Creates and deletes a volume""" - # Create volume with name + # Create volume created_volume = self.api.post_volume({'volume': {'size': 1}}) LOG.debug("created_volume: %s" % created_volume) self.assertTrue(created_volume['id']) @@ -72,14 +91,7 @@ class VolumesTest(test.TestCase): self.assertTrue(created_volume_id in volume_names) # Wait (briefly) for creation. Delay is due to the 'message queue' - retries = 0 - while found_volume['status'] == 'creating': - LOG.debug("Found %s" % found_volume) - time.sleep(1) - found_volume = self.api.get_volume(created_volume_id) - retries = retries + 1 - if retries > 5: - break + found_volume = self._poll_while(created_volume_id, ['creating']) # It should be available... self.assertEqual('available', found_volume['status']) @@ -88,18 +100,7 @@ class VolumesTest(test.TestCase): self.api.delete_volume(created_volume_id) # Wait (briefly) for deletion. Delay is due to the 'message queue' - for retries in range(5): - try: - found_volume = self.api.get_volume(created_volume_id) - except client.OpenStackApiNotFoundException: - found_volume = None - LOG.debug("Got 404, proceeding") - break - - LOG.debug("Found_volume=%s" % found_volume) - if found_volume['status'] != 'deleting': - break - time.sleep(1) + found_volume = self._poll_while(created_volume_id, ['deleting']) # Should be gone self.assertFalse(found_volume) @@ -110,7 +111,7 @@ class VolumesTest(test.TestCase): 'create_volume', id=created_volume_id) LOG.debug("Create_Actions: %s" % create_actions) - + self.assertEquals(1, len(create_actions)) create_action = create_actions[0] self.assertEquals(create_action['id'], created_volume_id) @@ -132,6 +133,156 @@ class VolumesTest(test.TestCase): delete_action = export_actions[0] self.assertEquals(delete_action['id'], created_volume_id) + def test_attach_and_detach_volume(self): + """Creates, attaches, detaches and deletes a volume""" + + # Create server + server_req = {'server': self._build_minimal_create_server_request()} + # NOTE(justinsb): Create an extra server so that server_id != volume_id + self.api.post_server(server_req) + created_server = self.api.post_server(server_req) + LOG.debug("created_server: %s" % created_server) + server_id = created_server['id'] + + # Create volume + created_volume = self.api.post_volume({'volume': {'size': 1}}) + LOG.debug("created_volume: %s" % created_volume) + volume_id = created_volume['id'] + self._poll_while(volume_id, ['creating']) + + # Check we've got different IDs + self.assertNotEqual(server_id, volume_id) + + # List current server attachments - should be none + attachments = self.api.get_server_volumes(server_id) + self.assertEquals([], attachments) + + # Template attach request + device = '/dev/sdc' + attach_req = { 'device': device } + post_req = { 'volumeAttachment': attach_req } + + # Try to attach to a non-existent volume; should fail + attach_req['volumeId'] = 3405691582 + self.assertRaises(client.OpenStackApiNotFoundException, + self.api.post_server_volume, server_id, post_req) + + # Try to attach to a non-existent server; should fail + attach_req['volumeId'] = volume_id + self.assertRaises(client.OpenStackApiNotFoundException, + self.api.post_server_volume, 3405691582, post_req) + + # Should still be no attachments... + attachments = self.api.get_server_volumes(server_id) + self.assertEquals([], attachments) + + # Do a real attach + attach_req['volumeId'] = volume_id + attach_result = self.api.post_server_volume(server_id, post_req) + LOG.debug(_("Attachment = %s") % attach_result) + + attachment_id = attach_result['id'] + self.assertEquals(volume_id, attach_result['volumeId']) + + # These fields aren't set because it's async + #self.assertEquals(server_id, attach_result['serverId']) + #self.assertEquals(device, attach_result['device']) + + # This is just an implementation detail, but let's check it... + self.assertEquals(volume_id, attachment_id) + + # NOTE(justinsb): There's an issue with the attach code, in that + # it's currently asynchronous and not recorded until the attach + # completes. So the caller must be 'smart', like this... + attach_done = None + retries = 0 + while True: + try: + attach_done = self.api.get_server_volume(server_id, + attachment_id) + break + except client.OpenStackApiNotFoundException: + LOG.debug("Got 404, waiting") + + time.sleep(1) + retries = retries + 1 + if retries > 10: + break + + expect_attach = {} + expect_attach['id'] = volume_id + expect_attach['volumeId'] = volume_id + expect_attach['serverId'] = server_id + expect_attach['device'] = device + + self.assertEqual(expect_attach, attach_done) + + # Should be one attachemnt + attachments = self.api.get_server_volumes(server_id) + self.assertEquals([expect_attach], attachments) + + # Should be able to get details + attachment_info = self.api.get_server_volume(server_id, attachment_id) + self.assertEquals(expect_attach, attachment_info) + + # Getting details on a different id should fail + self.assertRaises(client.OpenStackApiNotFoundException, + self.api.get_server_volume, server_id, 3405691582) + self.assertRaises(client.OpenStackApiNotFoundException, + self.api.get_server_volume, + 3405691582, attachment_id) + + # Trying to detach a different id should fail + self.assertRaises(client.OpenStackApiNotFoundException, + self.api.delete_server_volume, server_id, 3405691582) + + # Detach should work + self.api.delete_server_volume(server_id, attachment_id) + + # Again, it's async, so wait... + retries = 0 + while True: + try: + attachment = self.api.get_server_volume(server_id, + attachment_id) + LOG.debug("Attachment still there: %s" % attachment) + except client.OpenStackApiNotFoundException: + LOG.debug("Got 404, delete done") + break + + time.sleep(1) + retries = retries + 1 + self.assertTrue(retries < 10) + + # Should be no attachments again + attachments = self.api.get_server_volumes(server_id) + self.assertEquals([], attachments) + + LOG.debug("Logs: %s" % driver.LoggingVolumeDriver.all_logs()) + + # Discover_volume and undiscover_volume are called from compute + # on attach/detach + + disco_moves = driver.LoggingVolumeDriver.logs_like( + 'discover_volume', + id=volume_id) + LOG.debug("discover_volume actions: %s" % disco_moves) + + self.assertEquals(1, len(disco_moves)) + disco_move = disco_moves[0] + self.assertEquals(disco_move['id'], volume_id) + + last_days_of_disco_moves = driver.LoggingVolumeDriver.logs_like( + 'undiscover_volume', + id=volume_id) + LOG.debug("undiscover_volume actions: %s" % last_days_of_disco_moves) + + self.assertEquals(1, len(last_days_of_disco_moves)) + undisco_move = last_days_of_disco_moves[0] + self.assertEquals(undisco_move['id'], volume_id) + self.assertEquals(undisco_move['mountpoint'], device) + self.assertEquals(undisco_move['instance_id'], server_id) + if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/nova/volume/driver.py b/nova/volume/driver.py index 148e5facd..045974fa3 100644 --- a/nova/volume/driver.py +++ b/nova/volume/driver.py @@ -135,7 +135,7 @@ class VolumeDriver(object): """Removes an export for a logical volume.""" raise NotImplementedError() - def discover_volume(self, volume): + def discover_volume(self, context, volume): """Discover volume on a remote host.""" raise NotImplementedError() @@ -574,6 +574,8 @@ class RBDDriver(VolumeDriver): def discover_volume(self, volume): """Discover volume on a remote host""" + #NOTE(justinsb): This is messed up... discover_volume takes 3 args + # but then that would break local_path return "rbd:%s/%s" % (FLAGS.rbd_pool, volume['name']) def undiscover_volume(self, volume): @@ -622,7 +624,7 @@ class SheepdogDriver(VolumeDriver): """Removes an export for a logical volume""" pass - def discover_volume(self, volume): + def discover_volume(self, context, volume): """Discover volume on a remote host""" return "sheepdog:%s" % volume['name'] @@ -656,7 +658,7 @@ class LoggingVolumeDriver(VolumeDriver): def remove_export(self, context, volume): self.log_action('remove_export', volume) - def discover_volume(self, volume): + def discover_volume(self, context, volume): self.log_action('discover_volume', volume) def undiscover_volume(self, volume): @@ -667,6 +669,10 @@ class LoggingVolumeDriver(VolumeDriver): _LOGS = [] + @staticmethod + def clear_logs(): + LoggingVolumeDriver._LOGS = [] + @staticmethod def log_action(action, parameters): """Logs the command.""" -- cgit From d49219f8b6dd626b868b99bee8a22c4ac5495af1 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 24 Mar 2011 03:28:59 -0700 Subject: pep8 fixes --- nova/api/openstack/__init__.py | 1 + nova/api/openstack/volume_attachments.py | 10 +++++----- nova/tests/integrated/api/client.py | 2 +- nova/tests/integrated/test_volumes.py | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index e8aa4821b..030974482 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -141,6 +141,7 @@ class APIRouter(wsgi.Router): super(APIRouter, self).__init__(mapper) + class APIRouterV10(APIRouter): """Define routes specific to OpenStack API V1.0.""" diff --git a/nova/api/openstack/volume_attachments.py b/nova/api/openstack/volume_attachments.py index 2ce681e19..58a9a727b 100644 --- a/nova/api/openstack/volume_attachments.py +++ b/nova/api/openstack/volume_attachments.py @@ -62,17 +62,17 @@ def _translate_summary_view(context, vol): class Controller(wsgi.Controller): """ The volume attachment API controller for the Openstack API - + A child resource of the server. Note that we use the volume id as the ID of the attachment (though this is not guaranteed externally)""" _serialization_metadata = { 'application/xml': { 'attributes': { - 'volumeAttachment': [ 'id', - 'serverId', - 'volumeId', - 'device' ]}}} + 'volumeAttachment': ['id', + 'serverId', + 'volumeId', + 'device']}}} def __init__(self): self.compute_api = compute.API() diff --git a/nova/tests/integrated/api/client.py b/nova/tests/integrated/api/client.py index deb7fd981..023871bda 100644 --- a/nova/tests/integrated/api/client.py +++ b/nova/tests/integrated/api/client.py @@ -226,7 +226,7 @@ class TestOpenStackClient(object): def get_server_volume(self, server_id, attachment_id): return self.api_get('/servers/%s/volume_attachments/%s' % (server_id, attachment_id))['volumeAttachment'] - + def get_server_volumes(self, server_id): return self.api_get('/servers/%s/volume_attachments' % (server_id))['volumeAttachments'] diff --git a/nova/tests/integrated/test_volumes.py b/nova/tests/integrated/test_volumes.py index f69361fb0..aa90301a5 100644 --- a/nova/tests/integrated/test_volumes.py +++ b/nova/tests/integrated/test_volumes.py @@ -159,8 +159,8 @@ class VolumesTest(integrated_helpers._IntegratedTestBase): # Template attach request device = '/dev/sdc' - attach_req = { 'device': device } - post_req = { 'volumeAttachment': attach_req } + attach_req = {'device': device} + post_req = {'volumeAttachment': attach_req} # Try to attach to a non-existent volume; should fail attach_req['volumeId'] = 3405691582 -- cgit From bebc9504bb34934147705512413267d1ae4af170 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 24 Mar 2011 04:02:31 -0700 Subject: Fake out network service as well, otherwise we can't terminate the instance in test_servers now that we've started a compute service --- nova/tests/integrated/integrated_helpers.py | 17 ++++++++++++++--- nova/tests/integrated/test_login.py | 1 - nova/tests/integrated/test_servers.py | 7 ++++--- nova/tests/integrated/test_volumes.py | 11 ++++++----- nova/virt/fake.py | 8 ++++++++ 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/nova/tests/integrated/integrated_helpers.py b/nova/tests/integrated/integrated_helpers.py index b520cc5d3..3b7caecd6 100644 --- a/nova/tests/integrated/integrated_helpers.py +++ b/nova/tests/integrated/integrated_helpers.py @@ -128,6 +128,7 @@ class IntegratedUnitTestContext(object): self._start_compute_service() self._start_volume_service() self._start_scheduler_service() + self._start_network_service() # WSGI shutdown broken :-( # bug731668 @@ -140,6 +141,12 @@ class IntegratedUnitTestContext(object): self.services.append(compute_service) return compute_service + def _start_network_service(self): + network_service = service.Service.create(binary='nova-network') + network_service.start() + self.services.append(network_service) + return network_service + def _start_volume_service(self): volume_service = service.Service.create(binary='nova-volume') volume_service.start() @@ -236,7 +243,8 @@ class _IntegratedTestBase(test.TestCase): def setUp(self): super(_IntegratedTestBase, self).setUp() - self._setup_flags() + f = self._get_flags() + self.flags(**f) context = IntegratedUnitTestContext.startup() self.user = context.test_user @@ -246,9 +254,12 @@ class _IntegratedTestBase(test.TestCase): IntegratedUnitTestContext.shutdown() super(_IntegratedTestBase, self).tearDown() - def _setup_flags(self): + def _get_flags(self): """An opportunity to setup flags, before the services are started""" - pass + f = {} + #f['network_driver'] = 'nova.network.fake.FakeNetworkDriver' + f['fake_network'] = True + return f def _build_minimal_create_server_request(self): server = {} diff --git a/nova/tests/integrated/test_login.py b/nova/tests/integrated/test_login.py index cc3d555d0..d6e067c29 100644 --- a/nova/tests/integrated/test_login.py +++ b/nova/tests/integrated/test_login.py @@ -18,7 +18,6 @@ import unittest from nova import flags -from nova import test from nova.log import logging from nova.tests.integrated import integrated_helpers from nova.tests.integrated.api import client diff --git a/nova/tests/integrated/test_servers.py b/nova/tests/integrated/test_servers.py index 2b5d3324a..ed6522c38 100644 --- a/nova/tests/integrated/test_servers.py +++ b/nova/tests/integrated/test_servers.py @@ -19,7 +19,6 @@ import time import unittest from nova import flags -from nova import test from nova.log import logging from nova.tests.integrated import integrated_helpers from nova.tests.integrated.api import client @@ -32,8 +31,10 @@ FLAGS.verbose = True class ServersTest(integrated_helpers._IntegratedTestBase): - def _setup_flags(self): - self.flags(image_service='nova.image.fake.MockImageService') + def _get_flags(self): + f = super(ServersTest, self)._get_flags() + f['image_service'] = 'nova.image.fake.MockImageService' + return f def test_get_servers(self): """Simple check that listing servers works.""" diff --git a/nova/tests/integrated/test_volumes.py b/nova/tests/integrated/test_volumes.py index aa90301a5..701e9fe3c 100644 --- a/nova/tests/integrated/test_volumes.py +++ b/nova/tests/integrated/test_volumes.py @@ -19,7 +19,6 @@ import unittest import time from nova import flags -from nova import test from nova.log import logging from nova.tests.integrated import integrated_helpers from nova.tests.integrated.api import client @@ -37,10 +36,12 @@ class VolumesTest(integrated_helpers._IntegratedTestBase): super(VolumesTest, self).setUp() driver.LoggingVolumeDriver.clear_logs() - def _setup_flags(self): - self.flags(image_service='nova.image.fake.MockImageService', - volume_driver='nova.volume.driver.LoggingVolumeDriver') - self.flags(use_local_volumes=False) # Avoids calling local_path + def _get_flags(self): + f = super(VolumesTest, self)._get_flags() + f['use_local_volumes'] = False # Avoids calling local_path + f['image_service'] = 'nova.image.fake.MockImageService' + f['volume_driver'] = 'nova.volume.driver.LoggingVolumeDriver' + return f def test_get_volumes(self): """Simple check that listing volumes works""" diff --git a/nova/virt/fake.py b/nova/virt/fake.py index 3a06284a1..505ce0959 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -26,9 +26,13 @@ semantics of real hypervisor connections. """ from nova import exception +from nova import log as logging from nova.compute import power_state +LOG = logging.getLogger('nova.compute.disk') + + def get_connection(_): # The read_only parameter is ignored. return FakeConnection.instance() @@ -244,6 +248,10 @@ class FakeConnection(object): The work will be done asynchronously. This function returns a task that allows the caller to detect when it is complete. """ + key = instance.name + if not key in self.instances: + LOG.warning("Key '%s' not in instances '%s'" % + (key, self.instances)) del self.instances[instance.name] def attach_volume(self, instance_name, device_path, mountpoint): -- cgit From 83b25c2c8214462ab7f6b6ba76efdfba8c1de937 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 24 Mar 2011 04:37:21 -0700 Subject: Grrr... because we're not recycling the API yet, we have to configure flags the first time it's called. --- nova/tests/integrated/integrated_helpers.py | 7 +++++-- nova/tests/integrated/test_volumes.py | 1 - 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/nova/tests/integrated/integrated_helpers.py b/nova/tests/integrated/integrated_helpers.py index 3b7caecd6..953af2e75 100644 --- a/nova/tests/integrated/integrated_helpers.py +++ b/nova/tests/integrated/integrated_helpers.py @@ -19,6 +19,7 @@ Provides common functionality for integrated unit tests """ +import os import random import string @@ -255,9 +256,11 @@ class _IntegratedTestBase(test.TestCase): super(_IntegratedTestBase, self).tearDown() def _get_flags(self): - """An opportunity to setup flags, before the services are started""" + """An opportunity to setup flags, before the services are started + + Warning - this is a bit flaky till the WSGI recycle code lands""" f = {} - #f['network_driver'] = 'nova.network.fake.FakeNetworkDriver' + f['image_service'] = 'nova.image.fake.MockImageService' f['fake_network'] = True return f diff --git a/nova/tests/integrated/test_volumes.py b/nova/tests/integrated/test_volumes.py index 701e9fe3c..f173efea7 100644 --- a/nova/tests/integrated/test_volumes.py +++ b/nova/tests/integrated/test_volumes.py @@ -39,7 +39,6 @@ class VolumesTest(integrated_helpers._IntegratedTestBase): def _get_flags(self): f = super(VolumesTest, self)._get_flags() f['use_local_volumes'] = False # Avoids calling local_path - f['image_service'] = 'nova.image.fake.MockImageService' f['volume_driver'] = 'nova.volume.driver.LoggingVolumeDriver' return f -- cgit From 1378db7ac86b69b8a966448b63415b2136b6b5bc Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 24 Mar 2011 09:07:57 -0400 Subject: Fix up formatting of libvirt.xml.template --- nova/virt/libvirt.xml.template | 132 ++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index 77c1b1997..26f528cb1 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -3,47 +3,47 @@ ${memory_kb} #if $type == 'lxc' - #set $disk_prefix = '' + #set $disk prefix = '' #set $disk_bus = '' exe /sbin/init #else -#if $type == 'uml' - #set $disk_prefix = 'ubd' - #set $disk_bus = 'uml' - uml - /usr/bin/linux - /dev/ubda -#else - #if $type == 'xen' - #set $disk_prefix = 'sd' - #set $disk_bus = 'scsi' - linux - /dev/xvda - #else - #set $disk_prefix = 'vd' - #set $disk_bus = 'virtio' - hvm - #end if - #if $getVar('rescue', False) - ${basepath}/kernel.rescue - ${basepath}/ramdisk.rescue - #else - #if $getVar('kernel', None) - ${kernel} - #if $type == 'xen' - ro - #else - root=/dev/vda console=ttyS0 - #end if - #if $getVar('ramdisk', None) - ${ramdisk} - #end if - #else - - #end if - #end if - #end if + #if $type == 'uml' + #set $disk_prefix = 'ubd' + #set $disk_bus = 'uml' + uml + /usr/bin/linux + /dev/ubda + #else + #if $type == 'xen' + #set $disk_prefix = 'sd' + #set $disk_bus = 'scsi' + linux + /dev/xvda + #else + #set $disk_prefix = 'vd' + #set $disk_bus = 'virtio' + hvm + #end if + #if $getVar('rescue', False) + ${basepath}/kernel.rescue + ${basepath}/ramdisk.rescue + #else + #if $getVar('kernel', None) + ${kernel} + #if $type == 'xen' + ro + #else + root=/dev/vda console=ttyS0 + #end if + #if $getVar('ramdisk', None) + ${ramdisk} + #end if + #else + + #end if + #end if + #end if #end if @@ -52,36 +52,36 @@ ${vcpus} #if $type == 'lxc' - - - - -#else -#if $getVar('rescue', False) - - - - - - - - - - + + + + #else - - - - - - #if $getVar('local', False) - - - - - - #end if - #end if + #if $getVar('rescue', False) + + + + + + + + + + + #else + + + + + + #if $getVar('local', False) + + + + + + #end if +#end if #end if -- cgit From da159d18b56af44f93cbf2c5e80b6aa3c98d5187 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Thu, 24 Mar 2011 09:12:24 -0400 Subject: Dont use popen in dettaching the lxc loop --- nova/virt/disk.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index f6e6795d6..0bdb04cde 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -140,7 +140,8 @@ def destroy_container(target, instance): container_dir = '%s/rootfs' % target utils.execute('sudo', 'umount', container_dir) finally: - for loop in utils.popen('sudo losetup -a').readlines(): + out, err = utils('sudo', 'losetup', '-a') + for loop in out.splitlines(): if instance['name'] in loop: device = loop.split(loop, ':') utils.execute('sudo', 'losetup', '--detach', device) -- cgit From fa6b969a2a7c9252aaebc4a56d82f9b04e46910c Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Thu, 24 Mar 2011 10:34:34 -0400 Subject: Merged trunk and fixed tests. --- nova/tests/api/openstack/test_images.py | 40 +++++++++++++++------------------ 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index f64ee16a1..3a5d821d3 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -20,6 +20,7 @@ Tests of the new image services, both as a service layer, and as a WSGI layer """ +import copy import json import datetime import os @@ -193,6 +194,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): """ # Registered images at start of each test. now = datetime.datetime.utcnow() + formated_date = now.strftime('%Y-%m-%dT%H:%M:%SZ') IMAGE_FIXTURES = [ {'id': '23g2ogk23k4hhkk4k42l', 'imageId': '23g2ogk23k4hhkk4k42l', @@ -256,13 +258,13 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): actual_image = json.loads(response.body) - expected = self.IMAGE_FIXTURES[0] + expected = copy.copy(self.IMAGE_FIXTURES[0]) expected_image = { "image": { "id": expected["id"], "name": expected["name"], - "updated": expected["updated_at"], - "created": expected["created_at"], + "updated": self.formated_date, + "created": self.formated_date, "status": expected["status"], }, } @@ -275,15 +277,15 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): actual_image = json.loads(response.body) - expected = self.IMAGE_FIXTURES[0] + expected = copy.copy(self.IMAGE_FIXTURES[0]) href = "http://localhost/v1.1/images/%s" % expected["id"] expected_image = { "image": { "id": expected["id"], "name": expected["name"], - "updated": expected["updated_at"], - "created": expected["created_at"], + "updated": self.formated_date, + "created": self.formated_date, "status": expected["status"], "links": [{ "rel": "self", @@ -311,7 +313,9 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): actual_image = parseString(response.body.replace(" ", "")) - expected = self.IMAGE_FIXTURES[0] + expected = copy.copy(self.IMAGE_FIXTURES[0]) + expected["updated_at"] = self.formated_date + expected["created_at"] = self.formated_date expected_image = parseString(""" Date: Thu, 24 Mar 2011 12:15:33 -0400 Subject: Renamed __image and __compute to better describe their purposes. Use os.path.join to create href as per suggestion. Added base get_builder as per pychecker suggestion. --- nova/api/openstack/images.py | 24 ++++++++++++++---------- nova/api/openstack/views/images.py | 4 +++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index dc07348e4..b01d991e8 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -50,8 +50,8 @@ class Controller(wsgi.Controller): """ _default_service = utils.import_object(flags.FLAGS.image_service) - self.__compute = compute_service or compute.API() - self.__image = image_service or _default_service + self._compute_service = compute_service or compute.API() + self._image_service = image_service or _default_service def index(self, req): """ @@ -60,7 +60,7 @@ class Controller(wsgi.Controller): @param req: `wsgi.Request` object """ context = req.environ['nova.context'] - images = self.__image.index(context) + images = self._image_service.index(context) build = self.get_builder(req).build return dict(images=[build(image, False) for image in images]) @@ -71,7 +71,7 @@ class Controller(wsgi.Controller): @param req: `wsgi.Request` object. """ context = req.environ['nova.context'] - images = self.__image.detail(context) + images = self._image_service.detail(context) build = self.get_builder(req).build return dict(images=[build(image, True) for image in images]) @@ -86,7 +86,7 @@ class Controller(wsgi.Controller): context = req.environ['nova.context'] try: - image = self.__image.show(context, image_id) + image = self._image_service.show(context, image_id) except exception.NotFound: ex = webob.exc.HTTPNotFound(explanation="Image not found.") raise faults.Fault(ex) @@ -102,8 +102,8 @@ class Controller(wsgi.Controller): """ image_id = id context = req.environ['nova.context'] - self.__image.delete(context, image_id) - return exc.HTTPNoContent() + self._image_service.delete(context, image_id) + return webob.exc.HTTPNoContent() def create(self, req): """ @@ -116,17 +116,21 @@ class Controller(wsgi.Controller): image = self._deserialize(req.body, content_type) if not image: - raise exc.HTTPBadRequest() + raise webob.exc.HTTPBadRequest() try: server_id = image["image"]["serverId"] image_name = image["image"]["name"] except KeyError: - raise exc.HTTPBadRequest() + raise webob.exc.HTTPBadRequest() - image = self.__compute.snapshot(context, server_id, image_name) + image = self._compute_service.snapshot(context, server_id, image_name) return self.get_builder(req).build(image, True) + def get_builder(self, request): + """Indicates that you must use a Controller subclass.""" + raise NotImplementedError + class ControllerV10(Controller): """ diff --git a/nova/api/openstack/views/images.py b/nova/api/openstack/views/images.py index 9d0bad095..bab1f0bac 100644 --- a/nova/api/openstack/views/images.py +++ b/nova/api/openstack/views/images.py @@ -15,6 +15,8 @@ # License for the specific language governing permissions and limitations # under the License. +import os.path + class ViewBuilder(object): """ @@ -37,7 +39,7 @@ class ViewBuilder(object): """ Return an href string pointing to this object. """ - return "%s/images/%s" % (self._url, image_id) + return os.path.join(self._url, "images", str(image_id)) def build(self, image_obj, detail=False): """ -- cgit From a10f719cdbc666171d8923ae1fd65bac3d6ebda7 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 24 Mar 2011 10:49:19 -0700 Subject: Forgot one set of flags --- nova/tests/integrated/test_servers.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/nova/tests/integrated/test_servers.py b/nova/tests/integrated/test_servers.py index ed6522c38..c4676adc8 100644 --- a/nova/tests/integrated/test_servers.py +++ b/nova/tests/integrated/test_servers.py @@ -31,11 +31,6 @@ FLAGS.verbose = True class ServersTest(integrated_helpers._IntegratedTestBase): - def _get_flags(self): - f = super(ServersTest, self)._get_flags() - f['image_service'] = 'nova.image.fake.MockImageService' - return f - def test_get_servers(self): """Simple check that listing servers works.""" servers = self.api.get_servers() -- cgit From 71bd388a6c04df68e4392dbb7354cc8b14f596fe Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Thu, 24 Mar 2011 15:41:02 -0700 Subject: fix typo --- nova/virt/libvirt.xml.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index bcc6b3aed..ff98275fc 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -102,7 +102,7 @@ #if $getVar('vnc_compute_host_iface', False) - + #end if -- cgit From b01742ddb5bfec7e89ccc4cee17800614a0fce3c Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Thu, 24 Mar 2011 15:55:29 -0700 Subject: incorporate feedback from termie --- bin/nova-vnc-proxy | 5 +- nova/compute/api.py | 15 ++-- nova/compute/manager.py | 2 +- nova/flags.py | 4 +- nova/virt/libvirt.xml.template | 4 +- nova/virt/libvirt_conn.py | 3 +- nova/vnc/auth.py | 22 +++--- nova/vnc/proxy.py | 15 ++-- tools/euca-get-vnc-console | 163 ----------------------------------------- 9 files changed, 36 insertions(+), 197 deletions(-) delete mode 100755 tools/euca-get-vnc-console diff --git a/bin/nova-vnc-proxy b/bin/nova-vnc-proxy index ea2533dc3..e7b647c00 100755 --- a/bin/nova-vnc-proxy +++ b/bin/nova-vnc-proxy @@ -1,5 +1,4 @@ #!/usr/bin/env python -# pylint: disable-msg=C0103 # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2010 United States Government as represented by the @@ -50,7 +49,7 @@ flags.DEFINE_boolean('vnc_debug', False, 'Enable debugging features, like token bypassing') flags.DEFINE_integer('vnc_proxy_port', 6080, 'Port that the VNC proxy should bind to') -flags.DEFINE_string('vnc_proxy_iface', '0.0.0.0', +flags.DEFINE_string('vnc_proxy_host', '0.0.0.0', 'Address that the VNC proxy should bind to') flags.DEFINE_integer('vnc_token_ttl', 300, 'How many seconds before deleting tokens') @@ -90,5 +89,5 @@ if __name__ == "__main__": with_auth = auth.NovaAuthMiddleware(with_logging) server = wsgi.Server() - server.start(with_auth, FLAGS.vnc_proxy_port, host=FLAGS.vnc_proxy_iface) + server.start(with_auth, FLAGS.vnc_proxy_port, host=FLAGS.vnc_proxy_host) server.wait() diff --git a/nova/compute/api.py b/nova/compute/api.py index cec978d75..cb3898f72 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -477,21 +477,22 @@ class API(base.Base): output['token'])} def get_vnc_console(self, context, instance_id): - """Get a url to an AJAX Console""" + """Get a url to a VNC Console.""" instance = self.get(context, instance_id) output = self._call_compute_message('get_vnc_console', context, instance_id) rpc.cast(context, '%s' % FLAGS.vnc_console_proxy_topic, {'method': 'authorize_vnc_console', - 'args': {'token': output['token'], 'host': output['host'], + 'args': {'token': output['token'], + 'host': output['host'], 'port': output['port']}}) - time.sleep(1) - - return {'url': '%s/vnc_auto.html?token=%s&host=%s&port=%s' % - (FLAGS.vnc_console_proxy_url, - output['token'], 'hostignore', 'portignore')} + return {'url': '%s/vnc_auto.html?token=%s&host=%s&port=%s' % ( + FLAGS.vnc_console_proxy_url, + output['token'], + 'hostignore', + 'portignore')} def get_console_output(self, context, instance_id): """Get console output for an an instance""" diff --git a/nova/compute/manager.py b/nova/compute/manager.py index e53b36b34..64982d8ff 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -559,7 +559,7 @@ class ComputeManager(manager.Manager): @exception.wrap_exception def get_vnc_console(self, context, instance_id): - """Return connection information for an vnc console""" + """Return connection information for an vnc console.""" context = context.elevated() LOG.debug(_("instance %s: getting vnc console"), instance_id) instance_ref = self.db.instance_get(context, instance_id) diff --git a/nova/flags.py b/nova/flags.py index a0ea10795..1d2469206 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -287,8 +287,8 @@ DEFINE_string('vnc_console_proxy_url', 'http://127.0.0.1:6080', 'location of vnc console proxy, \ in the form "http://127.0.0.1:6080"') -DEFINE_string('vnc_compute_host_iface', '0.0.0.0', - 'the compute host interface on which vnc server should listen') +DEFINE_string('vnc_server_host', '0.0.0.0', + 'the host interface on which vnc server should listen') DEFINE_bool('vnc_enabled', True, 'enable vnc related features') DEFINE_bool('verbose', False, 'show debug output') diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index ff98275fc..609784982 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -101,8 +101,8 @@ -#if $getVar('vnc_compute_host_iface', False) - +#if $getVar('vnc_server_host', False) + #end if diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index c3529f512..cb6384e01 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -516,6 +516,7 @@ class LibvirtConnection(object): def get_vnc_port_for_instance(instance_name): virt_dom = self._conn.lookupByName(instance_name) xml = virt_dom.XMLDesc(0) + # TODO: use etree instead of minidom dom = minidom.parseString(xml) for graphic in dom.getElementsByTagName('graphics'): @@ -735,7 +736,7 @@ class LibvirtConnection(object): 'driver_type': driver_type} if FLAGS.vnc_enabled: - xml_info['vnc_compute_host_iface'] = FLAGS.vnc_compute_host_iface + xml_info['vnc_server_host'] = FLAGS.vnc_server_host if ra_server: xml_info['ra_server'] = ra_server + "/128" if not rescue: diff --git a/nova/vnc/auth.py b/nova/vnc/auth.py index 676cb2360..1c6a638fc 100644 --- a/nova/vnc/auth.py +++ b/nova/vnc/auth.py @@ -18,11 +18,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Auth Components for VNC Console""" +"""Auth Components for VNC Console.""" import time import urlparse import webob + from webob import Request from nova import flags @@ -32,12 +33,13 @@ from nova import utils from nova import wsgi from nova import vnc + LOG = logging.getLogger('nova.vnc-proxy') FLAGS = flags.FLAGS class NovaAuthMiddleware(object): - """Implementation of Middleware to Handle Nova Auth""" + """Implementation of Middleware to Handle Nova Auth.""" def __init__(self, app): self.app = app @@ -67,13 +69,12 @@ class NovaAuthMiddleware(object): middleware = self middleware.tokens = {} - class Callback: - def __call__(self, data, message): - if data['method'] == 'authorize_vnc_console': - token = data['args']['token'] - LOG.audit(_("Received Token: %s)"), token) - middleware.tokens[token] = \ - {'args': data['args'], 'last_activity_at': time.time()} + def callback(self, data, message): + if data['method'] == 'authorize_vnc_console': + token = data['args']['token'] + LOG.audit(_("Received Token: %s)"), token) + middleware.tokens[token] = \ + {'args': data['args'], 'last_activity_at': time.time()} def delete_expired_tokens(): now = time.time() @@ -90,7 +91,7 @@ class NovaAuthMiddleware(object): consumer = rpc.TopicConsumer( connection=conn, topic=FLAGS.vnc_console_proxy_topic) - consumer.register_callback(Callback()) + consumer.register_callback(callback) utils.LoopingCall(consumer.fetch, auto_ack=True, enable_callbacks=True).start(0.1) @@ -103,7 +104,6 @@ class LoggingMiddleware(object): @webob.dec.wsgify def __call__(self, req): - if req.path == vnc.proxy.WS_ENDPOINT: LOG.info(_("Received Websocket Request: %s"), req.url) else: diff --git a/nova/vnc/proxy.py b/nova/vnc/proxy.py index dea838e3d..49379d9ae 100644 --- a/nova/vnc/proxy.py +++ b/nova/vnc/proxy.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# pylint: disable-msg=C0103 # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2010 United States Government as represented by the @@ -20,11 +19,13 @@ """Eventlet WSGI Services to proxy VNC. No nova deps.""" -from base64 import b64encode, b64decode +import base64 +import os + import eventlet from eventlet import wsgi from eventlet import websocket -import os + from webob import Request import webob @@ -32,7 +33,7 @@ WS_ENDPOINT = '/data' class WebsocketVNCProxy(object): - """Class to proxy from websocket to vnc server""" + """Class to proxy from websocket to vnc server.""" def __init__(self, wwwroot): self.wwwroot = wwwroot @@ -58,7 +59,7 @@ class WebsocketVNCProxy(object): d = source.recv(32384) if d == '': break - d = b64encode(d) + d = base64.b64encode(d) dest.send(d) except: source.close() @@ -70,7 +71,7 @@ class WebsocketVNCProxy(object): d = source.wait() if d is None: break - d = b64decode(d) + d = base64.b64decode(d) dest.sendall(d) except: source.close() @@ -118,7 +119,7 @@ class WebsocketVNCProxy(object): class DebugMiddleware(object): - """Debug middleware. Skip auth, get vnc port and host from query string""" + """Debug middleware. Skip auth, get vnc connect info from query string.""" def __init__(self, app): self.app = app diff --git a/tools/euca-get-vnc-console b/tools/euca-get-vnc-console deleted file mode 100755 index bd2788f03..000000000 --- a/tools/euca-get-vnc-console +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/env python -# pylint: disable-msg=C0103 -# 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. - -"""Euca add-on to use vnc console""" - -import getopt -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) - -import boto -import nova -from boto.ec2.connection import EC2Connection -from euca2ools import Euca2ool, InstanceValidationError, Util, ConnectionFailed - -usage_string = """ -Retrieves a url to an vnc console terminal - -euca-get-vnc-console [-h, --help] [--version] [--debug] instance_id - -REQUIRED PARAMETERS - -instance_id: unique identifier for the instance show the console output for. - -OPTIONAL PARAMETERS - -""" - - -# This class extends boto to add VNCConsole functionality -class NovaEC2Connection(EC2Connection): - - def get_vnc_console(self, instance_id): - """ - Retrieves a console connection for the specified instance. - - :type instance_id: string - :param instance_id: The instance ID of a running instance on the cloud. - - :rtype: :class:`VNCConsole` - """ - - class VNCConsole: - def __init__(self, parent=None): - self.parent = parent - self.instance_id = None - self.url = None - - def startElement(self, name, attrs, connection): - return None - - def endElement(self, name, value, connection): - if name == 'instanceId': - self.instance_id = value - elif name == 'url': - self.url = value - else: - setattr(self, name, value) - - params = {} - return self.get_object('GetVNCConsole', - {'InstanceId': instance_id}, VNCConsole) - - -def override_connect_ec2(aws_access_key_id=None, - aws_secret_access_key=None, **kwargs): - return NovaEC2Connection(aws_access_key_id, - aws_secret_access_key, **kwargs) - -# override boto's connect_ec2 method, so that we can use NovaEC2Connection -boto.connect_ec2 = override_connect_ec2 - - -def usage(status=1): - print usage_string - Util().usage() - sys.exit(status) - - -def version(): - print Util().version() - sys.exit() - - -def display_console_output(console_output): - print console_output.instance_id - print console_output.timestamp - print console_output.output - - -def display_vnc_console_output(console_output): - print console_output.url - - -def main(): - try: - euca = Euca2ool() - except Exception, e: - print e - usage() - - instance_id = None - - for name, value in euca.opts: - if name in ('-h', '--help'): - usage(0) - elif name == '--version': - version() - elif name == '--debug': - debug = True - - for arg in euca.args: - instance_id = arg - break - - if instance_id: - try: - euca.validate_instance_id(instance_id) - except InstanceValidationError: - print 'Invalid instance id' - sys.exit(1) - - try: - euca_conn = euca.make_connection() - except ConnectionFailed, e: - print e.message - sys.exit(1) - try: - console_output = euca_conn.get_vnc_console(instance_id) - except Exception, ex: - euca.display_error_and_exit('%s' % ex) - - display_vnc_console_output(console_output) - else: - print 'instance_id must be specified' - usage() - -if __name__ == "__main__": - main() -- cgit From 3d06c636537374557ee6ff77b7c0bc7718eafcdb Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Thu, 24 Mar 2011 18:59:11 -0400 Subject: Added detail keywork and i18n as per suggestions. --- nova/api/openstack/images.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index b01d991e8..be33bb656 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -62,7 +62,7 @@ class Controller(wsgi.Controller): context = req.environ['nova.context'] images = self._image_service.index(context) build = self.get_builder(req).build - return dict(images=[build(image, False) for image in images]) + return dict(images=[build(image, detail=False) for image in images]) def detail(self, req): """ @@ -73,7 +73,7 @@ class Controller(wsgi.Controller): context = req.environ['nova.context'] images = self._image_service.detail(context) build = self.get_builder(req).build - return dict(images=[build(image, True) for image in images]) + return dict(images=[build(image, detail=True) for image in images]) def show(self, req, id): """ @@ -88,10 +88,10 @@ class Controller(wsgi.Controller): try: image = self._image_service.show(context, image_id) except exception.NotFound: - ex = webob.exc.HTTPNotFound(explanation="Image not found.") + ex = webob.exc.HTTPNotFound(explanation=_("Image not found.")) raise faults.Fault(ex) - return dict(image=self.get_builder(req).build(image, True)) + return dict(image=self.get_builder(req).build(image, detail=True)) def delete(self, req, id): """ @@ -125,7 +125,7 @@ class Controller(wsgi.Controller): raise webob.exc.HTTPBadRequest() image = self._compute_service.snapshot(context, server_id, image_name) - return self.get_builder(req).build(image, True) + return self.get_builder(req).build(image, detail=True) def get_builder(self, request): """Indicates that you must use a Controller subclass.""" -- cgit From f2f08a5b0309876bb312c9124e75bd89331c4816 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Thu, 24 Mar 2011 17:04:55 -0700 Subject: make everything work with trunk again --- nova/api/ec2/cloud.py | 2 +- nova/virt/libvirt_conn.py | 2 +- nova/vnc/auth.py | 20 +++++++++++--------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 6b08f98c2..eb0428c2c 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -538,7 +538,7 @@ class CloudController(object): def get_vnc_console(self, context, instance_id, **kwargs): ec2_id = instance_id - instance_id = ec2_id_to_id(ec2_id) + instance_id = ec2utils.ec2_id_to_id(ec2_id) return self.compute_api.get_vnc_console(context, instance_id=instance_id) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 9cd0e8ac9..41adbfe27 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -626,7 +626,7 @@ class LibvirtConnection(driver.ComputeDriver): return {'token': token, 'host': host, 'port': port} - _image_sems = {} # FIXME: why is this here? (anthony) + _image_sems = {} # FIXME: why is this here? (anthony) @staticmethod def _cache_image(fn, target, fname, cow=False, *args, **kwargs): diff --git a/nova/vnc/auth.py b/nova/vnc/auth.py index 1c6a638fc..4161f3666 100644 --- a/nova/vnc/auth.py +++ b/nova/vnc/auth.py @@ -69,12 +69,14 @@ class NovaAuthMiddleware(object): middleware = self middleware.tokens = {} - def callback(self, data, message): - if data['method'] == 'authorize_vnc_console': - token = data['args']['token'] + class Proxy(): + @staticmethod + def authorize_vnc_console(context, **kwargs): + data = kwargs + token = kwargs['token'] LOG.audit(_("Received Token: %s)"), token) middleware.tokens[token] = \ - {'args': data['args'], 'last_activity_at': time.time()} + {'args': kwargs, 'last_activity_at': time.time()} def delete_expired_tokens(): now = time.time() @@ -88,12 +90,12 @@ class NovaAuthMiddleware(object): del middleware.tokens[k] conn = rpc.Connection.instance(new=True) - consumer = rpc.TopicConsumer( - connection=conn, - topic=FLAGS.vnc_console_proxy_topic) - consumer.register_callback(callback) + consumer = rpc.TopicAdapterConsumer( + connection=conn, + proxy=Proxy, + topic=FLAGS.vnc_console_proxy_topic) - utils.LoopingCall(consumer.fetch, auto_ack=True, + utils.LoopingCall(consumer.fetch, enable_callbacks=True).start(0.1) utils.LoopingCall(delete_expired_tokens).start(1) -- cgit From 06c0eff8ec7eef33933da9bd8adbf7b70a977889 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Thu, 24 Mar 2011 17:44:27 -0700 Subject: add hook for osapi --- nova/api/ec2/cloud.py | 1 + nova/api/openstack/servers.py | 10 ++++++++++ nova/vnc/auth.py | 4 ++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index eb0428c2c..fa4624ff1 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -537,6 +537,7 @@ class CloudController(object): instance_id=instance_id) def get_vnc_console(self, context, instance_id, **kwargs): + """Returns vnc browser url to the dashboard.""" ec2_id = instance_id instance_id = ec2utils.ec2_id_to_id(ec2_id) return self.compute_api.get_vnc_console(context, diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 0dad46268..88cc790c1 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -481,6 +481,16 @@ class Controller(wsgi.Controller): return faults.Fault(exc.HTTPNotFound()) return exc.HTTPAccepted() + @scheduler_api.redirect_handler + def get_vnc_console(self, req, id): + """ Returns a url to an instance's ajaxterm console. """ + try: + self.compute_api.get_vnc_console(req.environ['nova.context'], + int(id)) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + return exc.HTTPAccepted() + @scheduler_api.redirect_handler def diagnostics(self, req, id): """Permit Admins to retrieve server diagnostics.""" diff --git a/nova/vnc/auth.py b/nova/vnc/auth.py index 4161f3666..dff9b376f 100644 --- a/nova/vnc/auth.py +++ b/nova/vnc/auth.py @@ -69,7 +69,7 @@ class NovaAuthMiddleware(object): middleware = self middleware.tokens = {} - class Proxy(): + class TopicProxy(): @staticmethod def authorize_vnc_console(context, **kwargs): data = kwargs @@ -92,7 +92,7 @@ class NovaAuthMiddleware(object): conn = rpc.Connection.instance(new=True) consumer = rpc.TopicAdapterConsumer( connection=conn, - proxy=Proxy, + proxy=TopicProxy, topic=FLAGS.vnc_console_proxy_topic) utils.LoopingCall(consumer.fetch, -- cgit From b30d5aa17c86bf1487945d8f2b2878644f79999e Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Thu, 24 Mar 2011 18:37:23 -0700 Subject: add documentation --- doc/source/runnova/vncconsole.rst | 76 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 doc/source/runnova/vncconsole.rst diff --git a/doc/source/runnova/vncconsole.rst b/doc/source/runnova/vncconsole.rst new file mode 100644 index 000000000..69f147613 --- /dev/null +++ b/doc/source/runnova/vncconsole.rst @@ -0,0 +1,76 @@ +.. + Copyright 2010-2011 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. + +Getting Started with the VNC Proxy +================================== + +The VNC Proxy is an OpenStack component that allows users of Nova to access +their instances through a websocket enabled browser (like Google Chrome). + +A VNC Connection works like so: + +* User connects over an api and gets a url like http://ip:port/?token=xyz +* User pastes url in browser +* Browser connects to VNC Proxy though a websocket enabled client like noVNC +* VNC Proxy authorizes users token, maps the token to a host and port of an + instance's VNC server +* VNC Proxy initiates connection to VNC server, and continues proxying until + the session ends + + +Configuring the VNC Proxy +------------------------- +nova-vnc-proxy requires a websocket enabled html client to work properly. At +this time, the only tested client is a slightly modified fork of noVNC, which +you can at find git://github.com/sleepsonthefloor/noVNC.git. + +.. todo:: add instruction for installing from package + +noVNC must be in the location specified by --vnc_proxy_wwwroot, which defaults +to /var/lib/nova/noVNC. nova-vnc-proxy will fail to launch until this code +is properly installed. + +By default, nova-vnc-proxy binds 0.0.0.0:6080. This can be configured with: + +* --vnc_proxy_port=[port] +* --vnc_proxy_host=[host] + + +Enabling VNC Consoles in Nova +----------------------------- +At the moment, VNC support is supported only when using libvirt. To enable VNC +Console, configure the following flags: + +* --vnc_console_proxy_url=http://[proxy_host]:[proxy_port] - proxy_port + defaults to 6080. This url must point to nova-vnc-proxy +* --vnc_enabled=[True|False] - defaults to True. If this flag is not set your + instances will launch without vnc support. + + +Getting an instance's VNC Console +--------------------------------- +You can access an instance's VNC Console url in the following methods: + +* Using the direct api: + eg: 'stack --user=admin --project=admin compute get_vnc_console instance_id=1' +* Support for Dashboard, and the Openstack API will be forthcoming + + +Accessing VNC Consoles without a web browser +-------------------------------------------- +At the moment, VNC Consoles are only supported through the web browser, but +more general VNC support is in the works. -- cgit From e722803067e6386e98f29aa867d4cf98ce6e0cc2 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Thu, 24 Mar 2011 18:38:28 -0700 Subject: clarify comment --- nova/api/ec2/cloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index fa4624ff1..e5a957b83 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -537,7 +537,7 @@ class CloudController(object): instance_id=instance_id) def get_vnc_console(self, context, instance_id, **kwargs): - """Returns vnc browser url to the dashboard.""" + """Returns vnc browser url. Used by OS dashboard.""" ec2_id = instance_id instance_id = ec2utils.ec2_id_to_id(ec2_id) return self.compute_api.get_vnc_console(context, -- cgit From 91458f29f8b04407471d9d94a5ad165817f72a43 Mon Sep 17 00:00:00 2001 From: Muneyuki Noguchi Date: Fri, 25 Mar 2011 11:47:17 +0900 Subject: Restore volume state on migration failure. --- nova/compute/manager.py | 19 +++++++++++++++++-- nova/virt/libvirt_conn.py | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 468771f46..356d20285 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1003,7 +1003,7 @@ class ComputeManager(manager.SchedulerDependentManager): "Domain not found: no domain with matching name.\" " "This error can be safely ignored.")) - def recover_live_migration(self, ctxt, instance_ref, host=None): + def recover_live_migration(self, ctxt, instance_ref, host=None, dest=None): """Recovers Instance/volume state from migrating -> running. :param ctxt: security context @@ -1011,6 +1011,7 @@ class ComputeManager(manager.SchedulerDependentManager): :param host: DB column value is updated by this hostname. if none, the host instance currently running is selected. + :param dest: destination host """ @@ -1024,7 +1025,21 @@ class ComputeManager(manager.SchedulerDependentManager): 'host': host}) for volume in instance_ref['volumes']: - self.db.volume_update(ctxt, volume['id'], {'status': 'in-use'}) + volume_id = volume['id'] + self.db.volume_update(ctxt, volume_id, {'status': 'in-use'}) + if dest: + topic = self.db.queue_get_for(ctxt, FLAGS.compute_topic, dest) + rpc.call(ctxt, topic, + {"method": "restore_volume_state", + "args": {'volume_id': volume_id}}) + + def restore_volume_state(self, context, volume_id): + """Restore volume state on migration failure. + + :param context: security context + :param volume_id: nova.db.sqlalchemy.models.Volume.id + """ + self.volume_manager.remove_compute_volume(context, volume_id) def periodic_tasks(self, context=None): """Tasks to be run at a periodic interval.""" diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 2cecb010d..5c6baa36e 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1370,7 +1370,7 @@ class LibvirtConnection(driver.ComputeDriver): FLAGS.live_migration_bandwidth) except Exception: - recover_method(ctxt, instance_ref) + recover_method(ctxt, instance_ref, None, dest) raise # Waiting for completion of live_migration. -- cgit From 9632db75d229eac16970af1dfabbb047c2b71a4e Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Fri, 25 Mar 2011 08:20:56 -0400 Subject: Removed partition from setup_container --- nova/virt/disk.py | 4 ++-- nova/virt/libvirt_conn.py | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index 0bdb04cde..bbdcc8ddf 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -115,13 +115,13 @@ def inject_data(image, key=None, net=None, partition=None, nbd=False): _unlink_device(device, nbd) -def setup_container(image, container_dir=None, partition=None): +def setup_container(image, container_dir=None): """Setup the LXC container It will mount the loopback image to the container directory in order to create the root filesystem for the container """ - nbd = False + nbd = "False" device = _link_device(image, nbd) err = utils.execute('sudo', 'mount', device, container_dir) if err: diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 9fb8ba955..bfb0a75f1 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -798,8 +798,7 @@ class LibvirtConnection(driver.ComputeDriver): if FLAGS.libvirt_type == 'lxc': disk.setup_container(basepath('disk'), - container_dir=container_dir, - partition=target_partition) + container_dir=container_dir) except Exception as e: # This could be a windows image, or a vmdk format disk LOG.warn(_('instance %(inst_name)s: ignoring error injecting' -- cgit From 47b54662c17c7af0bca9cf96dc5d4a498706fe8b Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Fri, 25 Mar 2011 08:37:47 -0400 Subject: Dont always assume qemu --- nova/virt/libvirt_conn.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index bfb0a75f1..840eaceeb 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1053,7 +1053,8 @@ class LibvirtConnection(driver.ComputeDriver): total = 0 for dom_id in self._conn.listDomainsID(): dom = self._conn.lookupByID(dom_id) - total += len(dom.vcpus()[1]) + if dom is None: + total += len(dom.vcpus()[1]) return total def get_memory_mb_used(self): -- cgit From 3d8b55294702b531a570b279fb29db8d4ea104d3 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Fri, 25 Mar 2011 08:52:18 -0400 Subject: Fix up templating --- nova/virt/libvirt.xml.template | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index c2c5384bb..26f528cb1 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -83,24 +83,21 @@ #end if #end if #end if - -#for $nic in $nics - - + + - - - -#if $getVar('nic.extra_params', False) - ${nic.extra_params} + + + +#if $getVar('extra_params', False) + ${extra_params} #end if -#if $getVar('nic.gateway_v6', False) - +#if $getVar('gateway_v6', False) + #end if -#end for -- cgit From 6ce4f9c6ae00138184e79cdcfb6f78fc3474580e Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Fri, 25 Mar 2011 08:52:54 -0400 Subject: Fix up destroy container --- nova/virt/disk.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index bbdcc8ddf..b9a8fb7e7 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -140,7 +140,7 @@ def destroy_container(target, instance): container_dir = '%s/rootfs' % target utils.execute('sudo', 'umount', container_dir) finally: - out, err = utils('sudo', 'losetup', '-a') + out, err = utils.execute('sudo', 'losetup', '-a') for loop in out.splitlines(): if instance['name'] in loop: device = loop.split(loop, ':') -- cgit From c8fb0c5a16852afc98349edf89bb31afac166749 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Fri, 25 Mar 2011 09:39:20 -0400 Subject: Revert dom check --- nova/virt/libvirt_conn.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 840eaceeb..bfb0a75f1 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1053,8 +1053,7 @@ class LibvirtConnection(driver.ComputeDriver): total = 0 for dom_id in self._conn.listDomainsID(): dom = self._conn.lookupByID(dom_id) - if dom is None: - total += len(dom.vcpus()[1]) + total += len(dom.vcpus()[1]) return total def get_memory_mb_used(self): -- cgit From ec524aae3224a806fa41f6ae6c2975a1ba124f15 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Fri, 25 Mar 2011 15:18:57 +0100 Subject: Toss an __init__ in the test extensions dir. This gets it included in the tarball. --- nova/tests/api/openstack/extensions/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 nova/tests/api/openstack/extensions/__init__.py diff --git a/nova/tests/api/openstack/extensions/__init__.py b/nova/tests/api/openstack/extensions/__init__.py new file mode 100644 index 000000000..e69de29bb -- cgit From af8aa36ca07c5e51016df68c0acc7449378fac2f Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Fri, 25 Mar 2011 18:23:36 +0100 Subject: Add license and copyright to nova/tests/api/openstack/extensions/__init__.py --- nova/tests/api/openstack/extensions/__init__.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/nova/tests/api/openstack/extensions/__init__.py b/nova/tests/api/openstack/extensions/__init__.py index e69de29bb..848908a95 100644 --- a/nova/tests/api/openstack/extensions/__init__.py +++ b/nova/tests/api/openstack/extensions/__init__.py @@ -0,0 +1,15 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. -- cgit From 51c07f77686473bc73c700aacc7baeecf278a948 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Fri, 25 Mar 2011 16:57:21 -0400 Subject: Removed print. --- nova/tests/api/openstack/test_images.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index b51a52cfe..3bf710d1a 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -642,7 +642,6 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): def test_get_image_found(self): req = webob.Request.blank('/v1.0/images/123') res = req.get_response(fakes.wsgi_app()) - print self.fixtures image_meta = json.loads(res.body)['image'] expected = {'id': 123, 'name': 'public image', 'updated': self.NOW_API_FORMAT, -- cgit From cd1bac4deff367131d43f87cdfbc3b6b34bbdc1e Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Fri, 25 Mar 2011 16:39:43 -0700 Subject: Initial extensification of volumes --- nova/api/openstack/__init__.py | 10 -- nova/api/openstack/extensions.py | 151 ++++++++++++++--- nova/api/openstack/incubator/__init__.py | 20 +++ nova/api/openstack/incubator/volumes/__init__.py | 18 ++ .../incubator/volumes/volume_attachments.py | 181 +++++++++++++++++++++ nova/api/openstack/incubator/volumes/volumes.py | 160 ++++++++++++++++++ .../api/openstack/incubator/volumes/volumes_ext.py | 55 +++++++ nova/api/openstack/volume_attachments.py | 181 --------------------- nova/api/openstack/volumes.py | 160 ------------------ nova/tests/api/openstack/extensions/foxinsocks.py | 98 ----------- .../openstack/extensions/foxinsocks/__init__.py | 19 +++ .../openstack/extensions/foxinsocks/foxinsocks.py | 98 +++++++++++ 12 files changed, 682 insertions(+), 469 deletions(-) create mode 100644 nova/api/openstack/incubator/__init__.py create mode 100644 nova/api/openstack/incubator/volumes/__init__.py create mode 100644 nova/api/openstack/incubator/volumes/volume_attachments.py create mode 100644 nova/api/openstack/incubator/volumes/volumes.py create mode 100644 nova/api/openstack/incubator/volumes/volumes_ext.py delete mode 100644 nova/api/openstack/volume_attachments.py delete mode 100644 nova/api/openstack/volumes.py delete mode 100644 nova/tests/api/openstack/extensions/foxinsocks.py create mode 100644 nova/tests/api/openstack/extensions/foxinsocks/__init__.py create mode 100644 nova/tests/api/openstack/extensions/foxinsocks/foxinsocks.py diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 0e5b2a071..731e16a58 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -128,16 +128,6 @@ class APIRouter(wsgi.Router): _limits = limits.LimitsController() mapper.resource("limit", "limits", controller=_limits) - #NOTE(justinsb): volumes is not yet part of the official API - mapper.resource("volume", "volumes", - controller=volumes.Controller(), - collection={'detail': 'GET'}) - - mapper.resource("volume_attachment", "volume_attachments", - controller=volume_attachments.Controller(), - parent_resource=dict(member_name='server', - collection_name='servers')) - super(APIRouter, self).__init__(mapper) diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index 9d98d849a..6a8ce9669 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -1,6 +1,7 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2011 OpenStack LLC. +# Copyright 2011 Justin Santa Barbara # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -16,12 +17,14 @@ # under the License. import imp +import inspect import os import sys import routes import webob.dec import webob.exc +from nova import exception from nova import flags from nova import log as logging from nova import wsgi @@ -34,6 +37,63 @@ LOG = logging.getLogger('extensions') FLAGS = flags.FLAGS +class ExtensionDescriptor(object): + """This is the base class that defines the contract for extensions""" + + def get_name(self): + """The name of the extension + + e.g. 'Fox In Socks' """ + raise NotImplementedError() + + def get_alias(self): + """The alias for the extension + + e.g. 'FOXNSOX'""" + raise NotImplementedError() + + def get_description(self): + """Friendly description for the extension + + e.g. 'The Fox In Socks Extension'""" + raise NotImplementedError() + + def get_namespace(self): + """The XML namespace for the extension + + e.g. 'http://www.fox.in.socks/api/ext/pie/v1.0'""" + raise NotImplementedError() + + def get_updated(self): + """The timestamp when the extension was last updated + + e.g. '2011-01-22T13:25:27-06:00'""" + #NOTE(justinsb): Huh? Isn't this defined by the namespace? + raise NotImplementedError() + + def get_resources(self): + """List of extensions.ResourceExtension extension objects + + Resources define new nouns, and are accessible through URLs""" + resources = [] + return resources + + def get_actions(self): + """List of extensions.ActionExtension extension objects + + Actions are verbs callable from the API""" + actions = [] + return actions + + def get_response_extensions(self): + """List of extensions.ResponseExtension extension objects + + Response extensions are used to insert information into existing + response data""" + response_exts = [] + return response_exts + + class ActionExtensionController(wsgi.Controller): def __init__(self, application): @@ -109,13 +169,10 @@ class ExtensionController(wsgi.Controller): return self._translate(ext) def delete(self, req, id): - raise faults.Fault(exc.HTTPNotFound()) + raise faults.Fault(webob.exc.HTTPNotFound()) def create(self, req): - raise faults.Fault(exc.HTTPNotFound()) - - def delete(self, req, id): - raise faults.Fault(exc.HTTPNotFound()) + raise faults.Fault(webob.exc.HTTPNotFound()) class ExtensionMiddleware(wsgi.Middleware): @@ -235,16 +292,19 @@ class ExtensionMiddleware(wsgi.Middleware): class ExtensionManager(object): """ Load extensions from the configured extension path. - See nova/tests/api/openstack/extensions/foxinsocks.py for an example - extension implementation. + + See nova/tests/api/openstack/extensions/foxinsocks/extension.py for an + example extension implementation. """ def __init__(self, path): LOG.audit(_('Initializing extension manager.')) + self.super_verbose = False + self.path = path self.extensions = {} - self._load_extensions() + self._load_all_extensions() def get_resources(self): """ @@ -300,7 +360,7 @@ class ExtensionManager(object): except AttributeError as ex: LOG.exception(_("Exception loading extension: %s"), unicode(ex)) - def _load_extensions(self): + def _load_all_extensions(self): """ Load extensions from the configured path. The extension name is constructed from the module_name. If your extension module was named @@ -310,23 +370,74 @@ class ExtensionManager(object): See nova/tests/api/openstack/extensions/foxinsocks.py for an example extension implementation. """ - if not os.path.exists(self.path): + self._load_extensions_under_path(self.path) + + incubator_path = os.path.join(os.path.dirname(__file__), "incubator") + self._load_extensions_under_path(incubator_path) + + def _load_extensions_under_path(self, path): + if not os.path.isdir(path): + LOG.warning(_('Extensions directory not found: %s') % path) return - for f in os.listdir(self.path): - LOG.audit(_('Loading extension file: %s'), f) + LOG.debug(_('Looking for extensions in: %s') % path) + + for child in os.listdir(path): + child_path = os.path.join(path, child) + if not os.path.isdir(child_path): + continue + self._load_extension(child_path) + + def _load_extension(self, path): + if not os.path.isdir(path): + return + + for f in os.listdir(path): mod_name, file_ext = os.path.splitext(os.path.split(f)[-1]) - ext_path = os.path.join(self.path, f) - if file_ext.lower() == '.py': - mod = imp.load_source(mod_name, ext_path) - ext_name = mod_name[0].upper() + mod_name[1:] + if file_ext.startswith('_'): + continue + if file_ext.lower() != '.py': + continue + + ext_path = os.path.join(path, f) + if self.super_verbose: + LOG.debug(_('Checking extension file: %s'), ext_path) + + mod = imp.load_source(mod_name, ext_path) + for _name, cls in inspect.getmembers(mod): try: - new_ext = getattr(mod, ext_name)() - self._check_extension(new_ext) - self.extensions[new_ext.get_alias()] = new_ext + if not inspect.isclass(cls): + continue + + #NOTE(justinsb): It seems that python modules aren't great + # If you have two identically named modules, the classes + # from both are mixed in. So name your extension based + # on the alias, not 'extension.py'! + #TODO(justinsb): Any way to work around this? + + if self.super_verbose: + LOG.debug(_('Checking class: %s'), cls) + + if not ExtensionDescriptor in cls.__bases__: + if self.super_verbose: + LOG.debug(_('Not a ExtensionDescriptor: %s'), cls) + continue + + obj = cls() + self._add_extension(obj) except AttributeError as ex: LOG.exception(_("Exception loading extension: %s"), - unicode(ex)) + unicode(ex)) + + def _add_extension(self, ext): + alias = ext.get_alias() + LOG.audit(_('Loaded extension: %s'), alias) + + self._check_extension(ext) + + if alias in self.extensions: + raise exception.Error("Found duplicate extension: %s" % alias) + self.extensions[alias] = ext class ResponseExtension(object): diff --git a/nova/api/openstack/incubator/__init__.py b/nova/api/openstack/incubator/__init__.py new file mode 100644 index 000000000..cded38174 --- /dev/null +++ b/nova/api/openstack/incubator/__init__.py @@ -0,0 +1,20 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License.import datetime + +"""Incubator contains extensions that are shipped with nova. + +It can't be called 'extensions' because that causes namespacing problems.""" diff --git a/nova/api/openstack/incubator/volumes/__init__.py b/nova/api/openstack/incubator/volumes/__init__.py new file mode 100644 index 000000000..2a9c93210 --- /dev/null +++ b/nova/api/openstack/incubator/volumes/__init__.py @@ -0,0 +1,18 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License.import datetime + +"""The volumes extension adds volumes and attachments to the API.""" diff --git a/nova/api/openstack/incubator/volumes/volume_attachments.py b/nova/api/openstack/incubator/volumes/volume_attachments.py new file mode 100644 index 000000000..58a9a727b --- /dev/null +++ b/nova/api/openstack/incubator/volumes/volume_attachments.py @@ -0,0 +1,181 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from webob import exc + +from nova import compute +from nova import exception +from nova import flags +from nova import log as logging +from nova import volume +from nova import wsgi +from nova.api.openstack import common +from nova.api.openstack import faults + + +LOG = logging.getLogger("nova.api.volumes") + +FLAGS = flags.FLAGS + + +def _translate_detail_view(context, volume): + """ Maps keys for details view""" + + d = _translate_summary_view(context, volume) + + # No additional data / lookups at the moment + + return d + + +def _translate_summary_view(context, vol): + """ Maps keys for summary view""" + d = {} + + volume_id = vol['id'] + + # NOTE(justinsb): We use the volume id as the id of the attachment object + d['id'] = volume_id + + d['volumeId'] = volume_id + if vol.get('instance_id'): + d['serverId'] = vol['instance_id'] + if vol.get('mountpoint'): + d['device'] = vol['mountpoint'] + + return d + + +class Controller(wsgi.Controller): + """ The volume attachment API controller for the Openstack API + + A child resource of the server. Note that we use the volume id + as the ID of the attachment (though this is not guaranteed externally)""" + + _serialization_metadata = { + 'application/xml': { + 'attributes': { + 'volumeAttachment': ['id', + 'serverId', + 'volumeId', + 'device']}}} + + def __init__(self): + self.compute_api = compute.API() + self.volume_api = volume.API() + super(Controller, self).__init__() + + def index(self, req, server_id): + """ Returns the list of volume attachments for a given instance """ + return self._items(req, server_id, + entity_maker=_translate_summary_view) + + def show(self, req, server_id, id): + """Return data about the given volume""" + context = req.environ['nova.context'] + + volume_id = id + try: + vol = self.volume_api.get(context, volume_id) + except exception.NotFound: + LOG.debug("volume_id not found") + return faults.Fault(exc.HTTPNotFound()) + + if str(vol['instance_id']) != server_id: + LOG.debug("instance_id != server_id") + return faults.Fault(exc.HTTPNotFound()) + + return {'volumeAttachment': _translate_detail_view(context, vol)} + + def create(self, req, server_id): + """ Attach a volume to an instance """ + context = req.environ['nova.context'] + + env = self._deserialize(req.body, req.get_content_type()) + if not env: + return faults.Fault(exc.HTTPUnprocessableEntity()) + + instance_id = server_id + volume_id = env['volumeAttachment']['volumeId'] + device = env['volumeAttachment']['device'] + + msg = _("Attach volume %(volume_id)s to instance %(server_id)s" + " at %(device)s") % locals() + LOG.audit(msg, context=context) + + try: + self.compute_api.attach_volume(context, + instance_id=instance_id, + volume_id=volume_id, + device=device) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + # The attach is async + attachment = {} + attachment['id'] = volume_id + attachment['volumeId'] = volume_id + + # NOTE(justinsb): And now, we have a problem... + # The attach is async, so there's a window in which we don't see + # the attachment (until the attachment completes). We could also + # get problems with concurrent requests. I think we need an + # attachment state, and to write to the DB here, but that's a bigger + # change. + # For now, we'll probably have to rely on libraries being smart + + # TODO: How do I return "accepted" here?? + return {'volumeAttachment': attachment} + + def update(self, _req, _server_id, _id): + """ Update a volume attachment. We don't currently support this.""" + return faults.Fault(exc.HTTPBadRequest()) + + def delete(self, req, server_id, id): + """ Detach a volume from an instance """ + context = req.environ['nova.context'] + + volume_id = id + LOG.audit(_("Detach volume %s"), volume_id, context=context) + + try: + vol = self.volume_api.get(context, volume_id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + if str(vol['instance_id']) != server_id: + LOG.debug("instance_id != server_id") + return faults.Fault(exc.HTTPNotFound()) + + self.compute_api.detach_volume(context, + volume_id=volume_id) + + return exc.HTTPAccepted() + + def _items(self, req, server_id, entity_maker): + """Returns a list of attachments, transformed through entity_maker""" + context = req.environ['nova.context'] + + try: + instance = self.compute_api.get(context, server_id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + volumes = instance['volumes'] + limited_list = common.limited(volumes, req) + res = [entity_maker(context, vol) for vol in limited_list] + return {'volumeAttachments': res} diff --git a/nova/api/openstack/incubator/volumes/volumes.py b/nova/api/openstack/incubator/volumes/volumes.py new file mode 100644 index 000000000..ec3b9a6c8 --- /dev/null +++ b/nova/api/openstack/incubator/volumes/volumes.py @@ -0,0 +1,160 @@ +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from webob import exc + +from nova import exception +from nova import flags +from nova import log as logging +from nova import volume +from nova import wsgi +from nova.api.openstack import common +from nova.api.openstack import faults + + +LOG = logging.getLogger("nova.api.volumes") + +FLAGS = flags.FLAGS + + +def _translate_detail_view(context, vol): + """ Maps keys for details view""" + + d = _translate_summary_view(context, vol) + + # No additional data / lookups at the moment + + return d + + +def _translate_summary_view(_context, vol): + """ Maps keys for summary view""" + d = {} + + instance_id = None + # instance_data = None + attached_to = vol.get('instance') + if attached_to: + instance_id = attached_to['id'] + # instance_data = '%s[%s]' % (instance_ec2_id, + # attached_to['host']) + d['id'] = vol['id'] + d['status'] = vol['status'] + d['size'] = vol['size'] + d['availabilityZone'] = vol['availability_zone'] + d['createdAt'] = vol['created_at'] + # if context.is_admin: + # v['status'] = '%s (%s, %s, %s, %s)' % ( + # vol['status'], + # vol['user_id'], + # vol['host'], + # instance_data, + # vol['mountpoint']) + if vol['attach_status'] == 'attached': + d['attachments'] = [{'attachTime': vol['attach_time'], + 'deleteOnTermination': False, + 'mountpoint': vol['mountpoint'], + 'instanceId': instance_id, + 'status': 'attached', + 'volumeId': vol['id']}] + else: + d['attachments'] = [{}] + + d['displayName'] = vol['display_name'] + d['displayDescription'] = vol['display_description'] + return d + + +class Controller(wsgi.Controller): + """ The Volumes API controller for the OpenStack API """ + + _serialization_metadata = { + 'application/xml': { + "attributes": { + "volume": [ + "id", + "status", + "size", + "availabilityZone", + "createdAt", + "displayName", + "displayDescription", + ]}}} + + def __init__(self): + self.volume_api = volume.API() + super(Controller, self).__init__() + + def show(self, req, id): + """Return data about the given volume""" + context = req.environ['nova.context'] + + try: + vol = self.volume_api.get(context, id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + return {'volume': _translate_detail_view(context, vol)} + + def delete(self, req, id): + """ Delete a volume """ + context = req.environ['nova.context'] + + LOG.audit(_("Delete volume with id: %s"), id, context=context) + + try: + self.volume_api.delete(context, volume_id=id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + return exc.HTTPAccepted() + + def index(self, req): + """ Returns a summary list of volumes""" + return self._items(req, entity_maker=_translate_summary_view) + + def detail(self, req): + """ Returns a detailed list of volumes """ + return self._items(req, entity_maker=_translate_detail_view) + + def _items(self, req, entity_maker): + """Returns a list of volumes, transformed through entity_maker""" + context = req.environ['nova.context'] + + volumes = self.volume_api.get_all(context) + limited_list = common.limited(volumes, req) + res = [entity_maker(context, vol) for vol in limited_list] + return {'volumes': res} + + def create(self, req): + """Creates a new volume""" + context = req.environ['nova.context'] + + env = self._deserialize(req.body, req.get_content_type()) + if not env: + return faults.Fault(exc.HTTPUnprocessableEntity()) + + vol = env['volume'] + size = vol['size'] + LOG.audit(_("Create volume of %s GB"), size, context=context) + new_volume = self.volume_api.create(context, size, + vol.get('display_name'), + vol.get('display_description')) + + # Work around problem that instance is lazy-loaded... + new_volume['instance'] = None + + retval = _translate_detail_view(context, new_volume) + + return {'volume': retval} diff --git a/nova/api/openstack/incubator/volumes/volumes_ext.py b/nova/api/openstack/incubator/volumes/volumes_ext.py new file mode 100644 index 000000000..87a57320d --- /dev/null +++ b/nova/api/openstack/incubator/volumes/volumes_ext.py @@ -0,0 +1,55 @@ +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from nova.api.openstack import extensions +from nova.api.openstack.incubator.volumes import volumes +from nova.api.openstack.incubator.volumes import volume_attachments + + +class VolumesExtension(extensions.ExtensionDescriptor): + def get_name(self): + return "Volumes" + + def get_alias(self): + return "VOLUMES" + + def get_description(self): + return "Volumes support" + + def get_namespace(self): + return "http://docs.openstack.org/ext/volumes/api/v1.1" + + def get_updated(self): + return "2011-03-25T00:00:00+00:00" + + def get_resources(self): + resources = [] + + #NOTE(justinsb): No way to provide singular name ('volume') + # Does this matter? + res = extensions.ResourceExtension('volumes', + volumes.Controller(), + collection_actions={'detail': 'GET'} + ) + resources.append(res) + + res = extensions.ResourceExtension('volume_attachments', + volume_attachments.Controller(), + parent=dict( + member_name='server', + collection_name='servers')) + resources.append(res) + + return resources diff --git a/nova/api/openstack/volume_attachments.py b/nova/api/openstack/volume_attachments.py deleted file mode 100644 index 58a9a727b..000000000 --- a/nova/api/openstack/volume_attachments.py +++ /dev/null @@ -1,181 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2011 Justin Santa Barbara -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from webob import exc - -from nova import compute -from nova import exception -from nova import flags -from nova import log as logging -from nova import volume -from nova import wsgi -from nova.api.openstack import common -from nova.api.openstack import faults - - -LOG = logging.getLogger("nova.api.volumes") - -FLAGS = flags.FLAGS - - -def _translate_detail_view(context, volume): - """ Maps keys for details view""" - - d = _translate_summary_view(context, volume) - - # No additional data / lookups at the moment - - return d - - -def _translate_summary_view(context, vol): - """ Maps keys for summary view""" - d = {} - - volume_id = vol['id'] - - # NOTE(justinsb): We use the volume id as the id of the attachment object - d['id'] = volume_id - - d['volumeId'] = volume_id - if vol.get('instance_id'): - d['serverId'] = vol['instance_id'] - if vol.get('mountpoint'): - d['device'] = vol['mountpoint'] - - return d - - -class Controller(wsgi.Controller): - """ The volume attachment API controller for the Openstack API - - A child resource of the server. Note that we use the volume id - as the ID of the attachment (though this is not guaranteed externally)""" - - _serialization_metadata = { - 'application/xml': { - 'attributes': { - 'volumeAttachment': ['id', - 'serverId', - 'volumeId', - 'device']}}} - - def __init__(self): - self.compute_api = compute.API() - self.volume_api = volume.API() - super(Controller, self).__init__() - - def index(self, req, server_id): - """ Returns the list of volume attachments for a given instance """ - return self._items(req, server_id, - entity_maker=_translate_summary_view) - - def show(self, req, server_id, id): - """Return data about the given volume""" - context = req.environ['nova.context'] - - volume_id = id - try: - vol = self.volume_api.get(context, volume_id) - except exception.NotFound: - LOG.debug("volume_id not found") - return faults.Fault(exc.HTTPNotFound()) - - if str(vol['instance_id']) != server_id: - LOG.debug("instance_id != server_id") - return faults.Fault(exc.HTTPNotFound()) - - return {'volumeAttachment': _translate_detail_view(context, vol)} - - def create(self, req, server_id): - """ Attach a volume to an instance """ - context = req.environ['nova.context'] - - env = self._deserialize(req.body, req.get_content_type()) - if not env: - return faults.Fault(exc.HTTPUnprocessableEntity()) - - instance_id = server_id - volume_id = env['volumeAttachment']['volumeId'] - device = env['volumeAttachment']['device'] - - msg = _("Attach volume %(volume_id)s to instance %(server_id)s" - " at %(device)s") % locals() - LOG.audit(msg, context=context) - - try: - self.compute_api.attach_volume(context, - instance_id=instance_id, - volume_id=volume_id, - device=device) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - - # The attach is async - attachment = {} - attachment['id'] = volume_id - attachment['volumeId'] = volume_id - - # NOTE(justinsb): And now, we have a problem... - # The attach is async, so there's a window in which we don't see - # the attachment (until the attachment completes). We could also - # get problems with concurrent requests. I think we need an - # attachment state, and to write to the DB here, but that's a bigger - # change. - # For now, we'll probably have to rely on libraries being smart - - # TODO: How do I return "accepted" here?? - return {'volumeAttachment': attachment} - - def update(self, _req, _server_id, _id): - """ Update a volume attachment. We don't currently support this.""" - return faults.Fault(exc.HTTPBadRequest()) - - def delete(self, req, server_id, id): - """ Detach a volume from an instance """ - context = req.environ['nova.context'] - - volume_id = id - LOG.audit(_("Detach volume %s"), volume_id, context=context) - - try: - vol = self.volume_api.get(context, volume_id) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - - if str(vol['instance_id']) != server_id: - LOG.debug("instance_id != server_id") - return faults.Fault(exc.HTTPNotFound()) - - self.compute_api.detach_volume(context, - volume_id=volume_id) - - return exc.HTTPAccepted() - - def _items(self, req, server_id, entity_maker): - """Returns a list of attachments, transformed through entity_maker""" - context = req.environ['nova.context'] - - try: - instance = self.compute_api.get(context, server_id) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - - volumes = instance['volumes'] - limited_list = common.limited(volumes, req) - res = [entity_maker(context, vol) for vol in limited_list] - return {'volumeAttachments': res} diff --git a/nova/api/openstack/volumes.py b/nova/api/openstack/volumes.py deleted file mode 100644 index ec3b9a6c8..000000000 --- a/nova/api/openstack/volumes.py +++ /dev/null @@ -1,160 +0,0 @@ -# Copyright 2011 Justin Santa Barbara -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from webob import exc - -from nova import exception -from nova import flags -from nova import log as logging -from nova import volume -from nova import wsgi -from nova.api.openstack import common -from nova.api.openstack import faults - - -LOG = logging.getLogger("nova.api.volumes") - -FLAGS = flags.FLAGS - - -def _translate_detail_view(context, vol): - """ Maps keys for details view""" - - d = _translate_summary_view(context, vol) - - # No additional data / lookups at the moment - - return d - - -def _translate_summary_view(_context, vol): - """ Maps keys for summary view""" - d = {} - - instance_id = None - # instance_data = None - attached_to = vol.get('instance') - if attached_to: - instance_id = attached_to['id'] - # instance_data = '%s[%s]' % (instance_ec2_id, - # attached_to['host']) - d['id'] = vol['id'] - d['status'] = vol['status'] - d['size'] = vol['size'] - d['availabilityZone'] = vol['availability_zone'] - d['createdAt'] = vol['created_at'] - # if context.is_admin: - # v['status'] = '%s (%s, %s, %s, %s)' % ( - # vol['status'], - # vol['user_id'], - # vol['host'], - # instance_data, - # vol['mountpoint']) - if vol['attach_status'] == 'attached': - d['attachments'] = [{'attachTime': vol['attach_time'], - 'deleteOnTermination': False, - 'mountpoint': vol['mountpoint'], - 'instanceId': instance_id, - 'status': 'attached', - 'volumeId': vol['id']}] - else: - d['attachments'] = [{}] - - d['displayName'] = vol['display_name'] - d['displayDescription'] = vol['display_description'] - return d - - -class Controller(wsgi.Controller): - """ The Volumes API controller for the OpenStack API """ - - _serialization_metadata = { - 'application/xml': { - "attributes": { - "volume": [ - "id", - "status", - "size", - "availabilityZone", - "createdAt", - "displayName", - "displayDescription", - ]}}} - - def __init__(self): - self.volume_api = volume.API() - super(Controller, self).__init__() - - def show(self, req, id): - """Return data about the given volume""" - context = req.environ['nova.context'] - - try: - vol = self.volume_api.get(context, id) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - - return {'volume': _translate_detail_view(context, vol)} - - def delete(self, req, id): - """ Delete a volume """ - context = req.environ['nova.context'] - - LOG.audit(_("Delete volume with id: %s"), id, context=context) - - try: - self.volume_api.delete(context, volume_id=id) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - return exc.HTTPAccepted() - - def index(self, req): - """ Returns a summary list of volumes""" - return self._items(req, entity_maker=_translate_summary_view) - - def detail(self, req): - """ Returns a detailed list of volumes """ - return self._items(req, entity_maker=_translate_detail_view) - - def _items(self, req, entity_maker): - """Returns a list of volumes, transformed through entity_maker""" - context = req.environ['nova.context'] - - volumes = self.volume_api.get_all(context) - limited_list = common.limited(volumes, req) - res = [entity_maker(context, vol) for vol in limited_list] - return {'volumes': res} - - def create(self, req): - """Creates a new volume""" - context = req.environ['nova.context'] - - env = self._deserialize(req.body, req.get_content_type()) - if not env: - return faults.Fault(exc.HTTPUnprocessableEntity()) - - vol = env['volume'] - size = vol['size'] - LOG.audit(_("Create volume of %s GB"), size, context=context) - new_volume = self.volume_api.create(context, size, - vol.get('display_name'), - vol.get('display_description')) - - # Work around problem that instance is lazy-loaded... - new_volume['instance'] = None - - retval = _translate_detail_view(context, new_volume) - - return {'volume': retval} diff --git a/nova/tests/api/openstack/extensions/foxinsocks.py b/nova/tests/api/openstack/extensions/foxinsocks.py deleted file mode 100644 index 0860b51ac..000000000 --- a/nova/tests/api/openstack/extensions/foxinsocks.py +++ /dev/null @@ -1,98 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2011 OpenStack LLC. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import json - -from nova import wsgi - -from nova.api.openstack import extensions - - -class FoxInSocksController(wsgi.Controller): - - def index(self, req): - return "Try to say this Mr. Knox, sir..." - - -class Foxinsocks(object): - - def __init__(self): - pass - - def get_name(self): - return "Fox In Socks" - - def get_alias(self): - return "FOXNSOX" - - def get_description(self): - return "The Fox In Socks Extension" - - def get_namespace(self): - return "http://www.fox.in.socks/api/ext/pie/v1.0" - - def get_updated(self): - return "2011-01-22T13:25:27-06:00" - - def get_resources(self): - resources = [] - resource = extensions.ResourceExtension('foxnsocks', - FoxInSocksController()) - resources.append(resource) - return resources - - def get_actions(self): - actions = [] - actions.append(extensions.ActionExtension('servers', 'add_tweedle', - self._add_tweedle)) - actions.append(extensions.ActionExtension('servers', 'delete_tweedle', - self._delete_tweedle)) - return actions - - def get_response_extensions(self): - response_exts = [] - - def _goose_handler(res): - #NOTE: This only handles JSON responses. - # You can use content type header to test for XML. - data = json.loads(res.body) - data['flavor']['googoose'] = "Gooey goo for chewy chewing!" - return data - - resp_ext = extensions.ResponseExtension('GET', '/v1.1/flavors/:(id)', - _goose_handler) - response_exts.append(resp_ext) - - def _bands_handler(res): - #NOTE: This only handles JSON responses. - # You can use content type header to test for XML. - data = json.loads(res.body) - data['big_bands'] = 'Pig Bands!' - return data - - resp_ext2 = extensions.ResponseExtension('GET', '/v1.1/flavors/:(id)', - _bands_handler) - response_exts.append(resp_ext2) - return response_exts - - def _add_tweedle(self, input_dict, req, id): - - return "Tweedle Beetle Added." - - def _delete_tweedle(self, input_dict, req, id): - - return "Tweedle Beetle Deleted." diff --git a/nova/tests/api/openstack/extensions/foxinsocks/__init__.py b/nova/tests/api/openstack/extensions/foxinsocks/__init__.py new file mode 100644 index 000000000..fe505359d --- /dev/null +++ b/nova/tests/api/openstack/extensions/foxinsocks/__init__.py @@ -0,0 +1,19 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License.import datetime + +"""Example Fox-in-Socks extension.""" diff --git a/nova/tests/api/openstack/extensions/foxinsocks/foxinsocks.py b/nova/tests/api/openstack/extensions/foxinsocks/foxinsocks.py new file mode 100644 index 000000000..442707714 --- /dev/null +++ b/nova/tests/api/openstack/extensions/foxinsocks/foxinsocks.py @@ -0,0 +1,98 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import json + +from nova import wsgi + +from nova.api.openstack import extensions + + +class FoxInSocksController(wsgi.Controller): + + def index(self, req): + return "Try to say this Mr. Knox, sir..." + + +class Foxinsocks(extensions.ExtensionDescriptor): + + def __init__(self): + pass + + def get_name(self): + return "Fox In Socks" + + def get_alias(self): + return "FOXNSOX" + + def get_description(self): + return "The Fox In Socks Extension" + + def get_namespace(self): + return "http://www.fox.in.socks/api/ext/pie/v1.0" + + def get_updated(self): + return "2011-01-22T13:25:27-06:00" + + def get_resources(self): + resources = [] + resource = extensions.ResourceExtension('foxnsocks', + FoxInSocksController()) + resources.append(resource) + return resources + + def get_actions(self): + actions = [] + actions.append(extensions.ActionExtension('servers', 'add_tweedle', + self._add_tweedle)) + actions.append(extensions.ActionExtension('servers', 'delete_tweedle', + self._delete_tweedle)) + return actions + + def get_response_extensions(self): + response_exts = [] + + def _goose_handler(res): + #NOTE: This only handles JSON responses. + # You can use content type header to test for XML. + data = json.loads(res.body) + data['flavor']['googoose'] = "Gooey goo for chewy chewing!" + return data + + resp_ext = extensions.ResponseExtension('GET', '/v1.1/flavors/:(id)', + _goose_handler) + response_exts.append(resp_ext) + + def _bands_handler(res): + #NOTE: This only handles JSON responses. + # You can use content type header to test for XML. + data = json.loads(res.body) + data['big_bands'] = 'Pig Bands!' + return data + + resp_ext2 = extensions.ResponseExtension('GET', '/v1.1/flavors/:(id)', + _bands_handler) + response_exts.append(resp_ext2) + return response_exts + + def _add_tweedle(self, input_dict, req, id): + + return "Tweedle Beetle Added." + + def _delete_tweedle(self, input_dict, req, id): + + return "Tweedle Beetle Deleted." -- cgit From 5936449d99b852897fddbbb140465db0ad9a330c Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Fri, 25 Mar 2011 17:48:59 -0700 Subject: Now that it's an extension, it has to be v1.1. Also fixed up all the things that changed in v1.1 --- nova/api/openstack/__init__.py | 2 -- nova/api/openstack/common.py | 5 ++++ nova/tests/integrated/integrated_helpers.py | 21 ++++++++++---- nova/tests/integrated/test_extensions.py | 43 +++++++++++++++++++++++++++++ nova/tests/integrated/test_servers.py | 16 ++++++----- nova/tests/integrated/test_volumes.py | 6 ++++ 6 files changed, 78 insertions(+), 15 deletions(-) create mode 100644 nova/tests/integrated/test_extensions.py diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 731e16a58..7f2bb1155 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -39,8 +39,6 @@ from nova.api.openstack import servers from nova.api.openstack import server_metadata from nova.api.openstack import shared_ip_groups from nova.api.openstack import users -from nova.api.openstack import volumes -from nova.api.openstack import volume_attachments from nova.api.openstack import zones diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py index 8cad1273a..4ab6b7a81 100644 --- a/nova/api/openstack/common.py +++ b/nova/api/openstack/common.py @@ -21,6 +21,10 @@ import webob from nova import exception from nova import flags +from nova import log as logging + + +LOG = logging.getLogger('common') FLAGS = flags.FLAGS @@ -121,4 +125,5 @@ def get_id_from_href(href): try: return int(urlparse(href).path.split('/')[-1]) except: + LOG.debug(_("Error extracting id from href: %s") % href) raise webob.exc.HTTPBadRequest(_('could not parse id from href')) diff --git a/nova/tests/integrated/integrated_helpers.py b/nova/tests/integrated/integrated_helpers.py index 99d597f9a..c64f6945d 100644 --- a/nova/tests/integrated/integrated_helpers.py +++ b/nova/tests/integrated/integrated_helpers.py @@ -196,7 +196,7 @@ class IntegratedUnitTestContext(object): # so we treat it separately self.api_service = api_service - self.auth_url = 'http://localhost:8774/v1.0' + self.auth_url = 'http://localhost:8774/v1.1' return api_service @@ -229,18 +229,27 @@ class _IntegratedTestBase(test.TestCase): server = {} image = self.user.get_valid_image(create=True) - image_id = image['id'] + LOG.debug("Image: %s" % image) - #TODO(justinsb): This is FUBAR - image_id = abs(hash(image_id)) + if 'imageRef' in image: + image_ref = image['imageRef'] + else: + #NOTE(justinsb): The imageRef code hasn't yet landed + LOG.warning("imageRef not yet in images output") + image_ref = image['id'] + + #TODO(justinsb): This is FUBAR + image_ref = abs(hash(image_ref)) + + image_ref = 'http://fake.server/%s' % image_ref # We now have a valid imageId - server['imageId'] = image_id + server['imageRef'] = image_ref # Set a valid flavorId flavor = self.api.get_flavors()[0] LOG.debug("Using flavor: %s" % flavor) - server['flavorId'] = flavor['id'] + server['flavorRef'] = 'http://fake.server/%s' % flavor['id'] # Set a valid server name server_name = self.user.get_unused_server_name() diff --git a/nova/tests/integrated/test_extensions.py b/nova/tests/integrated/test_extensions.py new file mode 100644 index 000000000..39906e8d0 --- /dev/null +++ b/nova/tests/integrated/test_extensions.py @@ -0,0 +1,43 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import os + +from nova import flags +from nova.log import logging +from nova.tests.integrated import integrated_helpers + + +LOG = logging.getLogger('nova.tests.integrated') + +FLAGS = flags.FLAGS +FLAGS.verbose = True + + +class ExtensionsTest(integrated_helpers._IntegratedTestBase): + def _get_flags(self): + f = super(ExtensionsTest, self)._get_flags() + f['osapi_extensions_path'] = os.path.join(os.path.dirname(__file__), + "../api/openstack/extensions") + return f + + def test_get_foxnsocks(self): + """Simple check that fox-n-socks works""" + response = self.api.api_request('/foxnsocks') + foxnsocks = response.read() + LOG.debug("foxnsocks: %s" % foxnsocks) + self.assertEqual('Try to say this Mr. Knox, sir...', foxnsocks) diff --git a/nova/tests/integrated/test_servers.py b/nova/tests/integrated/test_servers.py index c4676adc8..a0a6e333a 100644 --- a/nova/tests/integrated/test_servers.py +++ b/nova/tests/integrated/test_servers.py @@ -48,27 +48,29 @@ class ServersTest(integrated_helpers._IntegratedTestBase): post = {'server': server} - # Without an imageId, this throws 500. + # Without an imageRef, this throws 500. # TODO(justinsb): Check whatever the spec says should be thrown here self.assertRaises(client.OpenStackApiException, self.api.post_server, post) - # With an invalid imageId, this throws 500. - server['imageId'] = self.user.get_invalid_image() + # With an invalid imageRef, this throws 500. + server['imageRef'] = self.user.get_invalid_image() # TODO(justinsb): Check whatever the spec says should be thrown here self.assertRaises(client.OpenStackApiException, self.api.post_server, post) - # Add a valid imageId - server['imageId'] = good_server['imageId'] + # Add a valid imageId/imageRef + server['imageId'] = good_server.get('imageId') + server['imageRef'] = good_server.get('imageRef') # Without flavorId, this throws 500 # TODO(justinsb): Check whatever the spec says should be thrown here self.assertRaises(client.OpenStackApiException, self.api.post_server, post) - # Set a valid flavorId - server['flavorId'] = good_server['flavorId'] + # Set a valid flavorId/flavorRef + server['flavorRef'] = good_server.get('flavorRef') + server['flavorId'] = good_server.get('flavorId') # Without a name, this throws 500 # TODO(justinsb): Check whatever the spec says should be thrown here diff --git a/nova/tests/integrated/test_volumes.py b/nova/tests/integrated/test_volumes.py index f173efea7..9ddfe85f7 100644 --- a/nova/tests/integrated/test_volumes.py +++ b/nova/tests/integrated/test_volumes.py @@ -42,6 +42,12 @@ class VolumesTest(integrated_helpers._IntegratedTestBase): f['volume_driver'] = 'nova.volume.driver.LoggingVolumeDriver' return f + def test_get_volumes_summary(self): + """Simple check that listing volumes works""" + volumes = self.api.get_volumes(False) + for volume in volumes: + LOG.debug("volume: %s" % volume) + def test_get_volumes(self): """Simple check that listing volumes works""" volumes = self.api.get_volumes() -- cgit From a78c1bd3e862700dbab68cc5011197270abd4b38 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Fri, 25 Mar 2011 21:46:14 -0400 Subject: Replaced import of an object with module import as per suggestion. --- nova/tests/api/openstack/test_images.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index 3bf710d1a..5279ca77c 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -26,8 +26,7 @@ import datetime import os import shutil import tempfile - -from xml.dom.minidom import parseString +import xml.dom.minidom as minidom import stubout import webob @@ -326,10 +325,10 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): request.accept = "application/xml" response = request.get_response(fakes.wsgi_app()) - actual_image = parseString(response.body.replace(" ", "")) + actual_image = minidom.parseString(response.body.replace(" ", "")) expected_now = self.NOW_API_FORMAT - expected_image = parseString(""" + expected_image = minidom.parseString(""" Image not found. @@ -396,7 +395,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): """.replace(" ", "")) - actual = parseString(response.body.replace(" ", "")) + actual = minidom.parseString(response.body.replace(" ", "")) self.assertEqual(expected.toxml(), actual.toxml()) @@ -422,7 +421,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): response = request.get_response(fakes.wsgi_app()) self.assertEqual(404, response.status_int) - expected = parseString(""" + expected = minidom.parseString(""" Image not found. @@ -430,7 +429,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): """.replace(" ", "")) - actual = parseString(response.body.replace(" ", "")) + actual = minidom.parseString(response.body.replace(" ", "")) self.assertEqual(expected.toxml(), actual.toxml()) -- cgit From cb8a13e3751cc12f7157094d094c7a26d6f583f0 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Sun, 27 Mar 2011 15:30:47 -0400 Subject: Fix utils checking --- nova/virt/disk.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index fd45e2c51..15cd49789 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -124,7 +124,7 @@ def setup_container(image, container_dir=None): """ nbd = "False" device = _link_device(image, nbd) - err = utils.execute('sudo', 'mount', device, container_dir) + out, err = utils.execute('sudo', 'mount', device, container_dir) if err: raise exception.Error(_('Failed to mount filesystem: %s') % err) -- cgit From b3f8e9fb546c621946563af0908e43cb01c50431 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Sun, 27 Mar 2011 18:48:32 -0700 Subject: Bunch of style fixes --- nova/api/openstack/common.py | 1 + nova/api/openstack/extensions.py | 2 +- .../incubator/volumes/volume_attachments.py | 21 +++++++++++---------- nova/api/openstack/incubator/volumes/volumes.py | 13 +++++++------ nova/compute/manager.py | 2 +- nova/image/fake.py | 1 + nova/tests/integrated/api/client.py | 4 +++- nova/tests/integrated/integrated_helpers.py | 12 +++++------- nova/tests/integrated/test_extensions.py | 1 + nova/tests/integrated/test_servers.py | 15 ++++++++------- nova/tests/integrated/test_volumes.py | 7 ++++--- nova/virt/driver.py | 13 ++++++------- 12 files changed, 49 insertions(+), 43 deletions(-) diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py index 4ab6b7a81..75aeb0a5f 100644 --- a/nova/api/openstack/common.py +++ b/nova/api/openstack/common.py @@ -26,6 +26,7 @@ from nova import log as logging LOG = logging.getLogger('common') + FLAGS = flags.FLAGS diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index 6a8ce9669..e81ffb3d3 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -68,7 +68,7 @@ class ExtensionDescriptor(object): """The timestamp when the extension was last updated e.g. '2011-01-22T13:25:27-06:00'""" - #NOTE(justinsb): Huh? Isn't this defined by the namespace? + #NOTE(justinsb): Not sure of the purpose of this is, vs the XML NS raise NotImplementedError() def get_resources(self): diff --git a/nova/api/openstack/incubator/volumes/volume_attachments.py b/nova/api/openstack/incubator/volumes/volume_attachments.py index 58a9a727b..93786d1c7 100644 --- a/nova/api/openstack/incubator/volumes/volume_attachments.py +++ b/nova/api/openstack/incubator/volumes/volume_attachments.py @@ -29,11 +29,12 @@ from nova.api.openstack import faults LOG = logging.getLogger("nova.api.volumes") + FLAGS = flags.FLAGS def _translate_detail_view(context, volume): - """ Maps keys for details view""" + """Maps keys for details view""" d = _translate_summary_view(context, volume) @@ -43,12 +44,12 @@ def _translate_detail_view(context, volume): def _translate_summary_view(context, vol): - """ Maps keys for summary view""" + """Maps keys for summary view""" d = {} volume_id = vol['id'] - # NOTE(justinsb): We use the volume id as the id of the attachment object + #NOTE(justinsb): We use the volume id as the id of the attachment object d['id'] = volume_id d['volumeId'] = volume_id @@ -61,7 +62,7 @@ def _translate_summary_view(context, vol): class Controller(wsgi.Controller): - """ The volume attachment API controller for the Openstack API + """The volume attachment API controller for the Openstack API A child resource of the server. Note that we use the volume id as the ID of the attachment (though this is not guaranteed externally)""" @@ -80,7 +81,7 @@ class Controller(wsgi.Controller): super(Controller, self).__init__() def index(self, req, server_id): - """ Returns the list of volume attachments for a given instance """ + """Returns the list of volume attachments for a given instance """ return self._items(req, server_id, entity_maker=_translate_summary_view) @@ -102,7 +103,7 @@ class Controller(wsgi.Controller): return {'volumeAttachment': _translate_detail_view(context, vol)} def create(self, req, server_id): - """ Attach a volume to an instance """ + """Attach a volume to an instance """ context = req.environ['nova.context'] env = self._deserialize(req.body, req.get_content_type()) @@ -130,7 +131,7 @@ class Controller(wsgi.Controller): attachment['id'] = volume_id attachment['volumeId'] = volume_id - # NOTE(justinsb): And now, we have a problem... + #NOTE(justinsb): And now, we have a problem... # The attach is async, so there's a window in which we don't see # the attachment (until the attachment completes). We could also # get problems with concurrent requests. I think we need an @@ -138,15 +139,15 @@ class Controller(wsgi.Controller): # change. # For now, we'll probably have to rely on libraries being smart - # TODO: How do I return "accepted" here?? + #TODO(justinsb): How do I return "accepted" here? return {'volumeAttachment': attachment} def update(self, _req, _server_id, _id): - """ Update a volume attachment. We don't currently support this.""" + """Update a volume attachment. We don't currently support this.""" return faults.Fault(exc.HTTPBadRequest()) def delete(self, req, server_id, id): - """ Detach a volume from an instance """ + """Detach a volume from an instance """ context = req.environ['nova.context'] volume_id = id diff --git a/nova/api/openstack/incubator/volumes/volumes.py b/nova/api/openstack/incubator/volumes/volumes.py index ec3b9a6c8..e122bb465 100644 --- a/nova/api/openstack/incubator/volumes/volumes.py +++ b/nova/api/openstack/incubator/volumes/volumes.py @@ -26,11 +26,12 @@ from nova.api.openstack import faults LOG = logging.getLogger("nova.api.volumes") + FLAGS = flags.FLAGS def _translate_detail_view(context, vol): - """ Maps keys for details view""" + """Maps keys for details view""" d = _translate_summary_view(context, vol) @@ -40,7 +41,7 @@ def _translate_detail_view(context, vol): def _translate_summary_view(_context, vol): - """ Maps keys for summary view""" + """Maps keys for summary view""" d = {} instance_id = None @@ -78,7 +79,7 @@ def _translate_summary_view(_context, vol): class Controller(wsgi.Controller): - """ The Volumes API controller for the OpenStack API """ + """The Volumes API controller for the OpenStack API""" _serialization_metadata = { 'application/xml': { @@ -109,7 +110,7 @@ class Controller(wsgi.Controller): return {'volume': _translate_detail_view(context, vol)} def delete(self, req, id): - """ Delete a volume """ + """Delete a volume """ context = req.environ['nova.context'] LOG.audit(_("Delete volume with id: %s"), id, context=context) @@ -121,11 +122,11 @@ class Controller(wsgi.Controller): return exc.HTTPAccepted() def index(self, req): - """ Returns a summary list of volumes""" + """Returns a summary list of volumes""" return self._items(req, entity_maker=_translate_summary_view) def detail(self, req): - """ Returns a detailed list of volumes """ + """Returns a detailed list of volumes """ return self._items(req, entity_maker=_translate_detail_view) def _items(self, req, entity_maker): diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 468771f46..10636f602 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1078,6 +1078,6 @@ class ComputeManager(manager.SchedulerDependentManager): # Are there VMs not in the DB? for vm_not_found_in_db in vms_not_found_in_db: name = vm_not_found_in_db - # TODO(justinsb): What to do here? Adopt it? Shut it down? + #TODO(justinsb): What to do here? Adopt it? Shut it down? LOG.warning(_("Found VM not in DB: '%(name)s'. Ignoring") % locals()) diff --git a/nova/image/fake.py b/nova/image/fake.py index 9d28e316d..29159f337 100644 --- a/nova/image/fake.py +++ b/nova/image/fake.py @@ -24,6 +24,7 @@ from nova.image import service LOG = logging.getLogger('nova.image.fake') + FLAGS = flags.FLAGS diff --git a/nova/tests/integrated/api/client.py b/nova/tests/integrated/api/client.py index 023871bda..688ba8778 100644 --- a/nova/tests/integrated/api/client.py +++ b/nova/tests/integrated/api/client.py @@ -56,7 +56,9 @@ class OpenStackApiNotFoundException(OpenStackApiException): class TestOpenStackClient(object): - """ A really basic OpenStack API client that is under our control, + """Simple OpenStack API Client. + + This is a really basic OpenStack API client that is under our control, so we can make changes / insert hooks for testing""" def __init__(self, auth_user, auth_key, auth_uri): diff --git a/nova/tests/integrated/integrated_helpers.py b/nova/tests/integrated/integrated_helpers.py index c64f6945d..7aed69099 100644 --- a/nova/tests/integrated/integrated_helpers.py +++ b/nova/tests/integrated/integrated_helpers.py @@ -85,10 +85,10 @@ class TestUser(object): def get_valid_image(self, create=False): images = self.openstack_api.get_images() if create and not images: - # TODO(justinsb): No way to create an image through API??? + #TODO(justinsb): No way currently to create an image through API #created_image = self.openstack_api.post_image(image) #images.append(created_image) - raise exception.Error("No way to create an image through API??") + raise exception.Error("No way to create an image through API") if images: return images[0] @@ -124,7 +124,7 @@ class IntegratedUnitTestContext(object): self._start_volume_service() self._start_scheduler_service() - # NOTE(justinsb): There's a bug here which is eluding me... + #NOTE(justinsb): There's a bug here which is eluding me... # If we start the network_service, all is good, but then subsequent # tests fail: CloudTestCase.test_ajax_console in particular. #self._start_network_service() @@ -192,7 +192,7 @@ class IntegratedUnitTestContext(object): if not api_service: raise Exception("API Service was None") - # NOTE(justinsb): The API service doesn't have a kill method yet, + #NOTE(justinsb): The API service doesn't have a kill method yet, # so we treat it separately self.api_service = api_service @@ -217,9 +217,7 @@ class _IntegratedTestBase(test.TestCase): super(_IntegratedTestBase, self).tearDown() def _get_flags(self): - """An opportunity to setup flags, before the services are started - - Warning - this is a bit flaky till the WSGI recycle code lands""" + """An opportunity to setup flags, before the services are started""" f = {} f['image_service'] = 'nova.image.fake.MockImageService' f['fake_network'] = True diff --git a/nova/tests/integrated/test_extensions.py b/nova/tests/integrated/test_extensions.py index 39906e8d0..1aa471f49 100644 --- a/nova/tests/integrated/test_extensions.py +++ b/nova/tests/integrated/test_extensions.py @@ -24,6 +24,7 @@ from nova.tests.integrated import integrated_helpers LOG = logging.getLogger('nova.tests.integrated') + FLAGS = flags.FLAGS FLAGS.verbose = True diff --git a/nova/tests/integrated/test_servers.py b/nova/tests/integrated/test_servers.py index a0a6e333a..59e5dde14 100644 --- a/nova/tests/integrated/test_servers.py +++ b/nova/tests/integrated/test_servers.py @@ -26,6 +26,7 @@ from nova.tests.integrated.api import client LOG = logging.getLogger('nova.tests.integrated') + FLAGS = flags.FLAGS FLAGS.verbose = True @@ -49,13 +50,13 @@ class ServersTest(integrated_helpers._IntegratedTestBase): post = {'server': server} # Without an imageRef, this throws 500. - # TODO(justinsb): Check whatever the spec says should be thrown here + #TODO(justinsb): Check whatever the spec says should be thrown here self.assertRaises(client.OpenStackApiException, self.api.post_server, post) # With an invalid imageRef, this throws 500. server['imageRef'] = self.user.get_invalid_image() - # TODO(justinsb): Check whatever the spec says should be thrown here + #TODO(justinsb): Check whatever the spec says should be thrown here self.assertRaises(client.OpenStackApiException, self.api.post_server, post) @@ -64,7 +65,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): server['imageRef'] = good_server.get('imageRef') # Without flavorId, this throws 500 - # TODO(justinsb): Check whatever the spec says should be thrown here + #TODO(justinsb): Check whatever the spec says should be thrown here self.assertRaises(client.OpenStackApiException, self.api.post_server, post) @@ -73,7 +74,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): server['flavorId'] = good_server.get('flavorId') # Without a name, this throws 500 - # TODO(justinsb): Check whatever the spec says should be thrown here + #TODO(justinsb): Check whatever the spec says should be thrown here self.assertRaises(client.OpenStackApiException, self.api.post_server, post) @@ -105,7 +106,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): break # It should be available... - # TODO(justinsb): Mock doesn't yet do this... + #TODO(justinsb): Mock doesn't yet do this... #self.assertEqual('available', found_server['status']) self._delete_server(created_server_id) @@ -125,7 +126,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): LOG.debug("Found_server=%s" % found_server) - # TODO(justinsb): Mock doesn't yet do accurate state changes + #TODO(justinsb): Mock doesn't yet do accurate state changes #if found_server['status'] != 'deleting': # break time.sleep(1) @@ -133,7 +134,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): # Should be gone self.assertFalse(found_server) -# TODO(justinsb): Enable this unit test when the metadata bug is fixed +#TODO(justinsb): Enable this unit test when the metadata bug is fixed # def test_create_server_with_metadata(self): # """Creates a server with metadata""" # diff --git a/nova/tests/integrated/test_volumes.py b/nova/tests/integrated/test_volumes.py index 9ddfe85f7..89480618d 100644 --- a/nova/tests/integrated/test_volumes.py +++ b/nova/tests/integrated/test_volumes.py @@ -27,6 +27,7 @@ from nova.volume import driver LOG = logging.getLogger('nova.tests.integrated') + FLAGS = flags.FLAGS FLAGS.verbose = True @@ -55,7 +56,7 @@ class VolumesTest(integrated_helpers._IntegratedTestBase): LOG.debug("volume: %s" % volume) def _poll_while(self, volume_id, continue_states, max_retries=5): - """ Poll (briefly) while the state is in continue_states""" + """Poll (briefly) while the state is in continue_states""" retries = 0 while True: try: @@ -144,7 +145,7 @@ class VolumesTest(integrated_helpers._IntegratedTestBase): # Create server server_req = {'server': self._build_minimal_create_server_request()} - # NOTE(justinsb): Create an extra server so that server_id != volume_id + #NOTE(justinsb): Create an extra server so that server_id != volume_id self.api.post_server(server_req) created_server = self.api.post_server(server_req) LOG.debug("created_server: %s" % created_server) @@ -197,7 +198,7 @@ class VolumesTest(integrated_helpers._IntegratedTestBase): # This is just an implementation detail, but let's check it... self.assertEquals(volume_id, attachment_id) - # NOTE(justinsb): There's an issue with the attach code, in that + #NOTE(justinsb): There's an issue with the attach code, in that # it's currently asynchronous and not recorded until the attach # completes. So the caller must be 'smart', like this... attach_done = None diff --git a/nova/virt/driver.py b/nova/virt/driver.py index 1bc3e4dfc..eafede17a 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -66,8 +66,7 @@ class ComputeDriver(object): raise NotImplementedError() def destroy(self, instance, cleanup=True): - """ - Destroy (shutdown and delete) the specified instance. + """Destroy (shutdown and delete) the specified instance. The given parameter is an instance of nova.compute.service.Instance, and so the instance is being specified as instance.name. @@ -89,12 +88,12 @@ class ComputeDriver(object): raise NotImplementedError() def get_console_pool_info(self, console_type): - """??? + """? Returns a dict containing: - :address: ??? - :username: ??? - :password: ??? + :address: ? + :username: ? + :password: ? """ raise NotImplementedError() @@ -126,7 +125,7 @@ class ComputeDriver(object): raise NotImplementedError() def snapshot(self, instance, image_id): - """ Create snapshot from a running VM instance """ + """Create snapshot from a running VM instance """ raise NotImplementedError() def finish_resize(self, instance, disk_info): -- cgit From a1accc23427347205f7f6c49402a4f366e5256b6 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Sun, 27 Mar 2011 19:38:20 -0700 Subject: pep8 fixes --- nova/tests/integrated/api/client.py | 2 +- nova/tests/integrated/integrated_helpers.py | 85 +++++++++-------------------- 2 files changed, 26 insertions(+), 61 deletions(-) diff --git a/nova/tests/integrated/api/client.py b/nova/tests/integrated/api/client.py index 688ba8778..b9ed7b03b 100644 --- a/nova/tests/integrated/api/client.py +++ b/nova/tests/integrated/api/client.py @@ -57,7 +57,7 @@ class OpenStackApiNotFoundException(OpenStackApiException): class TestOpenStackClient(object): """Simple OpenStack API Client. - + This is a really basic OpenStack API client that is under our control, so we can make changes / insert hooks for testing""" diff --git a/nova/tests/integrated/integrated_helpers.py b/nova/tests/integrated/integrated_helpers.py index 7aed69099..bc516b4b3 100644 --- a/nova/tests/integrated/integrated_helpers.py +++ b/nova/tests/integrated/integrated_helpers.py @@ -96,12 +96,10 @@ class TestUser(object): class IntegratedUnitTestContext(object): - def __init__(self): + def __init__(self, auth_url): self.auth_manager = manager.AuthManager() - self.api_service = None - self.services = [] - self.auth_url = None + self.auth_url = auth_url self.project_name = None self.test_user = None @@ -109,7 +107,6 @@ class IntegratedUnitTestContext(object): self.setup() def setup(self): - self._start_services() self._create_test_user() def _create_test_user(self): @@ -119,47 +116,8 @@ class IntegratedUnitTestContext(object): self.project_name = 'openstack' self._configure_project(self.project_name, self.test_user) - def _start_services(self): - self._start_compute_service() - self._start_volume_service() - self._start_scheduler_service() - - #NOTE(justinsb): There's a bug here which is eluding me... - # If we start the network_service, all is good, but then subsequent - # tests fail: CloudTestCase.test_ajax_console in particular. - #self._start_network_service() - - self._start_api_service() - - def _start_compute_service(self): - compute_service = service.Service.create(binary='nova-compute') - compute_service.start() - self.services.append(compute_service) - return compute_service - - def _start_network_service(self): - network_service = service.Service.create(binary='nova-network') - network_service.start() - self.services.append(network_service) - return network_service - - def _start_volume_service(self): - volume_service = service.Service.create(binary='nova-volume') - volume_service.start() - self.services.append(volume_service) - return volume_service - - def _start_scheduler_service(self): - scheduler_service = service.Service.create(binary='nova-scheduler') - scheduler_service.start() - self.services.append(scheduler_service) - return scheduler_service - def cleanup(self): self.test_user = None - for svc in self.services: - svc.kill() - self.services = [] def _create_unittest_user(self): users = self.auth_manager.get_users() @@ -185,21 +143,6 @@ class IntegratedUnitTestContext(object): else: self.auth_manager.add_to_project(user.name, project_name) - def _start_api_service(self): - api_service = service.ApiService.create() - api_service.start() - - if not api_service: - raise Exception("API Service was None") - - #NOTE(justinsb): The API service doesn't have a kill method yet, - # so we treat it separately - self.api_service = api_service - - self.auth_url = 'http://localhost:8774/v1.1' - - return api_service - class _IntegratedTestBase(test.TestCase): def setUp(self): @@ -208,10 +151,32 @@ class _IntegratedTestBase(test.TestCase): f = self._get_flags() self.flags(**f) - self.context = IntegratedUnitTestContext() + # set up services + self.start_service('compute') + self.start_service('volume') + #NOTE(justinsb): There's a bug here which is eluding me... + # If we start the network_service, all is good, but then subsequent + # tests fail: CloudTestCase.test_ajax_console in particular. + #self.start_service('network') + self.start_service('scheduler') + + self.auth_url = self._start_api_service() + + self.context = IntegratedUnitTestContext(self.auth_url) + self.user = self.context.test_user self.api = self.user.openstack_api + def _start_api_service(self): + api_service = service.ApiService.create() + api_service.start() + + if not api_service: + raise Exception("API Service was None") + + auth_url = 'http://localhost:8774/v1.1' + return auth_url + def tearDown(self): self.context.cleanup() super(_IntegratedTestBase, self).tearDown() -- cgit From 8957914ad9dd7691b2a43d977d845e00f7dd48c4 Mon Sep 17 00:00:00 2001 From: Armando Migliaccio Date: Mon, 28 Mar 2011 10:54:29 +0100 Subject: addressed termies review (first round) --- nova/network/xenapi_net.py | 26 +++---- nova/tests/db/fakes.py | 8 +- nova/tests/fake_utils.py | 11 +-- nova/tests/fake_utils.py.moved | 106 --------------------------- nova/tests/test_xenapi.py | 37 +++++----- nova/virt/xenapi/network_utils.py | 2 +- nova/virt/xenapi/vmops.py | 149 ++++++++++++++++++++++---------------- 7 files changed, 125 insertions(+), 214 deletions(-) delete mode 100644 nova/tests/fake_utils.py.moved diff --git a/nova/network/xenapi_net.py b/nova/network/xenapi_net.py index 1725a4b7a..7a9da8046 100644 --- a/nova/network/xenapi_net.py +++ b/nova/network/xenapi_net.py @@ -35,19 +35,19 @@ FLAGS = flags.FLAGS def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None): - """Create a vlan and bridge unless they already exist""" - #open xenapi session + """Create a vlan and bridge unless they already exist.""" + # Open xenapi session LOG.debug("ENTERING ensure_vlan_bridge in xenapi net") url = FLAGS.xenapi_connection_url username = FLAGS.xenapi_connection_username password = FLAGS.xenapi_connection_password session = XenAPISession(url, username, password) - #check whether bridge already exists - #retrieve network whose name_label is "bridge" + # Check whether bridge already exists + # Retrieve network whose name_label is "bridge" network_ref = NetworkHelper.find_network_with_name_label(session, bridge) if network_ref == None: - #if bridge does not exists - #1 - create network + # If bridge does not exists + # 1 - create network description = "network for nova bridge %s" % bridge network_rec = { 'name_label': bridge, @@ -55,28 +55,28 @@ def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None): 'other_config': {}, } network_ref = session.call_xenapi('network.create', network_rec) - #2 - find PIF for VLAN + # 2 - find PIF for VLAN expr = 'field "device" = "%s" and \ field "VLAN" = "-1"' % FLAGS.vlan_interface pifs = session.call_xenapi('PIF.get_all_records_where', expr) pif_ref = None - #multiple PIF are ok: we are dealing with a pool + # Multiple PIF are ok: we are dealing with a pool if len(pifs) == 0: raise Exception( _('Found no PIF for device %s') % FLAGS.vlan_interface) - #3 - create vlan for network + # 3 - create vlan for network for pif_ref in pifs.keys(): session.call_xenapi('VLAN.create', pif_ref, str(vlan_num), network_ref) else: - #check VLAN tag is appropriate + # Check VLAN tag is appropriate network_rec = session.call_xenapi('network.get_record', network_ref) - #retrieve PIFs from network + # Retrieve PIFs from network for pif_ref in network_rec['PIFs']: - #retrieve VLAN from PIF + # Retrieve VLAN from PIF pif_rec = session.call_xenapi('PIF.get_record', pif_ref) pif_vlan = int(pif_rec['VLAN']) - #raise an exception if VLAN <> vlan_num + # Raise an exception if VLAN <> vlan_num if pif_vlan != vlan_num: raise Exception(_("PIF %(pif_rec['uuid'])s for network " "%(bridge)s has VLAN id %(pif_vlan)d. " diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py index 05a47d4c9..f7610aa56 100644 --- a/nova/tests/db/fakes.py +++ b/nova/tests/db/fakes.py @@ -25,7 +25,7 @@ from nova import utils def stub_out_db_instance_api(stubs, injected=True): - """ Stubs out the db API for creating Instances """ + """Stubs out the db API for creating Instances.""" INSTANCE_TYPES = { 'm1.tiny': dict(memory_mb=512, @@ -91,7 +91,7 @@ def stub_out_db_instance_api(stubs, injected=True): 'network_id': 'fake_flat'} class FakeModel(object): - """ Stubs out for model """ + """Stubs out for model.""" def __init__(self, values): self.values = values @@ -111,7 +111,7 @@ def stub_out_db_instance_api(stubs, injected=True): return INSTANCE_TYPES[name] def fake_network_get_by_instance(context, instance_id): - #even instance numbers are on vlan networks + # Even instance numbers are on vlan networks if instance_id % 2 == 0: return FakeModel(vlan_network_fields) else: @@ -119,7 +119,7 @@ def stub_out_db_instance_api(stubs, injected=True): return FakeModel(network_fields) def fake_network_get_all_by_instance(context, instance_id): - #even instance numbers are on vlan networks + # Even instance numbers are on vlan networks if instance_id % 2 == 0: return [FakeModel(vlan_network_fields)] else: diff --git a/nova/tests/fake_utils.py b/nova/tests/fake_utils.py index 823c775cb..23996ba95 100644 --- a/nova/tests/fake_utils.py +++ b/nova/tests/fake_utils.py @@ -14,8 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. -"""This modules stubs out functions in nova.utils -""" +"""This modules stubs out functions in nova.utils.""" import re import types @@ -42,22 +41,20 @@ def fake_execute_clear_log(): def fake_execute_set_repliers(repliers): - """Allows the client to configure replies to commands""" + """Allows the client to configure replies to commands.""" global _fake_execute_repliers _fake_execute_repliers = repliers def fake_execute_default_reply_handler(*ignore_args, **ignore_kwargs): """A reply handler for commands that haven't been added to the reply - list. Returns empty strings for stdout and stderr - """ + list. Returns empty strings for stdout and stderr.""" return '', '' def fake_execute(*cmd_parts, **kwargs): """This function stubs out execute, optionally executing - a preconfigued function to return expected data - """ + a preconfigued function to return expected data.""" global _fake_execute_repliers process_input = kwargs.get('process_input', None) diff --git a/nova/tests/fake_utils.py.moved b/nova/tests/fake_utils.py.moved deleted file mode 100644 index 8982f50be..000000000 --- a/nova/tests/fake_utils.py.moved +++ /dev/null @@ -1,106 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2011 Citrix Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""This modules stubs out functions in nova.utils -""" - -import re -import types - -from eventlet import greenthread - -from nova import exception -from nova import log as logging -from nova import utils - -LOG = logging.getLogger('nova.tests.fake_utils') - -_fake_execute_repliers = [] -_fake_execute_log = [] - - -def fake_execute_get_log(): - global _fake_execute_log - return _fake_execute_log - - -def fake_execute_clear_log(): - global _fake_execute_log - _fake_execute_log = [] - - -def fake_execute_set_repliers(repliers): - """Allows the client to configure replies to commands""" - global _fake_execute_repliers - _fake_execute_repliers = repliers - - -def fake_execute_default_reply_handler(*ignore_args, **ignore_kwargs): - """A reply handler for commands that haven't been added to the reply - list. Returns empty strings for stdout and stderr - """ - return '', '' - - -def fake_execute(*cmd, **kwargs): - """This function stubs out execute, optionally executing - a preconfigued function to return expected data - """ - global _fake_execute_repliers - - process_input = kwargs.get('process_input', None) - addl_env = kwargs.get('addl_env', None) - check_exit_code = kwargs.get('check_exit_code', 0) - cmd_map = map(str, cmd) - cmd_str = ' '.join(cmd_map) - - LOG.debug(_("Faking execution of cmd (subprocess): %s"), cmd_str) - _fake_execute_log.append(cmd_str) - - reply_handler = fake_execute_default_reply_handler - - for fake_replier in _fake_execute_repliers: - if re.match(fake_replier[0], cmd_str): - reply_handler = fake_replier[1] - LOG.debug(_('Faked command matched %s') % fake_replier[0]) - break - - if isinstance(reply_handler, types.StringTypes): - # If the reply handler is a string, return it as stdout - reply = reply_handler, '' - else: - try: - # Alternative is a function, so call it - reply = reply_handler(cmd, - process_input=process_input, - addl_env=addl_env, - check_exit_code=check_exit_code) - except exception.ProcessExecutionError as e: - LOG.debug(_('Faked command raised an exception %s' % str(e))) - raise - - LOG.debug(_("Reply to faked command is stdout='%(0)s' stderr='%(1)s'") % - {'0': reply[0], '1': reply[1]}) - - # Replicate the sleep call in the real function - greenthread.sleep(0) - return reply - - -def stub_out_utils_execute(stubs): - fake_execute_set_repliers([]) - fake_execute_clear_log() - stubs.Set(utils, 'execute', fake_execute) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index f91f37d4b..6ec0525a7 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -15,7 +15,7 @@ # under the License. """ -Test suite for XenAPI +Test suite for XenAPI. """ import functools @@ -66,7 +66,7 @@ def stub_vm_utils_with_vdi_attached_here(function, should_return=True): class XenAPIVolumeTestCase(test.TestCase): """ - Unit tests for Volume operations + Unit tests for Volume operations. """ def setUp(self): super(XenAPIVolumeTestCase, self).setUp() @@ -76,7 +76,6 @@ class XenAPIVolumeTestCase(test.TestCase): FLAGS.xenapi_connection_url = 'test_url' FLAGS.xenapi_connection_password = 'test_pass' db_fakes.stub_out_db_instance_api(self.stubs) - #db_fakes.stub_out_db_network_api(self.stubs) stubs.stub_out_get_target(self.stubs) xenapi_fake.reset() self.values = {'id': 1, @@ -102,7 +101,7 @@ class XenAPIVolumeTestCase(test.TestCase): return db.volume_create(self.context, vol) def test_create_iscsi_storage(self): - """ This shows how to test helper classes' methods """ + """This shows how to test helper classes' methods.""" stubs.stubout_session(self.stubs, stubs.FakeSessionForVolumeTests) session = xenapi_conn.XenAPISession('test_url', 'root', 'test_pass') helper = volume_utils.VolumeHelper @@ -117,7 +116,7 @@ class XenAPIVolumeTestCase(test.TestCase): db.volume_destroy(context.get_admin_context(), vol['id']) def test_parse_volume_info_raise_exception(self): - """ This shows how to test helper classes' methods """ + """This shows how to test helper classes' methods.""" stubs.stubout_session(self.stubs, stubs.FakeSessionForVolumeTests) session = xenapi_conn.XenAPISession('test_url', 'root', 'test_pass') helper = volume_utils.VolumeHelper @@ -131,7 +130,7 @@ class XenAPIVolumeTestCase(test.TestCase): db.volume_destroy(context.get_admin_context(), vol['id']) def test_attach_volume(self): - """ This shows how to test Ops classes' methods """ + """This shows how to test Ops classes' methods.""" stubs.stubout_session(self.stubs, stubs.FakeSessionForVolumeTests) conn = xenapi_conn.get_connection(False) volume = self._create_volume() @@ -150,7 +149,7 @@ class XenAPIVolumeTestCase(test.TestCase): check() def test_attach_volume_raise_exception(self): - """ This shows how to test when exceptions are raised """ + """This shows how to test when exceptions are raised.""" stubs.stubout_session(self.stubs, stubs.FakeSessionForVolumeFailedTests) conn = xenapi_conn.get_connection(False) @@ -174,7 +173,7 @@ def reset_network(*args): class XenAPIVMTestCase(test.TestCase): """ - Unit tests for VM operations + Unit tests for VM operations. """ def setUp(self): super(XenAPIVMTestCase, self).setUp() @@ -475,21 +474,21 @@ class XenAPIVMTestCase(test.TestCase): network_manager='nova.network.manager.VlanManager', network_driver='nova.network.xenapi_net', vlan_interface='fake0') - #reset network table + # Reset network table xenapi_fake.reset_table('network') - #instance id = 2 will use vlan network (see db/fakes.py) + # Instance id = 2 will use vlan network (see db/fakes.py) fake_instance_id = 2 network_bk = self.network - #ensure we use xenapi_net driver + # Ensure we use xenapi_net driver self.network = utils.import_object(FLAGS.network_manager) self.network.setup_compute_network(None, fake_instance_id) self._test_spawn(glance_stubs.FakeGlance.IMAGE_MACHINE, glance_stubs.FakeGlance.IMAGE_KERNEL, glance_stubs.FakeGlance.IMAGE_RAMDISK, instance_id=fake_instance_id) - #TODO(salvatore-orlando): a complete test here would require - #a check for making sure the bridge for the VM's VIF is - #consistent with bridge specified in nova db + # TODO(salvatore-orlando): a complete test here would require + # A check for making sure the bridge for the VM's VIF is + # consistent with bridge specified in nova db self.network = network_bk def test_spawn_with_network_qos(self): @@ -521,7 +520,7 @@ class XenAPIVMTestCase(test.TestCase): self.stubs.UnsetAll() def _create_instance(self): - """Creates and spawns a test instance""" + """Creates and spawns a test instance.""" stubs.stubout_loopingcall_start(self.stubs) values = { 'id': 1, @@ -540,7 +539,7 @@ class XenAPIVMTestCase(test.TestCase): class XenAPIDiffieHellmanTestCase(test.TestCase): """ - Unit tests for Diffie-Hellman code + Unit tests for Diffie-Hellman code. """ def setUp(self): super(XenAPIDiffieHellmanTestCase, self).setUp() @@ -566,7 +565,7 @@ class XenAPIDiffieHellmanTestCase(test.TestCase): class XenAPIMigrateInstance(test.TestCase): """ - Unit test for verifying migration-related actions + Unit test for verifying migration-related actions. """ def setUp(self): @@ -623,7 +622,7 @@ class XenAPIMigrateInstance(test.TestCase): class XenAPIDetermineDiskImageTestCase(test.TestCase): """ - Unit tests for code that detects the ImageType + Unit tests for code that detects the ImageType. """ def setUp(self): super(XenAPIDetermineDiskImageTestCase, self).setUp() @@ -644,7 +643,7 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): def test_instance_disk(self): """ - If a kernel is specified then the image type is DISK (aka machine) + If a kernel is specified then the image type is DISK (aka machine). """ FLAGS.xenapi_image_service = 'objectstore' self.fake_instance.image_id = glance_stubs.FakeGlance.IMAGE_MACHINE diff --git a/nova/virt/xenapi/network_utils.py b/nova/virt/xenapi/network_utils.py index 546f6bea9..94d8e5199 100644 --- a/nova/virt/xenapi/network_utils.py +++ b/nova/virt/xenapi/network_utils.py @@ -44,7 +44,7 @@ class NetworkHelper(HelperBase): """ Return the network on which the bridge is attached, if found. The bridge is defined in the nova db and can be found either in the - 'bridge' or 'name_label' fields of the XenAPI network record + 'bridge' or 'name_label' fields of the XenAPI network record. """ expr = 'field "name__label" = "%s" or ' \ 'field "bridge" = "%s"' % (bridge, bridge) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 52e1f9eba..9b18ac732 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -58,7 +58,7 @@ class VMOps(object): VMHelper.XenAPI = self.XenAPI def list_instances(self): - """List VM instances""" + """List VM instances.""" # TODO(justinsb): Should we just always use the details method? # Seems to be the same number of API calls.. vm_refs = [] @@ -69,7 +69,7 @@ class VMOps(object): return vm_refs def list_instances_detail(self): - """List VM instances, returning InstanceInfo objects""" + """List VM instances, returning InstanceInfo objects.""" instance_infos = [] for vm_ref in self._session.get_xenapi().VM.get_all(): vm_rec = self._session.get_xenapi().VM.get_record(vm_ref) @@ -119,11 +119,11 @@ class VMOps(object): self._spawn(instance, vm_ref) def spawn_rescue(self, instance): - """Spawn a rescue instance""" + """Spawn a rescue instance.""" self.spawn(instance) def _create_vm(self, instance, vdi_uuid, network_info=None): - """Create VM instance""" + """Create VM instance.""" instance_name = instance.name vm_ref = VMHelper.lookup(self._session, instance_name) if vm_ref is not None: @@ -180,7 +180,7 @@ class VMOps(object): return vm_ref def _spawn(self, instance, vm_ref): - """Spawn a new instance""" + """Spawn a new instance.""" LOG.debug(_('Starting VM %s...'), vm_ref) self._start(instance, vm_ref) instance_name = instance.name @@ -236,7 +236,8 @@ class VMOps(object): return timer.start(interval=0.5, now=True) def _get_vm_opaque_ref(self, instance_or_vm): - """Refactored out the common code of many methods that receive either + """ + Refactored out the common code of many methods that receive either a vm name or a vm instance, and want a vm instance in return. """ # if instance_or_vm is a string it must be opaque ref or instance name @@ -264,21 +265,22 @@ class VMOps(object): return vm_ref def _acquire_bootlock(self, vm): - """Prevent an instance from booting""" + """Prevent an instance from booting.""" self._session.call_xenapi( "VM.set_blocked_operations", vm, {"start": ""}) def _release_bootlock(self, vm): - """Allow an instance to boot""" + """Allow an instance to boot.""" self._session.call_xenapi( "VM.remove_from_blocked_operations", vm, "start") def snapshot(self, instance, image_id): - """Create snapshot from a running VM instance + """ + Create snapshot from a running VM instance :param instance: instance to be snapshotted :param image_id: id of image to upload to @@ -330,11 +332,12 @@ class VMOps(object): return def migrate_disk_and_power_off(self, instance, dest): - """Copies a VHD from one host machine to another + """ + Copies a VHD from one host machine to another - :param instance: the instance that owns the VHD in question - :param dest: the destination host machine - :param disk_type: values are 'primary' or 'cow' + :param instance: the instance that owns the VHD in question. + :param dest: the destination host machine. + :param disk_type: values are 'primary' or 'cow'. """ vm_ref = VMHelper.lookup(self._session, instance.name) @@ -383,7 +386,7 @@ class VMOps(object): return {'base_copy': base_copy_uuid, 'cow': cow_uuid} def link_disks(self, instance, base_copy_uuid, cow_uuid): - """Links the base copy VHD to the COW via the XAPI plugin""" + """Links the base copy VHD to the COW via the XAPI plugin.""" vm_ref = VMHelper.lookup(self._session, instance.name) new_base_copy_uuid = str(uuid.uuid4()) new_cow_uuid = str(uuid.uuid4()) @@ -404,7 +407,7 @@ class VMOps(object): return new_cow_uuid def resize_instance(self, instance, vdi_uuid): - """Resize a running instance by changing it's RAM and disk size """ + """Resize a running instance by changing it's RAM and disk size.""" #TODO(mdietz): this will need to be adjusted for swap later #The new disk size must be in bytes @@ -418,13 +421,14 @@ class VMOps(object): LOG.debug(_("Resize instance %s complete") % (instance.name)) def reboot(self, instance): - """Reboot VM instance""" + """Reboot VM instance.""" vm_ref = self._get_vm_opaque_ref(instance) task = self._session.call_xenapi('Async.VM.clean_reboot', vm_ref) self._session.wait_for_task(task, instance.id) def set_admin_password(self, instance, new_pass): - """Set the root/admin password on the VM instance. This is done via + """ + Set the root/admin password on the VM instance. This is done via an agent running on the VM. Communication between nova and the agent is done via writing xenstore records. Since communication is done over the XenAPI RPC calls, we need to encrypt the password. We're using a @@ -462,7 +466,8 @@ class VMOps(object): return resp_dict['message'] def inject_file(self, instance, path, contents): - """Write a file to the VM instance. The path to which it is to be + """ + Write a file to the VM instance. The path to which it is to be written and the contents of the file need to be supplied; both will be base64-encoded to prevent errors with non-ASCII characters being transmitted. If the agent does not support file injection, or the user @@ -487,7 +492,7 @@ class VMOps(object): return resp_dict['message'] def _shutdown(self, instance, vm_ref, hard=True): - """Shutdown an instance""" + """Shutdown an instance.""" state = self.get_info(instance['name'])['state'] if state == power_state.SHUTDOWN: instance_name = instance.name @@ -511,11 +516,11 @@ class VMOps(object): LOG.exception(exc) def _shutdown_rescue(self, rescue_vm_ref): - """Shutdown a rescue instance""" + """Shutdown a rescue instance.""" self._session.call_xenapi("Async.VM.hard_shutdown", rescue_vm_ref) def _destroy_vdis(self, instance, vm_ref): - """Destroys all VDIs associated with a VM""" + """Destroys all VDIs associated with a VM.""" instance_id = instance.id LOG.debug(_("Destroying VDIs for Instance %(instance_id)s") % locals()) @@ -532,7 +537,7 @@ class VMOps(object): LOG.exception(exc) def _destroy_rescue_vdis(self, rescue_vm_ref): - """Destroys all VDIs associated with a rescued VM""" + """Destroys all VDIs associated with a rescued VM.""" vdi_refs = VMHelper.lookup_vm_vdis(self._session, rescue_vm_ref) for vdi_ref in vdi_refs: try: @@ -541,7 +546,7 @@ class VMOps(object): continue def _destroy_rescue_vbds(self, rescue_vm_ref): - """Destroys all VBDs tied to a rescue VM""" + """Destroys all VBDs tied to a rescue VM.""" vbd_refs = self._session.get_xenapi().VM.get_VBDs(rescue_vm_ref) for vbd_ref in vbd_refs: vbd_rec = self._session.get_xenapi().VBD.get_record(vbd_ref) @@ -589,7 +594,7 @@ class VMOps(object): LOG.debug(_("kernel/ramdisk files removed")) def _destroy_vm(self, instance, vm_ref): - """Destroys a VM record""" + """Destroys a VM record.""" instance_id = instance.id try: task = self._session.call_xenapi('Async.VM.destroy', vm_ref) @@ -600,7 +605,7 @@ class VMOps(object): LOG.debug(_("Instance %(instance_id)s VM destroyed") % locals()) def _destroy_rescue_instance(self, rescue_vm_ref): - """Destroy a rescue instance""" + """Destroy a rescue instance.""" self._destroy_rescue_vbds(rescue_vm_ref) self._shutdown_rescue(rescue_vm_ref) self._destroy_rescue_vdis(rescue_vm_ref) @@ -624,10 +629,10 @@ class VMOps(object): """ Destroys VM instance by performing: - 1. A shutdown if requested - 2. Destroying associated VDIs - 3. Destroying kernel and ramdisk files (if necessary) - 4. Destroying that actual VM record + 1. A shutdown if requested. + 2. Destroying associated VDIs. + 3. Destroying kernel and ramdisk files (if necessary). + 4. Destroying that actual VM record. """ if vm_ref is None: LOG.warning(_("VM is not present, skipping destroy...")) @@ -650,36 +655,36 @@ class VMOps(object): callback(ret) def pause(self, instance, callback): - """Pause VM instance""" + """Pause VM instance.""" vm_ref = self._get_vm_opaque_ref(instance) task = self._session.call_xenapi('Async.VM.pause', vm_ref) self._wait_with_callback(instance.id, task, callback) def unpause(self, instance, callback): - """Unpause VM instance""" + """Unpause VM instance.""" vm_ref = self._get_vm_opaque_ref(instance) task = self._session.call_xenapi('Async.VM.unpause', vm_ref) self._wait_with_callback(instance.id, task, callback) def suspend(self, instance, callback): - """suspend the specified instance""" + """Suspend the specified instance""" vm_ref = self._get_vm_opaque_ref(instance) task = self._session.call_xenapi('Async.VM.suspend', vm_ref) self._wait_with_callback(instance.id, task, callback) def resume(self, instance, callback): - """resume the specified instance""" + """Resume the specified instance.""" vm_ref = self._get_vm_opaque_ref(instance) task = self._session.call_xenapi('Async.VM.resume', vm_ref, False, True) self._wait_with_callback(instance.id, task, callback) def rescue(self, instance, callback): - """Rescue the specified instance - - shutdown the instance VM - - set 'bootlock' to prevent the instance from starting in rescue - - spawn a rescue VM (the vm name-label will be instance-N-rescue) - + """ + Rescue the specified instance + - shutdown the instance VM. + - set 'bootlock' to prevent the instance from starting in rescue. + - spawn a rescue VM (the vm name-label will be instance-N-rescue). """ rescue_vm_ref = VMHelper.lookup(self._session, "%s-rescue" % instance.name) @@ -703,9 +708,9 @@ class VMOps(object): def unrescue(self, instance, callback): """Unrescue the specified instance - - unplug the instance VM's disk from the rescue VM - - teardown the rescue VM - - release the bootlock to allow the instance VM to start + - unplug the instance VM's disk from the rescue VM. + - teardown the rescue VM. + - release the bootlock to allow the instance VM to start. """ rescue_vm_ref = VMHelper.lookup(self._session, @@ -723,7 +728,8 @@ class VMOps(object): self._start(instance, original_vm_ref) def poll_rescued_instances(self, timeout): - """Look for expirable rescued instances + """ + Look for expirable rescued instances - forcibly exit rescue mode for any instances that have been in rescue mode for >= the provided timeout """ @@ -761,30 +767,30 @@ class VMOps(object): False) def get_info(self, instance): - """Return data about VM instance""" + """Return data about VM instance.""" vm_ref = self._get_vm_opaque_ref(instance) vm_rec = self._session.get_xenapi().VM.get_record(vm_ref) return VMHelper.compile_info(vm_rec) def get_diagnostics(self, instance): - """Return data about VM diagnostics""" + """Return data about VM diagnostics.""" vm_ref = self._get_vm_opaque_ref(instance) vm_rec = self._session.get_xenapi().VM.get_record(vm_ref) return VMHelper.compile_diagnostics(self._session, vm_rec) def get_console_output(self, instance): - """Return snapshot of console""" + """Return snapshot of console.""" # TODO: implement this to fix pylint! return 'FAKE CONSOLE OUTPUT of instance' def get_ajax_console(self, instance): - """Return link to instance's ajax console""" + """Return link to instance's ajax console.""" # TODO: implement this! return 'http://fakeajaxconsole/fake_url' # TODO(tr3buchet) - remove this function after nova multi-nic def _get_network_info(self, instance): - """creates network info list for instance""" + """Creates network info list for instance.""" admin_context = context.get_admin_context() IPs = db.fixed_ip_get_all_by_instance(admin_context, instance['id']) @@ -826,7 +832,7 @@ class VMOps(object): def inject_network_info(self, instance, vm_ref, network_info): """ Generate the network info and make calls to place it into the - xenstore and the xenstore param list + xenstore and the xenstore param list. """ logging.debug(_("injecting network info to xs for vm: |%s|"), vm_ref) @@ -847,7 +853,7 @@ class VMOps(object): pass def create_vifs(self, vm_ref, network_info): - """Creates vifs for an instance""" + """Creates vifs for an instance.""" logging.debug(_("creating vif(s) for vm: |%s|"), vm_ref) # this function raises if vm_ref is not a vm_opaque_ref @@ -872,7 +878,8 @@ class VMOps(object): args, vm_ref) def list_from_xenstore(self, vm, path): - """Runs the xenstore-ls command to get a listing of all records + """ + Runs the xenstore-ls command to get a listing of all records from 'path' downward. Returns a dict with the sub-paths as keys, and the value stored in those paths as values. If nothing is found at that path, returns None. @@ -881,7 +888,8 @@ class VMOps(object): return json.loads(ret) def read_from_xenstore(self, vm, path): - """Returns the value stored in the xenstore record for the given VM + """ + Returns the value stored in the xenstore record for the given VM at the specified location. A XenAPIPlugin.PluginError will be raised if any error is encountered in the read process. """ @@ -897,7 +905,8 @@ class VMOps(object): return ret def write_to_xenstore(self, vm, path, value): - """Writes the passed value to the xenstore record for the given VM + """ + Writes the passed value to the xenstore record for the given VM at the specified location. A XenAPIPlugin.PluginError will be raised if any error is encountered in the write process. """ @@ -905,7 +914,8 @@ class VMOps(object): {'value': json.dumps(value)}) def clear_xenstore(self, vm, path): - """Deletes the VM's xenstore record for the specified path. + """ + Deletes the VM's xenstore record for the specified path. If there is no such record, the request is ignored. """ self._make_xenstore_call('delete_record', vm, path) @@ -922,7 +932,8 @@ class VMOps(object): def _make_plugin_call(self, plugin, method, vm, path, addl_args=None, vm_ref=None): - """Abstracts out the process of calling a method of a xenapi plugin. + """ + Abstracts out the process of calling a method of a xenapi plugin. Any errors raised by the plugin will in turn raise a RuntimeError here. """ instance_id = vm.id @@ -952,7 +963,8 @@ class VMOps(object): return ret def add_to_xenstore(self, vm, path, key, value): - """Adds the passed key/value pair to the xenstore record for + """ + Adds the passed key/value pair to the xenstore record for the given VM at the specified location. A XenAPIPlugin.PluginError will be raised if any error is encountered in the write process. """ @@ -965,7 +977,8 @@ class VMOps(object): self.write_to_xenstore(vm, path, current) def remove_from_xenstore(self, vm, path, key_or_keys): - """Takes either a single key or a list of keys and removes + """ + Takes either a single key or a list of keys and removes them from the xenstoreirecord data for the given VM. If the key doesn't exist, the request is ignored. """ @@ -992,7 +1005,8 @@ class VMOps(object): ###### names to distinguish them. (dabo) ######################################################################## def read_partial_from_param_xenstore(self, instance_or_vm, key_prefix): - """Returns a dict of all the keys in the xenstore parameter record + """ + Returns a dict of all the keys in the xenstore parameter record for the given instance that begin with the key_prefix. """ data = self.read_from_param_xenstore(instance_or_vm) @@ -1003,7 +1017,8 @@ class VMOps(object): return data def read_from_param_xenstore(self, instance_or_vm, keys=None): - """Returns the xenstore parameter record data for the specified VM + """ + Returns the xenstore parameter record data for the specified VM instance as a dict. Accepts an optional key or list of keys; if a value for 'keys' is passed, the returned dict is filtered to only return the values for those keys. @@ -1025,9 +1040,11 @@ class VMOps(object): return ret def add_to_param_xenstore(self, instance_or_vm, key, val): - """Takes a key/value pair and adds it to the xenstore parameter + """ + Takes a key/value pair and adds it to the xenstore parameter record for the given vm instance. If the key exists in xenstore, - it is overwritten""" + it is overwritten + """ vm_ref = self._get_vm_opaque_ref(instance_or_vm) self.remove_from_param_xenstore(instance_or_vm, key) jsonval = json.dumps(val) @@ -1035,7 +1052,8 @@ class VMOps(object): (vm_ref, key, jsonval)) def write_to_param_xenstore(self, instance_or_vm, mapping): - """Takes a dict and writes each key/value pair to the xenstore + """ + Takes a dict and writes each key/value pair to the xenstore parameter record for the given vm instance. Any existing data for those keys is overwritten. """ @@ -1043,7 +1061,8 @@ class VMOps(object): self.add_to_param_xenstore(instance_or_vm, k, v) def remove_from_param_xenstore(self, instance_or_vm, key_or_keys): - """Takes either a single key or a list of keys and removes + """ + Takes either a single key or a list of keys and removes them from the xenstore parameter record data for the given VM. If the key doesn't exist, the request is ignored. """ @@ -1069,7 +1088,8 @@ def _runproc(cmd): class SimpleDH(object): - """This class wraps all the functionality needed to implement + """ + This class wraps all the functionality needed to implement basic Diffie-Hellman-Merkle key exchange in Python. It features intelligent defaults for the prime and base numbers needed for the calculation, while allowing you to supply your own. It requires that @@ -1078,7 +1098,8 @@ class SimpleDH(object): is not available, a RuntimeError will be raised. """ def __init__(self, prime=None, base=None, secret=None): - """You can specify the values for prime and base if you wish; + """ + You can specify the values for prime and base if you wish; otherwise, reasonable default values will be used. """ if prime is None: -- cgit From 7cdc3add34b109e3f956f785b60a5aa5cf273e53 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 28 Mar 2011 12:24:41 +0200 Subject: Do not load extensions that start with a "_" --- nova/api/openstack/extensions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index 9d98d849a..439612faa 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -317,7 +317,7 @@ class ExtensionManager(object): LOG.audit(_('Loading extension file: %s'), f) mod_name, file_ext = os.path.splitext(os.path.split(f)[-1]) ext_path = os.path.join(self.path, f) - if file_ext.lower() == '.py': + if file_ext.lower() == '.py' and not mod_name.startswith('_'): mod = imp.load_source(mod_name, ext_path) ext_name = mod_name[0].upper() + mod_name[1:] try: -- cgit From df946c08acba6fe1234b13f04d3c46c3973647c2 Mon Sep 17 00:00:00 2001 From: Armando Migliaccio Date: Mon, 28 Mar 2011 11:52:28 +0100 Subject: addressed termie's review (second round) --- nova/network/xenapi_net.py | 14 ++-- nova/tests/test_xenapi.py | 2 +- nova/virt/xenapi/fake.py | 156 +++++++++++++++++++++------------------------ nova/virt/xenapi/vmops.py | 2 +- 4 files changed, 82 insertions(+), 92 deletions(-) diff --git a/nova/network/xenapi_net.py b/nova/network/xenapi_net.py index 7a9da8046..8603fd842 100644 --- a/nova/network/xenapi_net.py +++ b/nova/network/xenapi_net.py @@ -49,11 +49,9 @@ def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None): # If bridge does not exists # 1 - create network description = "network for nova bridge %s" % bridge - network_rec = { - 'name_label': bridge, + network_rec = {'name_label': bridge, 'name_description': description, - 'other_config': {}, - } + 'other_config': {}} network_ref = session.call_xenapi('network.create', network_rec) # 2 - find PIF for VLAN expr = 'field "device" = "%s" and \ @@ -66,8 +64,10 @@ def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None): _('Found no PIF for device %s') % FLAGS.vlan_interface) # 3 - create vlan for network for pif_ref in pifs.keys(): - session.call_xenapi('VLAN.create', pif_ref, - str(vlan_num), network_ref) + session.call_xenapi('VLAN.create', + pif_ref, + str(vlan_num), + network_ref) else: # Check VLAN tag is appropriate network_rec = session.call_xenapi('network.get_record', network_ref) @@ -76,7 +76,7 @@ def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None): # Retrieve VLAN from PIF pif_rec = session.call_xenapi('PIF.get_record', pif_ref) pif_vlan = int(pif_rec['VLAN']) - # Raise an exception if VLAN <> vlan_num + # Raise an exception if VLAN != vlan_num if pif_vlan != vlan_num: raise Exception(_("PIF %(pif_rec['uuid'])s for network " "%(bridge)s has VLAN id %(pif_vlan)d. " diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 6ec0525a7..9fdd1feeb 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -487,7 +487,7 @@ class XenAPIVMTestCase(test.TestCase): glance_stubs.FakeGlance.IMAGE_RAMDISK, instance_id=fake_instance_id) # TODO(salvatore-orlando): a complete test here would require - # A check for making sure the bridge for the VM's VIF is + # a check for making sure the bridge for the VM's VIF is # consistent with bridge specified in nova db self.network = network_bk diff --git a/nova/virt/xenapi/fake.py b/nova/virt/xenapi/fake.py index 6d17a642e..d084c725f 100644 --- a/nova/virt/xenapi/fake.py +++ b/nova/virt/xenapi/fake.py @@ -78,7 +78,10 @@ def reset(): for c in _CLASSES: _db_content[c] = {} create_host('fake') - create_vm('fake', 'Running', is_a_template=False, is_control_domain=True) + create_vm('fake', + 'Running', + is_a_template=False, + is_control_domain=True) def reset_table(table): @@ -88,26 +91,23 @@ def reset_table(table): def create_host(name_label): - return _create_object('host', { - 'name_label': name_label, - }) + return _create_object('host', + {'name_label': name_label}) def create_network(name_label, bridge): - return _create_object('network', { - 'name_label': name_label, - 'bridge': bridge, - }) + return _create_object('network', + {'name_label': name_label, + 'bridge': bridge}) def create_vm(name_label, status, is_a_template=False, is_control_domain=False): - return _create_object('VM', { - 'name_label': name_label, - 'power-state': status, - 'is_a_template': is_a_template, - 'is_control_domain': is_control_domain, - }) + return _create_object('VM', + {'name_label': name_label, + 'power-state': status, + 'is_a_template': is_a_template, + 'is_control_domain': is_control_domain}) def destroy_vm(vm_ref): @@ -129,27 +129,24 @@ def destroy_vdi(vdi_ref): def create_vdi(name_label, read_only, sr_ref, sharable): - return _create_object('VDI', { - 'name_label': name_label, - 'read_only': read_only, - 'SR': sr_ref, - 'type': '', - 'name_description': '', - 'sharable': sharable, - 'other_config': {}, - 'location': '', - 'xenstore_data': '', - 'sm_config': {}, - 'VBDs': {}, - }) + return _create_object('VDI', + {'name_label': name_label, + 'read_only': read_only, + 'SR': sr_ref, + 'type': '', + 'name_description': '', + 'sharable': sharable, + 'other_config': {}, + 'location': '', + 'xenstore_data': '', + 'sm_config': {}, + 'VBDs': {}}) def create_vbd(vm_ref, vdi_ref): - vbd_rec = { - 'VM': vm_ref, - 'VDI': vdi_ref, - 'currently_attached': False, - } + vbd_rec = {'VM': vm_ref, + 'VDI': vdi_ref, + 'currently_attached': False} vbd_ref = _create_object('VBD', vbd_rec) after_VBD_create(vbd_ref, vbd_rec) return vbd_ref @@ -175,19 +172,17 @@ def after_VM_create(vm_ref, vm_rec): def create_pbd(config, host_ref, sr_ref, attached): - return _create_object('PBD', { - 'device-config': config, - 'host': host_ref, - 'SR': sr_ref, - 'currently-attached': attached, - }) + return _create_object('PBD', + {'device-config': config, + 'host': host_ref, + 'SR': sr_ref, + 'currently-attached': attached}) def create_task(name_label): - return _create_object('task', { - 'name_label': name_label, - 'status': 'pending', - }) + return _create_object('task', + {'name_label': name_label, + 'status': 'pending'}) def create_local_pifs(): @@ -205,34 +200,32 @@ def create_local_srs(): def _create_local_sr(host_ref): - sr_ref = _create_object('SR', { - 'name_label': 'Local storage', - 'type': 'lvm', - 'content_type': 'user', - 'shared': False, - 'physical_size': str(1 << 30), - 'physical_utilisation': str(0), - 'virtual_allocation': str(0), - 'other_config': { - 'i18n-original-value-name_label': 'Local storage', - 'i18n-key': 'local-storage', - }, - 'VDIs': [] - }) + sr_ref = \ + _create_object('SR', + {'name_label': 'Local storage', + 'type': 'lvm', + 'content_type': 'user', + 'shared': False, + 'physical_size': str(1 << 30), + 'physical_utilisation': str(0), + 'virtual_allocation': str(0), + 'other_config': {'i18n-original-value-name_label': \ + 'Local storage', + 'i18n-key': 'local-storage'}, + 'VDIs': []}) pbd_ref = create_pbd('', host_ref, sr_ref, True) _db_content['SR'][sr_ref]['PBDs'] = [pbd_ref] return sr_ref def _create_local_pif(host_ref): - pif_ref = _create_object('PIF', { - 'name-label': 'Fake PIF', - 'MAC': '00:11:22:33:44:55', - 'physical': True, - 'VLAN': -1, - 'device': 'fake0', - 'host_uuid': host_ref, - }) + pif_ref = _create_object('PIF', + {'name-label': 'Fake PIF', + 'MAC': '00:11:22:33:44:55', + 'physical': True, + 'VLAN': -1, + 'device': 'fake0', + 'host_uuid': host_ref}) def _create_object(table, obj): @@ -260,19 +253,17 @@ def _create_sr(table, obj): def _create_vlan(pif_ref, vlan_num, network_ref): pif_rec = get_record('PIF', pif_ref) - vlan_pif_ref = _create_object('PIF', { - 'name-label': 'Fake VLAN PIF', - 'MAC': '00:11:22:33:44:55', - 'physical': True, - 'VLAN': vlan_num, - 'device': pif_rec['device'], - 'host_uuid': pif_rec['host_uuid'], - }) - return _create_object('VLAN', { - 'tagged-pif': pif_ref, - 'untagged-pif': vlan_pif_ref, - 'tag': vlan_num, - }) + vlan_pif_ref = _create_object('PIF', + {'name-label': 'Fake VLAN PIF', + 'MAC': '00:11:22:33:44:55', + 'physical': True, + 'VLAN': vlan_num, + 'device': pif_rec['device'], + 'host_uuid': pif_rec['host_uuid']}) + return _create_object('VLAN', + {'tagged-pif': pif_ref, + 'untagged-pif': vlan_pif_ref, + 'tag': vlan_num}) def get_all(table): @@ -334,7 +325,7 @@ class SessionBase(object): rec['device'] = '' def PIF_get_all_records_where(self, _1, _2): - # TODO (salvatore-orlando):filter table on _2 + # TODO (salvatore-orlando): filter table on _2 return _db_content['PIF'] def VM_get_xenstore_data(self, _1, vm_ref): @@ -347,7 +338,7 @@ class SessionBase(object): db_ref['xenstore_data'][key] = None def network_get_all_records_where(self, _1, _2): - # TODO (salvatore-orlando):filter table on _2 + # TODO (salvatore-orlando): filter table on _2 return _db_content['network'] def VM_add_to_xenstore_data(self, _1, vm_ref, key, value): @@ -385,10 +376,9 @@ class SessionBase(object): def _login(self, method, params): self._session = str(uuid.uuid4()) - _db_content['session'][self._session] = { - 'uuid': str(uuid.uuid4()), - 'this_host': _db_content['host'].keys()[0], - } + _db_content['session'][self._session] = \ + {'uuid': str(uuid.uuid4()), + 'this_host': _db_content['host'].keys()[0]} def _logout(self): s = self._session diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 9b18ac732..08046318e 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -338,6 +338,7 @@ class VMOps(object): :param instance: the instance that owns the VHD in question. :param dest: the destination host machine. :param disk_type: values are 'primary' or 'cow'. + """ vm_ref = VMHelper.lookup(self._session, instance.name) @@ -711,7 +712,6 @@ class VMOps(object): - unplug the instance VM's disk from the rescue VM. - teardown the rescue VM. - release the bootlock to allow the instance VM to start. - """ rescue_vm_ref = VMHelper.lookup(self._session, "%s-rescue" % instance.name) -- cgit From 184fa8239d54d20ff294cdb019d07989ed3d6c4d Mon Sep 17 00:00:00 2001 From: Armando Migliaccio Date: Mon, 28 Mar 2011 12:08:43 +0100 Subject: addressed termies review (third round) --- nova/tests/db/fakes.py | 63 ++++++++++++++++++++++------------------------- nova/tests/test_xenapi.py | 26 +++++++++---------- nova/virt/xenapi/fake.py | 2 +- nova/virt/xenapi/vmops.py | 3 ++- 4 files changed, 46 insertions(+), 48 deletions(-) diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py index f7610aa56..7ddfe377a 100644 --- a/nova/tests/db/fakes.py +++ b/nova/tests/db/fakes.py @@ -56,39 +56,36 @@ def stub_out_db_instance_api(stubs, injected=True): flavorid=5, rxtx_cap=5)} - flat_network_fields = { - 'id': 'fake_flat', - 'bridge': 'xenbr0', - 'label': 'fake_flat_network', - 'netmask': '255.255.255.0', - 'cidr_v6': 'fe80::a00:0/120', - 'netmask_v6': '120', - 'gateway': '10.0.0.1', - 'gateway_v6': 'fe80::a00:1', - 'broadcast': '10.0.0.255', - 'dns': '10.0.0.2', - 'ra_server': None, - 'injected': injected} - - vlan_network_fields = { - 'id': 'fake_vlan', - 'bridge': 'br111', - 'label': 'fake_vlan_network', - 'netmask': '255.255.255.0', - 'cidr_v6': 'fe80::a00:0/120', - 'netmask_v6': '120', - 'gateway': '10.0.0.1', - 'gateway_v6': 'fe80::a00:1', - 'broadcast': '10.0.0.255', - 'dns': '10.0.0.2', - 'ra_server': None, - 'vlan': 111, - 'injected': False} - - fixed_ip_fields = { - 'address': '10.0.0.3', - 'address_v6': 'fe80::a00:3', - 'network_id': 'fake_flat'} + flat_network_fields = {'id': 'fake_flat', + 'bridge': 'xenbr0', + 'label': 'fake_flat_network', + 'netmask': '255.255.255.0', + 'cidr_v6': 'fe80::a00:0/120', + 'netmask_v6': '120', + 'gateway': '10.0.0.1', + 'gateway_v6': 'fe80::a00:1', + 'broadcast': '10.0.0.255', + 'dns': '10.0.0.2', + 'ra_server': None, + 'injected': injected} + + vlan_network_fields = {'id': 'fake_vlan', + 'bridge': 'br111', + 'label': 'fake_vlan_network', + 'netmask': '255.255.255.0', + 'cidr_v6': 'fe80::a00:0/120', + 'netmask_v6': '120', + 'gateway': '10.0.0.1', + 'gateway_v6': 'fe80::a00:1', + 'broadcast': '10.0.0.255', + 'dns': '10.0.0.2', + 'ra_server': None, + 'vlan': 111, + 'injected': False} + + fixed_ip_fields = {'address': '10.0.0.3', + 'address_v6': 'fe80::a00:3', + 'network_id': 'fake_flat'} class FakeModel(object): """Stubs out for model.""" diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 9fdd1feeb..bc1469223 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -287,19 +287,19 @@ class XenAPIVMTestCase(test.TestCase): key = 'vm-data/networking/aabbccddeeff' xenstore_value = xenstore_data[key] tcpip_data = ast.literal_eval(xenstore_value) - self.assertEquals(tcpip_data, { - 'label': 'fake_flat_network', - 'broadcast': '10.0.0.255', - 'ips': [{'ip': '10.0.0.3', - 'netmask':'255.255.255.0', - 'enabled':'1'}], - 'ip6s': [{'ip': 'fe80::a8bb:ccff:fedd:eeff', - 'netmask': '120', - 'enabled': '1', - 'gateway': 'fe80::a00:1'}], - 'mac': 'aa:bb:cc:dd:ee:ff', - 'dns': ['10.0.0.2'], - 'gateway': '10.0.0.1'}) + self.assertEquals(tcpip_data, + {'label': 'fake_flat_network', + 'broadcast': '10.0.0.255', + 'ips': [{'ip': '10.0.0.3', + 'netmask':'255.255.255.0', + 'enabled':'1'}], + 'ip6s': [{'ip': 'fe80::a8bb:ccff:fedd:eeff', + 'netmask': '120', + 'enabled': '1', + 'gateway': 'fe80::a00:1'}], + 'mac': 'aa:bb:cc:dd:ee:ff', + 'dns': ['10.0.0.2'], + 'gateway': '10.0.0.1'}) def check_vm_params_for_windows(self): self.assertEquals(self.vm['platform']['nx'], 'true') diff --git a/nova/virt/xenapi/fake.py b/nova/virt/xenapi/fake.py index d084c725f..d79312a60 100644 --- a/nova/virt/xenapi/fake.py +++ b/nova/virt/xenapi/fake.py @@ -60,7 +60,7 @@ from nova import exception from nova import log as logging -_CLASSES = ['host', 'network', 'session', 'SR', 'VBD',\ +_CLASSES = ['host', 'network', 'session', 'SR', 'VBD', \ 'PBD', 'VDI', 'VIF', 'PIF', 'VM', 'VLAN', 'task'] _db_content = {} diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 08046318e..147419f90 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -668,7 +668,7 @@ class VMOps(object): self._wait_with_callback(instance.id, task, callback) def suspend(self, instance, callback): - """Suspend the specified instance""" + """Suspend the specified instance.""" vm_ref = self._get_vm_opaque_ref(instance) task = self._session.call_xenapi('Async.VM.suspend', vm_ref) self._wait_with_callback(instance.id, task, callback) @@ -686,6 +686,7 @@ class VMOps(object): - shutdown the instance VM. - set 'bootlock' to prevent the instance from starting in rescue. - spawn a rescue VM (the vm name-label will be instance-N-rescue). + """ rescue_vm_ref = VMHelper.lookup(self._session, "%s-rescue" % instance.name) -- cgit From d25968ab494f65ed90981e440169e31a7488befe Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 28 Mar 2011 15:21:53 +0200 Subject: Add friendlier message if an extension fails to include a correctly named class or factory. --- nova/api/openstack/extensions.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index 439612faa..4a7236863 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -321,7 +321,14 @@ class ExtensionManager(object): mod = imp.load_source(mod_name, ext_path) ext_name = mod_name[0].upper() + mod_name[1:] try: - new_ext = getattr(mod, ext_name)() + new_ext_class = getattr(mod, ext_name, None) + if not new_ext_class: + LOG.warning(_('Did not find expected name ' + '"%(ext_name)" in %(file)s'), + { 'ext_name': ext_name, + 'file': ext_path }) + continue + new_ext = new_ext_class() self._check_extension(new_ext) self.extensions[new_ext.get_alias()] = new_ext except AttributeError as ex: -- cgit From 9786a19ec0bc5176cc01b56d473a977b85800977 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 28 Mar 2011 15:34:20 +0200 Subject: Spell "warn" correctly. --- nova/api/openstack/extensions.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index 4a7236863..259d24a7d 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -323,10 +323,10 @@ class ExtensionManager(object): try: new_ext_class = getattr(mod, ext_name, None) if not new_ext_class: - LOG.warning(_('Did not find expected name ' - '"%(ext_name)" in %(file)s'), - { 'ext_name': ext_name, - 'file': ext_path }) + LOG.warn(_('Did not find expected name ' + '"%(ext_name)" in %(file)s'), + { 'ext_name': ext_name, + 'file': ext_path }) continue new_ext = new_ext_class() self._check_extension(new_ext) -- cgit From 8922630e70e97b52e363a861c76fe4a01b8418ff Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Mon, 28 Mar 2011 09:37:05 -0400 Subject: Fix typo in libvirt xml template --- nova/virt/libvirt.xml.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index 26f528cb1..a62c3b6a8 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -3,7 +3,7 @@ ${memory_kb} #if $type == 'lxc' - #set $disk prefix = '' + #set $disk_prefix = '' #set $disk_bus = '' exe /sbin/init -- cgit From dbd4eebd7905ae950187dbafeba450f9706e609a Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Mon, 28 Mar 2011 10:31:51 -0400 Subject: TopicConsumer -> TopicAdapterConsumer --- 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 b4ba157e1..0342c620a 100755 --- a/bin/nova-ajax-console-proxy +++ b/bin/nova-ajax-console-proxy @@ -115,7 +115,7 @@ class AjaxConsoleProxy(object): {'args': data['args'], 'last_activity': time.time()} conn = rpc.Connection.instance(new=True) - consumer = rpc.TopicConsumer( + consumer = rpc.TopicAdapterConsumer( connection=conn, topic=FLAGS.ajax_console_proxy_topic) consumer.register_callback(Callback()) -- cgit From 4aad5721bff628ef8b34e0c536e0e2415f2b63f4 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Mon, 28 Mar 2011 11:16:59 -0400 Subject: Removed 'is not None' to do more general truth-checking. Added rather verbose testing. --- nova/image/glance.py | 2 +- nova/tests/api/openstack/test_images.py | 69 +++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/nova/image/glance.py b/nova/image/glance.py index be9805b69..f0f1ecf57 100644 --- a/nova/image/glance.py +++ b/nova/image/glance.py @@ -220,7 +220,7 @@ def _convert_timestamps_to_datetimes(image_meta): Returns image with known timestamp fields converted to datetime objects """ for attr in ['created_at', 'updated_at', 'deleted_at']: - if image_meta.get(attr) is not None: + if image_meta.get(attr): image_meta[attr] = _parse_glance_iso8601_timestamp( image_meta[attr]) return image_meta diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index 1cdccadd6..88dd8f506 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -197,6 +197,73 @@ class GlanceImageServiceTest(test.TestCase, image_metas = self.service.detail(self.context) self.assertDictMatch(image_metas[0], expected) + def test_image_valid_date_format(self): + """ + Ensure 'created_at', 'updated_at', and 'deleted_at' can be valid + ISO strings. + """ + fixture = { + 'name': 'test image', + 'is_public': False, + 'properties': { + 'instance_id': '42', + 'user_id': '1', + }, + } + + valid_dates = ['2010-10-11T10:30:22', '2012-12-21T00:00:00'] + + for date in valid_dates: + fixture["created_at"] = date + fixture["updated_at"] = date + fixture["deleted_at"] = date + image_id = self.service.create(self.context, fixture)['id'] + self.assertDictMatch(self.sent_to_glance['metadata'], fixture) + + def test_image_invalid_date_format(self): + """ + Ensure `created_at`, `modified_at` can't be invalid dates. + """ + fixture = { + 'name': 'test image', + 'is_public': False, + 'properties': { + 'instance_id': '42', + 'user_id': '1', + }, + } + + invalid_dates = ['Not a date.', 4] + + for date in invalid_dates: + fixture["created_at"] = date + fixture["updated_at"] = date + fixture["deleted_at"] = date + self.assertRaises((TypeError, ValueError), self.service.create, + self.context, fixture) + + def test_image_blank_date_format(self): + """ + Ensure `created_at`, `modified_at` can be blank dates. + """ + fixture = { + 'name': 'test image', + 'is_public': False, + 'properties': { + 'instance_id': '42', + 'user_id': '1', + }, + } + + blank_dates = [None, ''] + + for date in blank_dates: + fixture["created_at"] = date + fixture["updated_at"] = date + fixture["deleted_at"] = date + image_id = self.service.create(self.context, fixture)['id'] + self.assertDictMatch(self.sent_to_glance['metadata'], fixture) + def test_create_without_instance_id(self): """ Ensure we can create an image without having to specify an @@ -235,6 +302,8 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): FLAGS.image_service = self.orig_image_service super(ImageControllerWithGlanceServiceTest, self).tearDown() + + def test_get_image_index(self): req = webob.Request.blank('/v1.0/images') res = req.get_response(fakes.wsgi_app()) -- cgit From 23bed216dbbd512e733ecf6065105b2d20703531 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Mon, 28 Mar 2011 13:04:02 -0400 Subject: Added MUCH more flexiable iso8601 parser dep for added stability. --- nova/image/glance.py | 8 ++-- nova/tests/api/openstack/test_images.py | 69 --------------------------------- nova/tests/image/test_glance.py | 50 ++++++++++++++++++++++++ tools/pip-requires | 1 + 4 files changed, 54 insertions(+), 74 deletions(-) diff --git a/nova/image/glance.py b/nova/image/glance.py index f0f1ecf57..c08e2e0e8 100644 --- a/nova/image/glance.py +++ b/nova/image/glance.py @@ -20,6 +20,8 @@ from __future__ import absolute_import import datetime +import iso8601 + from glance.common import exception as glance_exception from nova import exception @@ -230,8 +232,4 @@ def _parse_glance_iso8601_timestamp(timestamp): """ Parse a subset of iso8601 timestamps into datetime objects """ - GLANCE_FMT = "%Y-%m-%dT%H:%M:%S" - ISO_FMT = "%Y-%m-%dT%H:%M:%S.%f" - # FIXME(sirp): Glance is not returning in ISO format, we should fix Glance - # to do so, and then switch to parsing it here - return datetime.datetime.strptime(timestamp, GLANCE_FMT) + return iso8601.parse_date(timestamp).replace(tzinfo=None) diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index 88dd8f506..1cdccadd6 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -197,73 +197,6 @@ class GlanceImageServiceTest(test.TestCase, image_metas = self.service.detail(self.context) self.assertDictMatch(image_metas[0], expected) - def test_image_valid_date_format(self): - """ - Ensure 'created_at', 'updated_at', and 'deleted_at' can be valid - ISO strings. - """ - fixture = { - 'name': 'test image', - 'is_public': False, - 'properties': { - 'instance_id': '42', - 'user_id': '1', - }, - } - - valid_dates = ['2010-10-11T10:30:22', '2012-12-21T00:00:00'] - - for date in valid_dates: - fixture["created_at"] = date - fixture["updated_at"] = date - fixture["deleted_at"] = date - image_id = self.service.create(self.context, fixture)['id'] - self.assertDictMatch(self.sent_to_glance['metadata'], fixture) - - def test_image_invalid_date_format(self): - """ - Ensure `created_at`, `modified_at` can't be invalid dates. - """ - fixture = { - 'name': 'test image', - 'is_public': False, - 'properties': { - 'instance_id': '42', - 'user_id': '1', - }, - } - - invalid_dates = ['Not a date.', 4] - - for date in invalid_dates: - fixture["created_at"] = date - fixture["updated_at"] = date - fixture["deleted_at"] = date - self.assertRaises((TypeError, ValueError), self.service.create, - self.context, fixture) - - def test_image_blank_date_format(self): - """ - Ensure `created_at`, `modified_at` can be blank dates. - """ - fixture = { - 'name': 'test image', - 'is_public': False, - 'properties': { - 'instance_id': '42', - 'user_id': '1', - }, - } - - blank_dates = [None, ''] - - for date in blank_dates: - fixture["created_at"] = date - fixture["updated_at"] = date - fixture["deleted_at"] = date - image_id = self.service.create(self.context, fixture)['id'] - self.assertDictMatch(self.sent_to_glance['metadata'], fixture) - def test_create_without_instance_id(self): """ Ensure we can create an image without having to specify an @@ -302,8 +235,6 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): FLAGS.image_service = self.orig_image_service super(ImageControllerWithGlanceServiceTest, self).tearDown() - - def test_get_image_index(self): req = webob.Request.blank('/v1.0/images') res = req.get_response(fakes.wsgi_app()) diff --git a/nova/tests/image/test_glance.py b/nova/tests/image/test_glance.py index d03aa9cc8..dfdce7584 100644 --- a/nova/tests/image/test_glance.py +++ b/nova/tests/image/test_glance.py @@ -57,6 +57,7 @@ class NullWriter(object): class BaseGlanceTest(unittest.TestCase): NOW_GLANCE_FORMAT = "2010-10-11T10:30:22" NOW_DATETIME = datetime.datetime(2010, 10, 11, 10, 30, 22) + NOW_ISO_FORMAT = "2010-10-11T10:30:22.000000" def setUp(self): # FIXME(sirp): we can probably use stubs library here rather than @@ -74,6 +75,10 @@ class BaseGlanceTest(unittest.TestCase): self.assertEqual(image_meta['updated_at'], None) self.assertEqual(image_meta['deleted_at'], None) + def assertDateTimesBlank(self, image_meta): + self.assertEqual(image_meta['updated_at'], '') + self.assertEqual(image_meta['deleted_at'], '') + class TestGlanceImageServiceProperties(BaseGlanceTest): def test_show_passes_through_to_client(self): @@ -108,33 +113,65 @@ class TestGetterDateTimeNoneTests(BaseGlanceTest): image_meta = self.service.show(self.context, 'image1') self.assertDateTimesEmpty(image_meta) + def test_show_handles_blank_datetimes(self): + self.client.images = self._make_blank_datetime_fixtures() + image_meta = self.service.show(self.context, 'image1') + self.assertDateTimesBlank(image_meta) + def test_detail_handles_none_datetimes(self): self.client.images = self._make_none_datetime_fixtures() image_meta = self.service.detail(self.context)[0] self.assertDateTimesEmpty(image_meta) + def test_detail_handles_blank_datetimes(self): + self.client.images = self._make_blank_datetime_fixtures() + image_meta = self.service.detail(self.context)[0] + self.assertDateTimesBlank(image_meta) + def test_get_handles_none_datetimes(self): self.client.images = self._make_none_datetime_fixtures() writer = NullWriter() image_meta = self.service.get(self.context, 'image1', writer) self.assertDateTimesEmpty(image_meta) + def test_get_handles_blank_datetimes(self): + self.client.images = self._make_blank_datetime_fixtures() + writer = NullWriter() + image_meta = self.service.get(self.context, 'image1', writer) + self.assertDateTimesBlank(image_meta) + def test_show_makes_datetimes(self): self.client.images = self._make_datetime_fixtures() image_meta = self.service.show(self.context, 'image1') self.assertDateTimesFilled(image_meta) + def test_show_makes_datetimes_iso(self): + self.client.images = self._make_iso_fixtures() + image_meta = self.service.show(self.context, 'image1') + self.assertDateTimesFilled(image_meta) + def test_detail_makes_datetimes(self): self.client.images = self._make_datetime_fixtures() image_meta = self.service.detail(self.context)[0] self.assertDateTimesFilled(image_meta) + def test_detail_makes_datetimes_iso(self): + self.client.images = self._make_iso_fixtures() + image_meta = self.service.detail(self.context)[0] + self.assertDateTimesFilled(image_meta) + def test_get_makes_datetimes(self): self.client.images = self._make_datetime_fixtures() writer = NullWriter() image_meta = self.service.get(self.context, 'image1', writer) self.assertDateTimesFilled(image_meta) + def test_get_makes_datetimes_iso(self): + self.client.images = self._make_iso_fixtures() + writer = NullWriter() + image_meta = self.service.get(self.context, 'image1', writer) + self.assertDateTimesFilled(image_meta) + def _make_datetime_fixtures(self): fixtures = {'image1': {'name': 'image1', 'is_public': True, 'created_at': self.NOW_GLANCE_FORMAT, @@ -142,12 +179,25 @@ class TestGetterDateTimeNoneTests(BaseGlanceTest): 'deleted_at': self.NOW_GLANCE_FORMAT}} return fixtures + def _make_iso_fixtures(self): + fixtures = {'image1': {'name': 'image1', 'is_public': True, + 'created_at': self.NOW_ISO_FORMAT, + 'updated_at': self.NOW_ISO_FORMAT, + 'deleted_at': self.NOW_ISO_FORMAT}} + return fixtures + def _make_none_datetime_fixtures(self): fixtures = {'image1': {'name': 'image1', 'is_public': True, 'updated_at': None, 'deleted_at': None}} return fixtures + def _make_blank_datetime_fixtures(self): + fixtures = {'image1': {'name': 'image1', 'is_public': True, + 'updated_at': '', + 'deleted_at': ''}} + return fixtures + class TestMutatorDateTimeTests(BaseGlanceTest): """Tests create(), update()""" diff --git a/tools/pip-requires b/tools/pip-requires index 4ab9644d8..5cd80d1f4 100644 --- a/tools/pip-requires +++ b/tools/pip-requires @@ -31,3 +31,4 @@ netaddr sphinx glance suds==0.4 +iso8601 -- cgit From 56b4dd3929448585c15c8d11c5fe1569ce21ea7d Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Mon, 28 Mar 2011 13:18:47 -0400 Subject: Removed extra dependency as per suggestion, although it fixes the issue much better IMO, we should be safe sticking with using the format from python's isoformat() --- nova/image/glance.py | 5 ++--- nova/tests/image/test_glance.py | 26 +------------------------- 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/nova/image/glance.py b/nova/image/glance.py index c08e2e0e8..32c9fa6be 100644 --- a/nova/image/glance.py +++ b/nova/image/glance.py @@ -20,8 +20,6 @@ from __future__ import absolute_import import datetime -import iso8601 - from glance.common import exception as glance_exception from nova import exception @@ -232,4 +230,5 @@ def _parse_glance_iso8601_timestamp(timestamp): """ Parse a subset of iso8601 timestamps into datetime objects """ - return iso8601.parse_date(timestamp).replace(tzinfo=None) + ISO_FMT = "%Y-%m-%dT%H:%M:%S.%f" + return datetime.datetime.strptime(timestamp, ISO_FMT) diff --git a/nova/tests/image/test_glance.py b/nova/tests/image/test_glance.py index dfdce7584..dfa754b89 100644 --- a/nova/tests/image/test_glance.py +++ b/nova/tests/image/test_glance.py @@ -55,9 +55,8 @@ class NullWriter(object): class BaseGlanceTest(unittest.TestCase): - NOW_GLANCE_FORMAT = "2010-10-11T10:30:22" + NOW_GLANCE_FORMAT = "2010-10-11T10:30:22.000000" NOW_DATETIME = datetime.datetime(2010, 10, 11, 10, 30, 22) - NOW_ISO_FORMAT = "2010-10-11T10:30:22.000000" def setUp(self): # FIXME(sirp): we can probably use stubs library here rather than @@ -145,33 +144,17 @@ class TestGetterDateTimeNoneTests(BaseGlanceTest): image_meta = self.service.show(self.context, 'image1') self.assertDateTimesFilled(image_meta) - def test_show_makes_datetimes_iso(self): - self.client.images = self._make_iso_fixtures() - image_meta = self.service.show(self.context, 'image1') - self.assertDateTimesFilled(image_meta) - def test_detail_makes_datetimes(self): self.client.images = self._make_datetime_fixtures() image_meta = self.service.detail(self.context)[0] self.assertDateTimesFilled(image_meta) - def test_detail_makes_datetimes_iso(self): - self.client.images = self._make_iso_fixtures() - image_meta = self.service.detail(self.context)[0] - self.assertDateTimesFilled(image_meta) - def test_get_makes_datetimes(self): self.client.images = self._make_datetime_fixtures() writer = NullWriter() image_meta = self.service.get(self.context, 'image1', writer) self.assertDateTimesFilled(image_meta) - def test_get_makes_datetimes_iso(self): - self.client.images = self._make_iso_fixtures() - writer = NullWriter() - image_meta = self.service.get(self.context, 'image1', writer) - self.assertDateTimesFilled(image_meta) - def _make_datetime_fixtures(self): fixtures = {'image1': {'name': 'image1', 'is_public': True, 'created_at': self.NOW_GLANCE_FORMAT, @@ -179,13 +162,6 @@ class TestGetterDateTimeNoneTests(BaseGlanceTest): 'deleted_at': self.NOW_GLANCE_FORMAT}} return fixtures - def _make_iso_fixtures(self): - fixtures = {'image1': {'name': 'image1', 'is_public': True, - 'created_at': self.NOW_ISO_FORMAT, - 'updated_at': self.NOW_ISO_FORMAT, - 'deleted_at': self.NOW_ISO_FORMAT}} - return fixtures - def _make_none_datetime_fixtures(self): fixtures = {'image1': {'name': 'image1', 'is_public': True, 'updated_at': None, -- cgit From e043561a8d5dc0c3183ec7e3a5a44f2aa306d2fd Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Mon, 28 Mar 2011 13:20:46 -0400 Subject: Removed iso8601 dep from pip-requires --- tools/pip-requires | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/pip-requires b/tools/pip-requires index 5cd80d1f4..4ab9644d8 100644 --- a/tools/pip-requires +++ b/tools/pip-requires @@ -31,4 +31,3 @@ netaddr sphinx glance suds==0.4 -iso8601 -- cgit From 5977a511ed202fcf396e7c60d713eb5329d6883b Mon Sep 17 00:00:00 2001 From: Mark Washenberger Date: Mon, 28 Mar 2011 13:30:15 -0400 Subject: style changes --- nova/api/openstack/servers.py | 12 ++++++------ nova/tests/api/openstack/test_servers.py | 5 ----- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index a8e3e7900..a98f81d98 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -267,11 +267,11 @@ class Controller(wsgi.Controller): actions = { 'changePassword': self._action_change_password, - 'reboot': self._action_reboot, - 'resize': self._action_resize, + 'reboot': self._action_reboot, + 'resize': self._action_resize, 'confirmResize': self._action_confirm_resize, - 'revertResize': self._action_revert_resize, - 'rebuild': self._action_rebuild, + 'revertResize': self._action_revert_resize, + 'rebuild': self._action_rebuild, } input_dict = self._deserialize(req.body, req.get_content_type()) @@ -595,8 +595,8 @@ class ControllerV11(Controller): def _action_change_password(self, input_dict, req, id): context = req.environ['nova.context'] - if not 'changePassword' in input_dict \ - or not 'adminPass' in input_dict['changePassword']: + if (not 'changePassword' in input_dict + or not 'adminPass' in input_dict['changePassword']): return exc.HTTPBadRequest() password = input_dict['changePassword']['adminPass'] self.compute_api.set_admin_password(context, id, password) diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index d2a72dd10..25d69401d 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -655,20 +655,16 @@ class ServersTest(test.TestCase): def test_server_change_password_v1_1(self): class MockSetAdminPassword(object): - def __init__(self): - self.called = False self.instance_id = None self.password = None def __call__(self, context, instance_id, password): - self.called = True self.instance_id = instance_id self.password = password mock_method = MockSetAdminPassword() self.stubs.Set(nova.compute.api.API, 'set_admin_password', mock_method) - body = {'changePassword': {'adminPass': '1234pass'}} req = webob.Request.blank('/v1.1/servers/1/action') req.method = 'POST' @@ -676,7 +672,6 @@ class ServersTest(test.TestCase): req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 202) - self.assertTrue(mock_method.called) self.assertEqual(mock_method.instance_id, '1') self.assertEqual(mock_method.password, '1234pass') -- cgit From 71347f2e9d6195a25cabff782c7058bed006e286 Mon Sep 17 00:00:00 2001 From: Mark Washenberger Date: Mon, 28 Mar 2011 13:40:16 -0400 Subject: lock down requirements for change password --- nova/api/openstack/servers.py | 2 ++ nova/tests/api/openstack/test_servers.py | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index a98f81d98..b5727a7e1 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -599,6 +599,8 @@ class ControllerV11(Controller): or not 'adminPass' in input_dict['changePassword']): return exc.HTTPBadRequest() password = input_dict['changePassword']['adminPass'] + if not isinstance(password, basestring) or password == '': + return exc.HTTPBadRequest() self.compute_api.set_admin_password(context, id, password) return exc.HTTPAccepted() diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 25d69401d..6d6be817a 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -684,6 +684,33 @@ class ServersTest(test.TestCase): res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 400) + def test_server_change_password_empty_string_v1_1(self): + body = {'changePassword': {'adminPass': ''}} + req = webob.Request.blank('/v1.1/servers/1/action') + req.method = 'POST' + req.content_type = 'application/json' + req.body = json.dumps(body) + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 400) + + def test_server_change_password_none_v1_1(self): + body = {'changePassword': {'adminPass': None}} + req = webob.Request.blank('/v1.1/servers/1/action') + req.method = 'POST' + req.content_type = 'application/json' + req.body = json.dumps(body) + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 400) + + def test_server_change_password_not_a_string_v1_1(self): + body = {'changePassword': {'adminPass': 1234}} + req = webob.Request.blank('/v1.1/servers/1/action') + req.method = 'POST' + req.content_type = 'application/json' + req.body = json.dumps(body) + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 400) + def test_server_reboot(self): body = dict(server=dict( name='server_test', imageId=2, flavorId=2, metadata={}, -- cgit From 805cb3609379827d1643785be83f75b69b602d74 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Mon, 28 Mar 2011 13:44:33 -0400 Subject: Fix libvirt merge mistake --- nova/virt/libvirt.xml.template | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index a62c3b6a8..894b216e9 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -83,22 +83,24 @@ #end if #end if #end if + +#for $nic in $nics - - + + - - - -#if $getVar('extra_params', False) - ${extra_params} + + + +#if $getVar('nic.extra_params', False) + ${nic.extra_params} #end if -#if $getVar('gateway_v6', False) - +#if $getVar('nic.gateway_v6', False) + #end if - +#end for -- cgit From 36e1510e4ad4a83bb062cdd82dc91d4ea15d1c5e Mon Sep 17 00:00:00 2001 From: termie Date: Mon, 28 Mar 2011 10:46:02 -0700 Subject: HACKING update for docstrings --- HACKING | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/HACKING b/HACKING index e58d60e58..95afc0f74 100644 --- a/HACKING +++ b/HACKING @@ -50,17 +50,22 @@ Human Alphabetical Order Examples Docstrings ---------- - """Summary of the function, class or method, less than 80 characters. + """A one line docstring looks like this and ends in a period.""" - New paragraph after newline that explains in more detail any general - information about the function, class or method. After this, if defining - parameters and return types use the Sphinx format. After that an extra - newline then close the quotations. + + """A multiline docstring has a one-line summary, less than 80 characters. + + Then a new paragraph after a newline that explains in more detail any + general information about the function, class or method. Example usages + are also great to have here if it is a complex class for function. When writing the docstring for a class, an extra line should be placed after the closing quotations. For more in-depth explanations for these decisions see http://www.python.org/dev/peps/pep-0257/ + If you are going to describe parameters and return values, use Sphinx, the + appropriate syntax is as follows. + :param foo: the foo parameter :param bar: the bar parameter :returns: description of the return value -- cgit From dbf14e9b6cc337233ef95b03fd1c2fdba8ebf8a7 Mon Sep 17 00:00:00 2001 From: termie Date: Mon, 28 Mar 2011 10:47:08 -0700 Subject: add snapshot support for libvirt --- nova/virt/libvirt_conn.py | 71 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 36457ee87..4456ffc12 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -38,12 +38,15 @@ Supports KVM, QEMU, UML, and XEN. import multiprocessing import os -import shutil -import sys import random +import shutil import subprocess +import sys +import tempfile +import time import uuid from xml.dom import minidom +from xml.etree import ElementTree from eventlet import greenthread from eventlet import tpool @@ -111,6 +114,8 @@ flags.DEFINE_string('live_migration_flag', 'Define live migration behavior.') flags.DEFINE_integer('live_migration_bandwidth', 0, 'Define live migration behavior') +flags.DEFINE_string('qemu_img', 'qemu-img', + 'binary to use for qemu-img commands') def get_connection(read_only): @@ -397,10 +402,64 @@ class LibvirtConnection(driver.ComputeDriver): @exception.wrap_exception def snapshot(self, instance, image_id): - """ Create snapshot from a running VM instance """ - raise NotImplementedError( - _("Instance snapshotting is not supported for libvirt" - "at this time")) + """Create snapshot from a running VM instance. + + This command only works with qemu 0.14+, the qemu_img flag is + provided so that a locally compiled binary of qemu-img can be used + to support this command. + + """ + image_service = utils.import_object(FLAGS.image_service) + virt_dom = self._conn.lookupByName(instance['name']) + elevated = context.get_admin_context() + + base = image_service.show(elevated, instance['image_id']) + + metadata = {'type': 'machine', + 'is_public': False, + 'properties': {'architecture': base['architecture'], + 'kernel_id': instance['kernel_id'], + 'image_location': 'snapshot', + 'image_state': 'available', + 'owner_id': instance['project_id'], + 'ramdisk_id': instance['ramdisk_id'], + } + } + + # Make the snapshot + snapshot_name = uuid.uuid4().hex + snapshot_xml = """ + + %s + + """ % snapshot_name + snapshot_ptr = virt_dom.snapshotCreateXML(snapshot_xml, 0) + + # Find the disk + xml_desc = virt_dom.XMLDesc(0) + domain = ElementTree.fromstring(xml_desc) + source = domain.find('devices/disk/source') + disk_path = source.get('file') + + # Export the snapshot to a raw image + temp_dir = tempfile.mkdtemp() + out_path = os.path.join(temp_dir, snapshot_name) + qemu_img_cmd = '%s convert -f qcow2 -O raw -s %s %s %s' % ( + FLAGS.qemu_img, + snapshot_name, + disk_path, + out_path) + utils.execute(qemu_img_cmd) + + # Upload that image to the image service + with open(out_path) as image_file: + image_service.update(elevated, + image_id, + metadata, + image_file) + + # Clean up + shutil.rmtree(temp_dir) @exception.wrap_exception def reboot(self, instance): -- cgit From 1e4024b72218a07d1e535878337547cf16406dd8 Mon Sep 17 00:00:00 2001 From: termie Date: Mon, 28 Mar 2011 10:47:11 -0700 Subject: update glance params per review --- nova/virt/libvirt_conn.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 4456ffc12..80eb64f3c 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -415,9 +415,12 @@ class LibvirtConnection(driver.ComputeDriver): base = image_service.show(elevated, instance['image_id']) - metadata = {'type': 'machine', + metadata = {'disk_format': base['disk_format'], + 'container_format': base['container_format'], 'is_public': False, 'properties': {'architecture': base['architecture'], + 'type': base['type'], + 'name': '%s.%s' % (base['name'], image_id), 'kernel_id': instance['kernel_id'], 'image_location': 'snapshot', 'image_state': 'available', -- cgit From de07a6409d575af5db748bdbfa2cc57881136d66 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Mon, 28 Mar 2011 13:47:18 -0400 Subject: Decided to not break old format so this should work with the way Glance used to work and the way glace works now..The best of both worlds? --- nova/image/glance.py | 12 ++++++++++-- nova/tests/image/test_glance.py | 27 +++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/nova/image/glance.py b/nova/image/glance.py index 32c9fa6be..34fc78e71 100644 --- a/nova/image/glance.py +++ b/nova/image/glance.py @@ -230,5 +230,13 @@ def _parse_glance_iso8601_timestamp(timestamp): """ Parse a subset of iso8601 timestamps into datetime objects """ - ISO_FMT = "%Y-%m-%dT%H:%M:%S.%f" - return datetime.datetime.strptime(timestamp, ISO_FMT) + ISO_FORMATS = ["%Y-%m-%dT%H:%M:%S.%f", "%Y-%m-%dT%H:%M:%S"] + + for iso_format in ISO_FORMATS: + try: + return datetime.datetime.strptime(timestamp, iso_format) + except ValueError: + pass + + raise ValueError(_("""%(timestamp)s does not follow any of the \ +signatures: %(ISO_FORMATS)s""") % (locals())) diff --git a/nova/tests/image/test_glance.py b/nova/tests/image/test_glance.py index dfa754b89..9d0b14613 100644 --- a/nova/tests/image/test_glance.py +++ b/nova/tests/image/test_glance.py @@ -55,6 +55,7 @@ class NullWriter(object): class BaseGlanceTest(unittest.TestCase): + NOW_GLANCE_OLD_FORMAT = "2010-10-11T10:30:22" NOW_GLANCE_FORMAT = "2010-10-11T10:30:22.000000" NOW_DATETIME = datetime.datetime(2010, 10, 11, 10, 30, 22) @@ -143,23 +144,41 @@ class TestGetterDateTimeNoneTests(BaseGlanceTest): self.client.images = self._make_datetime_fixtures() image_meta = self.service.show(self.context, 'image1') self.assertDateTimesFilled(image_meta) + image_meta = self.service.show(self.context, 'image2') + self.assertDateTimesFilled(image_meta) def test_detail_makes_datetimes(self): self.client.images = self._make_datetime_fixtures() image_meta = self.service.detail(self.context)[0] self.assertDateTimesFilled(image_meta) + image_meta = self.service.detail(self.context)[1] + self.assertDateTimesFilled(image_meta) def test_get_makes_datetimes(self): self.client.images = self._make_datetime_fixtures() writer = NullWriter() image_meta = self.service.get(self.context, 'image1', writer) self.assertDateTimesFilled(image_meta) + image_meta = self.service.get(self.context, 'image2', writer) + self.assertDateTimesFilled(image_meta) def _make_datetime_fixtures(self): - fixtures = {'image1': {'name': 'image1', 'is_public': True, - 'created_at': self.NOW_GLANCE_FORMAT, - 'updated_at': self.NOW_GLANCE_FORMAT, - 'deleted_at': self.NOW_GLANCE_FORMAT}} + fixtures = { + 'image1': { + 'name': 'image1', + 'is_public': True, + 'created_at': self.NOW_GLANCE_FORMAT, + 'updated_at': self.NOW_GLANCE_FORMAT, + 'deleted_at': self.NOW_GLANCE_FORMAT, + }, + 'image2': { + 'name': 'image2', + 'is_public': True, + 'created_at': self.NOW_GLANCE_OLD_FORMAT, + 'updated_at': self.NOW_GLANCE_OLD_FORMAT, + 'deleted_at': self.NOW_GLANCE_OLD_FORMAT, + }, + } return fixtures def _make_none_datetime_fixtures(self): -- cgit From 9c61085ea9612be24e9975ac3fba456874b89f08 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Mon, 28 Mar 2011 13:49:51 -0400 Subject: Add more unit tests for lxc --- nova/tests/test_virt.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index cee044279..ed7943ace 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -257,7 +257,9 @@ class LibvirtConnTestCase(test.TestCase): check = [ (lambda t: t.find('.').get('type'), 'lxc'), - (lambda t: t.find('./os/type').text, 'exe')] + (lambda t: t.find('./os/type').text, 'exe'), + (lambda t: t.find('./devices/filesystem/source').get('dir'), 'rootfs'), + (lambda t: t.find('./devices/filesystem/target').get('dir'), '/')] for i, (check, expected_result) in enumerate(check): self.assertEqual(check(tree), -- cgit From 63747d35929a1df0a29792f41657b4821c5787a3 Mon Sep 17 00:00:00 2001 From: Mark Washenberger Date: Mon, 28 Mar 2011 13:50:24 -0400 Subject: pep8 whitespace --- nova/api/openstack/servers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index b5727a7e1..aaae17a39 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -595,7 +595,7 @@ class ControllerV11(Controller): def _action_change_password(self, input_dict, req, id): context = req.environ['nova.context'] - if (not 'changePassword' in input_dict + if (not 'changePassword' in input_dict or not 'adminPass' in input_dict['changePassword']): return exc.HTTPBadRequest() password = input_dict['changePassword']['adminPass'] -- cgit From 14337b0a31c8f04d8044e234eb295b41a9a9c5ce Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Mon, 28 Mar 2011 14:02:53 -0400 Subject: adding shared_ip_groups testing; replacing all shared_ip_groups contoller code with HTTPNotImplemented; moving shared_ip_groups controller to APIRouterV10 --- nova/api/openstack/__init__.py | 8 +++--- nova/api/openstack/shared_ip_groups.py | 6 ++--- nova/tests/api/openstack/test_shared_ip_groups.py | 30 ++++++++++++++++++++--- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 8fabbce8e..cf53ffcd6 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -119,10 +119,6 @@ class APIRouter(wsgi.Router): mapper.resource("image", "images", controller=images.Controller(), collection={'detail': 'GET'}) - mapper.resource("shared_ip_group", "shared_ip_groups", - collection={'detail': 'GET'}, - controller=shared_ip_groups.Controller()) - _limits = limits.LimitsController() mapper.resource("limit", "limits", controller=_limits) @@ -141,6 +137,10 @@ class APIRouterV10(APIRouter): controller=flavors.ControllerV10(), collection={'detail': 'GET'}) + mapper.resource("shared_ip_group", "shared_ip_groups", + collection={'detail': 'GET'}, + controller=shared_ip_groups.Controller()) + class APIRouterV11(APIRouter): """Define routes specific to OpenStack API V1.1.""" diff --git a/nova/api/openstack/shared_ip_groups.py b/nova/api/openstack/shared_ip_groups.py index 5d78f9377..ee7991d7f 100644 --- a/nova/api/openstack/shared_ip_groups.py +++ b/nova/api/openstack/shared_ip_groups.py @@ -42,11 +42,11 @@ class Controller(wsgi.Controller): def index(self, req): """ Returns a list of Shared IP Groups for the user """ - return dict(sharedIpGroups=[]) + raise faults.Fault(exc.HTTPNotImplemented()) def show(self, req, id): """ Shows in-depth information on a specific Shared IP Group """ - return _translate_keys({}) + raise faults.Fault(exc.HTTPNotImplemented()) def update(self, req, id): """ You can't update a Shared IP Group """ @@ -58,7 +58,7 @@ class Controller(wsgi.Controller): def detail(self, req): """ Returns a complete list of Shared IP Groups """ - return _translate_detail_keys({}) + raise faults.Fault(exc.HTTPNotImplemented()) def create(self, req): """ Creates a new Shared IP group """ diff --git a/nova/tests/api/openstack/test_shared_ip_groups.py b/nova/tests/api/openstack/test_shared_ip_groups.py index b4de2ef41..c2bd7e45a 100644 --- a/nova/tests/api/openstack/test_shared_ip_groups.py +++ b/nova/tests/api/openstack/test_shared_ip_groups.py @@ -16,25 +16,49 @@ # under the License. import stubout +import webob from nova import test from nova.api.openstack import shared_ip_groups +from nova.tests.api.openstack import fakes class SharedIpGroupsTest(test.TestCase): def setUp(self): super(SharedIpGroupsTest, self).setUp() self.stubs = stubout.StubOutForTesting() + fakes.FakeAuthManager.reset_fake_data() + fakes.FakeAuthDatabase.data = {} + fakes.stub_out_auth(self.stubs) def tearDown(self): self.stubs.UnsetAll() super(SharedIpGroupsTest, self).tearDown() def test_get_shared_ip_groups(self): - pass + req = webob.Request.blank('/v1.0/shared_ip_groups') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 501) def test_create_shared_ip_group(self): - pass + req = webob.Request.blank('/v1.0/shared_ip_groups') + req.method = 'POST' + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 501) + + def test_update_shared_ip_group(self): + req = webob.Request.blank('/v1.0/shared_ip_groups/12') + req.method = 'PUT' + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 501) def test_delete_shared_ip_group(self): - pass + req = webob.Request.blank('/v1.0/shared_ip_groups/12') + req.method = 'DELETE' + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 501) + + def test_deprecated_v11(self): + req = webob.Request.blank('/v1.1/shared_ip_groups') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 404) -- cgit From e44ce1a95baddd4f6d511d8be253167436395cb2 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Mon, 28 Mar 2011 14:07:33 -0400 Subject: More pep8 corrections --- nova/tests/test_virt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index ed7943ace..8cee55576 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -258,8 +258,8 @@ class LibvirtConnTestCase(test.TestCase): check = [ (lambda t: t.find('.').get('type'), 'lxc'), (lambda t: t.find('./os/type').text, 'exe'), - (lambda t: t.find('./devices/filesystem/source').get('dir'), 'rootfs'), - (lambda t: t.find('./devices/filesystem/target').get('dir'), '/')] + (lambda t: t.find('./devices/filesystem/source').get('dir'), 'rootfs'), + (lambda t: t.find('./devices/filesystem/target').get('dir'), '/')] for i, (check, expected_result) in enumerate(check): self.assertEqual(check(tree), -- cgit From b6df504c33cfa0fe02e31962578b77d841e1e6d8 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Mon, 28 Mar 2011 14:31:12 -0400 Subject: backup_schedule tests corrected; controller moved to APIRouterV10; making controller fully HTTPNotImplemented --- nova/api/openstack/__init__.py | 10 +++++----- nova/api/openstack/backup_schedules.py | 6 +++++- nova/tests/api/openstack/test_servers.py | 22 ++++++++++++++++------ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 8fabbce8e..149abfeb8 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -106,11 +106,6 @@ class APIRouter(wsgi.Router): controller=accounts.Controller(), collection={'detail': 'GET'}) - mapper.resource("backup_schedule", "backup_schedule", - controller=backup_schedules.Controller(), - parent_resource=dict(member_name='server', - collection_name='servers')) - mapper.resource("console", "consoles", controller=consoles.Controller(), parent_resource=dict(member_name='server', @@ -141,6 +136,11 @@ class APIRouterV10(APIRouter): controller=flavors.ControllerV10(), collection={'detail': 'GET'}) + mapper.resource("backup_schedule", "backup_schedule", + controller=backup_schedules.Controller(), + parent_resource=dict(member_name='server', + collection_name='servers')) + class APIRouterV11(APIRouter): """Define routes specific to OpenStack API V1.1.""" diff --git a/nova/api/openstack/backup_schedules.py b/nova/api/openstack/backup_schedules.py index 7abb5f884..f2d2d86e8 100644 --- a/nova/api/openstack/backup_schedules.py +++ b/nova/api/openstack/backup_schedules.py @@ -42,7 +42,11 @@ class Controller(wsgi.Controller): def index(self, req, server_id): """ Returns the list of backup schedules for a given instance """ - return _translate_keys({}) + return faults.Fault(exc.HTTPNotImplemented()) + + def show(self, req, server_id, id): + """ Returns a single backup schedule for a given instance """ + return faults.Fault(exc.HTTPNotImplemented()) def create(self, req, server_id): """ No actual update method required, since the existing API allows diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 737b43c7b..989385a8c 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -483,21 +483,31 @@ class ServersTest(test.TestCase): req.get_response(fakes.wsgi_app()) def test_create_backup_schedules(self): - req = webob.Request.blank('/v1.0/servers/1/backup_schedules') + req = webob.Request.blank('/v1.0/servers/1/backup_schedule') req.method = 'POST' res = req.get_response(fakes.wsgi_app()) - self.assertEqual(res.status, '404 Not Found') + self.assertEqual(res.status_int, 501) def test_delete_backup_schedules(self): - req = webob.Request.blank('/v1.0/servers/1/backup_schedules') + req = webob.Request.blank('/v1.0/servers/1/backup_schedule/1') req.method = 'DELETE' res = req.get_response(fakes.wsgi_app()) - self.assertEqual(res.status, '404 Not Found') + self.assertEqual(res.status_int, 501) def test_get_server_backup_schedules(self): - req = webob.Request.blank('/v1.0/servers/1/backup_schedules') + req = webob.Request.blank('/v1.0/servers/1/backup_schedule') res = req.get_response(fakes.wsgi_app()) - self.assertEqual(res.status, '404 Not Found') + self.assertEqual(res.status_int, 501) + + def test_get_server_backup_schedule(self): + req = webob.Request.blank('/v1.0/servers/1/backup_schedule/1') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 501) + + def test_server_backup_schedule_deprecated_v11(self): + req = webob.Request.blank('/v1.1/servers/1/backup_schedule') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 404) def test_get_all_server_details_v1_0(self): req = webob.Request.blank('/v1.0/servers/detail') -- cgit From c8e708af1789fda97674fb4c3904d86de8473a7e Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Mon, 28 Mar 2011 14:32:03 -0400 Subject: Dont make the test fail --- nova/tests/test_virt.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 8cee55576..df29e69c2 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -258,7 +258,6 @@ class LibvirtConnTestCase(test.TestCase): check = [ (lambda t: t.find('.').get('type'), 'lxc'), (lambda t: t.find('./os/type').text, 'exe'), - (lambda t: t.find('./devices/filesystem/source').get('dir'), 'rootfs'), (lambda t: t.find('./devices/filesystem/target').get('dir'), '/')] for i, (check, expected_result) in enumerate(check): @@ -266,6 +265,9 @@ class LibvirtConnTestCase(test.TestCase): expected_result, '%s failed common check %d' % (xml, i)) + target = tree.find('./devices/filesystem/source').get('dir') + self.assertTrue(len(target) > 0) + def _check_xml_and_uri(self, instance, expect_ramdisk, expect_kernel, rescue=False): user_context = context.RequestContext(project=self.project, -- cgit From dea3af64186ff204de7d5ca9852af267e648823e Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 28 Mar 2011 20:36:07 +0200 Subject: Remove now useless try/except block. --- nova/api/openstack/extensions.py | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index 259d24a7d..e2f833d57 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -320,20 +320,16 @@ class ExtensionManager(object): if file_ext.lower() == '.py' and not mod_name.startswith('_'): mod = imp.load_source(mod_name, ext_path) ext_name = mod_name[0].upper() + mod_name[1:] - try: - new_ext_class = getattr(mod, ext_name, None) - if not new_ext_class: - LOG.warn(_('Did not find expected name ' - '"%(ext_name)" in %(file)s'), - { 'ext_name': ext_name, - 'file': ext_path }) - continue - new_ext = new_ext_class() - self._check_extension(new_ext) - self.extensions[new_ext.get_alias()] = new_ext - except AttributeError as ex: - LOG.exception(_("Exception loading extension: %s"), - unicode(ex)) + new_ext_class = getattr(mod, ext_name, None) + if not new_ext_class: + LOG.warn(_('Did not find expected name ' + '"%(ext_name)" in %(file)s'), + { 'ext_name': ext_name, + 'file': ext_path }) + continue + new_ext = new_ext_class() + self._check_extension(new_ext) + self.extensions[new_ext.get_alias()] = new_ext class ResponseExtension(object): -- cgit From bb7ed6cb9cf625b675a666866a7f9fb762ca6bd2 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Mon, 28 Mar 2011 14:47:25 -0400 Subject: use self.flags in virt test --- nova/tests/test_virt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index df29e69c2..e6beb8e2e 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -246,7 +246,7 @@ class LibvirtConnTestCase(test.TestCase): {'allocated': True, 'instance_id': instance_ref['id']}) - FLAGS.libvirt_type = 'lxc' + self.flags(libvirt_type='lxc') conn = libvirt_conn.LibvirtConnection(True) uri = conn.get_uri() -- cgit From 9fdf9967234d8553c3548ad03fc3b2691285fa7d Mon Sep 17 00:00:00 2001 From: Devin Carlen Date: Mon, 28 Mar 2011 11:56:19 -0700 Subject: Added image name and description mapping to ec2 api --- nova/api/ec2/cloud.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 0da642318..9e34d3317 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -890,6 +890,8 @@ class CloudController(object): i['imageOwnerId'] = image['properties'].get('owner_id') i['imageLocation'] = image['properties'].get('image_location') i['imageState'] = image['properties'].get('image_state') + i['displayName'] = image.get('name') + i['description'] = image.get('description') i['type'] = image_type i['isPublic'] = str(image['properties'].get('is_public', '')) == 'True' i['architecture'] = image['properties'].get('architecture') -- cgit From 78a9ec232cde1172fa4c639ebdcbf88967bf8e9c Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Mon, 28 Mar 2011 15:10:34 -0400 Subject: Fixed superfluous parentheses around locals(). --- nova/image/glance.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/image/glance.py b/nova/image/glance.py index 34fc78e71..d8f51429e 100644 --- a/nova/image/glance.py +++ b/nova/image/glance.py @@ -230,13 +230,13 @@ def _parse_glance_iso8601_timestamp(timestamp): """ Parse a subset of iso8601 timestamps into datetime objects """ - ISO_FORMATS = ["%Y-%m-%dT%H:%M:%S.%f", "%Y-%m-%dT%H:%M:%S"] + iso_formats = ["%Y-%m-%dT%H:%M:%S.%f", "%Y-%m-%dT%H:%M:%S"] - for iso_format in ISO_FORMATS: + for iso_format in iso_formats: try: return datetime.datetime.strptime(timestamp, iso_format) except ValueError: pass raise ValueError(_("""%(timestamp)s does not follow any of the \ -signatures: %(ISO_FORMATS)s""") % (locals())) +signatures: %(ISO_FORMATS)s""") % locals()) -- cgit From dbbceaebec3ca2a729582f9851f718b2b7c3f3b9 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Mon, 28 Mar 2011 15:57:18 -0400 Subject: Fix up libvirt.xml.template --- nova/virt/libvirt.xml.template | 138 ++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 70 deletions(-) diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index 894b216e9..36d18ed95 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -3,47 +3,45 @@ ${memory_kb} #if $type == 'lxc' - #set $disk_prefix = '' - #set $disk_bus = '' - exe - /sbin/init + #set $disk_prefix = '' + #set $disk_bus = '' + exe + /sbin/init +#else if $type == 'uml' + #set $disk_prefix = 'ubd' + #set $disk_bus = 'uml' + uml + /usr/bin/linux + /dev/ubda #else - #if $type == 'uml' - #set $disk_prefix = 'ubd' - #set $disk_bus = 'uml' - uml - /usr/bin/linux - /dev/ubda - #else - #if $type == 'xen' - #set $disk_prefix = 'sd' - #set $disk_bus = 'scsi' - linux - /dev/xvda - #else - #set $disk_prefix = 'vd' - #set $disk_bus = 'virtio' - hvm - #end if - #if $getVar('rescue', False) - ${basepath}/kernel.rescue - ${basepath}/ramdisk.rescue - #else - #if $getVar('kernel', None) - ${kernel} - #if $type == 'xen' - ro - #else - root=/dev/vda console=ttyS0 - #end if - #if $getVar('ramdisk', None) - ${ramdisk} - #end if - #else - - #end if - #end if - #end if + #if $type == 'xen' + #set $disk_prefix = 'sd' + #set $disk_bus = 'scsi' + linux + /dev/xvda + #else + #set $disk_prefix = 'vd' + #set $disk_bus = 'virtio' + hvm + #end if + #if $getVar('rescue', False) + ${basepath}/kernel.rescue + ${basepath}/ramdisk.rescue + #else + #if $getVar('kernel', None) + ${kernel} + #if $type == 'xen' + ro + #else + root=/dev/vda console=ttyS0 + #end if + #if $getVar('ramdisk', None) + ${ramdisk} + #end if + #else + + #end if + #end if #end if @@ -52,36 +50,36 @@ ${vcpus} #if $type == 'lxc' - - - - + + + + #else - #if $getVar('rescue', False) - - - - - - - - - - - #else - - - - - - #if $getVar('local', False) - - - - - - #end if -#end if + #if $getVar('rescue', False) + + + + + + + + + + + #else + + + + + + #if $getVar('local', False) + + + + + + #end if + #end if #end if #for $nic in $nics @@ -91,7 +89,7 @@ - + #if $getVar('nic.extra_params', False) ${nic.extra_params} #end if -- cgit From 7040eadcc7e86d063c5c69391dedafa181711913 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 28 Mar 2011 22:21:18 +0200 Subject: pep8 --- nova/api/openstack/extensions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index e2f833d57..b9b7f998d 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -324,8 +324,8 @@ class ExtensionManager(object): if not new_ext_class: LOG.warn(_('Did not find expected name ' '"%(ext_name)" in %(file)s'), - { 'ext_name': ext_name, - 'file': ext_path }) + {'ext_name': ext_name, + 'file': ext_path}) continue new_ext = new_ext_class() self._check_extension(new_ext) -- cgit From 633917f56200cc11ef26717b8305ef0ccbe76569 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Mon, 28 Mar 2011 16:42:09 -0400 Subject: Made param descriptions sphinx compatible. --- nova/api/openstack/images.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index 54e08438a..5fd1f0163 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -51,8 +51,8 @@ class Controller(wsgi.Controller): """ Initialize new `ImageController`. - @param compute_service: `nova.compute.api:API` - @param image_service: `nova.image.service:BaseImageService` + :param compute_service: `nova.compute.api:API` + :param image_service: `nova.image.service:BaseImageService` """ _default_service = utils.import_object(flags.FLAGS.image_service) @@ -63,7 +63,7 @@ class Controller(wsgi.Controller): """ Return an index listing of images available to the request. - @param req: `wsgi.Request` object + :param req: `wsgi.Request` object """ context = req.environ['nova.context'] images = self._image_service.index(context) @@ -75,7 +75,7 @@ class Controller(wsgi.Controller): """ Return a detailed index listing of images available to the request. - @param req: `wsgi.Request` object. + :param req: `wsgi.Request` object. """ context = req.environ['nova.context'] images = self._image_service.detail(context) @@ -87,8 +87,8 @@ class Controller(wsgi.Controller): """ Return detailed information about a specific image. - @param req: `wsgi.Request` object - @param id: Image identifier (integer) + :param req: `wsgi.Request` object + :param id: Image identifier (integer) """ context = req.environ['nova.context'] @@ -110,8 +110,8 @@ class Controller(wsgi.Controller): """ Delete an image, if allowed. - @param req: `wsgi.Request` object - @param id: Image identifier (integer) + :param req: `wsgi.Request` object + :param id: Image identifier (integer) """ image_id = id context = req.environ['nova.context'] @@ -122,7 +122,7 @@ class Controller(wsgi.Controller): """ Snapshot a server instance and save the image. - @param req: `wsgi.Request` object + :param req: `wsgi.Request` object """ context = req.environ['nova.context'] content_type = req.get_content_type() -- cgit From c1ed5fc3dfeecef281df45cd2e6779fa21c63bf5 Mon Sep 17 00:00:00 2001 From: Armando Migliaccio Date: Mon, 28 Mar 2011 22:00:17 +0100 Subject: style fixes --- nova/network/xenapi_net.py | 6 ++++-- nova/tests/fake_utils.py | 14 ++++++++++---- nova/tests/test_xenapi.py | 28 +++++++--------------------- nova/virt/xenapi/fake.py | 28 ++++++++++++++-------------- 4 files changed, 35 insertions(+), 41 deletions(-) diff --git a/nova/network/xenapi_net.py b/nova/network/xenapi_net.py index 8603fd842..9a99602d9 100644 --- a/nova/network/xenapi_net.py +++ b/nova/network/xenapi_net.py @@ -27,7 +27,7 @@ from nova import flags from nova import log as logging from nova import utils from nova.virt.xenapi_conn import XenAPISession -from nova.virt.xenapi.network_utils import NetworkHelper +from nova.virt.xenapi import network_utils LOG = logging.getLogger("nova.xenapi_net") @@ -44,7 +44,9 @@ def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None): session = XenAPISession(url, username, password) # Check whether bridge already exists # Retrieve network whose name_label is "bridge" - network_ref = NetworkHelper.find_network_with_name_label(session, bridge) + network_ref = network_utils.NetworkHelper.find_network_with_name_label( + session, + bridge) if network_ref == None: # If bridge does not exists # 1 - create network diff --git a/nova/tests/fake_utils.py b/nova/tests/fake_utils.py index 23996ba95..be59970c9 100644 --- a/nova/tests/fake_utils.py +++ b/nova/tests/fake_utils.py @@ -47,14 +47,20 @@ def fake_execute_set_repliers(repliers): def fake_execute_default_reply_handler(*ignore_args, **ignore_kwargs): - """A reply handler for commands that haven't been added to the reply - list. Returns empty strings for stdout and stderr.""" + """A reply handler for commands that haven't been added to the reply list. + + Returns empty strings for stdout and stderr. + + """ return '', '' def fake_execute(*cmd_parts, **kwargs): - """This function stubs out execute, optionally executing - a preconfigued function to return expected data.""" + """This function stubs out execute. + + It optionally executes a preconfigued function to return expected data. + + """ global _fake_execute_repliers process_input = kwargs.get('process_input', None) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index bc1469223..17e3f55e9 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -14,9 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Test suite for XenAPI. -""" +"""Test suite for XenAPI.""" import functools import os @@ -65,9 +63,7 @@ def stub_vm_utils_with_vdi_attached_here(function, should_return=True): class XenAPIVolumeTestCase(test.TestCase): - """ - Unit tests for Volume operations. - """ + """Unit tests for Volume operations.""" def setUp(self): super(XenAPIVolumeTestCase, self).setUp() self.stubs = stubout.StubOutForTesting() @@ -172,9 +168,7 @@ def reset_network(*args): class XenAPIVMTestCase(test.TestCase): - """ - Unit tests for VM operations. - """ + """Unit tests for VM operations.""" def setUp(self): super(XenAPIVMTestCase, self).setUp() self.manager = manager.AuthManager() @@ -538,9 +532,7 @@ class XenAPIVMTestCase(test.TestCase): class XenAPIDiffieHellmanTestCase(test.TestCase): - """ - Unit tests for Diffie-Hellman code. - """ + """Unit tests for Diffie-Hellman code.""" def setUp(self): super(XenAPIDiffieHellmanTestCase, self).setUp() self.alice = SimpleDH() @@ -564,9 +556,7 @@ class XenAPIDiffieHellmanTestCase(test.TestCase): class XenAPIMigrateInstance(test.TestCase): - """ - Unit test for verifying migration-related actions. - """ + """Unit test for verifying migration-related actions.""" def setUp(self): super(XenAPIMigrateInstance, self).setUp() @@ -621,9 +611,7 @@ class XenAPIMigrateInstance(test.TestCase): class XenAPIDetermineDiskImageTestCase(test.TestCase): - """ - Unit tests for code that detects the ImageType. - """ + """Unit tests for code that detects the ImageType.""" def setUp(self): super(XenAPIDetermineDiskImageTestCase, self).setUp() glance_stubs.stubout_glance_client(self.stubs, @@ -642,9 +630,7 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): self.assertEqual(disk_type, dt) def test_instance_disk(self): - """ - If a kernel is specified then the image type is DISK (aka machine). - """ + """If a kernel is specified, the image type is DISK (aka machine).""" FLAGS.xenapi_image_service = 'objectstore' self.fake_instance.image_id = glance_stubs.FakeGlance.IMAGE_MACHINE self.fake_instance.kernel_id = glance_stubs.FakeGlance.IMAGE_KERNEL diff --git a/nova/virt/xenapi/fake.py b/nova/virt/xenapi/fake.py index d79312a60..4434dbf0b 100644 --- a/nova/virt/xenapi/fake.py +++ b/nova/virt/xenapi/fake.py @@ -60,7 +60,7 @@ from nova import exception from nova import log as logging -_CLASSES = ['host', 'network', 'session', 'SR', 'VBD', \ +_CLASSES = ['host', 'network', 'session', 'SR', 'VBD', 'PBD', 'VDI', 'VIF', 'PIF', 'VM', 'VLAN', 'task'] _db_content = {} @@ -200,19 +200,19 @@ def create_local_srs(): def _create_local_sr(host_ref): - sr_ref = \ - _create_object('SR', - {'name_label': 'Local storage', - 'type': 'lvm', - 'content_type': 'user', - 'shared': False, - 'physical_size': str(1 << 30), - 'physical_utilisation': str(0), - 'virtual_allocation': str(0), - 'other_config': {'i18n-original-value-name_label': \ - 'Local storage', - 'i18n-key': 'local-storage'}, - 'VDIs': []}) + sr_ref = _create_object( + 'SR', + {'name_label': 'Local storage', + 'type': 'lvm', + 'content_type': 'user', + 'shared': False, + 'physical_size': str(1 << 30), + 'physical_utilisation': str(0), + 'virtual_allocation': str(0), + 'other_config': { + 'i18n-original-value-name_label': 'Local storage', + 'i18n-key': 'local-storage'}, + 'VDIs': []}) pbd_ref = create_pbd('', host_ref, sr_ref, True) _db_content['SR'][sr_ref]['PBDs'] = [pbd_ref] return sr_ref -- cgit From 45e3deee1581580bed56d1bdfaaf9f4814fe7963 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Mon, 28 Mar 2011 17:13:37 -0400 Subject: Updated docstrings to satisfy. --- nova/api/openstack/images.py | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index 5fd1f0163..ad748b4ca 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -32,10 +32,8 @@ FLAGS = flags.FLAGS class Controller(wsgi.Controller): - """ - Base `wsgi.Controller` for retrieving and displaying images in the - OpenStack API. Version-inspecific code goes here. - """ + """Base `wsgi.Controller` for retrieving and displaying images in the + OpenStack API. Version-inspecific code goes here.""" _serialization_metadata = { 'application/xml': { @@ -48,8 +46,7 @@ class Controller(wsgi.Controller): } def __init__(self, image_service=None, compute_service=None): - """ - Initialize new `ImageController`. + """Initialize new `ImageController`. :param compute_service: `nova.compute.api:API` :param image_service: `nova.image.service:BaseImageService` @@ -60,8 +57,7 @@ class Controller(wsgi.Controller): self._image_service = image_service or _default_service def index(self, req): - """ - Return an index listing of images available to the request. + """Return an index listing of images available to the request. :param req: `wsgi.Request` object """ @@ -72,8 +68,7 @@ class Controller(wsgi.Controller): return dict(images=[builder(image, detail=False) for image in images]) def detail(self, req): - """ - Return a detailed index listing of images available to the request. + """Return a detailed index listing of images available to the request. :param req: `wsgi.Request` object. """ @@ -84,8 +79,7 @@ class Controller(wsgi.Controller): return dict(images=[builder(image, detail=True) for image in images]) def show(self, req, id): - """ - Return detailed information about a specific image. + """Return detailed information about a specific image. :param req: `wsgi.Request` object :param id: Image identifier (integer) @@ -107,8 +101,7 @@ class Controller(wsgi.Controller): return dict(image=self.get_builder(req).build(image, detail=True)) def delete(self, req, id): - """ - Delete an image, if allowed. + """Delete an image, if allowed. :param req: `wsgi.Request` object :param id: Image identifier (integer) @@ -119,8 +112,7 @@ class Controller(wsgi.Controller): return webob.exc.HTTPNoContent() def create(self, req): - """ - Snapshot a server instance and save the image. + """Snapshot a server instance and save the image. :param req: `wsgi.Request` object """ @@ -146,26 +138,18 @@ class Controller(wsgi.Controller): class ControllerV10(Controller): - """ - Version 1.0 specific controller logic. - """ + """Version 1.0 specific controller logic.""" def get_builder(self, request): - """ - Property to get the ViewBuilder class we need to use. - """ + """Property to get the ViewBuilder class we need to use.""" base_url = request.application_url return images_view.ViewBuilderV10(base_url) class ControllerV11(Controller): - """ - Version 1.1 specific controller logic. - """ + """Version 1.1 specific controller logic.""" def get_builder(self, request): - """ - Property to get the ViewBuilder class we need to use. - """ + """Property to get the ViewBuilder class we need to use.""" base_url = request.application_url return images_view.ViewBuilderV11(base_url) -- cgit From 6efd9dc30870008750c9754de4672d3eea656cce Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Mon, 28 Mar 2011 17:15:54 -0400 Subject: Updated docstrings to satisfy. --- nova/api/openstack/views/images.py | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/nova/api/openstack/views/images.py b/nova/api/openstack/views/images.py index 9db73bd4b..8f5568f6c 100644 --- a/nova/api/openstack/views/images.py +++ b/nova/api/openstack/views/images.py @@ -19,29 +19,21 @@ import os.path class ViewBuilder(object): - """ - Base class for generating responses to OpenStack API requests for - information about images. - """ + """Base class for generating responses to OpenStack API requests for + information about images.""" def __init__(self, base_url): - """ - Initialize new `ViewBuilder`. - """ + """Initialize new `ViewBuilder`.""" self._url = base_url def _format_dates(self, image): - """ - Update all date fields to ensure standardized formatting. - """ + """Update all date fields to ensure standardized formatting.""" for attr in ['created_at', 'updated_at', 'deleted_at']: if image.get(attr) is not None: image[attr] = image[attr].strftime('%Y-%m-%dT%H:%M:%SZ') def _format_status(self, image): - """ - Update the status field to standardize format. - """ + """Update the status field to standardize format.""" status_mapping = { 'pending': 'queued', 'decrypting': 'preparing', @@ -56,15 +48,11 @@ class ViewBuilder(object): image['status'] = image['status'].upper() def generate_href(self, image_id): - """ - Return an href string pointing to this object. - """ + """Return an href string pointing to this object.""" return os.path.join(self._url, "images", str(image_id)) def build(self, image_obj, detail=False): - """ - Return a standardized image structure for display by the API. - """ + """Return a standardized image structure for display by the API.""" properties = image_obj.get("properties", {}) self._format_dates(image_obj) @@ -97,18 +85,15 @@ class ViewBuilder(object): class ViewBuilderV10(ViewBuilder): + """OpenStack API v1.0 Image Builder""" pass class ViewBuilderV11(ViewBuilder): - """ - OpenStack API v1.1 Image Builder - """ + """OpenStack API v1.1 Image Builder""" def build(self, image_obj, detail=False): - """ - Return a standardized image structure for display by the API. - """ + """Return a standardized image structure for display by the API.""" image = ViewBuilder.build(self, image_obj, detail) href = self.generate_href(image_obj["id"]) -- cgit From cd81e06c19893b44568a8cef37a1de30b726e236 Mon Sep 17 00:00:00 2001 From: Armando Migliaccio Date: Mon, 28 Mar 2011 22:25:11 +0100 Subject: fix docstrings --- nova/virt/xenapi/vmops.py | 61 +++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 147419f90..a9514bd61 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -279,8 +279,7 @@ class VMOps(object): "start") def snapshot(self, instance, image_id): - """ - Create snapshot from a running VM instance + """Create snapshot from a running VM instance. :param instance: instance to be snapshotted :param image_id: id of image to upload to @@ -300,6 +299,7 @@ class VMOps(object): 3. Push-to-glance: Once coalesced, we call a plugin on the XenServer that will bundle the VHDs together and then push the bundle into Glance. + """ template_vm_ref = None try: @@ -332,8 +332,7 @@ class VMOps(object): return def migrate_disk_and_power_off(self, instance, dest): - """ - Copies a VHD from one host machine to another + """Copies a VHD from one host machine to another. :param instance: the instance that owns the VHD in question. :param dest: the destination host machine. @@ -428,13 +427,14 @@ class VMOps(object): self._session.wait_for_task(task, instance.id) def set_admin_password(self, instance, new_pass): - """ - Set the root/admin password on the VM instance. This is done via - an agent running on the VM. Communication between nova and the agent - is done via writing xenstore records. Since communication is done over - the XenAPI RPC calls, we need to encrypt the password. We're using a - simple Diffie-Hellman class instead of the more advanced one in - M2Crypto for compatibility with the agent code. + """Set the root/admin password on the VM instance. + + This is done via an agent running on the VM. Communication between nova + and the agent is done via writing xenstore records. Since communication + is done over the XenAPI RPC calls, we need to encrypt the password. + We're using a simple Diffie-Hellman class instead of the more advanced + one in M2Crypto for compatibility with the agent code. + """ # Need to uniquely identify this request. transaction_id = str(uuid.uuid4()) @@ -467,12 +467,14 @@ class VMOps(object): return resp_dict['message'] def inject_file(self, instance, path, contents): - """ - Write a file to the VM instance. The path to which it is to be - written and the contents of the file need to be supplied; both will - be base64-encoded to prevent errors with non-ASCII characters being - transmitted. If the agent does not support file injection, or the user - has disabled it, a NotImplementedError will be raised. + """Write a file to the VM instance. + + The path to which it is to be written and the contents of the file + need to be supplied; both will be base64-encoded to prevent errors + with non-ASCII characters being transmitted. If the agent does not + support file injection, or the user has disabled it, a + NotImplementedError will be raised. + """ # Files/paths must be base64-encoded for transmission to agent b64_path = base64.b64encode(path) @@ -556,8 +558,7 @@ class VMOps(object): VMHelper.destroy_vbd(self._session, vbd_ref) def _destroy_kernel_ramdisk(self, instance, vm_ref): - """ - Three situations can occur: + """Three situations can occur: 1. We have neither a ramdisk nor a kernel, in which case we are a RAW image and can omit this step @@ -567,6 +568,7 @@ class VMOps(object): 3. We have both, in which case we safely remove both the kernel and the ramdisk. + """ instance_id = instance.id if not instance.kernel_id and not instance.ramdisk_id: @@ -614,11 +616,11 @@ class VMOps(object): self._session.call_xenapi("Async.VM.destroy", rescue_vm_ref) def destroy(self, instance): - """ - Destroy VM instance + """Destroy VM instance. This is the method exposed by xenapi_conn.destroy(). The rest of the destroy_* methods are internal. + """ instance_id = instance.id LOG.info(_("Destroying VM for Instance %(instance_id)s") % locals()) @@ -627,13 +629,13 @@ class VMOps(object): def _destroy(self, instance, vm_ref, shutdown=True, destroy_kernel_ramdisk=True): - """ - Destroys VM instance by performing: + """Destroys VM instance by performing: 1. A shutdown if requested. 2. Destroying associated VDIs. 3. Destroying kernel and ramdisk files (if necessary). 4. Destroying that actual VM record. + """ if vm_ref is None: LOG.warning(_("VM is not present, skipping destroy...")) @@ -681,8 +683,8 @@ class VMOps(object): self._wait_with_callback(instance.id, task, callback) def rescue(self, instance, callback): - """ - Rescue the specified instance + """Rescue the specified instance. + - shutdown the instance VM. - set 'bootlock' to prevent the instance from starting in rescue. - spawn a rescue VM (the vm name-label will be instance-N-rescue). @@ -709,10 +711,12 @@ class VMOps(object): self._session.call_xenapi("Async.VBD.plug", rescue_vbd_ref) def unrescue(self, instance, callback): - """Unrescue the specified instance + """Unrescue the specified instance. + - unplug the instance VM's disk from the rescue VM. - teardown the rescue VM. - release the bootlock to allow the instance VM to start. + """ rescue_vm_ref = VMHelper.lookup(self._session, "%s-rescue" % instance.name) @@ -729,10 +733,11 @@ class VMOps(object): self._start(instance, original_vm_ref) def poll_rescued_instances(self, timeout): - """ - Look for expirable rescued instances + """Look for expirable rescued instances. + - forcibly exit rescue mode for any instances that have been in rescue mode for >= the provided timeout + """ last_ran = self.poll_rescue_last_ran if not last_ran: -- cgit From c439309fddb7e6ebc14ab6b82ac9960f459c5aed Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Mon, 28 Mar 2011 17:40:45 -0400 Subject: osapi servers update tests actually assert now; enforcing server name being a string of length > 0; moving server update adminPass support to be v1.0-specific --- nova/api/openstack/servers.py | 30 +++++++++++++++++++++------- nova/tests/api/openstack/test_servers.py | 34 +++++++++++++++++++++++--------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 75a305a14..80617cf1c 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -246,20 +246,27 @@ class Controller(wsgi.Controller): ctxt = req.environ['nova.context'] update_dict = {} - if 'adminPass' in inst_dict['server']: - update_dict['admin_pass'] = inst_dict['server']['adminPass'] - try: - self.compute_api.set_admin_password(ctxt, id) - except exception.TimeoutException: - return exc.HTTPRequestTimeout() + if 'name' in inst_dict['server']: - update_dict['display_name'] = inst_dict['server']['name'] + name = inst_dict['server']['name'] + + if not isinstance(name, basestring) or name == '': + return exc.HTTPBadRequest() + + update_dict['display_name'] = name + + self._parse_update(ctxt, id, inst_dict, update_dict) + try: self.compute_api.update(ctxt, id, **update_dict) except exception.NotFound: return faults.Fault(exc.HTTPNotFound()) + return exc.HTTPNoContent() + def _parse_update(self, context, id, inst_dict, update_dict): + pass + @scheduler_api.redirect_handler def action(self, req, id): """Multi-purpose method used to reboot, rebuild, or @@ -566,6 +573,15 @@ class ControllerV10(Controller): def _limit_items(self, items, req): return common.limited(items, req) + def _parse_update(self, context, server_id, inst_dict, update_dict): + if 'adminPass' in inst_dict['server']: + update_dict['admin_pass'] = inst_dict['server']['adminPass'] + try: + self.compute_api.set_admin_password(context, server_id) + except exception.TimeoutException: + return exc.HTTPRequestTimeout() + + class ControllerV11(Controller): def _image_id_from_req_data(self, data): diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 989385a8c..1043838eb 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -448,39 +448,55 @@ class ServersTest(test.TestCase): res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 422) - def test_update_bad_params(self): + def test_update_bad_name(self): """ Confirm that update is filtering params """ - inst_dict = dict(cat='leopard', name='server_test', adminPass='bacon') + inst_dict = dict(name='', adminPass='bacon') + self.body = json.dumps(dict(server=inst_dict)) + + req = webob.Request.blank('/v1.0/servers/1') + req.method = 'PUT' + req.content_type = "application/json" + req.body = self.body + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 400) + + def test_update_server_v10(self): + inst_dict = dict(name='server_test', adminPass='bacon') self.body = json.dumps(dict(server=inst_dict)) def server_update(context, id, params): - self.update_called = True - filtered_dict = dict(name='server_test', admin_pass='bacon') + filtered_dict = dict(display_name='server_test', admin_pass='bacon') self.assertEqual(params, filtered_dict) + return filtered_dict self.stubs.Set(nova.db.api, 'instance_update', server_update) req = webob.Request.blank('/v1.0/servers/1') req.method = 'PUT' + req.content_type = "application/json" req.body = self.body - req.get_response(fakes.wsgi_app()) + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 204) - def test_update_server(self): + def test_update_server_adminPass_ignored_v11(self): inst_dict = dict(name='server_test', adminPass='bacon') self.body = json.dumps(dict(server=inst_dict)) def server_update(context, id, params): - filtered_dict = dict(name='server_test', admin_pass='bacon') + filtered_dict = dict(display_name='server_test') self.assertEqual(params, filtered_dict) + return filtered_dict self.stubs.Set(nova.db.api, 'instance_update', server_update) - req = webob.Request.blank('/v1.0/servers/1') + req = webob.Request.blank('/v1.1/servers/1') req.method = 'PUT' + req.content_type = "application/json" req.body = self.body - req.get_response(fakes.wsgi_app()) + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 204) def test_create_backup_schedules(self): req = webob.Request.blank('/v1.0/servers/1/backup_schedule') -- cgit From f460d75ae355ee76b6c51d884162f00076140716 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Mon, 28 Mar 2011 17:45:48 -0400 Subject: pep8 --- nova/api/openstack/servers.py | 3 +-- nova/tests/api/openstack/test_servers.py | 5 ++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 80617cf1c..e9bc0a797 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -253,7 +253,7 @@ class Controller(wsgi.Controller): if not isinstance(name, basestring) or name == '': return exc.HTTPBadRequest() - update_dict['display_name'] = name + update_dict['display_name'] = name self._parse_update(ctxt, id, inst_dict, update_dict) @@ -582,7 +582,6 @@ class ControllerV10(Controller): return exc.HTTPRequestTimeout() - class ControllerV11(Controller): def _image_id_from_req_data(self, data): href = data['server']['imageRef'] diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 1043838eb..506b24b8b 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -465,7 +465,10 @@ class ServersTest(test.TestCase): self.body = json.dumps(dict(server=inst_dict)) def server_update(context, id, params): - filtered_dict = dict(display_name='server_test', admin_pass='bacon') + filtered_dict = dict( + display_name='server_test', + admin_pass='bacon', + ) self.assertEqual(params, filtered_dict) return filtered_dict -- cgit From abdd9a5078bef240fac91085f4af2da3f86e0b4e Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Mon, 28 Mar 2011 15:30:25 -0700 Subject: add period, test github --- bin/nova-vnc-proxy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nova-vnc-proxy b/bin/nova-vnc-proxy index e7b647c00..d39a9613e 100755 --- a/bin/nova-vnc-proxy +++ b/bin/nova-vnc-proxy @@ -17,7 +17,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""VNC Console Proxy Server""" +"""VNC Console Proxy Server.""" import eventlet import gettext -- cgit From 94092e3d896732fa1a97627f0fa504c3af70b3c5 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Mon, 28 Mar 2011 15:38:09 -0700 Subject: address some of termie's recommendations --- bin/nova-vnc-proxy | 3 +++ nova/api/openstack/servers.py | 4 ++-- nova/compute/api.py | 2 +- nova/tests/test_compute.py | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/bin/nova-vnc-proxy b/bin/nova-vnc-proxy index d39a9613e..e26bc6d8c 100755 --- a/bin/nova-vnc-proxy +++ b/bin/nova-vnc-proxy @@ -40,8 +40,10 @@ from nova import version from nova.vnc import auth from nova.vnc import proxy + LOG = logging.getLogger('nova.vnc-proxy') + FLAGS = flags.FLAGS flags.DEFINE_string('vnc_proxy_wwwroot', '/var/lib/nova/noVNC/', 'Full path to noVNC directory') @@ -57,6 +59,7 @@ flags.DEFINE_flag(flags.HelpFlag()) flags.DEFINE_flag(flags.HelpshortFlag()) flags.DEFINE_flag(flags.HelpXMLFlag()) + if __name__ == "__main__": utils.default_flagfile() FLAGS(sys.argv) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index c0fba4bb9..822342149 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -473,7 +473,7 @@ class Controller(wsgi.Controller): @scheduler_api.redirect_handler def get_ajax_console(self, req, id): - """ Returns a url to an instance's ajaxterm console. """ + """Returns a url to an instance's ajaxterm console.""" try: self.compute_api.get_ajax_console(req.environ['nova.context'], int(id)) @@ -483,7 +483,7 @@ class Controller(wsgi.Controller): @scheduler_api.redirect_handler def get_vnc_console(self, req, id): - """ Returns a url to an instance's ajaxterm console. """ + """Returns a url to an instance's ajaxterm console.""" try: self.compute_api.get_vnc_console(req.environ['nova.context'], int(id)) diff --git a/nova/compute/api.py b/nova/compute/api.py index f19c552e9..5470f40dc 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -618,7 +618,7 @@ class API(base.Base): {'method': 'authorize_vnc_console', 'args': {'token': output['token'], 'host': output['host'], - 'port': output['port']}}) + 'port': output['port']}}) return {'url': '%s/vnc_auto.html?token=%s&host=%s&port=%s' % ( FLAGS.vnc_console_proxy_url, diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index 0be08a778..038824ef8 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -290,7 +290,7 @@ class ComputeTestCase(test.TestCase): self.compute.terminate_instance(self.context, instance_id) def test_vnc_console(self): - """Make sure we can a vnc console for an instance""" + """Make sure we can a vnc console for an instance.""" instance_id = self._create_instance() self.compute.run_instance(self.context, instance_id) -- cgit From 233fd092018ace16f0b9caaca55f4e2107c41fe2 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 28 Mar 2011 15:46:01 -0700 Subject: Fixes volume smoketests to work with ami-tty --- smoketests/test_sysadmin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smoketests/test_sysadmin.py b/smoketests/test_sysadmin.py index 9bed1e092..89a3e60c4 100644 --- a/smoketests/test_sysadmin.py +++ b/smoketests/test_sysadmin.py @@ -266,10 +266,10 @@ class VolumeTests(base.UserSmokeTestCase): ip = self.data['instance'].private_dns_name conn = self.connect_ssh(ip, TEST_KEY) stdin, stdout, stderr = conn.exec_command( - "blockdev --getsize64 %s" % self.device) + "cat /sys/class/block/%s/size" % self.device.rpartition('/')[2]) out = stdout.read().strip() conn.close() - expected_size = 1024 * 1024 * 1024 + expected_size = 1024 * 1024 * 1024 / 512 self.assertEquals('%s' % (expected_size,), out, 'Volume is not the right size: %s %s. Expected: %s' % (out, stderr.read(), expected_size)) -- cgit From f67b18b61297b4cb0d641695de01e52fd37ddd1c Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 28 Mar 2011 16:27:33 -0700 Subject: displays an error message if a command fails, so that the user knows something went wrong --- bin/nova-manage | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index cf0caf47e..f7308abe5 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -1098,8 +1098,8 @@ def main(): script_name = argv.pop(0) if len(argv) < 1: print script_name + " category action []" - print "Available categories:" - for k, _ in CATEGORIES: + print _("Available categories:") + for k, _v in CATEGORIES: print "\t%s" % k sys.exit(2) category = argv.pop(0) @@ -1110,7 +1110,7 @@ def main(): actions = methods_of(command_object) if len(argv) < 1: print script_name + " category action []" - print "Available actions for %s category:" % category + print _("Available actions for %s category:") % category for k, _v in actions: print "\t%s" % k sys.exit(2) @@ -1122,9 +1122,12 @@ def main(): fn(*argv) sys.exit(0) except TypeError: - print "Possible wrong number of arguments supplied" + print _("Possible wrong number of arguments supplied") print "%s %s: %s" % (category, action, fn.__doc__) raise + except: + print _("Command failed, please check log for more info") + raise if __name__ == '__main__': main() -- cgit From 57a4864e30df604612a347ba069ccc8499b04f1f Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Mon, 28 Mar 2011 16:30:31 -0700 Subject: Code cleanup to keep the termie-bot happy --- nova/api/openstack/extensions.py | 131 +++++++++++++++------------------------ 1 file changed, 50 insertions(+), 81 deletions(-) diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index e81ffb3d3..9566d3250 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -38,55 +38,55 @@ FLAGS = flags.FLAGS class ExtensionDescriptor(object): - """This is the base class that defines the contract for extensions""" + """This is the base class that defines the contract for extensions.""" def get_name(self): - """The name of the extension + """The name of the extension. e.g. 'Fox In Socks' """ raise NotImplementedError() def get_alias(self): - """The alias for the extension + """The alias for the extension. e.g. 'FOXNSOX'""" raise NotImplementedError() def get_description(self): - """Friendly description for the extension + """Friendly description for the extension. e.g. 'The Fox In Socks Extension'""" raise NotImplementedError() def get_namespace(self): - """The XML namespace for the extension + """The XML namespace for the extension. e.g. 'http://www.fox.in.socks/api/ext/pie/v1.0'""" raise NotImplementedError() def get_updated(self): - """The timestamp when the extension was last updated + """The timestamp when the extension was last updated. e.g. '2011-01-22T13:25:27-06:00'""" - #NOTE(justinsb): Not sure of the purpose of this is, vs the XML NS + # NOTE(justinsb): Not sure of the purpose of this is, vs the XML NS raise NotImplementedError() def get_resources(self): - """List of extensions.ResourceExtension extension objects + """List of extensions.ResourceExtension extension objects. Resources define new nouns, and are accessible through URLs""" resources = [] return resources def get_actions(self): - """List of extensions.ActionExtension extension objects + """List of extensions.ActionExtension extension objects. Actions are verbs callable from the API""" actions = [] return actions def get_response_extensions(self): - """List of extensions.ResponseExtension extension objects + """List of extensions.ResponseExtension extension objects. Response extensions are used to insert information into existing response data""" @@ -154,17 +154,17 @@ class ExtensionController(wsgi.Controller): ext_data['description'] = ext.get_description() ext_data['namespace'] = ext.get_namespace() ext_data['updated'] = ext.get_updated() - ext_data['links'] = [] # TODO: implement extension links + ext_data['links'] = [] # TODO(dprince): implement extension links return ext_data def index(self, req): extensions = [] - for alias, ext in self.extension_manager.extensions.iteritems(): + for _alias, ext in self.extension_manager.extensions.iteritems(): extensions.append(self._translate(ext)) return dict(extensions=extensions) def show(self, req, id): - # NOTE: the extensions alias is used as the 'id' for show + # NOTE(dprince): the extensions alias is used as the 'id' for show ext = self.extension_manager.extensions[id] return self._translate(ext) @@ -176,20 +176,16 @@ class ExtensionController(wsgi.Controller): class ExtensionMiddleware(wsgi.Middleware): - """ - Extensions middleware that intercepts configured routes for extensions. - """ + """Extensions middleware for WSGI.""" @classmethod def factory(cls, global_config, **local_config): - """ paste factory """ + """Paste factory.""" def _factory(app): return cls(app, **local_config) return _factory def _action_ext_controllers(self, application, ext_mgr, mapper): - """ - Return a dict of ActionExtensionController objects by collection - """ + """Return a dict of ActionExtensionController-s by collection.""" action_controllers = {} for action in ext_mgr.get_actions(): if not action.collection in action_controllers.keys(): @@ -208,9 +204,7 @@ class ExtensionMiddleware(wsgi.Middleware): return action_controllers def _response_ext_controllers(self, application, ext_mgr, mapper): - """ - Return a dict of ResponseExtensionController objects by collection - """ + """Returns a dict of ResponseExtensionController-s by collection.""" response_ext_controllers = {} for resp_ext in ext_mgr.get_response_extensions(): if not resp_ext.key in response_ext_controllers.keys(): @@ -269,16 +263,15 @@ class ExtensionMiddleware(wsgi.Middleware): @webob.dec.wsgify(RequestClass=wsgi.Request) def __call__(self, req): - """ - Route the incoming request with router. - """ + """Route the incoming request with router.""" req.environ['extended.app'] = self.application return self._router @staticmethod @webob.dec.wsgify(RequestClass=wsgi.Request) def _dispatch(req): - """ + """Dispatch the request. + Returns the routed WSGI app's response or defers to the extended application. """ @@ -290,8 +283,7 @@ class ExtensionMiddleware(wsgi.Middleware): class ExtensionManager(object): - """ - Load extensions from the configured extension path. + """Load extensions from the configured extension path. See nova/tests/api/openstack/extensions/foxinsocks/extension.py for an example extension implementation. @@ -307,50 +299,30 @@ class ExtensionManager(object): self._load_all_extensions() def get_resources(self): - """ - returns a list of ResourceExtension objects - """ + """Returns a list of ResourceExtension objects.""" resources = [] resources.append(ResourceExtension('extensions', ExtensionController(self))) - for alias, ext in self.extensions.iteritems(): - try: - resources.extend(ext.get_resources()) - except AttributeError: - # NOTE: Extension aren't required to have resource extensions - pass + for _alias, ext in self.extensions.iteritems(): + resources.extend(ext.get_resources()) return resources def get_actions(self): - """ - returns a list of ActionExtension objects - """ + """Returns a list of ActionExtension objects.""" actions = [] - for alias, ext in self.extensions.iteritems(): - try: - actions.extend(ext.get_actions()) - except AttributeError: - # NOTE: Extension aren't required to have action extensions - pass + for _alias, ext in self.extensions.iteritems(): + actions.extend(ext.get_actions()) return actions def get_response_extensions(self): - """ - returns a list of ResponseExtension objects - """ + """Returns a list of ResponseExtension objects.""" response_exts = [] - for alias, ext in self.extensions.iteritems(): - try: - response_exts.extend(ext.get_response_extensions()) - except AttributeError: - # NOTE: Extension aren't required to have response extensions - pass + for _alias, ext in self.extensions.iteritems(): + response_exts.extend(ext.get_response_extensions()) return response_exts def _check_extension(self, extension): - """ - Checks for required methods in extension objects. - """ + """Checks for required methods in extension objects.""" try: LOG.debug(_('Ext name: %s'), extension.get_name()) LOG.debug(_('Ext alias: %s'), extension.get_alias()) @@ -361,11 +333,17 @@ class ExtensionManager(object): LOG.exception(_("Exception loading extension: %s"), unicode(ex)) def _load_all_extensions(self): - """ - Load extensions from the configured path. The extension name is - constructed from the module_name. If your extension module was named - widgets.py the extension class within that module should be - 'Widgets'. + """Load extensions from the configured path. + + An extension consists of a directory of related files, with a class + that defines a class that inherits from ExtensionDescriptor. + + Because of some oddities involving identically named modules, it's + probably best to name your file after the name of your extension, + rather than something likely to clash like 'extension.py'. + + The name of your directory should be the same as the alias your + extension uses, for everyone's sanity. See nova/tests/api/openstack/extensions/foxinsocks.py for an example extension implementation. @@ -409,11 +387,11 @@ class ExtensionManager(object): if not inspect.isclass(cls): continue - #NOTE(justinsb): It seems that python modules aren't great - # If you have two identically named modules, the classes - # from both are mixed in. So name your extension based - # on the alias, not 'extension.py'! - #TODO(justinsb): Any way to work around this? + # NOTE(justinsb): It seems that python modules are odd. + # If you have two identically named modules, the classes + # from both are mixed in. So name your extension based + # on the alias, not 'extension.py'! + # TODO(justinsb): Any way to work around this? if self.super_verbose: LOG.debug(_('Checking class: %s'), cls) @@ -441,10 +419,7 @@ class ExtensionManager(object): class ResponseExtension(object): - """ - ResponseExtension objects can be used to add data to responses from - core nova OpenStack API controllers. - """ + """Add data to responses from core nova OpenStack API controllers.""" def __init__(self, method, url_route, handler): self.url_route = url_route @@ -454,10 +429,7 @@ class ResponseExtension(object): class ActionExtension(object): - """ - ActionExtension objects can be used to add custom actions to core nova - nova OpenStack API controllers. - """ + """Add custom actions to core nova OpenStack API controllers.""" def __init__(self, collection, action_name, handler): self.collection = collection @@ -466,10 +438,7 @@ class ActionExtension(object): class ResourceExtension(object): - """ - ResourceExtension objects can be used to add top level resources - to the OpenStack API in nova. - """ + """Add top level resources to the OpenStack API in nova.""" def __init__(self, collection, controller, parent=None, collection_actions={}, member_actions={}): -- cgit From a6e8c83196cb4b2d8a292a99cb1feb22ed9b21db Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Mon, 28 Mar 2011 16:36:25 -0700 Subject: Cleaned up images/fake.py, including move to Duplicate exception --- .../incubator/volumes/volume_attachments.py | 30 +++++++++++----------- nova/api/openstack/incubator/volumes/volumes.py | 18 ++++++------- .../api/openstack/incubator/volumes/volumes_ext.py | 4 +-- nova/compute/manager.py | 2 +- nova/image/fake.py | 29 +++++++++------------ 5 files changed, 39 insertions(+), 44 deletions(-) diff --git a/nova/api/openstack/incubator/volumes/volume_attachments.py b/nova/api/openstack/incubator/volumes/volume_attachments.py index 93786d1c7..1e260b34d 100644 --- a/nova/api/openstack/incubator/volumes/volume_attachments.py +++ b/nova/api/openstack/incubator/volumes/volume_attachments.py @@ -34,7 +34,7 @@ FLAGS = flags.FLAGS def _translate_detail_view(context, volume): - """Maps keys for details view""" + """Maps keys for details view.""" d = _translate_summary_view(context, volume) @@ -44,12 +44,12 @@ def _translate_detail_view(context, volume): def _translate_summary_view(context, vol): - """Maps keys for summary view""" + """Maps keys for summary view.""" d = {} volume_id = vol['id'] - #NOTE(justinsb): We use the volume id as the id of the attachment object + # NOTE(justinsb): We use the volume id as the id of the attachment object d['id'] = volume_id d['volumeId'] = volume_id @@ -62,7 +62,7 @@ def _translate_summary_view(context, vol): class Controller(wsgi.Controller): - """The volume attachment API controller for the Openstack API + """The volume attachment API controller for the Openstack API. A child resource of the server. Note that we use the volume id as the ID of the attachment (though this is not guaranteed externally)""" @@ -81,12 +81,12 @@ class Controller(wsgi.Controller): super(Controller, self).__init__() def index(self, req, server_id): - """Returns the list of volume attachments for a given instance """ + """Returns the list of volume attachments for a given instance.""" return self._items(req, server_id, entity_maker=_translate_summary_view) def show(self, req, server_id, id): - """Return data about the given volume""" + """Return data about the given volume.""" context = req.environ['nova.context'] volume_id = id @@ -103,7 +103,7 @@ class Controller(wsgi.Controller): return {'volumeAttachment': _translate_detail_view(context, vol)} def create(self, req, server_id): - """Attach a volume to an instance """ + """Attach a volume to an instance.""" context = req.environ['nova.context'] env = self._deserialize(req.body, req.get_content_type()) @@ -131,15 +131,15 @@ class Controller(wsgi.Controller): attachment['id'] = volume_id attachment['volumeId'] = volume_id - #NOTE(justinsb): And now, we have a problem... + # NOTE(justinsb): And now, we have a problem... # The attach is async, so there's a window in which we don't see - # the attachment (until the attachment completes). We could also - # get problems with concurrent requests. I think we need an - # attachment state, and to write to the DB here, but that's a bigger - # change. + # the attachment (until the attachment completes). We could also + # get problems with concurrent requests. I think we need an + # attachment state, and to write to the DB here, but that's a bigger + # change. # For now, we'll probably have to rely on libraries being smart - #TODO(justinsb): How do I return "accepted" here? + # TODO(justinsb): How do I return "accepted" here? return {'volumeAttachment': attachment} def update(self, _req, _server_id, _id): @@ -147,7 +147,7 @@ class Controller(wsgi.Controller): return faults.Fault(exc.HTTPBadRequest()) def delete(self, req, server_id, id): - """Detach a volume from an instance """ + """Detach a volume from an instance.""" context = req.environ['nova.context'] volume_id = id @@ -168,7 +168,7 @@ class Controller(wsgi.Controller): return exc.HTTPAccepted() def _items(self, req, server_id, entity_maker): - """Returns a list of attachments, transformed through entity_maker""" + """Returns a list of attachments, transformed through entity_maker.""" context = req.environ['nova.context'] try: diff --git a/nova/api/openstack/incubator/volumes/volumes.py b/nova/api/openstack/incubator/volumes/volumes.py index e122bb465..a7d5fbaa6 100644 --- a/nova/api/openstack/incubator/volumes/volumes.py +++ b/nova/api/openstack/incubator/volumes/volumes.py @@ -31,7 +31,7 @@ FLAGS = flags.FLAGS def _translate_detail_view(context, vol): - """Maps keys for details view""" + """Maps keys for details view.""" d = _translate_summary_view(context, vol) @@ -41,7 +41,7 @@ def _translate_detail_view(context, vol): def _translate_summary_view(_context, vol): - """Maps keys for summary view""" + """Maps keys for summary view.""" d = {} instance_id = None @@ -79,7 +79,7 @@ def _translate_summary_view(_context, vol): class Controller(wsgi.Controller): - """The Volumes API controller for the OpenStack API""" + """The Volumes API controller for the OpenStack API.""" _serialization_metadata = { 'application/xml': { @@ -99,7 +99,7 @@ class Controller(wsgi.Controller): super(Controller, self).__init__() def show(self, req, id): - """Return data about the given volume""" + """Return data about the given volume.""" context = req.environ['nova.context'] try: @@ -110,7 +110,7 @@ class Controller(wsgi.Controller): return {'volume': _translate_detail_view(context, vol)} def delete(self, req, id): - """Delete a volume """ + """Delete a volume.""" context = req.environ['nova.context'] LOG.audit(_("Delete volume with id: %s"), id, context=context) @@ -122,15 +122,15 @@ class Controller(wsgi.Controller): return exc.HTTPAccepted() def index(self, req): - """Returns a summary list of volumes""" + """Returns a summary list of volumes.""" return self._items(req, entity_maker=_translate_summary_view) def detail(self, req): - """Returns a detailed list of volumes """ + """Returns a detailed list of volumes.""" return self._items(req, entity_maker=_translate_detail_view) def _items(self, req, entity_maker): - """Returns a list of volumes, transformed through entity_maker""" + """Returns a list of volumes, transformed through entity_maker.""" context = req.environ['nova.context'] volumes = self.volume_api.get_all(context) @@ -139,7 +139,7 @@ class Controller(wsgi.Controller): return {'volumes': res} def create(self, req): - """Creates a new volume""" + """Creates a new volume.""" context = req.environ['nova.context'] env = self._deserialize(req.body, req.get_content_type()) diff --git a/nova/api/openstack/incubator/volumes/volumes_ext.py b/nova/api/openstack/incubator/volumes/volumes_ext.py index 87a57320d..6a3bb0265 100644 --- a/nova/api/openstack/incubator/volumes/volumes_ext.py +++ b/nova/api/openstack/incubator/volumes/volumes_ext.py @@ -37,8 +37,8 @@ class VolumesExtension(extensions.ExtensionDescriptor): def get_resources(self): resources = [] - #NOTE(justinsb): No way to provide singular name ('volume') - # Does this matter? + # NOTE(justinsb): No way to provide singular name ('volume') + # Does this matter? res = extensions.ResourceExtension('volumes', volumes.Controller(), collection_actions={'detail': 'GET'} diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 10636f602..468771f46 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1078,6 +1078,6 @@ class ComputeManager(manager.SchedulerDependentManager): # Are there VMs not in the DB? for vm_not_found_in_db in vms_not_found_in_db: name = vm_not_found_in_db - #TODO(justinsb): What to do here? Adopt it? Shut it down? + # TODO(justinsb): What to do here? Adopt it? Shut it down? LOG.warning(_("Found VM not in DB: '%(name)s'. Ignoring") % locals()) diff --git a/nova/image/fake.py b/nova/image/fake.py index 29159f337..cdb650165 100644 --- a/nova/image/fake.py +++ b/nova/image/fake.py @@ -29,11 +29,11 @@ FLAGS = flags.FLAGS class MockImageService(service.BaseImageService): - """Mock (fake) image service for unit testing""" + """Mock (fake) image service for unit testing.""" def __init__(self): self.images = {} - # NOTE(justinsb): The OpenStack API can't upload an image??? + # NOTE(justinsb): The OpenStack API can't upload an image? # So, make sure we've got one.. image = {'id': '123456', 'status': 'active', @@ -46,17 +46,17 @@ class MockImageService(service.BaseImageService): super(MockImageService, self).__init__() def index(self, context): - """Returns list of images""" + """Returns list of images.""" return self.images.values() def detail(self, context): - """Return list of detailed image information""" + """Return list of detailed image information.""" return self.images.values() def show(self, context, image_id): - """ - Returns a dict containing image data for the given opaque image id. - """ + """Get data about specified image. + + Returns a dict containing image data for the given opaque image id.""" image_id = int(image_id) image = self.images.get(image_id) if image: @@ -66,16 +66,14 @@ class MockImageService(service.BaseImageService): raise exception.NotFound def create(self, context, data): - """ - Store the image data and return the new image id. + """Store the image data and return the new image id. - :raises AlreadyExists if the image already exist. + :raises Duplicate if the image already exist. """ image_id = int(data['id']) if self.images.get(image_id): - #TODO(justinsb): Where is this AlreadyExists exception?? - raise exception.Error("AlreadyExists") + raise exception.Duplicate() self.images[image_id] = data @@ -91,8 +89,7 @@ class MockImageService(service.BaseImageService): self.images[image_id] = data def delete(self, context, image_id): - """ - Delete the given image. + """Delete the given image. :raises NotFound if the image does not exist. @@ -103,7 +100,5 @@ class MockImageService(service.BaseImageService): raise exception.NotFound def delete_all(self): - """ - Clears out all images - """ + """Clears out all images.""" self.images.clear() -- cgit From 276c153f44734e78cae25deb9fc9e79a604c6219 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Mon, 28 Mar 2011 16:42:28 -0700 Subject: More fixes to keep the stylebot happy --- nova/tests/integrated/api/client.py | 2 +- nova/tests/integrated/integrated_helpers.py | 20 ++++++++++---------- nova/tests/integrated/test_extensions.py | 2 +- nova/tests/integrated/test_login.py | 8 ++++---- nova/tests/integrated/test_servers.py | 16 ++++++++-------- nova/tests/integrated/test_volumes.py | 18 +++++++++--------- nova/virt/driver.py | 2 +- nova/volume/driver.py | 2 +- 8 files changed, 35 insertions(+), 35 deletions(-) diff --git a/nova/tests/integrated/api/client.py b/nova/tests/integrated/api/client.py index b9ed7b03b..b40ff58e3 100644 --- a/nova/tests/integrated/api/client.py +++ b/nova/tests/integrated/api/client.py @@ -124,7 +124,7 @@ class TestOpenStackClient(object): def api_request(self, relative_uri, check_response_status=None, **kwargs): auth_result = self._authenticate() - #NOTE(justinsb): httplib 'helpfully' converts headers to lower case + # NOTE(justinsb): httplib 'helpfully' converts headers to lower case base_uri = auth_result['x-server-management-url'] full_uri = base_uri + relative_uri diff --git a/nova/tests/integrated/integrated_helpers.py b/nova/tests/integrated/integrated_helpers.py index bc516b4b3..e0fe2d2a2 100644 --- a/nova/tests/integrated/integrated_helpers.py +++ b/nova/tests/integrated/integrated_helpers.py @@ -37,19 +37,19 @@ LOG = logging.getLogger('nova.tests.integrated') def generate_random_alphanumeric(length): - """Creates a random alphanumeric string of specified length""" + """Creates a random alphanumeric string of specified length.""" return ''.join(random.choice(string.ascii_uppercase + string.digits) for _x in range(length)) def generate_random_numeric(length): - """Creates a random numeric string of specified length""" + """Creates a random numeric string of specified length.""" return ''.join(random.choice(string.digits) for _x in range(length)) def generate_new_element(items, prefix, numeric=False): - """Creates a random string with prefix, that is not in 'items' list""" + """Creates a random string with prefix, that is not in 'items' list.""" while True: if numeric: candidate = prefix + generate_random_numeric(8) @@ -85,7 +85,7 @@ class TestUser(object): def get_valid_image(self, create=False): images = self.openstack_api.get_images() if create and not images: - #TODO(justinsb): No way currently to create an image through API + # TODO(justinsb): No way currently to create an image through API #created_image = self.openstack_api.post_image(image) #images.append(created_image) raise exception.Error("No way to create an image through API") @@ -154,9 +154,9 @@ class _IntegratedTestBase(test.TestCase): # set up services self.start_service('compute') self.start_service('volume') - #NOTE(justinsb): There's a bug here which is eluding me... - # If we start the network_service, all is good, but then subsequent - # tests fail: CloudTestCase.test_ajax_console in particular. + # NOTE(justinsb): There's a bug here which is eluding me... + # If we start the network_service, all is good, but then subsequent + # tests fail: CloudTestCase.test_ajax_console in particular. #self.start_service('network') self.start_service('scheduler') @@ -182,7 +182,7 @@ class _IntegratedTestBase(test.TestCase): super(_IntegratedTestBase, self).tearDown() def _get_flags(self): - """An opportunity to setup flags, before the services are started""" + """An opportunity to setup flags, before the services are started.""" f = {} f['image_service'] = 'nova.image.fake.MockImageService' f['fake_network'] = True @@ -197,11 +197,11 @@ class _IntegratedTestBase(test.TestCase): if 'imageRef' in image: image_ref = image['imageRef'] else: - #NOTE(justinsb): The imageRef code hasn't yet landed + # NOTE(justinsb): The imageRef code hasn't yet landed LOG.warning("imageRef not yet in images output") image_ref = image['id'] - #TODO(justinsb): This is FUBAR + # TODO(justinsb): This is FUBAR image_ref = abs(hash(image_ref)) image_ref = 'http://fake.server/%s' % image_ref diff --git a/nova/tests/integrated/test_extensions.py b/nova/tests/integrated/test_extensions.py index 1aa471f49..0d4ee8cab 100644 --- a/nova/tests/integrated/test_extensions.py +++ b/nova/tests/integrated/test_extensions.py @@ -37,7 +37,7 @@ class ExtensionsTest(integrated_helpers._IntegratedTestBase): return f def test_get_foxnsocks(self): - """Simple check that fox-n-socks works""" + """Simple check that fox-n-socks works.""" response = self.api.api_request('/foxnsocks') foxnsocks = response.read() LOG.debug("foxnsocks: %s" % foxnsocks) diff --git a/nova/tests/integrated/test_login.py b/nova/tests/integrated/test_login.py index d6e067c29..a5180b6bc 100644 --- a/nova/tests/integrated/test_login.py +++ b/nova/tests/integrated/test_login.py @@ -31,13 +31,13 @@ FLAGS.verbose = True class LoginTest(integrated_helpers._IntegratedTestBase): def test_login(self): - """Simple check - we list flavors - so we know we're logged in""" + """Simple check - we list flavors - so we know we're logged in.""" flavors = self.api.get_flavors() for flavor in flavors: LOG.debug(_("flavor: %s") % flavor) def test_bad_login_password(self): - """Test that I get a 401 with a bad username""" + """Test that I get a 401 with a bad username.""" bad_credentials_api = client.TestOpenStackClient(self.user.name, "notso_password", self.user.auth_url) @@ -46,7 +46,7 @@ class LoginTest(integrated_helpers._IntegratedTestBase): bad_credentials_api.get_flavors) def test_bad_login_username(self): - """Test that I get a 401 with a bad password""" + """Test that I get a 401 with a bad password.""" bad_credentials_api = client.TestOpenStackClient("notso_username", self.user.secret, self.user.auth_url) @@ -55,7 +55,7 @@ class LoginTest(integrated_helpers._IntegratedTestBase): bad_credentials_api.get_flavors) def test_bad_login_both_bad(self): - """Test that I get a 401 with both bad username and bad password""" + """Test that I get a 401 with both bad username and bad password.""" bad_credentials_api = client.TestOpenStackClient("notso_username", "notso_password", self.user.auth_url) diff --git a/nova/tests/integrated/test_servers.py b/nova/tests/integrated/test_servers.py index 59e5dde14..749ea8955 100644 --- a/nova/tests/integrated/test_servers.py +++ b/nova/tests/integrated/test_servers.py @@ -39,7 +39,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): LOG.debug("server: %s" % server) def test_create_and_delete_server(self): - """Creates and deletes a server""" + """Creates and deletes a server.""" # Create server @@ -50,13 +50,13 @@ class ServersTest(integrated_helpers._IntegratedTestBase): post = {'server': server} # Without an imageRef, this throws 500. - #TODO(justinsb): Check whatever the spec says should be thrown here + # TODO(justinsb): Check whatever the spec says should be thrown here self.assertRaises(client.OpenStackApiException, self.api.post_server, post) # With an invalid imageRef, this throws 500. server['imageRef'] = self.user.get_invalid_image() - #TODO(justinsb): Check whatever the spec says should be thrown here + # TODO(justinsb): Check whatever the spec says should be thrown here self.assertRaises(client.OpenStackApiException, self.api.post_server, post) @@ -65,7 +65,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): server['imageRef'] = good_server.get('imageRef') # Without flavorId, this throws 500 - #TODO(justinsb): Check whatever the spec says should be thrown here + # TODO(justinsb): Check whatever the spec says should be thrown here self.assertRaises(client.OpenStackApiException, self.api.post_server, post) @@ -74,7 +74,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): server['flavorId'] = good_server.get('flavorId') # Without a name, this throws 500 - #TODO(justinsb): Check whatever the spec says should be thrown here + # TODO(justinsb): Check whatever the spec says should be thrown here self.assertRaises(client.OpenStackApiException, self.api.post_server, post) @@ -106,7 +106,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): break # It should be available... - #TODO(justinsb): Mock doesn't yet do this... + # TODO(justinsb): Mock doesn't yet do this... #self.assertEqual('available', found_server['status']) self._delete_server(created_server_id) @@ -126,7 +126,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): LOG.debug("Found_server=%s" % found_server) - #TODO(justinsb): Mock doesn't yet do accurate state changes + # TODO(justinsb): Mock doesn't yet do accurate state changes #if found_server['status'] != 'deleting': # break time.sleep(1) @@ -134,7 +134,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): # Should be gone self.assertFalse(found_server) -#TODO(justinsb): Enable this unit test when the metadata bug is fixed +# TODO(justinsb): Enable this unit test when the metadata bug is fixed # def test_create_server_with_metadata(self): # """Creates a server with metadata""" # diff --git a/nova/tests/integrated/test_volumes.py b/nova/tests/integrated/test_volumes.py index 89480618d..e9fb3c4d1 100644 --- a/nova/tests/integrated/test_volumes.py +++ b/nova/tests/integrated/test_volumes.py @@ -44,19 +44,19 @@ class VolumesTest(integrated_helpers._IntegratedTestBase): return f def test_get_volumes_summary(self): - """Simple check that listing volumes works""" + """Simple check that listing volumes works.""" volumes = self.api.get_volumes(False) for volume in volumes: LOG.debug("volume: %s" % volume) def test_get_volumes(self): - """Simple check that listing volumes works""" + """Simple check that listing volumes works.""" volumes = self.api.get_volumes() for volume in volumes: LOG.debug("volume: %s" % volume) def _poll_while(self, volume_id, continue_states, max_retries=5): - """Poll (briefly) while the state is in continue_states""" + """Poll (briefly) while the state is in continue_states.""" retries = 0 while True: try: @@ -80,7 +80,7 @@ class VolumesTest(integrated_helpers._IntegratedTestBase): return found_volume def test_create_and_delete_volume(self): - """Creates and deletes a volume""" + """Creates and deletes a volume.""" # Create volume created_volume = self.api.post_volume({'volume': {'size': 1}}) @@ -141,11 +141,11 @@ class VolumesTest(integrated_helpers._IntegratedTestBase): self.assertEquals(delete_action['id'], created_volume_id) def test_attach_and_detach_volume(self): - """Creates, attaches, detaches and deletes a volume""" + """Creates, attaches, detaches and deletes a volume.""" # Create server server_req = {'server': self._build_minimal_create_server_request()} - #NOTE(justinsb): Create an extra server so that server_id != volume_id + # NOTE(justinsb): Create an extra server so that server_id != volume_id self.api.post_server(server_req) created_server = self.api.post_server(server_req) LOG.debug("created_server: %s" % created_server) @@ -198,9 +198,9 @@ class VolumesTest(integrated_helpers._IntegratedTestBase): # This is just an implementation detail, but let's check it... self.assertEquals(volume_id, attachment_id) - #NOTE(justinsb): There's an issue with the attach code, in that - # it's currently asynchronous and not recorded until the attach - # completes. So the caller must be 'smart', like this... + # NOTE(justinsb): There's an issue with the attach code, in that + # it's currently asynchronous and not recorded until the attach + # completes. So the caller must be 'smart', like this... attach_done = None retries = 0 while True: diff --git a/nova/virt/driver.py b/nova/virt/driver.py index eafede17a..f85796a97 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -125,7 +125,7 @@ class ComputeDriver(object): raise NotImplementedError() def snapshot(self, instance, image_id): - """Create snapshot from a running VM instance """ + """Create snapshot from a running VM instance.""" raise NotImplementedError() def finish_resize(self, instance, disk_info): diff --git a/nova/volume/driver.py b/nova/volume/driver.py index 161b35d1d..850893914 100644 --- a/nova/volume/driver.py +++ b/nova/volume/driver.py @@ -573,7 +573,7 @@ class RBDDriver(VolumeDriver): def discover_volume(self, volume): """Discover volume on a remote host""" - #NOTE(justinsb): This is messed up... discover_volume takes 3 args + # NOTE(justinsb): This is messed up... discover_volume takes 3 args # but then that would break local_path return "rbd:%s/%s" % (FLAGS.rbd_pool, volume['name']) -- cgit From 3a39fb7b09dfee3c971ae4adaeff4717f4839f8a Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 28 Mar 2011 16:50:33 -0700 Subject: add note per review --- smoketests/test_sysadmin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/smoketests/test_sysadmin.py b/smoketests/test_sysadmin.py index 89a3e60c4..268d9865b 100644 --- a/smoketests/test_sysadmin.py +++ b/smoketests/test_sysadmin.py @@ -269,6 +269,7 @@ class VolumeTests(base.UserSmokeTestCase): "cat /sys/class/block/%s/size" % self.device.rpartition('/')[2]) out = stdout.read().strip() conn.close() + # NOTE(vish): 1G bytes / 512 bytes per block expected_size = 1024 * 1024 * 1024 / 512 self.assertEquals('%s' % (expected_size,), out, 'Volume is not the right size: %s %s. Expected: %s' % -- cgit From 87bc3bca7904135656ed3a99efc19952be95dcbf Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Mon, 28 Mar 2011 16:54:17 -0700 Subject: Multi-line comments should end in a blankline --- nova/api/openstack/incubator/volumes/volume_attachments.py | 4 +++- nova/image/fake.py | 4 +++- nova/tests/integrated/api/client.py | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/nova/api/openstack/incubator/volumes/volume_attachments.py b/nova/api/openstack/incubator/volumes/volume_attachments.py index 1e260b34d..aec4ea8f3 100644 --- a/nova/api/openstack/incubator/volumes/volume_attachments.py +++ b/nova/api/openstack/incubator/volumes/volume_attachments.py @@ -65,7 +65,9 @@ class Controller(wsgi.Controller): """The volume attachment API controller for the Openstack API. A child resource of the server. Note that we use the volume id - as the ID of the attachment (though this is not guaranteed externally)""" + as the ID of the attachment (though this is not guaranteed externally) + + """ _serialization_metadata = { 'application/xml': { diff --git a/nova/image/fake.py b/nova/image/fake.py index cdb650165..4caf68d63 100644 --- a/nova/image/fake.py +++ b/nova/image/fake.py @@ -56,7 +56,9 @@ class MockImageService(service.BaseImageService): def show(self, context, image_id): """Get data about specified image. - Returns a dict containing image data for the given opaque image id.""" + Returns a dict containing image data for the given opaque image id. + + """ image_id = int(image_id) image = self.images.get(image_id) if image: diff --git a/nova/tests/integrated/api/client.py b/nova/tests/integrated/api/client.py index b40ff58e3..7e20c9b00 100644 --- a/nova/tests/integrated/api/client.py +++ b/nova/tests/integrated/api/client.py @@ -59,7 +59,9 @@ class TestOpenStackClient(object): """Simple OpenStack API Client. This is a really basic OpenStack API client that is under our control, - so we can make changes / insert hooks for testing""" + so we can make changes / insert hooks for testing + + """ def __init__(self, auth_user, auth_key, auth_uri): super(TestOpenStackClient, self).__init__() -- cgit From 55b801db77b9d631e746e79bd84a7866d1877fb2 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Mon, 28 Mar 2011 17:09:39 -0700 Subject: More style changes --- nova/api/openstack/extensions.py | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index 1c39dd0e2..d0b4d378a 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -43,45 +43,59 @@ class ExtensionDescriptor(object): def get_name(self): """The name of the extension. - e.g. 'Fox In Socks' """ + e.g. 'Fox In Socks' + + """ raise NotImplementedError() def get_alias(self): """The alias for the extension. - e.g. 'FOXNSOX'""" + e.g. 'FOXNSOX' + + """ raise NotImplementedError() def get_description(self): """Friendly description for the extension. - e.g. 'The Fox In Socks Extension'""" + e.g. 'The Fox In Socks Extension' + + """ raise NotImplementedError() def get_namespace(self): """The XML namespace for the extension. - e.g. 'http://www.fox.in.socks/api/ext/pie/v1.0'""" + e.g. 'http://www.fox.in.socks/api/ext/pie/v1.0' + + """ raise NotImplementedError() def get_updated(self): """The timestamp when the extension was last updated. - e.g. '2011-01-22T13:25:27-06:00'""" + e.g. '2011-01-22T13:25:27-06:00' + + """ # NOTE(justinsb): Not sure of the purpose of this is, vs the XML NS raise NotImplementedError() def get_resources(self): """List of extensions.ResourceExtension extension objects. - Resources define new nouns, and are accessible through URLs""" + Resources define new nouns, and are accessible through URLs. + + """ resources = [] return resources def get_actions(self): """List of extensions.ActionExtension extension objects. - Actions are verbs callable from the API""" + Actions are verbs callable from the API. + + """ actions = [] return actions @@ -89,7 +103,9 @@ class ExtensionDescriptor(object): """List of extensions.ResponseExtension extension objects. Response extensions are used to insert information into existing - response data""" + response data. + + """ response_exts = [] return response_exts @@ -274,6 +290,7 @@ class ExtensionMiddleware(wsgi.Middleware): Returns the routed WSGI app's response or defers to the extended application. + """ match = req.environ['wsgiorg.routing_args'][1] if not match: @@ -287,6 +304,7 @@ class ExtensionManager(object): See nova/tests/api/openstack/extensions/foxinsocks/extension.py for an example extension implementation. + """ def __init__(self, path): @@ -347,6 +365,7 @@ class ExtensionManager(object): See nova/tests/api/openstack/extensions/foxinsocks.py for an example extension implementation. + """ self._load_extensions_under_path(self.path) -- cgit From 699f82e7e14146feb272d61a98b89ad53c93bf08 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Mon, 28 Mar 2011 17:11:16 -0700 Subject: Yet more docstring fixes --- nova/virt/driver.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nova/virt/driver.py b/nova/virt/driver.py index 55281b741..c6c28b2ba 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -77,6 +77,7 @@ class ComputeDriver(object): If the instance is not found (for example if networking failed), this function should still succeed. It's probably a good idea to log a warning in that case. + """ raise NotImplementedError() @@ -94,6 +95,7 @@ class ComputeDriver(object): :address: ? :username: ? :password: ? + """ raise NotImplementedError() -- cgit From 0e81c4175cad97359e848c993efd9a91eb981174 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Mon, 28 Mar 2011 21:22:53 -0400 Subject: Pass along the nbd flags although we dont support it just yet --- nova/virt/disk.py | 13 ++++++++----- nova/virt/libvirt_conn.py | 5 +++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index 15cd49789..11a7a969e 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -116,13 +116,14 @@ def inject_data(image, key=None, net=None, partition=None, nbd=False): _unlink_device(device, nbd) -def setup_container(image, container_dir=None): +def setup_container(image, container_dir=None, nbd=False): """Setup the LXC container It will mount the loopback image to the container directory in order - to create the root filesystem for the container + to create the root filesystem for the container. + + LXC does not support qcow2 images yet. """ - nbd = "False" device = _link_device(image, nbd) out, err = utils.execute('sudo', 'mount', device, container_dir) if err: @@ -131,11 +132,13 @@ def setup_container(image, container_dir=None): _unlink_device(device, nbd) -def destroy_container(target, instance): +def destroy_container(target, instance, nbd=False): """Destroy the container once it terminates It will umount the container that is mounted, try to find the loopback device associated with the container and delete it. + + LXC does not support qcow2 images yet. """ try: container_dir = '%s/rootfs' % target @@ -145,7 +148,7 @@ def destroy_container(target, instance): for loop in out.splitlines(): if instance['name'] in loop: device = loop.split(loop, ':') - utils.execute('sudo', 'losetup', '--detach', device) + _unlink_device(device, nbd) def _link_device(image, nbd): diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 66d0d195b..af2dac9e8 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -342,7 +342,7 @@ class LibvirtConnection(driver.ComputeDriver): LOG.info(_('instance %(instance_name)s: deleting instance files' ' %(target)s') % locals()) if FLAGS.libvirt_type == 'lxc': - disk.destroy_container(target, instance) + disk.destroy_container(target, instance,nbd=FLAGS.use_cow_images) if os.path.exists(target): shutil.rmtree(target) @@ -797,7 +797,8 @@ class LibvirtConnection(driver.ComputeDriver): if FLAGS.libvirt_type == 'lxc': disk.setup_container(basepath('disk'), - container_dir=container_dir) + container_dir=container_dir, + nbd=FLAGS.use_cow_images) except Exception as e: # This could be a windows image, or a vmdk format disk LOG.warn(_('instance %(inst_name)s: ignoring error injecting' -- cgit From e5b0f3921331b5c0acbe321b00e2a9fa8d27be4e Mon Sep 17 00:00:00 2001 From: Muneyuki Noguchi Date: Tue, 29 Mar 2011 10:40:48 +0900 Subject: Add remove_volume to compute API. --- nova/compute/api.py | 7 +++++++ nova/compute/manager.py | 26 ++++++++++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index 266cbe677..0cdb8f4b7 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -668,6 +668,13 @@ class API(base.Base): "volume_id": volume_id}}) return instance + def remove_volume(self, context, volume_id, host): + """Remove volume on specified compute host.""" + rpc.call(context, + self.db.queue_get_for(context, FLAGS.compute_topic, host), + {"method": "remove_volume", + "args": {'volume_id': volume_id}}) + def associate_floating_ip(self, context, instance_id, address): instance = self.get(context, instance_id) self.network_api.associate_floating_ip(context, diff --git a/nova/compute/manager.py b/nova/compute/manager.py index aa612b137..bbd1fed1a 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -46,6 +46,7 @@ import functools from eventlet import greenthread +from nova import compute from nova import exception from nova import flags from nova import log as logging @@ -772,6 +773,14 @@ class ComputeManager(manager.SchedulerDependentManager): self.db.volume_detached(context, volume_id) return True + def remove_volume(self, context, volume_id): + """Remove volume on compute host. + + :param context: security context + :param volume_id: nova.db.sqlalchemy.models.Volume.id + """ + self.volume_manager.remove_compute_volume(context, volume_id) + @exception.wrap_exception def compare_cpu(self, context, cpu_info): """Checks the host cpu is compatible to a cpu given by xml. @@ -1018,22 +1027,15 @@ class ComputeManager(manager.SchedulerDependentManager): 'state': power_state.RUNNING, 'host': host}) + if dest: + # NOTE(noguchimn): We set image_service here + # not to import an image service object. + compute_api = compute.API(image_service=1) for volume in instance_ref['volumes']: volume_id = volume['id'] self.db.volume_update(ctxt, volume_id, {'status': 'in-use'}) if dest: - topic = self.db.queue_get_for(ctxt, FLAGS.compute_topic, dest) - rpc.call(ctxt, topic, - {"method": "restore_volume_state", - "args": {'volume_id': volume_id}}) - - def restore_volume_state(self, context, volume_id): - """Restore volume state on migration failure. - - :param context: security context - :param volume_id: nova.db.sqlalchemy.models.Volume.id - """ - self.volume_manager.remove_compute_volume(context, volume_id) + compute_api.remove_volume(ctxt, volume_id, dest) def periodic_tasks(self, context=None): """Tasks to be run at a periodic interval.""" -- cgit From 5c74862a08a82b7db3e11fbcbec63293ea903e00 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Mon, 28 Mar 2011 23:11:42 -0700 Subject: make all openstack status uppercase --- nova/api/openstack/views/servers.py | 4 ++-- nova/tests/api/openstack/test_servers.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index 4e7f62eb3..6b471a0f4 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -72,12 +72,12 @@ class ViewBuilder(object): 'id': int(inst['id']), 'name': inst['display_name'], 'addresses': self.addresses_builder.build(inst), - 'status': power_mapping[inst.get('state')]} + 'status': power_mapping[inst.get('state')].upper()} ctxt = nova.context.get_admin_context() compute_api = nova.compute.API() if compute_api.has_finished_migration(ctxt, inst['id']): - inst_dict['status'] = 'resize-confirm' + inst_dict['status'] = 'resize-confirm'.upper() # Return the metadata as a dictionary metadata = {} diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 989385a8c..27cbd28c1 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -738,7 +738,7 @@ class ServersTest(test.TestCase): fake_migration_get) res = req.get_response(fakes.wsgi_app()) body = json.loads(res.body) - self.assertEqual(body['server']['status'], 'resize-confirm') + self.assertEqual(body['server']['status'], 'RESIZE-CONFIRM') def test_confirm_resize_server(self): req = self.webreq('/1/action', 'POST', dict(confirmResize=None)) -- cgit From 73f05da6400fe7f4324cf98c7d0706fb68a62870 Mon Sep 17 00:00:00 2001 From: Armando Migliaccio Date: Tue, 29 Mar 2011 11:20:16 +0100 Subject: sorted pep8 errors that were introduced during previous fixes --- nova/virt/xenapi/vmops.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index a9514bd61..c96c35a6e 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -430,7 +430,7 @@ class VMOps(object): """Set the root/admin password on the VM instance. This is done via an agent running on the VM. Communication between nova - and the agent is done via writing xenstore records. Since communication + and the agent is done via writing xenstore records. Since communication is done over the XenAPI RPC calls, we need to encrypt the password. We're using a simple Diffie-Hellman class instead of the more advanced one in M2Crypto for compatibility with the agent code. @@ -467,12 +467,12 @@ class VMOps(object): return resp_dict['message'] def inject_file(self, instance, path, contents): - """Write a file to the VM instance. + """Write a file to the VM instance. The path to which it is to be written and the contents of the file need to be supplied; both will be base64-encoded to prevent errors with non-ASCII characters being transmitted. If the agent does not - support file injection, or the user has disabled it, a + support file injection, or the user has disabled it, a NotImplementedError will be raised. """ -- cgit From ad6735df0de8676768353516eee4af62af2c993c Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Tue, 29 Mar 2011 08:56:42 -0400 Subject: Catch the error that mount might through a bit better --- nova/virt/disk.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index 11a7a969e..8adef744f 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -124,11 +124,11 @@ def setup_container(image, container_dir=None, nbd=False): LXC does not support qcow2 images yet. """ - device = _link_device(image, nbd) - out, err = utils.execute('sudo', 'mount', device, container_dir) - if err: - raise exception.Error(_('Failed to mount filesystem: %s') - % err) + try: + device = _link_device(image, nbd) + utils.execute('sudo', 'mount', device, container_dir) + except Exception, exn: + LOG.exception(_('Failed to mount filesystem: %s'), exn) _unlink_device(device, nbd) -- cgit From c4c9c0e5b70305ac06494bde35fcd18fdf60798e Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Tue, 29 Mar 2011 09:51:02 -0400 Subject: Tweaking docstrings just in case. --- nova/api/openstack/images.py | 3 +-- nova/api/openstack/views/images.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index ad748b4ca..d672e3a0e 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -32,8 +32,7 @@ FLAGS = flags.FLAGS class Controller(wsgi.Controller): - """Base `wsgi.Controller` for retrieving and displaying images in the - OpenStack API. Version-inspecific code goes here.""" + """Base `wsgi.Controller` for retrieving/displaying images.""" _serialization_metadata = { 'application/xml': { diff --git a/nova/api/openstack/views/images.py b/nova/api/openstack/views/images.py index 8f5568f6c..3807fa95f 100644 --- a/nova/api/openstack/views/images.py +++ b/nova/api/openstack/views/images.py @@ -19,8 +19,7 @@ import os.path class ViewBuilder(object): - """Base class for generating responses to OpenStack API requests for - information about images.""" + """Base class for generating responses to OpenStack API image requests.""" def __init__(self, base_url): """Initialize new `ViewBuilder`.""" -- cgit From beec33e8dbffbe3ea02eccec4952705698db377a Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Tue, 29 Mar 2011 10:01:54 -0400 Subject: Fix pep8 error --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index c4d41881d..ae3a967a4 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -347,7 +347,7 @@ class LibvirtConnection(driver.ComputeDriver): LOG.info(_('instance %(instance_name)s: deleting instance files' ' %(target)s') % locals()) if FLAGS.libvirt_type == 'lxc': - disk.destroy_container(target, instance,nbd=FLAGS.use_cow_images) + disk.destroy_container(target, instance, nbd=FLAGS.use_cow_images) if os.path.exists(target): shutil.rmtree(target) -- cgit From 793de5cef9fb539a4fb3ba976d83adde38a589c1 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Tue, 29 Mar 2011 10:40:35 -0400 Subject: adding more tests; making name checks more robust --- nova/api/openstack/servers.py | 11 +++++++++-- nova/tests/api/openstack/test_servers.py | 26 +++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index e9bc0a797..29c491716 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -250,8 +250,15 @@ class Controller(wsgi.Controller): if 'name' in inst_dict['server']: name = inst_dict['server']['name'] - if not isinstance(name, basestring) or name == '': - return exc.HTTPBadRequest() + if not isinstance(name, basestring): + msg = _("Server name is not a string or unicode") + return exc.HTTPBadRequest(msg) + + name = name.strip() + + if name == '': + msg = _("Server name is an empty string") + return exc.HTTPBadRequest(msg) update_dict['display_name'] = name diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 506b24b8b..ef4cf55b8 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -448,7 +448,31 @@ class ServersTest(test.TestCase): res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 422) - def test_update_bad_name(self): + def test_update_nonstring_name(self): + """ Confirm that update is filtering params """ + inst_dict = dict(name=12, adminPass='bacon') + self.body = json.dumps(dict(server=inst_dict)) + + req = webob.Request.blank('/v1.0/servers/1') + req.method = 'PUT' + req.content_type = "application/json" + req.body = self.body + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 400) + + def test_update_whitespace_name(self): + """ Confirm that update is filtering params """ + inst_dict = dict(name=' ', adminPass='bacon') + self.body = json.dumps(dict(server=inst_dict)) + + req = webob.Request.blank('/v1.0/servers/1') + req.method = 'PUT' + req.content_type = "application/json" + req.body = self.body + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 400) + + def test_update_null_name(self): """ Confirm that update is filtering params """ inst_dict = dict(name='', adminPass='bacon') self.body = json.dumps(dict(server=inst_dict)) -- cgit From c512bae72859b8583731886011e8f9a4310d69f8 Mon Sep 17 00:00:00 2001 From: Mark Washenberger Date: Tue, 29 Mar 2011 10:53:44 -0400 Subject: use informative error messages --- nova/api/openstack/servers.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index aaae17a39..31b9bc2f1 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -597,10 +597,12 @@ class ControllerV11(Controller): context = req.environ['nova.context'] if (not 'changePassword' in input_dict or not 'adminPass' in input_dict['changePassword']): - return exc.HTTPBadRequest() + msg = _("No adminPass was specified") + return exc.HTTPBadRequest(msg) password = input_dict['changePassword']['adminPass'] if not isinstance(password, basestring) or password == '': - return exc.HTTPBadRequest() + msg = _("Invalid adminPass") + return exc.HTTPBadRequest(msg) self.compute_api.set_admin_password(context, id, password) return exc.HTTPAccepted() -- cgit From f624d2e35dab0d87a289a346999c0cb01ed0aa55 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Tue, 29 Mar 2011 11:11:57 -0400 Subject: adding server name validation to create method; adding tests --- nova/api/openstack/servers.py | 36 ++++++++++------- nova/tests/api/openstack/test_servers.py | 68 ++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 14 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 29c491716..d564b37c1 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -150,6 +150,15 @@ class Controller(wsgi.Controller): injected_files = self._get_injected_files(personality) flavor_id = self._flavor_id_from_req_data(env) + + if not 'name' in env['server']: + msg = _("Server name is not defined") + return exc.HTTPBadRequest(msg) + + name = env['server']['name'] + self._validate_server_name(name) + name = name.strip() + try: (inst,) = self.compute_api.create( context, @@ -157,8 +166,8 @@ class Controller(wsgi.Controller): image_id, kernel_id=kernel_id, ramdisk_id=ramdisk_id, - display_name=env['server']['name'], - display_description=env['server']['name'], + display_name=name, + display_description=name, key_name=key_name, key_data=key_data, metadata=metadata, @@ -249,18 +258,8 @@ class Controller(wsgi.Controller): if 'name' in inst_dict['server']: name = inst_dict['server']['name'] - - if not isinstance(name, basestring): - msg = _("Server name is not a string or unicode") - return exc.HTTPBadRequest(msg) - - name = name.strip() - - if name == '': - msg = _("Server name is an empty string") - return exc.HTTPBadRequest(msg) - - update_dict['display_name'] = name + self._validate_server_name(name) + update_dict['display_name'] = name.strip() self._parse_update(ctxt, id, inst_dict, update_dict) @@ -271,6 +270,15 @@ class Controller(wsgi.Controller): return exc.HTTPNoContent() + def _validate_server_name(self, value): + if not isinstance(value, basestring): + msg = _("Server name is not a string or unicode") + raise exc.HTTPBadRequest(msg) + + if value.strip() == '': + msg = _("Server name is an empty string") + raise exc.HTTPBadRequest(msg) + def _parse_update(self, context, id, inst_dict, update_dict): pass diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index ef4cf55b8..130b8c5d5 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -392,6 +392,74 @@ class ServersTest(test.TestCase): fakes.stub_out_key_pair_funcs(self.stubs, have_key_pair=False) self._test_create_instance_helper() + def test_create_instance_no_name(self): + self._setup_for_create_instance() + + body = { + 'server': { + 'imageId': 3, + 'flavorId': 1, + 'metadata': { + 'hello': 'world', + 'open': 'stack', + }, + 'personality': {}, + }, + } + + req = webob.Request.blank('/v1.0/servers') + req.method = 'POST' + req.body = json.dumps(body) + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 400) + + def test_create_instance_nonstring_name(self): + self._setup_for_create_instance() + + body = { + 'server': { + 'name': 12, + 'imageId': 3, + 'flavorId': 1, + 'metadata': { + 'hello': 'world', + 'open': 'stack', + }, + 'personality': {}, + }, + } + + req = webob.Request.blank('/v1.0/servers') + req.method = 'POST' + req.body = json.dumps(body) + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 400) + + def test_create_instance_whitespace_name(self): + self._setup_for_create_instance() + + body = { + 'server': { + 'name': ' ', + 'imageId': 3, + 'flavorId': 1, + 'metadata': { + 'hello': 'world', + 'open': 'stack', + }, + 'personality': {}, + }, + } + + req = webob.Request.blank('/v1.0/servers') + req.method = 'POST' + req.body = json.dumps(body) + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 400) + def test_create_instance_v11(self): self._setup_for_create_instance() -- cgit From a070b8861ccc01b485b109855f44a36cd6ebdbd6 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Tue, 29 Mar 2011 11:16:42 -0400 Subject: pep8 --- nova/api/openstack/servers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index d564b37c1..4400a68a1 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -154,7 +154,7 @@ class Controller(wsgi.Controller): if not 'name' in env['server']: msg = _("Server name is not defined") return exc.HTTPBadRequest(msg) - + name = env['server']['name'] self._validate_server_name(name) name = name.strip() -- cgit From d1ef69edb8da18c5c7e56b6006e22022d55d6664 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Tue, 29 Mar 2011 11:41:33 -0400 Subject: adding code to explicitly set the content-type in versions controller; updating test --- nova/api/openstack/versions.py | 10 ++++++++-- nova/tests/api/openstack/test_versions.py | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/nova/api/openstack/versions.py b/nova/api/openstack/versions.py index 33f1dd628..3f9d91934 100644 --- a/nova/api/openstack/versions.py +++ b/nova/api/openstack/versions.py @@ -15,8 +15,8 @@ # License for the specific language governing permissions and limitations # under the License. +import webob import webob.dec -import webob.exc from nova import wsgi import nova.api.openstack.views.versions @@ -51,4 +51,10 @@ class Versions(wsgi.Application): } content_type = req.best_match_content_type() - return wsgi.Serializer(metadata).serialize(response, content_type) + body = wsgi.Serializer(metadata).serialize(response, content_type) + + response = webob.Response() + response.content_type = content_type + response.body = body + + return response diff --git a/nova/tests/api/openstack/test_versions.py b/nova/tests/api/openstack/test_versions.py index ebb59a9a6..ee922a8d3 100644 --- a/nova/tests/api/openstack/test_versions.py +++ b/nova/tests/api/openstack/test_versions.py @@ -34,8 +34,10 @@ class VersionsTest(test.TestCase): def test_get_version_list(self): req = webob.Request.blank('/') + req.accept = "application/json" res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 200) + self.assertEqual(res.content_type, "application/json") versions = json.loads(res.body)["versions"] expected = [ { -- cgit From 343b969f7d790282b7b76bcb23b9d0d578d716b9 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Tue, 29 Mar 2011 12:04:43 -0400 Subject: adding xml test case --- nova/tests/api/openstack/test_versions.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/nova/tests/api/openstack/test_versions.py b/nova/tests/api/openstack/test_versions.py index ee922a8d3..2640a4ddb 100644 --- a/nova/tests/api/openstack/test_versions.py +++ b/nova/tests/api/openstack/test_versions.py @@ -63,6 +63,30 @@ class VersionsTest(test.TestCase): ] self.assertEqual(versions, expected) + def test_get_version_list_xml(self): + req = webob.Request.blank('/') + req.accept = "application/xml" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 200) + self.assertEqual(res.content_type, "application/xml") + + expected = """ + + + + + + + + + + + """.replace(" ", "").replace("\n", "") + + actual = res.body.replace(" ", "").replace("\n", "") + + self.assertEqual(expected, actual) + def test_view_builder(self): base_url = "http://example.org/" -- cgit From 07d985f8db30863bb9171e14fccbdb51d7b35f11 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Tue, 29 Mar 2011 12:06:52 -0400 Subject: Switch string concat style. --- nova/image/glance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/image/glance.py b/nova/image/glance.py index d8f51429e..fdf468594 100644 --- a/nova/image/glance.py +++ b/nova/image/glance.py @@ -238,5 +238,5 @@ def _parse_glance_iso8601_timestamp(timestamp): except ValueError: pass - raise ValueError(_("""%(timestamp)s does not follow any of the \ -signatures: %(ISO_FORMATS)s""") % locals()) + raise ValueError(_("%(timestamp)s does not follow any of the " + "signatures: %(ISO_FORMATS)s") % locals()) -- cgit From 2f89d5541aa11b8654b197ffe24d3fd13e945da6 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Tue, 29 Mar 2011 12:12:26 -0400 Subject: Import order. --- nova/api/openstack/images.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index d672e3a0e..e77100d7b 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -13,9 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. -import webob.exc import datetime +import webob.exc + from nova import compute from nova import exception from nova import flags -- cgit From 3b8aa1fed7cd6d1deb580eec0af283947060c04d Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Tue, 29 Mar 2011 21:26:17 +0400 Subject: Added checks that exists at least one network marked inhected in libvirt and xenapi --- nova/virt/libvirt_conn.py | 5 ++++- nova/virt/xenapi/vm_utils.py | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 80eb64f3c..7dd09813d 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -803,6 +803,7 @@ class LibvirtConnection(driver.ComputeDriver): nets = [] ifc_template = open(FLAGS.injected_network_template).read() ifc_num = -1 + have_injected_networks = False admin_context = context.get_admin_context() for (network_ref, mapping) in network_info: ifc_num += 1 @@ -810,6 +811,7 @@ class LibvirtConnection(driver.ComputeDriver): if not 'injected' in network_ref: continue + have_injected_networks = True address = mapping['ips'][0]['ip'] address_v6 = None if FLAGS.use_ipv6: @@ -825,7 +827,8 @@ class LibvirtConnection(driver.ComputeDriver): 'netmask_v6': network_ref['netmask_v6']} nets.append(net_info) - net = str(Template(ifc_template, + if have_injected_networks: + net = str(Template(ifc_template, searchList=[{'interfaces': nets, 'use_ipv6': FLAGS.use_ipv6}])) diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 2288ea8a5..18c29134d 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -1108,11 +1108,13 @@ def _prepare_injectables(inst, networks_info): if networks_info: ifc_num = -1 interfaces_info = [] + have_injected_networks = False for (network_ref, info) in networks_info: ifc_num += 1 if not network_ref['injected']: continue + have_injected_networks = True ip_v4 = ip_v6 = None if 'ips' in info and len(info['ips']) > 0: ip_v4 = info['ips'][0] @@ -1131,7 +1133,9 @@ def _prepare_injectables(inst, networks_info): 'gateway_v6': ip_v6 and ip_v6['gateway'] or '', 'use_ipv6': FLAGS.use_ipv6} interfaces_info.append(interface_info) - net = str(template(template_data, + + if have_injected_networks: + net = str(template(template_data, searchList=[{'interfaces': interfaces_info, 'use_ipv6': FLAGS.use_ipv6}])) return key, net -- cgit From d7798b3b383b32576f79e281a220266b65702b1e Mon Sep 17 00:00:00 2001 From: termie Date: Tue, 29 Mar 2011 11:15:16 -0700 Subject: accidentally dropped a sentence --- HACKING | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/HACKING b/HACKING index 95afc0f74..2f364c894 100644 --- a/HACKING +++ b/HACKING @@ -57,7 +57,9 @@ Docstrings Then a new paragraph after a newline that explains in more detail any general information about the function, class or method. Example usages - are also great to have here if it is a complex class for function. + are also great to have here if it is a complex class for function. After + you have finished your descriptions add an extra newline and close the + quotations. When writing the docstring for a class, an extra line should be placed after the closing quotations. For more in-depth explanations for these -- cgit From 2af6fb2a4d3659e9882a6f6d1c8e71bc8f040aba Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Tue, 29 Mar 2011 14:56:18 -0400 Subject: Added content_type to OSAPI faults. --- nova/api/openstack/faults.py | 1 + nova/tests/api/openstack/test_faults.py | 122 ++++++++++++++++++++++++++------ 2 files changed, 103 insertions(+), 20 deletions(-) diff --git a/nova/api/openstack/faults.py b/nova/api/openstack/faults.py index 0e9c4b26f..940bd8771 100644 --- a/nova/api/openstack/faults.py +++ b/nova/api/openstack/faults.py @@ -60,6 +60,7 @@ class Fault(webob.exc.HTTPException): serializer = wsgi.Serializer(metadata) content_type = req.best_match_content_type() self.wrapped_exc.body = serializer.serialize(fault_data, content_type) + self.wrapped_exc.content_type = content_type return self.wrapped_exc diff --git a/nova/tests/api/openstack/test_faults.py b/nova/tests/api/openstack/test_faults.py index 7667753f4..0cda542de 100644 --- a/nova/tests/api/openstack/test_faults.py +++ b/nova/tests/api/openstack/test_faults.py @@ -15,6 +15,8 @@ # License for the specific language governing permissions and limitations # under the License. +import json + import webob import webob.dec import webob.exc @@ -24,35 +26,115 @@ from nova.api.openstack import faults class TestFaults(test.TestCase): + """Tests covering `nova.api.openstack.faults:Fault` class.""" - def test_fault_parts(self): - req = webob.Request.blank('/.xml') - f = faults.Fault(webob.exc.HTTPBadRequest(explanation='scram')) - resp = req.get_response(f) + def _prepare_xml(self, xml_string): + """Remove characters from string which hinder XML equality testing.""" + xml_string = xml_string.replace(" ", "") + xml_string = xml_string.replace("\n", "") + xml_string = xml_string.replace("\t", "") + return xml_string - first_two_words = resp.body.strip().split()[:2] - self.assertEqual(first_two_words, ['']) - body_without_spaces = ''.join(resp.body.split()) - self.assertTrue('scram' in body_without_spaces) + def test_400_fault_xml(self): + """Test fault serialized to XML via file-extension and/or header.""" + requests = [ + webob.Request.blank('/.xml'), + webob.Request.blank('/', headers={"Accept": "application/xml"}), + ] - def test_retry_header(self): - req = webob.Request.blank('/.xml') - exc = webob.exc.HTTPRequestEntityTooLarge(explanation='sorry', - headers={'Retry-After': 4}) - f = faults.Fault(exc) - resp = req.get_response(f) - first_two_words = resp.body.strip().split()[:2] - self.assertEqual(first_two_words, ['']) - body_sans_spaces = ''.join(resp.body.split()) - self.assertTrue('sorry' in body_sans_spaces) - self.assertTrue('4' in body_sans_spaces) - self.assertEqual(resp.headers['Retry-After'], 4) + for request in requests: + fault = faults.Fault(webob.exc.HTTPBadRequest(explanation='scram')) + response = request.get_response(fault) + + expected = self._prepare_xml(""" + + scram + + """) + actual = self._prepare_xml(response.body) + + self.assertEqual(response.content_type, "application/xml") + self.assertEqual(expected, actual) + + def test_400_fault_json(self): + """Test fault serialized to JSON via file-extension and/or header.""" + requests = [ + webob.Request.blank('/.json'), + webob.Request.blank('/', headers={"Accept": "application/json"}), + ] + + for request in requests: + fault = faults.Fault(webob.exc.HTTPBadRequest(explanation='scram')) + response = request.get_response(fault) + + expected = { + "badRequest": { + "message": "scram", + "code": 400, + }, + } + actual = json.loads(response.body) + + self.assertEqual(response.content_type, "application/json") + self.assertEqual(expected, actual) + + def test_413_fault_xml(self): + requests = [ + webob.Request.blank('/.xml'), + webob.Request.blank('/', headers={"Accept": "application/xml"}), + ] + + for request in requests: + exc = webob.exc.HTTPRequestEntityTooLarge + fault = faults.Fault(exc(explanation='sorry', + headers={'Retry-After': 4})) + response = request.get_response(fault) + + expected = self._prepare_xml(""" + + sorry + 4 + + """) + actual = self._prepare_xml(response.body) + + self.assertEqual(expected, actual) + self.assertEqual(response.content_type, "application/xml") + self.assertEqual(response.headers['Retry-After'], 4) + + def test_413_fault_json(self): + """Test fault serialized to JSON via file-extension and/or header.""" + requests = [ + webob.Request.blank('/.json'), + webob.Request.blank('/', headers={"Accept": "application/json"}), + ] + + for request in requests: + exc = webob.exc.HTTPRequestEntityTooLarge + fault = faults.Fault(exc(explanation='sorry', + headers={'Retry-After': 4})) + response = request.get_response(fault) + + expected = { + "overLimit": { + "message": "sorry", + "code": 413, + "retryAfter": 4, + }, + } + actual = json.loads(response.body) + + self.assertEqual(response.content_type, "application/json") + self.assertEqual(expected, actual) def test_raise(self): + """Ensure the ability to raise exceptions in WSGI-ified methods.""" @webob.dec.wsgify def raiser(req): raise faults.Fault(webob.exc.HTTPNotFound(explanation='whut?')) + req = webob.Request.blank('/.xml') resp = req.get_response(raiser) + self.assertEqual(resp.content_type, "application/xml") self.assertEqual(resp.status_int, 404) self.assertTrue('whut?' in resp.body) -- cgit From 8f4176f289142e48d4a2c584ad1ce270dfa53d82 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Tue, 29 Mar 2011 14:56:46 -0400 Subject: Fix up docstring --- nova/virt/disk.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index 8adef744f..ddea1a1f7 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -117,7 +117,7 @@ def inject_data(image, key=None, net=None, partition=None, nbd=False): def setup_container(image, container_dir=None, nbd=False): - """Setup the LXC container + """Setup the LXC container. It will mount the loopback image to the container directory in order to create the root filesystem for the container. @@ -133,7 +133,7 @@ def setup_container(image, container_dir=None, nbd=False): def destroy_container(target, instance, nbd=False): - """Destroy the container once it terminates + """Destroy the container once it terminates. It will umount the container that is mounted, try to find the loopback device associated with the container and delete it. -- cgit From b161ae983edbd9e8c302907e8951075546eafc48 Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Tue, 29 Mar 2011 23:30:06 +0400 Subject: style fix --- nova/virt/libvirt_conn.py | 4 ++-- nova/virt/xenapi/vm_utils.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 7dd09813d..aaa0fe8d3 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -829,8 +829,8 @@ class LibvirtConnection(driver.ComputeDriver): if have_injected_networks: net = str(Template(ifc_template, - searchList=[{'interfaces': nets, - 'use_ipv6': FLAGS.use_ipv6}])) + searchList=[{'interfaces': nets, + 'use_ipv6': FLAGS.use_ipv6}])) if key or net: inst_name = inst['name'] diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 18c29134d..d07d60800 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -1136,6 +1136,6 @@ def _prepare_injectables(inst, networks_info): if have_injected_networks: net = str(template(template_data, - searchList=[{'interfaces': interfaces_info, - 'use_ipv6': FLAGS.use_ipv6}])) + searchList=[{'interfaces': interfaces_info, + 'use_ipv6': FLAGS.use_ipv6}])) return key, net -- cgit From 05a654211ab902cbb5b1b345dd3285efb1c6bf71 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Tue, 29 Mar 2011 15:48:02 -0400 Subject: Style fixes --- nova/tests/test_virt.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index e6beb8e2e..958c8e3e2 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -237,13 +237,13 @@ class LibvirtConnTestCase(test.TestCase): network_ref = db.project_get_network(context.get_admin_context(), self.project.id) - fixed_ip = {'address': self.test_ip, - 'network_id': network_ref['id']} + fixed_ip = {'address': self.test_ip, + 'network_id': network_ref['id']} ctxt = context.get_admin_context() fixed_ip_ref = db.fixed_ip_create(ctxt, fixed_ip) db.fixed_ip_update(ctxt, self.test_ip, - {'allocated': True, + {'allocated': True, 'instance_id': instance_ref['id']}) self.flags(libvirt_type='lxc') -- cgit From 3e9b5977137c430d218ec8c00e286b691ea8367d Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 29 Mar 2011 12:54:35 -0700 Subject: use manager pattern for auth token proxy --- bin/nova-vnc-proxy | 96 ----------------------------------- bin/nova-vncproxy | 101 +++++++++++++++++++++++++++++++++++++ doc/source/runnova/vncconsole.rst | 6 +-- nova/flags.py | 2 +- nova/vnc/auth.py | 103 +++++++++++++++++++++++--------------- nova/vnc/proxy.py | 3 +- 6 files changed, 168 insertions(+), 143 deletions(-) delete mode 100755 bin/nova-vnc-proxy create mode 100755 bin/nova-vncproxy diff --git a/bin/nova-vnc-proxy b/bin/nova-vnc-proxy deleted file mode 100755 index e26bc6d8c..000000000 --- a/bin/nova-vnc-proxy +++ /dev/null @@ -1,96 +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. - -"""VNC Console Proxy Server.""" - -import eventlet -import gettext -import os -import sys - -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 utils -from nova import wsgi -from nova import version -from nova.vnc import auth -from nova.vnc import proxy - - -LOG = logging.getLogger('nova.vnc-proxy') - - -FLAGS = flags.FLAGS -flags.DEFINE_string('vnc_proxy_wwwroot', '/var/lib/nova/noVNC/', - 'Full path to noVNC directory') -flags.DEFINE_boolean('vnc_debug', False, - 'Enable debugging features, like token bypassing') -flags.DEFINE_integer('vnc_proxy_port', 6080, - 'Port that the VNC proxy should bind to') -flags.DEFINE_string('vnc_proxy_host', '0.0.0.0', - 'Address that the VNC proxy should bind to') -flags.DEFINE_integer('vnc_token_ttl', 300, - 'How many seconds before deleting tokens') -flags.DEFINE_flag(flags.HelpFlag()) -flags.DEFINE_flag(flags.HelpshortFlag()) -flags.DEFINE_flag(flags.HelpXMLFlag()) - - -if __name__ == "__main__": - utils.default_flagfile() - FLAGS(sys.argv) - logging.setup() - - LOG.audit(_("Starting nova-vnc-proxy node (version %s)"), - version.version_string_with_vcs()) - - if not (os.path.exists(FLAGS.vnc_proxy_wwwroot) and - os.path.exists(FLAGS.vnc_proxy_wwwroot + '/vnc_auto.html')): - LOG.info(_("Missing vnc_proxy_wwwroot (version %s)"), - FLAGS.vnc_proxy_wwwroot) - LOG.info(_("You need a slightly modified version of noVNC " - "to work with the nova-vnc-proxy")) - LOG.info(_("Check out the most recent nova noVNC code: %s"), - "git://github.com/sleepsonthefloor/noVNC.git") - LOG.info(_("And drop it in %s"), FLAGS.vnc_proxy_wwwroot) - exit(1) - - app = proxy.WebsocketVNCProxy(FLAGS.vnc_proxy_wwwroot) - - LOG.audit(_("Allowing access to the following files: %s"), - app.get_whitelist()) - - with_logging = auth.LoggingMiddleware(app) - - if FLAGS.vnc_debug: - with_auth = proxy.DebugMiddleware(with_logging) - else: - with_auth = auth.NovaAuthMiddleware(with_logging) - - server = wsgi.Server() - server.start(with_auth, FLAGS.vnc_proxy_port, host=FLAGS.vnc_proxy_host) - server.wait() diff --git a/bin/nova-vncproxy b/bin/nova-vncproxy new file mode 100755 index 000000000..0fad8397d --- /dev/null +++ b/bin/nova-vncproxy @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2010 Openstack, LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""VNC Console Proxy Server.""" + +import eventlet +import gettext +import os +import sys + +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 +from nova import version +from nova.vnc import auth +from nova.vnc import proxy + + +LOG = logging.getLogger('nova.vnc-proxy') + + +FLAGS = flags.FLAGS +flags.DEFINE_string('vncproxy_wwwroot', '/var/lib/nova/noVNC/', + 'Full path to noVNC directory') +flags.DEFINE_boolean('vnc_debug', False, + 'Enable debugging features, like token bypassing') +flags.DEFINE_integer('vncproxy_port', 6080, + 'Port that the VNC proxy should bind to') +flags.DEFINE_string('vncproxy_host', '0.0.0.0', + 'Address that the VNC proxy should bind to') +flags.DEFINE_integer('vnc_token_ttl', 300, + 'How many seconds before deleting tokens') +flags.DEFINE_string('vncproxy_manager', 'nova.vnc.auth.VNCProxyAuthManager', + 'Manager for vncproxy auth') + +flags.DEFINE_flag(flags.HelpFlag()) +flags.DEFINE_flag(flags.HelpshortFlag()) +flags.DEFINE_flag(flags.HelpXMLFlag()) + + +if __name__ == "__main__": + utils.default_flagfile() + FLAGS(sys.argv) + logging.setup() + + LOG.audit(_("Starting nova-vnc-proxy node (version %s)"), + version.version_string_with_vcs()) + + service.serve() + + if not (os.path.exists(FLAGS.vncproxy_wwwroot) and + os.path.exists(FLAGS.vncproxy_wwwroot + '/vnc_auto.html')): + LOG.info(_("Missing vncproxy_wwwroot (version %s)"), + FLAGS.vncproxy_wwwroot) + LOG.info(_("You need a slightly modified version of noVNC " + "to work with the nova-vnc-proxy")) + LOG.info(_("Check out the most recent nova noVNC code: %s"), + "git://github.com/sleepsonthefloor/noVNC.git") + LOG.info(_("And drop it in %s"), FLAGS.vncproxy_wwwroot) + exit(1) + + app = proxy.WebsocketVNCProxy(FLAGS.vncproxy_wwwroot) + + LOG.audit(_("Allowing access to the following files: %s"), + app.get_whitelist()) + + with_logging = auth.LoggingMiddleware(app) + + if FLAGS.vnc_debug: + with_auth = proxy.DebugMiddleware(with_logging) + else: + with_auth = auth.VNCNovaAuthMiddleware(with_logging) + + server = wsgi.Server() + server.start(with_auth, FLAGS.vncproxy_port, host=FLAGS.vncproxy_host) + server.wait() diff --git a/doc/source/runnova/vncconsole.rst b/doc/source/runnova/vncconsole.rst index 69f147613..6d93bad93 100644 --- a/doc/source/runnova/vncconsole.rst +++ b/doc/source/runnova/vncconsole.rst @@ -40,14 +40,14 @@ you can at find git://github.com/sleepsonthefloor/noVNC.git. .. todo:: add instruction for installing from package -noVNC must be in the location specified by --vnc_proxy_wwwroot, which defaults +noVNC must be in the location specified by --vncproxy_wwwroot, which defaults to /var/lib/nova/noVNC. nova-vnc-proxy will fail to launch until this code is properly installed. By default, nova-vnc-proxy binds 0.0.0.0:6080. This can be configured with: -* --vnc_proxy_port=[port] -* --vnc_proxy_host=[host] +* --vncproxy_port=[port] +* --vncproxy_host=[host] Enabling VNC Consoles in Nova diff --git a/nova/flags.py b/nova/flags.py index ba543f46d..b5c0cd380 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -281,7 +281,7 @@ DEFINE_string('ajax_console_proxy_url', in the form "http://127.0.0.1:8000"') DEFINE_string('ajax_console_proxy_port', 8000, 'port that ajax_console_proxy binds') -DEFINE_string('vnc_console_proxy_topic', 'vnc_proxy', +DEFINE_string('vnc_console_proxy_topic', 'vncproxy', 'the topic vnc proxy nodes listen on') DEFINE_string('vnc_console_proxy_url', 'http://127.0.0.1:6080', diff --git a/nova/vnc/auth.py b/nova/vnc/auth.py index dff9b376f..105b68fe2 100644 --- a/nova/vnc/auth.py +++ b/nova/vnc/auth.py @@ -1,9 +1,7 @@ #!/usr/bin/env python -# pylint: disable-msg=C0103 # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. +# Copyright (c) 2010 Openstack, LLC. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,8 +24,10 @@ import webob from webob import Request +from nova import context from nova import flags from nova import log as logging +from nova import manager from nova import rpc from nova import utils from nova import wsgi @@ -38,12 +38,24 @@ LOG = logging.getLogger('nova.vnc-proxy') FLAGS = flags.FLAGS -class NovaAuthMiddleware(object): +class VNCNovaAuthMiddleware(object): """Implementation of Middleware to Handle Nova Auth.""" def __init__(self, app): self.app = app - self.register_listeners() + self.token_cache = {} + utils.LoopingCall(self._delete_expired_tokens).start(1) + + def get_token_info(self, token): + if token in self.token_cache: + return self.token_cache[token] + + rval = rpc.call(context.get_admin_context(), + FLAGS.vnc_console_proxy_topic, + {"method": "check_token", "args": {'token': token}}) + if rval: + self.token_cache[token] = rval + return rval @webob.dec.wsgify def __call__(self, req): @@ -55,49 +67,27 @@ class NovaAuthMiddleware(object): if 'token' in auth_params: token = auth_params['token'][0] - if not token in self.tokens: + connection_info = self.get_token_info(token) + if not connection_info: LOG.audit(_("Unauthorized Access: (%s)"), req.environ) return webob.exc.HTTPForbidden(detail='Unauthorized') if req.path == vnc.proxy.WS_ENDPOINT: - req.environ['vnc_host'] = self.tokens[token]['args']['host'] - req.environ['vnc_port'] = int(self.tokens[token]['args']['port']) + req.environ['vnc_host'] = connection_info['host'] + req.environ['vnc_port'] = int(connection_info['port']) return req.get_response(self.app) - def register_listeners(self): - middleware = self - middleware.tokens = {} - - class TopicProxy(): - @staticmethod - def authorize_vnc_console(context, **kwargs): - data = kwargs - token = kwargs['token'] - LOG.audit(_("Received Token: %s)"), token) - middleware.tokens[token] = \ - {'args': kwargs, 'last_activity_at': time.time()} - - def delete_expired_tokens(): - now = time.time() - to_delete = [] - for k, v in middleware.tokens.items(): - if now - v['last_activity_at'] > FLAGS.vnc_token_ttl: - to_delete.append(k) - - for k in to_delete: - LOG.audit(_("Deleting Token: %s)"), k) - del middleware.tokens[k] - - conn = rpc.Connection.instance(new=True) - consumer = rpc.TopicAdapterConsumer( - connection=conn, - proxy=TopicProxy, - topic=FLAGS.vnc_console_proxy_topic) - - utils.LoopingCall(consumer.fetch, - enable_callbacks=True).start(0.1) - utils.LoopingCall(delete_expired_tokens).start(1) + def _delete_expired_tokens(self): + now = time.time() + to_delete = [] + for k, v in self.token_cache.items(): + if now - v['last_activity_at'] > FLAGS.vnc_token_ttl: + to_delete.append(k) + + for k in to_delete: + del self.token_cache[k] + class LoggingMiddleware(object): @@ -112,3 +102,34 @@ class LoggingMiddleware(object): LOG.info(_("Received Request: %s"), req.url) return req.get_response(self.app) + + +class VNCProxyAuthManager(manager.Manager): + """Manages token based authentication.""" + + def __init__(self, scheduler_driver=None, *args, **kwargs): + super(VNCProxyAuthManager, self).__init__(*args, **kwargs) + self.tokens = {} + utils.LoopingCall(self._delete_expired_tokens).start(1) + + def authorize_vnc_console(self, context, token, host, port): + self.tokens[token] = {'host': host, + 'port': port, + 'last_activity_at': time.time()} + LOG.audit(_("Received Token: %s, %s)"), token, self.tokens[token]) + + def check_token(self, context, token): + LOG.audit(_("Checking Token: %s, %s)"), token, (token in self.tokens)) + if token in self.tokens: + return self.tokens[token] + + def _delete_expired_tokens(self): + now = time.time() + to_delete = [] + for k, v in self.tokens.items(): + if now - v['last_activity_at'] > FLAGS.vnc_token_ttl: + to_delete.append(k) + + for k in to_delete: + LOG.audit(_("Deleting Expired Token: %s)"), k) + del self.tokens[k] diff --git a/nova/vnc/proxy.py b/nova/vnc/proxy.py index 49379d9ae..c6e46396b 100644 --- a/nova/vnc/proxy.py +++ b/nova/vnc/proxy.py @@ -1,8 +1,7 @@ #!/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. +# Copyright (c) 2010 Openstack, LLC. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); -- cgit From dbef49203985b4eea82912d010df7204ec68586c Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 29 Mar 2011 13:32:03 -0700 Subject: fix flag names --- nova/compute/api.py | 4 ++-- nova/flags.py | 6 +++--- nova/virt/libvirt.xml.template | 4 ++-- nova/virt/libvirt_conn.py | 2 +- nova/vnc/auth.py | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index 5470f40dc..8f5803649 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -614,14 +614,14 @@ class API(base.Base): output = self._call_compute_message('get_vnc_console', context, instance_id) - rpc.cast(context, '%s' % FLAGS.vnc_console_proxy_topic, + rpc.cast(context, '%s' % FLAGS.vncproxy_topic, {'method': 'authorize_vnc_console', 'args': {'token': output['token'], 'host': output['host'], 'port': output['port']}}) return {'url': '%s/vnc_auto.html?token=%s&host=%s&port=%s' % ( - FLAGS.vnc_console_proxy_url, + FLAGS.vncproxy_url, output['token'], 'hostignore', 'portignore')} diff --git a/nova/flags.py b/nova/flags.py index b5c0cd380..b0c116f6b 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -281,13 +281,13 @@ DEFINE_string('ajax_console_proxy_url', in the form "http://127.0.0.1:8000"') DEFINE_string('ajax_console_proxy_port', 8000, 'port that ajax_console_proxy binds') -DEFINE_string('vnc_console_proxy_topic', 'vncproxy', +DEFINE_string('vncproxy_topic', 'vncproxy', 'the topic vnc proxy nodes listen on') -DEFINE_string('vnc_console_proxy_url', +DEFINE_string('vncproxy_url', 'http://127.0.0.1:6080', 'location of vnc console proxy, \ in the form "http://127.0.0.1:6080"') -DEFINE_string('vnc_server_host', '0.0.0.0', +DEFINE_string('vncserver_host', '0.0.0.0', 'the host interface on which vnc server should listen') DEFINE_bool('vnc_enabled', True, 'enable vnc related features') diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index c492e488c..cf6bed530 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -104,8 +104,8 @@ -#if $getVar('vnc_server_host', False) - +#if $getVar('vncserver_host', False) + #end if diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 41adbfe27..ec09aca28 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -885,7 +885,7 @@ class LibvirtConnection(driver.ComputeDriver): 'nics': nics} if FLAGS.vnc_enabled: - xml_info['vnc_server_host'] = FLAGS.vnc_server_host + xml_info['vncserver_host'] = FLAGS.vncserver_host if not rescue: if instance['kernel_id']: xml_info['kernel'] = xml_info['basepath'] + "/kernel" diff --git a/nova/vnc/auth.py b/nova/vnc/auth.py index 105b68fe2..45f77dd59 100644 --- a/nova/vnc/auth.py +++ b/nova/vnc/auth.py @@ -51,7 +51,7 @@ class VNCNovaAuthMiddleware(object): return self.token_cache[token] rval = rpc.call(context.get_admin_context(), - FLAGS.vnc_console_proxy_topic, + FLAGS.vncproxy_topic, {"method": "check_token", "args": {'token': token}}) if rval: self.token_cache[token] = rval -- cgit From 07076b1b9caf7f11c74686d546161994e2e2d691 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 29 Mar 2011 15:32:44 -0500 Subject: Make Dnsmasq_interface configurable --- bin/nova-dhcpbridge | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge index 7ef51feba..f42dfd6b5 100755 --- a/bin/nova-dhcpbridge +++ b/bin/nova-dhcpbridge @@ -48,6 +48,7 @@ flags.DECLARE('auth_driver', 'nova.auth.manager') flags.DECLARE('network_size', 'nova.network.manager') flags.DECLARE('num_networks', 'nova.network.manager') flags.DECLARE('update_dhcp_on_disassociate', 'nova.network.manager') +flags.DEFINE_string('dnsmasq_interface', 'br0', 'Default Dnsmasq interface') LOG = logging.getLogger('nova.dhcpbridge') @@ -103,7 +104,8 @@ def main(): utils.default_flagfile(flagfile) argv = FLAGS(sys.argv) logging.setup() - interface = os.environ.get('DNSMASQ_INTERFACE', 'br0') + # check ENV first so we don't break any older deploys + interface = os.environ.get('DNSMASQ_INTERFACE', FLAGS.dnsmasq_interface) if int(os.environ.get('TESTING', '0')): from nova.tests import fake_flags action = argv[1] -- cgit From 8cfc3d5e6b033a99fc47b3df8ac7e798d107240a Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 29 Mar 2011 13:43:03 -0700 Subject: don't print the error message on sys.exit(0) --- bin/nova-manage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nova-manage b/bin/nova-manage index f7308abe5..25695482f 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -1125,7 +1125,7 @@ def main(): print _("Possible wrong number of arguments supplied") print "%s %s: %s" % (category, action, fn.__doc__) raise - except: + except Exception: print _("Command failed, please check log for more info") raise -- cgit From 3987547248e07719dbc63752100b695ef0be1a9c Mon Sep 17 00:00:00 2001 From: John Tran Date: Tue, 29 Mar 2011 13:44:38 -0700 Subject: initial unit test for describe images --- nova/tests/test_cloud.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 00803d0ad..791498f89 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -216,6 +216,16 @@ class CloudTestCase(test.TestCase): db.service_destroy(self.context, comp1['id']) db.service_destroy(self.context, comp2['id']) + def test_describe_images(self): + def fake_detail(meh, context): + return [{'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1, + 'type':'machine'}}] + + self.stubs.Set(local.LocalImageService, 'detail', fake_detail) + result = self.cloud.describe_images(self.context) + result = result['imagesSet'][0] + self.assertEqual(result['imageId'], 'ami-00000001') + def test_console_output(self): instance_type = FLAGS.default_instance_type max_count = 1 -- cgit From cc7ba9a7a4ed8a38f217ad7f33fc33254f80ead7 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 29 Mar 2011 13:47:47 -0700 Subject: move flags per termie's feedback --- nova/flags.py | 10 ---------- nova/virt/libvirt_conn.py | 1 + nova/vnc/__init__.py | 35 +++++++++++++++++++++++++++++++++++ nova/vnc/auth.py | 3 ++- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/nova/flags.py b/nova/flags.py index b0c116f6b..f011ab383 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -281,16 +281,6 @@ DEFINE_string('ajax_console_proxy_url', in the form "http://127.0.0.1:8000"') DEFINE_string('ajax_console_proxy_port', 8000, 'port that ajax_console_proxy binds') -DEFINE_string('vncproxy_topic', 'vncproxy', - 'the topic vnc proxy nodes listen on') -DEFINE_string('vncproxy_url', - 'http://127.0.0.1:6080', - 'location of vnc console proxy, \ - in the form "http://127.0.0.1:6080"') -DEFINE_string('vncserver_host', '0.0.0.0', - 'the host interface on which vnc server should listen') -DEFINE_bool('vnc_enabled', True, - 'enable vnc related features') DEFINE_bool('verbose', False, 'show debug output') DEFINE_boolean('fake_rabbit', False, 'use a fake rabbit') DEFINE_bool('fake_network', False, diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index ec09aca28..8c948950b 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -57,6 +57,7 @@ from nova import flags from nova import log as logging #from nova import test from nova import utils +from nova import vnc from nova.auth import manager from nova.compute import instance_types from nova.compute import power_state diff --git a/nova/vnc/__init__.py b/nova/vnc/__init__.py index e69de29bb..1642295ec 100644 --- a/nova/vnc/__init__.py +++ b/nova/vnc/__init__.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2010 Openstack, LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Module for VNC Proxying.""" + +from nova import flags + + +FLAGS = flags.FLAGS + +flags.DEFINE_string('vncproxy_topic', 'vncproxy', + 'the topic vnc proxy nodes listen on') +flags.DEFINE_string('vncproxy_url', + 'http://127.0.0.1:6080', + 'location of vnc console proxy, \ + in the form "http://127.0.0.1:6080"') +flags.DEFINE_string('vncserver_host', '0.0.0.0', + 'the host interface on which vnc server should listen') +flags.DEFINE_bool('vnc_enabled', True, + 'enable vnc related features') diff --git a/nova/vnc/auth.py b/nova/vnc/auth.py index 45f77dd59..fd8d351f1 100644 --- a/nova/vnc/auth.py +++ b/nova/vnc/auth.py @@ -89,8 +89,9 @@ class VNCNovaAuthMiddleware(object): del self.token_cache[k] - class LoggingMiddleware(object): + """Middleware for basic vnc-specific request logging.""" + def __init__(self, app): self.app = app -- cgit From 817572265871fd2cfd1252dd0cffb167f0e2ccdb Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 29 Mar 2011 13:49:49 -0700 Subject: move functions around --- nova/vnc/auth.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/nova/vnc/auth.py b/nova/vnc/auth.py index fd8d351f1..86efffbe6 100644 --- a/nova/vnc/auth.py +++ b/nova/vnc/auth.py @@ -44,18 +44,7 @@ class VNCNovaAuthMiddleware(object): def __init__(self, app): self.app = app self.token_cache = {} - utils.LoopingCall(self._delete_expired_tokens).start(1) - - def get_token_info(self, token): - if token in self.token_cache: - return self.token_cache[token] - - rval = rpc.call(context.get_admin_context(), - FLAGS.vncproxy_topic, - {"method": "check_token", "args": {'token': token}}) - if rval: - self.token_cache[token] = rval - return rval + utils.LoopingCall(self.delete_expired_tokens).start(1) @webob.dec.wsgify def __call__(self, req): @@ -78,7 +67,18 @@ class VNCNovaAuthMiddleware(object): return req.get_response(self.app) - def _delete_expired_tokens(self): + def get_token_info(self, token): + if token in self.token_cache: + return self.token_cache[token] + + rval = rpc.call(context.get_admin_context(), + FLAGS.vncproxy_topic, + {"method": "check_token", "args": {'token': token}}) + if rval: + self.token_cache[token] = rval + return rval + + def delete_expired_tokens(self): now = time.time() to_delete = [] for k, v in self.token_cache.items(): -- cgit From 2c533ca5a4cd74907b3238ec65ab29c4f686dfcc Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 29 Mar 2011 13:55:01 -0700 Subject: switch cast to a call --- nova/compute/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index 8f5803649..89d821d44 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -614,7 +614,7 @@ class API(base.Base): output = self._call_compute_message('get_vnc_console', context, instance_id) - rpc.cast(context, '%s' % FLAGS.vncproxy_topic, + rpc.call(context, '%s' % FLAGS.vncproxy_topic, {'method': 'authorize_vnc_console', 'args': {'token': output['token'], 'host': output['host'], -- cgit From 8cdad1ab8343eb038f119a92e28d77c731b61793 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 29 Mar 2011 13:59:46 -0700 Subject: add comment --- nova/compute/api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/compute/api.py b/nova/compute/api.py index 89d821d44..7977b07a2 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -620,6 +620,7 @@ class API(base.Base): 'host': output['host'], 'port': output['port']}}) + # hostignore and portignore are compatability params for noVNC return {'url': '%s/vnc_auto.html?token=%s&host=%s&port=%s' % ( FLAGS.vncproxy_url, output['token'], -- cgit From f5c072de1edddc4ddab89be8146a81d361397c45 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 29 Mar 2011 14:53:38 -0700 Subject: incorporate feedback from termie --- bin/nova-vncproxy | 4 ++-- doc/source/runnova/vncconsole.rst | 2 +- nova/api/openstack/servers.py | 2 +- nova/virt/libvirt_conn.py | 2 -- nova/vnc/__init__.py | 2 -- nova/vnc/auth.py | 4 ++-- nova/vnc/proxy.py | 4 ++-- 7 files changed, 8 insertions(+), 12 deletions(-) diff --git a/bin/nova-vncproxy b/bin/nova-vncproxy index 0fad8397d..ccb97e3a3 100755 --- a/bin/nova-vncproxy +++ b/bin/nova-vncproxy @@ -71,8 +71,6 @@ if __name__ == "__main__": LOG.audit(_("Starting nova-vnc-proxy node (version %s)"), version.version_string_with_vcs()) - service.serve() - if not (os.path.exists(FLAGS.vncproxy_wwwroot) and os.path.exists(FLAGS.vncproxy_wwwroot + '/vnc_auto.html')): LOG.info(_("Missing vncproxy_wwwroot (version %s)"), @@ -96,6 +94,8 @@ if __name__ == "__main__": else: with_auth = auth.VNCNovaAuthMiddleware(with_logging) + service.serve() + server = wsgi.Server() server.start(with_auth, FLAGS.vncproxy_port, host=FLAGS.vncproxy_host) server.wait() diff --git a/doc/source/runnova/vncconsole.rst b/doc/source/runnova/vncconsole.rst index 6d93bad93..942ace611 100644 --- a/doc/source/runnova/vncconsole.rst +++ b/doc/source/runnova/vncconsole.rst @@ -36,7 +36,7 @@ Configuring the VNC Proxy ------------------------- nova-vnc-proxy requires a websocket enabled html client to work properly. At this time, the only tested client is a slightly modified fork of noVNC, which -you can at find git://github.com/sleepsonthefloor/noVNC.git. +you can at find http://github.com/openstack/noVNC.git .. todo:: add instruction for installing from package diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 822342149..8170ab4a1 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -486,7 +486,7 @@ class Controller(wsgi.Controller): """Returns a url to an instance's ajaxterm console.""" try: self.compute_api.get_vnc_console(req.environ['nova.context'], - int(id)) + int(id)) except exception.NotFound: return faults.Fault(exc.HTTPNotFound()) return exc.HTTPAccepted() diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 8c948950b..502e61395 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -627,8 +627,6 @@ class LibvirtConnection(driver.ComputeDriver): return {'token': token, 'host': host, 'port': port} - _image_sems = {} # FIXME: why is this here? (anthony) - @staticmethod def _cache_image(fn, target, fname, cow=False, *args, **kwargs): """Wrapper for a method that creates an image that caches the image. diff --git a/nova/vnc/__init__.py b/nova/vnc/__init__.py index 1642295ec..2733c81d6 100644 --- a/nova/vnc/__init__.py +++ b/nova/vnc/__init__.py @@ -20,9 +20,7 @@ from nova import flags - FLAGS = flags.FLAGS - flags.DEFINE_string('vncproxy_topic', 'vncproxy', 'the topic vnc proxy nodes listen on') flags.DEFINE_string('vncproxy_url', diff --git a/nova/vnc/auth.py b/nova/vnc/auth.py index 86efffbe6..c7df13450 100644 --- a/nova/vnc/auth.py +++ b/nova/vnc/auth.py @@ -44,7 +44,7 @@ class VNCNovaAuthMiddleware(object): def __init__(self, app): self.app = app self.token_cache = {} - utils.LoopingCall(self.delete_expired_tokens).start(1) + utils.LoopingCall(self.delete_expired_cache_items).start(1) @webob.dec.wsgify def __call__(self, req): @@ -78,7 +78,7 @@ class VNCNovaAuthMiddleware(object): self.token_cache[token] = rval return rval - def delete_expired_tokens(self): + def delete_expired_cache_items(self): now = time.time() to_delete = [] for k, v in self.token_cache.items(): diff --git a/nova/vnc/proxy.py b/nova/vnc/proxy.py index c6e46396b..c4603803b 100644 --- a/nova/vnc/proxy.py +++ b/nova/vnc/proxy.py @@ -25,9 +25,9 @@ import eventlet from eventlet import wsgi from eventlet import websocket -from webob import Request import webob + WS_ENDPOINT = '/data' @@ -88,7 +88,7 @@ class WebsocketVNCProxy(object): _handle(environ, start_response) def __call__(self, environ, start_response): - req = Request(environ) + req = webob.Request(environ) if req.path == WS_ENDPOINT: return self.proxy_connection(environ, start_response) else: -- cgit From 3cdc2a90f0a7a066a231b0590aeb3d51d8ec699a Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 29 Mar 2011 14:58:10 -0700 Subject: add line --- nova/vnc/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/vnc/__init__.py b/nova/vnc/__init__.py index 2733c81d6..b5b00e44e 100644 --- a/nova/vnc/__init__.py +++ b/nova/vnc/__init__.py @@ -20,6 +20,7 @@ from nova import flags + FLAGS = flags.FLAGS flags.DEFINE_string('vncproxy_topic', 'vncproxy', 'the topic vnc proxy nodes listen on') -- cgit From 93a7a7b94a0d9e4100abb3a4309a3546ab532535 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 29 Mar 2011 15:22:16 -0700 Subject: clarify test --- nova/tests/test_compute.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index 038824ef8..1b0f426d2 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -286,7 +286,7 @@ class ComputeTestCase(test.TestCase): console = self.compute.get_ajax_console(self.context, instance_id) - self.assert_(console) + self.assert_(set(['token', 'host', 'port']).issubset(console.keys())) self.compute.terminate_instance(self.context, instance_id) def test_vnc_console(self): -- cgit From 9513458c3e50fac5f40e76757b45ab15b67e8f00 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 29 Mar 2011 15:34:25 -0700 Subject: add nova-vncproxy to setup.py --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 3b48990ac..20f4c1947 100644 --- a/setup.py +++ b/setup.py @@ -112,4 +112,5 @@ DistUtilsExtra.auto.setup(name='nova', 'bin/nova-spoolsentry', 'bin/stack', 'bin/nova-volume', + 'bin/nova-vncproxy', 'tools/nova-debug']) -- cgit From a2d0718c20e45d39e3f2d46edb715a064f650e81 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 29 Mar 2011 15:37:32 -0700 Subject: conversion of properties should set owner as owner_id not owner --- bin/nova-manage | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 25695482f..6789efba8 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -902,7 +902,7 @@ class ImageCommands(object): 'disk_format': disk_format, 'container_format': container_format, 'properties': {'image_state': 'available', - 'owner': owner, + 'owner_id': owner, 'type': image_type, 'architecture': architecture, 'image_location': 'local', @@ -980,7 +980,7 @@ class ImageCommands(object): 'is_public': True, 'name': old['imageId'], 'properties': {'image_state': old['imageState'], - 'owner': old['imageOwnerId'], + 'owner_id': old['imageOwnerId'], 'architecture': old['architecture'], 'type': old['type'], 'image_location': old['imageLocation'], -- cgit From e86f58261ee6acb8705106d3de61be0de488d94b Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 15:37:45 -0700 Subject: Reverted extension loading tweaks --- nova/api/openstack/extensions.py | 116 +++---- nova/api/openstack/incubator/__init__.py | 4 +- nova/api/openstack/incubator/volumes.py | 355 +++++++++++++++++++++ nova/api/openstack/incubator/volumes/__init__.py | 18 -- .../incubator/volumes/volume_attachments.py | 184 ----------- nova/api/openstack/incubator/volumes/volumes.py | 161 ---------- .../api/openstack/incubator/volumes/volumes_ext.py | 55 ---- nova/tests/api/openstack/extensions/foxinsocks.py | 98 ++++++ .../openstack/extensions/foxinsocks/__init__.py | 19 -- .../openstack/extensions/foxinsocks/foxinsocks.py | 98 ------ 10 files changed, 505 insertions(+), 603 deletions(-) create mode 100644 nova/api/openstack/incubator/volumes.py delete mode 100644 nova/api/openstack/incubator/volumes/__init__.py delete mode 100644 nova/api/openstack/incubator/volumes/volume_attachments.py delete mode 100644 nova/api/openstack/incubator/volumes/volumes.py delete mode 100644 nova/api/openstack/incubator/volumes/volumes_ext.py create mode 100644 nova/tests/api/openstack/extensions/foxinsocks.py delete mode 100644 nova/tests/api/openstack/extensions/foxinsocks/__init__.py delete mode 100644 nova/tests/api/openstack/extensions/foxinsocks/foxinsocks.py diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index d0b4d378a..d1d479313 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -38,7 +38,10 @@ FLAGS = flags.FLAGS class ExtensionDescriptor(object): - """This is the base class that defines the contract for extensions.""" + """Base class that defines the contract for extensions. + + Note that you don't have to derive from this class to have a valid + extension; it is purely a convenience.""" def get_name(self): """The name of the extension. @@ -321,22 +324,37 @@ class ExtensionManager(object): resources = [] resources.append(ResourceExtension('extensions', ExtensionController(self))) - for _alias, ext in self.extensions.iteritems(): - resources.extend(ext.get_resources()) + for alias, ext in self.extensions.iteritems(): + try: + resources.extend(ext.get_resources()) + except AttributeError: + # NOTE(dprince): Extension aren't required to have resource + # extensions + pass return resources def get_actions(self): """Returns a list of ActionExtension objects.""" actions = [] - for _alias, ext in self.extensions.iteritems(): - actions.extend(ext.get_actions()) + for alias, ext in self.extensions.iteritems(): + try: + actions.extend(ext.get_actions()) + except AttributeError: + # NOTE(dprince): Extension aren't required to have action + # extensions + pass return actions def get_response_extensions(self): """Returns a list of ResponseExtension objects.""" response_exts = [] - for _alias, ext in self.extensions.iteritems(): - response_exts.extend(ext.get_response_extensions()) + for alias, ext in self.extensions.iteritems(): + try: + response_exts.extend(ext.get_response_extensions()) + except AttributeError: + # NOTE(dprince): Extension aren't required to have response + # extensions + pass return response_exts def _check_extension(self, extension): @@ -353,78 +371,42 @@ class ExtensionManager(object): def _load_all_extensions(self): """Load extensions from the configured path. - An extension consists of a directory of related files, with a class - that defines a class that inherits from ExtensionDescriptor. + Load extensions from the configured path. The extension name is + constructed from the module_name. If your extension module was named + widgets.py the extension class within that module should be + 'Widgets'. - Because of some oddities involving identically named modules, it's - probably best to name your file after the name of your extension, - rather than something likely to clash like 'extension.py'. - - The name of your directory should be the same as the alias your - extension uses, for everyone's sanity. + In addition, extensions are loaded from the 'incubator' directory. See nova/tests/api/openstack/extensions/foxinsocks.py for an example extension implementation. """ - self._load_extensions_under_path(self.path) + if os.path.exists(self.path): + self._load_all_extensions_from_path(self.path) incubator_path = os.path.join(os.path.dirname(__file__), "incubator") - self._load_extensions_under_path(incubator_path) - - def _load_extensions_under_path(self, path): - if not os.path.isdir(path): - LOG.warning(_('Extensions directory not found: %s') % path) - return - - LOG.debug(_('Looking for extensions in: %s') % path) - - for child in os.listdir(path): - child_path = os.path.join(path, child) - if not os.path.isdir(child_path): - continue - self._load_extension(child_path) - - def _load_extension(self, path): - if not os.path.isdir(path): - return + if os.path.exists(incubator_path): + self._load_all_extensions_from_path(incubator_path) + def _load_all_extensions_from_path(self, path): for f in os.listdir(path): + LOG.audit(_('Loading extension file: %s'), f) mod_name, file_ext = os.path.splitext(os.path.split(f)[-1]) - if mod_name.startswith('_'): - continue - if file_ext.lower() != '.py': - continue - ext_path = os.path.join(path, f) - if self.super_verbose: - LOG.debug(_('Checking extension file: %s'), ext_path) - - mod = imp.load_source(mod_name, ext_path) - for _name, cls in inspect.getmembers(mod): - try: - if not inspect.isclass(cls): - continue - - # NOTE(justinsb): It seems that python modules are odd. - # If you have two identically named modules, the classes - # from both are mixed in. So name your extension based - # on the alias, not 'extension.py'! - # TODO(justinsb): Any way to work around this? - - if self.super_verbose: - LOG.debug(_('Checking class: %s'), cls) - - if not ExtensionDescriptor in cls.__bases__: - if self.super_verbose: - LOG.debug(_('Not a ExtensionDescriptor: %s'), cls) - continue - - obj = cls() - self._add_extension(obj) - except AttributeError as ex: - LOG.exception(_("Exception loading extension: %s"), - unicode(ex)) + if file_ext.lower() == '.py' and not mod_name.startswith('_'): + mod = imp.load_source(mod_name, ext_path) + ext_name = mod_name[0].upper() + mod_name[1:] + new_ext_class = getattr(mod, ext_name, None) + if not new_ext_class: + LOG.warn(_('Did not find expected name ' + '"%(ext_name)s" in %(file)s'), + {'ext_name': ext_name, + 'file': ext_path}) + continue + new_ext = new_ext_class() + self._check_extension(new_ext) + self._add_extension(new_ext) def _add_extension(self, ext): alias = ext.get_alias() diff --git a/nova/api/openstack/incubator/__init__.py b/nova/api/openstack/incubator/__init__.py index cded38174..e115f1ab9 100644 --- a/nova/api/openstack/incubator/__init__.py +++ b/nova/api/openstack/incubator/__init__.py @@ -17,4 +17,6 @@ """Incubator contains extensions that are shipped with nova. -It can't be called 'extensions' because that causes namespacing problems.""" +It can't be called 'extensions' because that causes namespacing problems. + +""" diff --git a/nova/api/openstack/incubator/volumes.py b/nova/api/openstack/incubator/volumes.py new file mode 100644 index 000000000..7a5b2c1d0 --- /dev/null +++ b/nova/api/openstack/incubator/volumes.py @@ -0,0 +1,355 @@ +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""The volumes extension.""" + +from webob import exc + +from nova import compute +from nova import exception +from nova import flags +from nova import log as logging +from nova import volume +from nova import wsgi +from nova.api.openstack import common +from nova.api.openstack import extensions +from nova.api.openstack import faults + + +LOG = logging.getLogger("nova.api.volumes") + + +FLAGS = flags.FLAGS + + +def _translate_volume_detail_view(context, vol): + """Maps keys for volumes details view.""" + + d = _translate_volume_summary_view(context, vol) + + # No additional data / lookups at the moment + + return d + + +def _translate_volume_summary_view(_context, vol): + """Maps keys for volumes summary view.""" + d = {} + + instance_id = None + # instance_data = None + attached_to = vol.get('instance') + if attached_to: + instance_id = attached_to['id'] + # instance_data = '%s[%s]' % (instance_ec2_id, + # attached_to['host']) + d['id'] = vol['id'] + d['status'] = vol['status'] + d['size'] = vol['size'] + d['availabilityZone'] = vol['availability_zone'] + d['createdAt'] = vol['created_at'] + # if context.is_admin: + # v['status'] = '%s (%s, %s, %s, %s)' % ( + # vol['status'], + # vol['user_id'], + # vol['host'], + # instance_data, + # vol['mountpoint']) + if vol['attach_status'] == 'attached': + d['attachments'] = [{'attachTime': vol['attach_time'], + 'deleteOnTermination': False, + 'mountpoint': vol['mountpoint'], + 'instanceId': instance_id, + 'status': 'attached', + 'volumeId': vol['id']}] + else: + d['attachments'] = [{}] + + d['displayName'] = vol['display_name'] + d['displayDescription'] = vol['display_description'] + return d + + +class VolumeController(wsgi.Controller): + """The Volumes API controller for the OpenStack API.""" + + _serialization_metadata = { + 'application/xml': { + "attributes": { + "volume": [ + "id", + "status", + "size", + "availabilityZone", + "createdAt", + "displayName", + "displayDescription", + ]}}} + + def __init__(self): + self.volume_api = volume.API() + super(VolumeController, self).__init__() + + def show(self, req, id): + """Return data about the given volume.""" + context = req.environ['nova.context'] + + try: + vol = self.volume_api.get(context, id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + return {'volume': _translate_volume_detail_view(context, vol)} + + def delete(self, req, id): + """Delete a volume.""" + context = req.environ['nova.context'] + + LOG.audit(_("Delete volume with id: %s"), id, context=context) + + try: + self.volume_api.delete(context, volume_id=id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + return exc.HTTPAccepted() + + def index(self, req): + """Returns a summary list of volumes.""" + return self._items(req, entity_maker=_translate_volume_summary_view) + + def detail(self, req): + """Returns a detailed list of volumes.""" + return self._items(req, entity_maker=_translate_volume_detail_view) + + def _items(self, req, entity_maker): + """Returns a list of volumes, transformed through entity_maker.""" + context = req.environ['nova.context'] + + volumes = self.volume_api.get_all(context) + limited_list = common.limited(volumes, req) + res = [entity_maker(context, vol) for vol in limited_list] + return {'volumes': res} + + def create(self, req): + """Creates a new volume.""" + context = req.environ['nova.context'] + + env = self._deserialize(req.body, req.get_content_type()) + if not env: + return faults.Fault(exc.HTTPUnprocessableEntity()) + + vol = env['volume'] + size = vol['size'] + LOG.audit(_("Create volume of %s GB"), size, context=context) + new_volume = self.volume_api.create(context, size, + vol.get('display_name'), + vol.get('display_description')) + + # Work around problem that instance is lazy-loaded... + new_volume['instance'] = None + + retval = _translate_volume_detail_view(context, new_volume) + + return {'volume': retval} + + +def _translate_attachment_detail_view(_context, vol): + """Maps keys for attachment details view.""" + + d = _translate_attachment_summary_view(_context, vol) + + # No additional data / lookups at the moment + + return d + + +def _translate_attachment_summary_view(_context, vol): + """Maps keys for attachment summary view.""" + d = {} + + volume_id = vol['id'] + + # NOTE(justinsb): We use the volume id as the id of the attachment object + d['id'] = volume_id + + d['volumeId'] = volume_id + if vol.get('instance_id'): + d['serverId'] = vol['instance_id'] + if vol.get('mountpoint'): + d['device'] = vol['mountpoint'] + + return d + + +class VolumeAttachmentController(wsgi.Controller): + """The volume attachment API controller for the Openstack API. + + A child resource of the server. Note that we use the volume id + as the ID of the attachment (though this is not guaranteed externally) + + """ + + _serialization_metadata = { + 'application/xml': { + 'attributes': { + 'volumeAttachment': ['id', + 'serverId', + 'volumeId', + 'device']}}} + + def __init__(self): + self.compute_api = compute.API() + self.volume_api = volume.API() + super(VolumeAttachmentController, self).__init__() + + def index(self, req, server_id): + """Returns the list of volume attachments for a given instance.""" + return self._items(req, server_id, + entity_maker=_translate_attachment_summary_view) + + def show(self, req, server_id, id): + """Return data about the given volume.""" + context = req.environ['nova.context'] + + volume_id = id + try: + vol = self.volume_api.get(context, volume_id) + except exception.NotFound: + LOG.debug("volume_id not found") + return faults.Fault(exc.HTTPNotFound()) + + if str(vol['instance_id']) != server_id: + LOG.debug("instance_id != server_id") + return faults.Fault(exc.HTTPNotFound()) + + return {'volumeAttachment': _translate_attachment_detail_view(context, + vol)} + + def create(self, req, server_id): + """Attach a volume to an instance.""" + context = req.environ['nova.context'] + + env = self._deserialize(req.body, req.get_content_type()) + if not env: + return faults.Fault(exc.HTTPUnprocessableEntity()) + + instance_id = server_id + volume_id = env['volumeAttachment']['volumeId'] + device = env['volumeAttachment']['device'] + + msg = _("Attach volume %(volume_id)s to instance %(server_id)s" + " at %(device)s") % locals() + LOG.audit(msg, context=context) + + try: + self.compute_api.attach_volume(context, + instance_id=instance_id, + volume_id=volume_id, + device=device) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + # The attach is async + attachment = {} + attachment['id'] = volume_id + attachment['volumeId'] = volume_id + + # NOTE(justinsb): And now, we have a problem... + # The attach is async, so there's a window in which we don't see + # the attachment (until the attachment completes). We could also + # get problems with concurrent requests. I think we need an + # attachment state, and to write to the DB here, but that's a bigger + # change. + # For now, we'll probably have to rely on libraries being smart + + # TODO(justinsb): How do I return "accepted" here? + return {'volumeAttachment': attachment} + + def update(self, _req, _server_id, _id): + """Update a volume attachment. We don't currently support this.""" + return faults.Fault(exc.HTTPBadRequest()) + + def delete(self, req, server_id, id): + """Detach a volume from an instance.""" + context = req.environ['nova.context'] + + volume_id = id + LOG.audit(_("Detach volume %s"), volume_id, context=context) + + try: + vol = self.volume_api.get(context, volume_id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + if str(vol['instance_id']) != server_id: + LOG.debug("instance_id != server_id") + return faults.Fault(exc.HTTPNotFound()) + + self.compute_api.detach_volume(context, + volume_id=volume_id) + + return exc.HTTPAccepted() + + def _items(self, req, server_id, entity_maker): + """Returns a list of attachments, transformed through entity_maker.""" + context = req.environ['nova.context'] + + try: + instance = self.compute_api.get(context, server_id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + volumes = instance['volumes'] + limited_list = common.limited(volumes, req) + res = [entity_maker(context, vol) for vol in limited_list] + return {'volumeAttachments': res} + + +class Volumes(extensions.ExtensionDescriptor): + def get_name(self): + return "Volumes" + + def get_alias(self): + return "VOLUMES" + + def get_description(self): + return "Volumes support" + + def get_namespace(self): + return "http://docs.openstack.org/ext/volumes/api/v1.1" + + def get_updated(self): + return "2011-03-25T00:00:00+00:00" + + def get_resources(self): + resources = [] + + # NOTE(justinsb): No way to provide singular name ('volume') + # Does this matter? + res = extensions.ResourceExtension('volumes', + VolumeController(), + collection_actions= + {'detail': 'GET'} + ) + resources.append(res) + + res = extensions.ResourceExtension('volume_attachments', + VolumeAttachmentController(), + parent=dict( + member_name='server', + collection_name='servers')) + resources.append(res) + + return resources diff --git a/nova/api/openstack/incubator/volumes/__init__.py b/nova/api/openstack/incubator/volumes/__init__.py deleted file mode 100644 index 2a9c93210..000000000 --- a/nova/api/openstack/incubator/volumes/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2011 Justin Santa Barbara -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License.import datetime - -"""The volumes extension adds volumes and attachments to the API.""" diff --git a/nova/api/openstack/incubator/volumes/volume_attachments.py b/nova/api/openstack/incubator/volumes/volume_attachments.py deleted file mode 100644 index aec4ea8f3..000000000 --- a/nova/api/openstack/incubator/volumes/volume_attachments.py +++ /dev/null @@ -1,184 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2011 Justin Santa Barbara -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from webob import exc - -from nova import compute -from nova import exception -from nova import flags -from nova import log as logging -from nova import volume -from nova import wsgi -from nova.api.openstack import common -from nova.api.openstack import faults - - -LOG = logging.getLogger("nova.api.volumes") - - -FLAGS = flags.FLAGS - - -def _translate_detail_view(context, volume): - """Maps keys for details view.""" - - d = _translate_summary_view(context, volume) - - # No additional data / lookups at the moment - - return d - - -def _translate_summary_view(context, vol): - """Maps keys for summary view.""" - d = {} - - volume_id = vol['id'] - - # NOTE(justinsb): We use the volume id as the id of the attachment object - d['id'] = volume_id - - d['volumeId'] = volume_id - if vol.get('instance_id'): - d['serverId'] = vol['instance_id'] - if vol.get('mountpoint'): - d['device'] = vol['mountpoint'] - - return d - - -class Controller(wsgi.Controller): - """The volume attachment API controller for the Openstack API. - - A child resource of the server. Note that we use the volume id - as the ID of the attachment (though this is not guaranteed externally) - - """ - - _serialization_metadata = { - 'application/xml': { - 'attributes': { - 'volumeAttachment': ['id', - 'serverId', - 'volumeId', - 'device']}}} - - def __init__(self): - self.compute_api = compute.API() - self.volume_api = volume.API() - super(Controller, self).__init__() - - def index(self, req, server_id): - """Returns the list of volume attachments for a given instance.""" - return self._items(req, server_id, - entity_maker=_translate_summary_view) - - def show(self, req, server_id, id): - """Return data about the given volume.""" - context = req.environ['nova.context'] - - volume_id = id - try: - vol = self.volume_api.get(context, volume_id) - except exception.NotFound: - LOG.debug("volume_id not found") - return faults.Fault(exc.HTTPNotFound()) - - if str(vol['instance_id']) != server_id: - LOG.debug("instance_id != server_id") - return faults.Fault(exc.HTTPNotFound()) - - return {'volumeAttachment': _translate_detail_view(context, vol)} - - def create(self, req, server_id): - """Attach a volume to an instance.""" - context = req.environ['nova.context'] - - env = self._deserialize(req.body, req.get_content_type()) - if not env: - return faults.Fault(exc.HTTPUnprocessableEntity()) - - instance_id = server_id - volume_id = env['volumeAttachment']['volumeId'] - device = env['volumeAttachment']['device'] - - msg = _("Attach volume %(volume_id)s to instance %(server_id)s" - " at %(device)s") % locals() - LOG.audit(msg, context=context) - - try: - self.compute_api.attach_volume(context, - instance_id=instance_id, - volume_id=volume_id, - device=device) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - - # The attach is async - attachment = {} - attachment['id'] = volume_id - attachment['volumeId'] = volume_id - - # NOTE(justinsb): And now, we have a problem... - # The attach is async, so there's a window in which we don't see - # the attachment (until the attachment completes). We could also - # get problems with concurrent requests. I think we need an - # attachment state, and to write to the DB here, but that's a bigger - # change. - # For now, we'll probably have to rely on libraries being smart - - # TODO(justinsb): How do I return "accepted" here? - return {'volumeAttachment': attachment} - - def update(self, _req, _server_id, _id): - """Update a volume attachment. We don't currently support this.""" - return faults.Fault(exc.HTTPBadRequest()) - - def delete(self, req, server_id, id): - """Detach a volume from an instance.""" - context = req.environ['nova.context'] - - volume_id = id - LOG.audit(_("Detach volume %s"), volume_id, context=context) - - try: - vol = self.volume_api.get(context, volume_id) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - - if str(vol['instance_id']) != server_id: - LOG.debug("instance_id != server_id") - return faults.Fault(exc.HTTPNotFound()) - - self.compute_api.detach_volume(context, - volume_id=volume_id) - - return exc.HTTPAccepted() - - def _items(self, req, server_id, entity_maker): - """Returns a list of attachments, transformed through entity_maker.""" - context = req.environ['nova.context'] - - try: - instance = self.compute_api.get(context, server_id) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - - volumes = instance['volumes'] - limited_list = common.limited(volumes, req) - res = [entity_maker(context, vol) for vol in limited_list] - return {'volumeAttachments': res} diff --git a/nova/api/openstack/incubator/volumes/volumes.py b/nova/api/openstack/incubator/volumes/volumes.py deleted file mode 100644 index a7d5fbaa6..000000000 --- a/nova/api/openstack/incubator/volumes/volumes.py +++ /dev/null @@ -1,161 +0,0 @@ -# Copyright 2011 Justin Santa Barbara -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from webob import exc - -from nova import exception -from nova import flags -from nova import log as logging -from nova import volume -from nova import wsgi -from nova.api.openstack import common -from nova.api.openstack import faults - - -LOG = logging.getLogger("nova.api.volumes") - - -FLAGS = flags.FLAGS - - -def _translate_detail_view(context, vol): - """Maps keys for details view.""" - - d = _translate_summary_view(context, vol) - - # No additional data / lookups at the moment - - return d - - -def _translate_summary_view(_context, vol): - """Maps keys for summary view.""" - d = {} - - instance_id = None - # instance_data = None - attached_to = vol.get('instance') - if attached_to: - instance_id = attached_to['id'] - # instance_data = '%s[%s]' % (instance_ec2_id, - # attached_to['host']) - d['id'] = vol['id'] - d['status'] = vol['status'] - d['size'] = vol['size'] - d['availabilityZone'] = vol['availability_zone'] - d['createdAt'] = vol['created_at'] - # if context.is_admin: - # v['status'] = '%s (%s, %s, %s, %s)' % ( - # vol['status'], - # vol['user_id'], - # vol['host'], - # instance_data, - # vol['mountpoint']) - if vol['attach_status'] == 'attached': - d['attachments'] = [{'attachTime': vol['attach_time'], - 'deleteOnTermination': False, - 'mountpoint': vol['mountpoint'], - 'instanceId': instance_id, - 'status': 'attached', - 'volumeId': vol['id']}] - else: - d['attachments'] = [{}] - - d['displayName'] = vol['display_name'] - d['displayDescription'] = vol['display_description'] - return d - - -class Controller(wsgi.Controller): - """The Volumes API controller for the OpenStack API.""" - - _serialization_metadata = { - 'application/xml': { - "attributes": { - "volume": [ - "id", - "status", - "size", - "availabilityZone", - "createdAt", - "displayName", - "displayDescription", - ]}}} - - def __init__(self): - self.volume_api = volume.API() - super(Controller, self).__init__() - - def show(self, req, id): - """Return data about the given volume.""" - context = req.environ['nova.context'] - - try: - vol = self.volume_api.get(context, id) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - - return {'volume': _translate_detail_view(context, vol)} - - def delete(self, req, id): - """Delete a volume.""" - context = req.environ['nova.context'] - - LOG.audit(_("Delete volume with id: %s"), id, context=context) - - try: - self.volume_api.delete(context, volume_id=id) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - return exc.HTTPAccepted() - - def index(self, req): - """Returns a summary list of volumes.""" - return self._items(req, entity_maker=_translate_summary_view) - - def detail(self, req): - """Returns a detailed list of volumes.""" - return self._items(req, entity_maker=_translate_detail_view) - - def _items(self, req, entity_maker): - """Returns a list of volumes, transformed through entity_maker.""" - context = req.environ['nova.context'] - - volumes = self.volume_api.get_all(context) - limited_list = common.limited(volumes, req) - res = [entity_maker(context, vol) for vol in limited_list] - return {'volumes': res} - - def create(self, req): - """Creates a new volume.""" - context = req.environ['nova.context'] - - env = self._deserialize(req.body, req.get_content_type()) - if not env: - return faults.Fault(exc.HTTPUnprocessableEntity()) - - vol = env['volume'] - size = vol['size'] - LOG.audit(_("Create volume of %s GB"), size, context=context) - new_volume = self.volume_api.create(context, size, - vol.get('display_name'), - vol.get('display_description')) - - # Work around problem that instance is lazy-loaded... - new_volume['instance'] = None - - retval = _translate_detail_view(context, new_volume) - - return {'volume': retval} diff --git a/nova/api/openstack/incubator/volumes/volumes_ext.py b/nova/api/openstack/incubator/volumes/volumes_ext.py deleted file mode 100644 index 6a3bb0265..000000000 --- a/nova/api/openstack/incubator/volumes/volumes_ext.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright 2011 Justin Santa Barbara -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from nova.api.openstack import extensions -from nova.api.openstack.incubator.volumes import volumes -from nova.api.openstack.incubator.volumes import volume_attachments - - -class VolumesExtension(extensions.ExtensionDescriptor): - def get_name(self): - return "Volumes" - - def get_alias(self): - return "VOLUMES" - - def get_description(self): - return "Volumes support" - - def get_namespace(self): - return "http://docs.openstack.org/ext/volumes/api/v1.1" - - def get_updated(self): - return "2011-03-25T00:00:00+00:00" - - def get_resources(self): - resources = [] - - # NOTE(justinsb): No way to provide singular name ('volume') - # Does this matter? - res = extensions.ResourceExtension('volumes', - volumes.Controller(), - collection_actions={'detail': 'GET'} - ) - resources.append(res) - - res = extensions.ResourceExtension('volume_attachments', - volume_attachments.Controller(), - parent=dict( - member_name='server', - collection_name='servers')) - resources.append(res) - - return resources diff --git a/nova/tests/api/openstack/extensions/foxinsocks.py b/nova/tests/api/openstack/extensions/foxinsocks.py new file mode 100644 index 000000000..0860b51ac --- /dev/null +++ b/nova/tests/api/openstack/extensions/foxinsocks.py @@ -0,0 +1,98 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import json + +from nova import wsgi + +from nova.api.openstack import extensions + + +class FoxInSocksController(wsgi.Controller): + + def index(self, req): + return "Try to say this Mr. Knox, sir..." + + +class Foxinsocks(object): + + def __init__(self): + pass + + def get_name(self): + return "Fox In Socks" + + def get_alias(self): + return "FOXNSOX" + + def get_description(self): + return "The Fox In Socks Extension" + + def get_namespace(self): + return "http://www.fox.in.socks/api/ext/pie/v1.0" + + def get_updated(self): + return "2011-01-22T13:25:27-06:00" + + def get_resources(self): + resources = [] + resource = extensions.ResourceExtension('foxnsocks', + FoxInSocksController()) + resources.append(resource) + return resources + + def get_actions(self): + actions = [] + actions.append(extensions.ActionExtension('servers', 'add_tweedle', + self._add_tweedle)) + actions.append(extensions.ActionExtension('servers', 'delete_tweedle', + self._delete_tweedle)) + return actions + + def get_response_extensions(self): + response_exts = [] + + def _goose_handler(res): + #NOTE: This only handles JSON responses. + # You can use content type header to test for XML. + data = json.loads(res.body) + data['flavor']['googoose'] = "Gooey goo for chewy chewing!" + return data + + resp_ext = extensions.ResponseExtension('GET', '/v1.1/flavors/:(id)', + _goose_handler) + response_exts.append(resp_ext) + + def _bands_handler(res): + #NOTE: This only handles JSON responses. + # You can use content type header to test for XML. + data = json.loads(res.body) + data['big_bands'] = 'Pig Bands!' + return data + + resp_ext2 = extensions.ResponseExtension('GET', '/v1.1/flavors/:(id)', + _bands_handler) + response_exts.append(resp_ext2) + return response_exts + + def _add_tweedle(self, input_dict, req, id): + + return "Tweedle Beetle Added." + + def _delete_tweedle(self, input_dict, req, id): + + return "Tweedle Beetle Deleted." diff --git a/nova/tests/api/openstack/extensions/foxinsocks/__init__.py b/nova/tests/api/openstack/extensions/foxinsocks/__init__.py deleted file mode 100644 index fe505359d..000000000 --- a/nova/tests/api/openstack/extensions/foxinsocks/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2011 OpenStack LLC. -# Copyright 2011 Justin Santa Barbara -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License.import datetime - -"""Example Fox-in-Socks extension.""" diff --git a/nova/tests/api/openstack/extensions/foxinsocks/foxinsocks.py b/nova/tests/api/openstack/extensions/foxinsocks/foxinsocks.py deleted file mode 100644 index 442707714..000000000 --- a/nova/tests/api/openstack/extensions/foxinsocks/foxinsocks.py +++ /dev/null @@ -1,98 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2011 OpenStack LLC. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import json - -from nova import wsgi - -from nova.api.openstack import extensions - - -class FoxInSocksController(wsgi.Controller): - - def index(self, req): - return "Try to say this Mr. Knox, sir..." - - -class Foxinsocks(extensions.ExtensionDescriptor): - - def __init__(self): - pass - - def get_name(self): - return "Fox In Socks" - - def get_alias(self): - return "FOXNSOX" - - def get_description(self): - return "The Fox In Socks Extension" - - def get_namespace(self): - return "http://www.fox.in.socks/api/ext/pie/v1.0" - - def get_updated(self): - return "2011-01-22T13:25:27-06:00" - - def get_resources(self): - resources = [] - resource = extensions.ResourceExtension('foxnsocks', - FoxInSocksController()) - resources.append(resource) - return resources - - def get_actions(self): - actions = [] - actions.append(extensions.ActionExtension('servers', 'add_tweedle', - self._add_tweedle)) - actions.append(extensions.ActionExtension('servers', 'delete_tweedle', - self._delete_tweedle)) - return actions - - def get_response_extensions(self): - response_exts = [] - - def _goose_handler(res): - #NOTE: This only handles JSON responses. - # You can use content type header to test for XML. - data = json.loads(res.body) - data['flavor']['googoose'] = "Gooey goo for chewy chewing!" - return data - - resp_ext = extensions.ResponseExtension('GET', '/v1.1/flavors/:(id)', - _goose_handler) - response_exts.append(resp_ext) - - def _bands_handler(res): - #NOTE: This only handles JSON responses. - # You can use content type header to test for XML. - data = json.loads(res.body) - data['big_bands'] = 'Pig Bands!' - return data - - resp_ext2 = extensions.ResponseExtension('GET', '/v1.1/flavors/:(id)', - _bands_handler) - response_exts.append(resp_ext2) - return response_exts - - def _add_tweedle(self, input_dict, req, id): - - return "Tweedle Beetle Added." - - def _delete_tweedle(self, input_dict, req, id): - - return "Tweedle Beetle Deleted." -- cgit From 034a841cbac8e73c55e9525df7360a068fe9d892 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 15:43:38 -0700 Subject: pep8 fixes --- nova/api/openstack/incubator/volumes.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/nova/api/openstack/incubator/volumes.py b/nova/api/openstack/incubator/volumes.py index 7a5b2c1d0..47b86216e 100644 --- a/nova/api/openstack/incubator/volumes.py +++ b/nova/api/openstack/incubator/volumes.py @@ -339,9 +339,8 @@ class Volumes(extensions.ExtensionDescriptor): # NOTE(justinsb): No way to provide singular name ('volume') # Does this matter? res = extensions.ResourceExtension('volumes', - VolumeController(), - collection_actions= - {'detail': 'GET'} + VolumeController(), + collection_actions={'detail': 'GET'} ) resources.append(res) -- cgit From 11d258e1d8a4a78a699aa564b5f8139bf0b73db2 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 15:52:04 -0700 Subject: Added missing blank line at end of multiline docstring --- nova/api/openstack/extensions.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index d1d479313..631275235 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -41,7 +41,9 @@ class ExtensionDescriptor(object): """Base class that defines the contract for extensions. Note that you don't have to derive from this class to have a valid - extension; it is purely a convenience.""" + extension; it is purely a convenience. + + """ def get_name(self): """The name of the extension. -- cgit From 620c2dabfa8d92dbf250c078dda71d3ec11c6d8c Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 29 Mar 2011 16:13:09 -0700 Subject: fix for lp742650 --- bin/nova-ajax-console-proxy | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/bin/nova-ajax-console-proxy b/bin/nova-ajax-console-proxy index 0342c620a..d88f59e40 100755 --- a/bin/nova-ajax-console-proxy +++ b/bin/nova-ajax-console-proxy @@ -108,17 +108,17 @@ class AjaxConsoleProxy(object): return "Server Error" def register_listeners(self): - class Callback: - def __call__(self, data, message): - if data['method'] == 'authorize_ajax_console': - AjaxConsoleProxy.tokens[data['args']['token']] = \ - {'args': data['args'], 'last_activity': time.time()} + class TopicProxy(): + @staticmethod + def authorize_ajax_console(context, **kwargs): + AjaxConsoleProxy.tokens[kwargs['token']] = \ + {'args': kwargs, 'last_activity': time.time()} conn = rpc.Connection.instance(new=True) consumer = rpc.TopicAdapterConsumer( - connection=conn, - topic=FLAGS.ajax_console_proxy_topic) - consumer.register_callback(Callback()) + connection=conn, + proxy=TopicProxy, + topic=FLAGS.ajax_console_proxy_topic) def delete_expired_tokens(): now = time.time() @@ -130,8 +130,7 @@ class AjaxConsoleProxy(object): for k in to_delete: del AjaxConsoleProxy.tokens[k] - utils.LoopingCall(consumer.fetch, auto_ack=True, - enable_callbacks=True).start(0.1) + utils.LoopingCall(consumer.fetch, enable_callbacks=True).start(0.1) utils.LoopingCall(delete_expired_tokens).start(1) if __name__ == '__main__': -- cgit From 5e6c69bc7a7e5ddaa1bf0fa83f64da116343dba8 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 16:35:39 -0700 Subject: Narrowly focused bugfix - don't lose libvirt instances on host reboot or if they crash --- nova/compute/manager.py | 14 ++++++----- nova/virt/libvirt_conn.py | 59 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 55 insertions(+), 18 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index e0a5e2b3f..72f04ecb1 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1088,12 +1088,14 @@ class ComputeManager(manager.SchedulerDependentManager): db_instance['id'], vm_state) - if vm_state == power_state.SHUTOFF: - # TODO(soren): This is what the compute manager does when you - # terminate an instance. At some point I figure we'll have a - # "terminated" state and some sort of cleanup job that runs - # occasionally, cleaning them out. - self.db.instance_destroy(context, db_instance['id']) + # NOTE(justinsb): We no longer auto-remove SHUTOFF instances + # It's quite hard to get them back when we do. + #if vm_state == power_state.SHUTOFF: + # # TODO(soren): This is what the compute manager does when you + # # terminate an instance. At some point I figure we'll have a + # # "terminated" state and some sort of cleanup job that runs + # # occasionally, cleaning them out. + # self.db.instance_destroy(context, db_instance['id']) # Are there VMs not in the DB? for vm_not_found_in_db in vms_not_found_in_db: diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index c144e827e..533ff9394 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -116,6 +116,8 @@ flags.DEFINE_integer('live_migration_bandwidth', 0, 'Define live migration behavior') flags.DEFINE_string('qemu_img', 'qemu-img', 'binary to use for qemu-img commands') +flags.DEFINE_bool('start_guests_on_host_boot', False, + 'Whether to restart guests when the host reboots') def get_connection(read_only): @@ -230,12 +232,14 @@ class LibvirtConnection(driver.ComputeDriver): {'name': instance['name'], 'state': state}) db.instance_set_state(ctxt, instance['id'], state) - if state == power_state.SHUTOFF: - # TODO(soren): This is what the compute manager does when you - # terminate # an instance. At some point I figure we'll have a - # "terminated" state and some sort of cleanup job that runs - # occasionally, cleaning them out. - db.instance_destroy(ctxt, instance['id']) + # NOTE(justinsb): We no longer delete these instances, + # the user may want to power them back on + #if state == power_state.SHUTOFF: + # # TODO(soren): This is what the compute manager does when you + # # terminate # an instance. At some point I figure we'll have a + # # "terminated" state and some sort of cleanup job that runs + # # occasionally, cleaning them out. + # db.instance_destroy(ctxt, instance['id']) if state != power_state.RUNNING: continue @@ -474,7 +478,7 @@ class LibvirtConnection(driver.ComputeDriver): xml = self.to_xml(instance) self.firewall_driver.setup_basic_filtering(instance) self.firewall_driver.prepare_instance_filter(instance) - self._conn.createXML(xml, 0) + self._create_new_domain(xml) self.firewall_driver.apply_instance_filter(instance) timer = utils.LoopingCall(f=None) @@ -522,7 +526,7 @@ class LibvirtConnection(driver.ComputeDriver): 'kernel_id': FLAGS.rescue_kernel_id, 'ramdisk_id': FLAGS.rescue_ramdisk_id} self._create_image(instance, xml, '.rescue', rescue_images) - self._conn.createXML(xml, 0) + self._create_new_domain(xml) timer = utils.LoopingCall(f=None) @@ -565,10 +569,15 @@ class LibvirtConnection(driver.ComputeDriver): self.firewall_driver.setup_basic_filtering(instance, network_info) self.firewall_driver.prepare_instance_filter(instance, network_info) self._create_image(instance, xml, network_info) - self._conn.createXML(xml, 0) + domain = self._create_new_domain(xml) LOG.debug(_("instance %s: is running"), instance['name']) self.firewall_driver.apply_instance_filter(instance) + if FLAGS.start_guests_on_host_boot: + LOG.debug(_("instance %s: setting autostart ON") % + instance['name']) + domain.setAutostart(1) + timer = utils.LoopingCall(f=None) def _wait_for_boot(): @@ -964,11 +973,19 @@ class LibvirtConnection(driver.ComputeDriver): return xml def get_info(self, instance_name): + # NOTE(justinsb): When libvirt isn't running / can't connect, we get: + # libvir: Remote error : unable to connect to + # '/var/run/libvirt/libvirt-sock', libvirtd may need to be started: + # No such file or directory try: virt_dom = self._conn.lookupByName(instance_name) - except: - raise exception.NotFound(_("Instance %s not found") - % instance_name) + except libvirt.libvirtError as e: + if e.get_error_code() == libvirt.VIR_ERR_UNKNOWN_HOST: + raise exception.NotFound(_("Instance %s not found") + % instance_name) + LOG.warning(_("Error from libvirt during lookup: %s") % e) + raise + (state, max_mem, mem, num_cpu, cpu_time) = virt_dom.info() return {'state': state, 'max_mem': max_mem, @@ -976,6 +993,24 @@ class LibvirtConnection(driver.ComputeDriver): 'num_cpu': num_cpu, 'cpu_time': cpu_time} + def _create_new_domain(self, xml, persistent=True, launch_flags=0): + # NOTE(justinsb): libvirt has two types of domain: + # * a transient domain disappears when the guest is shutdown + # or the host is rebooted. + # * a permanent domain is not automatically deleted + # NOTE(justinsb): Even for ephemeral instances, transient seems risky + + if persistent: + # To create a persistent domain, first define it, then launch it. + domain = self._conn.defineXML(xml) + + domain.createWithFlags(launch_flags) + else: + # createXML call creates a transient domain + domain = self._conn.createXML(xml, launch_flags) + + return domain + def get_diagnostics(self, instance_name): raise exception.ApiError(_("diagnostics are not supported " "for libvirt")) -- cgit From 399056300a0be228ec4c56587ec0d9c0d09d927c Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 16:54:37 -0700 Subject: Fix unit test to reflect fact that instance is no longer deleted, just marked SHUTOFF --- nova/tests/test_compute.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index d1ef68de4..b7f08dfbe 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -654,4 +654,5 @@ class ComputeTestCase(test.TestCase): instances = db.instance_get_all(context.get_admin_context()) LOG.info(_("After force-killing instances: %s"), instances) - self.assertEqual(len(instances), 0) + self.assertEqual(len(instances), 1) + self.assertEqual(power_state.SHUTOFF, instances[0]['state']) -- cgit From d92322400c31f1cad933da5117b24376d60a5798 Mon Sep 17 00:00:00 2001 From: John Tran Date: Tue, 29 Mar 2011 17:07:59 -0700 Subject: adding unit tests for describe_images --- Authors | 1 + nova/tests/test_cloud.py | 31 ++++++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/Authors b/Authors index eccf38a43..48b912184 100644 --- a/Authors +++ b/Authors @@ -32,6 +32,7 @@ Jesse Andrews Joe Heck Joel Moore John Dewey +John Tran Jonathan Bryce Jordan Rinke Josh Durgin diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 791498f89..5cb969979 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -41,6 +41,7 @@ from nova.compute import power_state from nova.api.ec2 import cloud from nova.api.ec2 import ec2utils from nova.image import local +from nova.exception import NotFound FLAGS = flags.FLAGS @@ -71,7 +72,8 @@ class CloudTestCase(test.TestCase): host = self.network.get_network_host(self.context.elevated()) def fake_show(meh, context, id): - return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1}} + return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1, + 'type': 'machine'}} self.stubs.Set(local.LocalImageService, 'show', fake_show) self.stubs.Set(local.LocalImageService, 'show_by_name', fake_show) @@ -217,14 +219,33 @@ class CloudTestCase(test.TestCase): db.service_destroy(self.context, comp2['id']) def test_describe_images(self): + describe_images = self.cloud.describe_images + def fake_detail(meh, context): return [{'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1, - 'type':'machine'}}] + 'type': 'machine'}}] + + def fake_show_none(meh, context, id): + raise NotFound self.stubs.Set(local.LocalImageService, 'detail', fake_detail) - result = self.cloud.describe_images(self.context) - result = result['imagesSet'][0] - self.assertEqual(result['imageId'], 'ami-00000001') + # list all + result1 = describe_images(self.context) + result1 = result1['imagesSet'][0] + self.assertEqual(result1['imageId'], 'ami-00000001') + # provided a valid image_id + result2 = describe_images(self.context, ['ami-00000001']) + self.assertEqual(1, len(result2['imagesSet'])) + # provide more than 1 valid image_id + result3 = describe_images(self.context, ['ami-00000001', + 'ami-00000002']) + self.assertEqual(2, len(result3['imagesSet'])) + # provide an non-existing image_id + self.stubs.UnsetAll() + self.stubs.Set(local.LocalImageService, 'show', fake_show_none) + self.stubs.Set(local.LocalImageService, 'show_by_name', fake_show_none) + self.assertRaises(NotFound, describe_images, + self.context, ['ami-fake']) def test_console_output(self): instance_type = FLAGS.default_instance_type -- cgit From ded3416d48980c32eb20f95665f281ffc2927517 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 17:10:40 -0700 Subject: Removed commented-out EC2 code from volumes.py --- nova/api/openstack/incubator/volumes.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/nova/api/openstack/incubator/volumes.py b/nova/api/openstack/incubator/volumes.py index 47b86216e..0e6a1d0e9 100644 --- a/nova/api/openstack/incubator/volumes.py +++ b/nova/api/openstack/incubator/volumes.py @@ -49,24 +49,16 @@ def _translate_volume_summary_view(_context, vol): d = {} instance_id = None - # instance_data = None attached_to = vol.get('instance') if attached_to: instance_id = attached_to['id'] - # instance_data = '%s[%s]' % (instance_ec2_id, - # attached_to['host']) + d['id'] = vol['id'] d['status'] = vol['status'] d['size'] = vol['size'] d['availabilityZone'] = vol['availability_zone'] d['createdAt'] = vol['created_at'] - # if context.is_admin: - # v['status'] = '%s (%s, %s, %s, %s)' % ( - # vol['status'], - # vol['user_id'], - # vol['host'], - # instance_data, - # vol['mountpoint']) + if vol['attach_status'] == 'attached': d['attachments'] = [{'attachTime': vol['attach_time'], 'deleteOnTermination': False, -- cgit From 27b92e509c71a8b79dc6240aecdf598bf9d608f1 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 17:13:40 -0700 Subject: Change volume so that it returns attachments in the same format as is used for the attachment object --- nova/api/openstack/incubator/volumes.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/nova/api/openstack/incubator/volumes.py b/nova/api/openstack/incubator/volumes.py index 0e6a1d0e9..f96e20ed4 100644 --- a/nova/api/openstack/incubator/volumes.py +++ b/nova/api/openstack/incubator/volumes.py @@ -44,15 +44,10 @@ def _translate_volume_detail_view(context, vol): return d -def _translate_volume_summary_view(_context, vol): +def _translate_volume_summary_view(context, vol): """Maps keys for volumes summary view.""" d = {} - instance_id = None - attached_to = vol.get('instance') - if attached_to: - instance_id = attached_to['id'] - d['id'] = vol['id'] d['status'] = vol['status'] d['size'] = vol['size'] @@ -60,12 +55,7 @@ def _translate_volume_summary_view(_context, vol): d['createdAt'] = vol['created_at'] if vol['attach_status'] == 'attached': - d['attachments'] = [{'attachTime': vol['attach_time'], - 'deleteOnTermination': False, - 'mountpoint': vol['mountpoint'], - 'instanceId': instance_id, - 'status': 'attached', - 'volumeId': vol['id']}] + d['attachments'] = [_translate_attachment_detail_view(context, vol)] else: d['attachments'] = [{}] -- cgit From 6d3c31df757f65da7b29aaed1fb4d6e2b29126a0 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 17:17:20 -0700 Subject: Found a better (?) docstring from get_console_pool_info --- nova/virt/driver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/driver.py b/nova/virt/driver.py index c6c28b2ba..2f52f9cf1 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -89,7 +89,7 @@ class ComputeDriver(object): raise NotImplementedError() def get_console_pool_info(self, console_type): - """? + """Get info about the host on which the VM resides. Returns a dict containing: :address: ? -- cgit From 86914566436d778cdae2244cb9b277e25e21cb21 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 17:22:20 -0700 Subject: Fix a docstring --- nova/api/openstack/incubator/volumes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/openstack/incubator/volumes.py b/nova/api/openstack/incubator/volumes.py index f96e20ed4..6efacce52 100644 --- a/nova/api/openstack/incubator/volumes.py +++ b/nova/api/openstack/incubator/volumes.py @@ -202,7 +202,7 @@ class VolumeAttachmentController(wsgi.Controller): entity_maker=_translate_attachment_summary_view) def show(self, req, server_id, id): - """Return data about the given volume.""" + """Return data about the given volume attachment.""" context = req.environ['nova.context'] volume_id = id -- cgit From 60685eabcde99140f36e1ffbd16dbbbacc87baff Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 29 Mar 2011 17:23:09 -0700 Subject: use project key for decrypting images --- nova/image/s3.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/image/s3.py b/nova/image/s3.py index 85a2c651c..ddec5f3aa 100644 --- a/nova/image/s3.py +++ b/nova/image/s3.py @@ -31,6 +31,7 @@ from xml.etree import ElementTree import boto.s3.connection +from nova import crypto from nova import exception from nova import flags from nova import utils @@ -210,7 +211,7 @@ class S3ImageService(service.BaseImageService): # FIXME(vish): grab key from common service so this can run on # any host. - cloud_pk = os.path.join(FLAGS.ca_path, "private/cakey.pem") + cloud_pk = crypto.key_path(context.project_id) decrypted_filename = os.path.join(image_path, 'image.tar.gz') self._decrypt_image(encrypted_filename, encrypted_key, -- cgit From f0cd8a993d235fddbfb9478b69a77f4ed32f6dff Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 17:35:24 -0700 Subject: Wipe out the bad docstring on get_console_pool_info --- nova/virt/driver.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/nova/virt/driver.py b/nova/virt/driver.py index 2f52f9cf1..eb9626d08 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -89,14 +89,6 @@ class ComputeDriver(object): raise NotImplementedError() def get_console_pool_info(self, console_type): - """Get info about the host on which the VM resides. - - Returns a dict containing: - :address: ? - :username: ? - :password: ? - - """ raise NotImplementedError() def get_console_output(self, instance): -- cgit From 9c8300c98239c181cc66740bf18717f0488a0743 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 18:08:17 -0700 Subject: Renamed incubator => contrib --- nova/api/openstack/contrib/__init__.py | 22 ++ nova/api/openstack/contrib/volumes.py | 336 +++++++++++++++++++++++++++++++ nova/api/openstack/extensions.py | 4 +- nova/api/openstack/incubator/__init__.py | 22 -- nova/api/openstack/incubator/volumes.py | 336 ------------------------------- 5 files changed, 360 insertions(+), 360 deletions(-) create mode 100644 nova/api/openstack/contrib/__init__.py create mode 100644 nova/api/openstack/contrib/volumes.py delete mode 100644 nova/api/openstack/incubator/__init__.py delete mode 100644 nova/api/openstack/incubator/volumes.py diff --git a/nova/api/openstack/contrib/__init__.py b/nova/api/openstack/contrib/__init__.py new file mode 100644 index 000000000..e115f1ab9 --- /dev/null +++ b/nova/api/openstack/contrib/__init__.py @@ -0,0 +1,22 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License.import datetime + +"""Incubator contains extensions that are shipped with nova. + +It can't be called 'extensions' because that causes namespacing problems. + +""" diff --git a/nova/api/openstack/contrib/volumes.py b/nova/api/openstack/contrib/volumes.py new file mode 100644 index 000000000..6efacce52 --- /dev/null +++ b/nova/api/openstack/contrib/volumes.py @@ -0,0 +1,336 @@ +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""The volumes extension.""" + +from webob import exc + +from nova import compute +from nova import exception +from nova import flags +from nova import log as logging +from nova import volume +from nova import wsgi +from nova.api.openstack import common +from nova.api.openstack import extensions +from nova.api.openstack import faults + + +LOG = logging.getLogger("nova.api.volumes") + + +FLAGS = flags.FLAGS + + +def _translate_volume_detail_view(context, vol): + """Maps keys for volumes details view.""" + + d = _translate_volume_summary_view(context, vol) + + # No additional data / lookups at the moment + + return d + + +def _translate_volume_summary_view(context, vol): + """Maps keys for volumes summary view.""" + d = {} + + d['id'] = vol['id'] + d['status'] = vol['status'] + d['size'] = vol['size'] + d['availabilityZone'] = vol['availability_zone'] + d['createdAt'] = vol['created_at'] + + if vol['attach_status'] == 'attached': + d['attachments'] = [_translate_attachment_detail_view(context, vol)] + else: + d['attachments'] = [{}] + + d['displayName'] = vol['display_name'] + d['displayDescription'] = vol['display_description'] + return d + + +class VolumeController(wsgi.Controller): + """The Volumes API controller for the OpenStack API.""" + + _serialization_metadata = { + 'application/xml': { + "attributes": { + "volume": [ + "id", + "status", + "size", + "availabilityZone", + "createdAt", + "displayName", + "displayDescription", + ]}}} + + def __init__(self): + self.volume_api = volume.API() + super(VolumeController, self).__init__() + + def show(self, req, id): + """Return data about the given volume.""" + context = req.environ['nova.context'] + + try: + vol = self.volume_api.get(context, id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + return {'volume': _translate_volume_detail_view(context, vol)} + + def delete(self, req, id): + """Delete a volume.""" + context = req.environ['nova.context'] + + LOG.audit(_("Delete volume with id: %s"), id, context=context) + + try: + self.volume_api.delete(context, volume_id=id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + return exc.HTTPAccepted() + + def index(self, req): + """Returns a summary list of volumes.""" + return self._items(req, entity_maker=_translate_volume_summary_view) + + def detail(self, req): + """Returns a detailed list of volumes.""" + return self._items(req, entity_maker=_translate_volume_detail_view) + + def _items(self, req, entity_maker): + """Returns a list of volumes, transformed through entity_maker.""" + context = req.environ['nova.context'] + + volumes = self.volume_api.get_all(context) + limited_list = common.limited(volumes, req) + res = [entity_maker(context, vol) for vol in limited_list] + return {'volumes': res} + + def create(self, req): + """Creates a new volume.""" + context = req.environ['nova.context'] + + env = self._deserialize(req.body, req.get_content_type()) + if not env: + return faults.Fault(exc.HTTPUnprocessableEntity()) + + vol = env['volume'] + size = vol['size'] + LOG.audit(_("Create volume of %s GB"), size, context=context) + new_volume = self.volume_api.create(context, size, + vol.get('display_name'), + vol.get('display_description')) + + # Work around problem that instance is lazy-loaded... + new_volume['instance'] = None + + retval = _translate_volume_detail_view(context, new_volume) + + return {'volume': retval} + + +def _translate_attachment_detail_view(_context, vol): + """Maps keys for attachment details view.""" + + d = _translate_attachment_summary_view(_context, vol) + + # No additional data / lookups at the moment + + return d + + +def _translate_attachment_summary_view(_context, vol): + """Maps keys for attachment summary view.""" + d = {} + + volume_id = vol['id'] + + # NOTE(justinsb): We use the volume id as the id of the attachment object + d['id'] = volume_id + + d['volumeId'] = volume_id + if vol.get('instance_id'): + d['serverId'] = vol['instance_id'] + if vol.get('mountpoint'): + d['device'] = vol['mountpoint'] + + return d + + +class VolumeAttachmentController(wsgi.Controller): + """The volume attachment API controller for the Openstack API. + + A child resource of the server. Note that we use the volume id + as the ID of the attachment (though this is not guaranteed externally) + + """ + + _serialization_metadata = { + 'application/xml': { + 'attributes': { + 'volumeAttachment': ['id', + 'serverId', + 'volumeId', + 'device']}}} + + def __init__(self): + self.compute_api = compute.API() + self.volume_api = volume.API() + super(VolumeAttachmentController, self).__init__() + + def index(self, req, server_id): + """Returns the list of volume attachments for a given instance.""" + return self._items(req, server_id, + entity_maker=_translate_attachment_summary_view) + + def show(self, req, server_id, id): + """Return data about the given volume attachment.""" + context = req.environ['nova.context'] + + volume_id = id + try: + vol = self.volume_api.get(context, volume_id) + except exception.NotFound: + LOG.debug("volume_id not found") + return faults.Fault(exc.HTTPNotFound()) + + if str(vol['instance_id']) != server_id: + LOG.debug("instance_id != server_id") + return faults.Fault(exc.HTTPNotFound()) + + return {'volumeAttachment': _translate_attachment_detail_view(context, + vol)} + + def create(self, req, server_id): + """Attach a volume to an instance.""" + context = req.environ['nova.context'] + + env = self._deserialize(req.body, req.get_content_type()) + if not env: + return faults.Fault(exc.HTTPUnprocessableEntity()) + + instance_id = server_id + volume_id = env['volumeAttachment']['volumeId'] + device = env['volumeAttachment']['device'] + + msg = _("Attach volume %(volume_id)s to instance %(server_id)s" + " at %(device)s") % locals() + LOG.audit(msg, context=context) + + try: + self.compute_api.attach_volume(context, + instance_id=instance_id, + volume_id=volume_id, + device=device) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + # The attach is async + attachment = {} + attachment['id'] = volume_id + attachment['volumeId'] = volume_id + + # NOTE(justinsb): And now, we have a problem... + # The attach is async, so there's a window in which we don't see + # the attachment (until the attachment completes). We could also + # get problems with concurrent requests. I think we need an + # attachment state, and to write to the DB here, but that's a bigger + # change. + # For now, we'll probably have to rely on libraries being smart + + # TODO(justinsb): How do I return "accepted" here? + return {'volumeAttachment': attachment} + + def update(self, _req, _server_id, _id): + """Update a volume attachment. We don't currently support this.""" + return faults.Fault(exc.HTTPBadRequest()) + + def delete(self, req, server_id, id): + """Detach a volume from an instance.""" + context = req.environ['nova.context'] + + volume_id = id + LOG.audit(_("Detach volume %s"), volume_id, context=context) + + try: + vol = self.volume_api.get(context, volume_id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + if str(vol['instance_id']) != server_id: + LOG.debug("instance_id != server_id") + return faults.Fault(exc.HTTPNotFound()) + + self.compute_api.detach_volume(context, + volume_id=volume_id) + + return exc.HTTPAccepted() + + def _items(self, req, server_id, entity_maker): + """Returns a list of attachments, transformed through entity_maker.""" + context = req.environ['nova.context'] + + try: + instance = self.compute_api.get(context, server_id) + except exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + + volumes = instance['volumes'] + limited_list = common.limited(volumes, req) + res = [entity_maker(context, vol) for vol in limited_list] + return {'volumeAttachments': res} + + +class Volumes(extensions.ExtensionDescriptor): + def get_name(self): + return "Volumes" + + def get_alias(self): + return "VOLUMES" + + def get_description(self): + return "Volumes support" + + def get_namespace(self): + return "http://docs.openstack.org/ext/volumes/api/v1.1" + + def get_updated(self): + return "2011-03-25T00:00:00+00:00" + + def get_resources(self): + resources = [] + + # NOTE(justinsb): No way to provide singular name ('volume') + # Does this matter? + res = extensions.ResourceExtension('volumes', + VolumeController(), + collection_actions={'detail': 'GET'} + ) + resources.append(res) + + res = extensions.ResourceExtension('volume_attachments', + VolumeAttachmentController(), + parent=dict( + member_name='server', + collection_name='servers')) + resources.append(res) + + return resources diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index 631275235..cba151fb6 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -378,7 +378,7 @@ class ExtensionManager(object): widgets.py the extension class within that module should be 'Widgets'. - In addition, extensions are loaded from the 'incubator' directory. + In addition, extensions are loaded from the 'contrib' directory. See nova/tests/api/openstack/extensions/foxinsocks.py for an example extension implementation. @@ -387,7 +387,7 @@ class ExtensionManager(object): if os.path.exists(self.path): self._load_all_extensions_from_path(self.path) - incubator_path = os.path.join(os.path.dirname(__file__), "incubator") + incubator_path = os.path.join(os.path.dirname(__file__), "contrib") if os.path.exists(incubator_path): self._load_all_extensions_from_path(incubator_path) diff --git a/nova/api/openstack/incubator/__init__.py b/nova/api/openstack/incubator/__init__.py deleted file mode 100644 index e115f1ab9..000000000 --- a/nova/api/openstack/incubator/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2011 Justin Santa Barbara -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License.import datetime - -"""Incubator contains extensions that are shipped with nova. - -It can't be called 'extensions' because that causes namespacing problems. - -""" diff --git a/nova/api/openstack/incubator/volumes.py b/nova/api/openstack/incubator/volumes.py deleted file mode 100644 index 6efacce52..000000000 --- a/nova/api/openstack/incubator/volumes.py +++ /dev/null @@ -1,336 +0,0 @@ -# Copyright 2011 Justin Santa Barbara -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""The volumes extension.""" - -from webob import exc - -from nova import compute -from nova import exception -from nova import flags -from nova import log as logging -from nova import volume -from nova import wsgi -from nova.api.openstack import common -from nova.api.openstack import extensions -from nova.api.openstack import faults - - -LOG = logging.getLogger("nova.api.volumes") - - -FLAGS = flags.FLAGS - - -def _translate_volume_detail_view(context, vol): - """Maps keys for volumes details view.""" - - d = _translate_volume_summary_view(context, vol) - - # No additional data / lookups at the moment - - return d - - -def _translate_volume_summary_view(context, vol): - """Maps keys for volumes summary view.""" - d = {} - - d['id'] = vol['id'] - d['status'] = vol['status'] - d['size'] = vol['size'] - d['availabilityZone'] = vol['availability_zone'] - d['createdAt'] = vol['created_at'] - - if vol['attach_status'] == 'attached': - d['attachments'] = [_translate_attachment_detail_view(context, vol)] - else: - d['attachments'] = [{}] - - d['displayName'] = vol['display_name'] - d['displayDescription'] = vol['display_description'] - return d - - -class VolumeController(wsgi.Controller): - """The Volumes API controller for the OpenStack API.""" - - _serialization_metadata = { - 'application/xml': { - "attributes": { - "volume": [ - "id", - "status", - "size", - "availabilityZone", - "createdAt", - "displayName", - "displayDescription", - ]}}} - - def __init__(self): - self.volume_api = volume.API() - super(VolumeController, self).__init__() - - def show(self, req, id): - """Return data about the given volume.""" - context = req.environ['nova.context'] - - try: - vol = self.volume_api.get(context, id) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - - return {'volume': _translate_volume_detail_view(context, vol)} - - def delete(self, req, id): - """Delete a volume.""" - context = req.environ['nova.context'] - - LOG.audit(_("Delete volume with id: %s"), id, context=context) - - try: - self.volume_api.delete(context, volume_id=id) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - return exc.HTTPAccepted() - - def index(self, req): - """Returns a summary list of volumes.""" - return self._items(req, entity_maker=_translate_volume_summary_view) - - def detail(self, req): - """Returns a detailed list of volumes.""" - return self._items(req, entity_maker=_translate_volume_detail_view) - - def _items(self, req, entity_maker): - """Returns a list of volumes, transformed through entity_maker.""" - context = req.environ['nova.context'] - - volumes = self.volume_api.get_all(context) - limited_list = common.limited(volumes, req) - res = [entity_maker(context, vol) for vol in limited_list] - return {'volumes': res} - - def create(self, req): - """Creates a new volume.""" - context = req.environ['nova.context'] - - env = self._deserialize(req.body, req.get_content_type()) - if not env: - return faults.Fault(exc.HTTPUnprocessableEntity()) - - vol = env['volume'] - size = vol['size'] - LOG.audit(_("Create volume of %s GB"), size, context=context) - new_volume = self.volume_api.create(context, size, - vol.get('display_name'), - vol.get('display_description')) - - # Work around problem that instance is lazy-loaded... - new_volume['instance'] = None - - retval = _translate_volume_detail_view(context, new_volume) - - return {'volume': retval} - - -def _translate_attachment_detail_view(_context, vol): - """Maps keys for attachment details view.""" - - d = _translate_attachment_summary_view(_context, vol) - - # No additional data / lookups at the moment - - return d - - -def _translate_attachment_summary_view(_context, vol): - """Maps keys for attachment summary view.""" - d = {} - - volume_id = vol['id'] - - # NOTE(justinsb): We use the volume id as the id of the attachment object - d['id'] = volume_id - - d['volumeId'] = volume_id - if vol.get('instance_id'): - d['serverId'] = vol['instance_id'] - if vol.get('mountpoint'): - d['device'] = vol['mountpoint'] - - return d - - -class VolumeAttachmentController(wsgi.Controller): - """The volume attachment API controller for the Openstack API. - - A child resource of the server. Note that we use the volume id - as the ID of the attachment (though this is not guaranteed externally) - - """ - - _serialization_metadata = { - 'application/xml': { - 'attributes': { - 'volumeAttachment': ['id', - 'serverId', - 'volumeId', - 'device']}}} - - def __init__(self): - self.compute_api = compute.API() - self.volume_api = volume.API() - super(VolumeAttachmentController, self).__init__() - - def index(self, req, server_id): - """Returns the list of volume attachments for a given instance.""" - return self._items(req, server_id, - entity_maker=_translate_attachment_summary_view) - - def show(self, req, server_id, id): - """Return data about the given volume attachment.""" - context = req.environ['nova.context'] - - volume_id = id - try: - vol = self.volume_api.get(context, volume_id) - except exception.NotFound: - LOG.debug("volume_id not found") - return faults.Fault(exc.HTTPNotFound()) - - if str(vol['instance_id']) != server_id: - LOG.debug("instance_id != server_id") - return faults.Fault(exc.HTTPNotFound()) - - return {'volumeAttachment': _translate_attachment_detail_view(context, - vol)} - - def create(self, req, server_id): - """Attach a volume to an instance.""" - context = req.environ['nova.context'] - - env = self._deserialize(req.body, req.get_content_type()) - if not env: - return faults.Fault(exc.HTTPUnprocessableEntity()) - - instance_id = server_id - volume_id = env['volumeAttachment']['volumeId'] - device = env['volumeAttachment']['device'] - - msg = _("Attach volume %(volume_id)s to instance %(server_id)s" - " at %(device)s") % locals() - LOG.audit(msg, context=context) - - try: - self.compute_api.attach_volume(context, - instance_id=instance_id, - volume_id=volume_id, - device=device) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - - # The attach is async - attachment = {} - attachment['id'] = volume_id - attachment['volumeId'] = volume_id - - # NOTE(justinsb): And now, we have a problem... - # The attach is async, so there's a window in which we don't see - # the attachment (until the attachment completes). We could also - # get problems with concurrent requests. I think we need an - # attachment state, and to write to the DB here, but that's a bigger - # change. - # For now, we'll probably have to rely on libraries being smart - - # TODO(justinsb): How do I return "accepted" here? - return {'volumeAttachment': attachment} - - def update(self, _req, _server_id, _id): - """Update a volume attachment. We don't currently support this.""" - return faults.Fault(exc.HTTPBadRequest()) - - def delete(self, req, server_id, id): - """Detach a volume from an instance.""" - context = req.environ['nova.context'] - - volume_id = id - LOG.audit(_("Detach volume %s"), volume_id, context=context) - - try: - vol = self.volume_api.get(context, volume_id) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - - if str(vol['instance_id']) != server_id: - LOG.debug("instance_id != server_id") - return faults.Fault(exc.HTTPNotFound()) - - self.compute_api.detach_volume(context, - volume_id=volume_id) - - return exc.HTTPAccepted() - - def _items(self, req, server_id, entity_maker): - """Returns a list of attachments, transformed through entity_maker.""" - context = req.environ['nova.context'] - - try: - instance = self.compute_api.get(context, server_id) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - - volumes = instance['volumes'] - limited_list = common.limited(volumes, req) - res = [entity_maker(context, vol) for vol in limited_list] - return {'volumeAttachments': res} - - -class Volumes(extensions.ExtensionDescriptor): - def get_name(self): - return "Volumes" - - def get_alias(self): - return "VOLUMES" - - def get_description(self): - return "Volumes support" - - def get_namespace(self): - return "http://docs.openstack.org/ext/volumes/api/v1.1" - - def get_updated(self): - return "2011-03-25T00:00:00+00:00" - - def get_resources(self): - resources = [] - - # NOTE(justinsb): No way to provide singular name ('volume') - # Does this matter? - res = extensions.ResourceExtension('volumes', - VolumeController(), - collection_actions={'detail': 'GET'} - ) - resources.append(res) - - res = extensions.ResourceExtension('volume_attachments', - VolumeAttachmentController(), - parent=dict( - member_name='server', - collection_name='servers')) - resources.append(res) - - return resources -- cgit From be8bf22f90e322823cb3cf4963f5c7313ef727ec Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 18:08:36 -0700 Subject: Removed unused super_verbose argument left over from previous code --- nova/api/openstack/extensions.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index cba151fb6..6813d85c9 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -315,8 +315,6 @@ class ExtensionManager(object): def __init__(self, path): LOG.audit(_('Initializing extension manager.')) - self.super_verbose = False - self.path = path self.extensions = {} self._load_all_extensions() -- cgit From 4c16db6ad330b0c3a1bdde098bbdcf958fc23bdf Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 18:13:04 -0700 Subject: Rename MockImageService -> FakeImageService --- nova/image/fake.py | 4 ++-- nova/tests/integrated/integrated_helpers.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/image/fake.py b/nova/image/fake.py index 4caf68d63..c84f7ec02 100644 --- a/nova/image/fake.py +++ b/nova/image/fake.py @@ -28,7 +28,7 @@ LOG = logging.getLogger('nova.image.fake') FLAGS = flags.FLAGS -class MockImageService(service.BaseImageService): +class FakeImageService(service.BaseImageService): """Mock (fake) image service for unit testing.""" def __init__(self): @@ -43,7 +43,7 @@ class MockImageService(service.BaseImageService): 'disk_format': 'ami'} } self.create(None, image) - super(MockImageService, self).__init__() + super(FakeImageService, self).__init__() def index(self, context): """Returns list of images.""" diff --git a/nova/tests/integrated/integrated_helpers.py b/nova/tests/integrated/integrated_helpers.py index e0fe2d2a2..2e5d67017 100644 --- a/nova/tests/integrated/integrated_helpers.py +++ b/nova/tests/integrated/integrated_helpers.py @@ -184,7 +184,7 @@ class _IntegratedTestBase(test.TestCase): def _get_flags(self): """An opportunity to setup flags, before the services are started.""" f = {} - f['image_service'] = 'nova.image.fake.MockImageService' + f['image_service'] = 'nova.image.fake.FakeImageService' f['fake_network'] = True return f -- cgit From 2315682856f420ff0b781bead142e1aff82071a4 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 18:16:09 -0700 Subject: "Incubator" is no more. Long live "contrib" --- nova/api/openstack/contrib/__init__.py | 2 +- nova/api/openstack/extensions.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nova/api/openstack/contrib/__init__.py b/nova/api/openstack/contrib/__init__.py index e115f1ab9..b42a1d89d 100644 --- a/nova/api/openstack/contrib/__init__.py +++ b/nova/api/openstack/contrib/__init__.py @@ -15,7 +15,7 @@ # License for the specific language governing permissions and limitations # under the License.import datetime -"""Incubator contains extensions that are shipped with nova. +"""Contrib contains extensions that are shipped with nova. It can't be called 'extensions' because that causes namespacing problems. diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index 6813d85c9..fb1dccb28 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -385,9 +385,9 @@ class ExtensionManager(object): if os.path.exists(self.path): self._load_all_extensions_from_path(self.path) - incubator_path = os.path.join(os.path.dirname(__file__), "contrib") - if os.path.exists(incubator_path): - self._load_all_extensions_from_path(incubator_path) + contrib_path = os.path.join(os.path.dirname(__file__), "contrib") + if os.path.exists(contrib_path): + self._load_all_extensions_from_path(contrib_path) def _load_all_extensions_from_path(self, path): for f in os.listdir(path): -- cgit From f4b9e95bd143d46cd4939a3ea31de10a3e66fd90 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 19:10:23 -0700 Subject: name, created_at, updated_at are required. I think some of the other image services might also break because of this, but that's a different issue... --- nova/image/fake.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nova/image/fake.py b/nova/image/fake.py index c84f7ec02..16c628091 100644 --- a/nova/image/fake.py +++ b/nova/image/fake.py @@ -16,6 +16,8 @@ # under the License. """Implementation of an fake image service""" +import datetime + from nova import exception from nova import flags from nova import log as logging @@ -35,7 +37,11 @@ class FakeImageService(service.BaseImageService): self.images = {} # NOTE(justinsb): The OpenStack API can't upload an image? # So, make sure we've got one.. + timestamp = datetime.datetime(2011, 01, 01, 01, 02, 03) image = {'id': '123456', + 'name': 'fakeimage123456', + 'created_at': timestamp, + 'updated_at': timestamp, 'status': 'active', 'type': 'machine', 'properties': {'kernel_id': FLAGS.null_kernel, -- cgit From 9397766990b00167071bca6392096abfb93af982 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 29 Mar 2011 19:11:12 -0700 Subject: Deepcopy the images, because the string formatting transforms them in-place --- nova/image/fake.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/nova/image/fake.py b/nova/image/fake.py index 16c628091..08302d6eb 100644 --- a/nova/image/fake.py +++ b/nova/image/fake.py @@ -16,6 +16,7 @@ # under the License. """Implementation of an fake image service""" +import copy import datetime from nova import exception @@ -53,11 +54,11 @@ class FakeImageService(service.BaseImageService): def index(self, context): """Returns list of images.""" - return self.images.values() + return copy.deepcopy(self.images.values()) def detail(self, context): """Return list of detailed image information.""" - return self.images.values() + return copy.deepcopy(self.images.values()) def show(self, context, image_id): """Get data about specified image. @@ -68,7 +69,7 @@ class FakeImageService(service.BaseImageService): image_id = int(image_id) image = self.images.get(image_id) if image: - return image + return copy.deepcopy(image) LOG.warn("Unable to find image id %s. Have images: %s", image_id, self.images) raise exception.NotFound @@ -83,7 +84,7 @@ class FakeImageService(service.BaseImageService): if self.images.get(image_id): raise exception.Duplicate() - self.images[image_id] = data + self.images[image_id] = copy.deepcopy(data) def update(self, context, image_id, data): """Replace the contents of the given image with the new data. @@ -94,7 +95,7 @@ class FakeImageService(service.BaseImageService): image_id = int(image_id) if not self.images.get(image_id): raise exception.NotFound - self.images[image_id] = data + self.images[image_id] = copy.deepcopy(data) def delete(self, context, image_id): """Delete the given image. -- cgit From 3e9bafd4f05a4bda29c30460bf3e3428a03f8218 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 29 Mar 2011 22:37:19 -0700 Subject: fix doc to refer to nova-vncproxy --- doc/source/runnova/vncconsole.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/source/runnova/vncconsole.rst b/doc/source/runnova/vncconsole.rst index 942ace611..c1fe9be39 100644 --- a/doc/source/runnova/vncconsole.rst +++ b/doc/source/runnova/vncconsole.rst @@ -26,7 +26,7 @@ A VNC Connection works like so: * User connects over an api and gets a url like http://ip:port/?token=xyz * User pastes url in browser * Browser connects to VNC Proxy though a websocket enabled client like noVNC -* VNC Proxy authorizes users token, maps the token to a host and port of an +* VNC Proxy authorizes users token, maps the token to a host and port of an instance's VNC server * VNC Proxy initiates connection to VNC server, and continues proxying until the session ends @@ -34,17 +34,17 @@ A VNC Connection works like so: Configuring the VNC Proxy ------------------------- -nova-vnc-proxy requires a websocket enabled html client to work properly. At -this time, the only tested client is a slightly modified fork of noVNC, which +nova-vncproxy requires a websocket enabled html client to work properly. At +this time, the only tested client is a slightly modified fork of noVNC, which you can at find http://github.com/openstack/noVNC.git .. todo:: add instruction for installing from package noVNC must be in the location specified by --vncproxy_wwwroot, which defaults -to /var/lib/nova/noVNC. nova-vnc-proxy will fail to launch until this code -is properly installed. +to /var/lib/nova/noVNC. nova-vncproxy will fail to launch until this code +is properly installed. -By default, nova-vnc-proxy binds 0.0.0.0:6080. This can be configured with: +By default, nova-vncproxy binds 0.0.0.0:6080. This can be configured with: * --vncproxy_port=[port] * --vncproxy_host=[host] @@ -55,17 +55,17 @@ Enabling VNC Consoles in Nova At the moment, VNC support is supported only when using libvirt. To enable VNC Console, configure the following flags: -* --vnc_console_proxy_url=http://[proxy_host]:[proxy_port] - proxy_port - defaults to 6080. This url must point to nova-vnc-proxy +* --vnc_console_proxy_url=http://[proxy_host]:[proxy_port] - proxy_port + defaults to 6080. This url must point to nova-vncproxy * --vnc_enabled=[True|False] - defaults to True. If this flag is not set your - instances will launch without vnc support. + instances will launch without vnc support. Getting an instance's VNC Console --------------------------------- You can access an instance's VNC Console url in the following methods: -* Using the direct api: +* Using the direct api: eg: 'stack --user=admin --project=admin compute get_vnc_console instance_id=1' * Support for Dashboard, and the Openstack API will be forthcoming -- cgit From 7856df88b22e6ff3bd0f124e3d71f130e3e9c205 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 29 Mar 2011 22:41:15 -0700 Subject: fix localization for multiple replacement strings --- nova/vnc/auth.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/nova/vnc/auth.py b/nova/vnc/auth.py index c7df13450..ce5e10388 100644 --- a/nova/vnc/auth.py +++ b/nova/vnc/auth.py @@ -117,11 +117,13 @@ class VNCProxyAuthManager(manager.Manager): self.tokens[token] = {'host': host, 'port': port, 'last_activity_at': time.time()} - LOG.audit(_("Received Token: %s, %s)"), token, self.tokens[token]) + token_dict = self.tokens[token] + LOG.audit(_("Received Token: %(token)s, %(token_dict)s)"), locals()) def check_token(self, context, token): - LOG.audit(_("Checking Token: %s, %s)"), token, (token in self.tokens)) - if token in self.tokens: + token_valid = token in self.tokens + LOG.audit(_("Checking Token: %(token)s, %(token_valid)s)"), locals()) + if token_valid: return self.tokens[token] def _delete_expired_tokens(self): -- cgit From 7aa0102b2d451ffa87a095ac4471a65260aff3fe Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 29 Mar 2011 22:55:16 -0700 Subject: make sure that flag is there in compute api --- nova/compute/api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/compute/api.py b/nova/compute/api.py index 7977b07a2..7f358fdfd 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -39,6 +39,7 @@ from nova.db import base FLAGS = flags.FLAGS LOG = logging.getLogger('nova.compute.api') +flags.DECLARE('vncproxy_topic', 'nova.vnc') def generate_default_hostname(instance_id): -- cgit From 047af2c506374aa44bb896a7df0cb5813bf3a123 Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Wed, 30 Mar 2011 15:02:59 +0200 Subject: Add missing method that prevent HyperV compute nodes from starting up --- nova/virt/hyperv.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nova/virt/hyperv.py b/nova/virt/hyperv.py index a1ed5ebbf..13f403a66 100644 --- a/nova/virt/hyperv.py +++ b/nova/virt/hyperv.py @@ -485,3 +485,7 @@ class HyperVConnection(driver.ComputeDriver): def poll_rescued_instances(self, timeout): pass + + def update_available_resource(self, ctxt, host): + """This method is supported only by libvirt.""" + return -- cgit From 6f274d0a5818633b072e432ba7182650f0d30001 Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Wed, 30 Mar 2011 15:28:21 +0200 Subject: Do not push 'None' to authorized_keys when no key is specified --- nova/virt/libvirt_conn.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index b28584cb6..f34ea7225 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -828,7 +828,10 @@ class LibvirtConnection(driver.ComputeDriver): if FLAGS.libvirt_type == 'lxc': target_partition = None - key = str(inst['key_data']) + if inst['key_data']: + key = str(inst['key_data']) + else: + key = None net = None nets = [] -- cgit From b1589b5f034db95b1d18910e27cae516258a4311 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Wed, 30 Mar 2011 09:39:35 -0400 Subject: exception -> Fault --- nova/tests/api/openstack/test_faults.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/tests/api/openstack/test_faults.py b/nova/tests/api/openstack/test_faults.py index 0cda542de..9746e8168 100644 --- a/nova/tests/api/openstack/test_faults.py +++ b/nova/tests/api/openstack/test_faults.py @@ -128,7 +128,7 @@ class TestFaults(test.TestCase): self.assertEqual(expected, actual) def test_raise(self): - """Ensure the ability to raise exceptions in WSGI-ified methods.""" + """Ensure the ability to raise `Fault`s in WSGI-ified methods.""" @webob.dec.wsgify def raiser(req): raise faults.Fault(webob.exc.HTTPNotFound(explanation='whut?')) -- cgit From de9091a74107827b8f7157d6b89c2fb5dcf92dd2 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Wed, 30 Mar 2011 08:29:17 -0700 Subject: queues properly reconnect if rabbitmq is restarted --- nova/rpc.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/nova/rpc.py b/nova/rpc.py index 388f78d69..be7cb3f37 100644 --- a/nova/rpc.py +++ b/nova/rpc.py @@ -74,7 +74,12 @@ class Connection(carrot_connection.BrokerConnection): """Recreates the connection instance This is necessary to recover from some network errors/disconnects""" - del cls._instance + try: + del cls._instance + except AttributeError, e: + # The _instance stuff is for testing purposes. Usually we don't use + # it. So don't freak out if it doesn't exist. + pass return cls.instance() @@ -125,10 +130,12 @@ class Consumer(messaging.Consumer): # NOTE(vish): This is catching all errors because we really don't # want exceptions to be logged 10 times a second if some # persistent failure occurs. - except Exception: # pylint: disable=W0703 + except Exception, e: # pylint: disable=W0703 if not self.failed_connection: - LOG.exception(_("Failed to fetch message from queue")) + LOG.exception(_("Failed to fetch message from queue: %s" % e)) self.failed_connection = True + else: + LOG.exception(_("Unhandled exception %s" % e)) def attach_to_eventlet(self): """Only needed for unit tests!""" -- cgit From 951ec0d0fb2711e5d5ef4d6e9e78fe74d6c62360 Mon Sep 17 00:00:00 2001 From: Masanori Itoh Date: Thu, 31 Mar 2011 00:45:59 +0900 Subject: Added synchronize_session parameter to a query in fixed_ip_disassociate_all_by_timeout() and fix #735974. --- nova/db/sqlalchemy/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index b2a13a01b..08eb0b7b2 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -660,7 +660,7 @@ def fixed_ip_disassociate_all_by_timeout(_context, host, time): filter(models.FixedIp.instance_id != None).\ filter_by(allocated=0).\ update({'instance_id': None, - 'leased': 0}) + 'leased': 0}, synchronize_session='fetch') return result -- cgit From 12505c6bae61e72b6c75ac647323c3ec15997df1 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Wed, 30 Mar 2011 10:05:06 -0700 Subject: Add XML namespaces to the OpenStack API --- nova/api/openstack/accounts.py | 5 ++- nova/api/openstack/backup_schedules.py | 4 +-- nova/api/openstack/common.py | 11 +++++++ nova/api/openstack/consoles.py | 4 +-- nova/api/openstack/extensions.py | 7 +++-- nova/api/openstack/flavors.py | 7 +++-- nova/api/openstack/image_metadata.py | 3 +- nova/api/openstack/images.py | 5 ++- nova/api/openstack/limits.py | 4 +-- nova/api/openstack/server_metadata.py | 3 +- nova/api/openstack/servers.py | 5 ++- nova/api/openstack/shared_ip_groups.py | 4 +-- nova/api/openstack/users.py | 3 +- nova/api/openstack/zones.py | 6 ++-- nova/tests/integrated/test_xml.py | 56 ++++++++++++++++++++++++++++++++++ nova/wsgi.py | 8 ++--- 16 files changed, 103 insertions(+), 32 deletions(-) create mode 100644 nova/tests/integrated/test_xml.py diff --git a/nova/api/openstack/accounts.py b/nova/api/openstack/accounts.py index 86066fa20..6e3763e47 100644 --- a/nova/api/openstack/accounts.py +++ b/nova/api/openstack/accounts.py @@ -13,15 +13,14 @@ # License for the specific language governing permissions and limitations # under the License. -import common import webob.exc from nova import exception from nova import flags from nova import log as logging -from nova import wsgi from nova.auth import manager +from nova.api.openstack import common from nova.api.openstack import faults FLAGS = flags.FLAGS @@ -35,7 +34,7 @@ def _translate_keys(account): manager=account.project_manager_id) -class Controller(wsgi.Controller): +class Controller(common.OpenstackController): _serialization_metadata = { 'application/xml': { diff --git a/nova/api/openstack/backup_schedules.py b/nova/api/openstack/backup_schedules.py index f2d2d86e8..4bf744046 100644 --- a/nova/api/openstack/backup_schedules.py +++ b/nova/api/openstack/backup_schedules.py @@ -19,7 +19,7 @@ import time from webob import exc -from nova import wsgi +from nova.api.openstack import common from nova.api.openstack import faults import nova.image.service @@ -29,7 +29,7 @@ def _translate_keys(inst): return dict(backupSchedule=inst) -class Controller(wsgi.Controller): +class Controller(common.OpenstackController): """ The backup schedule API controller for the Openstack API """ _serialization_metadata = { diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py index 75aeb0a5f..234f921ab 100644 --- a/nova/api/openstack/common.py +++ b/nova/api/openstack/common.py @@ -22,6 +22,7 @@ import webob from nova import exception from nova import flags from nova import log as logging +from nova import wsgi LOG = logging.getLogger('common') @@ -30,6 +31,10 @@ LOG = logging.getLogger('common') FLAGS = flags.FLAGS +XML_NS_V10 = 'http://docs.rackspacecloud.com/servers/api/v1.0' +XML_NS_V11 = 'http://docs.openstack.org/compute/api/v1.1' + + def limited(items, request, max_limit=FLAGS.osapi_max_limit): """ Return a slice of items according to requested offset and limit. @@ -128,3 +133,9 @@ def get_id_from_href(href): except: LOG.debug(_("Error extracting id from href: %s") % href) raise webob.exc.HTTPBadRequest(_('could not parse id from href')) + + +class OpenstackController(wsgi.Controller): + def get_default_xmlns(self, req): + # Use V10 by default + return XML_NS_V10 diff --git a/nova/api/openstack/consoles.py b/nova/api/openstack/consoles.py index 8c291c2eb..1a77f25d7 100644 --- a/nova/api/openstack/consoles.py +++ b/nova/api/openstack/consoles.py @@ -19,7 +19,7 @@ from webob import exc from nova import console from nova import exception -from nova import wsgi +from nova.api.openstack import common from nova.api.openstack import faults @@ -43,7 +43,7 @@ def _translate_detail_keys(cons): return dict(console=info) -class Controller(wsgi.Controller): +class Controller(common.OpenstackController): """The Consoles Controller for the Openstack API""" _serialization_metadata = { diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index fb1dccb28..75f369cac 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -28,6 +28,7 @@ from nova import exception from nova import flags from nova import log as logging from nova import wsgi +from nova.api.openstack import common from nova.api.openstack import faults @@ -115,7 +116,7 @@ class ExtensionDescriptor(object): return response_exts -class ActionExtensionController(wsgi.Controller): +class ActionExtensionController(common.OpenstackController): def __init__(self, application): @@ -136,7 +137,7 @@ class ActionExtensionController(wsgi.Controller): return res -class ResponseExtensionController(wsgi.Controller): +class ResponseExtensionController(common.OpenstackController): def __init__(self, application): self.application = application @@ -163,7 +164,7 @@ class ResponseExtensionController(wsgi.Controller): return res -class ExtensionController(wsgi.Controller): +class ExtensionController(common.OpenstackController): def __init__(self, extension_manager): self.extension_manager = extension_manager diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py index 5b99b5a6f..40787bd17 100644 --- a/nova/api/openstack/flavors.py +++ b/nova/api/openstack/flavors.py @@ -19,11 +19,11 @@ import webob from nova import db from nova import exception -from nova import wsgi +from nova.api.openstack import common from nova.api.openstack import views -class Controller(wsgi.Controller): +class Controller(common.OpenstackController): """Flavor controller for the OpenStack API.""" _serialization_metadata = { @@ -76,3 +76,6 @@ class ControllerV11(Controller): def _get_view_builder(self, req): base_url = req.application_url return views.flavors.ViewBuilderV11(base_url) + + def get_default_xmlns(self, req): + return common.XML_NS_V11 diff --git a/nova/api/openstack/image_metadata.py b/nova/api/openstack/image_metadata.py index c9d6ac532..e673e5f7b 100644 --- a/nova/api/openstack/image_metadata.py +++ b/nova/api/openstack/image_metadata.py @@ -20,13 +20,14 @@ from webob import exc from nova import flags from nova import utils from nova import wsgi +from nova.api.openstack import common from nova.api.openstack import faults FLAGS = flags.FLAGS -class Controller(wsgi.Controller): +class Controller(common.OpenstackController): """The image metadata API controller for the Openstack API""" def __init__(self): diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index e77100d7b..5550ee532 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -32,7 +32,7 @@ LOG = log.getLogger('nova.api.openstack.images') FLAGS = flags.FLAGS -class Controller(wsgi.Controller): +class Controller(common.OpenstackController): """Base `wsgi.Controller` for retrieving/displaying images.""" _serialization_metadata = { @@ -153,3 +153,6 @@ class ControllerV11(Controller): """Property to get the ViewBuilder class we need to use.""" base_url = request.application_url return images_view.ViewBuilderV11(base_url) + + def get_default_xmlns(self, req): + return common.XML_NS_V11 diff --git a/nova/api/openstack/limits.py b/nova/api/openstack/limits.py index efc7d193d..9877af191 100644 --- a/nova/api/openstack/limits.py +++ b/nova/api/openstack/limits.py @@ -31,8 +31,8 @@ from collections import defaultdict from webob.dec import wsgify from nova import wsgi +from nova.api.openstack import common from nova.api.openstack import faults -from nova.wsgi import Controller from nova.wsgi import Middleware @@ -43,7 +43,7 @@ PER_HOUR = 60 * 60 PER_DAY = 60 * 60 * 24 -class LimitsController(Controller): +class LimitsController(common.OpenstackController): """ Controller for accessing limits in the OpenStack API. """ diff --git a/nova/api/openstack/server_metadata.py b/nova/api/openstack/server_metadata.py index 45bbac99d..5c1390b9c 100644 --- a/nova/api/openstack/server_metadata.py +++ b/nova/api/openstack/server_metadata.py @@ -19,10 +19,11 @@ from webob import exc from nova import compute from nova import wsgi +from nova.api.openstack import common from nova.api.openstack import faults -class Controller(wsgi.Controller): +class Controller(common.OpenstackController): """ The server metadata API controller for the Openstack API """ def __init__(self): diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index f7696d918..64090d830 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -44,7 +44,7 @@ LOG = logging.getLogger('server') FLAGS = flags.FLAGS -class Controller(wsgi.Controller): +class Controller(common.OpenstackController): """ The Server API controller for the OpenStack API """ _serialization_metadata = { @@ -632,6 +632,9 @@ class ControllerV11(Controller): def _limit_items(self, items, req): return common.limited_by_marker(items, req) + def get_default_xmlns(self, req): + return common.XML_NS_V11 + class ServerCreateRequestXMLDeserializer(object): """ diff --git a/nova/api/openstack/shared_ip_groups.py b/nova/api/openstack/shared_ip_groups.py index ee7991d7f..996db3648 100644 --- a/nova/api/openstack/shared_ip_groups.py +++ b/nova/api/openstack/shared_ip_groups.py @@ -17,7 +17,7 @@ from webob import exc -from nova import wsgi +from nova.api.openstack import common from nova.api.openstack import faults @@ -32,7 +32,7 @@ def _translate_detail_keys(inst): return dict(sharedIpGroups=inst) -class Controller(wsgi.Controller): +class Controller(common.OpenstackController): """ The Shared IP Groups Controller for the Openstack API """ _serialization_metadata = { diff --git a/nova/api/openstack/users.py b/nova/api/openstack/users.py index d3ab3d553..077ccfc79 100644 --- a/nova/api/openstack/users.py +++ b/nova/api/openstack/users.py @@ -18,7 +18,6 @@ from webob import exc from nova import exception from nova import flags from nova import log as logging -from nova import wsgi from nova.api.openstack import common from nova.api.openstack import faults from nova.auth import manager @@ -35,7 +34,7 @@ def _translate_keys(user): admin=user.admin) -class Controller(wsgi.Controller): +class Controller(common.OpenstackController): _serialization_metadata = { 'application/xml': { diff --git a/nova/api/openstack/zones.py b/nova/api/openstack/zones.py index 846cb48a1..227ffecdc 100644 --- a/nova/api/openstack/zones.py +++ b/nova/api/openstack/zones.py @@ -13,12 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. -import common - from nova import db from nova import flags from nova import log as logging -from nova import wsgi +from nova.api.openstack import common from nova.scheduler import api @@ -43,7 +41,7 @@ def _scrub_zone(zone): 'deleted', 'deleted_at', 'updated_at')) -class Controller(wsgi.Controller): +class Controller(common.OpenstackController): _serialization_metadata = { 'application/xml': { diff --git a/nova/tests/integrated/test_xml.py b/nova/tests/integrated/test_xml.py new file mode 100644 index 000000000..8a9754777 --- /dev/null +++ b/nova/tests/integrated/test_xml.py @@ -0,0 +1,56 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from nova import flags +from nova.log import logging +from nova.tests.integrated import integrated_helpers +from nova.api.openstack import common + + +LOG = logging.getLogger('nova.tests.integrated') + + +FLAGS = flags.FLAGS +FLAGS.verbose = True + + +class XmlTests(integrated_helpers._IntegratedTestBase): + """"Some basic XML sanity checks.""" + + def test_namespace_limits(self): + """/limits should have v1.0 namespace (hasn't changed in 1.1).""" + headers = {} + headers['Accept'] = 'application/xml' + + response = self.api.api_request('/limits', headers=headers) + data = response.read() + LOG.debug("data: %s" % data) + + prefix = ' Date: Wed, 30 Mar 2011 13:18:47 -0400 Subject: Implement quotas for the new v1.1 server metadata controller. Modified the compute API so that metadata is a dict (not an array) to ensure we are using unique key values for metadata. This is isn't explicit in the SPECs but it is implied by the new v1.1 spec since PUT requests modify individual items. Re-enabled the metadata integration test. --- nova/api/openstack/server_metadata.py | 30 ++++++-- nova/api/openstack/servers.py | 12 +--- nova/compute/api.py | 52 ++++++++------ nova/db/sqlalchemy/api.py | 5 +- nova/tests/api/openstack/test_server_metadata.py | 38 ++++++++++ nova/tests/integrated/test_servers.py | 88 ++++++++++++------------ 6 files changed, 139 insertions(+), 86 deletions(-) diff --git a/nova/api/openstack/server_metadata.py b/nova/api/openstack/server_metadata.py index 45bbac99d..2a1249b10 100644 --- a/nova/api/openstack/server_metadata.py +++ b/nova/api/openstack/server_metadata.py @@ -18,6 +18,7 @@ from webob import exc from nova import compute +from nova import quota from nova import wsgi from nova.api.openstack import faults @@ -43,10 +44,13 @@ class Controller(wsgi.Controller): def create(self, req, server_id): context = req.environ['nova.context'] - body = self._deserialize(req.body, req.get_content_type()) - self.compute_api.update_or_create_instance_metadata(context, - server_id, - body['metadata']) + data = self._deserialize(req.body, req.get_content_type())['metadata'] + try: + self.compute_api.update_or_create_instance_metadata(context, + server_id, + data) + except quota.QuotaError as error: + self._handle_quota_error(error) return req.body def update(self, req, server_id, id): @@ -58,9 +62,13 @@ class Controller(wsgi.Controller): if len(body) > 1: expl = _('Request body contains too many items') raise exc.HTTPBadRequest(explanation=expl) - self.compute_api.update_or_create_instance_metadata(context, - server_id, - body) + try: + self.compute_api.update_or_create_instance_metadata(context, + server_id, + body) + except quota.QuotaError as error: + self._handle_quota_error(error) + return req.body def show(self, req, server_id, id): @@ -76,3 +84,11 @@ class Controller(wsgi.Controller): """ Deletes an existing metadata """ context = req.environ['nova.context'] self.compute_api.delete_instance_metadata(context, server_id, id) + + def _handle_quota_error(self, error): + """ + Reraise quota errors as api-specific http exceptions + """ + if error.code == "MetadataLimitExceeded": + raise exc.HTTPBadRequest(explanation=error.message) + raise error diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 6bd173bb8..966680c41 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -134,16 +134,6 @@ class Controller(wsgi.Controller): kernel_id, ramdisk_id = self._get_kernel_ramdisk_from_image( req, image_id) - # Metadata is a list, not a Dictionary, because we allow duplicate keys - # (even though JSON can't encode this) - # In future, we may not allow duplicate keys. - # However, the CloudServers API is not definitive on this front, - # and we want to be compatible. - metadata = [] - if env['server'].get('metadata'): - for k, v in env['server']['metadata'].items(): - metadata.append({'key': k, 'value': v}) - personality = env['server'].get('personality') injected_files = [] if personality: @@ -161,7 +151,7 @@ class Controller(wsgi.Controller): display_description=env['server']['name'], key_name=key_name, key_data=key_data, - metadata=metadata, + metadata=env['server'].get('metadata', {}), injected_files=injected_files) except quota.QuotaError as error: self._handle_quota_error(error) diff --git a/nova/compute/api.py b/nova/compute/api.py index 1dbd73f8f..678900fd9 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -100,26 +100,12 @@ class API(base.Base): if len(content) > content_limit: raise quota.QuotaError(code="OnsetFileContentLimitExceeded") - def create(self, context, instance_type, - image_id, kernel_id=None, ramdisk_id=None, - min_count=1, max_count=1, - display_name='', display_description='', - key_name=None, key_data=None, security_group='default', - availability_zone=None, user_data=None, metadata=[], - injected_files=None): - """Create the number of instances requested if quota and - other arguments check out ok.""" - - type_data = instance_types.get_instance_type(instance_type) - num_instances = quota.allowed_instances(context, max_count, type_data) - if num_instances < min_count: - pid = context.project_id - LOG.warn(_("Quota exceeeded for %(pid)s," - " tried to run %(min_count)s instances") % locals()) - raise quota.QuotaError(_("Instance quota exceeded. You can only " - "run %s more instances of this type.") % - num_instances, "InstanceLimitExceeded") + def _check_metadata_properties_quota(self, context, metadata={}): + """ + Enforce quota limits on metadata properties + Raises a QuotaError if any limit is exceeded + """ num_metadata = len(metadata) quota_metadata = quota.allowed_metadata_items(context, num_metadata) if quota_metadata < num_metadata: @@ -133,9 +119,7 @@ class API(base.Base): # Because metadata is stored in the DB, we hard-code the size limits # In future, we may support more variable length strings, so we act # as if this is quota-controlled for forwards compatibility - for metadata_item in metadata: - k = metadata_item['key'] - v = metadata_item['value'] + for k, v in metadata.iteritems(): if len(k) > 255 or len(v) > 255: pid = context.project_id msg = (_("Quota exceeeded for %(pid)s," @@ -144,6 +128,27 @@ class API(base.Base): LOG.warn(msg) raise quota.QuotaError(msg, "MetadataLimitExceeded") + def create(self, context, instance_type, + image_id, kernel_id=None, ramdisk_id=None, + min_count=1, max_count=1, + display_name='', display_description='', + key_name=None, key_data=None, security_group='default', + availability_zone=None, user_data=None, metadata={}, + injected_files=None): + """Create the number of instances requested if quota and + other arguments check out ok.""" + + type_data = instance_types.get_instance_type(instance_type) + num_instances = quota.allowed_instances(context, max_count, type_data) + if num_instances < min_count: + pid = context.project_id + LOG.warn(_("Quota exceeeded for %(pid)s," + " tried to run %(min_count)s instances") % locals()) + raise quota.QuotaError(_("Instance quota exceeded. You can only " + "run %s more instances of this type.") % + num_instances, "InstanceLimitExceeded") + + self._check_metadata_properties_quota(context, metadata) self._check_injected_file_quota(context, injected_files) image = self.image_service.show(context, image_id) @@ -705,5 +710,8 @@ class API(base.Base): def update_or_create_instance_metadata(self, context, instance_id, metadata): """Updates or creates instance metadata""" + combined_metadata = self.get_instance_metadata(context, instance_id) + combined_metadata.update(metadata) + self._check_metadata_properties_quota(context, combined_metadata) self.db.instance_metadata_update_or_create(context, instance_id, metadata) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index b2a13a01b..b591eb871 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -768,9 +768,10 @@ def instance_create(context, values): metadata = values.get('metadata') metadata_refs = [] if metadata: - for metadata_item in metadata: + for k, v in metadata.iteritems(): metadata_ref = models.InstanceMetadata() - metadata_ref.update(metadata_item) + metadata_ref['key'] = k + metadata_ref['value'] = v metadata_refs.append(metadata_ref) values['metadata'] = metadata_refs diff --git a/nova/tests/api/openstack/test_server_metadata.py b/nova/tests/api/openstack/test_server_metadata.py index c8d456472..3ae97c2ef 100644 --- a/nova/tests/api/openstack/test_server_metadata.py +++ b/nova/tests/api/openstack/test_server_metadata.py @@ -21,11 +21,17 @@ import unittest import webob +from nova import flags from nova.api import openstack from nova.tests.api.openstack import fakes import nova.wsgi +FLAGS = flags.FLAGS + +def return_create_instance_metadata_max(context, server_id, metadata): + return stub_max_server_metadata() + def return_create_instance_metadata(context, server_id, metadata): return stub_server_metadata() @@ -53,6 +59,12 @@ def stub_server_metadata(): return metadata +def stub_max_server_metadata(): + metadata = {"metadata": {}} + for num in range(FLAGS.quota_metadata_items): + metadata['metadata']['key%i' % num] = "blah" + return metadata + class ServerMetaDataTest(unittest.TestCase): def setUp(self): @@ -162,3 +174,29 @@ class ServerMetaDataTest(unittest.TestCase): req.headers["content-type"] = "application/json" res = req.get_response(fakes.wsgi_app()) self.assertEqual(400, res.status_int) + + def test_too_many_metadata_items_on_create(self): + self.stubs.Set(nova.db.api, 'instance_metadata_update_or_create', + return_create_instance_metadata) + data = {"metadata": {}} + for num in range(FLAGS.quota_metadata_items + 1): + data['metadata']['key%i' % num] = "blah" + json_string = str(data).replace("\'", "\"") + req = webob.Request.blank('/v1.1/servers/1/meta') + req.environ['api.version'] = '1.1' + req.method = 'POST' + req.body = json_string + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(400, res.status_int) + + def test_to_many_metadata_items_on_update_item(self): + self.stubs.Set(nova.db.api, 'instance_metadata_update_or_create', + return_create_instance_metadata_max) + req = webob.Request.blank('/v1.1/servers/1/meta/key1') + req.environ['api.version'] = '1.1' + req.method = 'PUT' + req.body = '{"a new key": "a new value"}' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(400, res.status_int) diff --git a/nova/tests/integrated/test_servers.py b/nova/tests/integrated/test_servers.py index 749ea8955..8175659a3 100644 --- a/nova/tests/integrated/test_servers.py +++ b/nova/tests/integrated/test_servers.py @@ -134,50 +134,50 @@ class ServersTest(integrated_helpers._IntegratedTestBase): # Should be gone self.assertFalse(found_server) -# TODO(justinsb): Enable this unit test when the metadata bug is fixed -# def test_create_server_with_metadata(self): -# """Creates a server with metadata""" -# -# # Build the server data gradually, checking errors along the way -# server = self._build_minimal_create_server_request() -# -# for metadata_count in range(30): -# metadata = {} -# for i in range(metadata_count): -# metadata['key_%s' % i] = 'value_%s' % i -# server['metadata'] = metadata -# -# post = {'server': server} -# created_server = self.api.post_server(post) -# LOG.debug("created_server: %s" % created_server) -# self.assertTrue(created_server['id']) -# created_server_id = created_server['id'] -# # Reenable when bug fixed -# # self.assertEqual(metadata, created_server.get('metadata')) -# -# # Check it's there -# found_server = self.api.get_server(created_server_id) -# self.assertEqual(created_server_id, found_server['id']) -# self.assertEqual(metadata, found_server.get('metadata')) -# -# # The server should also be in the all-servers details list -# servers = self.api.get_servers(detail=True) -# server_map = dict((server['id'], server) for server in servers) -# found_server = server_map.get(created_server_id) -# self.assertTrue(found_server) -# # Details do include metadata -# self.assertEqual(metadata, found_server.get('metadata')) -# -# # The server should also be in the all-servers summary list -# servers = self.api.get_servers(detail=False) -# server_map = dict((server['id'], server) for server in servers) -# found_server = server_map.get(created_server_id) -# self.assertTrue(found_server) -# # Summary should not include metadata -# self.assertFalse(found_server.get('metadata')) -# -# # Cleanup -# self._delete_server(created_server_id) + def test_create_server_with_metadata(self): + """Creates a server with metadata""" + + # Build the server data gradually, checking errors along the way + server = self._build_minimal_create_server_request() + + metadata = {} + for i in range(30): + metadata['key_%s' % i] = 'value_%s' % i + + server['metadata'] = metadata + + post = {'server': server} + created_server = self.api.post_server(post) + LOG.debug("created_server: %s" % created_server) + self.assertTrue(created_server['id']) + created_server_id = created_server['id'] + + # Reenable when bug fixed + self.assertEqual(metadata, created_server.get('metadata')) + # Check it's there + + found_server = self.api.get_server(created_server_id) + self.assertEqual(created_server_id, found_server['id']) + self.assertEqual(metadata, found_server.get('metadata')) + + # The server should also be in the all-servers details list + servers = self.api.get_servers(detail=True) + server_map = dict((server['id'], server) for server in servers) + found_server = server_map.get(created_server_id) + self.assertTrue(found_server) + # Details do include metadata + self.assertEqual(metadata, found_server.get('metadata')) + + # The server should also be in the all-servers summary list + servers = self.api.get_servers(detail=False) + server_map = dict((server['id'], server) for server in servers) + found_server = server_map.get(created_server_id) + self.assertTrue(found_server) + # Summary should not include metadata + self.assertFalse(found_server.get('metadata')) + + # Cleanup + self._delete_server(created_server_id) if __name__ == "__main__": -- cgit From 23776e5b2bdb73df10be590b589c34788c28023a Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Wed, 30 Mar 2011 12:28:09 -0500 Subject: Avoid hard dependencies --- nova/virt/vmwareapi_conn.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py index 87c3fa299..34d29a4e5 100644 --- a/nova/virt/vmwareapi_conn.py +++ b/nova/virt/vmwareapi_conn.py @@ -43,10 +43,12 @@ from nova import flags from nova import log as logging from nova import utils from nova.virt.vmwareapi import error_util -from nova.virt.vmwareapi import vim from nova.virt.vmwareapi import vim_util from nova.virt.vmwareapi.vmops import VMWareVMOps + +vim = None + LOG = logging.getLogger("nova.virt.vmwareapi_conn") FLAGS = flags.FLAGS @@ -78,6 +80,13 @@ flags.DEFINE_string('vmwareapi_vlan_interface', TIME_BETWEEN_API_CALL_RETRIES = 2.0 +def get_imported_vim(): + """Avoid any hard dependencies.""" + global vim + if vim is None: + vim = __import__("nova.virt.vmwareapi.vim") + + class Failure(Exception): """Base Exception class for handling task failures.""" @@ -109,7 +118,7 @@ class VMWareESXConnection(object): def __init__(self, host_ip, host_username, host_password, api_retry_count, scheme="https"): session = VMWareAPISession(host_ip, host_username, host_password, - api_retry_count, scheme=scheme) + api_retry_count, scheme=scheme) self._vmops = VMWareVMOps(session) def init_host(self, host): @@ -204,6 +213,7 @@ class VMWareAPISession(object): self._session_id = None self.vim = None self._create_session() + get_imported_vim() def _get_vim_object(self): """Create the VIM Object instance.""" -- cgit From 82759db16019509b9ca77fb7d86015d29c598f70 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Wed, 30 Mar 2011 13:34:45 -0400 Subject: pep8 fixes. --- nova/tests/api/openstack/test_server_metadata.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nova/tests/api/openstack/test_server_metadata.py b/nova/tests/api/openstack/test_server_metadata.py index 3ae97c2ef..fc51370f6 100644 --- a/nova/tests/api/openstack/test_server_metadata.py +++ b/nova/tests/api/openstack/test_server_metadata.py @@ -29,9 +29,11 @@ import nova.wsgi FLAGS = flags.FLAGS + def return_create_instance_metadata_max(context, server_id, metadata): return stub_max_server_metadata() + def return_create_instance_metadata(context, server_id, metadata): return stub_server_metadata() @@ -65,6 +67,7 @@ def stub_max_server_metadata(): metadata['metadata']['key%i' % num] = "blah" return metadata + class ServerMetaDataTest(unittest.TestCase): def setUp(self): -- cgit From ee709d39e6c66ec4aad722fb20951ae9d714f259 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Wed, 30 Mar 2011 10:41:22 -0700 Subject: Some tests actually tested for the lack of a namespace :-) --- nova/api/openstack/extensions.py | 3 ++- nova/api/openstack/faults.py | 5 +++-- nova/api/openstack/images.py | 3 --- nova/tests/api/openstack/test_images.py | 16 +++++++++++----- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index 75f369cac..7ea7afef6 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -156,7 +156,8 @@ class ResponseExtensionController(common.OpenstackController): body = res.body headers = res.headers except AttributeError: - body = self._serialize(res, content_type) + default_xmlns = None + body = self._serialize(res, content_type, default_xmlns) headers = {"Content-Type": content_type} res = webob.Response() res.body = body diff --git a/nova/api/openstack/faults.py b/nova/api/openstack/faults.py index 0e9c4b26f..a05e97021 100644 --- a/nova/api/openstack/faults.py +++ b/nova/api/openstack/faults.py @@ -20,10 +20,10 @@ import webob.dec import webob.exc from nova import wsgi +from nova.api.openstack import common class Fault(webob.exc.HTTPException): - """An RS API fault response.""" _fault_names = { @@ -57,7 +57,8 @@ class Fault(webob.exc.HTTPException): fault_data[fault_name]['retryAfter'] = retry # 'code' is an attribute on the fault tag itself metadata = {'application/xml': {'attributes': {fault_name: 'code'}}} - serializer = wsgi.Serializer(metadata) + default_xmlns = common.XML_NS_V10 + serializer = wsgi.Serializer(metadata, default_xmlns) content_type = req.best_match_content_type() self.wrapped_exc.body = serializer.serialize(fault_data, content_type) return self.wrapped_exc diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index 5550ee532..77baf5947 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -13,8 +13,6 @@ # License for the specific language governing permissions and limitations # under the License. -import datetime - import webob.exc from nova import compute @@ -22,7 +20,6 @@ from nova import exception from nova import flags from nova import log from nova import utils -from nova import wsgi from nova.api.openstack import common from nova.api.openstack import faults from nova.api.openstack.views import images as images_view diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index 57e447dce..ff3fe8976 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -146,7 +146,7 @@ class LocalImageServiceTest(_BaseImageServiceTests): for x in [1, 2, 3]: tempfile.mkstemp(prefix='ami-', dir=self.tempdir) # create some valid image directories names - for x in ["1485baed", "1a60f0ee", "3123a73d"]: + for x in ["1485baed", "1a60f0ee", "3123a73d"]: os.makedirs(os.path.join(self.tempdir, x)) found_image_ids = self.service._ids() self.assertEqual(True, isinstance(found_image_ids, list)) @@ -334,7 +334,8 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): name="public image" updated="%(expected_now)s" created="%(expected_now)s" - status="ACTIVE" /> + status="ACTIVE" + xmlns="http://docs.rackspacecloud.com/servers/api/v1.0" /> """ % (locals())) self.assertEqual(expected_image.toxml(), actual_image.toxml()) @@ -353,7 +354,8 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): name="public image" updated="%(expected_now)s" created="%(expected_now)s" - status="ACTIVE"> + status="ACTIVE" + xmlns="http://docs.openstack.org/compute/api/v1.1"> + Image not found. @@ -422,8 +425,11 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): response = request.get_response(fakes.wsgi_app()) self.assertEqual(404, response.status_int) + # NOTE(justinsb): I believe this should still use the v1.0 XSD, + # because the element hasn't changed definition expected = minidom.parseString(""" - + Image not found. -- cgit From d2aa73efed6f4eb731c4fe8dca3f4ceb5b36caeb Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Wed, 30 Mar 2011 10:49:09 -0700 Subject: More tests that were checking for no-namespace --- nova/tests/api/openstack/test_faults.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/nova/tests/api/openstack/test_faults.py b/nova/tests/api/openstack/test_faults.py index 7667753f4..505e7e308 100644 --- a/nova/tests/api/openstack/test_faults.py +++ b/nova/tests/api/openstack/test_faults.py @@ -20,6 +20,7 @@ import webob.dec import webob.exc from nova import test +from nova.api.openstack import common from nova.api.openstack import faults @@ -30,8 +31,11 @@ class TestFaults(test.TestCase): f = faults.Fault(webob.exc.HTTPBadRequest(explanation='scram')) resp = req.get_response(f) - first_two_words = resp.body.strip().split()[:2] - self.assertEqual(first_two_words, ['']) + first_three_words = resp.body.strip().split()[:3] + self.assertEqual(first_three_words, + ['' % common.XML_NS_V10]) body_without_spaces = ''.join(resp.body.split()) self.assertTrue('scram' in body_without_spaces) @@ -41,8 +45,11 @@ class TestFaults(test.TestCase): headers={'Retry-After': 4}) f = faults.Fault(exc) resp = req.get_response(f) - first_two_words = resp.body.strip().split()[:2] - self.assertEqual(first_two_words, ['']) + first_three_words = resp.body.strip().split()[:3] + self.assertEqual(first_three_words, + ['' % common.XML_NS_V10]) body_sans_spaces = ''.join(resp.body.split()) self.assertTrue('sorry' in body_sans_spaces) self.assertTrue('4' in body_sans_spaces) -- cgit From 168fdb09f369287f3ec8c19ef73915280ff79d20 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Wed, 30 Mar 2011 11:15:16 -0700 Subject: Refixed unit test to check XML ns --- nova/tests/api/openstack/test_faults.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nova/tests/api/openstack/test_faults.py b/nova/tests/api/openstack/test_faults.py index b3433f45f..4d86ffb26 100644 --- a/nova/tests/api/openstack/test_faults.py +++ b/nova/tests/api/openstack/test_faults.py @@ -48,10 +48,10 @@ class TestFaults(test.TestCase): response = request.get_response(fault) expected = self._prepare_xml(""" - + scram - """) + """ % common.XML_NS_V10) actual = self._prepare_xml(response.body) self.assertEqual(response.content_type, "application/xml") @@ -92,11 +92,11 @@ class TestFaults(test.TestCase): response = request.get_response(fault) expected = self._prepare_xml(""" - + sorry 4 - """) + """ % common.XML_NS_V10) actual = self._prepare_xml(response.body) self.assertEqual(expected, actual) -- cgit From be4be55bf03c907f46e76fffe3457743915d734a Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Wed, 30 Mar 2011 13:50:02 -0500 Subject: Handle in vim.py --- nova/virt/vmwareapi/vim.py | 15 +++++++++++---- nova/virt/vmwareapi_conn.py | 10 ---------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/nova/virt/vmwareapi/vim.py b/nova/virt/vmwareapi/vim.py index ba14f1512..1c850595d 100644 --- a/nova/virt/vmwareapi/vim.py +++ b/nova/virt/vmwareapi/vim.py @@ -21,10 +21,14 @@ Classes for making VMware VI SOAP calls. import httplib -from suds import WebFault -from suds.client import Client -from suds.plugin import MessagePlugin -from suds.sudsobject import Property +try: + suds = True + from suds import WebFault + from suds.client import Client + from suds.plugin import MessagePlugin + from suds.sudsobject import Property +except ImportError: + suds = False from nova import flags from nova.virt.vmwareapi import error_util @@ -75,6 +79,9 @@ class Vim: protocol: http or https host : ESX IPAddress[:port] or ESX Hostname[:port] """ + if not suds: + raise Exception(_("Unable to import suds.")) + self._protocol = protocol self._host_name = host wsdl_url = FLAGS.vmwareapi_wsdl_loc diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py index 34d29a4e5..b909e659d 100644 --- a/nova/virt/vmwareapi_conn.py +++ b/nova/virt/vmwareapi_conn.py @@ -47,8 +47,6 @@ from nova.virt.vmwareapi import vim_util from nova.virt.vmwareapi.vmops import VMWareVMOps -vim = None - LOG = logging.getLogger("nova.virt.vmwareapi_conn") FLAGS = flags.FLAGS @@ -80,13 +78,6 @@ flags.DEFINE_string('vmwareapi_vlan_interface', TIME_BETWEEN_API_CALL_RETRIES = 2.0 -def get_imported_vim(): - """Avoid any hard dependencies.""" - global vim - if vim is None: - vim = __import__("nova.virt.vmwareapi.vim") - - class Failure(Exception): """Base Exception class for handling task failures.""" @@ -213,7 +204,6 @@ class VMWareAPISession(object): self._session_id = None self.vim = None self._create_session() - get_imported_vim() def _get_vim_object(self): """Create the VIM Object instance.""" -- cgit From 2eadc55dbd66af7b5adb3c21fe9cc91cd04b0f8b Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Wed, 30 Mar 2011 13:56:02 -0500 Subject: Whoops --- nova/virt/vmwareapi_conn.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py index b909e659d..20c1b2b45 100644 --- a/nova/virt/vmwareapi_conn.py +++ b/nova/virt/vmwareapi_conn.py @@ -43,6 +43,7 @@ from nova import flags from nova import log as logging from nova import utils from nova.virt.vmwareapi import error_util +from nova.virt.vmwareapi import vim from nova.virt.vmwareapi import vim_util from nova.virt.vmwareapi.vmops import VMWareVMOps -- cgit From 323eb60884cf8736448d997068d32f252d22e7f3 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 30 Mar 2011 12:05:25 -0700 Subject: Key type values in ec2_api off of container format --- nova/api/ec2/cloud.py | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 7ba8dfbea..1e6c4d1db 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -146,7 +146,7 @@ class CloudController(object): floating_ip = db.instance_get_floating_address(ctxt, instance_ref['id']) ec2_id = ec2utils.id_to_ec2_id(instance_ref['id']) - image_ec2_id = self._image_ec2_id(instance_ref['image_id'], 'machine') + image_ec2_id = self._image_ec2_id(instance_ref['image_id'], 'ami') data = { 'user-data': base64.b64decode(instance_ref['user_data']), 'meta-data': { @@ -176,7 +176,7 @@ class CloudController(object): for image_type in ['kernel', 'ramdisk']: if '%s_id' % image_type in instance_ref: ec2_id = self._image_ec2_id(instance_ref['%s_id' % image_type], - image_type) + self._image_type(image_type)) data['meta-data']['%s-id' % image_type] = ec2_id if False: # TODO(vish): store ancestor ids @@ -862,13 +862,27 @@ class CloudController(object): self.compute_api.update(context, instance_id=instance_id, **kwargs) return True - _type_prefix_map = {'machine': 'ami', - 'kernel': 'aki', - 'ramdisk': 'ari'} + @staticmethod + def _image_type(image_type): + """Converts to a three letter image type. - def _image_ec2_id(self, image_id, image_type='machine'): - prefix = self._type_prefix_map[image_type] - template = prefix + '-%08x' + aki, kernel => aki + ari, ramdisk => ari + anything else => ami + + """ + if image_type == 'kernel': + return 'aki' + if image_type == 'ramdisk': + return 'ari' + if image_type not in ['aki', 'ari']: + return 'ami' + return image_type + + @staticmethod + def _image_ec2_id(image_id, image_type='ami'): + """Returns image ec2_id using id and three letter type""" + template = image_type + '-%08x' return ec2utils.id_to_ec2_id(int(image_id), template=template) def _get_image(self, context, ec2_id): @@ -881,7 +895,7 @@ class CloudController(object): def _format_image(self, image): """Convert from format defined by BaseImageService to S3 format.""" i = {} - image_type = image['properties'].get('type') + image_type = self._image_type(image.get('container_format')) ec2_id = self._image_ec2_id(image.get('id'), image_type) name = image.get('name') if name: @@ -890,16 +904,19 @@ class CloudController(object): i['imageId'] = ec2_id kernel_id = image['properties'].get('kernel_id') if kernel_id: - i['kernelId'] = self._image_ec2_id(kernel_id, 'kernel') + i['kernelId'] = self._image_ec2_id(kernel_id, 'aki') ramdisk_id = image['properties'].get('ramdisk_id') if ramdisk_id: - i['ramdiskId'] = self._image_ec2_id(ramdisk_id, 'ramdisk') + i['ramdiskId'] = self._image_ec2_id(ramdisk_id, 'ari') i['imageOwnerId'] = image['properties'].get('owner_id') i['imageLocation'] = image['properties'].get('image_location') i['imageState'] = image['properties'].get('image_state') i['displayName'] = image.get('name') i['description'] = image.get('description') - i['type'] = image_type + display_mapping = {'aki': 'kernel', + 'ari': 'ramdisk', + 'ami': 'machine'} + i['type'] = display_mapping.get(image_type) i['isPublic'] = str(image['properties'].get('is_public', '')) == 'True' i['architecture'] = image['properties'].get('architecture') return i @@ -932,8 +949,9 @@ class CloudController(object): image_location = kwargs['name'] metadata = {'properties': {'image_location': image_location}} image = self.image_service.create(context, metadata) + image_type = self._image_type(image.get('container_format')) image_id = self._image_ec2_id(image['id'], - image['properties']['type']) + image_type) msg = _("Registered image %(image_location)s with" " id %(image_id)s") % locals() LOG.audit(msg, context=context) -- cgit From 1703592992ebdd5bbf19952f79f05022a4cdc849 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 30 Mar 2011 12:34:10 -0700 Subject: remove all references to image_type and change nova-manage upload to set container format more intelligently --- bin/nova-manage | 27 +++++++++++++------------ nova/api/openstack/servers.py | 2 +- nova/image/fake.py | 6 +++--- nova/image/s3.py | 1 - nova/tests/api/openstack/test_image_metadata.py | 2 -- nova/virt/libvirt_conn.py | 1 - 6 files changed, 18 insertions(+), 21 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 6789efba8..4e14b6cab 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -894,20 +894,18 @@ class ImageCommands(object): def __init__(self, *args, **kwargs): self.image_service = utils.import_object(FLAGS.image_service) - def _register(self, image_type, disk_format, container_format, + def _register(self, container_format, disk_format, path, owner, name=None, is_public='T', architecture='x86_64', kernel_id=None, ramdisk_id=None): meta = {'is_public': True, 'name': name, - 'disk_format': disk_format, 'container_format': container_format, + 'disk_format': disk_format, 'properties': {'image_state': 'available', 'owner_id': owner, - 'type': image_type, 'architecture': architecture, 'image_location': 'local', 'is_public': (is_public == 'T')}} - print image_type, meta if kernel_id: meta['properties']['kernel_id'] = int(kernel_id) if ramdisk_id: @@ -932,16 +930,17 @@ class ImageCommands(object): ramdisk_id = self.ramdisk_register(ramdisk, owner, None, is_public, architecture) self.image_register(image, owner, name, is_public, - architecture, kernel_id, ramdisk_id) + architecture, 'ami', 'ami', + kernel_id, ramdisk_id) def image_register(self, path, owner, name=None, is_public='T', - architecture='x86_64', kernel_id=None, ramdisk_id=None, - disk_format='ami', container_format='ami'): + architecture='x86_64', container_format='bare', + disk_format='raw', kernel_id=None, ramdisk_id=None): """Uploads an image into the image_service arguments: path owner [name] [is_public='T'] [architecture='x86_64'] - [kernel_id=None] [ramdisk_id=None] - [disk_format='ami'] [container_format='ami']""" - return self._register('machine', disk_format, container_format, path, + [container_format='bare'] [disk_format='raw'] + [kernel_id=None] [ramdisk_id=None]""" + return self._register(container_format, disk_format, path, owner, name, is_public, architecture, kernel_id, ramdisk_id) @@ -950,7 +949,7 @@ class ImageCommands(object): """Uploads a kernel into the image_service arguments: path owner [name] [is_public='T'] [architecture='x86_64'] """ - return self._register('kernel', 'aki', 'aki', path, owner, name, + return self._register('aki', 'aki', path, owner, name, is_public, architecture) def ramdisk_register(self, path, owner, name=None, is_public='T', @@ -958,7 +957,7 @@ class ImageCommands(object): """Uploads a ramdisk into the image_service arguments: path owner [name] [is_public='T'] [architecture='x86_64'] """ - return self._register('ramdisk', 'ari', 'ari', path, owner, name, + return self._register('ari', 'ari', path, owner, name, is_public, architecture) def _lookup(self, old_image_id): @@ -975,6 +974,9 @@ class ImageCommands(object): 'ramdisk': 'ari'} container_format = mapping[old['type']] disk_format = container_format + if container_format == 'ami' and not old.get('kernelId'): + container_format = 'bare' + disk_format = 'raw' new = {'disk_format': disk_format, 'container_format': container_format, 'is_public': True, @@ -982,7 +984,6 @@ class ImageCommands(object): 'properties': {'image_state': old['imageState'], 'owner_id': old['imageOwnerId'], 'architecture': old['architecture'], - 'type': old['type'], 'image_location': old['imageLocation'], 'is_public': old['isPublic']}} if old.get('kernelId'): diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index f7696d918..d640e8684 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -562,7 +562,7 @@ class Controller(wsgi.Controller): _("Cannot build from image %(image_id)s, status not active") % locals()) - if image_meta['properties']['disk_format'] != 'ami': + if image_meta.get('container_format') != 'ami': return None, None try: diff --git a/nova/image/fake.py b/nova/image/fake.py index 08302d6eb..d1c62757f 100644 --- a/nova/image/fake.py +++ b/nova/image/fake.py @@ -44,10 +44,10 @@ class FakeImageService(service.BaseImageService): 'created_at': timestamp, 'updated_at': timestamp, 'status': 'active', - 'type': 'machine', + 'container_format': 'ami', + 'disk_format': 'raw', 'properties': {'kernel_id': FLAGS.null_kernel, - 'ramdisk_id': FLAGS.null_kernel, - 'disk_format': 'ami'} + 'ramdisk_id': FLAGS.null_kernel} } self.create(None, image) super(FakeImageService, self).__init__() diff --git a/nova/image/s3.py b/nova/image/s3.py index ddec5f3aa..203bedc49 100644 --- a/nova/image/s3.py +++ b/nova/image/s3.py @@ -177,7 +177,6 @@ class S3ImageService(service.BaseImageService): properties['ramdisk_id'] = ec2utils.ec2_id_to_id(ramdisk_id) properties['is_public'] = False - properties['type'] = image_type metadata.update({'disk_format': image_format, 'container_format': image_format, 'status': 'queued', diff --git a/nova/tests/api/openstack/test_image_metadata.py b/nova/tests/api/openstack/test_image_metadata.py index 9be753f84..7c3287006 100644 --- a/nova/tests/api/openstack/test_image_metadata.py +++ b/nova/tests/api/openstack/test_image_metadata.py @@ -45,7 +45,6 @@ class ImageMetaDataTest(unittest.TestCase): 'is_public': True, 'deleted_at': None, 'properties': { - 'type': 'ramdisk', 'key1': 'value1', 'key2': 'value2' }, @@ -62,7 +61,6 @@ class ImageMetaDataTest(unittest.TestCase): 'is_public': True, 'deleted_at': None, 'properties': { - 'type': 'ramdisk', 'key1': 'value1', 'key2': 'value2' }, diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index f34ea7225..adcb2ffa3 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -424,7 +424,6 @@ class LibvirtConnection(driver.ComputeDriver): 'container_format': base['container_format'], 'is_public': False, 'properties': {'architecture': base['architecture'], - 'type': base['type'], 'name': '%s.%s' % (base['name'], image_id), 'kernel_id': instance['kernel_id'], 'image_location': 'snapshot', -- cgit From c29dc77c6f42c5a345ee6b510a373236d7988440 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 30 Mar 2011 12:46:22 -0700 Subject: fixed ordering and spacing --- nova/compute/api.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index a5f6afb02..996955fe3 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -37,8 +37,11 @@ from nova.compute import instance_types from nova.scheduler import api as scheduler_api from nova.db import base -FLAGS = flags.FLAGS + LOG = logging.getLogger('nova.compute.api') + + +FLAGS = flags.FLAGS flags.DECLARE('vncproxy_topic', 'nova.vnc') -- cgit From 176d98aa179b174c4e4a5621f723ef7b9145e3cb Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Wed, 30 Mar 2011 15:47:12 -0400 Subject: Update docstrings and spacing. --- nova/api/openstack/server_metadata.py | 4 +--- nova/compute/api.py | 6 +----- nova/tests/api/openstack/test_server_metadata.py | 22 +++++++++++----------- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/nova/api/openstack/server_metadata.py b/nova/api/openstack/server_metadata.py index 2a1249b10..618665082 100644 --- a/nova/api/openstack/server_metadata.py +++ b/nova/api/openstack/server_metadata.py @@ -86,9 +86,7 @@ class Controller(wsgi.Controller): self.compute_api.delete_instance_metadata(context, server_id, id) def _handle_quota_error(self, error): - """ - Reraise quota errors as api-specific http exceptions - """ + """Reraise quota errors as api-specific http exceptions""" if error.code == "MetadataLimitExceeded": raise exc.HTTPBadRequest(explanation=error.message) raise error diff --git a/nova/compute/api.py b/nova/compute/api.py index 678900fd9..c4aa581be 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -101,11 +101,7 @@ class API(base.Base): raise quota.QuotaError(code="OnsetFileContentLimitExceeded") def _check_metadata_properties_quota(self, context, metadata={}): - """ - Enforce quota limits on metadata properties - - Raises a QuotaError if any limit is exceeded - """ + """Enforce quota limits on metadata properties""" num_metadata = len(metadata) quota_metadata = quota.allowed_metadata_items(context, num_metadata) if quota_metadata < num_metadata: diff --git a/nova/tests/api/openstack/test_server_metadata.py b/nova/tests/api/openstack/test_server_metadata.py index fc51370f6..862e14b7c 100644 --- a/nova/tests/api/openstack/test_server_metadata.py +++ b/nova/tests/api/openstack/test_server_metadata.py @@ -84,7 +84,7 @@ class ServerMetaDataTest(unittest.TestCase): def test_index(self): self.stubs.Set(nova.db.api, 'instance_metadata_get', - return_server_metadata) + return_server_metadata) req = webob.Request.blank('/v1.1/servers/1/meta') req.environ['api.version'] = '1.1' res = req.get_response(fakes.wsgi_app()) @@ -94,7 +94,7 @@ class ServerMetaDataTest(unittest.TestCase): def test_index_no_data(self): self.stubs.Set(nova.db.api, 'instance_metadata_get', - return_empty_server_metadata) + return_empty_server_metadata) req = webob.Request.blank('/v1.1/servers/1/meta') req.environ['api.version'] = '1.1' res = req.get_response(fakes.wsgi_app()) @@ -104,7 +104,7 @@ class ServerMetaDataTest(unittest.TestCase): def test_show(self): self.stubs.Set(nova.db.api, 'instance_metadata_get', - return_server_metadata) + return_server_metadata) req = webob.Request.blank('/v1.1/servers/1/meta/key5') req.environ['api.version'] = '1.1' res = req.get_response(fakes.wsgi_app()) @@ -114,7 +114,7 @@ class ServerMetaDataTest(unittest.TestCase): def test_show_meta_not_found(self): self.stubs.Set(nova.db.api, 'instance_metadata_get', - return_empty_server_metadata) + return_empty_server_metadata) req = webob.Request.blank('/v1.1/servers/1/meta/key6') req.environ['api.version'] = '1.1' res = req.get_response(fakes.wsgi_app()) @@ -123,7 +123,7 @@ class ServerMetaDataTest(unittest.TestCase): def test_delete(self): self.stubs.Set(nova.db.api, 'instance_metadata_delete', - delete_server_metadata) + delete_server_metadata) req = webob.Request.blank('/v1.1/servers/1/meta/key5') req.environ['api.version'] = '1.1' req.method = 'DELETE' @@ -132,7 +132,7 @@ class ServerMetaDataTest(unittest.TestCase): def test_create(self): self.stubs.Set(nova.db.api, 'instance_metadata_update_or_create', - return_create_instance_metadata) + return_create_instance_metadata) req = webob.Request.blank('/v1.1/servers/1/meta') req.environ['api.version'] = '1.1' req.method = 'POST' @@ -145,7 +145,7 @@ class ServerMetaDataTest(unittest.TestCase): def test_update_item(self): self.stubs.Set(nova.db.api, 'instance_metadata_update_or_create', - return_create_instance_metadata) + return_create_instance_metadata) req = webob.Request.blank('/v1.1/servers/1/meta/key1') req.environ['api.version'] = '1.1' req.method = 'PUT' @@ -158,7 +158,7 @@ class ServerMetaDataTest(unittest.TestCase): def test_update_item_too_many_keys(self): self.stubs.Set(nova.db.api, 'instance_metadata_update_or_create', - return_create_instance_metadata) + return_create_instance_metadata) req = webob.Request.blank('/v1.1/servers/1/meta/key1') req.environ['api.version'] = '1.1' req.method = 'PUT' @@ -169,7 +169,7 @@ class ServerMetaDataTest(unittest.TestCase): def test_update_item_body_uri_mismatch(self): self.stubs.Set(nova.db.api, 'instance_metadata_update_or_create', - return_create_instance_metadata) + return_create_instance_metadata) req = webob.Request.blank('/v1.1/servers/1/meta/bad') req.environ['api.version'] = '1.1' req.method = 'PUT' @@ -180,7 +180,7 @@ class ServerMetaDataTest(unittest.TestCase): def test_too_many_metadata_items_on_create(self): self.stubs.Set(nova.db.api, 'instance_metadata_update_or_create', - return_create_instance_metadata) + return_create_instance_metadata) data = {"metadata": {}} for num in range(FLAGS.quota_metadata_items + 1): data['metadata']['key%i' % num] = "blah" @@ -195,7 +195,7 @@ class ServerMetaDataTest(unittest.TestCase): def test_to_many_metadata_items_on_update_item(self): self.stubs.Set(nova.db.api, 'instance_metadata_update_or_create', - return_create_instance_metadata_max) + return_create_instance_metadata_max) req = webob.Request.blank('/v1.1/servers/1/meta/key1') req.environ['api.version'] = '1.1' req.method = 'PUT' -- cgit From b54b6c200092054e38af1fa1e5885fe915e53149 Mon Sep 17 00:00:00 2001 From: John Tran Date: Wed, 30 Mar 2011 13:10:11 -0700 Subject: submitting a unit test for terminate_instance --- Authors | 1 + nova/tests/test_cloud.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/Authors b/Authors index eccf38a43..48b912184 100644 --- a/Authors +++ b/Authors @@ -32,6 +32,7 @@ Jesse Andrews Joe Heck Joel Moore John Dewey +John Tran Jonathan Bryce Jordan Rinke Josh Durgin diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 00803d0ad..be1939193 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -36,6 +36,7 @@ from nova import rpc from nova import service from nova import test from nova import utils +from nova import exception from nova.auth import manager from nova.compute import power_state from nova.api.ec2 import cloud @@ -310,6 +311,19 @@ class CloudTestCase(test.TestCase): LOG.debug(_("Terminating instance %s"), instance_id) rv = self.compute.terminate_instance(instance_id) + def test_terminate_instances(self): + inst1 = db.instance_create(self.context, {'reservation_id': 'a', + 'image_id': 1, + 'host': 'host1'}) + terminate_instances = self.cloud.terminate_instances + # valid instance_id + result = terminate_instances(self.context, ['i-00000001']) + self.assertTrue(result) + # non-existing instance_id + self.assertRaises(exception.InstanceNotFound, terminate_instances, + self.context, ['i-2']) + db.instance_destroy(self.context, inst1['id']) + def test_update_of_instance_display_fields(self): inst = db.instance_create(self.context, {}) ec2_id = ec2utils.id_to_ec2_id(inst['id']) -- cgit From a1992ba586acc7545a7edb37130727e19e4d1065 Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Wed, 30 Mar 2011 13:13:04 -0700 Subject: Add ed leafe's code for the inject_file agent plugin method that somehow got lost (fixes bug 741246). Update TimeoutError string for i18n --- plugins/xenserver/xenapi/etc/xapi.d/plugins/agent | 79 +++++++++++++++++++++-- 1 file changed, 75 insertions(+), 4 deletions(-) diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent index 94eaabe73..3522df49d 100755 --- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent +++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent @@ -22,6 +22,7 @@ # XenAPI plugin for reading/writing information to xenstore # +import base64 try: import json except ImportError: @@ -31,6 +32,7 @@ import random import subprocess import tempfile import time +import uuid import XenAPIPlugin @@ -102,6 +104,75 @@ def resetnetwork(self, arg_dict): xenstore.write_record(self, arg_dict) +@jsonify +def inject_file(self, arg_dict): + """Expects a file path and the contents of the file to be written. Both + should be base64-encoded in order to eliminate errors as they are passed + through the stack. Writes that information to xenstore for the agent, + which will decode the file and intended path, and create it on the + instance. The original agent munged both of these into a single entry; + the new agent keeps them separate. We will need to test for the new agent, + and write the xenstore records to match the agent version. We will also + need to test to determine if the file injection method on the agent has + been disabled, and raise a NotImplemented error if that is the case. + """ + b64_path = arg_dict["b64_path"] + b64_file = arg_dict["b64_file"] + request_id = arg_dict["id"] + if self._agent_has_method("file_inject"): + # New version of the agent. Agent should receive a 'value' + # key whose value is a dictionary containing 'b64_path' and + # 'b64_file'. See old version below. + arg_dict["value"] = json.dumps({"name": "file_inject", + "value": {"b64_path": b64_path, "b64_file": b64_file}}) + elif self._agent_has_method("injectfile"): + # Old agent requires file path and file contents to be + # combined into one base64 value. + raw_path = base64.b64decode(b64_path) + raw_file = base64.b64decode(b64_file) + new_b64 = base64.b64encode("%s,%s") % (raw_path, raw_file) + arg_dict["value"] = json.dumps({"name": "injectfile", + "value": new_b64}) + else: + # Either the methods don't exist in the agent, or they + # have been disabled. + raise NotImplementedError("NOT IMPLEMENTED: Agent does not support" + " file injection.") + arg_dict["path"] = "data/host/%s" % request_id + xenstore.write_record(self, arg_dict) + try: + resp = _wait_for_agent(self, request_id, arg_dict) + except TimeoutError, e: + raise PluginError("%s" % e) + return resp + + +def _agent_has_method(self, method): + """Check that the agent has a particular method by checking its + features. Cache the features so we don't have to query the agent + every time we need to check. + """ + try: + self._agent_methods + except AttributeError: + self._agent_methods = [] + if not self._agent_methods: + # Haven't been defined + tmp_id = str(uuid.uuid4()) + dct = {} + dct["value"] = json.dumps({"name": "features", "value": ""}) + dct["path"] = "data/host/%s" % tmp_id + xenstore.write_record(self, dct) + try: + resp = _wait_for_agent(self, tmp_id, dct) + except TimeoutError, e: + raise PluginError("%s" % e) + response = json.loads(resp) + # The agent returns a comma-separated list of methods. + self._agent_methods = response.split(",") + return method in self._agent_methods + + def _wait_for_agent(self, request_id, arg_dict): """Periodically checks xenstore for a response from the agent. The request is always written to 'data/host/{id}', and @@ -119,9 +190,8 @@ def _wait_for_agent(self, request_id, arg_dict): # First, delete the request record arg_dict["path"] = "data/host/%s" % request_id xenstore.delete_record(self, arg_dict) - raise TimeoutError( - "TIMEOUT: No response from agent within %s seconds." % - AGENT_TIMEOUT) + raise TimeoutError(_("TIMEOUT: No response from agent within" + " %s seconds.") % AGENT_TIMEOUT) ret = xenstore.read_record(self, arg_dict) # Note: the response for None with be a string that includes # double quotes. @@ -136,4 +206,5 @@ if __name__ == "__main__": XenAPIPlugin.dispatch( {"key_init": key_init, "password": password, - "resetnetwork": resetnetwork}) + "resetnetwork": resetnetwork, + "inject_file": inject_file}) -- cgit From ba5715b46d82498ed30aa146294850a134022617 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Wed, 30 Mar 2011 13:32:13 -0700 Subject: Fix for LP Bug #745152 --- nova/network/api.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/nova/network/api.py b/nova/network/api.py index 4ee1148cb..424c3f592 100644 --- a/nova/network/api.py +++ b/nova/network/api.py @@ -66,6 +66,18 @@ class API(base.Base): if isinstance(fixed_ip, str) or isinstance(fixed_ip, unicode): fixed_ip = self.db.fixed_ip_get_by_address(context, fixed_ip) floating_ip = self.db.floating_ip_get_by_address(context, floating_ip) + # Check if the floating ip address is allocated + if floating_ip['project_id'] is None: + raise exception.ApiError(_("Address (%s) is not allocated") + % floating_ip['address']) + # Check if the floating ip address is allocated to the same project + if floating_ip['project_id'] != context.project_id: + LOG.warn(_("Address (%s) is not allocated to your project " + "(%s)"), floating_ip['address'], context.project_id) + raise exception.ApiError(_("Address (%s) is not " + "allocated to your project (%s)") % + (floating_ip['address'], + context.project_id)) # NOTE(vish): Perhaps we should just pass this on to compute and # let compute communicate with network. host = fixed_ip['network']['host'] -- cgit From 1e9cc02d3cb63c9431921064aac23327198d4b8c Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Wed, 30 Mar 2011 13:36:03 -0700 Subject: Change '"%s" % e' to 'e'. --- plugins/xenserver/xenapi/etc/xapi.d/plugins/agent | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent index 3522df49d..83ac341a7 100755 --- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent +++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent @@ -68,7 +68,7 @@ def key_init(self, arg_dict): try: resp = _wait_for_agent(self, request_id, arg_dict) except TimeoutError, e: - raise PluginError("%s" % e) + raise PluginError(e) return resp @@ -89,7 +89,7 @@ def password(self, arg_dict): try: resp = _wait_for_agent(self, request_id, arg_dict) except TimeoutError, e: - raise PluginError("%s" % e) + raise PluginError(e) return resp @@ -143,7 +143,7 @@ def inject_file(self, arg_dict): try: resp = _wait_for_agent(self, request_id, arg_dict) except TimeoutError, e: - raise PluginError("%s" % e) + raise PluginError(e) return resp @@ -166,7 +166,7 @@ def _agent_has_method(self, method): try: resp = _wait_for_agent(self, tmp_id, dct) except TimeoutError, e: - raise PluginError("%s" % e) + raise PluginError(e) response = json.loads(resp) # The agent returns a comma-separated list of methods. self._agent_methods = response.split(",") -- cgit From cf89dea62e777bb3052f3a178e38d0b665c1983d Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Wed, 30 Mar 2011 13:38:10 -0700 Subject: localize NotImplementedError() --- plugins/xenserver/xenapi/etc/xapi.d/plugins/agent | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent index 83ac341a7..5c5a6d645 100755 --- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent +++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent @@ -136,8 +136,8 @@ def inject_file(self, arg_dict): else: # Either the methods don't exist in the agent, or they # have been disabled. - raise NotImplementedError("NOT IMPLEMENTED: Agent does not support" - " file injection.") + raise NotImplementedError(_("NOT IMPLEMENTED: Agent does not" + " support file injection.")) arg_dict["path"] = "data/host/%s" % request_id xenstore.write_record(self, arg_dict) try: -- cgit From b8173ba9fe80045665064208e66f46cca75fd3ba Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 30 Mar 2011 13:48:07 -0700 Subject: review cleanup --- bin/nova-manage | 3 ++- nova/api/ec2/cloud.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 4e14b6cab..fbf16f570 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -939,7 +939,8 @@ class ImageCommands(object): """Uploads an image into the image_service arguments: path owner [name] [is_public='T'] [architecture='x86_64'] [container_format='bare'] [disk_format='raw'] - [kernel_id=None] [ramdisk_id=None]""" + [kernel_id=None] [ramdisk_id=None] + """ return self._register(container_format, disk_format, path, owner, name, is_public, architecture, kernel_id, ramdisk_id) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 1e6c4d1db..3541e49ca 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -881,7 +881,7 @@ class CloudController(object): @staticmethod def _image_ec2_id(image_id, image_type='ami'): - """Returns image ec2_id using id and three letter type""" + """Returns image ec2_id using id and three letter type.""" template = image_type + '-%08x' return ec2utils.id_to_ec2_id(int(image_id), template=template) -- cgit From bb1c49bc324956241383add85297510842d4464c Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Wed, 30 Mar 2011 15:00:47 -0700 Subject: fixed review comment for i18n string multiple replacement strings need to use dictionary format --- nova/network/api.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/nova/network/api.py b/nova/network/api.py index 424c3f592..47e56ebc6 100644 --- a/nova/network/api.py +++ b/nova/network/api.py @@ -68,16 +68,20 @@ class API(base.Base): floating_ip = self.db.floating_ip_get_by_address(context, floating_ip) # Check if the floating ip address is allocated if floating_ip['project_id'] is None: - raise exception.ApiError(_("Address (%s) is not allocated") - % floating_ip['address']) + raise exception.ApiError(_("Address (%(address)s) is not " + "allocated") % {'address': + floating_ip['address']}) # Check if the floating ip address is allocated to the same project if floating_ip['project_id'] != context.project_id: - LOG.warn(_("Address (%s) is not allocated to your project " - "(%s)"), floating_ip['address'], context.project_id) - raise exception.ApiError(_("Address (%s) is not " - "allocated to your project (%s)") % - (floating_ip['address'], - context.project_id)) + LOG.warn(_("Address (%(address)s) is not allocated to your " + "project (%(project)s)"), + {'address': floating_ip['address'], + 'project': context.project_id}) + raise exception.ApiError(_("Address (%(address)s) is not " + "allocated to your project" + "(%(project)s)") % + {'address': floating_ip['address'], + 'project': context.project_id}) # NOTE(vish): Perhaps we should just pass this on to compute and # let compute communicate with network. host = fixed_ip['network']['host'] -- cgit From 7d86a9e478c92ac9f79039c4592c6355c91b8b61 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Wed, 30 Mar 2011 15:10:55 -0700 Subject: fixed review comment for i18n string multiple replacement strings need to use dictionary format --- nova/network/api.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/nova/network/api.py b/nova/network/api.py index 47e56ebc6..c56e3062b 100644 --- a/nova/network/api.py +++ b/nova/network/api.py @@ -68,9 +68,8 @@ class API(base.Base): floating_ip = self.db.floating_ip_get_by_address(context, floating_ip) # Check if the floating ip address is allocated if floating_ip['project_id'] is None: - raise exception.ApiError(_("Address (%(address)s) is not " - "allocated") % {'address': - floating_ip['address']}) + raise exception.ApiError(_("Address (%s) is not allocated") % + floating_ip['address']) # Check if the floating ip address is allocated to the same project if floating_ip['project_id'] != context.project_id: LOG.warn(_("Address (%(address)s) is not allocated to your " -- cgit From ce5ad4acbc81c8c444d7b6a02400d6bc0ef6b233 Mon Sep 17 00:00:00 2001 From: Devin Carlen Date: Wed, 30 Mar 2011 20:33:56 -0700 Subject: Removed adminclient and referred to pypi nova_adminclient module --- nova/adminclient.py | 473 ----------------------------------------------- smoketests/test_admin.py | 2 +- tools/pip-requires | 1 + 3 files changed, 2 insertions(+), 474 deletions(-) delete mode 100644 nova/adminclient.py diff --git a/nova/adminclient.py b/nova/adminclient.py deleted file mode 100644 index f570e12c2..000000000 --- a/nova/adminclient.py +++ /dev/null @@ -1,473 +0,0 @@ -# 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. -""" -Nova User API client library. -""" - -import base64 -import boto -import boto.exception -import httplib -import re -import string - -from boto.ec2.regioninfo import RegionInfo - - -DEFAULT_CLC_URL = 'http://127.0.0.1:8773' -DEFAULT_REGION = 'nova' - - -class UserInfo(object): - """ - Information about a Nova user, as parsed through SAX. - - **Fields Include** - - * username - * accesskey - * secretkey - * file (optional) containing zip of X509 cert & rc file - - """ - - def __init__(self, connection=None, username=None, endpoint=None): - self.connection = connection - self.username = username - self.endpoint = endpoint - - def __repr__(self): - return 'UserInfo:%s' % self.username - - def startElement(self, name, attrs, connection): - return None - - def endElement(self, name, value, connection): - if name == 'username': - self.username = str(value) - elif name == 'file': - self.file = base64.b64decode(str(value)) - elif name == 'accesskey': - self.accesskey = str(value) - elif name == 'secretkey': - self.secretkey = str(value) - - -class UserRole(object): - """ - Information about a Nova user's role, as parsed through SAX. - - **Fields include** - - * role - - """ - - def __init__(self, connection=None): - self.connection = connection - self.role = None - - def __repr__(self): - return 'UserRole:%s' % self.role - - def startElement(self, name, attrs, connection): - return None - - def endElement(self, name, value, connection): - if name == 'role': - self.role = value - else: - setattr(self, name, str(value)) - - -class ProjectInfo(object): - """ - Information about a Nova project, as parsed through SAX. - - **Fields include** - - * projectname - * description - * projectManagerId - * memberIds - - """ - - def __init__(self, connection=None): - self.connection = connection - self.projectname = None - self.description = None - self.projectManagerId = None - self.memberIds = [] - - def __repr__(self): - return 'ProjectInfo:%s' % self.projectname - - def startElement(self, name, attrs, connection): - return None - - def endElement(self, name, value, connection): - if name == 'projectname': - self.projectname = value - elif name == 'description': - self.description = value - elif name == 'projectManagerId': - self.projectManagerId = value - elif name == 'memberId': - self.memberIds.append(value) - else: - setattr(self, name, str(value)) - - -class ProjectMember(object): - """ - Information about a Nova project member, as parsed through SAX. - - **Fields include** - - * memberId - - """ - - def __init__(self, connection=None): - self.connection = connection - self.memberId = None - - def __repr__(self): - return 'ProjectMember:%s' % self.memberId - - def startElement(self, name, attrs, connection): - return None - - def endElement(self, name, value, connection): - if name == 'member': - self.memberId = value - else: - setattr(self, name, str(value)) - - -class HostInfo(object): - """ - Information about a Nova Host, as parsed through SAX. - - **Fields Include** - - * 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 - - # this is needed by the sax parser, so ignore the ugly name - def startElement(self, name, attrs, connection): - return None - - # this is needed by the sax parser, so ignore the ugly name - def endElement(self, name, value, connection): - 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): - """ - Information about a Nova instance type, as parsed through SAX. - - **Fields include** - - * name - * vcpus - * disk_gb - * memory_mb - * flavor_id - - """ - - def __init__(self, connection=None): - self.connection = connection - self.name = None - self.vcpus = None - self.disk_gb = None - self.memory_mb = None - self.flavor_id = None - - def __repr__(self): - return 'InstanceType:%s' % self.name - - def startElement(self, name, attrs, connection): - return None - - def endElement(self, name, value, connection): - if name == "memoryMb": - self.memory_mb = str(value) - elif name == "flavorId": - self.flavor_id = str(value) - elif name == "diskGb": - self.disk_gb = str(value) - else: - setattr(self, name, str(value)) - - -class NovaAdminClient(object): - - def __init__( - self, - clc_url=DEFAULT_CLC_URL, - region=DEFAULT_REGION, - access_key=None, - secret_key=None, - **kwargs): - parts = self.split_clc_url(clc_url) - - self.clc_url = clc_url - self.region = region - self.access = access_key - self.secret = secret_key - self.apiconn = boto.connect_ec2(aws_access_key_id=access_key, - aws_secret_access_key=secret_key, - is_secure=parts['is_secure'], - region=RegionInfo(None, - region, - parts['ip']), - port=parts['port'], - path='/services/Admin', - **kwargs) - self.apiconn.APIVersion = 'nova' - - def connection_for(self, username, project, clc_url=None, region=None, - **kwargs): - """Returns a boto ec2 connection for the given username.""" - if not clc_url: - clc_url = self.clc_url - if not region: - region = self.region - parts = self.split_clc_url(clc_url) - user = self.get_user(username) - access_key = '%s:%s' % (user.accesskey, project) - return boto.connect_ec2(aws_access_key_id=access_key, - aws_secret_access_key=user.secretkey, - is_secure=parts['is_secure'], - region=RegionInfo(None, - self.region, - parts['ip']), - port=parts['port'], - path='/services/Cloud', - **kwargs) - - def split_clc_url(self, clc_url): - """Splits a cloud controller endpoint url.""" - parts = httplib.urlsplit(clc_url) - is_secure = parts.scheme == 'https' - ip, port = parts.netloc.split(':') - return {'ip': ip, 'port': int(port), 'is_secure': is_secure} - - def get_users(self): - """Grabs the list of all users.""" - return self.apiconn.get_list('DescribeUsers', {}, [('item', UserInfo)]) - - def get_user(self, name): - """Grab a single user by name.""" - user = self.apiconn.get_object('DescribeUser', - {'Name': name}, - UserInfo) - if user.username != None: - return user - - def has_user(self, username): - """Determine if user exists.""" - return self.get_user(username) != None - - def create_user(self, username): - """Creates a new user, returning the userinfo object with - access/secret.""" - return self.apiconn.get_object('RegisterUser', {'Name': username}, - UserInfo) - - def delete_user(self, username): - """Deletes a user.""" - return self.apiconn.get_object('DeregisterUser', {'Name': username}, - UserInfo) - - def get_roles(self, project_roles=True): - """Returns a list of available roles.""" - return self.apiconn.get_list('DescribeRoles', - {'ProjectRoles': project_roles}, - [('item', UserRole)]) - - def get_user_roles(self, user, project=None): - """Returns a list of roles for the given user. - - Omitting project will return any global roles that the user has. - Specifying project will return only project specific roles. - - """ - params = {'User': user} - if project: - params['Project'] = project - return self.apiconn.get_list('DescribeUserRoles', - params, - [('item', UserRole)]) - - def add_user_role(self, user, role, project=None): - """Add a role to a user either globally or for a specific project.""" - return self.modify_user_role(user, role, project=project, - operation='add') - - def remove_user_role(self, user, role, project=None): - """Remove a role from a user either globally or for a specific - project.""" - return self.modify_user_role(user, role, project=project, - operation='remove') - - def modify_user_role(self, user, role, project=None, operation='add', - **kwargs): - """Add or remove a role for a user and project.""" - params = {'User': user, - 'Role': role, - 'Project': project, - 'Operation': operation} - return self.apiconn.get_status('ModifyUserRole', params) - - def get_projects(self, user=None): - """Returns a list of all projects.""" - if user: - params = {'User': user} - else: - params = {} - return self.apiconn.get_list('DescribeProjects', - params, - [('item', ProjectInfo)]) - - def get_project(self, name): - """Returns a single project with the specified name.""" - project = self.apiconn.get_object('DescribeProject', - {'Name': name}, - ProjectInfo) - - if project.projectname != None: - return project - - def create_project(self, projectname, manager_user, description=None, - member_users=None): - """Creates a new project.""" - params = {'Name': projectname, - 'ManagerUser': manager_user, - 'Description': description, - 'MemberUsers': member_users} - return self.apiconn.get_object('RegisterProject', params, ProjectInfo) - - def modify_project(self, projectname, manager_user=None, description=None): - """Modifies an existing project.""" - params = {'Name': projectname, - 'ManagerUser': manager_user, - 'Description': description} - return self.apiconn.get_status('ModifyProject', params) - - def delete_project(self, projectname): - """Permanently deletes the specified project.""" - return self.apiconn.get_object('DeregisterProject', - {'Name': projectname}, - ProjectInfo) - - def get_project_members(self, name): - """Returns a list of members of a project.""" - return self.apiconn.get_list('DescribeProjectMembers', - {'Name': name}, - [('item', ProjectMember)]) - - def add_project_member(self, user, project): - """Adds a user to a project.""" - return self.modify_project_member(user, project, operation='add') - - def remove_project_member(self, user, project): - """Removes a user from a project.""" - return self.modify_project_member(user, project, operation='remove') - - def modify_project_member(self, user, project, operation='add'): - """Adds or removes a user from a project.""" - params = {'User': user, - 'Project': project, - 'Operation': operation} - return self.apiconn.get_status('ModifyProjectMember', params) - - def get_zip(self, user, project): - """Returns the content of a zip file containing novarc and access - credentials.""" - params = {'Name': user, 'Project': project} - 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)]) - - def get_instance_types(self): - """Grabs the list of all users.""" - return self.apiconn.get_list('DescribeInstanceTypes', {}, - [('item', InstanceType)]) diff --git a/smoketests/test_admin.py b/smoketests/test_admin.py index 46e5b2233..1b7a8d673 100644 --- a/smoketests/test_admin.py +++ b/smoketests/test_admin.py @@ -30,7 +30,6 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): sys.path.insert(0, possible_topdir) -from nova import adminclient from smoketests import flags from smoketests import base @@ -47,6 +46,7 @@ TEST_PROJECTNAME = '%sproject' % TEST_PREFIX class AdminSmokeTestCase(base.SmokeTestCase): def setUp(self): + import nova_adminclient as adminclient self.admin = adminclient.NovaAdminClient( access_key=os.getenv('EC2_ACCESS_KEY'), secret_key=os.getenv('EC2_SECRET_KEY'), diff --git a/tools/pip-requires b/tools/pip-requires index 4ab9644d8..6ea446493 100644 --- a/tools/pip-requires +++ b/tools/pip-requires @@ -30,4 +30,5 @@ sqlalchemy-migrate netaddr sphinx glance +nova-adminclient suds==0.4 -- cgit From b5f0d2c22ce48d06dc502f7790ed48fdf007d7f6 Mon Sep 17 00:00:00 2001 From: Muneyuki Noguchi Date: Thu, 31 Mar 2011 17:39:00 +0900 Subject: Add volume.API.remove_from_compute instead of compute.API.remove_volume. --- nova/compute/api.py | 7 ------- nova/compute/manager.py | 12 +++++------- nova/volume/api.py | 7 +++++++ 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index 63983afd8..1dbd73f8f 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -687,13 +687,6 @@ class API(base.Base): "volume_id": volume_id}}) return instance - def remove_volume(self, context, volume_id, host): - """Remove volume on specified compute host.""" - rpc.call(context, - self.db.queue_get_for(context, FLAGS.compute_topic, host), - {"method": "remove_volume", - "args": {'volume_id': volume_id}}) - def associate_floating_ip(self, context, instance_id, address): instance = self.get(context, instance_id) self.network_api.associate_floating_ip(context, diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 8ce8a5d86..85bcd7590 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -46,13 +46,13 @@ import functools from eventlet import greenthread -from nova import compute from nova import exception from nova import flags from nova import log as logging from nova import manager from nova import rpc from nova import utils +from nova import volume from nova.compute import power_state from nova.virt import driver @@ -1037,14 +1037,12 @@ class ComputeManager(manager.SchedulerDependentManager): 'host': host}) if dest: - # NOTE(noguchimn): We set image_service here - # not to import an image service object. - compute_api = compute.API(image_service=1) - for volume in instance_ref['volumes']: - volume_id = volume['id'] + volume_api = volume.API() + for volume_ref in instance_ref['volumes']: + volume_id = volume_ref['id'] self.db.volume_update(ctxt, volume_id, {'status': 'in-use'}) if dest: - compute_api.remove_volume(ctxt, volume_id, dest) + volume_api.remove_from_compute(ctxt, volume_id, dest) def periodic_tasks(self, context=None): """Tasks to be run at a periodic interval.""" diff --git a/nova/volume/api.py b/nova/volume/api.py index 4b4bb9dc5..09befb647 100644 --- a/nova/volume/api.py +++ b/nova/volume/api.py @@ -103,3 +103,10 @@ class API(base.Base): # TODO(vish): abstract status checking? if volume['status'] == "available": raise exception.ApiError(_("Volume is already detached")) + + def remove_from_compute(self, context, volume_id, host): + """Remove volume from specified compute host.""" + rpc.call(context, + self.db.queue_get_for(context, FLAGS.compute_topic, host), + {"method": "remove_volume", + "args": {'volume_id': volume_id}}) -- cgit From 7f98416fdba59c4305f88a30a457bbf6c68ef372 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Thu, 31 Mar 2011 09:20:47 -0400 Subject: Limit image metadata to the configured metadata quota for a project. --- nova/api/openstack/image_metadata.py | 12 ++++++++ nova/tests/api/openstack/test_image_metadata.py | 39 +++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/nova/api/openstack/image_metadata.py b/nova/api/openstack/image_metadata.py index c9d6ac532..76abdaa7e 100644 --- a/nova/api/openstack/image_metadata.py +++ b/nova/api/openstack/image_metadata.py @@ -18,6 +18,7 @@ from webob import exc from nova import flags +from nova import quota from nova import utils from nova import wsgi from nova.api.openstack import faults @@ -39,6 +40,15 @@ class Controller(wsgi.Controller): metadata = image.get('properties', {}) return metadata + def _check_quota_limit(self, context, metadata): + if metadata is None: + return + num_metadata = len(metadata) + quota_metadata = quota.allowed_metadata_items(context, num_metadata) + if quota_metadata < num_metadata: + expl = ("Image metadata limit exceeded") + raise exc.HTTPBadRequest(explanation=expl) + def index(self, req, image_id): """Returns the list of metadata for a given instance""" context = req.environ['nova.context'] @@ -61,6 +71,7 @@ class Controller(wsgi.Controller): if 'metadata' in body: for key, value in body['metadata'].iteritems(): metadata[key] = value + self._check_quota_limit(context, metadata) img['properties'] = metadata self.image_service.update(context, image_id, img, None) return dict(metadata=metadata) @@ -77,6 +88,7 @@ class Controller(wsgi.Controller): img = self.image_service.show(context, image_id) metadata = self._get_metadata(context, image_id, img) metadata[id] = body[id] + self._check_quota_limit(context, metadata) img['properties'] = metadata self.image_service.update(context, image_id, img, None) diff --git a/nova/tests/api/openstack/test_image_metadata.py b/nova/tests/api/openstack/test_image_metadata.py index 9be753f84..51f64680b 100644 --- a/nova/tests/api/openstack/test_image_metadata.py +++ b/nova/tests/api/openstack/test_image_metadata.py @@ -67,6 +67,19 @@ class ImageMetaDataTest(unittest.TestCase): 'key2': 'value2' }, 'size': 5882349}, + {'status': 'active', + 'name': 'image3', + 'deleted': False, + 'container_format': None, + 'created_at': '2011-03-22T17:40:15', + 'disk_format': None, + 'updated_at': '2011-03-22T17:40:15', + 'id': '3', + 'location': 'file:///var/lib/glance/images/2', + 'is_public': True, + 'deleted_at': None, + 'properties': {}, + 'size': 5882349}, ] def setUp(self): @@ -77,6 +90,10 @@ class ImageMetaDataTest(unittest.TestCase): fakes.FakeAuthManager.auth_data = {} fakes.FakeAuthDatabase.data = {} fakes.stub_out_auth(self.stubs) + # NOTE(dprince) max out properties/metadata in image 3 for testing + img3 = self.IMAGE_FIXTURES[2] + for num in range(FLAGS.quota_metadata_items): + img3['properties']['key%i' % num] = "blah" fakes.stub_out_glance(self.stubs, self.IMAGE_FIXTURES) def tearDown(self): @@ -164,3 +181,25 @@ class ImageMetaDataTest(unittest.TestCase): req.method = 'DELETE' res = req.get_response(fakes.wsgi_app()) self.assertEqual(404, res.status_int) + + def test_too_many_metadata_items_on_create(self): + data = {"metadata": {}} + for num in range(FLAGS.quota_metadata_items + 1): + data['metadata']['key%i' % num] = "blah" + json_string = str(data).replace("\'", "\"") + req = webob.Request.blank('/v1.1/images/2/meta') + req.environ['api.version'] = '1.1' + req.method = 'POST' + req.body = json_string + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(400, res.status_int) + + def test_too_many_metadata_items_on_put(self): + req = webob.Request.blank('/v1.1/images/3/meta/blah') + req.environ['api.version'] = '1.1' + req.method = 'PUT' + req.body = '{"blah": "blah"}' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(400, res.status_int) -- cgit From b39a0eabd507f804300c1741b768cf3c2584393d Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Thu, 31 Mar 2011 09:01:01 -0700 Subject: need to support python2.4, so can't use uuid module --- plugins/xenserver/xenapi/etc/xapi.d/plugins/agent | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent index 5c5a6d645..5496a6bd5 100755 --- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent +++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent @@ -23,6 +23,7 @@ # import base64 +import commands try: import json except ImportError: @@ -32,7 +33,6 @@ import random import subprocess import tempfile import time -import uuid import XenAPIPlugin @@ -158,7 +158,7 @@ def _agent_has_method(self, method): self._agent_methods = [] if not self._agent_methods: # Haven't been defined - tmp_id = str(uuid.uuid4()) + tmp_id = commands.getoutput("uuidgen") dct = {} dct["value"] = json.dumps({"name": "features", "value": ""}) dct["path"] = "data/host/%s" % tmp_id -- cgit From 45bb2fb1f74c21e9ef8b65f6c4e22965e2c94fbd Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Thu, 31 Mar 2011 13:08:49 -0500 Subject: More friendly error message --- nova/scheduler/chance.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nova/scheduler/chance.py b/nova/scheduler/chance.py index 9deaa2777..ae81679e1 100644 --- a/nova/scheduler/chance.py +++ b/nova/scheduler/chance.py @@ -34,5 +34,7 @@ class ChanceScheduler(driver.Scheduler): hosts = self.hosts_up(context, topic) if not hosts: - raise driver.NoValidHost(_("No hosts found")) + raise driver.NoValidHost(_("Scheduler was unable to locate a host" + " for this request. Is the compute node" + " running?")) return hosts[int(random.random() * len(hosts))] -- cgit From 62b52833cc28d203c648585feceb1de3be9eed25 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Thu, 31 Mar 2011 14:29:16 -0500 Subject: Review feedback --- nova/scheduler/chance.py | 4 ++-- nova/scheduler/simple.py | 12 +++++++++--- nova/scheduler/zone.py | 5 ++++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/nova/scheduler/chance.py b/nova/scheduler/chance.py index ae81679e1..f4461cee2 100644 --- a/nova/scheduler/chance.py +++ b/nova/scheduler/chance.py @@ -35,6 +35,6 @@ class ChanceScheduler(driver.Scheduler): hosts = self.hosts_up(context, topic) if not hosts: raise driver.NoValidHost(_("Scheduler was unable to locate a host" - " for this request. Is the compute node" - " running?")) + " for this request. Is the appropriate" + " service running?")) return hosts[int(random.random() * len(hosts))] diff --git a/nova/scheduler/simple.py b/nova/scheduler/simple.py index 0191ceb3d..dd568d2c6 100644 --- a/nova/scheduler/simple.py +++ b/nova/scheduler/simple.py @@ -72,7 +72,9 @@ class SimpleScheduler(chance.ChanceScheduler): {'host': service['host'], 'scheduled_at': now}) return service['host'] - raise driver.NoValidHost(_("No hosts found")) + raise driver.NoValidHost(_("Scheduler was unable to locate a host" + " for this request. Is the appropriate" + " service running?")) def schedule_create_volume(self, context, volume_id, *_args, **_kwargs): """Picks a host that is up and has the fewest volumes.""" @@ -107,7 +109,9 @@ class SimpleScheduler(chance.ChanceScheduler): {'host': service['host'], 'scheduled_at': now}) return service['host'] - raise driver.NoValidHost(_("No hosts found")) + raise driver.NoValidHost(_("Scheduler was unable to locate a host" + " for this request. Is the appropriate" + " service running?")) def schedule_set_network_host(self, context, *_args, **_kwargs): """Picks a host that is up and has the fewest networks.""" @@ -119,4 +123,6 @@ class SimpleScheduler(chance.ChanceScheduler): raise driver.NoValidHost(_("All hosts have too many networks")) if self.service_is_up(service): return service['host'] - raise driver.NoValidHost(_("No hosts found")) + raise driver.NoValidHost(_("Scheduler was unable to locate a host" + " for this request. Is the appropriate" + " service running?")) diff --git a/nova/scheduler/zone.py b/nova/scheduler/zone.py index 49786cd32..44d5a166f 100644 --- a/nova/scheduler/zone.py +++ b/nova/scheduler/zone.py @@ -52,5 +52,8 @@ class ZoneScheduler(driver.Scheduler): zone = _kwargs.get('availability_zone') hosts = self.hosts_up_with_zone(context, topic, zone) if not hosts: - raise driver.NoValidHost(_("No hosts found")) + raise driver.NoValidHost(_("Scheduler was unable to locate a host" + " for this request. Is the appropriate" + " service running?")) + return hosts[int(random.random() * len(hosts))] -- cgit From 82224b6681750819a4ee0d8b081823863cb0523c Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 31 Mar 2011 12:31:35 -0700 Subject: removes excessive logging on rabbitmq failure --- nova/rpc.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/nova/rpc.py b/nova/rpc.py index be7cb3f37..b610cdf9b 100644 --- a/nova/rpc.py +++ b/nova/rpc.py @@ -134,8 +134,6 @@ class Consumer(messaging.Consumer): if not self.failed_connection: LOG.exception(_("Failed to fetch message from queue: %s" % e)) self.failed_connection = True - else: - LOG.exception(_("Unhandled exception %s" % e)) def attach_to_eventlet(self): """Only needed for unit tests!""" -- cgit From 1654afaabba498ab690c07ccc6de858783dc1742 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 31 Mar 2011 12:38:05 -0700 Subject: makes sure s3 filtering works even without metadata set properly --- nova/image/s3.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nova/image/s3.py b/nova/image/s3.py index 203bedc49..def49f682 100644 --- a/nova/image/s3.py +++ b/nova/image/s3.py @@ -80,9 +80,10 @@ class S3ImageService(service.BaseImageService): @classmethod def _is_visible(cls, context, image): + return (context.is_admin - or context.project_id == image['properties']['owner_id'] - or image['properties']['is_public'] == 'True') + or context.project_id == image['properties'].get('owner_id') + or str(image['properties'].get('is_public')) == 'True') @classmethod def _filter(cls, context, images): -- cgit From 032acaab1fd9a3823e203ddaf9c50857acd25ac7 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Thu, 31 Mar 2011 15:32:31 -0500 Subject: Don't include first 4 chars of instance name in adminPass --- nova/api/openstack/servers.py | 3 +-- nova/tests/api/openstack/test_servers.py | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index f7696d918..d47ea5788 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -180,8 +180,7 @@ class Controller(wsgi.Controller): builder = self._get_view_builder(req) server = builder.build(inst, is_detail=True) - password = "%s%s" % (server['server']['name'][:4], - utils.generate_password(12)) + password = utils.generate_password(16) server['server']['adminPass'] = password self.compute_api.set_admin_password(context, server['server']['id'], password) diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 130b8c5d5..5fbc9837b 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -377,7 +377,6 @@ class ServersTest(test.TestCase): res = req.get_response(fakes.wsgi_app()) server = json.loads(res.body)['server'] - self.assertEqual('serv', server['adminPass'][:4]) self.assertEqual(16, len(server['adminPass'])) self.assertEqual('server_test', server['name']) self.assertEqual(1, server['id']) @@ -486,7 +485,6 @@ class ServersTest(test.TestCase): res = req.get_response(fakes.wsgi_app()) server = json.loads(res.body)['server'] - self.assertEqual('serv', server['adminPass'][:4]) self.assertEqual(16, len(server['adminPass'])) self.assertEqual('server_test', server['name']) self.assertEqual(1, server['id']) @@ -1426,7 +1424,7 @@ class TestServerInstanceCreation(test.TestCase): self.assertEquals(response.status_int, 200) response = json.loads(response.body) self.assertTrue('adminPass' in response['server']) - self.assertTrue(response['server']['adminPass'].startswith('fake')) + self.assertEqual(16, len(response['server']['adminPass'])) def test_create_instance_admin_pass_xml(self): request, response, dummy = \ @@ -1435,7 +1433,7 @@ class TestServerInstanceCreation(test.TestCase): dom = minidom.parseString(response.body) server = dom.childNodes[0] self.assertEquals(server.nodeName, 'server') - self.assertTrue(server.getAttribute('adminPass').startswith('fake')) + self.assertEqual(16, len(server.getAttribute('adminPass'))) class TestGetKernelRamdiskFromImage(test.TestCase): -- cgit From 5d71e187dc6eddab19ecdc0feb97e41263e09a84 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Thu, 31 Mar 2011 17:19:59 -0400 Subject: Hopefully absolved us of the suds issue? --- nova/virt/vmwareapi/vim.py | 47 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/nova/virt/vmwareapi/vim.py b/nova/virt/vmwareapi/vim.py index 1c850595d..159e16a80 100644 --- a/nova/virt/vmwareapi/vim.py +++ b/nova/virt/vmwareapi/vim.py @@ -22,13 +22,9 @@ Classes for making VMware VI SOAP calls. import httplib try: - suds = True - from suds import WebFault - from suds.client import Client - from suds.plugin import MessagePlugin - from suds.sudsobject import Property + import suds except ImportError: - suds = False + suds = None from nova import flags from nova.virt.vmwareapi import error_util @@ -46,24 +42,25 @@ flags.DEFINE_string('vmwareapi_wsdl_loc', 'Refer readme-vmware to setup') -class VIMMessagePlugin(MessagePlugin): +if suds: + class VIMMessagePlugin(suds.plugin.MessagePlugin): - def addAttributeForValue(self, node): - # suds does not handle AnyType properly. - # VI SDK requires type attribute to be set when AnyType is used - if node.name == 'value': - node.set('xsi:type', 'xsd:string') + def addAttributeForValue(self, node): + # suds does not handle AnyType properly. + # VI SDK requires type attribute to be set when AnyType is used + if node.name == 'value': + node.set('xsi:type', 'xsd:string') - def marshalled(self, context): - """suds will send the specified soap envelope. - Provides the plugin with the opportunity to prune empty - nodes and fixup nodes before sending it to the server. - """ - # suds builds the entire request object based on the wsdl schema. - # VI SDK throws server errors if optional SOAP nodes are sent without - # values, e.g. as opposed to test - context.envelope.prune() - context.envelope.walk(self.addAttributeForValue) + def marshalled(self, context): + """suds will send the specified soap envelope. + Provides the plugin with the opportunity to prune empty + nodes and fixup nodes before sending it to the server. + """ + # suds builds the entire request object based on the wsdl schema. + # VI SDK throws server errors if optional SOAP nodes are sent + # without values, e.g. as opposed to test + context.envelope.prune() + context.envelope.walk(self.addAttributeForValue) class Vim: @@ -91,7 +88,7 @@ class Vim: #wsdl_url = '%s://%s/sdk/vimService.wsdl' % (self._protocol, # self._host_name) url = '%s://%s/sdk' % (self._protocol, self._host_name) - self.client = Client(wsdl_url, location=url, + self.client = suds.client.Client(wsdl_url, location=url, plugins=[VIMMessagePlugin()]) self._service_content = \ self.RetrieveServiceContent("ServiceInstance") @@ -134,7 +131,7 @@ class Vim: # check of the SOAP response except error_util.VimFaultException, excep: raise - except WebFault, excep: + except suds.WebFault, excep: doc = excep.document detail = doc.childAtPath("/Envelope/Body/Fault/detail") fault_list = [] @@ -170,7 +167,7 @@ class Vim: """Builds the request managed object.""" # Request Managed Object Builder if type(managed_object) == type(""): - mo = Property(managed_object) + mo = suds.sudsobject.Property(managed_object) mo._type = managed_object else: mo = managed_object -- cgit From b56c406429e4748f52ba8215beb4076165c6640d Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Fri, 1 Apr 2011 11:23:05 +0200 Subject: Make euca-get-ajax-console work with Euca2ools 1.3 --- tools/euca-get-ajax-console | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/euca-get-ajax-console b/tools/euca-get-ajax-console index 3df3dcb53..c76d4f39c 100755 --- a/tools/euca-get-ajax-console +++ b/tools/euca-get-ajax-console @@ -93,8 +93,13 @@ def override_connect_ec2(aws_access_key_id=None, aws_secret_access_key, **kwargs) # override boto's connect_ec2 method, so that we can use NovaEC2Connection +# (This is for Euca2ools 1.2) boto.connect_ec2 = override_connect_ec2 +# Override Euca2ools' EC2Connection class (which it gets from boto) +# (This is for Euca2ools 1.3) +euca2ools.EC2Connection = NovaEC2Connection + def usage(status=1): print usage_string -- cgit From 0865cc59c1a525d21937224b7ff1ff61ce43f4b1 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Fri, 1 Apr 2011 17:10:06 +0200 Subject: Add euca2ools import --- tools/euca-get-ajax-console | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/euca-get-ajax-console b/tools/euca-get-ajax-console index c76d4f39c..a67c79d90 100755 --- a/tools/euca-get-ajax-console +++ b/tools/euca-get-ajax-console @@ -35,6 +35,7 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): import boto import nova from boto.ec2.connection import EC2Connection +import euca2ools from euca2ools import Euca2ool, InstanceValidationError, Util usage_string = """ -- cgit From 007992e57c064c90e6a09f8dac070d3b56dc72a0 Mon Sep 17 00:00:00 2001 From: Masanori Itoh Date: Sat, 2 Apr 2011 00:28:32 +0900 Subject: Added updated_at field to update statement according to Jay's comment. --- nova/db/sqlalchemy/api.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 08eb0b7b2..6da8dac10 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -660,7 +660,9 @@ def fixed_ip_disassociate_all_by_timeout(_context, host, time): filter(models.FixedIp.instance_id != None).\ filter_by(allocated=0).\ update({'instance_id': None, - 'leased': 0}, synchronize_session='fetch') + 'leased': 0, + 'updated_at': datetime.datetime.utcnow()}, + synchronize_session='fetch') return result -- cgit From d98c61d21f3a60e3368cc723fc6764c66b8176b4 Mon Sep 17 00:00:00 2001 From: Masanori Itoh Date: Sat, 2 Apr 2011 01:05:50 +0900 Subject: Add checking if the floating_ip is allocated or not before appending to result array. --- nova/api/ec2/cloud.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 7ba8dfbea..a6bdab808 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -757,19 +757,20 @@ class CloudController(object): iterator = db.floating_ip_get_all_by_project(context, context.project_id) for floating_ip_ref in iterator: - address = floating_ip_ref['address'] - ec2_id = None - if (floating_ip_ref['fixed_ip'] - and floating_ip_ref['fixed_ip']['instance']): - instance_id = floating_ip_ref['fixed_ip']['instance']['id'] - ec2_id = ec2utils.id_to_ec2_id(instance_id) - address_rv = {'public_ip': address, - 'instance_id': ec2_id} - if context.is_admin: - details = "%s (%s)" % (address_rv['instance_id'], - floating_ip_ref['project_id']) - address_rv['instance_id'] = details - addresses.append(address_rv) + if floating_ip_ref['project_id'] is not None: + address = floating_ip_ref['address'] + ec2_id = None + if (floating_ip_ref['fixed_ip'] + and floating_ip_ref['fixed_ip']['instance']): + instance_id = floating_ip_ref['fixed_ip']['instance']['id'] + ec2_id = ec2utils.id_to_ec2_id(instance_id) + address_rv = {'public_ip': address, + 'instance_id': ec2_id} + if context.is_admin: + details = "%s (%s)" % (address_rv['instance_id'], + floating_ip_ref['project_id']) + address_rv['instance_id'] = details + addresses.append(address_rv) return {'addressesSet': addresses} def allocate_address(self, context, **kwargs): -- cgit From ec3b3d6ae97cddce490c2cbeed2f8f9241704ed1 Mon Sep 17 00:00:00 2001 From: Masanori Itoh Date: Sat, 2 Apr 2011 01:44:12 +0900 Subject: Made the fix simpler. --- nova/api/ec2/cloud.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index a6bdab808..425784e8a 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -757,20 +757,21 @@ class CloudController(object): iterator = db.floating_ip_get_all_by_project(context, context.project_id) for floating_ip_ref in iterator: - if floating_ip_ref['project_id'] is not None: - address = floating_ip_ref['address'] - ec2_id = None - if (floating_ip_ref['fixed_ip'] - and floating_ip_ref['fixed_ip']['instance']): - instance_id = floating_ip_ref['fixed_ip']['instance']['id'] - ec2_id = ec2utils.id_to_ec2_id(instance_id) - address_rv = {'public_ip': address, - 'instance_id': ec2_id} - if context.is_admin: - details = "%s (%s)" % (address_rv['instance_id'], - floating_ip_ref['project_id']) - address_rv['instance_id'] = details - addresses.append(address_rv) + if floating_ip_ref['project_id'] is None: + continue + address = floating_ip_ref['address'] + ec2_id = None + if (floating_ip_ref['fixed_ip'] + and floating_ip_ref['fixed_ip']['instance']): + instance_id = floating_ip_ref['fixed_ip']['instance']['id'] + ec2_id = ec2utils.id_to_ec2_id(instance_id) + address_rv = {'public_ip': address, + 'instance_id': ec2_id} + if context.is_admin: + details = "%s (%s)" % (address_rv['instance_id'], + floating_ip_ref['project_id']) + address_rv['instance_id'] = details + addresses.append(address_rv) return {'addressesSet': addresses} def allocate_address(self, context, **kwargs): -- cgit From c1120caaa8c8ed8902b5634da56b2bd5478662e1 Mon Sep 17 00:00:00 2001 From: Muneyuki Noguchi Date: Mon, 4 Apr 2011 10:25:58 +0900 Subject: Use keyword arguments. --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index c5a71d244..c03c2ae1d 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1475,7 +1475,7 @@ class LibvirtConnection(driver.ComputeDriver): FLAGS.live_migration_bandwidth) except Exception: - recover_method(ctxt, instance_ref, None, dest) + recover_method(ctxt, instance_ref, dest=dest) raise # Waiting for completion of live_migration. -- cgit -- cgit From ec30c42b3b4532743c8353c5e9fa04ae00803db3 Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Mon, 4 Apr 2011 18:31:35 +0400 Subject: network injection check fixed --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index f34ea7225..c952f6f47 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -842,7 +842,7 @@ class LibvirtConnection(driver.ComputeDriver): for (network_ref, mapping) in network_info: ifc_num += 1 - if not 'injected' in network_ref: + if not network_ref.injected: continue have_injected_networks = True -- cgit From bd64c4f6bebb50528b87bf6e3f64d7d1cba053df Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Mon, 4 Apr 2011 10:59:44 -0400 Subject: Fixes error which occurs when no name is specified for an image. --- nova/api/openstack/views/images.py | 2 +- nova/tests/api/openstack/test_images.py | 57 +++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/nova/api/openstack/views/images.py b/nova/api/openstack/views/images.py index 3807fa95f..d8578ebdd 100644 --- a/nova/api/openstack/views/images.py +++ b/nova/api/openstack/views/images.py @@ -61,7 +61,7 @@ class ViewBuilder(object): image = { "id": image_obj["id"], - "name": image_obj["name"], + "name": image_obj.get("name"), } if "instance_id" in properties: diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index 57e447dce..69cc3116d 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -263,7 +263,8 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): {'id': 124, 'name': 'queued backup'}, {'id': 125, 'name': 'saving backup'}, {'id': 126, 'name': 'active backup'}, - {'id': 127, 'name': 'killed backup'}] + {'id': 127, 'name': 'killed backup'}, + {'id': 129, 'name': None}] self.assertDictListMatch(response_list, expected) @@ -339,6 +340,24 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): self.assertEqual(expected_image.toxml(), actual_image.toxml()) + def test_get_image_xml_no_name(self): + request = webob.Request.blank('/v1.0/images/129') + request.accept = "application/xml" + response = request.get_response(fakes.wsgi_app()) + + actual_image = minidom.parseString(response.body.replace(" ", "")) + + expected_now = self.NOW_API_FORMAT + expected_image = minidom.parseString(""" + + """ % (locals())) + + self.assertEqual(expected_image.toxml(), actual_image.toxml()) + def test_get_image_v1_1_xml(self): request = webob.Request.blank('/v1.1/images/123') request.accept = "application/xml" @@ -516,6 +535,13 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): 'updated': self.NOW_API_FORMAT, 'created': self.NOW_API_FORMAT, 'status': 'FAILED', + }, + { + 'id': 129, + 'name': None, + 'updated': self.NOW_API_FORMAT, + 'created': self.NOW_API_FORMAT, + 'status': 'ACTIVE', }] self.assertDictListMatch(expected, response_list) @@ -635,7 +661,29 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): "type": "application/xml", "href": "http://localhost/v1.1/images/127", }], - }] + }, + { + 'id': 129, + 'name': None, + 'updated': self.NOW_API_FORMAT, + 'created': self.NOW_API_FORMAT, + 'status': 'ACTIVE', + "links": [{ + "rel": "self", + "href": "http://localhost/v1.1/images/129", + }, + { + "rel": "bookmark", + "type": "application/json", + "href": "http://localhost/v1.1/images/129", + }, + { + "rel": "bookmark", + "type": "application/xml", + "href": "http://localhost/v1.1/images/129", + }], + }, + ] self.assertDictListMatch(expected, response_list) @@ -694,4 +742,9 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): status='active', properties=other_backup_properties) image_id += 1 + # Image without a name + add_fixture(id=image_id, is_public=True, status='active', + properties={}) + image_id += 1 + return fixtures -- cgit From 59d46ada05f47bf477427b932a47c1cf1d91811e Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Mon, 4 Apr 2011 11:19:20 -0400 Subject: Ensure no errors for improper responses from image service. --- nova/api/openstack/views/images.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nova/api/openstack/views/images.py b/nova/api/openstack/views/images.py index d8578ebdd..16195b050 100644 --- a/nova/api/openstack/views/images.py +++ b/nova/api/openstack/views/images.py @@ -60,7 +60,7 @@ class ViewBuilder(object): self._format_status(image_obj) image = { - "id": image_obj["id"], + "id": image_obj.get("id"), "name": image_obj.get("name"), } @@ -72,9 +72,9 @@ class ViewBuilder(object): if detail: image.update({ - "created": image_obj["created_at"], - "updated": image_obj["updated_at"], - "status": image_obj["status"], + "created": image_obj.get("created_at"), + "updated": image_obj.get("updated_at"), + "status": image_obj.get("status"), }) if image["status"] == "SAVING": -- cgit From fc53de592fb903f8a7e3741fa98d03140aca9066 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Mon, 4 Apr 2011 09:45:26 -0700 Subject: corrected capitalization of openstack api status and added tests --- nova/api/openstack/views/servers.py | 24 ++++++++++++------------ nova/tests/api/openstack/test_servers.py | 2 ++ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index 6b471a0f4..d24c025be 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -57,27 +57,27 @@ class ViewBuilder(object): def _build_detail(self, inst): """Returns a detailed model of a server.""" power_mapping = { - None: 'build', - power_state.NOSTATE: 'build', - power_state.RUNNING: 'active', - power_state.BLOCKED: 'active', - power_state.SUSPENDED: 'suspended', - power_state.PAUSED: 'paused', - power_state.SHUTDOWN: 'active', - power_state.SHUTOFF: 'active', - power_state.CRASHED: 'error', - power_state.FAILED: 'error'} + None: 'BUILD', + power_state.NOSTATE: 'BUILD', + power_state.RUNNING: 'ACTIVE', + power_state.BLOCKED: 'ACTIVE', + power_state.SUSPENDED: 'SUSPENDED', + power_state.PAUSED: 'PAUSED', + power_state.SHUTDOWN: 'ACTIVE', + power_state.SHUTOFF: 'ACTIVE', + power_state.CRASHED: 'ERROR', + power_state.FAILED: 'ERROR'} inst_dict = { 'id': int(inst['id']), 'name': inst['display_name'], 'addresses': self.addresses_builder.build(inst), - 'status': power_mapping[inst.get('state')].upper()} + 'status': power_mapping[inst.get('state')]} ctxt = nova.context.get_admin_context() compute_api = nova.compute.API() if compute_api.has_finished_migration(ctxt, inst['id']): - inst_dict['status'] = 'resize-confirm'.upper() + inst_dict['status'] = 'RESIZE-CONFIRM' # Return the metadata as a dictionary metadata = {} diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index d32e8eea8..cf55c8383 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -631,6 +631,7 @@ class ServersTest(test.TestCase): self.assertEqual(s['name'], 'server%d' % i) self.assertEqual(s['imageId'], '10') self.assertEqual(s['flavorId'], '1') + self.assertEqual(s['status'], 'BUILD') self.assertEqual(s['metadata']['seq'], i) def test_get_all_server_details_v1_1(self): @@ -644,6 +645,7 @@ class ServersTest(test.TestCase): self.assertEqual(s['name'], 'server%d' % i) self.assertEqual(s['imageRef'], 'http://localhost/v1.1/images/10') self.assertEqual(s['flavorRef'], 'http://localhost/v1.1/flavors/1') + self.assertEqual(s['status'], 'BUILD') self.assertEqual(s['metadata']['seq'], i) def test_get_all_server_details_with_host(self): -- cgit From 95fe2026e869e2da29196f8bf3e48ae2a2560e46 Mon Sep 17 00:00:00 2001 From: Masanori Itoh Date: Tue, 5 Apr 2011 02:04:58 +0900 Subject: Moved 'name' property from to , corrected and fixes bug # 750482. --- nova/api/ec2/cloud.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 425784e8a..ecf144452 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -886,10 +886,7 @@ class CloudController(object): image_type = image['properties'].get('type') ec2_id = self._image_ec2_id(image.get('id'), image_type) name = image.get('name') - if name: - i['imageId'] = "%s (%s)" % (ec2_id, name) - else: - i['imageId'] = ec2_id + i['imageId'] = ec2_id kernel_id = image['properties'].get('kernel_id') if kernel_id: i['kernelId'] = self._image_ec2_id(kernel_id, 'kernel') @@ -897,11 +894,15 @@ class CloudController(object): if ramdisk_id: i['ramdiskId'] = self._image_ec2_id(ramdisk_id, 'ramdisk') i['imageOwnerId'] = image['properties'].get('owner_id') - i['imageLocation'] = image['properties'].get('image_location') + if name: + i['imageLocation'] = "%s (%s)" % (image['properties']. + get('image_location'), name) + else: + i['imageLocation'] = image['properties'].get('image_location') i['imageState'] = image['properties'].get('image_state') - i['displayName'] = image.get('name') + i['displayName'] = name i['description'] = image.get('description') - i['type'] = image_type + i['imageType'] = image_type i['isPublic'] = str(image['properties'].get('is_public', '')) == 'True' i['architecture'] = image['properties'].get('architecture') return i -- cgit From d7053efa810aa3d20ef7cd089429c6d96f451a7d Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Mon, 4 Apr 2011 21:05:38 +0400 Subject: Fixed network_info creating. --- nova/tests/test_virt.py | 6 ++++-- nova/virt/libvirt_conn.py | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 958c8e3e2..5a010d347 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -617,7 +617,8 @@ class IptablesFirewallTestCase(test.TestCase): instance_ref = db.instance_create(self.context, {'user_id': 'fake', 'project_id': 'fake', - 'mac_address': '56:12:12:12:12:12'}) + 'mac_address': '56:12:12:12:12:12', + 'instance_type': 'm1.small'}) ip = '10.11.12.13' network_ref = db.project_get_network(self.context, @@ -840,7 +841,8 @@ class NWFilterTestCase(test.TestCase): instance_ref = db.instance_create(self.context, {'user_id': 'fake', 'project_id': 'fake', - 'mac_address': '00:A0:C9:14:C8:29'}) + 'mac_address': '00:A0:C9:14:C8:29', + 'instance_type': 'm1.small'}) inst_id = instance_ref['id'] ip = '10.11.12.13' diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index f34ea7225..93a250502 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -167,6 +167,9 @@ def _get_network_info(instance): networks = db.network_get_all_by_instance(admin_context, instance['id']) + + flavor = db.instance_type_get_by_name(admin_context, + instance['instance_type']) network_info = [] def ip_dict(ip): @@ -191,7 +194,9 @@ def _get_network_info(instance): mapping = { 'label': network['label'], 'gateway': network['gateway'], + 'broadcast': network['broadcast'], 'mac': instance.mac_address, + 'rxtx_cap': flavor['rxtx_cap'], 'dns': [network['dns']], 'ips': [ip_dict(ip) for ip in network_ips]} -- cgit From 350aaa819c8f97e0bcbd9e4d0f6f0da41784b630 Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Mon, 4 Apr 2011 22:39:39 +0400 Subject: working with network_ref like with mapping --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index c952f6f47..babbc610d 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -842,7 +842,7 @@ class LibvirtConnection(driver.ComputeDriver): for (network_ref, mapping) in network_info: ifc_num += 1 - if not network_ref.injected: + if not network_ref['injected']: continue have_injected_networks = True -- cgit From 38b4cd9e68d7e1c262b08474b277573440ec3e87 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Mon, 4 Apr 2011 16:17:04 -0400 Subject: Refactor so that instances.instance_type is now instances.instance_type_id. Update the Openstack API to return the correct flavor_id. --- bin/nova-manage | 2 +- nova/api/ec2/cloud.py | 7 +- nova/api/openstack/servers.py | 6 +- nova/api/openstack/views/servers.py | 4 +- nova/compute/api.py | 18 +++-- nova/compute/instance_types.py | 46 ++++++------ nova/db/api.py | 5 ++ nova/db/sqlalchemy/api.py | 22 ++++++ .../014_add_instance_type_id_to_instances.py | 86 ++++++++++++++++++++++ nova/db/sqlalchemy/models.py | 11 ++- nova/tests/api/openstack/test_servers.py | 24 +++--- nova/tests/db/fakes.py | 22 ++++-- nova/tests/test_compute.py | 18 +++-- nova/tests/test_console.py | 2 +- nova/tests/test_instance_types.py | 6 +- nova/tests/test_quota.py | 17 +++-- nova/tests/test_scheduler.py | 2 +- nova/tests/test_virt.py | 2 +- nova/tests/test_volume.py | 2 +- nova/tests/test_xenapi.py | 12 +-- nova/virt/libvirt_conn.py | 22 +++--- nova/virt/xenapi/vm_utils.py | 8 +- nova/virt/xenapi/vmops.py | 8 +- 23 files changed, 256 insertions(+), 96 deletions(-) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/014_add_instance_type_id_to_instances.py diff --git a/bin/nova-manage b/bin/nova-manage index 6789efba8..b80a6e31d 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -878,7 +878,7 @@ class InstanceTypeCommands(object): elif name == "--all": inst_types = instance_types.get_all_types(True) else: - inst_types = instance_types.get_instance_type(name) + inst_types = instance_types.get_instance_type_by_name(name) except exception.DBError, e: _db_error(e) if isinstance(inst_types.values()[0], dict): diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 7ba8dfbea..cd1195502 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -722,7 +722,10 @@ class CloudController(object): instance['project_id'], instance['host']) i['productCodesSet'] = self._convert_to_set([], 'product_codes') - i['instanceType'] = instance['instance_type'] + if instance['instance_type']: + i['instanceType'] = instance['instance_type'].get('name', None) + else: + i['instanceType'] = None i['launchTime'] = instance['created_at'] i['amiLaunchIndex'] = instance['launch_index'] i['displayName'] = instance['display_name'] @@ -805,7 +808,7 @@ class CloudController(object): ramdisk = self._get_image(context, kwargs['ramdisk_id']) kwargs['ramdisk_id'] = ramdisk['id'] instances = self.compute_api.create(context, - instance_type=instance_types.get_by_type( + instance_type=instance_types.get_instance_type_by_name( kwargs.get('instance_type', None)), image_id=self._get_image(context, kwargs['image_id'])['id'], min_count=int(kwargs.get('min_count', max_count)), diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 4e2ebb2bd..327911f6f 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -160,9 +160,11 @@ class Controller(wsgi.Controller): name = name.strip() try: + inst_type = \ + instance_types.get_instance_type_by_flavor_id(flavor_id) (inst,) = self.compute_api.create( context, - instance_types.get_by_flavor_id(flavor_id), + inst_type, image_id, kernel_id=kernel_id, ramdisk_id=ramdisk_id, @@ -175,7 +177,7 @@ class Controller(wsgi.Controller): except quota.QuotaError as error: self._handle_quota_error(error) - inst['instance_type'] = flavor_id + inst['instance_type'] = inst_type inst['image_id'] = requested_image_id builder = self._get_view_builder(req) diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index 4e7f62eb3..2f400eef6 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -115,7 +115,7 @@ class ViewBuilderV10(ViewBuilder): def _build_flavor(self, response, inst): if 'instance_type' in dict(inst): - response['flavorId'] = inst['instance_type'] + response['flavorId'] = inst['instance_type']['flavorid'] class ViewBuilderV11(ViewBuilder): @@ -134,7 +134,7 @@ class ViewBuilderV11(ViewBuilder): def _build_flavor(self, response, inst): if "instance_type" in dict(inst): - flavor_id = inst["instance_type"] + flavor_id = inst["instance_type"]['flavorid'] flavor_ref = self.flavor_builder.generate_href(flavor_id) response["flavorRef"] = flavor_ref diff --git a/nova/compute/api.py b/nova/compute/api.py index 1dbd73f8f..363d61f29 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -110,8 +110,11 @@ class API(base.Base): """Create the number of instances requested if quota and other arguments check out ok.""" - type_data = instance_types.get_instance_type(instance_type) - num_instances = quota.allowed_instances(context, max_count, type_data) + if not instance_type: + instance_type = instance_types.get_default_instance_type() + + num_instances = quota.allowed_instances(context, max_count, + instance_type) if num_instances < min_count: pid = context.project_id LOG.warn(_("Quota exceeeded for %(pid)s," @@ -197,10 +200,10 @@ class API(base.Base): 'user_id': context.user_id, 'project_id': context.project_id, 'launch_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()), - 'instance_type': instance_type, - 'memory_mb': type_data['memory_mb'], - 'vcpus': type_data['vcpus'], - 'local_gb': type_data['local_gb'], + 'instance_type_id': instance_type['id'], + 'memory_mb': instance_type['memory_mb'], + 'vcpus': instance_type['vcpus'], + 'local_gb': instance_type['local_gb'], 'display_name': display_name, 'display_description': display_description, 'user_data': user_data or '', @@ -517,8 +520,7 @@ class API(base.Base): def resize(self, context, instance_id, flavor_id): """Resize a running instance.""" instance = self.db.instance_get(context, instance_id) - current_instance_type = self.db.instance_type_get_by_name( - context, instance['instance_type']) + current_instance_type = instance['instance_type'] new_instance_type = self.db.instance_type_get_by_flavor_id( context, flavor_id) diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index fa02a5dfa..5b1d92e29 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -101,41 +101,43 @@ def get_all_flavors(): return get_all_types(context.get_admin_context()) -def get_instance_type(name): - """Retrieves single instance type by name""" - if name is None: - return FLAGS.default_instance_type +def get_default_instance_type(): + name = FLAGS.default_instance_type try: - ctxt = context.get_admin_context() - inst_type = db.instance_type_get_by_name(ctxt, name) - return inst_type + return get_instance_type_by_name(name) except exception.DBError: raise exception.ApiError(_("Unknown instance type: %s" % name)) -def get_by_type(instance_type): - """retrieve instance type name""" - if instance_type is None: - return FLAGS.default_instance_type +def get_instance_type(id): + """Retrieves single instance type by id""" + if id is None: + return get_default_instance_type() + try: + ctxt = context.get_admin_context() + return db.instance_type_get_by_id(ctxt, id) + except exception.DBError: + raise exception.ApiError(_("Unknown instance type: %s" % name)) + +def get_instance_type_by_name(name): + """Retrieves single instance type by name""" + if name is None: + return get_default_instance_type() try: ctxt = context.get_admin_context() - inst_type = db.instance_type_get_by_name(ctxt, instance_type) - return inst_type['name'] - except exception.DBError, e: - LOG.exception(_('DB error: %s' % e)) - raise exception.ApiError(_("Unknown instance type: %s" %\ - instance_type)) + return db.instance_type_get_by_name(ctxt, name) + except exception.DBError: + raise exception.ApiError(_("Unknown instance type: %s" % name)) -def get_by_flavor_id(flavor_id): - """retrieve instance type's name by flavor_id""" +def get_instance_type_by_flavor_id(flavor_id): + """retrieve instance type by flavor_id""" if flavor_id is None: - return FLAGS.default_instance_type + return get_default_instance_type() try: ctxt = context.get_admin_context() - flavor = db.instance_type_get_by_flavor_id(ctxt, flavor_id) - return flavor['name'] + return db.instance_type_get_by_flavor_id(ctxt, flavor_id) except exception.DBError, e: LOG.exception(_('DB error: %s' % e)) raise exception.ApiError(_("Unknown flavor: %s" % flavor_id)) diff --git a/nova/db/api.py b/nova/db/api.py index fd3c63b76..63901e94d 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -1124,6 +1124,11 @@ def instance_type_get_all(context, inactive=False): return IMPL.instance_type_get_all(context, inactive) +def instance_type_get_by_id(context, id): + """Get instance type by id""" + return IMPL.instance_type_get_by_id(context, id) + + def instance_type_get_by_name(context, name): """Get instance type by name""" return IMPL.instance_type_get_by_name(context, name) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index b2a13a01b..9f600b236 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -829,6 +829,7 @@ def instance_get(context, instance_id, session=None): options(joinedload('volumes')).\ options(joinedload_all('fixed_ip.network')).\ options(joinedload('metadata')).\ + options(joinedload('instance_type')).\ filter_by(id=instance_id).\ filter_by(deleted=can_read_deleted(context)).\ first() @@ -838,6 +839,7 @@ def instance_get(context, instance_id, session=None): options(joinedload_all('security_groups.rules')).\ options(joinedload('volumes')).\ options(joinedload('metadata')).\ + options(joinedload('instance_type')).\ filter_by(project_id=context.project_id).\ filter_by(id=instance_id).\ filter_by(deleted=False).\ @@ -857,6 +859,7 @@ def instance_get_all(context): options(joinedload_all('fixed_ip.floating_ips')).\ options(joinedload('security_groups')).\ options(joinedload_all('fixed_ip.network')).\ + options(joinedload('instance_type')).\ filter_by(deleted=can_read_deleted(context)).\ all() @@ -868,6 +871,7 @@ def instance_get_all_by_user(context, user_id): options(joinedload_all('fixed_ip.floating_ips')).\ options(joinedload('security_groups')).\ options(joinedload_all('fixed_ip.network')).\ + options(joinedload('instance_type')).\ filter_by(deleted=can_read_deleted(context)).\ filter_by(user_id=user_id).\ all() @@ -880,6 +884,7 @@ def instance_get_all_by_host(context, host): options(joinedload_all('fixed_ip.floating_ips')).\ options(joinedload('security_groups')).\ options(joinedload_all('fixed_ip.network')).\ + options(joinedload('instance_type')).\ filter_by(host=host).\ filter_by(deleted=can_read_deleted(context)).\ all() @@ -894,6 +899,7 @@ def instance_get_all_by_project(context, project_id): options(joinedload_all('fixed_ip.floating_ips')).\ options(joinedload('security_groups')).\ options(joinedload_all('fixed_ip.network')).\ + options(joinedload('instance_type')).\ filter_by(project_id=project_id).\ filter_by(deleted=can_read_deleted(context)).\ all() @@ -908,6 +914,7 @@ def instance_get_all_by_reservation(context, reservation_id): options(joinedload_all('fixed_ip.floating_ips')).\ options(joinedload('security_groups')).\ options(joinedload_all('fixed_ip.network')).\ + options(joinedload('instance_type')).\ filter_by(reservation_id=reservation_id).\ filter_by(deleted=can_read_deleted(context)).\ all() @@ -916,6 +923,7 @@ def instance_get_all_by_reservation(context, reservation_id): options(joinedload_all('fixed_ip.floating_ips')).\ options(joinedload('security_groups')).\ options(joinedload_all('fixed_ip.network')).\ + options(joinedload('instance_type')).\ filter_by(project_id=context.project_id).\ filter_by(reservation_id=reservation_id).\ filter_by(deleted=False).\ @@ -928,6 +936,7 @@ def instance_get_project_vpn(context, project_id): return session.query(models.Instance).\ options(joinedload_all('fixed_ip.floating_ips')).\ options(joinedload('security_groups')).\ + options(joinedload('instance_type')).\ filter_by(project_id=project_id).\ filter_by(image_id=FLAGS.vpn_image_id).\ filter_by(deleted=can_read_deleted(context)).\ @@ -2368,6 +2377,19 @@ def instance_type_get_all(context, inactive=False): raise exception.NotFound +@require_context +def instance_type_get_by_id(context, id): + """Returns a dict describing specific instance_type""" + session = get_session() + inst_type = session.query(models.InstanceTypes).\ + filter_by(id=id).\ + first() + if not inst_type: + raise exception.NotFound(_("No instance type with id %s") % id) + else: + return dict(inst_type) + + @require_context def instance_type_get_by_name(context, name): """Returns a dict describing specific instance_type""" diff --git a/nova/db/sqlalchemy/migrate_repo/versions/014_add_instance_type_id_to_instances.py b/nova/db/sqlalchemy/migrate_repo/versions/014_add_instance_type_id_to_instances.py new file mode 100644 index 000000000..813e57e10 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/014_add_instance_type_id_to_instances.py @@ -0,0 +1,86 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import * +from sqlalchemy.sql import text +from migrate import * + +#from nova import log as logging + + +meta = MetaData() + + +c_instance_type = Column('instance_type', + String(length=255, convert_unicode=False, + assert_unicode=None, unicode_error=None, + _warn_on_bytestring=False), + nullable=True) + +c_instance_type_id = Column('instance_type_id', + String(length=255, convert_unicode=False, + assert_unicode=None, unicode_error=None, + _warn_on_bytestring=False), + nullable=True) + +instance_types = Table('instance_types', meta, + Column('id', Integer(), primary_key=True, nullable=False), + Column('name', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False), + unique=True)) + + +def upgrade(migrate_engine): + # Upgrade operations go here. Don't create your own engine; + # bind migrate_engine to your metadata + meta.bind = migrate_engine + + instances = Table('instances', meta, autoload=True, + autoload_with=migrate_engine) + + instances.create_column(c_instance_type_id) + + recs = migrate_engine.execute(instance_types.select()) + for row in recs: + type_id = row[0] + type_name = row[1] + migrate_engine.execute(instances.update()\ + .where(instances.c.instance_type == type_name)\ + .values(instance_type_id=type_id)) + + instances.c.instance_type.drop() + #instances.c.instance_type_id.alter(nullable=False) + + +def downgrade(migrate_engine): + meta.bind = migrate_engine + + instances = Table('instances', meta, autoload=True, + autoload_with=migrate_engine) + + instances.create_column(c_instance_type) + + recs = migrate_engine.execute(instance_types.select()) + for row in recs: + type_id = row[0] + type_name = row[1] + migrate_engine.execute(instances.update()\ + .where(instances.c.instance_type_id == type_id)\ + .values(instance_type=type_name)) + + instances.c.instance_type_id.drop() + #instances.c.instance_type.alter(nullable=False) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 3b95ac23e..9d4c6cdef 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -209,7 +209,7 @@ class Instance(BASE, NovaBase): hostname = Column(String(255)) host = Column(String(255)) # , ForeignKey('hosts.id')) - instance_type = Column(String(255)) + instance_type_id = Column(String(255)) user_data = Column(Text) @@ -258,7 +258,8 @@ class InstanceActions(BASE, NovaBase): class InstanceTypes(BASE, NovaBase): """Represent possible instance_types or flavor of VM offered""" __tablename__ = "instance_types" - id = Column(Integer, primary_key=True) + id = Column(Integer, ForeignKey('instances.instance_type_id'), + primary_key=True) name = Column(String(255), unique=True) memory_mb = Column(Integer) vcpus = Column(Integer) @@ -268,6 +269,12 @@ class InstanceTypes(BASE, NovaBase): rxtx_quota = Column(Integer, nullable=False, default=0) rxtx_cap = Column(Integer, nullable=False, default=0) + instances = relationship(Instance, + backref=backref('instance_type', uselist=False), + foreign_keys=id, + primaryjoin='and_(Instance.instance_type_id == ' + 'InstanceTypes.id)') + class Volume(BASE, NovaBase): """Represents a block storage device that can be attached to a vm.""" diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index cb5047da9..899dcf7f7 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -32,6 +32,7 @@ from nova import test import nova.api.openstack from nova.api.openstack import servers import nova.compute.api +from nova.compute import instance_types import nova.db.api from nova.db.sqlalchemy.models import Instance from nova.db.sqlalchemy.models import InstanceMetadata @@ -71,13 +72,19 @@ def instance_address(context, instance_id): return None -def stub_instance(id, user_id=1, private_address=None, public_addresses=None): +def stub_instance(id, user_id=1, private_address=None, public_addresses=None, + host=None): metadata = [] metadata.append(InstanceMetadata(key='seq', value=id)) + inst_type = instance_types.get_instance_type_by_flavor_id(1) + if public_addresses == None: public_addresses = list() + if host != None: + host = str(host) + instance = { "id": id, "admin_pass": "", @@ -95,8 +102,8 @@ def stub_instance(id, user_id=1, private_address=None, public_addresses=None): "vcpus": 0, "local_gb": 0, "hostname": "", - "host": None, - "instance_type": "1", + "host": host, + "instance_type": dict(inst_type), "user_data": "", "reservation_id": "", "mac_address": "", @@ -630,7 +637,7 @@ class ServersTest(test.TestCase): self.assertEqual(s['hostId'], '') self.assertEqual(s['name'], 'server%d' % i) self.assertEqual(s['imageId'], '10') - self.assertEqual(s['flavorId'], '1') + self.assertEqual(s['flavorId'], 1) self.assertEqual(s['metadata']['seq'], i) def test_get_all_server_details_v1_1(self): @@ -654,12 +661,8 @@ class ServersTest(test.TestCase): instances - 2 on one host and 3 on another. ''' - def stub_instance(id, user_id=1): - return Instance(id=id, state=0, image_id=10, user_id=user_id, - display_name='server%s' % id, host='host%s' % (id % 2)) - def return_servers_with_host(context, user_id=1): - return [stub_instance(i) for i in xrange(5)] + return [stub_instance(i, 1, None, None, i % 2) for i in xrange(5)] self.stubs.Set(nova.db.api, 'instance_get_all_by_user', return_servers_with_host) @@ -677,7 +680,8 @@ class ServersTest(test.TestCase): self.assertEqual(s['id'], i) self.assertEqual(s['hostId'], host_ids[i % 2]) self.assertEqual(s['name'], 'server%d' % i) - self.assertEqual(s['imageId'], 10) + self.assertEqual(s['imageId'], '10') + self.assertEqual(s['flavorId'], 1) def test_server_pause(self): FLAGS.allow_admin_api = True diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py index 7ddfe377a..58d251b1e 100644 --- a/nova/tests/db/fakes.py +++ b/nova/tests/db/fakes.py @@ -28,29 +28,34 @@ def stub_out_db_instance_api(stubs, injected=True): """Stubs out the db API for creating Instances.""" INSTANCE_TYPES = { - 'm1.tiny': dict(memory_mb=512, + 'm1.tiny': dict(id=2, + memory_mb=512, vcpus=1, local_gb=0, flavorid=1, rxtx_cap=1), - 'm1.small': dict(memory_mb=2048, + 'm1.small': dict(id=5, + memory_mb=2048, vcpus=1, local_gb=20, flavorid=2, rxtx_cap=2), 'm1.medium': - dict(memory_mb=4096, + dict(id=1, + memory_mb=4096, vcpus=2, local_gb=40, flavorid=3, rxtx_cap=3), - 'm1.large': dict(memory_mb=8192, + 'm1.large': dict(id=3, + memory_mb=8192, vcpus=4, local_gb=80, flavorid=4, rxtx_cap=4), 'm1.xlarge': - dict(memory_mb=16384, + dict(id=4, + memory_mb=16384, vcpus=8, local_gb=160, flavorid=5, @@ -107,6 +112,12 @@ def stub_out_db_instance_api(stubs, injected=True): def fake_instance_type_get_by_name(context, name): return INSTANCE_TYPES[name] + def fake_instance_type_get_by_id(context, id): + for name, inst_type in INSTANCE_TYPES.iteritems(): + if str(inst_type['id']) == str(id): + return inst_type + return None + def fake_network_get_by_instance(context, instance_id): # Even instance numbers are on vlan networks if instance_id % 2 == 0: @@ -136,6 +147,7 @@ def stub_out_db_instance_api(stubs, injected=True): fake_network_get_all_by_instance) stubs.Set(db, 'instance_type_get_all', fake_instance_type_get_all) stubs.Set(db, 'instance_type_get_by_name', fake_instance_type_get_by_name) + stubs.Set(db, 'instance_type_get_by_id', fake_instance_type_get_by_id) stubs.Set(db, 'instance_get_fixed_address', fake_instance_get_fixed_address) stubs.Set(db, 'instance_get_fixed_address_v6', diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index 1b0f426d2..1917dff3e 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -84,7 +84,8 @@ class ComputeTestCase(test.TestCase): inst['launch_time'] = '10' inst['user_id'] = self.user.id inst['project_id'] = self.project.id - inst['instance_type'] = 'm1.tiny' + type_id = instance_types.get_instance_type_by_name('m1.tiny')['id'] + inst['instance_type_id'] = type_id inst['mac_address'] = utils.generate_mac() inst['ami_launch_index'] = 0 inst.update(params) @@ -132,7 +133,7 @@ class ComputeTestCase(test.TestCase): cases = [dict(), dict(display_name=None)] for instance in cases: ref = self.compute_api.create(self.context, - FLAGS.default_instance_type, None, **instance) + instance_types.get_default_instance_type(), None, **instance) try: self.assertNotEqual(ref[0]['display_name'], None) finally: @@ -143,7 +144,7 @@ class ComputeTestCase(test.TestCase): group = self._create_group() ref = self.compute_api.create( self.context, - instance_type=FLAGS.default_instance_type, + instance_type=instance_types.get_default_instance_type(), image_id=None, security_group=['testgroup']) try: @@ -161,7 +162,7 @@ class ComputeTestCase(test.TestCase): ref = self.compute_api.create( self.context, - instance_type=FLAGS.default_instance_type, + instance_type=instance_types.get_default_instance_type(), image_id=None, security_group=['testgroup']) try: @@ -177,7 +178,7 @@ class ComputeTestCase(test.TestCase): ref = self.compute_api.create( self.context, - instance_type=FLAGS.default_instance_type, + instance_type=instance_types.get_default_instance_type(), image_id=None, security_group=['testgroup']) @@ -359,8 +360,9 @@ class ComputeTestCase(test.TestCase): instance_id = self._create_instance() self.compute.run_instance(self.context, instance_id) + inst_type = instance_types.get_instance_type_by_name('m1.xlarge') db.instance_update(self.context, instance_id, - {'instance_type': 'm1.xlarge'}) + {'instance_type_id': inst_type['id']}) self.assertRaises(exception.ApiError, self.compute_api.resize, context, instance_id, 1) @@ -380,8 +382,8 @@ class ComputeTestCase(test.TestCase): self.compute.terminate_instance(context, instance_id) def test_get_by_flavor_id(self): - type = instance_types.get_by_flavor_id(1) - self.assertEqual(type, 'm1.tiny') + type = instance_types.get_instance_type_by_flavor_id(1) + self.assertEqual(type['name'], 'm1.tiny') def test_resize_same_source_fails(self): """Ensure instance fails to migrate when source and destination are diff --git a/nova/tests/test_console.py b/nova/tests/test_console.py index d47c70d88..1a9a867ee 100644 --- a/nova/tests/test_console.py +++ b/nova/tests/test_console.py @@ -62,7 +62,7 @@ class ConsoleTestCase(test.TestCase): inst['launch_time'] = '10' inst['user_id'] = self.user.id inst['project_id'] = self.project.id - inst['instance_type'] = 'm1.tiny' + inst['instance_type_id'] = 1 inst['mac_address'] = utils.generate_mac() inst['ami_launch_index'] = 0 return db.instance_create(self.context, inst)['id'] diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index edc538879..5d6d5e1f4 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -40,7 +40,11 @@ class InstanceTypeTestCase(test.TestCase): max_flavorid = session.query(models.InstanceTypes).\ order_by("flavorid desc").\ first() + max_id = session.query(models.InstanceTypes).\ + order_by("id desc").\ + first() self.flavorid = max_flavorid["flavorid"] + 1 + self.id = max_id["id"] + 1 self.name = str(int(time.time())) def test_instance_type_create_then_delete(self): @@ -53,7 +57,7 @@ class InstanceTypeTestCase(test.TestCase): 'instance type was not created') instance_types.destroy(self.name) self.assertEqual(1, - instance_types.get_instance_type(self.name)["deleted"]) + instance_types.get_instance_type(self.id)["deleted"]) self.assertEqual(starting_inst_list, instance_types.get_all_types()) instance_types.purge(self.name) self.assertEqual(len(starting_inst_list), diff --git a/nova/tests/test_quota.py b/nova/tests/test_quota.py index c65bc459d..39a123158 100644 --- a/nova/tests/test_quota.py +++ b/nova/tests/test_quota.py @@ -67,7 +67,7 @@ class QuotaTestCase(test.TestCase): inst['reservation_id'] = 'r-fakeres' inst['user_id'] = self.user.id inst['project_id'] = self.project.id - inst['instance_type'] = 'm1.large' + inst['instance_type_id'] = '3' # m1.large inst['vcpus'] = cores inst['mac_address'] = utils.generate_mac() return db.instance_create(self.context, inst)['id'] @@ -124,11 +124,12 @@ class QuotaTestCase(test.TestCase): for i in range(FLAGS.quota_instances): instance_id = self._create_instance() instance_ids.append(instance_id) + inst_type = instance_types.get_instance_type_by_name('m1.small') self.assertRaises(quota.QuotaError, compute.API().create, self.context, min_count=1, max_count=1, - instance_type='m1.small', + instance_type=inst_type, image_id=1) for instance_id in instance_ids: db.instance_destroy(self.context, instance_id) @@ -137,11 +138,12 @@ class QuotaTestCase(test.TestCase): instance_ids = [] instance_id = self._create_instance(cores=4) instance_ids.append(instance_id) + inst_type = instance_types.get_instance_type_by_name('m1.small') self.assertRaises(quota.QuotaError, compute.API().create, self.context, min_count=1, max_count=1, - instance_type='m1.small', + instance_type=inst_type, image_id=1) for instance_id in instance_ids: db.instance_destroy(self.context, instance_id) @@ -192,11 +194,12 @@ class QuotaTestCase(test.TestCase): metadata = {} for i in range(FLAGS.quota_metadata_items + 1): metadata['key%s' % i] = 'value%s' % i + inst_type = instance_types.get_instance_type_by_name('m1.small') self.assertRaises(quota.QuotaError, compute.API().create, self.context, min_count=1, max_count=1, - instance_type='m1.small', + instance_type=inst_type, image_id='fake', metadata=metadata) @@ -207,13 +210,15 @@ class QuotaTestCase(test.TestCase): def _create_with_injected_files(self, files): api = compute.API(image_service=self.StubImageService()) + inst_type = instance_types.get_instance_type_by_name('m1.small') api.create(self.context, min_count=1, max_count=1, - instance_type='m1.small', image_id='fake', + instance_type=inst_type, image_id='fake', injected_files=files) def test_no_injected_files(self): api = compute.API(image_service=self.StubImageService()) - api.create(self.context, instance_type='m1.small', image_id='fake') + inst_type = instance_types.get_instance_type_by_name('m1.small') + api.create(self.context, instance_type=inst_type, image_id='fake') def test_max_injected_files(self): files = [] diff --git a/nova/tests/test_scheduler.py b/nova/tests/test_scheduler.py index 6df74dd61..ae56a1a16 100644 --- a/nova/tests/test_scheduler.py +++ b/nova/tests/test_scheduler.py @@ -263,7 +263,7 @@ class SimpleDriverTestCase(test.TestCase): inst['reservation_id'] = 'r-fakeres' inst['user_id'] = self.user.id inst['project_id'] = self.project.id - inst['instance_type'] = 'm1.tiny' + inst['instance_type_id'] = '1' inst['mac_address'] = utils.generate_mac() inst['vcpus'] = kwargs.get('vcpus', 1) inst['ami_launch_index'] = 0 diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 958c8e3e2..c13cbf043 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -140,7 +140,7 @@ class LibvirtConnTestCase(test.TestCase): 'vcpus': 2, 'project_id': 'fake', 'bridge': 'br101', - 'instance_type': 'm1.small'} + 'instance_type_id': '5'} # m1.small def lazy_load_library_exists(self): """check if libvirt is available.""" diff --git a/nova/tests/test_volume.py b/nova/tests/test_volume.py index d71b75f3f..e9d8289aa 100644 --- a/nova/tests/test_volume.py +++ b/nova/tests/test_volume.py @@ -106,7 +106,7 @@ class VolumeTestCase(test.TestCase): inst['launch_time'] = '10' inst['user_id'] = 'fake' inst['project_id'] = 'fake' - inst['instance_type'] = 'm1.tiny' + inst['instance_type_id'] = '2' # m1.tiny inst['mac_address'] = utils.generate_mac() inst['ami_launch_index'] = 0 instance_id = db.instance_create(self.context, inst)['id'] diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 17e3f55e9..665ec068e 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -80,7 +80,7 @@ class XenAPIVolumeTestCase(test.TestCase): 'image_id': 1, 'kernel_id': 2, 'ramdisk_id': 3, - 'instance_type': 'm1.large', + 'instance_type_id': '3', # m1.large 'mac_address': 'aa:bb:cc:dd:ee:ff', 'os_type': 'linux'} @@ -328,7 +328,7 @@ class XenAPIVMTestCase(test.TestCase): self.assertEquals(self.vm['HVM_boot_policy'], '') def _test_spawn(self, image_id, kernel_id, ramdisk_id, - instance_type="m1.large", os_type="linux", + instance_type_id="3", os_type="linux", instance_id=1, check_injection=False): stubs.stubout_loopingcall_start(self.stubs) values = {'id': instance_id, @@ -337,7 +337,7 @@ class XenAPIVMTestCase(test.TestCase): 'image_id': image_id, 'kernel_id': kernel_id, 'ramdisk_id': ramdisk_id, - 'instance_type': instance_type, + 'instance_type_id': instance_type_id, 'mac_address': 'aa:bb:cc:dd:ee:ff', 'os_type': os_type} instance = db.instance_create(self.context, values) @@ -349,7 +349,7 @@ class XenAPIVMTestCase(test.TestCase): FLAGS.xenapi_image_service = 'glance' self.assertRaises(Exception, self._test_spawn, - 1, 2, 3, "m1.xlarge") + 1, 2, 3, "4") # m1.xlarge def test_spawn_raw_objectstore(self): FLAGS.xenapi_image_service = 'objectstore' @@ -523,7 +523,7 @@ class XenAPIVMTestCase(test.TestCase): 'image_id': 1, 'kernel_id': 2, 'ramdisk_id': 3, - 'instance_type': 'm1.large', + 'instance_type_id': '3', # m1.large 'mac_address': 'aa:bb:cc:dd:ee:ff', 'os_type': 'linux'} instance = db.instance_create(self.context, values) @@ -580,7 +580,7 @@ class XenAPIMigrateInstance(test.TestCase): 'kernel_id': None, 'ramdisk_id': None, 'local_gb': 5, - 'instance_type': 'm1.large', + 'instance_type_id': '3', # m1.large 'mac_address': 'aa:bb:cc:dd:ee:ff', 'os_type': 'linux'} diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index f34ea7225..6b7fce634 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -797,7 +797,10 @@ class LibvirtConnection(driver.ComputeDriver): root_fname = '%08x' % int(disk_images['image_id']) size = FLAGS.minimum_root_size - if inst['instance_type'] == 'm1.tiny' or suffix == '.rescue': + + inst_type_id = instance['instance_type_id'] + inst_type = instance_types.get_instance_type(inst_type_id) + if inst_type['name'] == 'm1.tiny' or suffix == '.rescue': size = None root_fname += "_sm" @@ -809,14 +812,13 @@ class LibvirtConnection(driver.ComputeDriver): user=user, project=project, size=size) - type_data = instance_types.get_instance_type(inst['instance_type']) - if type_data['local_gb']: + if inst_type['local_gb']: self._cache_image(fn=self._create_local, target=basepath('disk.local'), - fname="local_%s" % type_data['local_gb'], + fname="local_%s" % inst_type['local_gb'], cow=FLAGS.use_cow_images, - local_gb=type_data['local_gb']) + local_gb=inst_type['local_gb']) # For now, we assume that if we're not using a kernel, we're using a # partitioned disk image where the target partition is the first @@ -950,8 +952,8 @@ class LibvirtConnection(driver.ComputeDriver): nics.append(self._get_nic_for_xml(network, mapping)) # FIXME(vish): stick this in db - instance_type_name = instance['instance_type'] - instance_type = instance_types.get_instance_type(instance_type_name) + inst_type_id = instance['instance_type_id'] + inst_type = instance_types.get_instance_type(inst_type_id) if FLAGS.use_cow_images: driver_type = 'qcow2' @@ -962,10 +964,10 @@ class LibvirtConnection(driver.ComputeDriver): 'name': instance['name'], 'basepath': os.path.join(FLAGS.instances_path, instance['name']), - 'memory_kb': instance_type['memory_mb'] * 1024, - 'vcpus': instance_type['vcpus'], + 'memory_kb': inst_type['memory_mb'] * 1024, + 'vcpus': inst_type['vcpus'], 'rescue': rescue, - 'local': instance_type['local_gb'], + 'local': inst_type['local_gb'], 'driver_type': driver_type, 'nics': nics} diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index d07d60800..fd4f3705a 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -101,8 +101,8 @@ class VMHelper(HelperBase): 3. Using hardware virtualization """ - instance_type = instance_types.\ - get_instance_type(instance.instance_type) + inst_type_id = instance.instance_type_id + instance_type = instance_types.get_instance_type(inst_type_id) mem = str(long(instance_type['memory_mb']) * 1024 * 1024) vcpus = str(instance_type['vcpus']) rec = { @@ -169,8 +169,8 @@ class VMHelper(HelperBase): @classmethod def ensure_free_mem(cls, session, instance): - instance_type = instance_types.get_instance_type( - instance.instance_type) + inst_type_id = instance.instance_type_id + instance_type = instance_types.get_instance_type(inst_type_id) mem = long(instance_type['memory_mb']) * 1024 * 1024 #get free memory from host host = session.get_xenapi_host() diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index c96c35a6e..c26965c9a 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -802,8 +802,10 @@ class VMOps(object): instance['id']) networks = db.network_get_all_by_instance(admin_context, instance['id']) - flavor = db.instance_type_get_by_name(admin_context, - instance['instance_type']) + + inst_type = db.instance_type_get_by_id(admin_context, + instance['instance_type_id']) + network_info = [] for network in networks: network_IPs = [ip for ip in IPs if ip.network_id == network.id] @@ -827,7 +829,7 @@ class VMOps(object): 'gateway': network['gateway'], 'broadcast': network['broadcast'], 'mac': instance.mac_address, - 'rxtx_cap': flavor['rxtx_cap'], + 'rxtx_cap': inst_type['rxtx_cap'], 'dns': [network['dns']], 'ips': [ip_dict(ip) for ip in network_IPs]} if network['cidr_v6']: -- cgit From 5c67809e4b9a1546c48316ea52676dfeba8f1a75 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Mon, 4 Apr 2011 15:58:41 -0700 Subject: openstack api requires uppercase image format status responses --- nova/api/openstack/views/images.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nova/api/openstack/views/images.py b/nova/api/openstack/views/images.py index 16195b050..9dec8a355 100644 --- a/nova/api/openstack/views/images.py +++ b/nova/api/openstack/views/images.py @@ -34,11 +34,11 @@ class ViewBuilder(object): def _format_status(self, image): """Update the status field to standardize format.""" status_mapping = { - 'pending': 'queued', - 'decrypting': 'preparing', - 'untarring': 'saving', - 'available': 'active', - 'killed': 'failed', + 'pending': 'QUEUED', + 'decrypting': 'PREPARING', + 'untarring': 'SAVING', + 'available': 'ACTIVE', + 'killed': 'FAILED', } try: -- cgit From a6c283f00d67a5172d8271d7e48bd58484ac6b96 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Mon, 4 Apr 2011 16:00:59 -0700 Subject: openstack api metadata responses must be strings --- nova/api/openstack/views/servers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index d24c025be..baa911590 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -82,7 +82,8 @@ class ViewBuilder(object): # Return the metadata as a dictionary metadata = {} for item in inst.get('metadata', []): - metadata[item['key']] = item['value'] + # metadata values must be strings per API + metadata[item['key']] = str(item['value']) inst_dict['metadata'] = metadata inst_dict['hostId'] = '' -- cgit From 868288b9705ea765b5515fd0ac9e0858f37239d0 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Mon, 4 Apr 2011 16:07:39 -0700 Subject: correct test for numeric/string metadata value conversion --- nova/tests/api/openstack/test_servers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 313676e72..08a3f5d5a 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -630,7 +630,7 @@ class ServersTest(test.TestCase): self.assertEqual(s['imageId'], '10') self.assertEqual(s['flavorId'], '1') self.assertEqual(s['status'], 'BUILD') - self.assertEqual(s['metadata']['seq'], i) + self.assertEqual(s['metadata']['seq'], str(i)) def test_get_all_server_details_v1_1(self): req = webob.Request.blank('/v1.1/servers/detail') @@ -644,7 +644,7 @@ class ServersTest(test.TestCase): self.assertEqual(s['imageRef'], 'http://localhost/v1.1/images/10') self.assertEqual(s['flavorRef'], 'http://localhost/v1.1/flavors/1') self.assertEqual(s['status'], 'BUILD') - self.assertEqual(s['metadata']['seq'], i) + self.assertEqual(s['metadata']['seq'], str(i)) def test_get_all_server_details_with_host(self): ''' -- cgit From a18fece993c21f2ae1cbb44d8a0dea92d58d3b44 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Mon, 4 Apr 2011 22:16:53 -0400 Subject: Correct variable name. --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index d4cef8d7c..099ef647c 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -798,7 +798,7 @@ class LibvirtConnection(driver.ComputeDriver): root_fname = '%08x' % int(disk_images['image_id']) size = FLAGS.minimum_root_size - inst_type_id = instance['instance_type_id'] + inst_type_id = inst['instance_type_id'] inst_type = instance_types.get_instance_type(inst_type_id) if inst_type['name'] == 'm1.tiny' or suffix == '.rescue': size = None -- cgit From ff23dd2a3b86c816da04eddc903de0c8c3141954 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 5 Apr 2011 11:42:14 +0200 Subject: Allow CA code and state to be separated, and make sure CA code gets installed by setup.py install. --- CA/.gitignore | 11 ------ CA/geninter.sh | 39 ------------------- CA/genrootca.sh | 29 -------------- CA/genvpn.sh | 36 ----------------- CA/newcerts/.placeholder | 0 CA/openssl.cnf.tmpl | 90 ------------------------------------------- CA/private/.placeholder | 0 CA/projects/.gitignore | 1 - CA/projects/.placeholder | 0 CA/reqs/.gitignore | 1 - CA/reqs/.placeholder | 0 MANIFEST.in | 2 +- nova/CA/.gitignore | 11 ++++++ nova/CA/geninter.sh | 39 +++++++++++++++++++ nova/CA/genrootca.sh | 29 ++++++++++++++ nova/CA/genvpn.sh | 36 +++++++++++++++++ nova/CA/newcerts/.placeholder | 0 nova/CA/openssl.cnf.tmpl | 90 +++++++++++++++++++++++++++++++++++++++++++ nova/CA/private/.placeholder | 0 nova/CA/projects/.gitignore | 1 + nova/CA/projects/.placeholder | 0 nova/CA/reqs/.gitignore | 1 + nova/CA/reqs/.placeholder | 0 nova/api/ec2/cloud.py | 8 +++- nova/crypto.py | 10 ++++- 25 files changed, 223 insertions(+), 211 deletions(-) delete mode 100644 CA/.gitignore delete mode 100755 CA/geninter.sh delete mode 100755 CA/genrootca.sh delete mode 100755 CA/genvpn.sh delete mode 100644 CA/newcerts/.placeholder delete mode 100644 CA/openssl.cnf.tmpl delete mode 100644 CA/private/.placeholder delete mode 100644 CA/projects/.gitignore delete mode 100644 CA/projects/.placeholder delete mode 100644 CA/reqs/.gitignore delete mode 100644 CA/reqs/.placeholder create mode 100644 nova/CA/.gitignore create mode 100755 nova/CA/geninter.sh create mode 100755 nova/CA/genrootca.sh create mode 100755 nova/CA/genvpn.sh create mode 100644 nova/CA/newcerts/.placeholder create mode 100644 nova/CA/openssl.cnf.tmpl create mode 100644 nova/CA/private/.placeholder create mode 100644 nova/CA/projects/.gitignore create mode 100644 nova/CA/projects/.placeholder create mode 100644 nova/CA/reqs/.gitignore create mode 100644 nova/CA/reqs/.placeholder diff --git a/CA/.gitignore b/CA/.gitignore deleted file mode 100644 index fae0922bf..000000000 --- a/CA/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -index.txt -index.txt.old -index.txt.attr -index.txt.attr.old -cacert.pem -serial -serial.old -openssl.cnf -private/* -newcerts/* - diff --git a/CA/geninter.sh b/CA/geninter.sh deleted file mode 100755 index 1fbcc9e73..000000000 --- a/CA/geninter.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -# 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. - -# $1 is the id of the project and $2 is the subject of the cert -NAME=$1 -SUBJ=$2 -mkdir -p projects/$NAME -cd projects/$NAME -cp ../../openssl.cnf.tmpl openssl.cnf -sed -i -e s/%USERNAME%/$NAME/g openssl.cnf -mkdir certs crl newcerts private -openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 365 -config ./openssl.cnf -batch -nodes -echo "10" > serial -touch index.txt -# NOTE(vish): Disabling intermediate ca's because we don't actually need them. -# It makes more sense to have each project have its own root ca. -# openssl genrsa -out private/cakey.pem 1024 -config ./openssl.cnf -batch -nodes -# openssl req -new -sha256 -key private/cakey.pem -out ../../reqs/inter$NAME.csr -batch -subj "$SUBJ" -openssl ca -gencrl -config ./openssl.cnf -out crl.pem -if [ "`id -u`" != "`grep nova /etc/passwd | cut -d':' -f3`" ]; then - sudo chown -R nova:nogroup . -fi -# cd ../../ -# openssl ca -extensions v3_ca -days 365 -out INTER/$NAME/cacert.pem -in reqs/inter$NAME.csr -config openssl.cnf -batch diff --git a/CA/genrootca.sh b/CA/genrootca.sh deleted file mode 100755 index 8f2c3ee3f..000000000 --- a/CA/genrootca.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -# 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. - -if [ -f "cacert.pem" ]; -then - echo "Not installing, it's already done." -else - cp openssl.cnf.tmpl openssl.cnf - sed -i -e s/%USERNAME%/ROOT/g openssl.cnf - openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 365 -config ./openssl.cnf -batch -nodes - touch index.txt - echo "10" > serial - openssl ca -gencrl -config ./openssl.cnf -out crl.pem -fi diff --git a/CA/genvpn.sh b/CA/genvpn.sh deleted file mode 100755 index 7e7db185d..000000000 --- a/CA/genvpn.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -# 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. - -# This gets zipped and run on the cloudpipe-managed OpenVPN server -NAME=$1 -SUBJ=$2 - -mkdir -p projects/$NAME -cd projects/$NAME - -# generate a server priv key -openssl genrsa -out server.key 2048 - -# generate a server CSR -openssl req -new -key server.key -out server.csr -batch -subj "$SUBJ" - -novauid=`getent passwd nova | awk -F: '{print $3}'` -if [ ! -z "${novauid}" ] && [ "`id -u`" != "${novauid}" ]; then - sudo chown -R nova:nogroup . -fi diff --git a/CA/newcerts/.placeholder b/CA/newcerts/.placeholder deleted file mode 100644 index e69de29bb..000000000 diff --git a/CA/openssl.cnf.tmpl b/CA/openssl.cnf.tmpl deleted file mode 100644 index dd81f1c2b..000000000 --- a/CA/openssl.cnf.tmpl +++ /dev/null @@ -1,90 +0,0 @@ -# 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. - -# -# OpenSSL configuration file. -# - -# Establish working directory. - -dir = . - -[ ca ] -default_ca = CA_default - -[ CA_default ] -serial = $dir/serial -database = $dir/index.txt -new_certs_dir = $dir/newcerts -certificate = $dir/cacert.pem -private_key = $dir/private/cakey.pem -unique_subject = no -default_crl_days = 365 -default_days = 365 -default_md = md5 -preserve = no -email_in_dn = no -nameopt = default_ca -certopt = default_ca -policy = policy_match - -[ policy_match ] -countryName = match -stateOrProvinceName = match -organizationName = optional -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - - -[ req ] -default_bits = 1024 # Size of keys -default_keyfile = key.pem # name of generated keys -default_md = md5 # message digest algorithm -string_mask = nombstr # permitted characters -distinguished_name = req_distinguished_name - -[ req_distinguished_name ] -# Variable name Prompt string -#---------------------- ---------------------------------- -0.organizationName = Organization Name (company) -organizationalUnitName = Organizational Unit Name (department, division) -emailAddress = Email Address -emailAddress_max = 40 -localityName = Locality Name (city, district) -stateOrProvinceName = State or Province Name (full name) -countryName = Country Name (2 letter code) -countryName_min = 2 -countryName_max = 2 -commonName = Common Name (hostname, IP, or your name) -commonName_max = 64 - -# Default values for the above, for consistency and less typing. -# Variable name Value -#------------------------------ ------------------------------ -0.organizationName_default = NOVA %USERNAME% -localityName_default = Mountain View -stateOrProvinceName_default = California -countryName_default = US - -[ v3_ca ] -basicConstraints = CA:TRUE -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid:always,issuer:always - -[ v3_req ] -basicConstraints = CA:FALSE -subjectKeyIdentifier = hash diff --git a/CA/private/.placeholder b/CA/private/.placeholder deleted file mode 100644 index e69de29bb..000000000 diff --git a/CA/projects/.gitignore b/CA/projects/.gitignore deleted file mode 100644 index 72e8ffc0d..000000000 --- a/CA/projects/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* diff --git a/CA/projects/.placeholder b/CA/projects/.placeholder deleted file mode 100644 index e69de29bb..000000000 diff --git a/CA/reqs/.gitignore b/CA/reqs/.gitignore deleted file mode 100644 index 72e8ffc0d..000000000 --- a/CA/reqs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* diff --git a/CA/reqs/.placeholder b/CA/reqs/.placeholder deleted file mode 100644 index e69de29bb..000000000 diff --git a/MANIFEST.in b/MANIFEST.in index bf30d1546..e7a6e7da4 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,7 +1,7 @@ include HACKING LICENSE run_tests.py run_tests.sh include README builddeb.sh exercise_rsapi.py include ChangeLog MANIFEST.in pylintrc Authors -graft CA +graft nova/CA graft doc graft smoketests graft tools diff --git a/nova/CA/.gitignore b/nova/CA/.gitignore new file mode 100644 index 000000000..fae0922bf --- /dev/null +++ b/nova/CA/.gitignore @@ -0,0 +1,11 @@ +index.txt +index.txt.old +index.txt.attr +index.txt.attr.old +cacert.pem +serial +serial.old +openssl.cnf +private/* +newcerts/* + diff --git a/nova/CA/geninter.sh b/nova/CA/geninter.sh new file mode 100755 index 000000000..1fbcc9e73 --- /dev/null +++ b/nova/CA/geninter.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# 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. + +# $1 is the id of the project and $2 is the subject of the cert +NAME=$1 +SUBJ=$2 +mkdir -p projects/$NAME +cd projects/$NAME +cp ../../openssl.cnf.tmpl openssl.cnf +sed -i -e s/%USERNAME%/$NAME/g openssl.cnf +mkdir certs crl newcerts private +openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 365 -config ./openssl.cnf -batch -nodes +echo "10" > serial +touch index.txt +# NOTE(vish): Disabling intermediate ca's because we don't actually need them. +# It makes more sense to have each project have its own root ca. +# openssl genrsa -out private/cakey.pem 1024 -config ./openssl.cnf -batch -nodes +# openssl req -new -sha256 -key private/cakey.pem -out ../../reqs/inter$NAME.csr -batch -subj "$SUBJ" +openssl ca -gencrl -config ./openssl.cnf -out crl.pem +if [ "`id -u`" != "`grep nova /etc/passwd | cut -d':' -f3`" ]; then + sudo chown -R nova:nogroup . +fi +# cd ../../ +# openssl ca -extensions v3_ca -days 365 -out INTER/$NAME/cacert.pem -in reqs/inter$NAME.csr -config openssl.cnf -batch diff --git a/nova/CA/genrootca.sh b/nova/CA/genrootca.sh new file mode 100755 index 000000000..8f2c3ee3f --- /dev/null +++ b/nova/CA/genrootca.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# 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. + +if [ -f "cacert.pem" ]; +then + echo "Not installing, it's already done." +else + cp openssl.cnf.tmpl openssl.cnf + sed -i -e s/%USERNAME%/ROOT/g openssl.cnf + openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 365 -config ./openssl.cnf -batch -nodes + touch index.txt + echo "10" > serial + openssl ca -gencrl -config ./openssl.cnf -out crl.pem +fi diff --git a/nova/CA/genvpn.sh b/nova/CA/genvpn.sh new file mode 100755 index 000000000..7e7db185d --- /dev/null +++ b/nova/CA/genvpn.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# 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. + +# This gets zipped and run on the cloudpipe-managed OpenVPN server +NAME=$1 +SUBJ=$2 + +mkdir -p projects/$NAME +cd projects/$NAME + +# generate a server priv key +openssl genrsa -out server.key 2048 + +# generate a server CSR +openssl req -new -key server.key -out server.csr -batch -subj "$SUBJ" + +novauid=`getent passwd nova | awk -F: '{print $3}'` +if [ ! -z "${novauid}" ] && [ "`id -u`" != "${novauid}" ]; then + sudo chown -R nova:nogroup . +fi diff --git a/nova/CA/newcerts/.placeholder b/nova/CA/newcerts/.placeholder new file mode 100644 index 000000000..e69de29bb diff --git a/nova/CA/openssl.cnf.tmpl b/nova/CA/openssl.cnf.tmpl new file mode 100644 index 000000000..dd81f1c2b --- /dev/null +++ b/nova/CA/openssl.cnf.tmpl @@ -0,0 +1,90 @@ +# 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. + +# +# OpenSSL configuration file. +# + +# Establish working directory. + +dir = . + +[ ca ] +default_ca = CA_default + +[ CA_default ] +serial = $dir/serial +database = $dir/index.txt +new_certs_dir = $dir/newcerts +certificate = $dir/cacert.pem +private_key = $dir/private/cakey.pem +unique_subject = no +default_crl_days = 365 +default_days = 365 +default_md = md5 +preserve = no +email_in_dn = no +nameopt = default_ca +certopt = default_ca +policy = policy_match + +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + + +[ req ] +default_bits = 1024 # Size of keys +default_keyfile = key.pem # name of generated keys +default_md = md5 # message digest algorithm +string_mask = nombstr # permitted characters +distinguished_name = req_distinguished_name + +[ req_distinguished_name ] +# Variable name Prompt string +#---------------------- ---------------------------------- +0.organizationName = Organization Name (company) +organizationalUnitName = Organizational Unit Name (department, division) +emailAddress = Email Address +emailAddress_max = 40 +localityName = Locality Name (city, district) +stateOrProvinceName = State or Province Name (full name) +countryName = Country Name (2 letter code) +countryName_min = 2 +countryName_max = 2 +commonName = Common Name (hostname, IP, or your name) +commonName_max = 64 + +# Default values for the above, for consistency and less typing. +# Variable name Value +#------------------------------ ------------------------------ +0.organizationName_default = NOVA %USERNAME% +localityName_default = Mountain View +stateOrProvinceName_default = California +countryName_default = US + +[ v3_ca ] +basicConstraints = CA:TRUE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always + +[ v3_req ] +basicConstraints = CA:FALSE +subjectKeyIdentifier = hash diff --git a/nova/CA/private/.placeholder b/nova/CA/private/.placeholder new file mode 100644 index 000000000..e69de29bb diff --git a/nova/CA/projects/.gitignore b/nova/CA/projects/.gitignore new file mode 100644 index 000000000..72e8ffc0d --- /dev/null +++ b/nova/CA/projects/.gitignore @@ -0,0 +1 @@ +* diff --git a/nova/CA/projects/.placeholder b/nova/CA/projects/.placeholder new file mode 100644 index 000000000..e69de29bb diff --git a/nova/CA/reqs/.gitignore b/nova/CA/reqs/.gitignore new file mode 100644 index 000000000..72e8ffc0d --- /dev/null +++ b/nova/CA/reqs/.gitignore @@ -0,0 +1 @@ +* diff --git a/nova/CA/reqs/.placeholder b/nova/CA/reqs/.placeholder new file mode 100644 index 000000000..e69de29bb diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 425784e8a..f119bd75c 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -103,10 +103,16 @@ class CloudController(object): # Gen root CA, if we don't have one root_ca_path = os.path.join(FLAGS.ca_path, FLAGS.ca_file) if not os.path.exists(root_ca_path): + genrootca_sh_path = os.path.join(os.path.dirname(__file__), + os.path.pardir, + os.path.pardir, + 'CA', + 'genrootca.sh') + start = os.getcwd() os.chdir(FLAGS.ca_path) # TODO(vish): Do this with M2Crypto instead - utils.runthis(_("Generating root CA: %s"), "sh", "genrootca.sh") + utils.runthis(_("Generating root CA: %s"), "sh", genrootca_sh_path) os.chdir(start) def _get_mpi_data(self, context, project_id): diff --git a/nova/crypto.py b/nova/crypto.py index b112e5b92..2b122e560 100644 --- a/nova/crypto.py +++ b/nova/crypto.py @@ -215,9 +215,12 @@ def generate_x509_cert(user_id, project_id, bits=1024): def _ensure_project_folder(project_id): if not os.path.exists(ca_path(project_id)): + geninter_sh_path = os.path.join(os.path.dirname(__file__), + 'CA', + 'geninter.sh') start = os.getcwd() os.chdir(ca_folder()) - utils.execute('sh', 'geninter.sh', project_id, + utils.execute('sh', geninter_sh_path, project_id, _project_cert_subject(project_id)) os.chdir(start) @@ -227,13 +230,16 @@ def generate_vpn_files(project_id): csr_fn = os.path.join(project_folder, "server.csr") crt_fn = os.path.join(project_folder, "server.crt") + genvpn_sh_path = os.path.join(os.path.dirname(__file__), + 'CA', + 'geninter.sh') if os.path.exists(crt_fn): return _ensure_project_folder(project_id) start = os.getcwd() os.chdir(ca_folder()) # TODO(vish): the shell scripts could all be done in python - utils.execute('sh', 'genvpn.sh', + utils.execute('sh', genvpn_sh_path, project_id, _vpn_cert_subject(project_id)) with open(csr_fn, "r") as csrfile: csr_text = csrfile.read() -- cgit From 7702affdbf09127e3e7cdfafcb6382673914438e Mon Sep 17 00:00:00 2001 From: Masanori Itoh Date: Tue, 5 Apr 2011 18:43:11 +0900 Subject: Remove and from AllocateAddress response, and fix bug #751176. --- nova/api/ec2/cloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 425784e8a..3b333437b 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -777,7 +777,7 @@ class CloudController(object): def allocate_address(self, context, **kwargs): LOG.audit(_("Allocate address"), context=context) public_ip = self.network_api.allocate_floating_ip(context) - return {'addressSet': [{'publicIp': public_ip}]} + return {'publicIp': public_ip} def release_address(self, context, public_ip, **kwargs): LOG.audit(_("Release address %s"), public_ip, context=context) -- cgit From 2b3aea4be35f370c68ac3c24ab15d4851aa28e94 Mon Sep 17 00:00:00 2001 From: Kei Masumoto Date: Tue, 5 Apr 2011 20:10:10 +0900 Subject: fix bug 746821 --- nova/tests/test_virt.py | 3 ++- nova/virt/libvirt_conn.py | 38 +++++++++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 958c8e3e2..2e9eac0d5 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -479,7 +479,7 @@ class LibvirtConnTestCase(test.TestCase): fake_timer = FakeTime() - self.create_fake_libvirt_mock(nwfilterLookupByName=fake_raise) + self.create_fake_libvirt_mock() instance_ref = db.instance_create(self.context, self.test_instance) # Start test @@ -488,6 +488,7 @@ class LibvirtConnTestCase(test.TestCase): conn = libvirt_conn.LibvirtConnection(False) conn.firewall_driver.setattr('setup_basic_filtering', fake_none) conn.firewall_driver.setattr('prepare_instance_filter', fake_none) + conn.firewall_driver.setattr('instance_filter_exists', fake_none) conn.ensure_filtering_rules_for_instance(instance_ref, time=fake_timer) except exception.Error, e: diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index babbc610d..bdf577825 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1401,18 +1401,13 @@ class LibvirtConnection(driver.ComputeDriver): # wait for completion timeout_count = range(FLAGS.live_migration_retry_count) while timeout_count: - try: - filter_name = 'nova-instance-%s' % instance_ref.name - self._conn.nwfilterLookupByName(filter_name) + if self.firewall_driver.instance_filter_exists(instance_ref): break - except libvirt.libvirtError: - timeout_count.pop() - if len(timeout_count) == 0: - ec2_id = instance_ref['hostname'] - iname = instance_ref.name - msg = _('Timeout migrating for %(ec2_id)s(%(iname)s)') - raise exception.Error(msg % locals()) - time.sleep(1) + timeout_count.pop() + if len(timeout_count) == 0: + msg = _('Timeout migrating for %s. nwfilter not found.') + raise exception.Error(msg % instance_ref.name) + time.sleep(1) def live_migration(self, ctxt, instance_ref, dest, post_method, recover_method): @@ -1541,6 +1536,10 @@ class FirewallDriver(object): """ raise NotImplementedError() + def instance_filter_exists(self, instance): + """Check nova-instance-instance-xxx exists""" + raise NotImplementedError() + class NWFilterFirewall(FirewallDriver): """ @@ -1848,6 +1847,19 @@ class NWFilterFirewall(FirewallDriver): return 'nova-instance-%s' % (instance['name']) return 'nova-instance-%s-%s' % (instance['name'], nic_id) + def instance_filter_exists(self, instance): + """Check nova-instance-instance-xxx exists""" + + network_info = _get_network_info(instance) + for (network, mapping) in network_info: + nic_id = mapping['mac'].replace(':', '') + instance_filter_name = self._instance_filter_name(instance, nic_id) + try: + self._conn.nwfilterLookupByName(instance_filter_name) + except libvirt.libvirtError: + return False + return True + class IptablesFirewallDriver(FirewallDriver): def __init__(self, execute=None, **kwargs): @@ -2037,6 +2049,10 @@ class IptablesFirewallDriver(FirewallDriver): return ipv4_rules, ipv6_rules + def instance_filter_exists(self, instance): + """Check nova-instance-instance-xxx exists""" + return self.nwfilter.instance_filter_exists(instance) + def refresh_security_group_members(self, security_group): pass -- cgit From d7013c9617d0740976a78ba87b1214c2b15ee702 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 5 Apr 2011 13:16:12 +0200 Subject: Automatically create CA state dir, and make sure the CA scripts look for the templates in the right places. --- nova/CA/geninter.sh | 2 +- nova/CA/genrootca.sh | 3 ++- nova/api/ec2/cloud.py | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/nova/CA/geninter.sh b/nova/CA/geninter.sh index 1fbcc9e73..4b7f5a55c 100755 --- a/nova/CA/geninter.sh +++ b/nova/CA/geninter.sh @@ -23,7 +23,7 @@ mkdir -p projects/$NAME cd projects/$NAME cp ../../openssl.cnf.tmpl openssl.cnf sed -i -e s/%USERNAME%/$NAME/g openssl.cnf -mkdir certs crl newcerts private +mkdir -p certs crl newcerts private openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 365 -config ./openssl.cnf -batch -nodes echo "10" > serial touch index.txt diff --git a/nova/CA/genrootca.sh b/nova/CA/genrootca.sh index 8f2c3ee3f..091cf17fc 100755 --- a/nova/CA/genrootca.sh +++ b/nova/CA/genrootca.sh @@ -20,8 +20,9 @@ if [ -f "cacert.pem" ]; then echo "Not installing, it's already done." else - cp openssl.cnf.tmpl openssl.cnf + cp "$(dirname $0)/openssl.cnf.tmpl" openssl.cnf sed -i -e s/%USERNAME%/ROOT/g openssl.cnf + mkdir -p certs crl newcerts private openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 365 -config ./openssl.cnf -batch -nodes touch index.txt echo "10" > serial diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index f119bd75c..5d6d9537a 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -110,6 +110,7 @@ class CloudController(object): 'genrootca.sh') start = os.getcwd() + os.makedirs(FLAGS.ca_path) os.chdir(FLAGS.ca_path) # TODO(vish): Do this with M2Crypto instead utils.runthis(_("Generating root CA: %s"), "sh", genrootca_sh_path) -- cgit From 4d1f60df049e11623df7d6174eda19e5e27d004e Mon Sep 17 00:00:00 2001 From: Kei Masumoto Date: Tue, 5 Apr 2011 20:20:32 +0900 Subject: fix bug lp751231 --- nova/compute/manager.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 08b772517..37a904b1e 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1090,6 +1090,15 @@ class ComputeManager(manager.SchedulerDependentManager): vm_state = vm_instance.state vms_not_found_in_db.remove(name) + if db_instance['state_description'] == 'migrating': + # A situation which db record exists, but no instance" + # sometimes occurs while live-migration at src compute, + # this case should be ignored. + LOG.info(_("the instance '%(name)s' is not found in hypervisor" + ", while db record is found. But not synchronize " + "since it is migrating." % locals())) + continue + if vm_state != db_state: LOG.info(_("DB/VM state mismatch. Changing state from " "'%(db_state)s' to '%(vm_state)s'") % locals()) -- cgit From ca2ce6dc4a96c7bded2c30c258b7becaee5a1ed7 Mon Sep 17 00:00:00 2001 From: Kei Masumoto Date: Tue, 5 Apr 2011 20:39:22 +0900 Subject: fix bug lp751242 --- nova/compute/api.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nova/compute/api.py b/nova/compute/api.py index 996955fe3..f67aa47e8 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -372,6 +372,10 @@ class API(base.Base): instance_id) return + if (instance['state_description'] == 'migrating'): + LOG.warning(_("Instance %s is being migrated"), instance_id) + return + self.update(context, instance['id'], state_description='terminating', -- cgit From d8ab404fd74facd181eaaee7cbc78b39a82afd1c Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Tue, 5 Apr 2011 08:26:16 -0400 Subject: Add missing underscore. --- nova/api/openstack/image_metadata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/openstack/image_metadata.py b/nova/api/openstack/image_metadata.py index 76abdaa7e..c733172ae 100644 --- a/nova/api/openstack/image_metadata.py +++ b/nova/api/openstack/image_metadata.py @@ -46,7 +46,7 @@ class Controller(wsgi.Controller): num_metadata = len(metadata) quota_metadata = quota.allowed_metadata_items(context, num_metadata) if quota_metadata < num_metadata: - expl = ("Image metadata limit exceeded") + expl = _("Image metadata limit exceeded") raise exc.HTTPBadRequest(explanation=expl) def index(self, req, image_id): -- cgit From affb632be0c0054a7b0a4858c6e0a585cc1afd0d Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Tue, 5 Apr 2011 08:49:44 -0400 Subject: Nits. --- nova/api/openstack/server_metadata.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nova/api/openstack/server_metadata.py b/nova/api/openstack/server_metadata.py index 618665082..2f7f6bc82 100644 --- a/nova/api/openstack/server_metadata.py +++ b/nova/api/openstack/server_metadata.py @@ -44,11 +44,12 @@ class Controller(wsgi.Controller): def create(self, req, server_id): context = req.environ['nova.context'] - data = self._deserialize(req.body, req.get_content_type())['metadata'] + data = self._deserialize(req.body, req.get_content_type()) + metadata = data.get('metadata') try: self.compute_api.update_or_create_instance_metadata(context, server_id, - data) + metadata) except quota.QuotaError as error: self._handle_quota_error(error) return req.body -- cgit From 7285694cb83ed618bea0d8c9170b725dd5566a27 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 5 Apr 2011 14:53:56 +0200 Subject: Add a find_data_files method to setup.py. Use it to get tools/ installed under /usr/(local/)/share/nova --- setup.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/setup.py b/setup.py index 20f4c1947..6c45109bc 100644 --- a/setup.py +++ b/setup.py @@ -16,6 +16,7 @@ # License for the specific language governing permissions and limitations # under the License. +import glob import os import subprocess import sys @@ -86,6 +87,19 @@ try: except: pass + +def find_data_files(destdir, srcdir): + package_data = [] + files = [] + for d in glob.glob('%s/*' % (srcdir, )): + if os.path.isdir(d): + package_data += find_data_files( + os.path.join(destdir, os.path.basename(d)), d) + else: + files += [d] + package_data += [(destdir, files)] + return package_data + DistUtilsExtra.auto.setup(name='nova', version=version.canonical_version_string(), description='cloud computing fabric controller', @@ -96,6 +110,7 @@ DistUtilsExtra.auto.setup(name='nova', packages=find_packages(exclude=['bin', 'smoketests']), include_package_data=True, test_suite='nose.collector', + data_files=find_data_files('share/nova', 'tools'), scripts=['bin/nova-ajax-console-proxy', 'bin/nova-api', 'bin/nova-compute', -- cgit From 669c0214ec77127ca7efe4d1e347ccaf2c2ae8b0 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 5 Apr 2011 14:54:11 +0200 Subject: Move api-paste.ini into a nova/ subdir of etc/ --- etc/api-paste.ini | 101 ------------------------------------------------- etc/nova/api-paste.ini | 101 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 101 deletions(-) delete mode 100644 etc/api-paste.ini create mode 100644 etc/nova/api-paste.ini diff --git a/etc/api-paste.ini b/etc/api-paste.ini deleted file mode 100644 index abe8c20c4..000000000 --- a/etc/api-paste.ini +++ /dev/null @@ -1,101 +0,0 @@ -####### -# EC2 # -####### - -[composite:ec2] -use = egg:Paste#urlmap -/: ec2versions -/services/Cloud: ec2cloud -/services/Admin: ec2admin -/latest: ec2metadata -/2007-01-19: ec2metadata -/2007-03-01: ec2metadata -/2007-08-29: ec2metadata -/2007-10-10: ec2metadata -/2007-12-15: ec2metadata -/2008-02-01: ec2metadata -/2008-09-01: ec2metadata -/2009-04-04: ec2metadata -/1.0: ec2metadata - -[pipeline:ec2cloud] -pipeline = logrequest authenticate cloudrequest authorizer ec2executor -#pipeline = logrequest ec2lockout authenticate cloudrequest authorizer ec2executor - -[pipeline:ec2admin] -pipeline = logrequest authenticate adminrequest authorizer ec2executor - -[pipeline:ec2metadata] -pipeline = logrequest ec2md - -[pipeline:ec2versions] -pipeline = logrequest ec2ver - -[filter:logrequest] -paste.filter_factory = nova.api.ec2:RequestLogging.factory - -[filter:ec2lockout] -paste.filter_factory = nova.api.ec2:Lockout.factory - -[filter:authenticate] -paste.filter_factory = nova.api.ec2:Authenticate.factory - -[filter:cloudrequest] -controller = nova.api.ec2.cloud.CloudController -paste.filter_factory = nova.api.ec2:Requestify.factory - -[filter:adminrequest] -controller = nova.api.ec2.admin.AdminController -paste.filter_factory = nova.api.ec2:Requestify.factory - -[filter:authorizer] -paste.filter_factory = nova.api.ec2:Authorizer.factory - -[app:ec2executor] -paste.app_factory = nova.api.ec2:Executor.factory - -[app:ec2ver] -paste.app_factory = nova.api.ec2:Versions.factory - -[app:ec2md] -paste.app_factory = nova.api.ec2.metadatarequesthandler:MetadataRequestHandler.factory - -############# -# Openstack # -############# - -[composite:osapi] -use = egg:Paste#urlmap -/: osversions -/v1.0: openstackapi10 -/v1.1: openstackapi11 - -[pipeline:openstackapi10] -pipeline = faultwrap auth ratelimit osapiapp10 - -[pipeline:openstackapi11] -pipeline = faultwrap auth ratelimit extensions osapiapp11 - -[filter:faultwrap] -paste.filter_factory = nova.api.openstack:FaultWrapper.factory - -[filter:auth] -paste.filter_factory = nova.api.openstack.auth:AuthMiddleware.factory - -[filter:ratelimit] -paste.filter_factory = nova.api.openstack.limits:RateLimitingMiddleware.factory - -[filter:extensions] -paste.filter_factory = nova.api.openstack.extensions:ExtensionMiddleware.factory - -[app:osapiapp10] -paste.app_factory = nova.api.openstack:APIRouterV10.factory - -[app:osapiapp11] -paste.app_factory = nova.api.openstack:APIRouterV11.factory - -[pipeline:osversions] -pipeline = faultwrap osversionapp - -[app:osversionapp] -paste.app_factory = nova.api.openstack.versions:Versions.factory diff --git a/etc/nova/api-paste.ini b/etc/nova/api-paste.ini new file mode 100644 index 000000000..abe8c20c4 --- /dev/null +++ b/etc/nova/api-paste.ini @@ -0,0 +1,101 @@ +####### +# EC2 # +####### + +[composite:ec2] +use = egg:Paste#urlmap +/: ec2versions +/services/Cloud: ec2cloud +/services/Admin: ec2admin +/latest: ec2metadata +/2007-01-19: ec2metadata +/2007-03-01: ec2metadata +/2007-08-29: ec2metadata +/2007-10-10: ec2metadata +/2007-12-15: ec2metadata +/2008-02-01: ec2metadata +/2008-09-01: ec2metadata +/2009-04-04: ec2metadata +/1.0: ec2metadata + +[pipeline:ec2cloud] +pipeline = logrequest authenticate cloudrequest authorizer ec2executor +#pipeline = logrequest ec2lockout authenticate cloudrequest authorizer ec2executor + +[pipeline:ec2admin] +pipeline = logrequest authenticate adminrequest authorizer ec2executor + +[pipeline:ec2metadata] +pipeline = logrequest ec2md + +[pipeline:ec2versions] +pipeline = logrequest ec2ver + +[filter:logrequest] +paste.filter_factory = nova.api.ec2:RequestLogging.factory + +[filter:ec2lockout] +paste.filter_factory = nova.api.ec2:Lockout.factory + +[filter:authenticate] +paste.filter_factory = nova.api.ec2:Authenticate.factory + +[filter:cloudrequest] +controller = nova.api.ec2.cloud.CloudController +paste.filter_factory = nova.api.ec2:Requestify.factory + +[filter:adminrequest] +controller = nova.api.ec2.admin.AdminController +paste.filter_factory = nova.api.ec2:Requestify.factory + +[filter:authorizer] +paste.filter_factory = nova.api.ec2:Authorizer.factory + +[app:ec2executor] +paste.app_factory = nova.api.ec2:Executor.factory + +[app:ec2ver] +paste.app_factory = nova.api.ec2:Versions.factory + +[app:ec2md] +paste.app_factory = nova.api.ec2.metadatarequesthandler:MetadataRequestHandler.factory + +############# +# Openstack # +############# + +[composite:osapi] +use = egg:Paste#urlmap +/: osversions +/v1.0: openstackapi10 +/v1.1: openstackapi11 + +[pipeline:openstackapi10] +pipeline = faultwrap auth ratelimit osapiapp10 + +[pipeline:openstackapi11] +pipeline = faultwrap auth ratelimit extensions osapiapp11 + +[filter:faultwrap] +paste.filter_factory = nova.api.openstack:FaultWrapper.factory + +[filter:auth] +paste.filter_factory = nova.api.openstack.auth:AuthMiddleware.factory + +[filter:ratelimit] +paste.filter_factory = nova.api.openstack.limits:RateLimitingMiddleware.factory + +[filter:extensions] +paste.filter_factory = nova.api.openstack.extensions:ExtensionMiddleware.factory + +[app:osapiapp10] +paste.app_factory = nova.api.openstack:APIRouterV10.factory + +[app:osapiapp11] +paste.app_factory = nova.api.openstack:APIRouterV11.factory + +[pipeline:osversions] +pipeline = faultwrap osversionapp + +[app:osversionapp] +paste.app_factory = nova.api.openstack.versions:Versions.factory -- cgit -- cgit From 6c8c454826263b334eb674c9ab1c8d62e5fd491f Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 5 Apr 2011 14:55:19 +0200 Subject: Help paste_config_file find the api config now that we moved it. --- nova/wsgi.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/wsgi.py b/nova/wsgi.py index ba0819466..05e7d5924 100644 --- a/nova/wsgi.py +++ b/nova/wsgi.py @@ -532,6 +532,7 @@ def paste_config_file(basename): """ configfiles = [basename, + os.path.join(FLAGS.state_path, 'etc', 'nova', basename), os.path.join(FLAGS.state_path, 'etc', basename), os.path.join(FLAGS.state_path, basename), '/etc/nova/%s' % basename] -- cgit From f1f8e00dc420bbc78b8d143c56375afc721c4c7d Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Tue, 5 Apr 2011 10:17:29 -0400 Subject: Dont configure vnc if we are using lxc --- nova/virt/libvirt_conn.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index babbc610d..2be190256 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -970,7 +970,8 @@ class LibvirtConnection(driver.ComputeDriver): 'nics': nics} if FLAGS.vnc_enabled: - xml_info['vncserver_host'] = FLAGS.vncserver_host + if FLAGS.libvirt_type != 'lxc': + xml_info['vncserver_host'] = FLAGS.vncserver_host if not rescue: if instance['kernel_id']: xml_info['kernel'] = xml_info['basepath'] + "/kernel" -- cgit From e6505fd78cc28a5e91ec6fbf55e2e8de07679c7c Mon Sep 17 00:00:00 2001 From: Naveed Massjouni Date: Tue, 5 Apr 2011 10:56:24 -0400 Subject: Fixed the addresses and metadata collections in xml responses. Added corresponding tests. --- nova/api/openstack/servers.py | 7 +++++++ nova/tests/api/openstack/test_servers.py | 36 ++++++++++++++++++++++++++++++++ nova/wsgi.py | 18 ++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 6704a68ae..cada92813 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -55,6 +55,13 @@ class Controller(wsgi.Controller): "imageRef"], "link": ["rel", "type", "href"], }, + "dict_collections": { + "metadata": {"item_name": "meta", "item_key": "key"}, + }, + "list_collections": { + "public": {"item_name": "ip", "item_key": "addr"}, + "private": {"item_name": "ip", "item_key": "addr"}, + }, }, } diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 313676e72..ce9821587 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -192,6 +192,26 @@ class ServersTest(test.TestCase): print res_dict['server'] self.assertEqual(res_dict['server']['links'], expected_links) + def test_get_server_by_id_with_addresses_xml(self): + private = "192.168.0.3" + public = ["1.2.3.4"] + new_return_server = return_server_with_addresses(private, public) + self.stubs.Set(nova.db.api, 'instance_get', new_return_server) + req = webob.Request.blank('/v1.0/servers/1') + req.headers['Accept'] = 'application/xml' + res = req.get_response(fakes.wsgi_app()) + dom = minidom.parseString(res.body) + server = dom.childNodes[0] + self.assertEquals(server.nodeName, 'server') + self.assertEquals(server.getAttribute('id'), '1') + self.assertEquals(server.getAttribute('name'), 'server1') + (public,) = server.getElementsByTagName('public'); + (ip,) = public.getElementsByTagName('ip') + self.assertEquals(ip.getAttribute('addr'), '1.2.3.4') + (private,) = server.getElementsByTagName('private') + (ip,) = private.getElementsByTagName('ip') + self.assertEquals(ip.getAttribute('addr'), '192.168.0.3') + def test_get_server_by_id_with_addresses(self): private = "192.168.0.3" public = ["1.2.3.4"] @@ -618,6 +638,22 @@ class ServersTest(test.TestCase): res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 404) + def test_get_all_server_details_xml_v1_0(self): + req = webob.Request.blank('/v1.0/servers/detail') + req.headers['Accept'] = 'application/xml' + res = req.get_response(fakes.wsgi_app()) + print res.body + dom = minidom.parseString(res.body) + for i, server in enumerate(dom.getElementsByTagName('server')): + self.assertEqual(server.getAttribute('id'), str(i)) + self.assertEqual(server.getAttribute('hostId'), '') + self.assertEqual(server.getAttribute('name'), 'server%d' % i) + self.assertEqual(server.getAttribute('imageId'), '10') + self.assertEqual(server.getAttribute('status'), 'BUILD') + (meta,) = server.getElementsByTagName('meta') + self.assertEqual(meta.getAttribute('key'), 'seq') + self.assertEqual(meta.firstChild.data.strip(), str(i)) + def test_get_all_server_details_v1_0(self): req = webob.Request.blank('/v1.0/servers/detail') res = req.get_response(fakes.wsgi_app()) diff --git a/nova/wsgi.py b/nova/wsgi.py index ba0819466..a550a33b0 100644 --- a/nova/wsgi.py +++ b/nova/wsgi.py @@ -484,6 +484,14 @@ class Serializer(object): """Recursive method to convert data members to XML nodes.""" result = doc.createElement(nodename) if type(data) is list: + collections = metadata.get('list_collections', {}) + if nodename in collections: + metadata = collections[nodename] + for item in data: + node = doc.createElement(metadata['item_name']) + node.setAttribute(metadata['item_key'], str(item)) + result.appendChild(node) + return result singular = metadata.get('plurals', {}).get(nodename, None) if singular is None: if nodename.endswith('s'): @@ -494,6 +502,16 @@ class Serializer(object): node = self._to_xml_node(doc, metadata, singular, item) result.appendChild(node) elif type(data) is dict: + collections = metadata.get('dict_collections', {}) + if nodename in collections: + metadata = collections[nodename] + for k, v in data.items(): + node = doc.createElement(metadata['item_name']) + node.setAttribute(metadata['item_key'], str(k)) + text = doc.createTextNode(str(v)) + node.appendChild(text) + result.appendChild(node) + return result attrs = metadata.get('attributes', {}).get(nodename, {}) for k, v in data.items(): if k in attrs: -- cgit From 519c885a4e3622417cd78655a211a2f23033d610 Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Tue, 5 Apr 2011 19:42:09 +0400 Subject: pep8 fixed --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 93a250502..1eec55e5f 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -167,7 +167,7 @@ def _get_network_info(instance): networks = db.network_get_all_by_instance(admin_context, instance['id']) - + flavor = db.instance_type_get_by_name(admin_context, instance['instance_type']) network_info = [] -- cgit From 28568e51ab4eb84e66e7d15adc9648220684ab84 Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Tue, 5 Apr 2011 20:40:52 +0400 Subject: removed blank lines for pep8 fix --- nova/virt/libvirt_conn.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 1eec55e5f..d6f51a644 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -164,10 +164,8 @@ def _get_network_info(instance): ip_addresses = db.fixed_ip_get_all_by_instance(admin_context, instance['id']) - networks = db.network_get_all_by_instance(admin_context, instance['id']) - flavor = db.instance_type_get_by_name(admin_context, instance['instance_type']) network_info = [] -- cgit From 3bb6e627fd99a307825f88ff8882e974bcf1b365 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Tue, 5 Apr 2011 13:02:42 -0400 Subject: Remove comments. --- .../migrate_repo/versions/014_add_instance_type_id_to_instances.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/014_add_instance_type_id_to_instances.py b/nova/db/sqlalchemy/migrate_repo/versions/014_add_instance_type_id_to_instances.py index 813e57e10..b12a0a801 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/014_add_instance_type_id_to_instances.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/014_add_instance_type_id_to_instances.py @@ -63,7 +63,6 @@ def upgrade(migrate_engine): .values(instance_type_id=type_id)) instances.c.instance_type.drop() - #instances.c.instance_type_id.alter(nullable=False) def downgrade(migrate_engine): @@ -83,4 +82,3 @@ def downgrade(migrate_engine): .values(instance_type=type_name)) instances.c.instance_type_id.drop() - #instances.c.instance_type.alter(nullable=False) -- cgit From a7a1f4dfda3751bb1f0f5c875e0799f1905259bd Mon Sep 17 00:00:00 2001 From: Mark Washenberger Date: Tue, 5 Apr 2011 15:44:41 -0400 Subject: add tests for adminPass on server create --- nova/tests/api/openstack/test_servers.py | 46 ++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 313676e72..bd0bdf1b3 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -508,6 +508,52 @@ class ServersTest(test.TestCase): res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 400) + def test_create_instance_with_admin_pass_v10(self): + self._setup_for_create_instance() + + body = { + 'server': { + 'name': 'test-server-create', + 'imageId': 3, + 'flavorId': 1, + 'adminPass': 'testpass', + }, + } + + req = webob.Request.blank('/v1.0/servers') + req.method = 'POST' + req.body = json.dumps(body) + req.headers['content-type'] = "application/json" + res = req.get_response(fakes.wsgi_app()) + res = json.loads(res.body) + self.assertNotEqual(res['server']['adminPass'], + body['server']['adminPass']) + + def test_create_instance_with_admin_pass_v11(self): + self._setup_for_create_instance() + + imageRef = 'http://localhost/v1.1/images/2' + flavorRef = 'http://localhost/v1.1/flavors/3' + body = { + 'server': { + 'name': 'server_test', + 'imageRef': imageRef, + 'flavorRef': flavorRef, + 'adminPass': 'testpass', + }, + } + + req = webob.Request.blank('/v1.1/servers') + req.method = 'POST' + req.body = json.dumps(body) + req.headers['content-type'] = "application/json" + + res = req.get_response(fakes.wsgi_app()) + + server = json.loads(res.body)['server'] + self.assertEqual(server['adminPass'], body['server']['adminPass']) + + def test_update_no_body(self): req = webob.Request.blank('/v1.0/servers/1') req.method = 'PUT' -- cgit From 2468743697faf81851bef1cafba95337dbd57153 Mon Sep 17 00:00:00 2001 From: Mark Washenberger Date: Tue, 5 Apr 2011 15:55:49 -0400 Subject: add support for specifying adminPass for JSON only in openstack api 1.1 --- nova/api/openstack/servers.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 6704a68ae..c19b53b5e 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -180,7 +180,7 @@ class Controller(wsgi.Controller): builder = self._get_view_builder(req) server = builder.build(inst, is_detail=True) - password = utils.generate_password(16) + password = self._get_admin_password_from_request_server(env['server']) server['server']['adminPass'] = password self.compute_api.set_admin_password(context, server['server']['id'], password) @@ -242,6 +242,9 @@ class Controller(wsgi.Controller): # if the original error is okay, just reraise it raise error + def _get_admin_password_from_request_server(self, server): + return utils.generate_password(16) + @scheduler_api.redirect_handler def update(self, req, id): """ Updates the server name or password """ @@ -648,6 +651,12 @@ class ControllerV11(Controller): def _limit_items(self, items, req): return common.limited_by_marker(items, req) + def _get_admin_password_from_request_server(self, server): + password = server.get('adminPass') + if password: + return password + return utils.generate_password(16) + class ServerCreateRequestXMLDeserializer(object): """ -- cgit From b59f7e2b9ed0f08ac033cd839a6996a1931ccec6 Mon Sep 17 00:00:00 2001 From: Mark Washenberger Date: Tue, 5 Apr 2011 16:30:30 -0400 Subject: refactor to handle invalid adminPass --- nova/api/openstack/servers.py | 11 ++++++----- nova/tests/api/openstack/test_servers.py | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index c19b53b5e..8f5adaad5 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -120,6 +120,11 @@ class Controller(wsgi.Controller): context = req.environ['nova.context'] + password = self._get_admin_password_from_request_server(env['server']) + if not isinstance(password, basestring) or password == '': + msg = _("Invalid adminPass") + return exc.HTTPBadRequest(msg) + key_name = None key_data = None key_pairs = auth_manager.AuthManager.get_key_pairs(context) @@ -180,7 +185,6 @@ class Controller(wsgi.Controller): builder = self._get_view_builder(req) server = builder.build(inst, is_detail=True) - password = self._get_admin_password_from_request_server(env['server']) server['server']['adminPass'] = password self.compute_api.set_admin_password(context, server['server']['id'], password) @@ -652,10 +656,7 @@ class ControllerV11(Controller): return common.limited_by_marker(items, req) def _get_admin_password_from_request_server(self, server): - password = server.get('adminPass') - if password: - return password - return utils.generate_password(16) + return server.get('adminPass', utils.generate_password(16)) class ServerCreateRequestXMLDeserializer(object): diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index bd0bdf1b3..65e6fee51 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -553,6 +553,26 @@ class ServersTest(test.TestCase): server = json.loads(res.body)['server'] self.assertEqual(server['adminPass'], body['server']['adminPass']) + def test_create_instance_with_empty_admin_pass_v11(self): + self._setup_for_create_instance() + + imageRef = 'http://localhost/v1.1/images/2' + flavorRef = 'http://localhost/v1.1/flavors/3' + body = { + 'server': { + 'name': 'server_test', + 'imageRef': imageRef, + 'flavorRef': flavorRef, + 'adminPass': '', + }, + } + + req = webob.Request.blank('/v1.1/servers') + req.method = 'POST' + req.body = json.dumps(body) + req.headers['content-type'] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 400) def test_update_no_body(self): req = webob.Request.blank('/v1.0/servers/1') -- cgit From 7ed00acea541dc4cf3b70ecf923b649e9ee7ae11 Mon Sep 17 00:00:00 2001 From: Mark Washenberger Date: Tue, 5 Apr 2011 16:46:44 -0400 Subject: move error handling down into get_password function --- nova/api/openstack/servers.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 8f5adaad5..40aca64b4 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -120,10 +120,7 @@ class Controller(wsgi.Controller): context = req.environ['nova.context'] - password = self._get_admin_password_from_request_server(env['server']) - if not isinstance(password, basestring) or password == '': - msg = _("Invalid adminPass") - return exc.HTTPBadRequest(msg) + password = self._get_server_admin_password(env['server']) key_name = None key_data = None @@ -246,7 +243,7 @@ class Controller(wsgi.Controller): # if the original error is okay, just reraise it raise error - def _get_admin_password_from_request_server(self, server): + def _get_server_admin_password(self, server): return utils.generate_password(16) @scheduler_api.redirect_handler @@ -655,8 +652,14 @@ class ControllerV11(Controller): def _limit_items(self, items, req): return common.limited_by_marker(items, req) - def _get_admin_password_from_request_server(self, server): - return server.get('adminPass', utils.generate_password(16)) + def _get_server_admin_password(self, server): + password = server.get('adminPass') + if password is None: + return utils.generate_password(16) + if not isinstance(password, basestring) or password == '': + msg = _("Invalid adminPass") + raise exc.HTTPBadRequest(msg) + return password class ServerCreateRequestXMLDeserializer(object): -- cgit From 1afcf5511d4cfa70dd17113c9253594fbd5b7aa1 Mon Sep 17 00:00:00 2001 From: Mark Washenberger Date: Tue, 5 Apr 2011 16:53:59 -0400 Subject: remove extraneous empty lines --- nova/tests/api/openstack/test_servers.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 65e6fee51..368343ce6 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -547,9 +547,7 @@ class ServersTest(test.TestCase): req.method = 'POST' req.body = json.dumps(body) req.headers['content-type'] = "application/json" - res = req.get_response(fakes.wsgi_app()) - server = json.loads(res.body)['server'] self.assertEqual(server['adminPass'], body['server']['adminPass']) -- cgit From 3c487493de2a0f827780d54080797bfe70183ba6 Mon Sep 17 00:00:00 2001 From: Naveed Massjouni Date: Tue, 5 Apr 2011 17:49:38 -0400 Subject: Removing naughty semicolon. --- nova/tests/api/openstack/test_servers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index ce9821587..a424a8105 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -205,7 +205,7 @@ class ServersTest(test.TestCase): self.assertEquals(server.nodeName, 'server') self.assertEquals(server.getAttribute('id'), '1') self.assertEquals(server.getAttribute('name'), 'server1') - (public,) = server.getElementsByTagName('public'); + (public,) = server.getElementsByTagName('public') (ip,) = public.getElementsByTagName('ip') self.assertEquals(ip.getAttribute('addr'), '1.2.3.4') (private,) = server.getElementsByTagName('private') -- cgit From 56eb682a169c20a9a8275b3b9bfd423f0d562cbc Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 5 Apr 2011 15:01:33 -0700 Subject: unite the filtering done by glance client and s3 --- bin/nova-manage | 14 ++++++-------- nova/api/ec2/cloud.py | 2 +- nova/image/glance.py | 28 ---------------------------- nova/image/local.py | 4 +++- nova/image/s3.py | 45 +++------------------------------------------ nova/image/service.py | 27 +++++++++++++++++++++++++++ 6 files changed, 40 insertions(+), 80 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index fbf16f570..bfff227c9 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -897,15 +897,14 @@ class ImageCommands(object): def _register(self, container_format, disk_format, path, owner, name=None, is_public='T', architecture='x86_64', kernel_id=None, ramdisk_id=None): - meta = {'is_public': True, + meta = {'is_public': (is_public == 'T'), 'name': name, 'container_format': container_format, 'disk_format': disk_format, 'properties': {'image_state': 'available', - 'owner_id': owner, + 'project_id': owner, 'architecture': architecture, - 'image_location': 'local', - 'is_public': (is_public == 'T')}} + 'image_location': 'local'}} if kernel_id: meta['properties']['kernel_id'] = int(kernel_id) if ramdisk_id: @@ -980,13 +979,12 @@ class ImageCommands(object): disk_format = 'raw' new = {'disk_format': disk_format, 'container_format': container_format, - 'is_public': True, + 'is_public': old['isPublic'], 'name': old['imageId'], 'properties': {'image_state': old['imageState'], - 'owner_id': old['imageOwnerId'], + 'project_id': old['imageOwnerId'], 'architecture': old['architecture'], - 'image_location': old['imageLocation'], - 'is_public': old['isPublic']}} + 'image_location': old['imageLocation']}} if old.get('kernelId'): new['properties']['kernel_id'] = self._lookup(old['kernelId']) if old.get('ramdiskId'): diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 02a30220a..b4705820e 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -927,7 +927,7 @@ class CloudController(object): 'ari': 'ramdisk', 'ami': 'machine'} i['imageType'] = display_mapping.get(image_type) - i['isPublic'] = str(image['properties'].get('is_public', '')) == 'True' + i['isPublic'] = image.get('is_public') == True i['architecture'] = image['properties'].get('architecture') return i diff --git a/nova/image/glance.py b/nova/image/glance.py index fdf468594..e583c504d 100644 --- a/nova/image/glance.py +++ b/nova/image/glance.py @@ -186,34 +186,6 @@ class GlanceImageService(service.BaseImageService): image_meta = _convert_timestamps_to_datetimes(image_meta) return image_meta - @staticmethod - def _is_image_available(context, image_meta): - """ - Images are always available if they are public or if the user is an - admin. - - Otherwise, we filter by project_id (if present) and then fall-back to - images owned by user. - """ - # FIXME(sirp): We should be filtering by user_id on the Glance side - # for security; however, we can't do that until we get authn/authz - # sorted out. Until then, filtering in Nova. - if image_meta['is_public'] or context.is_admin: - return True - - properties = image_meta['properties'] - - if context.project_id and ('project_id' in properties): - return str(properties['project_id']) == str(project_id) - - try: - user_id = properties['user_id'] - except KeyError: - return False - - return str(user_id) == str(context.user_id) - - # utility functions def _convert_timestamps_to_datetimes(image_meta): """ diff --git a/nova/image/local.py b/nova/image/local.py index 1fb6e1f13..92d3dabd4 100644 --- a/nova/image/local.py +++ b/nova/image/local.py @@ -84,7 +84,9 @@ class LocalImageService(service.BaseImageService): def show(self, context, image_id): try: with open(self._path_to(image_id)) as metadata_file: - return json.load(metadata_file) + image_meta = json.load(metadata_file) + if not self._is_image_available(context, image_meta): + raise exception.NotFound except (IOError, ValueError): raise exception.NotFound diff --git a/nova/image/s3.py b/nova/image/s3.py index def49f682..93af21022 100644 --- a/nova/image/s3.py +++ b/nova/image/s3.py @@ -58,54 +58,16 @@ class S3ImageService(service.BaseImageService): return image def delete(self, context, image_id): - # FIXME(vish): call to show is to check filter + # FIXME(vish): call to show is to check visibility self.show(context, image_id) self.service.delete(context, image_id) def update(self, context, image_id, metadata, data=None): - # FIXME(vish): call to show is to check filter + # FIXME(vish): call to show is to check visibility self.show(context, image_id) image = self.service.update(context, image_id, metadata, data) return image - def index(self, context): - images = self.service.index(context) - # FIXME(vish): index doesn't filter so we do it manually - return self._filter(context, images) - - def detail(self, context): - images = self.service.detail(context) - # FIXME(vish): detail doesn't filter so we do it manually - return self._filter(context, images) - - @classmethod - def _is_visible(cls, context, image): - - return (context.is_admin - or context.project_id == image['properties'].get('owner_id') - or str(image['properties'].get('is_public')) == 'True') - - @classmethod - def _filter(cls, context, images): - filtered = [] - for image in images: - if not cls._is_visible(context, image): - continue - filtered.append(image) - return filtered - - def show(self, context, image_id): - image = self.service.show(context, image_id) - if not self._is_visible(context, image): - raise exception.NotFound - return image - - def show_by_name(self, context, name): - image = self.service.show_by_name(context, name) - if not self._is_visible(context, image): - raise exception.NotFound - return image - @staticmethod def _conn(context): # TODO(vish): is there a better way to get creds to sign @@ -168,7 +130,7 @@ class S3ImageService(service.BaseImageService): arch = 'x86_64' properties = metadata['properties'] - properties['owner_id'] = context.project_id + properties['project_id'] = context.project_id properties['architecture'] = arch if kernel_id: @@ -177,7 +139,6 @@ class S3ImageService(service.BaseImageService): if ramdisk_id: properties['ramdisk_id'] = ec2utils.ec2_id_to_id(ramdisk_id) - properties['is_public'] = False metadata.update({'disk_format': image_format, 'container_format': image_format, 'status': 'queued', diff --git a/nova/image/service.py b/nova/image/service.py index b9897ecae..fddc72409 100644 --- a/nova/image/service.py +++ b/nova/image/service.py @@ -136,6 +136,33 @@ class BaseImageService(object): """ raise NotImplementedError + @staticmethod + def _is_image_available(context, image_meta): + """ + Images are always available if they are public or if the user is an + admin. + + Otherwise, we filter by project_id (if present) and then fall-back to + images owned by user. + """ + # FIXME(sirp): We should be filtering by user_id on the Glance side + # for security; however, we can't do that until we get authn/authz + # sorted out. Until then, filtering in Nova. + if image_meta['is_public'] or context.is_admin: + return True + + properties = image_meta['properties'] + + if context.project_id and ('project_id' in properties): + return str(properties['project_id']) == str(context.project_id) + + try: + user_id = properties['user_id'] + except KeyError: + return False + + return str(user_id) == str(context.user_id) + @classmethod def _translate_to_base(cls, metadata): """Return a metadata dictionary that is BaseImageService compliant. -- cgit From 8eff0a91bbc475d8559b39fb81e1a62beda841f3 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 5 Apr 2011 15:35:17 -0700 Subject: update and fix tests --- nova/image/local.py | 1 + nova/image/s3.py | 13 +++++++++++++ nova/tests/api/openstack/test_servers.py | 16 +++++++--------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/nova/image/local.py b/nova/image/local.py index 92d3dabd4..bad4c2d85 100644 --- a/nova/image/local.py +++ b/nova/image/local.py @@ -87,6 +87,7 @@ class LocalImageService(service.BaseImageService): image_meta = json.load(metadata_file) if not self._is_image_available(context, image_meta): raise exception.NotFound + return image_meta except (IOError, ValueError): raise exception.NotFound diff --git a/nova/image/s3.py b/nova/image/s3.py index 93af21022..a7301eefd 100644 --- a/nova/image/s3.py +++ b/nova/image/s3.py @@ -46,6 +46,7 @@ flags.DEFINE_string('image_decryption_dir', '/tmp', class S3ImageService(service.BaseImageService): + """Wraps an existing image service to support s3 based register""" def __init__(self, service=None, *args, **kwargs): if service == None: service = utils.import_object(FLAGS.image_service) @@ -68,6 +69,18 @@ class S3ImageService(service.BaseImageService): image = self.service.update(context, image_id, metadata, data) return image + def index(self, context): + return self.service.index(context) + + def detail(self, context): + return self.service.detail(context) + + def show(self, context, image_id): + return self.service.show(context, image_id) + + def show_by_name(self, context, name): + return self.service.show(context, name) + @staticmethod def _conn(context): # TODO(vish): is there a better way to get creds to sign diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 313676e72..1ec01bb4c 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -1525,29 +1525,27 @@ class TestGetKernelRamdiskFromImage(test.TestCase): def test_not_ami(self): """Anything other than ami should return no kernel and no ramdisk""" - image_meta = {'id': 1, 'status': 'active', - 'properties': {'disk_format': 'vhd'}} + image_meta = {'id': 1, 'status': 'active', 'container_format': 'vhd'} kernel_id, ramdisk_id = self._get_k_r(image_meta) self.assertEqual(kernel_id, None) self.assertEqual(ramdisk_id, None) def test_ami_no_kernel(self): """If an ami is missing a kernel it should raise NotFound""" - image_meta = {'id': 1, 'status': 'active', - 'properties': {'disk_format': 'ami', 'ramdisk_id': 1}} + image_meta = {'id': 1, 'status': 'active', 'container_format': 'ami', + 'properties': {'ramdisk_id': 1}} self.assertRaises(exception.NotFound, self._get_k_r, image_meta) def test_ami_no_ramdisk(self): """If an ami is missing a ramdisk it should raise NotFound""" - image_meta = {'id': 1, 'status': 'active', - 'properties': {'disk_format': 'ami', 'kernel_id': 1}} + image_meta = {'id': 1, 'status': 'active', 'container_format': 'ami', + 'properties': {'kernel_id': 1}} self.assertRaises(exception.NotFound, self._get_k_r, image_meta) def test_ami_kernel_ramdisk_present(self): """Return IDs if both kernel and ramdisk are present""" - image_meta = {'id': 1, 'status': 'active', - 'properties': {'disk_format': 'ami', 'kernel_id': 1, - 'ramdisk_id': 2}} + image_meta = {'id': 1, 'status': 'active', 'container_format': 'ami', + 'properties': {'kernel_id': 1, 'ramdisk_id': 2}} kernel_id, ramdisk_id = self._get_k_r(image_meta) self.assertEqual(kernel_id, 1) self.assertEqual(ramdisk_id, 2) -- cgit From 5f414311fb581ba612cf152f3ec9983d5f39c2e4 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 5 Apr 2011 15:45:01 -0700 Subject: fallback to status if image_state is not set --- nova/api/ec2/cloud.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index b4705820e..4e5b8bfc6 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -920,7 +920,11 @@ class CloudController(object): get('image_location'), name) else: i['imageLocation'] = image['properties'].get('image_location') - i['imageState'] = image['properties'].get('image_state') + # NOTE(vish): fallback status if image_state isn't set + state = image.get('status') + if state == 'active': + state = 'available' + i['imageState'] = image['properties'].get('image_state', state) i['displayName'] = name i['description'] = image.get('description') display_mapping = {'aki': 'kernel', -- cgit From 75082c44cdc0319c56805b5558927760636eaf4b Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 5 Apr 2011 15:49:43 -0700 Subject: pep8 --- nova/image/glance.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/image/glance.py b/nova/image/glance.py index e583c504d..f848f40d8 100644 --- a/nova/image/glance.py +++ b/nova/image/glance.py @@ -186,6 +186,7 @@ class GlanceImageService(service.BaseImageService): image_meta = _convert_timestamps_to_datetimes(image_meta) return image_meta + # utility functions def _convert_timestamps_to_datetimes(image_meta): """ -- cgit From a254fd9b63c48f64a62fd38df3a2caae81ce63c7 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Tue, 5 Apr 2011 18:29:53 -0500 Subject: typo --- nova/virt/xenapi/vmops.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index c96c35a6e..ef2ab09b9 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -814,12 +814,11 @@ class VMOps(object): "netmask": network["netmask"], "enabled": "1"} - def ip6_dict(ip6): + def ip6_dict(): return { "ip": utils.to_global_ipv6(network['cidr_v6'], instance['mac_address']), "netmask": network['netmask_v6'], - "gateway": network['gateway_v6'], "enabled": "1"} info = { @@ -831,7 +830,9 @@ class VMOps(object): 'dns': [network['dns']], 'ips': [ip_dict(ip) for ip in network_IPs]} if network['cidr_v6']: - info['ip6s'] = [ip6_dict(ip) for ip in network_IPs] + info['ip6s'] = [ip6_dict()] + if network['gateway_v6']: + info['gateway6'] = network['gateway_v6'], network_info.append((network, info)) return network_info -- cgit From d137ffdc2fb4e0298a6fb177df9e6a8299320301 Mon Sep 17 00:00:00 2001 From: John Tran Date: Tue, 5 Apr 2011 18:35:15 -0700 Subject: Add a patch for python eventlet, when using install_venv.py (see FAQ # 1485) --- tools/eventlet-patch | 24 ++++++++++++++++++++++++ tools/install_venv.py | 6 ++++++ 2 files changed, 30 insertions(+) create mode 100644 tools/eventlet-patch diff --git a/tools/eventlet-patch b/tools/eventlet-patch new file mode 100644 index 000000000..c87c5f279 --- /dev/null +++ b/tools/eventlet-patch @@ -0,0 +1,24 @@ +# HG changeset patch +# User Soren Hansen +# Date 1297678255 -3600 +# Node ID 4c846d555010bb5a91ab4da78dfe596451313742 +# Parent 5b7e9946c79f005c028eb63207cf5eb7bb21d1c3 +Don't attempt to wrap GreenPipes in GreenPipe + +If the os module is monkeypatched, Python's standard subprocess module +will return greenio.GreenPipe instances for Popen objects' stdin, stdout, +and stderr attributes. However, eventlet.green.subprocess tries to wrap +these attributes in another greenio.GreenPipe, which GreenPipe refuses. + +diff -r 5b7e9946c79f -r 4c846d555010 eventlet/green/subprocess.py +--- a/eventlet/green/subprocess.py Sat Feb 05 13:05:05 2011 -0800 ++++ b/eventlet/green/subprocess.py Mon Feb 14 11:10:55 2011 +0100 +@@ -27,7 +27,7 @@ + # eventlet.processes.Process.run() method. + for attr in "stdin", "stdout", "stderr": + pipe = getattr(self, attr) +- if pipe is not None: ++ if pipe is not None and not type(pipe) == greenio.GreenPipe: + wrapped_pipe = greenio.GreenPipe(pipe, pipe.mode, bufsize) + setattr(self, attr, wrapped_pipe) + __init__.__doc__ = subprocess_orig.Popen.__init__.__doc__ diff --git a/tools/install_venv.py b/tools/install_venv.py index 4e3941210..30ec85374 100644 --- a/tools/install_venv.py +++ b/tools/install_venv.py @@ -103,6 +103,12 @@ def install_dependencies(venv=VENV): pthfile = os.path.join(venv, "lib", "python2.6", "site-packages", "nova.pth") f = open(pthfile, 'w') f.write("%s\n" % ROOT) + # Patch eventlet (see FAQ # 1485) + patchsrc = os.path.join(ROOT, 'tools', 'eventlet-patch') + patchfile = os.path.join(venv, "lib", "python2.6", "site-packages", "eventlet", + "green", "subprocess.py") + patch_cmd = "patch %s %s" % (patchfile, patchsrc) + os.system(patch_cmd) def print_help(): -- cgit From 44eefb1eefda5e42a286ee1aa689c1c93e72aae4 Mon Sep 17 00:00:00 2001 From: Kei Masumoto Date: Wed, 6 Apr 2011 14:44:19 +0900 Subject: fixed based on reviwer's comment --- nova/compute/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index f67aa47e8..db04143c1 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -367,12 +367,12 @@ class API(base.Base): instance_id) raise - if (instance['state_description'] == 'terminating'): + if instance['state_description'] == 'terminating': LOG.warning(_("Instance %s is already being terminated"), instance_id) return - if (instance['state_description'] == 'migrating'): + if instance['state_description'] == 'migrating': LOG.warning(_("Instance %s is being migrated"), instance_id) return -- cgit From d99a40d0a34a0d7ec05dcaa188a58535f0e41953 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Wed, 6 Apr 2011 14:05:12 +0200 Subject: Only create ca_path directory if it does not already exist. --- nova/api/ec2/cloud.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 99520b302..58effd134 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -110,7 +110,8 @@ class CloudController(object): 'genrootca.sh') start = os.getcwd() - os.makedirs(FLAGS.ca_path) + if not os.path.exists(FLAGS.ca_path): + os.makedirs(FLAGS.ca_path) os.chdir(FLAGS.ca_path) # TODO(vish): Do this with M2Crypto instead utils.runthis(_("Generating root CA: %s"), "sh", genrootca_sh_path) -- cgit -- cgit From dbeab47bbdeceab0bef896c9d7646ae346c9dd3a Mon Sep 17 00:00:00 2001 From: Johannes Erdfelt Date: Wed, 6 Apr 2011 09:05:12 -0700 Subject: Wait for device node to be created after mounting image VDI --- nova/virt/xenapi/vm_utils.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index d07d60800..d29456ec6 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -49,6 +49,8 @@ LOG = logging.getLogger("nova.virt.xenapi.vm_utils") FLAGS = flags.FLAGS flags.DEFINE_string('default_os_type', 'linux', 'Default OS type') +flags.DEFINE_integer('timeout_block', 10, + 'time to wait for a block device to be created') XENAPI_POWER_STATE = { 'Halted': power_state.SHUTDOWN, @@ -896,6 +898,16 @@ def remap_vbd_dev(dev): return remapped_dev +def _wait_for_device(dev): + """Wait for device node to appear""" + for i in xrange(0, FLAGS.timeout_block): + if os.path.exists('/dev/%s' % dev): + return + time.sleep(1) + + raise StorageError(_('Timeout waiting for device %s to be created') % dev) + + def with_vdi_attached_here(session, vdi_ref, read_only, f): this_vm_ref = get_this_vm_ref(session) vbd_rec = {} @@ -924,6 +936,7 @@ def with_vdi_attached_here(session, vdi_ref, read_only, f): if dev != orig_dev: LOG.debug(_('VBD %(vbd_ref)s plugged into wrong dev, ' 'remapping to %(dev)s') % locals()) + _wait_for_device(dev) return f(dev) finally: LOG.debug(_('Destroying VBD for VDI %s ... '), vdi_ref) -- cgit From 0a8ca1bb7f123718ae48bb842b1c532b07f03890 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Wed, 6 Apr 2011 18:10:42 +0200 Subject: Create ca_folder if it does not already exist. --- nova/crypto.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nova/crypto.py b/nova/crypto.py index 2b122e560..9b1897926 100644 --- a/nova/crypto.py +++ b/nova/crypto.py @@ -269,6 +269,8 @@ def _sign_csr(csr_text, ca_folder): LOG.debug(_("Flags path: %s"), ca_folder) start = os.getcwd() # Change working dir to CA + if not os.path.exists(ca_folder): + os.makedirs(ca_folder) os.chdir(ca_folder) utils.execute('openssl', 'ca', '-batch', '-out', outbound, '-config', './openssl.cnf', '-infiles', inbound) -- cgit From 481a77134a4e0e1d668fa488d7c5b1d7e1bc5429 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Wed, 6 Apr 2011 11:15:35 -0500 Subject: modified behavior of inject_network_info and reset_network related to a vm_ref not being passed in --- nova/virt/xenapi/vmops.py | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index ef2ab09b9..f02beda24 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -176,7 +176,7 @@ class VMOps(object): vdi_ref, network_info) self.create_vifs(vm_ref, network_info) - self.inject_network_info(instance, vm_ref, network_info) + self.inject_network_info(instance, network_info, vm_ref) return vm_ref def _spawn(self, instance, vm_ref): @@ -836,15 +836,31 @@ class VMOps(object): network_info.append((network, info)) return network_info - def inject_network_info(self, instance, vm_ref, network_info): + #TODO{tr3buchet) remove this shim with nova-multi-nic + def inject_network_info(self, instance, network_info=None, vm_ref=None): + """ + shim in place which makes inject_network_info work without being + passed network_info. + shim goes away after nova-multi-nic + """ + if not network_info: + network_info = self._get_network_info(instance) + self._inject_network_info(instance, network_info, vm_ref) + + def _inject_network_info(self, instance, network_info, vm_ref=None): """ Generate the network info and make calls to place it into the xenstore and the xenstore param list. + vm_ref can be passed in because it will sometimes be different than + what VMHelper.lookup(session, instance.name) will find (ex: rescue) """ logging.debug(_("injecting network info to xs for vm: |%s|"), vm_ref) - # this function raises if vm_ref is not a vm_opaque_ref - self._session.get_xenapi().VM.get_record(vm_ref) + if vm_ref: + # this function raises if vm_ref is not a vm_opaque_ref + self._session.get_xenapi().VM.get_record(vm_ref) + else: + vm_ref = VMHelper.lookup(self._session, instance.name) for (network, info) in network_info: location = 'vm-data/networking/%s' % info['mac'].replace(':', '') @@ -876,8 +892,10 @@ class VMOps(object): VMHelper.create_vif(self._session, vm_ref, network_ref, mac_address, device, rxtx_cap) - def reset_network(self, instance, vm_ref): + def reset_network(self, instance, vm_ref=None): """Creates uuid arg to pass to make_agent_call and calls it.""" + if not vm_ref: + vm_ref = VMHelper.lookup(self._session, instance.name) args = {'id': str(uuid.uuid4())} # TODO(tr3buchet): fix function call after refactor #resp = self._make_agent_call('resetnetwork', instance, '', args) -- cgit From e46d78218eec77f8502579496ee0922ce401e84a Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Wed, 6 Apr 2011 12:33:07 -0500 Subject: updated _prepare_injectables() to use info[gateway6] instead of looking inside the ip6 address dict for the gateway6 information --- nova/virt/xenapi/vm_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index d07d60800..886f1ec88 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -1130,7 +1130,7 @@ def _prepare_injectables(inst, networks_info): 'dns': dns, 'address_v6': ip_v6 and ip_v6['ip'] or '', 'netmask_v6': ip_v6 and ip_v6['netmask'] or '', - 'gateway_v6': ip_v6 and ip_v6['gateway'] or '', + 'gateway_v6': ip_v6 and info['gateway6'] or '', 'use_ipv6': FLAGS.use_ipv6} interfaces_info.append(interface_info) -- cgit From 3e120e52fcb8fca1b97b496c618c3b9e2b459598 Mon Sep 17 00:00:00 2001 From: Mark Washenberger Date: Wed, 6 Apr 2011 13:42:04 -0400 Subject: add docstrings --- nova/api/openstack/servers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 40aca64b4..3b6d14ae1 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -244,6 +244,7 @@ class Controller(wsgi.Controller): raise error def _get_server_admin_password(self, server): + """ Determine the admin password for a server on creation """ return utils.generate_password(16) @scheduler_api.redirect_handler @@ -653,6 +654,7 @@ class ControllerV11(Controller): return common.limited_by_marker(items, req) def _get_server_admin_password(self, server): + """ Determine the admin password for a server on creation """ password = server.get('adminPass') if password is None: return utils.generate_password(16) -- cgit From c18bf716f08e6b9fbdc259755cf172b5a6cf096a Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Wed, 6 Apr 2011 12:52:25 -0500 Subject: updated get_network_info in libvirt_conn to correctly insert ip6s and gateway6 into the network info, also small style fixes --- nova/virt/libvirt_conn.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 2be190256..f1fa859ed 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -169,34 +169,34 @@ def _get_network_info(instance): instance['id']) network_info = [] - def ip_dict(ip): - return { - "ip": ip.address, - "netmask": network["netmask"], - "enabled": "1"} - - def ip6_dict(ip6): - prefix = ip6.network.cidr_v6 - mac = instance.mac_address - return { - "ip": utils.to_global_ipv6(prefix, mac), - "netmask": ip6.network.netmask_v6, - "gateway": ip6.network.gateway_v6, - "enabled": "1"} - for network in networks: network_ips = [ip for ip in ip_addresses - if ip.network_id == network.id] + if ip['network_id'] == network['id']] + + def ip_dict(ip): + return { + 'ip': ip['address'], + 'netmask': network['netmask'], + 'enabled': '1'} + + def ip6_dict(): + prefix = network['cidr_v6'] + mac = instance['mac_address'] + return { + 'ip': utils.to_global_ipv6(prefix, mac), + 'netmask': network['netmask_v6'], + 'enabled': '1'} mapping = { 'label': network['label'], 'gateway': network['gateway'], - 'mac': instance.mac_address, + 'mac': instance['mac_address'], 'dns': [network['dns']], 'ips': [ip_dict(ip) for ip in network_ips]} if FLAGS.use_ipv6: - mapping['ip6s'] = [ip6_dict(ip) for ip in network_ips] + mapping['ip6s'] = [ip6_dict()] + mapping['gateway6'] = network['gateway_v6'], network_info.append((network, mapping)) return network_info -- cgit From d5c077131e00f41a38fa03fdbea46aa4351f95b5 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Wed, 6 Apr 2011 13:05:39 -0500 Subject: updated check_vm_record in test_xenapi to check the gateway6 correctly --- nova/tests/test_xenapi.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 17e3f55e9..42fe8f3fa 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -289,11 +289,11 @@ class XenAPIVMTestCase(test.TestCase): 'enabled':'1'}], 'ip6s': [{'ip': 'fe80::a8bb:ccff:fedd:eeff', 'netmask': '120', - 'enabled': '1', - 'gateway': 'fe80::a00:1'}], + 'enabled': '1'}], 'mac': 'aa:bb:cc:dd:ee:ff', 'dns': ['10.0.0.2'], - 'gateway': '10.0.0.1'}) + 'gateway': '10.0.0.1', + 'gateway6': 'fe80::a00:1'}) def check_vm_params_for_windows(self): self.assertEquals(self.vm['platform']['nx'], 'true') -- cgit From 07113a8ff0210bce81de5ef8a948cc0ff32d6623 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Wed, 6 Apr 2011 13:27:43 -0500 Subject: Incorprate johannes.erdfelt's patch --- .../xenapi/etc/xapi.d/plugins/xenstore.py | 35 ++++++++++++---------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenstore.py b/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenstore.py index a35ccd6ab..d33c7346b 100755 --- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenstore.py +++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenstore.py @@ -56,16 +56,17 @@ def read_record(self, arg_dict): and boolean True, attempting to read a non-existent path will return the string 'None' instead of raising an exception. """ - cmd = "xenstore-read /local/domain/%(dom_id)s/%(path)s" % arg_dict + cmd = ["xenstore-read", "/local/domain/%(dom_id)s/%(path)s" % arg_dict] try: - return _run_command(cmd).rstrip("\n") + ret, result = _run_command(cmd) + return result.rstrip("\n") except pluginlib.PluginError, e: if arg_dict.get("ignore_missing_path", False): - cmd = "xenstore-exists /local/domain/%(dom_id)s/%(path)s; echo $?" - cmd = cmd % arg_dict - ret = _run_command(cmd).strip() + cmd = ["xenstore-exists", + "/local/domain/%(dom_id)s/%(path)s" % arg_dict] + ret, result = _run_command(cmd).strip() # If the path exists, the cmd should return "0" - if ret != "0": + if ret != 0: # No such path, so ignore the error and return the # string 'None', since None can't be marshalled # over RPC. @@ -83,8 +84,9 @@ def write_record(self, arg_dict): you must specify a 'value' key, whose value must be a string. Typically, you can json-ify more complex values and store the json output. """ - cmd = "xenstore-write /local/domain/%(dom_id)s/%(path)s '%(value)s'" - cmd = cmd % arg_dict + cmd = ["xenstore-write", + "/local/domain/%(dom_id)s/%(path)s" % arg_dict, + arg_dict["value"]] _run_command(cmd) return arg_dict["value"] @@ -96,10 +98,10 @@ def list_records(self, arg_dict): path as the key and the stored value as the value. If the path doesn't exist, an empty dict is returned. """ - cmd = "xenstore-ls /local/domain/%(dom_id)s/%(path)s" % arg_dict - cmd = cmd.rstrip("/") + dirpath = "/local/domain/%(dom_id)s/%(path)s" % arg_dict + cmd = ["xenstore-ls", dirpath.rstrip("/")] try: - recs = _run_command(cmd) + ret, recs = _run_command(cmd) except pluginlib.PluginError, e: if "No such file or directory" in "%s" % e: # Path doesn't exist. @@ -128,8 +130,9 @@ def delete_record(self, arg_dict): """Just like it sounds: it removes the record for the specified VM and the specified path from xenstore. """ - cmd = "xenstore-rm /local/domain/%(dom_id)s/%(path)s" % arg_dict - return _run_command(cmd) + cmd = ["xenstore-rm", "/local/domain/%(dom_id)s/%(path)s" % arg_dict] + ret, result = _run_command(cmd) + return result def _paths_from_ls(recs): @@ -171,9 +174,9 @@ def _run_command(cmd): Otherwise, the output from stdout is returned. """ pipe = subprocess.PIPE - proc = subprocess.Popen([cmd], shell=True, stdin=pipe, stdout=pipe, - stderr=pipe, close_fds=True) - proc.wait() + proc = subprocess.Popen(cmd, stdin=pipe, stdout=pipe, stderr=pipe, + close_fds=True) + ret = proc.wait() err = proc.stderr.read() if err: raise pluginlib.PluginError(err) -- cgit From d3fec5c2c3de2d3a1ef0fd1fd809ff248b6df5a8 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Wed, 6 Apr 2011 13:31:51 -0500 Subject: syntax error --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index f1fa859ed..50b09d19b 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -196,7 +196,7 @@ def _get_network_info(instance): if FLAGS.use_ipv6: mapping['ip6s'] = [ip6_dict()] - mapping['gateway6'] = network['gateway_v6'], + mapping['gateway6'] = network['gateway_v6'] network_info.append((network, mapping)) return network_info -- cgit From cb51075ceeb17d43bd53617a3dc8a561e7608722 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Wed, 6 Apr 2011 14:31:54 -0400 Subject: Added logging statements for generic WSGI and specific OpenStack API requests. --- nova/api/openstack/auth.py | 17 ++++++++++++++++- nova/wsgi.py | 5 +++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py index f3a9bdeca..42c23785a 100644 --- a/nova/api/openstack/auth.py +++ b/nova/api/openstack/auth.py @@ -55,6 +55,9 @@ class AuthMiddleware(wsgi.Middleware): user = self.get_user_by_authentication(req) accounts = self.auth.get_projects(user=user) if not user: + token = req.headers["X-Auth-Token"] + msg = _("%(user)s could not be found with token '%(token)s'") + LOG.warn(msg % locals()) return faults.Fault(webob.exc.HTTPUnauthorized()) if accounts: @@ -66,6 +69,8 @@ class AuthMiddleware(wsgi.Middleware): if not self.auth.is_admin(user) and \ not self.auth.is_project_member(user, account): + msg = _("%(user)s must be an admin or a member of %(account)s") + LOG.warn(msg % locals()) return faults.Fault(webob.exc.HTTPUnauthorized()) req.environ['nova.context'] = context.RequestContext(user, account) @@ -82,12 +87,15 @@ class AuthMiddleware(wsgi.Middleware): # honor it path_info = req.path_info if len(path_info) > 1: + msg = _("Authentication requests must be made against /") + LOG.warn(msg) return faults.Fault(webob.exc.HTTPUnauthorized()) try: username = req.headers['X-Auth-User'] key = req.headers['X-Auth-Key'] - except KeyError: + except KeyError as ex: + LOG.warn(_("Could not find %s in request.") % ex) return faults.Fault(webob.exc.HTTPUnauthorized()) token, user = self._authorize_user(username, key, req) @@ -100,6 +108,7 @@ class AuthMiddleware(wsgi.Middleware): res.headers['X-CDN-Management-Url'] = token.cdn_management_url res.content_type = 'text/plain' res.status = '204' + LOG.debug(_("Successfully authenticated '%s'") % username) return res else: return faults.Fault(webob.exc.HTTPUnauthorized()) @@ -139,6 +148,7 @@ class AuthMiddleware(wsgi.Middleware): try: user = self.auth.get_user_from_access_key(key) except exception.NotFound: + LOG.warn(_("User not found with provided API key.")) user = None if user and user.name == username: @@ -153,4 +163,9 @@ class AuthMiddleware(wsgi.Middleware): token_dict['user_id'] = user.id token = self.db.auth_token_create(ctxt, token_dict) return token, user + elif user and user.name != username: + msg = _("Provided API key is valid, but not for user " + "'%(username)s'") % locals() + LOG.warn(msg) + return None, None diff --git a/nova/wsgi.py b/nova/wsgi.py index 05e7d5924..d7a1594d9 100644 --- a/nova/wsgi.py +++ b/nova/wsgi.py @@ -43,6 +43,7 @@ from nova import utils FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.wsgi') class WritableLogger(object): @@ -346,6 +347,7 @@ class Controller(object): arg_dict = req.environ['wsgiorg.routing_args'][1] action = arg_dict['action'] method = getattr(self, action) + LOG.debug("%s %s" % (req.method, req.url)) del arg_dict['controller'] del arg_dict['action'] if 'format' in arg_dict: @@ -360,6 +362,9 @@ class Controller(object): response = webob.Response() response.headers["Content-Type"] = content_type response.body = body + msg_dict = dict(url=req.url, status=response.status_int) + msg = _("%(url)s returned with HTTP %(status)d") % msg_dict + LOG.debug(msg) return response else: -- cgit From c649c8d5febab7d0dfa329bc5d78f0147383c5ee Mon Sep 17 00:00:00 2001 From: Johannes Erdfelt Date: Wed, 6 Apr 2011 11:36:08 -0700 Subject: Use a more descriptive name for the flag to make it easier to understand the purpose --- nova/virt/xenapi/vm_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index d29456ec6..cf2adb44c 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -49,7 +49,7 @@ LOG = logging.getLogger("nova.virt.xenapi.vm_utils") FLAGS = flags.FLAGS flags.DEFINE_string('default_os_type', 'linux', 'Default OS type') -flags.DEFINE_integer('timeout_block', 10, +flags.DEFINE_integer('block_device_creation_timeout', 10, 'time to wait for a block device to be created') XENAPI_POWER_STATE = { @@ -900,7 +900,7 @@ def remap_vbd_dev(dev): def _wait_for_device(dev): """Wait for device node to appear""" - for i in xrange(0, FLAGS.timeout_block): + for i in xrange(0, FLAGS.block_device_creation_timeout): if os.path.exists('/dev/%s' % dev): return time.sleep(1) -- cgit From 560d36e7ad87ca7e8f8619e146ed4965f33dd391 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Wed, 6 Apr 2011 13:43:02 -0500 Subject: another syntax error --- nova/virt/xenapi/vmops.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index f02beda24..30754b7b6 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -832,7 +832,7 @@ class VMOps(object): if network['cidr_v6']: info['ip6s'] = [ip6_dict()] if network['gateway_v6']: - info['gateway6'] = network['gateway_v6'], + info['gateway6'] = network['gateway_v6'] network_info.append((network, info)) return network_info -- cgit From 7ef28c854fa386ee1aa64aaa22c3ef026094f40a Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Wed, 6 Apr 2011 15:42:24 -0400 Subject: YADU (Yet Another Docstring Update). --- nova/compute/api.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index 790c205c0..af212ed32 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -135,8 +135,11 @@ class API(base.Base): key_name=None, key_data=None, security_group='default', availability_zone=None, user_data=None, metadata={}, injected_files=None): - """Create the number of instances requested if quota and - other arguments check out ok.""" + """Create number of instances requested, given quotas. + + Create the number of instances requested if quota and + other arguments check out ok. + """ type_data = instance_types.get_instance_type(instance_type) num_instances = quota.allowed_instances(context, max_count, type_data) -- cgit From cd279bec6391ef40d278f377f0039b507b14904b Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 6 Apr 2011 12:58:57 -0700 Subject: check visibility on delete and update --- nova/image/glance.py | 4 ++++ nova/image/local.py | 6 +++++- nova/image/s3.py | 4 ---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/nova/image/glance.py b/nova/image/glance.py index f848f40d8..bf49ca96c 100644 --- a/nova/image/glance.py +++ b/nova/image/glance.py @@ -151,6 +151,8 @@ class GlanceImageService(service.BaseImageService): :raises NotFound if the image does not exist. """ + # NOTE(vish): show is to check if image is available + self.show(context, image_id) try: image_meta = self.client.update_image(image_id, image_meta, data) except glance_exception.NotFound: @@ -165,6 +167,8 @@ class GlanceImageService(service.BaseImageService): :raises NotFound if the image does not exist. """ + # NOTE(vish): show is to check if image is available + self.show(context, image_id) try: result = self.client.delete_image(image_id) except glance_exception.NotFound: diff --git a/nova/image/local.py b/nova/image/local.py index bad4c2d85..8bf78b4c9 100644 --- a/nova/image/local.py +++ b/nova/image/local.py @@ -126,6 +126,8 @@ class LocalImageService(service.BaseImageService): def update(self, context, image_id, metadata, data=None): """Replace the contents of the given image with the new data.""" + # NOTE(vish): show is to check if image is available + self.show(context, image_id) metadata['id'] = image_id try: if data: @@ -143,9 +145,11 @@ class LocalImageService(service.BaseImageService): def delete(self, context, image_id): """Delete the given image. - Raises OSError if the image does not exist. + Raises NotFound if the image does not exist. """ + # NOTE(vish): show is to check if image is available + self.show(context, image_id) try: shutil.rmtree(self._path_to(image_id, None)) except (IOError, ValueError): diff --git a/nova/image/s3.py b/nova/image/s3.py index a7301eefd..554760d53 100644 --- a/nova/image/s3.py +++ b/nova/image/s3.py @@ -59,13 +59,9 @@ class S3ImageService(service.BaseImageService): return image def delete(self, context, image_id): - # FIXME(vish): call to show is to check visibility - self.show(context, image_id) self.service.delete(context, image_id) def update(self, context, image_id, metadata, data=None): - # FIXME(vish): call to show is to check visibility - self.show(context, image_id) image = self.service.update(context, image_id, metadata, data) return image -- cgit From 5534113f65cc578dcdf93432981b836bf4e3dfaf Mon Sep 17 00:00:00 2001 From: Naveed Massjouni Date: Wed, 6 Apr 2011 16:12:32 -0400 Subject: Added support for listing addresses of a server in the openstack api. Now you can GET * /servers/1/ips * /servers/1/ips/public * /servers/1/ips/private Supports v1.0 json and xml. Added corresponding tests. --- nova/api/openstack/__init__.py | 6 +++ nova/api/openstack/ips.py | 71 +++++++++++++++++++++++++++++ nova/api/openstack/servers.py | 9 ---- nova/api/openstack/views/addresses.py | 10 +++- nova/tests/api/openstack/test_servers.py | 78 ++++++++++++++++++++++++++++++++ 5 files changed, 163 insertions(+), 11 deletions(-) create mode 100644 nova/api/openstack/ips.py diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 7545eb0c9..5e76a06f7 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -34,6 +34,7 @@ from nova.api.openstack import consoles from nova.api.openstack import flavors from nova.api.openstack import images from nova.api.openstack import image_metadata +from nova.api.openstack import ips from nova.api.openstack import limits from nova.api.openstack import servers from nova.api.openstack import server_metadata @@ -144,6 +145,11 @@ class APIRouterV10(APIRouter): parent_resource=dict(member_name='server', collection_name='servers')) + mapper.resource("ip", "ips", controller=ips.Controller(), + collection=dict(public='GET', private='GET'), + parent_resource=dict(member_name='server', + collection_name='servers')) + class APIRouterV11(APIRouter): """Define routes specific to OpenStack API V1.1.""" diff --git a/nova/api/openstack/ips.py b/nova/api/openstack/ips.py new file mode 100644 index 000000000..89b0936d5 --- /dev/null +++ b/nova/api/openstack/ips.py @@ -0,0 +1,71 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import time + +from webob import exc + +import nova +import nova.api.openstack.views.addresses +from nova.api.openstack import faults + + +class Controller(nova.wsgi.Controller): + """The servers addresses API controller for the Openstack API.""" + + _serialization_metadata = { + 'application/xml': { + 'list_collections': { + 'public': {'item_name': 'ip', 'item_key': 'addr'}, + 'private': {'item_name': 'ip', 'item_key': 'addr'}, + }, + }, + } + + def __init__(self): + self.compute_api = nova.compute.API() + self.builder = nova.api.openstack.views.addresses.ViewBuilderV10() + + def index(self, req, server_id): + try: + instance = self.compute_api.get(req.environ['nova.context'], id) + except nova.exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + return {'addresses': self.builder.build(instance)} + + def public(self, req, server_id): + try: + instance = self.compute_api.get(req.environ['nova.context'], id) + except nova.exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + return {'public': self.builder.build_public_parts(instance)} + + def private(self, req, server_id): + try: + instance = self.compute_api.get(req.environ['nova.context'], id) + except nova.exception.NotFound: + return faults.Fault(exc.HTTPNotFound()) + return {'private': self.builder.build_private_parts(instance)} + + def show(self, req, server_id, id): + return faults.Fault(exc.HTTPNotImplemented()) + + def create(self, req, server_id): + return faults.Fault(exc.HTTPNotImplemented()) + + def delete(self, req, server_id, id): + return faults.Fault(exc.HTTPNotImplemented()) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index cada92813..67e6eefd8 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -70,15 +70,6 @@ class Controller(wsgi.Controller): self._image_service = utils.import_object(FLAGS.image_service) super(Controller, self).__init__() - def ips(self, req, id): - try: - instance = self.compute_api.get(req.environ['nova.context'], id) - except exception.NotFound: - return faults.Fault(exc.HTTPNotFound()) - - builder = self._get_addresses_view_builder(req) - return builder.build(instance) - def index(self, req): """ Returns a list of server names and ids for a given user """ return self._items(req, is_detail=False) diff --git a/nova/api/openstack/views/addresses.py b/nova/api/openstack/views/addresses.py index 90c77855b..2810cce39 100644 --- a/nova/api/openstack/views/addresses.py +++ b/nova/api/openstack/views/addresses.py @@ -28,10 +28,16 @@ class ViewBuilder(object): class ViewBuilderV10(ViewBuilder): def build(self, inst): - private_ips = utils.get_from_path(inst, 'fixed_ip/address') - public_ips = utils.get_from_path(inst, 'fixed_ip/floating_ips/address') + private_ips = self.build_private_parts(inst) + public_ips = self.build_public_parts(inst) return dict(public=public_ips, private=private_ips) + def build_public_parts(self, inst): + return utils.get_from_path(inst, 'fixed_ip/floating_ips/address') + + def build_private_parts(self, inst): + return utils.get_from_path(inst, 'fixed_ip/address') + class ViewBuilderV11(ViewBuilder): def build(self, inst): diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index a424a8105..640418cfa 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -228,6 +228,84 @@ class ServersTest(test.TestCase): self.assertEqual(len(addresses["private"]), 1) self.assertEqual(addresses["private"][0], private) + def test_get_server_addresses_V10(self): + private = '192.168.0.3' + public = ['1.2.3.4'] + new_return_server = return_server_with_addresses(private, public) + self.stubs.Set(nova.db.api, 'instance_get', new_return_server) + req = webob.Request.blank('/v1.0/servers/1/ips') + res = req.get_response(fakes.wsgi_app()) + res_dict = json.loads(res.body) + self.assertEqual(res_dict, { + 'addresses': {'public': public, 'private': [private]}}) + + def test_get_server_addresses_xml_V10(self): + private_expected = "192.168.0.3" + public_expected = ["1.2.3.4"] + new_return_server = return_server_with_addresses(private_expected, + public_expected) + self.stubs.Set(nova.db.api, 'instance_get', new_return_server) + req = webob.Request.blank('/v1.0/servers/1/ips') + req.headers['Accept'] = 'application/xml' + res = req.get_response(fakes.wsgi_app()) + dom = minidom.parseString(res.body) + (addresses,) = dom.childNodes + self.assertEquals(addresses.nodeName, 'addresses') + (public,) = addresses.getElementsByTagName('public') + (ip,) = public.getElementsByTagName('ip') + self.assertEquals(ip.getAttribute('addr'), public_expected[0]) + (private,) = addresses.getElementsByTagName('private') + (ip,) = private.getElementsByTagName('ip') + self.assertEquals(ip.getAttribute('addr'), private_expected) + + def test_get_server_addresses_public_V10(self): + private = "192.168.0.3" + public = ["1.2.3.4"] + new_return_server = return_server_with_addresses(private, public) + self.stubs.Set(nova.db.api, 'instance_get', new_return_server) + req = webob.Request.blank('/v1.0/servers/1/ips/public') + res = req.get_response(fakes.wsgi_app()) + res_dict = json.loads(res.body) + self.assertEqual(res_dict, {'public': public}) + + def test_get_server_addresses_private_V10(self): + private = "192.168.0.3" + public = ["1.2.3.4"] + new_return_server = return_server_with_addresses(private, public) + self.stubs.Set(nova.db.api, 'instance_get', new_return_server) + req = webob.Request.blank('/v1.0/servers/1/ips/private') + res = req.get_response(fakes.wsgi_app()) + res_dict = json.loads(res.body) + self.assertEqual(res_dict, {'private': [private]}) + + def test_get_server_addresses_public_xml_V10(self): + private = "192.168.0.3" + public = ["1.2.3.4"] + new_return_server = return_server_with_addresses(private, public) + self.stubs.Set(nova.db.api, 'instance_get', new_return_server) + req = webob.Request.blank('/v1.0/servers/1/ips/public') + req.headers['Accept'] = 'application/xml' + res = req.get_response(fakes.wsgi_app()) + dom = minidom.parseString(res.body) + (public_node,) = dom.childNodes + self.assertEquals(public_node.nodeName, 'public') + (ip,) = public_node.getElementsByTagName('ip') + self.assertEquals(ip.getAttribute('addr'), public[0]) + + def test_get_server_addresses_private_xml_V10(self): + private = "192.168.0.3" + public = ["1.2.3.4"] + new_return_server = return_server_with_addresses(private, public) + self.stubs.Set(nova.db.api, 'instance_get', new_return_server) + req = webob.Request.blank('/v1.0/servers/1/ips/private') + req.headers['Accept'] = 'application/xml' + res = req.get_response(fakes.wsgi_app()) + dom = minidom.parseString(res.body) + (private_node,) = dom.childNodes + self.assertEquals(private_node.nodeName, 'private') + (ip,) = private_node.getElementsByTagName('ip') + self.assertEquals(ip.getAttribute('addr'), private) + def test_get_server_by_id_with_addresses_v11(self): private = "192.168.0.3" public = ["1.2.3.4"] -- cgit From e16571671e4baab50521870ec64e4ab954c7d165 Mon Sep 17 00:00:00 2001 From: Naveed Massjouni Date: Wed, 6 Apr 2011 17:50:11 -0400 Subject: Controllers now inherit from nova.api.openstack.common.OpenstackController. --- nova/api/openstack/ips.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/api/openstack/ips.py b/nova/api/openstack/ips.py index 89b0936d5..778e9ba1a 100644 --- a/nova/api/openstack/ips.py +++ b/nova/api/openstack/ips.py @@ -21,10 +21,11 @@ from webob import exc import nova import nova.api.openstack.views.addresses +from nova.api.openstack import common from nova.api.openstack import faults -class Controller(nova.wsgi.Controller): +class Controller(common.OpenstackController): """The servers addresses API controller for the Openstack API.""" _serialization_metadata = { -- cgit From 040428cc35aa046de4bcf744c95b7c507df94550 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 6 Apr 2011 14:53:35 -0700 Subject: Add automatic metadata ip to network host on start. Also fix race where gw is readded twice --- nova/network/linux_net.py | 13 ++++++++++++- nova/network/manager.py | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index d11d21dad..6a7051d10 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -391,6 +391,13 @@ def unbind_floating_ip(floating_ip): 'dev', FLAGS.public_interface) +def ensure_metadata_ip(interface): + """Sets up local metadata ip""" + _execute('sudo', 'ip', 'addr', 'add', '169.254.169.254/32', + 'scope', 'link', 'dev', interface, + check_exit_code=False) + + def ensure_vlan_forward(public_ip, port, private_ip): """Sets up forwarding rules for vlan""" iptables_manager.ipv4['filter'].add_rule("FORWARD", @@ -504,7 +511,11 @@ def ensure_bridge(bridge, interface, net_attrs=None): _execute(*_ip_bridge_cmd('del', params, fields[-1])) _execute(*_ip_bridge_cmd('add', params, bridge)) if gateway: - _execute('sudo', 'route', 'add', '0.0.0.0', 'gw', gateway) + # NOTE(vish): If the gateway already exists we are fine + out, err = _execute('sudo', 'route', 'add', '0.0.0.0', 'gw', + gateway, check_exit_code=False) + if err and err != "SIOCADDRT: File exists\n": + raise exception.Error("Failed to reset gateway: %s" % err) out, err = _execute('sudo', 'brctl', 'addif', bridge, interface, check_exit_code=False) diff --git a/nova/network/manager.py b/nova/network/manager.py index 86ee4fc00..a3c345b69 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -100,6 +100,8 @@ flags.DEFINE_string('network_host', socket.gethostname(), 'Network host to use for ip allocation in flat modes') flags.DEFINE_bool('fake_call', False, 'If True, skip using the queue and make local calls') +flags.DEFINE_string('metadata_interface', 'eth0', + 'interface to add the metadata ip to') class AddressAlreadyAllocated(exception.Error): @@ -128,6 +130,7 @@ class NetworkManager(manager.SchedulerDependentManager): self.driver.init_host() # Set up networking for the projects for which we're already # the designated network host. + self.driver.ensure_metadata_ip(FLAGS.metadata_interface) ctxt = context.get_admin_context() for network in self.db.host_get_networks(ctxt, self.host): self._on_set_network_host(ctxt, network['id']) -- cgit From 14833117f19a3a1789c99a519b12bf9c61faec07 Mon Sep 17 00:00:00 2001 From: Naveed Massjouni Date: Wed, 6 Apr 2011 18:17:43 -0400 Subject: Added an option to run_tests.sh so you can run just pep8. So now you can: ./run_tests.sh --just-pep8 or ./run_tests.sh -p --- run_tests.sh | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/run_tests.sh b/run_tests.sh index 8f4d37cd4..9773071c7 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -7,6 +7,7 @@ function usage { echo " -V, --virtual-env Always use virtualenv. Install automatically if not present" echo " -N, --no-virtual-env Don't use virtualenv. Run tests in local environment" echo " -f, --force Force a clean re-build of the virtual environment. Useful when dependencies have been added." + echo " -p, --just-pep8 Just run pep8" echo " -h, --help Print this usage message" echo "" echo "Note: with no options specified, the script will try to run the tests in a virtual environment," @@ -21,6 +22,7 @@ function process_option { -V|--virtual-env) let always_venv=1; let never_venv=0;; -N|--no-virtual-env) let always_venv=0; let never_venv=1;; -f|--force) let force=1;; + -p|--just-pep8) let just_pep8=1;; *) noseargs="$noseargs $1" esac } @@ -32,6 +34,7 @@ never_venv=0 force=0 noseargs= wrapper="" +just_pep8=0 for arg in "$@"; do process_option $arg @@ -53,6 +56,18 @@ function run_tests { return $RESULT } +function run_pep8 { + echo "Running pep8 ..." + srcfiles=`find bin -type f ! -name "nova.conf*"` + srcfiles+=" nova setup.py plugins/xenserver/xenapi/etc/xapi.d/plugins/glance" + pep8 --repeat --show-pep8 --show-source --exclude=vcsversion.py ${srcfiles} +} + +if [ $just_pep8 -eq 1 ]; then + run_pep8 + exit +fi + NOSETESTS="python run_tests.py $noseargs" if [ $never_venv -eq 0 ] @@ -81,11 +96,9 @@ then fi fi -if [ -z "$noseargs" ]; -then - srcfiles=`find bin -type f ! -name "nova.conf*"` - srcfiles+=" nova setup.py plugins/xenserver/xenapi/etc/xapi.d/plugins/glance" - run_tests && pep8 --repeat --show-pep8 --show-source --exclude=vcsversion.py ${srcfiles} || exit 1 -else - run_tests +run_tests + +# Also run pep8 if no options were provided. +if [ -z "$noseargs" ]; then + run_pep8 fi -- cgit From dc8b3cb3fa124755ed3e5282b2d11a811f1db2d5 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 6 Apr 2011 15:39:44 -0700 Subject: removed comment on API compliance --- nova/api/openstack/views/servers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index baa911590..096bf70c6 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -82,7 +82,6 @@ class ViewBuilder(object): # Return the metadata as a dictionary metadata = {} for item in inst.get('metadata', []): - # metadata values must be strings per API metadata[item['key']] = str(item['value']) inst_dict['metadata'] = metadata -- cgit From 3831008b4e8aeec08b58afb49e40428ad5ece5b1 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 6 Apr 2011 16:10:08 -0700 Subject: if we delete the old route when we move it we don't need to check for exists --- nova/network/linux_net.py | 9 ++++----- nova/network/manager.py | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index 6a7051d10..a4d312f02 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -449,6 +449,7 @@ def ensure_vlan(vlan_num): return interface +@utils.synchronized('ensure_bridge', external=True) def ensure_bridge(bridge, interface, net_attrs=None): """Create a bridge unless it already exists. @@ -502,6 +503,8 @@ def ensure_bridge(bridge, interface, net_attrs=None): fields = line.split() if fields and fields[0] == "0.0.0.0" and fields[-1] == interface: gateway = fields[1] + _execute('sudo', 'route', 'del', 'default', 'gw', gateway, + 'dev', interface) out, err = _execute('sudo', 'ip', 'addr', 'show', 'dev', interface, 'scope', 'global') for line in out.split("\n"): @@ -511,11 +514,7 @@ def ensure_bridge(bridge, interface, net_attrs=None): _execute(*_ip_bridge_cmd('del', params, fields[-1])) _execute(*_ip_bridge_cmd('add', params, bridge)) if gateway: - # NOTE(vish): If the gateway already exists we are fine - out, err = _execute('sudo', 'route', 'add', '0.0.0.0', 'gw', - gateway, check_exit_code=False) - if err and err != "SIOCADDRT: File exists\n": - raise exception.Error("Failed to reset gateway: %s" % err) + _execute('sudo', 'route', 'add', 'default', 'gw', gateway) out, err = _execute('sudo', 'brctl', 'addif', bridge, interface, check_exit_code=False) diff --git a/nova/network/manager.py b/nova/network/manager.py index a3c345b69..b80560bdf 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -128,9 +128,9 @@ class NetworkManager(manager.SchedulerDependentManager): standalone service. """ self.driver.init_host() + self.driver.ensure_metadata_ip(FLAGS.metadata_interface) # Set up networking for the projects for which we're already # the designated network host. - self.driver.ensure_metadata_ip(FLAGS.metadata_interface) ctxt = context.get_admin_context() for network in self.db.host_get_networks(ctxt, self.host): self._on_set_network_host(ctxt, network['id']) -- cgit From 1ee150c449e630c6409798399eccb577c8273c70 Mon Sep 17 00:00:00 2001 From: Muneyuki Noguchi Date: Thu, 7 Apr 2011 12:35:45 +0900 Subject: Make description of volume_id more generic. --- nova/compute/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 85bcd7590..383eda0dc 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -786,7 +786,7 @@ class ComputeManager(manager.SchedulerDependentManager): """Remove volume on compute host. :param context: security context - :param volume_id: nova.db.sqlalchemy.models.Volume.id + :param volume_id: volume ID """ self.volume_manager.remove_compute_volume(context, volume_id) -- cgit From d7e8d91d6bc4954f2d256f57e34444b5bd170ab0 Mon Sep 17 00:00:00 2001 From: Kei Masumoto Date: Thu, 7 Apr 2011 13:08:14 +0900 Subject: fixed based on reviewer's comment - 'locals() should be off from _() --- nova/compute/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 37a904b1e..847c3655a 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1096,7 +1096,7 @@ class ComputeManager(manager.SchedulerDependentManager): # this case should be ignored. LOG.info(_("the instance '%(name)s' is not found in hypervisor" ", while db record is found. But not synchronize " - "since it is migrating." % locals())) + "since it is migrating.") % locals()) continue if vm_state != db_state: -- cgit From 2bc0e744162276048ddd9c1a1eeacbd647cda6f4 Mon Sep 17 00:00:00 2001 From: Kei Masumoto Date: Thu, 7 Apr 2011 13:32:19 +0900 Subject: fixed based on reviewer's comment - 1. erase unnecessary blank line, 2. adding LOG.debug --- nova/virt/libvirt_conn.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index bdf577825..eab54c53e 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1849,7 +1849,6 @@ class NWFilterFirewall(FirewallDriver): def instance_filter_exists(self, instance): """Check nova-instance-instance-xxx exists""" - network_info = _get_network_info(instance) for (network, mapping) in network_info: nic_id = mapping['mac'].replace(':', '') @@ -1857,6 +1856,9 @@ class NWFilterFirewall(FirewallDriver): try: self._conn.nwfilterLookupByName(instance_filter_name) except libvirt.libvirtError: + name = instance.name + LOG.debug(_('The nwfilter(%(instance_filter_name)s) for' + '%(name)s is not found.') % locals()) return False return True -- cgit From 7cf0deda8f7ab410005c556779353d599c8e8a63 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 7 Apr 2011 10:34:14 -0300 Subject: adds timeout to login_with_password --- nova/virt/xenapi_conn.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 99fd35c61..6dfe0b9a9 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -63,6 +63,7 @@ import xmlrpclib from eventlet import event from eventlet import tpool +from eventlet import timeout from nova import context from nova import db @@ -140,7 +141,9 @@ flags.DEFINE_bool('xenapi_remap_vbd_dev', False, flags.DEFINE_string('xenapi_remap_vbd_dev_prefix', 'sd', 'Specify prefix to remap VBD dev to ' '(ex. /dev/xvdb -> /dev/sdb)') - +flags.DEFINE_integer('xenapi_login_timeout', + 10, + 'Timeout in seconds for XenAPI login.') def get_connection(_): """Note that XenAPI doesn't have a read-only connection mode, so @@ -318,7 +321,9 @@ class XenAPISession(object): def __init__(self, url, user, pw): self.XenAPI = self.get_imported_xenapi() self._session = self._create_session(url) - self._session.login_with_password(user, pw) + exception = self.XenAPI.Failure(_("Unable to log in to XenAPI.")) + with timeout.Timeout(FLAGS.xenapi_login_timeout, exception): + self._session.login_with_password(user, pw) self.loop = None def get_imported_xenapi(self): -- cgit From 9b24c399c5689a1492b96dcd6725590c2a97c6e3 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 7 Apr 2011 10:42:29 -0300 Subject: pep8 --- nova/virt/xenapi_conn.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 6dfe0b9a9..f10aa6eb5 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -145,6 +145,7 @@ flags.DEFINE_integer('xenapi_login_timeout', 10, 'Timeout in seconds for XenAPI login.') + def get_connection(_): """Note that XenAPI doesn't have a read-only connection mode, so the read_only parameter is ignored.""" -- cgit From 9f57f78efab4a31bfe29e2edab1e86eedf4352fd Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 7 Apr 2011 11:59:40 -0300 Subject: better error message --- nova/virt/xenapi_conn.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index f10aa6eb5..0cabccf08 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -322,7 +322,8 @@ class XenAPISession(object): def __init__(self, url, user, pw): self.XenAPI = self.get_imported_xenapi() self._session = self._create_session(url) - exception = self.XenAPI.Failure(_("Unable to log in to XenAPI.")) + exception = self.XenAPI.Failure(_("Unable to log in to XenAPI " + "(is the Dom0 disk full?)")) with timeout.Timeout(FLAGS.xenapi_login_timeout, exception): self._session.login_with_password(user, pw) self.loop = None -- cgit From 8da3e6c19b97ab7cd08e69fb0df114653c0b90db Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 7 Apr 2011 10:37:40 -0700 Subject: Simplify by always adding to loopback --- nova/network/linux_net.py | 5 ++--- nova/network/manager.py | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index a4d312f02..ed6c943c7 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -391,11 +391,10 @@ def unbind_floating_ip(floating_ip): 'dev', FLAGS.public_interface) -def ensure_metadata_ip(interface): +def ensure_metadata_ip(): """Sets up local metadata ip""" _execute('sudo', 'ip', 'addr', 'add', '169.254.169.254/32', - 'scope', 'link', 'dev', interface, - check_exit_code=False) + 'scope', 'link', 'dev', 'lo', check_exit_code=False) def ensure_vlan_forward(public_ip, port, private_ip): diff --git a/nova/network/manager.py b/nova/network/manager.py index b80560bdf..0dd7f2360 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -100,8 +100,6 @@ flags.DEFINE_string('network_host', socket.gethostname(), 'Network host to use for ip allocation in flat modes') flags.DEFINE_bool('fake_call', False, 'If True, skip using the queue and make local calls') -flags.DEFINE_string('metadata_interface', 'eth0', - 'interface to add the metadata ip to') class AddressAlreadyAllocated(exception.Error): @@ -128,7 +126,7 @@ class NetworkManager(manager.SchedulerDependentManager): standalone service. """ self.driver.init_host() - self.driver.ensure_metadata_ip(FLAGS.metadata_interface) + self.driver.ensure_metadata_ip() # Set up networking for the projects for which we're already # the designated network host. ctxt = context.get_admin_context() -- cgit From fcf358cacd8f993faaf64310307956686a7d330b Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 7 Apr 2011 11:12:14 -0700 Subject: moved -manage instance list command to -manage vm list to avoid lazy match conflict with instance_types --- bin/nova-manage | 85 +++++++++++++++++++++++++++------------------------------ 1 file changed, 40 insertions(+), 45 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 6789efba8..bd3f9f50d 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -570,6 +570,45 @@ class NetworkCommands(object): class VmCommands(object): """Class for mangaging VM instances.""" + def list(self, host=None, instance=None): + """Show a list of all instances""" + print "%-10s %-15s %-10s %-10s %-19s %-12s %-12s %-12s" \ + " %-10s %-10s %-10s %-5s" % ( + _('instance'), + _('node'), + _('type'), + _('state'), + _('launched'), + _('image'), + _('kernel'), + _('ramdisk'), + _('project'), + _('user'), + _('zone'), + _('index')) + + if host == None: + instances = db.instance_get_all(context.get_admin_context()) + else: + instances = db.instance_get_all_by_host( + context.get_admin_context(), host) + + for instance in instances: + print "%-10s %-15s %-10s %-10s %-19s %-12s %-12s %-12s" \ + " %-10s %-10s %-10s %-5d" % ( + instance['hostname'], + instance['host'], + instance['instance_type'], + instance['state_description'], + instance['launched_at'], + instance['image_id'], + instance['kernel_id'], + instance['ramdisk_id'], + instance['project_id'], + instance['user_id'], + instance['availability_zone'], + instance['launch_index']) + def live_migration(self, ec2_id, dest): """Migrates a running instance to a new machine. @@ -725,49 +764,6 @@ class DbCommands(object): print migration.db_version() -class InstanceCommands(object): - """Class for managing instances.""" - - def list(self, host=None, instance=None): - """Show a list of all instances""" - print "%-10s %-15s %-10s %-10s %-19s %-12s %-12s %-12s" \ - " %-10s %-10s %-10s %-5s" % ( - _('instance'), - _('node'), - _('type'), - _('state'), - _('launched'), - _('image'), - _('kernel'), - _('ramdisk'), - _('project'), - _('user'), - _('zone'), - _('index')) - - if host == None: - instances = db.instance_get_all(context.get_admin_context()) - else: - instances = db.instance_get_all_by_host( - context.get_admin_context(), host) - - for instance in instances: - print "%-10s %-15s %-10s %-10s %-19s %-12s %-12s %-12s" \ - " %-10s %-10s %-10s %-5d" % ( - instance['hostname'], - instance['host'], - instance['instance_type'], - instance['state_description'], - instance['launched_at'], - instance['image_id'], - instance['kernel_id'], - instance['ramdisk_id'], - instance['project_id'], - instance['user_id'], - instance['availability_zone'], - instance['launch_index']) - - class VolumeCommands(object): """Methods for dealing with a cloud in an odd state""" @@ -1054,8 +1050,7 @@ CATEGORIES = [ ('volume', VolumeCommands), ('instance_type', InstanceTypeCommands), ('image', ImageCommands), - ('flavor', InstanceTypeCommands), - ('instance', InstanceCommands)] + ('flavor', InstanceTypeCommands)] def lazy_match(name, key_value_tuples): -- cgit From ce5e102d0097f1b3f2322dc0d1ac1d0e5dea7f0a Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 7 Apr 2011 11:22:31 -0700 Subject: removed unused instance parameter from vm list ... as it is unused. added parameters to docstring for vm list. --- bin/nova-manage | 8 ++++++-- doc/source/man/novamanage.rst | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index bd3f9f50d..6903c16c9 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -570,8 +570,12 @@ class NetworkCommands(object): class VmCommands(object): """Class for mangaging VM instances.""" - def list(self, host=None, instance=None): - """Show a list of all instances""" + def list(self, host=None): + """Show a list of all instances + + :param host: show all instance on specified host. + :param instance: show specificed instance. + """ print "%-10s %-15s %-10s %-10s %-19s %-12s %-12s %-12s" \ " %-10s %-10s %-10s %-5s" % ( _('instance'), diff --git a/doc/source/man/novamanage.rst b/doc/source/man/novamanage.rst index 1d8446f08..b7688f0d8 100644 --- a/doc/source/man/novamanage.rst +++ b/doc/source/man/novamanage.rst @@ -240,6 +240,16 @@ Nova Images Converts all images in directory from the old (Bexar) format to the new format. +Nova VM +~~~~~~~~~~~ + +``nova-manage vm list [host]`` + Show a list of all instances. Accepts optional hostname (to show only instances on specific host). + +``nova-manage live-migration `` + Live migrate instance from current host to destination host. Requires instance id (which comes from euca-describe-instance) and destination host name. + + FILES ======== -- cgit From 11b76108dbd8a540da151141f5208de9358cf38b Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 7 Apr 2011 11:25:44 -0700 Subject: added -manage vm [list|live-migration] to man page --- doc/source/man/novamanage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/man/novamanage.rst b/doc/source/man/novamanage.rst index b7688f0d8..9c54f3608 100644 --- a/doc/source/man/novamanage.rst +++ b/doc/source/man/novamanage.rst @@ -247,7 +247,7 @@ Nova VM Show a list of all instances. Accepts optional hostname (to show only instances on specific host). ``nova-manage live-migration `` - Live migrate instance from current host to destination host. Requires instance id (which comes from euca-describe-instance) and destination host name. + Live migrate instance from current host to destination host. Requires instance id (which comes from euca-describe-instance) and destination host name (which can be found from nova-manage service list). FILES -- cgit From 404feb59a829e24e026f793a362e54aad1aaa03f Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Thu, 7 Apr 2011 13:55:42 -0500 Subject: Renamed computeFault to cloudServersFault --- nova/api/openstack/faults.py | 2 +- nova/tests/api/openstack/test_api.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nova/api/openstack/faults.py b/nova/api/openstack/faults.py index bc97639a0..87118ce19 100644 --- a/nova/api/openstack/faults.py +++ b/nova/api/openstack/faults.py @@ -47,7 +47,7 @@ class Fault(webob.exc.HTTPException): """Generate a WSGI response based on the exception passed to ctor.""" # Replace the body with fault details. code = self.wrapped_exc.status_int - fault_name = self._fault_names.get(code, "computeFault") + fault_name = self._fault_names.get(code, "cloudServersFault") fault_data = { fault_name: { 'code': code, diff --git a/nova/tests/api/openstack/test_api.py b/nova/tests/api/openstack/test_api.py index 5112c486f..c63431a45 100644 --- a/nova/tests/api/openstack/test_api.py +++ b/nova/tests/api/openstack/test_api.py @@ -53,13 +53,13 @@ class APITest(test.TestCase): #api.application = succeed api = self._wsgi_app(succeed) resp = Request.blank('/').get_response(api) - self.assertFalse('computeFault' in resp.body, resp.body) + self.assertFalse('cloudServersFault' in resp.body, resp.body) self.assertEqual(resp.status_int, 200, resp.body) #api.application = raise_webob_exc api = self._wsgi_app(raise_webob_exc) resp = Request.blank('/').get_response(api) - self.assertFalse('computeFault' in resp.body, resp.body) + self.assertFalse('cloudServersFault' in resp.body, resp.body) self.assertEqual(resp.status_int, 404, resp.body) #api.application = raise_api_fault @@ -71,11 +71,11 @@ class APITest(test.TestCase): #api.application = fail api = self._wsgi_app(fail) resp = Request.blank('/').get_response(api) - self.assertTrue('{"computeFault' in resp.body, resp.body) + self.assertTrue('{"cloudServersFault' in resp.body, resp.body) self.assertEqual(resp.status_int, 500, resp.body) #api.application = fail api = self._wsgi_app(fail) resp = Request.blank('/.xml').get_response(api) - self.assertTrue(' Date: Thu, 7 Apr 2011 15:09:10 -0400 Subject: Drop unneeded Fkey on InstanceTypes.id. --- nova/db/sqlalchemy/models.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 9d4c6cdef..f79d0f16c 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -258,8 +258,7 @@ class InstanceActions(BASE, NovaBase): class InstanceTypes(BASE, NovaBase): """Represent possible instance_types or flavor of VM offered""" __tablename__ = "instance_types" - id = Column(Integer, ForeignKey('instances.instance_type_id'), - primary_key=True) + id = Column(Integer, primary_key=True) name = Column(String(255), unique=True) memory_mb = Column(Integer) vcpus = Column(Integer) -- cgit From 99e8335e9b07b1cbf9c28cda2dfb2496d955c72c Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Thu, 7 Apr 2011 15:43:51 -0400 Subject: Some i18n fixes to instance_types. --- nova/compute/instance_types.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index 5b1d92e29..b3a5ab0ac 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -59,8 +59,8 @@ def create(name, memory, vcpus, local_gb, flavorid, swap=0, rxtx_quota=rxtx_quota, rxtx_cap=rxtx_cap)) except exception.DBError, e: - LOG.exception(_('DB error: %s' % e)) - raise exception.ApiError(_("Cannot create instance type: %s" % name)) + LOG.exception(_('DB error: %s') % e) + raise exception.ApiError(_("Cannot create instance type: %s") % name) def destroy(name): @@ -72,8 +72,8 @@ def destroy(name): try: db.instance_type_destroy(context.get_admin_context(), name) except exception.NotFound: - LOG.exception(_('Instance type %s not found for deletion' % name)) - raise exception.ApiError(_("Unknown instance type: %s" % name)) + LOG.exception(_('Instance type %s not found for deletion') % name) + raise exception.ApiError(_("Unknown instance type: %s") % name) def purge(name): @@ -85,8 +85,8 @@ def purge(name): try: db.instance_type_purge(context.get_admin_context(), name) except exception.NotFound: - LOG.exception(_('Instance type %s not found for purge' % name)) - raise exception.ApiError(_("Unknown instance type: %s" % name)) + LOG.exception(_('Instance type %s not found for purge') % name) + raise exception.ApiError(_("Unknown instance type: %s") % name) def get_all_types(inactive=0): @@ -106,7 +106,7 @@ def get_default_instance_type(): try: return get_instance_type_by_name(name) except exception.DBError: - raise exception.ApiError(_("Unknown instance type: %s" % name)) + raise exception.ApiError(_("Unknown instance type: %s") % name) def get_instance_type(id): @@ -117,7 +117,7 @@ def get_instance_type(id): ctxt = context.get_admin_context() return db.instance_type_get_by_id(ctxt, id) except exception.DBError: - raise exception.ApiError(_("Unknown instance type: %s" % name)) + raise exception.ApiError(_("Unknown instance type: %s") % name) def get_instance_type_by_name(name): @@ -128,7 +128,7 @@ def get_instance_type_by_name(name): ctxt = context.get_admin_context() return db.instance_type_get_by_name(ctxt, name) except exception.DBError: - raise exception.ApiError(_("Unknown instance type: %s" % name)) + raise exception.ApiError(_("Unknown instance type: %s") % name) def get_instance_type_by_flavor_id(flavor_id): @@ -139,5 +139,5 @@ def get_instance_type_by_flavor_id(flavor_id): ctxt = context.get_admin_context() return db.instance_type_get_by_flavor_id(ctxt, flavor_id) except exception.DBError, e: - LOG.exception(_('DB error: %s' % e)) - raise exception.ApiError(_("Unknown flavor: %s" % flavor_id)) + LOG.exception(_('DB error: %s') % e) + raise exception.ApiError(_("Unknown flavor: %s") % flavor_id) -- cgit From c7fd470d7ff0df4b23664b6599e5ae5acdb21511 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Thu, 7 Apr 2011 15:52:14 -0400 Subject: Drop extra 'None' arg from dict.get call. --- nova/api/ec2/cloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index e4bcccb2b..c3124b89d 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -731,7 +731,7 @@ class CloudController(object): instance['host']) i['productCodesSet'] = self._convert_to_set([], 'product_codes') if instance['instance_type']: - i['instanceType'] = instance['instance_type'].get('name', None) + i['instanceType'] = instance['instance_type'].get('name') else: i['instanceType'] = None i['launchTime'] = instance['created_at'] -- cgit From b5310d58d418f123b2d5d2953d6b4082a70120cd Mon Sep 17 00:00:00 2001 From: Kei Masumoto Date: Fri, 8 Apr 2011 06:32:53 +0900 Subject: fix pep8 violation --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index eab54c53e..256e6e635 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1857,7 +1857,7 @@ class NWFilterFirewall(FirewallDriver): self._conn.nwfilterLookupByName(instance_filter_name) except libvirt.libvirtError: name = instance.name - LOG.debug(_('The nwfilter(%(instance_filter_name)s) for' + LOG.debug(_('The nwfilter(%(instance_filter_name)s) for' '%(name)s is not found.') % locals()) return False return True -- cgit From a1572a4f234bdeda1d25250de62b5892d8f47891 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 7 Apr 2011 15:00:35 -0700 Subject: clarified nova-manage instance_type create error output on duplicate flavorid --- bin/nova-manage | 10 +++++++--- nova/compute/instance_types.py | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 25695482f..a999571b2 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -819,6 +819,7 @@ class InstanceTypeCommands(object): """Class for managing instance types / flavors.""" def _print_instance_types(self, n, val): + """helper method to print out instance_types values""" deleted = ('', ', inactive')[val["deleted"] == 1] print ("%s: Memory: %sMB, VCPUS: %s, Storage: %sGB, FlavorID: %s, " "Swap: %sGB, RXTX Quota: %sGB, RXTX Cap: %sMB%s") % ( @@ -836,11 +837,14 @@ class InstanceTypeCommands(object): instance_types.create(name, memory, vcpus, local_gb, flavorid, swap, rxtx_quota, rxtx_cap) except exception.InvalidInputException: - print "Must supply valid parameters to create instance type" + print "Must supply valid parameters to create instance_type" print e sys.exit(1) - except exception.DBError, e: - print "DB Error: %s" % e + except exception.ApiError, e: + print e + print "Please ensure instance_type name and flavor id are unique" + print "Here are the already defined instance_type names and flavorids:" + self.list("--all") sys.exit(2) except: print "Unknown error" diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index fa02a5dfa..bfa120675 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -60,7 +60,9 @@ def create(name, memory, vcpus, local_gb, flavorid, swap=0, rxtx_cap=rxtx_cap)) except exception.DBError, e: LOG.exception(_('DB error: %s' % e)) - raise exception.ApiError(_("Cannot create instance type: %s" % name)) + raise exception.ApiError( + _("Cannot create instance_type with name %s and flavorid %s"\ + % (name, flavorid))) def destroy(name): -- cgit From 59b460e98c5b8f718a654539c5788e8775126dfd Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 7 Apr 2011 15:08:29 -0700 Subject: slight typo --- bin/nova-manage | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/nova-manage b/bin/nova-manage index a999571b2..5369a98b3 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -841,7 +841,6 @@ class InstanceTypeCommands(object): print e sys.exit(1) except exception.ApiError, e: - print e print "Please ensure instance_type name and flavor id are unique" print "Here are the already defined instance_type names and flavorids:" self.list("--all") -- cgit From b54be0e29cdcd91e3d106fb587b89c39ca3a0bff Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 7 Apr 2011 15:52:27 -0700 Subject: Removed commented-out old 'delete instance on SHUTOFF' code --- nova/compute/manager.py | 6 ------ nova/virt/libvirt_conn.py | 8 +------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 72f04ecb1..d3cd2e51a 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1090,12 +1090,6 @@ class ComputeManager(manager.SchedulerDependentManager): # NOTE(justinsb): We no longer auto-remove SHUTOFF instances # It's quite hard to get them back when we do. - #if vm_state == power_state.SHUTOFF: - # # TODO(soren): This is what the compute manager does when you - # # terminate an instance. At some point I figure we'll have a - # # "terminated" state and some sort of cleanup job that runs - # # occasionally, cleaning them out. - # self.db.instance_destroy(context, db_instance['id']) # Are there VMs not in the DB? for vm_not_found_in_db in vms_not_found_in_db: diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 533ff9394..4523cdd2f 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -232,14 +232,8 @@ class LibvirtConnection(driver.ComputeDriver): {'name': instance['name'], 'state': state}) db.instance_set_state(ctxt, instance['id'], state) - # NOTE(justinsb): We no longer delete these instances, + # NOTE(justinsb): We no longer delete SHUTOFF instances, # the user may want to power them back on - #if state == power_state.SHUTOFF: - # # TODO(soren): This is what the compute manager does when you - # # terminate # an instance. At some point I figure we'll have a - # # "terminated" state and some sort of cleanup job that runs - # # occasionally, cleaning them out. - # db.instance_destroy(ctxt, instance['id']) if state != power_state.RUNNING: continue -- cgit From 52478e039b094861e7d783b7995b9cafa68e32b9 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 7 Apr 2011 15:56:16 -0700 Subject: Fix to correct libvirt error code when the domain is not found --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 4523cdd2f..a7a8a14b1 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -974,7 +974,7 @@ class LibvirtConnection(driver.ComputeDriver): try: virt_dom = self._conn.lookupByName(instance_name) except libvirt.libvirtError as e: - if e.get_error_code() == libvirt.VIR_ERR_UNKNOWN_HOST: + if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN: raise exception.NotFound(_("Instance %s not found") % instance_name) LOG.warning(_("Error from libvirt during lookup: %s") % e) -- cgit From 0c5f70c0bcf9395fb25a231057d997b075d04fda Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 7 Apr 2011 16:00:55 -0700 Subject: Log libvirt errcode on exception --- nova/virt/libvirt_conn.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index a7a8a14b1..5f1c12ab3 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -974,10 +974,13 @@ class LibvirtConnection(driver.ComputeDriver): try: virt_dom = self._conn.lookupByName(instance_name) except libvirt.libvirtError as e: - if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN: + errcode = e.get_error_code() + if errcode == libvirt.VIR_ERR_NO_DOMAIN: raise exception.NotFound(_("Instance %s not found") % instance_name) - LOG.warning(_("Error from libvirt during lookup: %s") % e) + LOG.warning(_("Error from libvirt during lookup. " + "Code=%(errcode)s Error=%(e)s") % + locals()) raise (state, max_mem, mem, num_cpu, cpu_time) = virt_dom.info() -- cgit From b0ad20c796bd25dad0538ab85b1a56f421e16039 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 7 Apr 2011 16:42:33 -0700 Subject: fix tests from moving access check into update and delete --- nova/image/local.py | 5 ++++- nova/tests/image/test_glance.py | 8 ++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/nova/image/local.py b/nova/image/local.py index 8bf78b4c9..d4fd62156 100644 --- a/nova/image/local.py +++ b/nova/image/local.py @@ -122,12 +122,15 @@ class LocalImageService(service.BaseImageService): image_path = self._path_to(image_id, None) if not os.path.exists(image_path): os.mkdir(image_path) - return self.update(context, image_id, metadata, data) + return self._store(context, image_id, metadata, data) def update(self, context, image_id, metadata, data=None): """Replace the contents of the given image with the new data.""" # NOTE(vish): show is to check if image is available self.show(context, image_id) + return self._store(context, image_id, metadata, data) + + def _store(self, context, image_id, metadata, data=None): metadata['id'] = image_id try: if data: diff --git a/nova/tests/image/test_glance.py b/nova/tests/image/test_glance.py index 9d0b14613..109905ded 100644 --- a/nova/tests/image/test_glance.py +++ b/nova/tests/image/test_glance.py @@ -209,17 +209,17 @@ class TestMutatorDateTimeTests(BaseGlanceTest): self.assertDateTimesEmpty(image_meta) def test_update_handles_datetimes(self): + self.client.images = {'image1': self._make_datetime_fixture()} self.client.update_response = self._make_datetime_fixture() - dummy_id = 'dummy_id' dummy_meta = {} - image_meta = self.service.update(self.context, 'dummy_id', dummy_meta) + image_meta = self.service.update(self.context, 'image1', dummy_meta) self.assertDateTimesFilled(image_meta) def test_update_handles_none_datetimes(self): + self.client.images = {'image1': self._make_datetime_fixture()} self.client.update_response = self._make_none_datetime_fixture() - dummy_id = 'dummy_id' dummy_meta = {} - image_meta = self.service.update(self.context, 'dummy_id', dummy_meta) + image_meta = self.service.update(self.context, 'image1', dummy_meta) self.assertDateTimesEmpty(image_meta) def _make_datetime_fixture(self): -- cgit From 86ffed4e988025023b570b9e6e87f89b6075c7b0 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 7 Apr 2011 17:38:24 -0700 Subject: reminde admins of --purge option --- bin/nova-manage | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index e63898979..73da83767 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -841,8 +841,10 @@ class InstanceTypeCommands(object): print e sys.exit(1) except exception.ApiError, e: - print "Please ensure instance_type name and flavor id are unique" - print "Here are the already defined instance_type names and flavorids:" + print "\n\nPlease ensure instance_type name and flavor id are unique." + print "To complete remove a instance_type, use the --purge flag:" + print "\n # nova-manage instance_type delete --purge\n" + print "Currently defined instance_type names and flavorids:" self.list("--all") sys.exit(2) except: -- cgit From 254834b864808b33ced23784048f14fa1bcf7489 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Thu, 7 Apr 2011 18:04:42 -0700 Subject: removed log command from nova-manage. no longer applicable with multiple logfiles. --- bin/nova-manage | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 6789efba8..a8eb49081 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -701,15 +701,6 @@ class ServiceCommands(object): {"method": "update_available_resource"}) -class LogCommands(object): - def request(self, request_id, logfile='/var/log/nova.log'): - """Show all fields in the log for the given request. Assumes you - haven't changed the log format too much. - ARGS: request_id [logfile]""" - lines = utils.execute("cat %s | grep '\[%s '" % (logfile, request_id)) - print re.sub('#012', "\n", "\n".join(lines)) - - class DbCommands(object): """Class for managing the database.""" @@ -1049,7 +1040,6 @@ CATEGORIES = [ ('network', NetworkCommands), ('vm', VmCommands), ('service', ServiceCommands), - ('log', LogCommands), ('db', DbCommands), ('volume', VolumeCommands), ('instance_type', InstanceTypeCommands), -- cgit From 479c95b8e855c5f07b75883a1f55b4657e886a92 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Thu, 7 Apr 2011 21:44:41 -0400 Subject: Ignore errors when deleting the default route in the ensure_bridge function. --- nova/network/linux_net.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index ed6c943c7..ec5579dee 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -503,7 +503,7 @@ def ensure_bridge(bridge, interface, net_attrs=None): if fields and fields[0] == "0.0.0.0" and fields[-1] == interface: gateway = fields[1] _execute('sudo', 'route', 'del', 'default', 'gw', gateway, - 'dev', interface) + 'dev', interface, check_exit_code=False) out, err = _execute('sudo', 'ip', 'addr', 'show', 'dev', interface, 'scope', 'global') for line in out.split("\n"): -- cgit From 7badb6c0278c8cc51fc3e870fd3810ea3706f494 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Thu, 7 Apr 2011 23:39:29 -0400 Subject: Update the describe_image_attribute and modify_image_attribute functions in the ec2 API so they use the top level 'is_public' attribute of image objects. This brings these functions in line with the base image service. Added missing EC2 unit tests on describing and modifying image attributes. --- nova/api/ec2/cloud.py | 4 ++-- nova/tests/test_cloud.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 4ed8a9ecf..651ec47f9 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -984,7 +984,7 @@ class CloudController(object): except exception.NotFound: raise exception.NotFound(_('Image %s not found') % image_id) result = {'imageId': image_id, 'launchPermission': []} - if image['properties']['is_public']: + if image['is_public']: result['launchPermission'].append({'group': 'all'}) return result @@ -1009,7 +1009,7 @@ class CloudController(object): internal_id = image['id'] del(image['id']) - image['properties']['is_public'] = (operation_type == 'add') + image['is_public'] = (operation_type == 'add') return self.image_service.update(context, internal_id, image) def update_image(self, context, image_id, **kwargs): diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 5cb969979..5f76a9005 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -247,6 +247,37 @@ class CloudTestCase(test.TestCase): self.assertRaises(NotFound, describe_images, self.context, ['ami-fake']) + def test_describe_image_attribute(self): + describe_image_attribute = self.cloud.describe_image_attribute + + def fake_show(meh, context, id): + return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1, + 'type': 'machine'}, 'is_public': True} + + self.stubs.Set(local.LocalImageService, 'show', fake_show) + self.stubs.Set(local.LocalImageService, 'show_by_name', fake_show) + result = describe_image_attribute(self.context, 'ami-00000001', + 'launchPermission') + self.assertEqual([{'group': 'all'}], result['launchPermission']) + + def test_modify_image_attribute(self): + modify_image_attribute = self.cloud.modify_image_attribute + + def fake_show(meh, context, id): + return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1, + 'type': 'machine'}, 'is_public': False} + + def fake_update(meh, context, image_id, metadata, data=None): + return metadata + + self.stubs.Set(local.LocalImageService, 'show', fake_show) + self.stubs.Set(local.LocalImageService, 'show_by_name', fake_show) + self.stubs.Set(local.LocalImageService, 'update', fake_update) + result = modify_image_attribute(self.context, 'ami-00000001', + 'launchPermission', 'add', + user_group=['all']) + self.assertEqual(True, result['is_public']) + def test_console_output(self): instance_type = FLAGS.default_instance_type max_count = 1 -- cgit From 2e7c4c744dd37358d79b03d52e8a59ab6eb9e197 Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Fri, 8 Apr 2011 10:42:01 +0200 Subject: Import from lp:~nova-core/nova/translations --- po/ast.po | 2614 +++++++++++++++++++++++++--------------- po/cs.po | 2659 +++++++++++++++++++++++++--------------- po/da.po | 2610 ++++++++++++++++++++++++--------------- po/de.po | 2706 ++++++++++++++++++++++++++--------------- po/es.po | 3866 +++++++++++++++++++++++++++++++++++++--------------------- po/it.po | 2789 ++++++++++++++++++++++++++---------------- po/ja.po | 3886 ++++++++++++++++++++++++++++++++++++++--------------------- po/pt_BR.po | 3147 ++++++++++++++++++++++++++++++----------------- po/ru.po | 2993 ++++++++++++++++++++++++++++----------------- po/uk.po | 2745 ++++++++++++++++++++++++++--------------- po/zh_CN.po | 2997 ++++++++++++++++++++++++++++----------------- 11 files changed, 21163 insertions(+), 11849 deletions(-) diff --git a/po/ast.po b/po/ast.po index 6e224f235..be9910a2c 100644 --- a/po/ast.po +++ b/po/ast.po @@ -7,2124 +7,2842 @@ msgid "" msgstr "" "Project-Id-Version: nova\n" "Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"POT-Creation-Date: 2011-02-21 10:03-0500\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-02-05 05:36+0000\n" -"X-Generator: Launchpad (build 12177)\n" +"X-Launchpad-Export-Date: 2011-03-19 06:18+0000\n" +"X-Generator: Launchpad (build 12559)\n" -#: nova/crypto.py:46 +#: ../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 "" + +#: ../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/api/openstack/servers.py:72 +msgid "Failed to read private ip" +msgstr "" + +#: ../nova/api/openstack/servers.py:79 +msgid "Failed to read public ip(s)" +msgstr "" + +#: ../nova/api/openstack/servers.py:152 +#, python-format +msgid "%(param)s property not found for image %(_image_id)s" +msgstr "" + +#: ../nova/api/openstack/servers.py:168 +msgid "No keypairs defined" +msgstr "" + +#: ../nova/api/openstack/servers.py:238 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:253 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:267 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:281 +#, python-format +msgid "Compute.api::reset_network %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:292 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:303 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:314 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:325 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: ../nova/twistd.py:157 +msgid "Wrong number of arguments." +msgstr "" + +#: ../nova/twistd.py:209 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "" + +#: ../nova/twistd.py:221 +msgid "No such process" +msgstr "" + +#: ../nova/twistd.py:230 ../nova/service.py:224 +#, python-format +msgid "Serving %s" +msgstr "" + +#: ../nova/twistd.py:262 ../nova/service.py:225 +msgid "Full set of FLAGS:" +msgstr "" + +#: ../nova/twistd.py:266 +#, python-format +msgid "Starting %s" +msgstr "" + +#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101 +#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741 +#: ../nova/api/ec2/__init__.py:317 +#, 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 "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: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/scheduler/manager.py:69 +#, python-format +msgid "Casting to %(topic)s %(host)s for %(method)s" +msgstr "" + +#: ../nova/compute/manager.py:78 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:80 +#, python-format +msgid "" +"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|" +msgstr "" + +#: ../nova/compute/manager.py:84 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:91 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:95 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: ../nova/compute/manager.py:179 +msgid "Instance has already been created" +msgstr "" + +#: ../nova/compute/manager.py:180 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#. pylint: disable=W0702 +#: ../nova/compute/manager.py:219 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: ../nova/compute/manager.py:255 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: ../nova/compute/manager.py:268 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: ../nova/compute/manager.py:282 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: ../nova/compute/manager.py:287 +#, python-format +msgid "" +"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:311 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: ../nova/compute/manager.py:316 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:332 +#, python-format +msgid "" +"trying to reset the password on a non-running instance: %(instance_id)s " +"(state: %(instance_state)s expected: %(expected_state)s)" +msgstr "" + +#: ../nova/compute/manager.py:335 +#, python-format +msgid "instance %s: setting admin password" +msgstr "" + +#: ../nova/compute/manager.py:353 +#, python-format +msgid "" +"trying to inject a file into a non-running instance: %(instance_id)s (state: " +"%(instance_state)s expected: %(expected_state)s)" +msgstr "" + +#: ../nova/compute/manager.py:362 +#, python-format +msgid "instance %(nm)s: injecting file to %(plain_path)s" +msgstr "" + +#: ../nova/compute/manager.py:372 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: ../nova/compute/manager.py:387 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: ../nova/compute/manager.py:406 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: ../nova/compute/manager.py:423 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: ../nova/compute/manager.py:440 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: ../nova/compute/manager.py:453 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: ../nova/compute/manager.py:472 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: ../nova/compute/manager.py:491 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: ../nova/compute/manager.py:503 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: ../nova/compute/manager.py:513 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: ../nova/compute/manager.py:526 +#, python-format +msgid "instance %s: reset network" +msgstr "" + +#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: ../nova/compute/manager.py:543 +#, python-format +msgid "instance %s: getting ajax console" +msgstr "" + +#: ../nova/compute/manager.py:553 +#, python-format +msgid "" +"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s" +msgstr "" + +#. pylint: disable=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:569 +#, python-format +msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing" +msgstr "" + +#: ../nova/compute/manager.py:585 +#, python-format +msgid "" +"Detach volume %(volume_id)s from mountpoint %(mp)s on instance " +"%(instance_id)s" +msgstr "" + +#: ../nova/compute/manager.py:588 +#, 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:304 ../nova/virt/xenapi/fake.py:404 +#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478 +msgid "Raising NotImplemented" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:306 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:341 +#, python-format +msgid "Calling %(localname)s %(impl)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:346 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:406 +#, 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:187 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: ../nova/network/linux_net.py:208 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:314 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" -#: 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/network/linux_net.py:316 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" -#: nova/crypto.py:53 -msgid "Where we keep our keys" +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:358 +#, python-format +msgid "killing radvd threw %s" msgstr "" -#: nova/crypto.py:55 -msgid "Where we keep our root CA" +#: ../nova/network/linux_net.py:360 +#, python-format +msgid "Pid %d is stale, relaunching radvd" msgstr "" -#: nova/crypto.py:57 -msgid "Should we use a CA for each project?" +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:449 +#, python-format +msgid "Killing dnsmasq threw %s" msgstr "" -#: nova/crypto.py:61 +#: ../nova/utils.py:58 #, python-format -msgid "Subject for certificate for users, %s for project, user, timestamp" +msgid "Inner Exception: %s" msgstr "" -#: nova/crypto.py:66 +#: ../nova/utils.py:59 #, python-format -msgid "Subject for certificate for projects, %s for project, timestamp" +msgid "Class %s cannot be found" msgstr "" -#: nova/crypto.py:71 +#: ../nova/utils.py:118 #, python-format -msgid "Subject for certificate for vpns, %s for project, timestamp" +msgid "Fetching %s" msgstr "" -#: nova/crypto.py:258 +#: ../nova/utils.py:130 #, python-format -msgid "Flags path: %s" +msgid "Running cmd (subprocess): %s" msgstr "" -#: nova/exception.py:33 -msgid "Unexpected error while running command." +#: ../nova/utils.py:143 ../nova/utils.py:183 +#, python-format +msgid "Result was %s" msgstr "" -#: nova/exception.py:36 +#: ../nova/utils.py:159 #, python-format -msgid "" -"%s\n" -"Command: %s\n" -"Exit code: %s\n" -"Stdout: %r\n" -"Stderr: %r" +msgid "Running cmd (SSH): %s" msgstr "" -#: nova/exception.py:86 -msgid "Uncaught exception" +#: ../nova/utils.py:217 +#, python-format +msgid "debug in callback: %s" +msgstr "" + +#: ../nova/utils.py:222 +#, python-format +msgid "Running %s" +msgstr "" + +#: ../nova/utils.py:262 +#, python-format +msgid "Link Local address is not found.:%s" +msgstr "" + +#: ../nova/utils.py:265 +#, python-format +msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s" +msgstr "" + +#: ../nova/utils.py:363 +#, python-format +msgid "Invalid backend: %s" +msgstr "" + +#: ../nova/utils.py:374 +#, python-format +msgid "backend %s" msgstr "" -#: nova/fakerabbit.py:48 +#: ../nova/fakerabbit.py:49 #, python-format -msgid "(%s) publish (key: %s) %s" +msgid "(%(nm)s) publish (key: %(routing_key)s) %(message)s" msgstr "" -#: nova/fakerabbit.py:53 +#: ../nova/fakerabbit.py:54 #, python-format msgid "Publishing to route %s" msgstr "" -#: nova/fakerabbit.py:83 +#: ../nova/fakerabbit.py:84 #, python-format msgid "Declaring queue %s" msgstr "" -#: nova/fakerabbit.py:89 +#: ../nova/fakerabbit.py:90 #, python-format msgid "Declaring exchange %s" msgstr "" -#: nova/fakerabbit.py:95 +#: ../nova/fakerabbit.py:96 #, python-format -msgid "Binding %s to %s with key %s" +msgid "Binding %(queue)s to %(exchange)s with key %(routing_key)s" msgstr "" -#: nova/fakerabbit.py:120 +#: ../nova/fakerabbit.py:121 #, python-format -msgid "Getting from %s: %s" +msgid "Getting from %(queue)s: %(message)s" msgstr "" -#: nova/rpc.py:92 +#: ../nova/virt/xenapi/vm_utils.py:135 ../nova/virt/hyperv.py:171 #, python-format -msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgid "Created VM %s..." msgstr "" -#: nova/rpc.py:99 +#: ../nova/virt/xenapi/vm_utils.py:138 #, python-format -msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgid "Created VM %(instance_name)s as %(vm_ref)s." msgstr "" -#: nova/rpc.py:118 -msgid "Reconnected to queue" +#: ../nova/virt/xenapi/vm_utils.py:168 +#, python-format +msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... " msgstr "" -#: nova/rpc.py:125 -msgid "Failed to fetch message from queue" +#: ../nova/virt/xenapi/vm_utils.py:171 +#, python-format +msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s." msgstr "" -#: nova/rpc.py:155 +#: ../nova/virt/xenapi/vm_utils.py:187 #, python-format -msgid "Initing the Adapter Consumer for %s" +msgid "VBD not found in instance %s" msgstr "" -#: nova/rpc.py:170 +#: ../nova/virt/xenapi/vm_utils.py:197 #, python-format -msgid "received %s" +msgid "Unable to unplug VBD %s" msgstr "" -#: nova/rpc.py:183 +#: ../nova/virt/xenapi/vm_utils.py:209 #, python-format -msgid "no method for message: %s" +msgid "Unable to destroy VBD %s" msgstr "" -#: nova/rpc.py:184 +#: ../nova/virt/xenapi/vm_utils.py:224 #, python-format -msgid "No method for message: %s" +msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s." msgstr "" -#: nova/rpc.py:245 +#: ../nova/virt/xenapi/vm_utils.py:227 #, python-format -msgid "Returning exception %s to caller" +msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s." msgstr "" -#: nova/rpc.py:286 +#: ../nova/virt/xenapi/vm_utils.py:246 #, python-format -msgid "unpacked context: %s" +msgid "" +"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on " +"%(sr_ref)s." msgstr "" -#: nova/rpc.py:305 -msgid "Making asynchronous call..." +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vm_utils.py:258 +#, python-format +msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..." msgstr "" -#: nova/rpc.py:308 +#: ../nova/virt/xenapi/vm_utils.py:272 #, python-format -msgid "MSG_ID is %s" +msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s." msgstr "" -#: nova/rpc.py:356 +#: ../nova/virt/xenapi/vm_utils.py:286 #, python-format -msgid "response %s" +msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s" msgstr "" -#: nova/rpc.py:365 +#: ../nova/virt/xenapi/vm_utils.py:327 #, python-format -msgid "topic is %s" +msgid "Size for image %(image)s:%(virtual_size)d" msgstr "" -#: nova/rpc.py:366 +#: ../nova/virt/xenapi/vm_utils.py:332 #, python-format -msgid "message %s" +msgid "Glance image %s" msgstr "" -#: nova/service.py:157 +#. we need to invoke a plugin for copying VDI's +#. content into proper path +#: ../nova/virt/xenapi/vm_utils.py:342 #, python-format -msgid "Starting %s node" +msgid "Copying VDI %s to /boot/guest on dom0" msgstr "" -#: nova/service.py:169 -msgid "Service killed that has no database entry" +#: ../nova/virt/xenapi/vm_utils.py:352 +#, python-format +msgid "Kernel/Ramdisk VDI %s destroyed" msgstr "" -#: nova/service.py:190 -msgid "The service database object disappeared, Recreating it." +#: ../nova/virt/xenapi/vm_utils.py:361 +#, python-format +msgid "Asking xapi to fetch %(url)s as %(access)s" msgstr "" -#: nova/service.py:202 -msgid "Recovered model server connection!" +#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402 +#, python-format +msgid "Looking up vdi %s for PV kernel" msgstr "" -#: nova/service.py:208 -msgid "model server went away" +#: ../nova/virt/xenapi/vm_utils.py:397 +#, python-format +msgid "PV Kernel in VDI:%s" msgstr "" -#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#: ../nova/virt/xenapi/vm_utils.py:405 #, python-format -msgid "Data store %s is unreachable. Trying again in %d seconds." +msgid "Running pygrub against %s" msgstr "" -#: nova/service.py:232 nova/twistd.py:232 +#: ../nova/virt/xenapi/vm_utils.py:411 #, python-format -msgid "Serving %s" +msgid "Found Xen kernel %s" msgstr "" -#: nova/service.py:234 nova/twistd.py:264 -msgid "Full set of FLAGS:" +#: ../nova/virt/xenapi/vm_utils.py:413 +msgid "No Xen kernel found. Booting HVM." msgstr "" -#: nova/twistd.py:211 +#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431 #, python-format -msgid "pidfile %s does not exist. Daemon not running?\n" +msgid "duplicate name found: %s" msgstr "" -#: nova/twistd.py:268 +#: ../nova/virt/xenapi/vm_utils.py:442 #, python-format -msgid "Starting %s" +msgid "VDI %s is still available" msgstr "" -#: nova/utils.py:53 +#: ../nova/virt/xenapi/vm_utils.py:463 #, python-format -msgid "Inner Exception: %s" +msgid "(VM_UTILS) xenserver vm state -> |%s|" msgstr "" -#: nova/utils.py:54 +#: ../nova/virt/xenapi/vm_utils.py:465 #, python-format -msgid "Class %s cannot be found" +msgid "(VM_UTILS) xenapi power_state -> |%s|" msgstr "" -#: nova/utils.py:113 +#: ../nova/virt/xenapi/vm_utils.py:525 #, python-format -msgid "Fetching %s" +msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s" msgstr "" -#: nova/utils.py:125 +#: ../nova/virt/xenapi/vm_utils.py:542 #, python-format -msgid "Running cmd (subprocess): %s" +msgid "Re-scanning SR %s" msgstr "" -#: nova/utils.py:138 +#: ../nova/virt/xenapi/vm_utils.py:567 #, python-format -msgid "Result was %s" +msgid "" +"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..." msgstr "" -#: nova/utils.py:171 +#: ../nova/virt/xenapi/vm_utils.py:574 #, python-format -msgid "debug in callback: %s" +msgid "" +"Parent %(parent_uuid)s doesn't match original parent " +"%(original_parent_uuid)s, waiting for coalesce..." msgstr "" -#: nova/utils.py:176 +#: ../nova/virt/xenapi/vm_utils.py:590 #, python-format -msgid "Running %s" +msgid "No VDIs found for VM %s" msgstr "" -#: nova/utils.py:207 +#: ../nova/virt/xenapi/vm_utils.py:594 #, python-format -msgid "Couldn't get IP, using 127.0.0.1 %s" +msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s" msgstr "" -#: nova/utils.py:289 +#: ../nova/virt/xenapi/vm_utils.py:653 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188 #, python-format -msgid "Invalid backend: %s" +msgid "Creating VBD for VDI %s ... " msgstr "" -#: nova/utils.py:300 +#: ../nova/virt/xenapi/vm_utils.py:655 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190 #, python-format -msgid "backend %s" +msgid "Creating VBD for VDI %s done." msgstr "" -#: nova/api/ec2/__init__.py:133 -msgid "Too many failed authentications." +#: ../nova/virt/xenapi/vm_utils.py:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192 +#, python-format +msgid "Plugging VBD %s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:659 +#: ../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:661 +#, python-format +msgid "VBD %(vbd)s plugged as %(orig_dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:664 +#, python-format +msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:668 +#: ../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:671 +#: ../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:683 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211 +msgid "VBD.unplug successful first time." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:688 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216 +msgid "VBD.unplug rejected: retrying..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:692 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220 +msgid "VBD.unplug successful eventually." msgstr "" -#: nova/api/ec2/__init__.py:142 +#: ../nova/virt/xenapi/vm_utils.py:695 +#: ../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:704 +#: ../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:735 #, python-format msgid "" -"Access key %s has had %d failed authentications and will be locked out for " -"%d minutes." +"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..." msgstr "" -#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#: ../nova/virt/xenapi/vm_utils.py:747 #, python-format -msgid "Authentication Failure: %s" +msgid "Writing partition table %s done." msgstr "" -#: nova/api/ec2/__init__.py:190 +#: ../nova/tests/test_rpc.py:89 #, python-format -msgid "Authenticated Request For %s:%s)" +msgid "Nested received %(queue)s, %(value)s" msgstr "" -#: nova/api/ec2/__init__.py:227 +#: ../nova/tests/test_rpc.py:95 #, python-format -msgid "action: %s" +msgid "Nested return %s" msgstr "" -#: nova/api/ec2/__init__.py:229 +#: ../nova/tests/test_rpc.py:120 ../nova/tests/test_rpc.py:126 #, python-format -msgid "arg: %s\t\tval: %s" +msgid "Received %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:44 +msgid "Use of empty request context is deprecated" msgstr "" -#: nova/api/ec2/__init__.py:301 +#: ../nova/db/sqlalchemy/api.py:133 #, python-format -msgid "Unauthorized request for controller=%s and action=%s" +msgid "No service for id %s" msgstr "" -#: nova/api/ec2/__init__.py:339 +#: ../nova/db/sqlalchemy/api.py:251 #, python-format -msgid "NotFound raised: %s" +msgid "No service for %(host)s, %(binary)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:592 +msgid "No fixed ips defined" msgstr "" -#: nova/api/ec2/__init__.py:342 +#: ../nova/db/sqlalchemy/api.py:608 #, python-format -msgid "ApiError raised: %s" +msgid "No floating ip for address %s" msgstr "" -#: nova/api/ec2/__init__.py:349 +#: ../nova/db/sqlalchemy/api.py:629 #, python-format -msgid "Unexpected error raised: %s" +msgid "No address for instance %s" msgstr "" -#: nova/api/ec2/__init__.py:354 -msgid "An unknown error has occurred. Please try your request again." +#: ../nova/db/sqlalchemy/api.py:961 +#, python-format +msgid "no keypair for user %(user_id)s, name %(name)s" msgstr "" -#: nova/api/ec2/admin.py:84 +#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156 #, python-format -msgid "Creating new user: %s" +msgid "No network for id %s" msgstr "" -#: nova/api/ec2/admin.py:92 +#: ../nova/db/sqlalchemy/api.py:1086 +msgid "No networks defined" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1115 #, python-format -msgid "Deleting user: %s" +msgid "No network for bridge %s" msgstr "" -#: nova/api/ec2/admin.py:114 +#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142 #, python-format -msgid "Adding role %s to user %s for project %s" +msgid "No network for instance %s" msgstr "" -#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#: ../nova/db/sqlalchemy/api.py:1277 #, python-format -msgid "Adding sitewide role %s to user %s" +msgid "Token %s does not exist" msgstr "" -#: nova/api/ec2/admin.py:122 +#: ../nova/db/sqlalchemy/api.py:1302 #, python-format -msgid "Removing role %s from user %s for project %s" +msgid "No quota for project_id %s" msgstr "" -#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501 +#: ../nova/api/ec2/__init__.py:323 #, python-format -msgid "Removing sitewide role %s from user %s" +msgid "Volume %s not found" msgstr "" -#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 -msgid "operation must be add or remove" +#: ../nova/db/sqlalchemy/api.py:1514 +#, python-format +msgid "No export device found for volume %s" msgstr "" -#: nova/api/ec2/admin.py:142 +#: ../nova/db/sqlalchemy/api.py:1527 #, python-format -msgid "Getting x509 for user: %s on project: %s" +msgid "No target id found for volume %s" msgstr "" -#: nova/api/ec2/admin.py:159 +#: ../nova/db/sqlalchemy/api.py:1572 #, python-format -msgid "Create project %s managed by %s" +msgid "No security group with id %s" msgstr "" -#: nova/api/ec2/admin.py:170 +#: ../nova/db/sqlalchemy/api.py:1589 #, python-format -msgid "Delete project: %s" +msgid "No security group named %(group_name)s for project: %(project_id)s" msgstr "" -#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#: ../nova/db/sqlalchemy/api.py:1682 #, python-format -msgid "Adding user %s to project %s" +msgid "No secuity group rule with id %s" msgstr "" -#: nova/api/ec2/admin.py:188 +#: ../nova/db/sqlalchemy/api.py:1756 #, python-format -msgid "Removing user %s from project %s" +msgid "No user for id %s" msgstr "" -#: nova/api/ec2/apirequest.py:95 +#: ../nova/db/sqlalchemy/api.py:1772 #, python-format -msgid "Unsupported API request: controller = %s,action = %s" +msgid "No user for access key %s" msgstr "" -#: nova/api/ec2/cloud.py:117 +#: ../nova/db/sqlalchemy/api.py:1834 #, python-format -msgid "Generating root CA: %s" +msgid "No project with id %s" msgstr "" -#: nova/api/ec2/cloud.py:277 +#: ../nova/db/sqlalchemy/api.py:1979 #, python-format -msgid "Create key pair %s" +msgid "No console pool with id %(pool_id)s" msgstr "" -#: nova/api/ec2/cloud.py:285 +#: ../nova/db/sqlalchemy/api.py:1996 #, python-format -msgid "Delete key pair %s" +msgid "" +"No console pool of type %(console_type)s for compute host %(compute_host)s " +"on proxy host %(host)s" msgstr "" -#: nova/api/ec2/cloud.py:357 +#: ../nova/db/sqlalchemy/api.py:2035 #, python-format -msgid "%s is not a valid ipProtocol" +msgid "No console for instance %(instance_id)s in pool %(pool_id)s" msgstr "" -#: nova/api/ec2/cloud.py:361 -msgid "Invalid port range" +#: ../nova/db/sqlalchemy/api.py:2057 +#, python-format +msgid "on instance %s" msgstr "" -#: nova/api/ec2/cloud.py:392 +#: ../nova/db/sqlalchemy/api.py:2058 #, python-format -msgid "Revoke security group ingress %s" +msgid "No console with id %(console_id)s %(idesc)s" msgstr "" -#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 -msgid "No rule for the specified parameters." +#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097 +#, python-format +msgid "No zone with id %(zone_id)s" msgstr "" -#: nova/api/ec2/cloud.py:421 +#: ../nova/virt/libvirt_conn.py:160 #, python-format -msgid "Authorize security group ingress %s" +msgid "Checking state of %s" msgstr "" -#: nova/api/ec2/cloud.py:432 +#: ../nova/virt/libvirt_conn.py:165 #, python-format -msgid "This rule already exists in group %s" +msgid "Current state of %(name)s was %(state)s." msgstr "" -#: nova/api/ec2/cloud.py:460 +#: ../nova/virt/libvirt_conn.py:183 #, python-format -msgid "Create Security Group %s" +msgid "Connecting to libvirt: %s" msgstr "" -#: nova/api/ec2/cloud.py:463 +#: ../nova/virt/libvirt_conn.py:196 +msgid "Connection to libvirt broke" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:258 #, python-format -msgid "group %s already exists" +msgid "instance %(instance_name)s: deleting instance files %(target)s" msgstr "" -#: nova/api/ec2/cloud.py:475 +#: ../nova/virt/libvirt_conn.py:283 #, python-format -msgid "Delete security group %s" +msgid "Invalid device path %s" msgstr "" -#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#: ../nova/virt/libvirt_conn.py:313 #, python-format -msgid "Get console output for instance %s" +msgid "No disk at %s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:320 +msgid "Instance snapshotting is not supported for libvirtat this time" msgstr "" -#: nova/api/ec2/cloud.py:543 +#: ../nova/virt/libvirt_conn.py:336 #, python-format -msgid "Create volume of %s GB" +msgid "instance %s: rebooted" msgstr "" -#: nova/api/ec2/cloud.py:567 +#: ../nova/virt/libvirt_conn.py:339 #, python-format -msgid "Attach volume %s to instacne %s at %s" +msgid "_wait_for_reboot failed: %s" msgstr "" -#: nova/api/ec2/cloud.py:579 +#: ../nova/virt/libvirt_conn.py:382 #, python-format -msgid "Detach volume %s" +msgid "instance %s: rescued" msgstr "" -#: nova/api/ec2/cloud.py:686 -msgid "Allocate address" +#: ../nova/virt/libvirt_conn.py:385 +#, python-format +msgid "_wait_for_rescue failed: %s" msgstr "" -#: nova/api/ec2/cloud.py:691 +#: ../nova/virt/libvirt_conn.py:411 #, python-format -msgid "Release address %s" +msgid "instance %s: is running" msgstr "" -#: nova/api/ec2/cloud.py:696 +#: ../nova/virt/libvirt_conn.py:422 #, python-format -msgid "Associate address %s to instance %s" +msgid "instance %s: booted" msgstr "" -#: nova/api/ec2/cloud.py:703 +#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186 #, python-format -msgid "Disassociate address %s" +msgid "instance %s: failed to boot" msgstr "" -#: nova/api/ec2/cloud.py:730 -msgid "Going to start terminating instances" +#: ../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/api/ec2/cloud.py:738 +#: ../nova/virt/libvirt_conn.py:448 #, python-format -msgid "Reboot instance %r" +msgid "data: %(data)r, fpath: %(fpath)r" msgstr "" -#: nova/api/ec2/cloud.py:775 +#: ../nova/virt/libvirt_conn.py:456 #, python-format -msgid "De-registering image %s" +msgid "Contents of file %(fpath)s: %(contents)r" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:489 +msgid "Unable to find an open port" msgstr "" -#: nova/api/ec2/cloud.py:783 +#: ../nova/virt/libvirt_conn.py:563 #, python-format -msgid "Registered image %s with id %s" +msgid "instance %s: Creating image" msgstr "" -#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#: ../nova/virt/libvirt_conn.py:646 #, python-format -msgid "attribute not supported: %s" +msgid "instance %(inst_name)s: injecting key into image %(img_id)s" msgstr "" -#: nova/api/ec2/cloud.py:794 +#: ../nova/virt/libvirt_conn.py:649 #, python-format -msgid "invalid id: %s" +msgid "instance %(inst_name)s: injecting net into image %(img_id)s" msgstr "" -#: nova/api/ec2/cloud.py:807 -msgid "user or group not specified" +#. 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 "" -#: nova/api/ec2/cloud.py:809 -msgid "only group \"all\" is supported" +#. TODO(termie): cache? +#: ../nova/virt/libvirt_conn.py:665 +#, python-format +msgid "instance %s: starting toXML method" msgstr "" -#: nova/api/ec2/cloud.py:811 -msgid "operation_type must be add or remove" +#: ../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/api/ec2/cloud.py:812 +#: ../nova/virt/libvirt_conn.py:1225 #, python-format -msgid "Updating image %s publicity" +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/api/ec2/metadatarequesthandler.py:75 -#, python-format -msgid "Failed to get metadata for ip: %s" +#: ../nova/console/manager.py:70 +msgid "Adding console" msgstr "" -#: nova/api/openstack/__init__.py:70 +#: ../nova/console/manager.py:90 #, python-format -msgid "Caught error: %s" +msgid "Tried to remove non-existant console %(console_id)s." msgstr "" -#: nova/api/openstack/__init__.py:86 -msgid "Including admin operations in API." +#: ../nova/api/direct.py:149 +msgid "not available" msgstr "" -#: nova/api/openstack/servers.py:184 +#: ../nova/api/ec2/cloud.py:62 #, python-format -msgid "Compute.api::lock %s" +msgid "The key_pair %s already exists" msgstr "" -#: nova/api/openstack/servers.py:199 +#. TODO(vish): Do this with M2Crypto instead +#: ../nova/api/ec2/cloud.py:118 #, python-format -msgid "Compute.api::unlock %s" +msgid "Generating root CA: %s" msgstr "" -#: nova/api/openstack/servers.py:213 +#: ../nova/api/ec2/cloud.py:303 #, python-format -msgid "Compute.api::get_lock %s" +msgid "Create key pair %s" msgstr "" -#: nova/api/openstack/servers.py:224 +#: ../nova/api/ec2/cloud.py:311 #, python-format -msgid "Compute.api::pause %s" +msgid "Delete key pair %s" msgstr "" -#: nova/api/openstack/servers.py:235 +#: ../nova/api/ec2/cloud.py:386 #, python-format -msgid "Compute.api::unpause %s" +msgid "%s is not a valid ipProtocol" msgstr "" -#: nova/api/openstack/servers.py:246 -#, python-format -msgid "compute.api::suspend %s" +#: ../nova/api/ec2/cloud.py:390 +msgid "Invalid port range" msgstr "" -#: nova/api/openstack/servers.py:257 +#: ../nova/api/ec2/cloud.py:421 #, python-format -msgid "compute.api::resume %s" +msgid "Revoke security group ingress %s" msgstr "" -#: nova/auth/dbdriver.py:84 -#, python-format -msgid "User %s already exists" +#: ../nova/api/ec2/cloud.py:430 ../nova/api/ec2/cloud.py:459 +msgid "Not enough parameters to build a valid rule." 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" +#: ../nova/api/ec2/cloud.py:443 +msgid "No rule for the specified parameters." msgstr "" -#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#: ../nova/api/ec2/cloud.py:450 #, python-format -msgid "Project can't be created because project %s already exists" +msgid "Authorize security group ingress %s" msgstr "" -#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#: ../nova/api/ec2/cloud.py:464 #, python-format -msgid "Project can't be modified because manager %s doesn't exist" +msgid "This rule already exists in group %s" msgstr "" -#: nova/auth/dbdriver.py:245 +#: ../nova/api/ec2/cloud.py:492 #, python-format -msgid "User \"%s\" not found" +msgid "Create Security Group %s" msgstr "" -#: nova/auth/dbdriver.py:248 +#: ../nova/api/ec2/cloud.py:495 #, python-format -msgid "Project \"%s\" not found" -msgstr "" - -#: nova/auth/fakeldap.py:33 -msgid "Attempted to instantiate singleton" +msgid "group %s already exists" msgstr "" -#: nova/auth/ldapdriver.py:181 +#: ../nova/api/ec2/cloud.py:507 #, python-format -msgid "LDAP object for %s doesn't exist" +msgid "Delete security group %s" msgstr "" -#: nova/auth/ldapdriver.py:218 +#: ../nova/api/ec2/cloud.py:584 #, python-format -msgid "Project can't be created because user %s doesn't exist" +msgid "Create volume of %s GB" msgstr "" -#: nova/auth/ldapdriver.py:478 +#: ../nova/api/ec2/cloud.py:612 #, python-format -msgid "User %s is already a member of the group %s" +msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s" msgstr "" -#: nova/auth/ldapdriver.py:507 +#: ../nova/api/ec2/cloud.py:629 #, python-format -msgid "" -"Attempted to remove the last member of a group. Deleting the group at %s " -"instead." +msgid "Detach volume %s" msgstr "" -#: nova/auth/ldapdriver.py:528 -#, python-format -msgid "Group at dn %s doesn't exist" +#: ../nova/api/ec2/cloud.py:761 +msgid "Allocate address" msgstr "" -#: nova/auth/manager.py:259 +#: ../nova/api/ec2/cloud.py:766 #, python-format -msgid "Looking up user: %r" +msgid "Release address %s" msgstr "" -#: nova/auth/manager.py:263 +#: ../nova/api/ec2/cloud.py:771 #, python-format -msgid "Failed authorization for access key %s" +msgid "Associate address %(public_ip)s to instance %(instance_id)s" msgstr "" -#: nova/auth/manager.py:264 +#: ../nova/api/ec2/cloud.py:780 #, python-format -msgid "No user found for access key %s" +msgid "Disassociate address %s" msgstr "" -#: nova/auth/manager.py:270 -#, python-format -msgid "Using project name = user name (%s)" +#: ../nova/api/ec2/cloud.py:807 +msgid "Going to start terminating instances" msgstr "" -#: nova/auth/manager.py:275 +#: ../nova/api/ec2/cloud.py:815 #, python-format -msgid "failed authorization: no project named %s (user=%s)" +msgid "Reboot instance %r" msgstr "" -#: nova/auth/manager.py:277 +#: ../nova/api/ec2/cloud.py:867 #, python-format -msgid "No project called %s could be found" +msgid "De-registering image %s" msgstr "" -#: nova/auth/manager.py:281 +#: ../nova/api/ec2/cloud.py:875 #, python-format -msgid "Failed authorization: user %s not admin and not member of project %s" +msgid "Registered image %(image_location)s with id %(image_id)s" msgstr "" -#: nova/auth/manager.py:283 +#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900 #, python-format -msgid "User %s is not a member of project %s" +msgid "attribute not supported: %s" msgstr "" -#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#: ../nova/api/ec2/cloud.py:890 #, python-format -msgid "Invalid signature for user %s" +msgid "invalid id: %s" msgstr "" -#: nova/auth/manager.py:293 nova/auth/manager.py:304 -msgid "Signature does not match" +#: ../nova/api/ec2/cloud.py:903 +msgid "user or group not specified" msgstr "" -#: nova/auth/manager.py:374 -msgid "Must specify project" +#: ../nova/api/ec2/cloud.py:905 +msgid "only group \"all\" is supported" msgstr "" -#: nova/auth/manager.py:408 -#, python-format -msgid "The %s role can not be found" +#: ../nova/api/ec2/cloud.py:907 +msgid "operation_type must be add or remove" msgstr "" -#: nova/auth/manager.py:410 +#: ../nova/api/ec2/cloud.py:908 #, python-format -msgid "The %s role is global only" +msgid "Updating image %s publicity" msgstr "" -#: nova/auth/manager.py:412 +#: ../bin/nova-api.py:52 #, python-format -msgid "Adding role %s to user %s in project %s" +msgid "Using paste.deploy config at: %s" msgstr "" -#: nova/auth/manager.py:438 +#: ../bin/nova-api.py:57 #, python-format -msgid "Removing role %s from user %s on project %s" +msgid "No paste configuration for app: %s" msgstr "" -#: nova/auth/manager.py:505 +#: ../bin/nova-api.py:59 #, python-format -msgid "Created project %s with manager %s" +msgid "" +"App Config: %(api)s\n" +"%(config)r" msgstr "" -#: nova/auth/manager.py:523 +#: ../bin/nova-api.py:64 #, python-format -msgid "modifying project %s" +msgid "Running %s API" msgstr "" -#: nova/auth/manager.py:553 +#: ../bin/nova-api.py:69 #, python-format -msgid "Remove user %s from project %s" +msgid "No known API applications configured in %s." msgstr "" -#: nova/auth/manager.py:581 +#: ../bin/nova-api.py:83 #, python-format -msgid "Deleting project %s" +msgid "Starting nova-api node (version %s)" msgstr "" -#: nova/auth/manager.py:637 +#: ../bin/nova-api.py:89 #, python-format -msgid "Created user %s (admin: %r)" +msgid "No paste configuration found for: %s" msgstr "" -#: nova/auth/manager.py:645 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84 #, python-format -msgid "Deleting user %s" +msgid "Argument %(key)s value %(value)s is too short." msgstr "" -#: nova/auth/manager.py:655 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89 #, python-format -msgid "Access Key change for user %s" +msgid "Argument %(key)s value %(value)s contains invalid characters." msgstr "" -#: nova/auth/manager.py:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94 #, python-format -msgid "Secret Key change for user %s" +msgid "Argument %(key)s value %(value)s starts with a hyphen." msgstr "" -#: nova/auth/manager.py:659 +#: ../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 "Admin status set to %r for user %s" +msgid "Argument %s is required." msgstr "" -#: nova/auth/manager.py:708 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117 #, 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" +msgid "" +"Argument %(key)s may not take value %(value)s. Valid values are ['true', " +"'false']." msgstr "" -#: nova/cloudpipe/pipelib.py:51 -msgid "Netmask to push into openvpn config" +#: ../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/cloudpipe/pipelib.py:97 +#: ../nova/virt/xenapi/vmops.py:67 #, python-format -msgid "Launching VPN for %s" +msgid "Attempted to create non-unique name %s" msgstr "" -#: nova/compute/api.py:67 +#: ../nova/virt/xenapi/vmops.py:73 #, python-format -msgid "Instance %d was not found in get_network_topic" +msgid "instance %(name)s: not enough free memory" msgstr "" -#: nova/compute/api.py:73 +#: ../nova/virt/xenapi/vmops.py:148 #, python-format -msgid "Instance %d has no host" +msgid "Starting VM %s..." msgstr "" -#: nova/compute/api.py:92 +#: ../nova/virt/xenapi/vmops.py:151 #, python-format -msgid "Quota exceeeded for %s, tried to run %s instances" +msgid "Spawning VM %(instance_name)s created %(vm_ref)s." msgstr "" -#: nova/compute/api.py:94 +#: ../nova/virt/xenapi/vmops.py:162 #, python-format -msgid "" -"Instance quota exceeded. You can only run %s more instances of this type." +msgid "Invalid value for onset_files: '%s'" msgstr "" -#: nova/compute/api.py:109 -msgid "Creating a raw instance" +#: ../nova/virt/xenapi/vmops.py:167 +#, python-format +msgid "Injecting file path: '%s'" msgstr "" -#: nova/compute/api.py:156 +#: ../nova/virt/xenapi/vmops.py:180 #, python-format -msgid "Going to run %s instances..." +msgid "Instance %s: booted" msgstr "" -#: nova/compute/api.py:180 +#: ../nova/virt/xenapi/vmops.py:232 #, python-format -msgid "Casting to scheduler for %s/%s's instance %s" +msgid "Instance not present %s" msgstr "" -#: nova/compute/api.py:279 +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vmops.py:261 #, python-format -msgid "Going to try and terminate %s" +msgid "Starting snapshot for VM %s" msgstr "" -#: nova/compute/api.py:283 +#: ../nova/virt/xenapi/vmops.py:269 #, python-format -msgid "Instance %d was not found during terminate" +msgid "Unable to Snapshot %(vm_ref)s: %(exc)s" msgstr "" -#: nova/compute/api.py:288 +#: ../nova/virt/xenapi/vmops.py:280 #, python-format -msgid "Instance %d is already being terminated" +msgid "Finished snapshot and upload for VM %s" msgstr "" -#: nova/compute/api.py:450 +#: ../nova/virt/xenapi/vmops.py:356 #, python-format -msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgid "VM %(vm)s already halted, skipping shutdown..." msgstr "" -#: nova/compute/api.py:465 -msgid "Volume isn't attached to anything!" +#: ../nova/virt/xenapi/vmops.py:389 +msgid "Removing kernel/ramdisk files" msgstr "" -#: nova/compute/disk.py:71 -#, python-format -msgid "Input partition size not evenly divisible by sector size: %d / %d" +#: ../nova/virt/xenapi/vmops.py:399 +msgid "kernel/ramdisk files removed" msgstr "" -#: nova/compute/disk.py:75 +#: ../nova/virt/xenapi/vmops.py:561 #, python-format -msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgid "" +"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/disk.py:128 +#: ../nova/virt/xenapi/vmops.py:564 #, python-format -msgid "Could not attach image to loopback: %s" +msgid "" +"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM " +"id=%(instance_id)s; args=%(strargs)s" msgstr "" -#: nova/compute/disk.py:136 +#: ../nova/virt/xenapi/vmops.py:569 #, python-format -msgid "Failed to load partition: %s" +msgid "" +"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/disk.py:158 +#: ../nova/virt/xenapi/vmops.py:760 #, python-format -msgid "Failed to mount filesystem: %s" +msgid "OpenSSL error: %s" msgstr "" -#: nova/compute/instance_types.py:41 +#: ../nova/tests/test_compute.py:148 #, python-format -msgid "Unknown instance type: %s" +msgid "Running instances: %s" msgstr "" -#: nova/compute/manager.py:69 +#: ../nova/tests/test_compute.py:154 #, python-format -msgid "check_instance_lock: decorating: |%s|" +msgid "After terminating instances: %s" msgstr "" -#: nova/compute/manager.py:71 -#, python-format -msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +#: ../nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" msgstr "" -#: nova/compute/manager.py:75 -#, python-format -msgid "check_instance_lock: locked: |%s|" +#: ../nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" msgstr "" -#: nova/compute/manager.py:77 -#, python-format -msgid "check_instance_lock: admin: |%s|" +#: ../nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" msgstr "" -#: nova/compute/manager.py:82 +#: ../nova/cloudpipe/pipelib.py:97 #, python-format -msgid "check_instance_lock: executing: |%s|" +msgid "Launching VPN for %s" msgstr "" -#: nova/compute/manager.py:86 -#, python-format -msgid "check_instance_lock: not executing |%s|" +#: ../nova/db/sqlalchemy/migration.py:35 +msgid "python-migrate is not installed. Exiting." msgstr "" -#: nova/compute/manager.py:157 -msgid "Instance has already been created" +#: ../nova/image/s3.py:99 +#, python-format +msgid "Image %s could not be found" msgstr "" -#: nova/compute/manager.py:158 -#, python-format -msgid "instance %s: starting..." +#: ../nova/api/ec2/__init__.py:121 +msgid "Too many failed authentications." msgstr "" -#: nova/compute/manager.py:197 +#: ../nova/api/ec2/__init__.py:131 #, python-format -msgid "instance %s: Failed to spawn" +msgid "" +"Access key %(access_key)s has had %(failures)d failed authentications and " +"will be locked out for %(lock_mins)d minutes." msgstr "" -#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140 #, python-format -msgid "Terminating instance %s" +msgid "Authentication Failure: %s" msgstr "" -#: nova/compute/manager.py:217 +#: ../nova/api/ec2/__init__.py:182 #, python-format -msgid "Disassociating address %s" +msgid "Authenticated Request For %(uname)s:%(pname)s)" msgstr "" -#: nova/compute/manager.py:230 +#: ../nova/api/ec2/__init__.py:207 #, python-format -msgid "Deallocating address %s" +msgid "action: %s" msgstr "" -#: nova/compute/manager.py:243 +#: ../nova/api/ec2/__init__.py:209 #, python-format -msgid "trying to destroy already destroyed instance: %s" +msgid "arg: %(key)s\t\tval: %(value)s" msgstr "" -#: nova/compute/manager.py:257 +#: ../nova/api/ec2/__init__.py:281 #, python-format -msgid "Rebooting instance %s" +msgid "" +"Unauthorized request for controller=%(controller)s and action=%(action)s" msgstr "" -#: nova/compute/manager.py:260 +#: ../nova/api/ec2/__init__.py:314 #, python-format -msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgid "InstanceNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:286 +#: ../nova/api/ec2/__init__.py:320 #, python-format -msgid "instance %s: snapshotting" +msgid "VolumeNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:289 +#: ../nova/api/ec2/__init__.py:326 #, python-format -msgid "" -"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgid "NotFound raised: %s" msgstr "" -#: nova/compute/manager.py:301 +#: ../nova/api/ec2/__init__.py:329 #, python-format -msgid "instance %s: rescuing" +msgid "ApiError raised: %s" msgstr "" -#: nova/compute/manager.py:316 +#: ../nova/api/ec2/__init__.py:338 #, python-format -msgid "instance %s: unrescuing" +msgid "Unexpected error raised: %s" msgstr "" -#: nova/compute/manager.py:335 -#, python-format -msgid "instance %s: pausing" +#: ../nova/api/ec2/__init__.py:343 +msgid "An unknown error has occurred. Please try your request again." msgstr "" -#: nova/compute/manager.py:352 +#: ../nova/auth/dbdriver.py:84 #, python-format -msgid "instance %s: unpausing" +msgid "User %s already exists" msgstr "" -#: nova/compute/manager.py:369 +#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232 #, python-format -msgid "instance %s: retrieving diagnostics" +msgid "Project can't be created because manager %s doesn't exist" msgstr "" -#: nova/compute/manager.py:382 +#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243 #, python-format -msgid "instance %s: suspending" +msgid "Project can't be created because user %s doesn't exist" msgstr "" -#: nova/compute/manager.py:401 +#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229 #, python-format -msgid "instance %s: resuming" +msgid "Project can't be created because project %s already exists" msgstr "" -#: nova/compute/manager.py:420 +#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268 #, python-format -msgid "instance %s: locking" +msgid "Project can't be modified because manager %s doesn't exist" msgstr "" -#: nova/compute/manager.py:432 +#: ../nova/auth/dbdriver.py:245 #, python-format -msgid "instance %s: unlocking" +msgid "User \"%s\" not found" msgstr "" -#: nova/compute/manager.py:442 +#: ../nova/auth/dbdriver.py:248 #, python-format -msgid "instance %s: getting locked state" +msgid "Project \"%s\" not found" msgstr "" -#: nova/compute/manager.py:462 -#, python-format -msgid "instance %s: attaching volume %s to %s" +#: ../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/compute/manager.py:478 +#: ../nova/virt/xenapi_conn.py:311 #, python-format -msgid "instance %s: attach failed %s, removing" +msgid "Task [%(name)s] %(task)s status: success %(result)s" msgstr "" -#: nova/compute/manager.py:493 +#: ../nova/virt/xenapi_conn.py:317 #, python-format -msgid "Detach volume %s from mountpoint %s on instance %s" +msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s" msgstr "" -#: nova/compute/manager.py:497 +#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344 #, python-format -msgid "Detaching volume from unknown instance %s" +msgid "Got exception: %s" msgstr "" -#: nova/compute/monitor.py:259 +#: ../nova/compute/monitor.py:259 #, python-format msgid "updating %s..." msgstr "" -#: nova/compute/monitor.py:289 +#: ../nova/compute/monitor.py:289 msgid "unexpected error during update" msgstr "" -#: nova/compute/monitor.py:355 +#: ../nova/compute/monitor.py:356 #, python-format -msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/monitor.py:377 +#: ../nova/compute/monitor.py:379 #, python-format -msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/monitor.py:412 +#: ../nova/compute/monitor.py:414 msgid "unexpected exception getting connection" msgstr "" -#: nova/compute/monitor.py:427 +#: ../nova/compute/monitor.py:429 #, 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 +#: ../nova/volume/san.py:67 #, python-format -msgid "No service for id %s" +msgid "Could not find iSCSI export for volume %s" msgstr "" -#: nova/db/sqlalchemy/api.py:229 +#: ../nova/api/ec2/apirequest.py:100 #, python-format -msgid "No service for %s, %s" +msgid "" +"Unsupported API request: controller = %(controller)s, action = %(action)s" msgstr "" -#: nova/db/sqlalchemy/api.py:574 +#: ../nova/api/openstack/__init__.py:55 #, python-format -msgid "No floating ip for address %s" +msgid "Caught error: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:668 -#, python-format -msgid "No instance for id %s" +#: ../nova/api/openstack/__init__.py:76 +msgid "Including admin operations in API." 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" +#: ../nova/console/xvp.py:99 +msgid "Rebuilding xvp conf" msgstr "" -#: nova/db/sqlalchemy/api.py:891 +#: ../nova/console/xvp.py:116 #, python-format -msgid "no keypair for user %s, name %s" +msgid "Re-wrote %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 -#, python-format -msgid "No network for id %s" +#: ../nova/console/xvp.py:121 +msgid "Stopping xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1036 -#, python-format -msgid "No network for bridge %s" +#: ../nova/console/xvp.py:134 +msgid "Starting xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1050 +#: ../nova/console/xvp.py:141 #, python-format -msgid "No network for instance %s" +msgid "Error starting xvp: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1180 -#, python-format -msgid "Token %s does not exist" +#: ../nova/console/xvp.py:144 +msgid "Restarting xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1205 -#, python-format -msgid "No quota for project_id %s" +#: ../nova/console/xvp.py:146 +msgid "xvp not running..." msgstr "" -#: nova/db/sqlalchemy/api.py:1356 -#, python-format -msgid "No volume for id %s" +#: ../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 "" -#: nova/db/sqlalchemy/api.py:1401 -#, python-format -msgid "Volume %s not found" +#: ../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 "" -#: nova/db/sqlalchemy/api.py:1413 -#, python-format -msgid "No export device found for volume %s" +#: ../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/db/sqlalchemy/api.py:1426 -#, python-format -msgid "No target id found for volume %s" +#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536 +msgid "network" msgstr "" -#: nova/db/sqlalchemy/api.py:1471 -#, python-format -msgid "No security group with id %s" +#: ../bin/nova-manage.py:448 +msgid "IP address" msgstr "" -#: nova/db/sqlalchemy/api.py:1488 -#, python-format -msgid "No security group named %s for project: %s" +#: ../bin/nova-manage.py:449 +msgid "MAC address" msgstr "" -#: nova/db/sqlalchemy/api.py:1576 -#, python-format -msgid "No secuity group rule with id %s" +#: ../bin/nova-manage.py:450 +msgid "hostname" msgstr "" -#: nova/db/sqlalchemy/api.py:1650 -#, python-format -msgid "No user for id %s" +#: ../bin/nova-manage.py:451 +msgid "host" msgstr "" -#: nova/db/sqlalchemy/api.py:1666 -#, python-format -msgid "No user for access key %s" +#: ../bin/nova-manage.py:537 +msgid "netmask" msgstr "" -#: nova/db/sqlalchemy/api.py:1728 -#, python-format -msgid "No project with id %s" +#: ../bin/nova-manage.py:538 +msgid "start address" msgstr "" -#: nova/image/glance.py:78 +#: ../nova/virt/disk.py:69 #, python-format -msgid "Parallax returned HTTP error %d from request for /images" +msgid "Failed to load partition: %s" msgstr "" -#: nova/image/glance.py:97 +#: ../nova/virt/disk.py:91 #, python-format -msgid "Parallax returned HTTP error %d from request for /images/detail" +msgid "Failed to mount filesystem: %s" msgstr "" -#: nova/image/s3.py:82 +#: ../nova/virt/disk.py:124 #, python-format -msgid "Image %s could not be found" +msgid "nbd device %s did not show up" msgstr "" -#: nova/network/api.py:39 +#: ../nova/virt/disk.py:128 #, python-format -msgid "Quota exceeeded for %s, tried to allocate address" +msgid "Could not attach image to loopback: %s" msgstr "" -#: nova/network/api.py:42 -msgid "Address quota exceeded. You cannot allocate any more addresses" +#: ../nova/virt/disk.py:151 +msgid "No free nbd devices" msgstr "" -#: nova/network/linux_net.py:176 +#: ../doc/ext/nova_todo.py:46 #, python-format -msgid "Starting VLAN inteface %s" +msgid "%(filename)s, line %(line_info)d" msgstr "" -#: nova/network/linux_net.py:186 -#, python-format -msgid "Starting Bridge interface for %s" +#. FIXME(chiradeep): implement this +#: ../nova/virt/hyperv.py:118 +msgid "In init host" msgstr "" -#: nova/network/linux_net.py:254 +#: ../nova/virt/hyperv.py:131 #, python-format -msgid "Hupping dnsmasq threw %s" +msgid "Attempt to create duplicate vm %s" msgstr "" -#: nova/network/linux_net.py:256 +#: ../nova/virt/hyperv.py:148 #, python-format -msgid "Pid %d is stale, relaunching dnsmasq" +msgid "Starting VM %s " msgstr "" -#: nova/network/linux_net.py:334 +#: ../nova/virt/hyperv.py:150 #, python-format -msgid "Killing dnsmasq threw %s" +msgid "Started VM %s " msgstr "" -#: nova/network/manager.py:135 -msgid "setting network host" +#: ../nova/virt/hyperv.py:152 +#, python-format +msgid "spawn vm failed: %s" msgstr "" -#: nova/network/manager.py:190 +#: ../nova/virt/hyperv.py:169 #, python-format -msgid "Leasing IP %s" +msgid "Failed to create VM %s" msgstr "" -#: nova/network/manager.py:194 +#: ../nova/virt/hyperv.py:188 #, python-format -msgid "IP %s leased that isn't associated" +msgid "Set memory for vm %s..." msgstr "" -#: nova/network/manager.py:197 +#: ../nova/virt/hyperv.py:198 #, python-format -msgid "IP %s leased to bad mac %s vs %s" +msgid "Set vcpus for vm %s..." msgstr "" -#: nova/network/manager.py:205 +#: ../nova/virt/hyperv.py:202 #, python-format -msgid "IP %s leased that was already deallocated" +msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s" msgstr "" -#: nova/network/manager.py:214 +#: ../nova/virt/hyperv.py:227 #, python-format -msgid "IP %s released that isn't associated" +msgid "Failed to add diskdrive to VM %s" msgstr "" -#: nova/network/manager.py:217 +#: ../nova/virt/hyperv.py:230 #, python-format -msgid "IP %s released from bad mac %s vs %s" +msgid "New disk drive path is %s" msgstr "" -#: nova/network/manager.py:220 +#: ../nova/virt/hyperv.py:247 #, python-format -msgid "IP %s released that was not leased" +msgid "Failed to add vhd file to VM %s" msgstr "" -#: nova/network/manager.py:442 +#: ../nova/virt/hyperv.py:249 #, python-format -msgid "Dissassociated %s stale fixed ip(s)" +msgid "Created disk for %s" msgstr "" -#: nova/objectstore/handler.py:106 +#: ../nova/virt/hyperv.py:253 #, python-format -msgid "Unknown S3 value type %r" +msgid "Creating nic for %s " msgstr "" -#: nova/objectstore/handler.py:137 -msgid "Authenticated request" +#: ../nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" msgstr "" -#: nova/objectstore/handler.py:182 -msgid "List of buckets requested" +#: ../nova/virt/hyperv.py:273 +#, python-format +msgid "Failed creating port for %s" msgstr "" -#: nova/objectstore/handler.py:209 +#: ../nova/virt/hyperv.py:276 #, python-format -msgid "List keys for bucket %s" +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/objectstore/handler.py:217 +#: ../nova/virt/hyperv.py:288 #, python-format -msgid "Unauthorized attempt to access bucket %s" +msgid "Created nic for %s " msgstr "" -#: nova/objectstore/handler.py:235 +#: ../nova/virt/hyperv.py:321 #, python-format -msgid "Creating bucket %s" +msgid "WMI job failed: %s" msgstr "" -#: nova/objectstore/handler.py:245 +#: ../nova/virt/hyperv.py:325 #, python-format -msgid "Deleting bucket %s" +msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s " msgstr "" -#: nova/objectstore/handler.py:249 +#: ../nova/virt/hyperv.py:361 #, python-format -msgid "Unauthorized attempt to delete bucket %s" +msgid "Got request to destroy vm %s" msgstr "" -#: nova/objectstore/handler.py:271 +#: ../nova/virt/hyperv.py:386 #, python-format -msgid "Getting object: %s / %s" +msgid "Failed to destroy vm %s" msgstr "" -#: nova/objectstore/handler.py:274 +#: ../nova/virt/hyperv.py:393 #, python-format -msgid "Unauthorized attempt to get object %s from bucket %s" +msgid "Del: disk %(vhdfile)s vm %(instance_name)s" msgstr "" -#: nova/objectstore/handler.py:292 +#: ../nova/virt/hyperv.py:415 #, python-format -msgid "Putting object: %s / %s" +msgid "" +"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, " +"num_cpu=%(numprocs)s, cpu_time=%(uptime)s" msgstr "" -#: nova/objectstore/handler.py:295 +#: ../nova/virt/hyperv.py:451 #, python-format -msgid "Unauthorized attempt to upload object %s to bucket %s" +msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/objectstore/handler.py:314 +#: ../nova/virt/hyperv.py:454 #, python-format -msgid "Deleting object: %s / %s" +msgid "Failed to change vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/objectstore/handler.py:393 +#: ../nova/compute/api.py:71 #, python-format -msgid "Not authorized to upload image: invalid directory %s" +msgid "Instance %d was not found in get_network_topic" msgstr "" -#: nova/objectstore/handler.py:401 +#: ../nova/compute/api.py:77 #, python-format -msgid "Not authorized to upload image: unauthorized bucket %s" +msgid "Instance %d has no host" msgstr "" -#: nova/objectstore/handler.py:406 +#: ../nova/compute/api.py:97 #, python-format -msgid "Starting image upload: %s" +msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances" msgstr "" -#: nova/objectstore/handler.py:420 +#: ../nova/compute/api.py:99 #, python-format -msgid "Not authorized to update attributes of image %s" +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." msgstr "" -#: nova/objectstore/handler.py:428 -#, python-format -msgid "Toggling publicity flag of image %s %r" +#: ../nova/compute/api.py:112 +msgid "Creating a raw instance" msgstr "" -#: nova/objectstore/handler.py:433 +#: ../nova/compute/api.py:160 #, python-format -msgid "Updating user fields on image %s" +msgid "Going to run %s instances..." msgstr "" -#: nova/objectstore/handler.py:447 +#: ../nova/compute/api.py:187 #, python-format -msgid "Unauthorized attempt to delete image %s" +msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s" msgstr "" -#: nova/objectstore/handler.py:452 +#: ../nova/compute/api.py:292 #, python-format -msgid "Deleted image: %s" +msgid "Going to try to terminate %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" +#: ../nova/compute/api.py:296 +#, python-format +msgid "Instance %d was not found during terminate" msgstr "" -#: nova/scheduler/driver.py:66 -msgid "Must implement a fallback schedule" +#: ../nova/compute/api.py:301 +#, python-format +msgid "Instance %d is already being terminated" msgstr "" -#: nova/scheduler/manager.py:69 +#: ../nova/compute/api.py:481 #, python-format -msgid "Casting to %s %s for %s" +msgid "Invalid device specified: %s. Example device: /dev/vdb" msgstr "" -#: nova/scheduler/simple.py:63 -msgid "All hosts have too many cores" +#: ../nova/compute/api.py:496 +msgid "Volume isn't attached to anything!" msgstr "" -#: nova/scheduler/simple.py:95 -msgid "All hosts have too many gigabytes" +#: ../nova/rpc.py:98 +#, python-format +msgid "" +"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in " +"%(fl_intv)d seconds." msgstr "" -#: nova/scheduler/simple.py:115 -msgid "All hosts have too many networks" +#: ../nova/rpc.py:103 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." msgstr "" -#: nova/tests/test_cloud.py:198 -msgid "Can't test instances without a real virtual env." +#: ../nova/rpc.py:122 +msgid "Reconnected to queue" msgstr "" -#: nova/tests/test_cloud.py:210 -#, python-format -msgid "Need to watch instance %s until it's running..." +#: ../nova/rpc.py:129 +msgid "Failed to fetch message from queue" msgstr "" -#: nova/tests/test_compute.py:104 +#: ../nova/rpc.py:159 #, python-format -msgid "Running instances: %s" +msgid "Initing the Adapter Consumer for %s" msgstr "" -#: nova/tests/test_compute.py:110 +#: ../nova/rpc.py:178 #, python-format -msgid "After terminating instances: %s" +msgid "received %s" msgstr "" -#: nova/tests/test_rpc.py:89 +#. 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:191 #, python-format -msgid "Nested received %s, %s" +msgid "no method for message: %s" msgstr "" -#: nova/tests/test_rpc.py:94 +#: ../nova/rpc.py:192 #, python-format -msgid "Nested return %s" +msgid "No method for message: %s" msgstr "" -#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#: ../nova/rpc.py:253 #, python-format -msgid "Received %s" +msgid "Returning exception %s to caller" msgstr "" -#: nova/tests/test_volume.py:162 +#: ../nova/rpc.py:294 #, python-format -msgid "Target %s allocated" +msgid "unpacked context: %s" msgstr "" -#: nova/virt/connection.py:73 -msgid "Failed to open connection to the hypervisor" +#: ../nova/rpc.py:313 +msgid "Making asynchronous call..." msgstr "" -#: nova/virt/fake.py:210 +#: ../nova/rpc.py:316 #, python-format -msgid "Instance %s Not Found" +msgid "MSG_ID is %s" msgstr "" -#: nova/virt/hyperv.py:118 -msgid "In init host" +#: ../nova/rpc.py:354 +msgid "Making asynchronous cast..." msgstr "" -#: nova/virt/hyperv.py:131 +#: ../nova/rpc.py:364 #, python-format -msgid "Attempt to create duplicate vm %s" +msgid "response %s" msgstr "" -#: nova/virt/hyperv.py:148 +#: ../nova/rpc.py:373 #, python-format -msgid "Starting VM %s " +msgid "topic is %s" msgstr "" -#: nova/virt/hyperv.py:150 +#: ../nova/rpc.py:374 #, python-format -msgid "Started VM %s " +msgid "message %s" msgstr "" -#: nova/virt/hyperv.py:152 +#: ../nova/volume/driver.py:78 #, python-format -msgid "spawn vm failed: %s" +msgid "Recovering from a failed execute. Try number %s" msgstr "" -#: nova/virt/hyperv.py:169 +#: ../nova/volume/driver.py:87 #, python-format -msgid "Failed to create VM %s" +msgid "volume group %s doesn't exist" msgstr "" -#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#: ../nova/volume/driver.py:220 #, python-format -msgid "Created VM %s..." +msgid "FAKE AOE: %s" msgstr "" -#: nova/virt/hyperv.py:188 -#, python-format -msgid "Set memory for vm %s..." +#: ../nova/volume/driver.py:233 +msgid "Skipping ensure_export. No iscsi_target " msgstr "" -#: nova/virt/hyperv.py:198 -#, python-format -msgid "Set vcpus for vm %s..." +#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288 +msgid "Skipping remove_export. No iscsi_target " msgstr "" -#: nova/virt/hyperv.py:202 +#: ../nova/volume/driver.py:347 #, python-format -msgid "Creating disk for %s by attaching disk file %s" +msgid "FAKE ISCSI: %s" msgstr "" -#: nova/virt/hyperv.py:227 +#: ../nova/volume/driver.py:359 #, python-format -msgid "Failed to add diskdrive to VM %s" +msgid "rbd has no pool %s" msgstr "" -#: nova/virt/hyperv.py:230 +#: ../nova/volume/driver.py:414 #, python-format -msgid "New disk drive path is %s" +msgid "Sheepdog is not working: %s" msgstr "" -#: nova/virt/hyperv.py:247 -#, python-format -msgid "Failed to add vhd file to VM %s" +#: ../nova/volume/driver.py:416 +msgid "Sheepdog is not working" msgstr "" -#: nova/virt/hyperv.py:249 +#: ../nova/wsgi.py:68 #, python-format -msgid "Created disk for %s" +msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: nova/virt/hyperv.py:253 -#, python-format -msgid "Creating nic for %s " +#: ../nova/wsgi.py:147 +msgid "You must implement __call__" msgstr "" -#: nova/virt/hyperv.py:272 -msgid "Failed creating a port on the external vswitch" +#: ../bin/nova-instancemonitor.py:55 +msgid "Starting instance monitor" msgstr "" -#: nova/virt/hyperv.py:273 -#, python-format -msgid "Failed creating port for %s" +#: ../bin/nova-dhcpbridge.py:58 +msgid "leasing ip" msgstr "" -#: nova/virt/hyperv.py:275 -#, python-format -msgid "Created switch port %s on switch %s" +#: ../bin/nova-dhcpbridge.py:73 +msgid "Adopted old lease or got a change of mac/hostname" msgstr "" -#: nova/virt/hyperv.py:285 -#, python-format -msgid "Failed to add nic to VM %s" +#: ../bin/nova-dhcpbridge.py:80 +msgid "releasing ip" msgstr "" -#: nova/virt/hyperv.py:287 +#: ../bin/nova-dhcpbridge.py:123 #, python-format -msgid "Created nic for %s " +msgid "" +"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s " +"on interface %(interface)s" msgstr "" -#: nova/virt/hyperv.py:320 +#: ../nova/virt/fake.py:239 #, python-format -msgid "WMI job failed: %s" +msgid "Instance %s Not Found" msgstr "" -#: nova/virt/hyperv.py:322 +#: ../nova/network/manager.py:153 #, python-format -msgid "WMI job succeeded: %s, Elapsed=%s " +msgid "Dissassociated %s stale fixed ip(s)" msgstr "" -#: nova/virt/hyperv.py:358 -#, python-format -msgid "Got request to destroy vm %s" +#: ../nova/network/manager.py:157 +msgid "setting network host" msgstr "" -#: nova/virt/hyperv.py:383 +#: ../nova/network/manager.py:212 #, python-format -msgid "Failed to destroy vm %s" +msgid "Leasing IP %s" msgstr "" -#: nova/virt/hyperv.py:389 +#: ../nova/network/manager.py:216 #, python-format -msgid "Del: disk %s vm %s" +msgid "IP %s leased that isn't associated" msgstr "" -#: nova/virt/hyperv.py:405 +#: ../nova/network/manager.py:220 #, python-format -msgid "" -"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " -"cpu_time=%s" +msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#: ../nova/network/manager.py:228 #, python-format -msgid "duplicate name found: %s" +msgid "IP %s leased that was already deallocated" msgstr "" -#: nova/virt/hyperv.py:444 +#: ../nova/network/manager.py:233 #, python-format -msgid "Successfully changed vm state of %s to %s" +msgid "Releasing IP %s" msgstr "" -#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#: ../nova/network/manager.py:237 #, python-format -msgid "Failed to change vm state of %s to %s" +msgid "IP %s released that isn't associated" msgstr "" -#: nova/virt/images.py:70 +#: ../nova/network/manager.py:241 #, python-format -msgid "Finished retreving %s -- placed in %s" +msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/libvirt_conn.py:144 +#: ../nova/network/manager.py:244 #, python-format -msgid "Connecting to libvirt: %s" +msgid "IP %s released that was not leased" msgstr "" -#: nova/virt/libvirt_conn.py:157 -msgid "Connection to libvirt broke" +#: ../nova/network/manager.py:519 +msgid "" +"The sum between the number of networks and the vlan start cannot be greater " +"than 4094" msgstr "" -#: nova/virt/libvirt_conn.py:229 +#: ../nova/virt/xenapi/volume_utils.py:57 #, python-format -msgid "instance %s: deleting instance files %s" +msgid "Introducing %s..." msgstr "" -#: nova/virt/libvirt_conn.py:271 +#: ../nova/virt/xenapi/volume_utils.py:74 #, python-format -msgid "No disk at %s" +msgid "Introduced %(label)s as %(sr_ref)s." msgstr "" -#: nova/virt/libvirt_conn.py:278 -msgid "Instance snapshotting is not supported for libvirtat this time" +#: ../nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" msgstr "" -#: nova/virt/libvirt_conn.py:294 +#: ../nova/virt/xenapi/volume_utils.py:90 #, python-format -msgid "instance %s: rebooted" +msgid "Unable to find SR from VBD %s" msgstr "" -#: nova/virt/libvirt_conn.py:297 +#: ../nova/virt/xenapi/volume_utils.py:96 #, python-format -msgid "_wait_for_reboot failed: %s" +msgid "Forgetting SR %s ... " msgstr "" -#: nova/virt/libvirt_conn.py:340 +#: ../nova/virt/xenapi/volume_utils.py:101 #, python-format -msgid "instance %s: rescued" +msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s" msgstr "" -#: nova/virt/libvirt_conn.py:343 +#: ../nova/virt/xenapi/volume_utils.py:107 #, python-format -msgid "_wait_for_rescue failed: %s" +msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s" msgstr "" -#: nova/virt/libvirt_conn.py:370 +#: ../nova/virt/xenapi/volume_utils.py:111 #, python-format -msgid "instance %s: is running" +msgid "Forgetting SR %s done." msgstr "" -#: nova/virt/libvirt_conn.py:381 +#: ../nova/virt/xenapi/volume_utils.py:113 #, python-format -msgid "instance %s: booted" +msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s" msgstr "" -#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#: ../nova/virt/xenapi/volume_utils.py:123 #, python-format -msgid "instance %s: failed to boot" +msgid "Unable to introduce VDI on SR %s" msgstr "" -#: nova/virt/libvirt_conn.py:395 +#: ../nova/virt/xenapi/volume_utils.py:128 #, python-format -msgid "virsh said: %r" -msgstr "" - -#: nova/virt/libvirt_conn.py:399 -msgid "cool, it's a device" +msgid "Unable to get record of VDI %s on" msgstr "" -#: nova/virt/libvirt_conn.py:407 +#: ../nova/virt/xenapi/volume_utils.py:146 #, python-format -msgid "data: %r, fpath: %r" +msgid "Unable to introduce VDI for SR %s" msgstr "" -#: nova/virt/libvirt_conn.py:415 +#: ../nova/virt/xenapi/volume_utils.py:175 #, python-format -msgid "Contents of file %s: %r" +msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s" msgstr "" -#: nova/virt/libvirt_conn.py:449 +#: ../nova/virt/xenapi/volume_utils.py:197 #, python-format -msgid "instance %s: Creating image" +msgid "Mountpoint cannot be translated: %s" msgstr "" -#: nova/virt/libvirt_conn.py:505 +#: ../nova/objectstore/image.py:262 #, python-format -msgid "instance %s: injecting key into image %s" +msgid "Failed to decrypt private key: %s" msgstr "" -#: nova/virt/libvirt_conn.py:508 +#: ../nova/objectstore/image.py:269 #, python-format -msgid "instance %s: injecting net into image %s" +msgid "Failed to decrypt initialization vector: %s" msgstr "" -#: nova/virt/libvirt_conn.py:516 +#: ../nova/objectstore/image.py:277 #, python-format -msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgid "Failed to decrypt image file %(image_file)s: %(err)s" msgstr "" -#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#: ../nova/objectstore/handler.py:106 #, python-format -msgid "instance %s: starting toXML method" +msgid "Unknown S3 value type %r" msgstr "" -#: nova/virt/libvirt_conn.py:589 -#, python-format -msgid "instance %s: finished toXML method" +#: ../nova/objectstore/handler.py:137 +msgid "Authenticated request" 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" +#: ../nova/objectstore/handler.py:182 +msgid "List of buckets requested" msgstr "" -#: nova/virt/xenapi_conn.py:263 +#: ../nova/objectstore/handler.py:209 #, python-format -msgid "Task [%s] %s status: success %s" +msgid "List keys for bucket %s" msgstr "" -#: nova/virt/xenapi_conn.py:271 +#: ../nova/objectstore/handler.py:217 #, python-format -msgid "Task [%s] %s status: %s %s" +msgid "Unauthorized attempt to access bucket %s" msgstr "" -#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#: ../nova/objectstore/handler.py:235 #, python-format -msgid "Got exception: %s" +msgid "Creating bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:72 +#: ../nova/objectstore/handler.py:245 #, 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" +msgid "Deleting bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:249 +#: ../nova/objectstore/handler.py:249 #, python-format -msgid "xenapi.fake does not have an implementation for %s" +msgid "Unauthorized attempt to delete bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:283 +#: ../nova/objectstore/handler.py:273 #, python-format -msgid "Calling %s %s" +msgid "Getting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/fake.py:288 +#: ../nova/objectstore/handler.py:276 #, python-format -msgid "Calling getter %s" +msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/fake.py:340 +#: ../nova/objectstore/handler.py:296 #, python-format -msgid "" -"xenapi.fake does not have an implementation for %s or it has been called " -"with the wrong number of arguments" +msgid "Putting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/network_utils.py:40 +#: ../nova/objectstore/handler.py:299 #, python-format -msgid "Found non-unique network for bridge %s" +msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/network_utils.py:43 +#: ../nova/objectstore/handler.py:318 #, python-format -msgid "Found no network for bridge %s" +msgid "Deleting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:127 +#: ../nova/objectstore/handler.py:322 #, python-format -msgid "Created VM %s as %s." +msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:147 +#: ../nova/objectstore/handler.py:396 #, python-format -msgid "Creating VBD for VM %s, VDI %s ... " +msgid "Not authorized to upload image: invalid directory %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:149 +#: ../nova/objectstore/handler.py:404 #, python-format -msgid "Created VBD %s for VM %s, VDI %s." +msgid "Not authorized to upload image: unauthorized bucket %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:165 +#: ../nova/objectstore/handler.py:409 #, python-format -msgid "VBD not found in instance %s" +msgid "Starting image upload: %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:175 +#: ../nova/objectstore/handler.py:423 #, python-format -msgid "Unable to unplug VBD %s" +msgid "Not authorized to update attributes of image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:187 +#: ../nova/objectstore/handler.py:431 #, python-format -msgid "Unable to destroy VBD %s" +msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r" msgstr "" -#: nova/virt/xenapi/vm_utils.py:202 +#. other attributes imply update +#: ../nova/objectstore/handler.py:436 #, python-format -msgid "Creating VIF for VM %s, network %s." +msgid "Updating user fields on image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:205 +#: ../nova/objectstore/handler.py:450 #, python-format -msgid "Created VIF %s for VM %s, network %s." +msgid "Unauthorized attempt to delete image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:216 +#: ../nova/objectstore/handler.py:455 #, python-format -msgid "Snapshotting VM %s with label '%s'..." +msgid "Deleted image: %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:229 +#: ../nova/auth/manager.py:259 #, python-format -msgid "Created snapshot %s from VM %s." +msgid "Looking up user: %r" msgstr "" -#: nova/virt/xenapi/vm_utils.py:243 +#: ../nova/auth/manager.py:263 #, python-format -msgid "Asking xapi to upload %s as '%s'" +msgid "Failed authorization for access key %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:261 +#: ../nova/auth/manager.py:264 #, python-format -msgid "Asking xapi to fetch %s as %s" +msgid "No user found for access key %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:279 +#: ../nova/auth/manager.py:270 #, python-format -msgid "Looking up vdi %s for PV kernel" +msgid "Using project name = user name (%s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:290 +#: ../nova/auth/manager.py:277 #, python-format -msgid "PV Kernel in VDI:%d" +msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:318 +#: ../nova/auth/manager.py:279 #, python-format -msgid "VDI %s is still available" +msgid "No project called %s could be found" msgstr "" -#: nova/virt/xenapi/vm_utils.py:331 +#: ../nova/auth/manager.py:287 #, python-format -msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgid "" +"Failed authorization: user %(uname)s not admin and not member of project " +"%(pjname)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:333 +#: ../nova/auth/manager.py:289 #, python-format -msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgid "User %(uid)s is not a member of project %(pjid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:390 +#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309 #, python-format -msgid "VHD %s has parent %s" +msgid "Invalid signature for user %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:407 -#, python-format -msgid "Re-scanning SR %s" +#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310 +msgid "Signature does not match" msgstr "" -#: nova/virt/xenapi/vm_utils.py:431 -#, python-format -msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +#: ../nova/auth/manager.py:380 +msgid "Must specify project" msgstr "" -#: nova/virt/xenapi/vm_utils.py:448 +#: ../nova/auth/manager.py:414 #, python-format -msgid "No VDIs found for VM %s" +msgid "The %s role can not be found" msgstr "" -#: nova/virt/xenapi/vm_utils.py:452 +#: ../nova/auth/manager.py:416 #, python-format -msgid "Unexpected number of VDIs (%s) found for VM %s" +msgid "The %s role is global only" msgstr "" -#: nova/virt/xenapi/vmops.py:62 +#: ../nova/auth/manager.py:420 #, python-format -msgid "Attempted to create non-unique name %s" +msgid "Adding role %(role)s to user %(uid)s in project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:99 +#: ../nova/auth/manager.py:423 #, python-format -msgid "Starting VM %s..." +msgid "Adding sitewide role %(role)s to user %(uid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:101 +#: ../nova/auth/manager.py:448 #, python-format -msgid "Spawning VM %s created %s." +msgid "Removing role %(role)s from user %(uid)s on project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:112 +#: ../nova/auth/manager.py:451 #, python-format -msgid "Instance %s: booted" +msgid "Removing sitewide role %(role)s from user %(uid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:137 +#: ../nova/auth/manager.py:515 #, python-format -msgid "Instance not present %s" +msgid "Created project %(name)s with manager %(manager_user)s" msgstr "" -#: nova/virt/xenapi/vmops.py:166 +#: ../nova/auth/manager.py:533 #, python-format -msgid "Starting snapshot for VM %s" +msgid "modifying project %s" msgstr "" -#: nova/virt/xenapi/vmops.py:174 +#: ../nova/auth/manager.py:545 #, python-format -msgid "Unable to Snapshot %s: %s" +msgid "Adding user %(uid)s to project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:184 +#: ../nova/auth/manager.py:566 #, python-format -msgid "Finished snapshot and upload for VM %s" +msgid "Remove user %(uid)s from project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:252 +#: ../nova/auth/manager.py:592 #, python-format -msgid "suspend: instance not present %s" +msgid "Deleting project %s" msgstr "" -#: nova/virt/xenapi/vmops.py:262 +#: ../nova/auth/manager.py:650 #, python-format -msgid "resume: instance not present %s" +msgid "Created user %(rvname)s (admin: %(rvadmin)r)" msgstr "" -#: nova/virt/xenapi/vmops.py:271 +#: ../nova/auth/manager.py:659 #, python-format -msgid "Instance not found %s" +msgid "Deleting user %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:57 +#: ../nova/auth/manager.py:669 #, python-format -msgid "Introducing %s..." +msgid "Access Key change for user %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:74 +#: ../nova/auth/manager.py:671 #, python-format -msgid "Introduced %s as %s." -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:78 -msgid "Unable to create Storage Repository" +msgid "Secret Key change for user %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:90 +#: ../nova/auth/manager.py:673 #, python-format -msgid "Unable to find SR from VBD %s" +msgid "Admin status set to %(admin)r for user %(uid)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:96 +#: ../nova/auth/manager.py:722 #, python-format -msgid "Forgetting SR %s ... " +msgid "No vpn data for project %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:101 +#: ../nova/service.py:161 #, python-format -msgid "Ignoring exception %s when getting PBDs for %s" +msgid "Starting %(topic)s node (version %(vcs_string)s)" msgstr "" -#: nova/virt/xenapi/volume_utils.py:107 -#, python-format -msgid "Ignoring exception %s when unplugging PBD %s" +#: ../nova/service.py:174 +msgid "Service killed that has no database entry" msgstr "" -#: nova/virt/xenapi/volume_utils.py:111 -#, python-format -msgid "Forgetting SR %s done." +#: ../nova/service.py:195 +msgid "The service database object disappeared, Recreating it." msgstr "" -#: nova/virt/xenapi/volume_utils.py:113 -#, python-format -msgid "Ignoring exception %s when forgetting SR %s" +#: ../nova/service.py:207 +msgid "Recovered model server connection!" msgstr "" -#: nova/virt/xenapi/volume_utils.py:123 -#, python-format -msgid "Unable to introduce VDI on SR %s" +#: ../nova/service.py:213 +msgid "model server went away" msgstr "" -#: nova/virt/xenapi/volume_utils.py:128 +#: ../nova/auth/ldapdriver.py:174 #, python-format -msgid "Unable to get record of VDI %s on" +msgid "LDAP user %s already exists" msgstr "" -#: nova/virt/xenapi/volume_utils.py:146 +#: ../nova/auth/ldapdriver.py:205 #, python-format -msgid "Unable to introduce VDI for SR %s" +msgid "LDAP object for %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:175 +#: ../nova/auth/ldapdriver.py:348 #, python-format -msgid "Unable to obtain target information %s, %s" +msgid "User %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:197 +#: ../nova/auth/ldapdriver.py:472 #, python-format -msgid "Mountpoint cannot be translated: %s" +msgid "Group can't be created because group %s already exists" msgstr "" -#: nova/virt/xenapi/volumeops.py:51 +#: ../nova/auth/ldapdriver.py:478 #, python-format -msgid "Attach_volume: %s, %s, %s" +msgid "Group can't be created because user %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:69 +#: ../nova/auth/ldapdriver.py:495 #, python-format -msgid "Unable to create VDI on SR %s for instance %s" +msgid "User %s can't be searched in group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:81 +#: ../nova/auth/ldapdriver.py:507 #, python-format -msgid "Unable to use SR %s for instance %s" +msgid "User %s can't be added to the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:93 +#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521 #, python-format -msgid "Unable to attach volume to instance %s" +msgid "The group at dn %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:95 +#: ../nova/auth/ldapdriver.py:513 #, python-format -msgid "Mountpoint %s attached to instance %s" +msgid "User %(uid)s is already a member of the group %(group_dn)s" msgstr "" -#: nova/virt/xenapi/volumeops.py:106 +#: ../nova/auth/ldapdriver.py:524 #, python-format -msgid "Detach_volume: %s, %s" +msgid "" +"User %s can't be removed from the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:113 +#: ../nova/auth/ldapdriver.py:528 #, python-format -msgid "Unable to locate volume %s" +msgid "User %s is not a member of the group" msgstr "" -#: nova/virt/xenapi/volumeops.py:121 +#: ../nova/auth/ldapdriver.py:542 #, python-format -msgid "Unable to detach volume %s" +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." msgstr "" -#: nova/virt/xenapi/volumeops.py:128 +#: ../nova/auth/ldapdriver.py:549 #, python-format -msgid "Mountpoint %s detached from instance %s" +msgid "User %s can't be removed from all because the user doesn't exist" msgstr "" -#: nova/volume/api.py:44 +#: ../nova/auth/ldapdriver.py:564 #, python-format -msgid "Quota exceeeded for %s, tried to create %sG volume" +msgid "Group at dn %s doesn't exist" msgstr "" -#: nova/volume/api.py:46 +#: ../nova/virt/xenapi/network_utils.py:40 #, 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" +msgid "Found non-unique network for bridge %s" msgstr "" -#: nova/volume/driver.py:76 +#: ../nova/virt/xenapi/network_utils.py:43 #, python-format -msgid "Recovering from a failed execute. Try number %s" +msgid "Found no network for bridge %s" msgstr "" -#: nova/volume/driver.py:85 +#: ../nova/api/ec2/admin.py:97 #, python-format -msgid "volume group %s doesn't exist" +msgid "Creating new user: %s" msgstr "" -#: nova/volume/driver.py:210 +#: ../nova/api/ec2/admin.py:105 #, python-format -msgid "FAKE AOE: %s" +msgid "Deleting user: %s" msgstr "" -#: nova/volume/driver.py:315 +#: ../nova/api/ec2/admin.py:127 #, python-format -msgid "FAKE ISCSI: %s" +msgid "Adding role %(role)s to user %(user)s for project %(project)s" msgstr "" -#: nova/volume/manager.py:85 +#: ../nova/api/ec2/admin.py:131 #, python-format -msgid "Re-exporting %s volumes" +msgid "Adding sitewide role %(role)s to user %(user)s" msgstr "" -#: nova/volume/manager.py:93 +#: ../nova/api/ec2/admin.py:137 #, python-format -msgid "volume %s: creating" +msgid "Removing role %(role)s from user %(user)s for project %(project)s" msgstr "" -#: nova/volume/manager.py:102 +#: ../nova/api/ec2/admin.py:141 #, python-format -msgid "volume %s: creating lv of size %sG" +msgid "Removing sitewide role %(role)s from user %(user)s" msgstr "" -#: nova/volume/manager.py:106 -#, python-format -msgid "volume %s: creating export" +#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223 +msgid "operation must be add or remove" msgstr "" -#: nova/volume/manager.py:113 +#: ../nova/api/ec2/admin.py:159 #, python-format -msgid "volume %s: created successfully" +msgid "Getting x509 for user: %(name)s on project: %(project)s" msgstr "" -#: nova/volume/manager.py:121 -msgid "Volume is still attached" +#: ../nova/api/ec2/admin.py:177 +#, python-format +msgid "Create project %(name)s managed by %(manager_user)s" msgstr "" -#: nova/volume/manager.py:123 -msgid "Volume is not local to this node" +#: ../nova/api/ec2/admin.py:190 +#, python-format +msgid "Modify project: %(name)s managed by %(manager_user)s" msgstr "" -#: nova/volume/manager.py:124 +#: ../nova/api/ec2/admin.py:200 #, python-format -msgid "volume %s: removing export" +msgid "Delete project: %s" msgstr "" -#: nova/volume/manager.py:126 +#: ../nova/api/ec2/admin.py:214 #, python-format -msgid "volume %s: deleting" +msgid "Adding user %(user)s to project %(project)s" msgstr "" -#: nova/volume/manager.py:129 +#: ../nova/api/ec2/admin.py:218 #, python-format -msgid "volume %s: deleted successfully" +msgid "Removing user %(user)s from project %(project)s" msgstr "" diff --git a/po/cs.po b/po/cs.po index 861efa37e..7c69e2f79 100644 --- a/po/cs.po +++ b/po/cs.po @@ -7,2131 +7,2862 @@ msgid "" msgstr "" "Project-Id-Version: nova\n" "Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"POT-Creation-Date: 2011-02-21 10:03-0500\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-08 05:28+0000\n" -"X-Generator: Launchpad (build 12177)\n" +"X-Launchpad-Export-Date: 2011-03-19 06:18+0000\n" +"X-Generator: Launchpad (build 12559)\n" -#: nova/crypto.py:46 +#: ../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 "" + +#: ../nova/exception.py:33 +msgid "Unexpected error while running command." +msgstr "Při spouštění příkazu došlo k nečekané chybě" + +#: ../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 "Neošetřená výjimka" + +#: ../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/api/openstack/servers.py:72 +msgid "Failed to read private ip" +msgstr "" + +#: ../nova/api/openstack/servers.py:79 +msgid "Failed to read public ip(s)" +msgstr "" + +#: ../nova/api/openstack/servers.py:152 +#, python-format +msgid "%(param)s property not found for image %(_image_id)s" +msgstr "" + +#: ../nova/api/openstack/servers.py:168 +msgid "No keypairs defined" +msgstr "" + +#: ../nova/api/openstack/servers.py:238 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:253 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:267 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:281 +#, python-format +msgid "Compute.api::reset_network %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:292 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:303 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:314 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:325 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: ../nova/twistd.py:157 +msgid "Wrong number of arguments." +msgstr "" + +#: ../nova/twistd.py:209 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "" + +#: ../nova/twistd.py:221 +msgid "No such process" +msgstr "" + +#: ../nova/twistd.py:230 ../nova/service.py:224 +#, python-format +msgid "Serving %s" +msgstr "" + +#: ../nova/twistd.py:262 ../nova/service.py:225 +msgid "Full set of FLAGS:" +msgstr "" + +#: ../nova/twistd.py:266 +#, python-format +msgid "Starting %s" +msgstr "" + +#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101 +#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741 +#: ../nova/api/ec2/__init__.py:317 +#, 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 "Jméno souboru kořenové CA" -#: nova/crypto.py:49 +#: ../nova/crypto.py:49 msgid "Filename of private key" msgstr "Jméno souboru s privátním klíčem" -#: nova/crypto.py:51 -msgid "Filename of root Certificate Revokation List" +#: ../nova/crypto.py:51 +msgid "Filename of root Certificate Revokation List" +msgstr "" + +#: ../nova/crypto.py:53 +msgid "Where we keep our keys" +msgstr "Adresář, do kterého ukládáme naše klíče" + +#: ../nova/crypto.py:55 +msgid "Where we keep our root CA" +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 "Použijeme CA pro každý projekt?" + +#: ../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:78 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:80 +#, python-format +msgid "" +"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|" +msgstr "" + +#: ../nova/compute/manager.py:84 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:91 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:95 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: ../nova/compute/manager.py:179 +msgid "Instance has already been created" +msgstr "" + +#: ../nova/compute/manager.py:180 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#. pylint: disable=W0702 +#: ../nova/compute/manager.py:219 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: ../nova/compute/manager.py:255 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: ../nova/compute/manager.py:268 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: ../nova/compute/manager.py:282 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: ../nova/compute/manager.py:287 +#, python-format +msgid "" +"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:311 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: ../nova/compute/manager.py:316 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:332 +#, python-format +msgid "" +"trying to reset the password on a non-running instance: %(instance_id)s " +"(state: %(instance_state)s expected: %(expected_state)s)" +msgstr "" + +#: ../nova/compute/manager.py:335 +#, python-format +msgid "instance %s: setting admin password" +msgstr "" + +#: ../nova/compute/manager.py:353 +#, python-format +msgid "" +"trying to inject a file into a non-running instance: %(instance_id)s (state: " +"%(instance_state)s expected: %(expected_state)s)" +msgstr "" + +#: ../nova/compute/manager.py:362 +#, python-format +msgid "instance %(nm)s: injecting file to %(plain_path)s" +msgstr "" + +#: ../nova/compute/manager.py:372 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: ../nova/compute/manager.py:387 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: ../nova/compute/manager.py:406 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: ../nova/compute/manager.py:423 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: ../nova/compute/manager.py:440 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: ../nova/compute/manager.py:453 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: ../nova/compute/manager.py:472 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: ../nova/compute/manager.py:491 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: ../nova/compute/manager.py:503 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: ../nova/compute/manager.py:513 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: ../nova/compute/manager.py:526 +#, python-format +msgid "instance %s: reset network" +msgstr "" + +#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: ../nova/compute/manager.py:543 +#, python-format +msgid "instance %s: getting ajax console" +msgstr "" + +#: ../nova/compute/manager.py:553 +#, python-format +msgid "" +"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s" +msgstr "" + +#. pylint: disable=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:569 +#, python-format +msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing" +msgstr "" + +#: ../nova/compute/manager.py:585 +#, python-format +msgid "" +"Detach volume %(volume_id)s from mountpoint %(mp)s on instance " +"%(instance_id)s" +msgstr "" + +#: ../nova/compute/manager.py:588 +#, 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:304 ../nova/virt/xenapi/fake.py:404 +#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478 +msgid "Raising NotImplemented" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:306 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:341 +#, python-format +msgid "Calling %(localname)s %(impl)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:346 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:406 +#, 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:187 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: ../nova/network/linux_net.py:208 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:314 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:316 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:358 +#, python-format +msgid "killing radvd threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:360 +#, python-format +msgid "Pid %d is stale, relaunching radvd" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:449 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: ../nova/utils.py:58 +#, python-format +msgid "Inner Exception: %s" +msgstr "" + +#: ../nova/utils.py:59 +#, python-format +msgid "Class %s cannot be found" +msgstr "" + +#: ../nova/utils.py:118 +#, python-format +msgid "Fetching %s" msgstr "" -#: nova/crypto.py:53 -msgid "Where we keep our keys" -msgstr "Adresář, do kterého ukládáme naše klíče" +#: ../nova/utils.py:130 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "" -#: nova/crypto.py:55 -msgid "Where we keep our root CA" -msgstr "Adresář, do kterého ukládáme naši kořenovou CA" +#: ../nova/utils.py:143 ../nova/utils.py:183 +#, python-format +msgid "Result was %s" +msgstr "" -#: nova/crypto.py:57 -msgid "Should we use a CA for each project?" -msgstr "Použijeme CA pro každý projekt?" +#: ../nova/utils.py:159 +#, python-format +msgid "Running cmd (SSH): %s" +msgstr "" -#: nova/crypto.py:61 +#: ../nova/utils.py:217 #, python-format -msgid "Subject for certificate for users, %s for project, user, timestamp" +msgid "debug in callback: %s" msgstr "" -#: nova/crypto.py:66 +#: ../nova/utils.py:222 #, python-format -msgid "Subject for certificate for projects, %s for project, timestamp" +msgid "Running %s" msgstr "" -#: nova/crypto.py:71 +#: ../nova/utils.py:262 #, python-format -msgid "Subject for certificate for vpns, %s for project, timestamp" +msgid "Link Local address is not found.:%s" msgstr "" -#: nova/crypto.py:258 +#: ../nova/utils.py:265 #, python-format -msgid "Flags path: %s" +msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s" msgstr "" -#: nova/exception.py:33 -msgid "Unexpected error while running command." -msgstr "Při spouštění příkazu došlo k nečekané chybě" +#: ../nova/utils.py:363 +#, python-format +msgid "Invalid backend: %s" +msgstr "" -#: nova/exception.py:36 +#: ../nova/utils.py:374 #, python-format -msgid "" -"%s\n" -"Command: %s\n" -"Exit code: %s\n" -"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 "Neošetřená výjimka" +msgid "backend %s" +msgstr "" -#: nova/fakerabbit.py:48 +#: ../nova/fakerabbit.py:49 #, python-format -msgid "(%s) publish (key: %s) %s" +msgid "(%(nm)s) publish (key: %(routing_key)s) %(message)s" msgstr "" -#: nova/fakerabbit.py:53 +#: ../nova/fakerabbit.py:54 #, python-format msgid "Publishing to route %s" msgstr "" -#: nova/fakerabbit.py:83 +#: ../nova/fakerabbit.py:84 #, python-format msgid "Declaring queue %s" msgstr "" -#: nova/fakerabbit.py:89 +#: ../nova/fakerabbit.py:90 #, python-format msgid "Declaring exchange %s" msgstr "" -#: nova/fakerabbit.py:95 +#: ../nova/fakerabbit.py:96 #, python-format -msgid "Binding %s to %s with key %s" +msgid "Binding %(queue)s to %(exchange)s with key %(routing_key)s" msgstr "" -#: nova/fakerabbit.py:120 +#: ../nova/fakerabbit.py:121 #, python-format -msgid "Getting from %s: %s" +msgid "Getting from %(queue)s: %(message)s" msgstr "" -#: nova/rpc.py:92 +#: ../nova/virt/xenapi/vm_utils.py:135 ../nova/virt/hyperv.py:171 #, python-format -msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." -msgstr "AMQP server na %s:%d není dosažitelný. Zkusím znovu za %d sekund." +msgid "Created VM %s..." +msgstr "" -#: nova/rpc.py:99 +#: ../nova/virt/xenapi/vm_utils.py:138 #, python-format -msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgid "Created VM %(instance_name)s as %(vm_ref)s." 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 "Znovu připojeno k AMQP frontě" +#: ../nova/virt/xenapi/vm_utils.py:168 +#, python-format +msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... " +msgstr "" -#: nova/rpc.py:125 -msgid "Failed to fetch message from queue" -msgstr "Selhalo získání zprávy z AMQP fronty" +#: ../nova/virt/xenapi/vm_utils.py:171 +#, python-format +msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s." +msgstr "" -#: nova/rpc.py:155 +#: ../nova/virt/xenapi/vm_utils.py:187 #, python-format -msgid "Initing the Adapter Consumer for %s" +msgid "VBD not found in instance %s" msgstr "" -#: nova/rpc.py:170 +#: ../nova/virt/xenapi/vm_utils.py:197 #, python-format -msgid "received %s" -msgstr "získáno: %s" +msgid "Unable to unplug VBD %s" +msgstr "" -#: nova/rpc.py:183 +#: ../nova/virt/xenapi/vm_utils.py:209 #, python-format -msgid "no method for message: %s" -msgstr "Není metoda pro zpracování zprávy: %s" +msgid "Unable to destroy VBD %s" +msgstr "" -#: nova/rpc.py:184 +#: ../nova/virt/xenapi/vm_utils.py:224 #, python-format -msgid "No method for message: %s" -msgstr "Není metoda pro zpracování zprávy: %s" +msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s." +msgstr "" -#: nova/rpc.py:245 +#: ../nova/virt/xenapi/vm_utils.py:227 #, python-format -msgid "Returning exception %s to caller" -msgstr "Volajícímu je vrácena výjimka: %s" +msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s." +msgstr "" -#: nova/rpc.py:286 +#: ../nova/virt/xenapi/vm_utils.py:246 #, python-format -msgid "unpacked context: %s" -msgstr "rozbalený obsah: %s" +msgid "" +"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on " +"%(sr_ref)s." +msgstr "" -#: nova/rpc.py:305 -msgid "Making asynchronous call..." -msgstr "Volání asynchronní funkce..." +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vm_utils.py:258 +#, python-format +msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..." +msgstr "" -#: nova/rpc.py:308 +#: ../nova/virt/xenapi/vm_utils.py:272 #, python-format -msgid "MSG_ID is %s" -msgstr "MSG_ID je %s" +msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s." +msgstr "" -#: nova/rpc.py:356 +#: ../nova/virt/xenapi/vm_utils.py:286 #, python-format -msgid "response %s" -msgstr "odpověď %s" +msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s" +msgstr "" -#: nova/rpc.py:365 +#: ../nova/virt/xenapi/vm_utils.py:327 #, python-format -msgid "topic is %s" +msgid "Size for image %(image)s:%(virtual_size)d" msgstr "" -#: nova/rpc.py:366 +#: ../nova/virt/xenapi/vm_utils.py:332 #, python-format -msgid "message %s" -msgstr "zpráva %s" +msgid "Glance image %s" +msgstr "" -#: nova/service.py:157 +#. we need to invoke a plugin for copying VDI's +#. content into proper path +#: ../nova/virt/xenapi/vm_utils.py:342 #, python-format -msgid "Starting %s node" +msgid "Copying VDI %s to /boot/guest on dom0" msgstr "" -#: nova/service.py:169 -msgid "Service killed that has no database entry" +#: ../nova/virt/xenapi/vm_utils.py:352 +#, python-format +msgid "Kernel/Ramdisk VDI %s destroyed" msgstr "" -#: nova/service.py:190 -msgid "The service database object disappeared, Recreating it." +#: ../nova/virt/xenapi/vm_utils.py:361 +#, python-format +msgid "Asking xapi to fetch %(url)s as %(access)s" msgstr "" -#: nova/service.py:202 -msgid "Recovered model server connection!" +#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402 +#, python-format +msgid "Looking up vdi %s for PV kernel" msgstr "" -#: nova/service.py:208 -msgid "model server went away" +#: ../nova/virt/xenapi/vm_utils.py:397 +#, python-format +msgid "PV Kernel in VDI:%s" msgstr "" -#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#: ../nova/virt/xenapi/vm_utils.py:405 #, python-format -msgid "Data store %s is unreachable. Trying again in %d seconds." +msgid "Running pygrub against %s" msgstr "" -#: nova/service.py:232 nova/twistd.py:232 +#: ../nova/virt/xenapi/vm_utils.py:411 #, python-format -msgid "Serving %s" +msgid "Found Xen kernel %s" msgstr "" -#: nova/service.py:234 nova/twistd.py:264 -msgid "Full set of FLAGS:" +#: ../nova/virt/xenapi/vm_utils.py:413 +msgid "No Xen kernel found. Booting HVM." msgstr "" -#: nova/twistd.py:211 +#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431 #, python-format -msgid "pidfile %s does not exist. Daemon not running?\n" +msgid "duplicate name found: %s" msgstr "" -#: nova/twistd.py:268 +#: ../nova/virt/xenapi/vm_utils.py:442 #, python-format -msgid "Starting %s" +msgid "VDI %s is still available" msgstr "" -#: nova/utils.py:53 +#: ../nova/virt/xenapi/vm_utils.py:463 #, python-format -msgid "Inner Exception: %s" +msgid "(VM_UTILS) xenserver vm state -> |%s|" msgstr "" -#: nova/utils.py:54 +#: ../nova/virt/xenapi/vm_utils.py:465 #, python-format -msgid "Class %s cannot be found" +msgid "(VM_UTILS) xenapi power_state -> |%s|" msgstr "" -#: nova/utils.py:113 +#: ../nova/virt/xenapi/vm_utils.py:525 #, python-format -msgid "Fetching %s" +msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s" msgstr "" -#: nova/utils.py:125 +#: ../nova/virt/xenapi/vm_utils.py:542 #, python-format -msgid "Running cmd (subprocess): %s" +msgid "Re-scanning SR %s" msgstr "" -#: nova/utils.py:138 +#: ../nova/virt/xenapi/vm_utils.py:567 #, python-format -msgid "Result was %s" +msgid "" +"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..." msgstr "" -#: nova/utils.py:171 +#: ../nova/virt/xenapi/vm_utils.py:574 #, python-format -msgid "debug in callback: %s" +msgid "" +"Parent %(parent_uuid)s doesn't match original parent " +"%(original_parent_uuid)s, waiting for coalesce..." msgstr "" -#: nova/utils.py:176 +#: ../nova/virt/xenapi/vm_utils.py:590 #, python-format -msgid "Running %s" +msgid "No VDIs found for VM %s" msgstr "" -#: nova/utils.py:207 +#: ../nova/virt/xenapi/vm_utils.py:594 #, python-format -msgid "Couldn't get IP, using 127.0.0.1 %s" +msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s" msgstr "" -#: nova/utils.py:289 +#: ../nova/virt/xenapi/vm_utils.py:653 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188 #, python-format -msgid "Invalid backend: %s" +msgid "Creating VBD for VDI %s ... " msgstr "" -#: nova/utils.py:300 +#: ../nova/virt/xenapi/vm_utils.py:655 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190 #, python-format -msgid "backend %s" +msgid "Creating VBD for VDI %s done." msgstr "" -#: nova/api/ec2/__init__.py:133 -msgid "Too many failed authentications." +#: ../nova/virt/xenapi/vm_utils.py:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192 +#, python-format +msgid "Plugging VBD %s ... " msgstr "" -#: nova/api/ec2/__init__.py:142 +#: ../nova/virt/xenapi/vm_utils.py:659 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:194 #, python-format -msgid "" -"Access key %s has had %d failed authentications and will be locked out for " -"%d minutes." +msgid "Plugging VBD %s done." msgstr "" -#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#: ../nova/virt/xenapi/vm_utils.py:661 #, python-format -msgid "Authentication Failure: %s" +msgid "VBD %(vbd)s plugged as %(orig_dev)s" msgstr "" -#: nova/api/ec2/__init__.py:190 +#: ../nova/virt/xenapi/vm_utils.py:664 #, python-format -msgid "Authenticated Request For %s:%s)" +msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s" msgstr "" -#: nova/api/ec2/__init__.py:227 +#: ../nova/virt/xenapi/vm_utils.py:668 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:197 #, python-format -msgid "action: %s" +msgid "Destroying VBD for VDI %s ... " msgstr "" -#: nova/api/ec2/__init__.py:229 +#: ../nova/virt/xenapi/vm_utils.py:671 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:200 #, python-format -msgid "arg: %s\t\tval: %s" +msgid "Destroying VBD for VDI %s done." msgstr "" -#: nova/api/ec2/__init__.py:301 -#, python-format -msgid "Unauthorized request for controller=%s and action=%s" +#: ../nova/virt/xenapi/vm_utils.py:683 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211 +msgid "VBD.unplug successful first time." msgstr "" -#: nova/api/ec2/__init__.py:339 -#, python-format -msgid "NotFound raised: %s" +#: ../nova/virt/xenapi/vm_utils.py:688 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216 +msgid "VBD.unplug rejected: retrying..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:692 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220 +msgid "VBD.unplug successful eventually." msgstr "" -#: nova/api/ec2/__init__.py:342 +#: ../nova/virt/xenapi/vm_utils.py:695 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:223 #, python-format -msgid "ApiError raised: %s" +msgid "Ignoring XenAPI.Failure in VBD.unplug: %s" msgstr "" -#: nova/api/ec2/__init__.py:349 +#: ../nova/virt/xenapi/vm_utils.py:704 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:66 #, python-format -msgid "Unexpected error raised: %s" +msgid "Ignoring XenAPI.Failure %s" msgstr "" -#: nova/api/ec2/__init__.py:354 -msgid "An unknown error has occurred. Please try your request again." +#: ../nova/virt/xenapi/vm_utils.py:735 +#, python-format +msgid "" +"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..." msgstr "" -#: nova/api/ec2/admin.py:84 +#: ../nova/virt/xenapi/vm_utils.py:747 #, python-format -msgid "Creating new user: %s" +msgid "Writing partition table %s done." msgstr "" -#: nova/api/ec2/admin.py:92 +#: ../nova/tests/test_rpc.py:89 #, python-format -msgid "Deleting user: %s" +msgid "Nested received %(queue)s, %(value)s" msgstr "" -#: nova/api/ec2/admin.py:114 +#: ../nova/tests/test_rpc.py:95 #, python-format -msgid "Adding role %s to user %s for project %s" +msgid "Nested return %s" msgstr "" -#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#: ../nova/tests/test_rpc.py:120 ../nova/tests/test_rpc.py:126 #, python-format -msgid "Adding sitewide role %s to user %s" +msgid "Received %s" msgstr "" -#: nova/api/ec2/admin.py:122 +#: ../nova/db/sqlalchemy/api.py:44 +msgid "Use of empty request context is deprecated" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:133 #, python-format -msgid "Removing role %s from user %s for project %s" +msgid "No service for id %s" msgstr "" -#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#: ../nova/db/sqlalchemy/api.py:251 #, python-format -msgid "Removing sitewide role %s from user %s" +msgid "No service for %(host)s, %(binary)s" msgstr "" -#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 -msgid "operation must be add or remove" +#: ../nova/db/sqlalchemy/api.py:592 +msgid "No fixed ips defined" msgstr "" -#: nova/api/ec2/admin.py:142 +#: ../nova/db/sqlalchemy/api.py:608 #, python-format -msgid "Getting x509 for user: %s on project: %s" +msgid "No floating ip for address %s" msgstr "" -#: nova/api/ec2/admin.py:159 +#: ../nova/db/sqlalchemy/api.py:629 #, python-format -msgid "Create project %s managed by %s" +msgid "No address for instance %s" msgstr "" -#: nova/api/ec2/admin.py:170 +#: ../nova/db/sqlalchemy/api.py:961 #, python-format -msgid "Delete project: %s" +msgid "no keypair for user %(user_id)s, name %(name)s" msgstr "" -#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156 #, python-format -msgid "Adding user %s to project %s" +msgid "No network for id %s" msgstr "" -#: nova/api/ec2/admin.py:188 +#: ../nova/db/sqlalchemy/api.py:1086 +msgid "No networks defined" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1115 #, python-format -msgid "Removing user %s from project %s" +msgid "No network for bridge %s" msgstr "" -#: nova/api/ec2/apirequest.py:95 +#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142 #, python-format -msgid "Unsupported API request: controller = %s,action = %s" +msgid "No network for instance %s" msgstr "" -#: nova/api/ec2/cloud.py:117 +#: ../nova/db/sqlalchemy/api.py:1277 #, python-format -msgid "Generating root CA: %s" +msgid "Token %s does not exist" msgstr "" -#: nova/api/ec2/cloud.py:277 +#: ../nova/db/sqlalchemy/api.py:1302 #, python-format -msgid "Create key pair %s" +msgid "No quota for project_id %s" msgstr "" -#: nova/api/ec2/cloud.py:285 +#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501 +#: ../nova/api/ec2/__init__.py:323 #, python-format -msgid "Delete key pair %s" +msgid "Volume %s not found" msgstr "" -#: nova/api/ec2/cloud.py:357 +#: ../nova/db/sqlalchemy/api.py:1514 #, python-format -msgid "%s is not a valid ipProtocol" +msgid "No export device found for volume %s" msgstr "" -#: nova/api/ec2/cloud.py:361 -msgid "Invalid port range" +#: ../nova/db/sqlalchemy/api.py:1527 +#, python-format +msgid "No target id found for volume %s" msgstr "" -#: nova/api/ec2/cloud.py:392 +#: ../nova/db/sqlalchemy/api.py:1572 #, python-format -msgid "Revoke security group ingress %s" +msgid "No security group with id %s" msgstr "" -#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 -msgid "No rule for the specified parameters." +#: ../nova/db/sqlalchemy/api.py:1589 +#, python-format +msgid "No security group named %(group_name)s for project: %(project_id)s" msgstr "" -#: nova/api/ec2/cloud.py:421 +#: ../nova/db/sqlalchemy/api.py:1682 #, python-format -msgid "Authorize security group ingress %s" +msgid "No secuity group rule with id %s" msgstr "" -#: nova/api/ec2/cloud.py:432 +#: ../nova/db/sqlalchemy/api.py:1756 #, python-format -msgid "This rule already exists in group %s" +msgid "No user for id %s" msgstr "" -#: nova/api/ec2/cloud.py:460 +#: ../nova/db/sqlalchemy/api.py:1772 #, python-format -msgid "Create Security Group %s" +msgid "No user for access key %s" msgstr "" -#: nova/api/ec2/cloud.py:463 +#: ../nova/db/sqlalchemy/api.py:1834 #, python-format -msgid "group %s already exists" +msgid "No project with id %s" msgstr "" -#: nova/api/ec2/cloud.py:475 +#: ../nova/db/sqlalchemy/api.py:1979 #, python-format -msgid "Delete security group %s" +msgid "No console pool with id %(pool_id)s" msgstr "" -#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#: ../nova/db/sqlalchemy/api.py:1996 #, python-format -msgid "Get console output for instance %s" +msgid "" +"No console pool of type %(console_type)s for compute host %(compute_host)s " +"on proxy host %(host)s" msgstr "" -#: nova/api/ec2/cloud.py:543 +#: ../nova/db/sqlalchemy/api.py:2035 #, python-format -msgid "Create volume of %s GB" +msgid "No console for instance %(instance_id)s in pool %(pool_id)s" msgstr "" -#: nova/api/ec2/cloud.py:567 +#: ../nova/db/sqlalchemy/api.py:2057 #, python-format -msgid "Attach volume %s to instacne %s at %s" +msgid "on instance %s" msgstr "" -#: nova/api/ec2/cloud.py:579 +#: ../nova/db/sqlalchemy/api.py:2058 #, python-format -msgid "Detach volume %s" +msgid "No console with id %(console_id)s %(idesc)s" msgstr "" -#: nova/api/ec2/cloud.py:686 -msgid "Allocate address" +#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097 +#, python-format +msgid "No zone with id %(zone_id)s" msgstr "" -#: nova/api/ec2/cloud.py:691 +#: ../nova/virt/libvirt_conn.py:160 #, python-format -msgid "Release address %s" +msgid "Checking state of %s" msgstr "" -#: nova/api/ec2/cloud.py:696 +#: ../nova/virt/libvirt_conn.py:165 #, python-format -msgid "Associate address %s to instance %s" +msgid "Current state of %(name)s was %(state)s." msgstr "" -#: nova/api/ec2/cloud.py:703 +#: ../nova/virt/libvirt_conn.py:183 #, python-format -msgid "Disassociate address %s" +msgid "Connecting to libvirt: %s" msgstr "" -#: nova/api/ec2/cloud.py:730 -msgid "Going to start terminating instances" +#: ../nova/virt/libvirt_conn.py:196 +msgid "Connection to libvirt broke" msgstr "" -#: nova/api/ec2/cloud.py:738 +#: ../nova/virt/libvirt_conn.py:258 #, python-format -msgid "Reboot instance %r" +msgid "instance %(instance_name)s: deleting instance files %(target)s" msgstr "" -#: nova/api/ec2/cloud.py:775 +#: ../nova/virt/libvirt_conn.py:283 #, python-format -msgid "De-registering image %s" +msgid "Invalid device path %s" msgstr "" -#: nova/api/ec2/cloud.py:783 +#: ../nova/virt/libvirt_conn.py:313 #, python-format -msgid "Registered image %s with id %s" +msgid "No disk at %s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:320 +msgid "Instance snapshotting is not supported for libvirtat this time" msgstr "" -#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#: ../nova/virt/libvirt_conn.py:336 #, python-format -msgid "attribute not supported: %s" +msgid "instance %s: rebooted" msgstr "" -#: nova/api/ec2/cloud.py:794 +#: ../nova/virt/libvirt_conn.py:339 #, python-format -msgid "invalid id: %s" +msgid "_wait_for_reboot failed: %s" msgstr "" -#: nova/api/ec2/cloud.py:807 -msgid "user or group not specified" +#: ../nova/virt/libvirt_conn.py:382 +#, python-format +msgid "instance %s: rescued" msgstr "" -#: nova/api/ec2/cloud.py:809 -msgid "only group \"all\" is supported" +#: ../nova/virt/libvirt_conn.py:385 +#, python-format +msgid "_wait_for_rescue failed: %s" msgstr "" -#: nova/api/ec2/cloud.py:811 -msgid "operation_type must be add or remove" +#: ../nova/virt/libvirt_conn.py:411 +#, python-format +msgid "instance %s: is running" msgstr "" -#: nova/api/ec2/cloud.py:812 +#: ../nova/virt/libvirt_conn.py:422 #, python-format -msgid "Updating image %s publicity" +msgid "instance %s: booted" msgstr "" -#: nova/api/ec2/metadatarequesthandler.py:75 +#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186 #, python-format -msgid "Failed to get metadata for ip: %s" +msgid "instance %s: failed to boot" msgstr "" -#: nova/api/openstack/__init__.py:70 +#: ../nova/virt/libvirt_conn.py:436 #, python-format -msgid "Caught error: %s" +msgid "virsh said: %r" msgstr "" -#: nova/api/openstack/__init__.py:86 -msgid "Including admin operations in API." +#: ../nova/virt/libvirt_conn.py:440 +msgid "cool, it's a device" msgstr "" -#: nova/api/openstack/servers.py:184 +#: ../nova/virt/libvirt_conn.py:448 #, python-format -msgid "Compute.api::lock %s" +msgid "data: %(data)r, fpath: %(fpath)r" msgstr "" -#: nova/api/openstack/servers.py:199 +#: ../nova/virt/libvirt_conn.py:456 #, python-format -msgid "Compute.api::unlock %s" +msgid "Contents of file %(fpath)s: %(contents)r" msgstr "" -#: nova/api/openstack/servers.py:213 +#: ../nova/virt/libvirt_conn.py:489 +msgid "Unable to find an open port" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:563 #, python-format -msgid "Compute.api::get_lock %s" +msgid "instance %s: Creating image" msgstr "" -#: nova/api/openstack/servers.py:224 +#: ../nova/virt/libvirt_conn.py:646 #, python-format -msgid "Compute.api::pause %s" +msgid "instance %(inst_name)s: injecting key into image %(img_id)s" msgstr "" -#: nova/api/openstack/servers.py:235 +#: ../nova/virt/libvirt_conn.py:649 #, python-format -msgid "Compute.api::unpause %s" +msgid "instance %(inst_name)s: injecting net into image %(img_id)s" msgstr "" -#: nova/api/openstack/servers.py:246 +#. This could be a windows image, or a vmdk format disk +#: ../nova/virt/libvirt_conn.py:657 #, python-format -msgid "compute.api::suspend %s" +msgid "" +"instance %(inst_name)s: ignoring error injecting data into image %(img_id)s " +"(%(e)s)" msgstr "" -#: nova/api/openstack/servers.py:257 +#. TODO(termie): cache? +#: ../nova/virt/libvirt_conn.py:665 #, python-format -msgid "compute.api::resume %s" +msgid "instance %s: starting toXML method" msgstr "" -#: nova/auth/dbdriver.py:84 +#: ../nova/virt/libvirt_conn.py:732 #, python-format -msgid "User %s already exists" +msgid "instance %s: finished toXML method" msgstr "" -#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#: ../nova/virt/libvirt_conn.py:751 +msgid "diagnostics are not supported for libvirt" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:1225 #, python-format -msgid "Project can't be created because manager %s doesn't exist" +msgid "Attempted to unfilter instance %s which is not filtered" msgstr "" -#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#: ../nova/api/ec2/metadatarequesthandler.py:76 #, python-format -msgid "Project can't be created because project %s already exists" +msgid "Failed to get metadata for ip: %s" +msgstr "" + +#: ../nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" msgstr "" -#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#: ../nova/network/api.py:39 #, python-format -msgid "Project can't be modified because manager %s doesn't exist" +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/auth/dbdriver.py:245 +#: ../nova/tests/test_volume.py:162 #, python-format -msgid "User \"%s\" not found" +msgid "Target %s allocated" msgstr "" -#: nova/auth/dbdriver.py:248 +#: ../nova/virt/images.py:70 #, python-format -msgid "Project \"%s\" not found" +msgid "Finished retreving %(url)s -- placed in %(path)s" msgstr "" -#: nova/auth/fakeldap.py:33 -msgid "Attempted to instantiate singleton" +#: ../nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" msgstr "" -#: nova/auth/ldapdriver.py:181 -#, python-format -msgid "LDAP object for %s doesn't exist" +#: ../nova/console/manager.py:70 +msgid "Adding console" msgstr "" -#: nova/auth/ldapdriver.py:218 +#: ../nova/console/manager.py:90 #, python-format -msgid "Project can't be created because user %s doesn't exist" +msgid "Tried to remove non-existant console %(console_id)s." +msgstr "" + +#: ../nova/api/direct.py:149 +msgid "not available" msgstr "" -#: nova/auth/ldapdriver.py:478 +#: ../nova/api/ec2/cloud.py:62 #, python-format -msgid "User %s is already a member of the group %s" +msgid "The key_pair %s already exists" msgstr "" -#: nova/auth/ldapdriver.py:507 +#. TODO(vish): Do this with M2Crypto instead +#: ../nova/api/ec2/cloud.py:118 #, python-format -msgid "" -"Attempted to remove the last member of a group. Deleting the group at %s " -"instead." +msgid "Generating root CA: %s" msgstr "" -#: nova/auth/ldapdriver.py:528 +#: ../nova/api/ec2/cloud.py:303 #, python-format -msgid "Group at dn %s doesn't exist" +msgid "Create key pair %s" msgstr "" -#: nova/auth/manager.py:259 +#: ../nova/api/ec2/cloud.py:311 #, python-format -msgid "Looking up user: %r" +msgid "Delete key pair %s" msgstr "" -#: nova/auth/manager.py:263 +#: ../nova/api/ec2/cloud.py:386 #, python-format -msgid "Failed authorization for access key %s" +msgid "%s is not a valid ipProtocol" +msgstr "" + +#: ../nova/api/ec2/cloud.py:390 +msgid "Invalid port range" msgstr "" -#: nova/auth/manager.py:264 +#: ../nova/api/ec2/cloud.py:421 #, python-format -msgid "No user found for access key %s" +msgid "Revoke security group ingress %s" msgstr "" -#: nova/auth/manager.py:270 -#, python-format -msgid "Using project name = user name (%s)" +#: ../nova/api/ec2/cloud.py:430 ../nova/api/ec2/cloud.py:459 +msgid "Not enough parameters to build a valid rule." msgstr "" -#: nova/auth/manager.py:275 -#, python-format -msgid "failed authorization: no project named %s (user=%s)" +#: ../nova/api/ec2/cloud.py:443 +msgid "No rule for the specified parameters." msgstr "" -#: nova/auth/manager.py:277 +#: ../nova/api/ec2/cloud.py:450 #, python-format -msgid "No project called %s could be found" +msgid "Authorize security group ingress %s" msgstr "" -#: nova/auth/manager.py:281 +#: ../nova/api/ec2/cloud.py:464 #, python-format -msgid "Failed authorization: user %s not admin and not member of project %s" +msgid "This rule already exists in group %s" msgstr "" -#: nova/auth/manager.py:283 +#: ../nova/api/ec2/cloud.py:492 #, python-format -msgid "User %s is not a member of project %s" +msgid "Create Security Group %s" msgstr "" -#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#: ../nova/api/ec2/cloud.py:495 #, python-format -msgid "Invalid signature for user %s" -msgstr "" - -#: nova/auth/manager.py:293 nova/auth/manager.py:304 -msgid "Signature does not match" +msgid "group %s already exists" msgstr "" -#: nova/auth/manager.py:374 -msgid "Must specify project" +#: ../nova/api/ec2/cloud.py:507 +#, python-format +msgid "Delete security group %s" msgstr "" -#: nova/auth/manager.py:408 +#: ../nova/api/ec2/cloud.py:584 #, python-format -msgid "The %s role can not be found" +msgid "Create volume of %s GB" msgstr "" -#: nova/auth/manager.py:410 +#: ../nova/api/ec2/cloud.py:612 #, python-format -msgid "The %s role is global only" +msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s" msgstr "" -#: nova/auth/manager.py:412 +#: ../nova/api/ec2/cloud.py:629 #, python-format -msgid "Adding role %s to user %s in project %s" +msgid "Detach volume %s" msgstr "" -#: nova/auth/manager.py:438 -#, python-format -msgid "Removing role %s from user %s on project %s" +#: ../nova/api/ec2/cloud.py:761 +msgid "Allocate address" msgstr "" -#: nova/auth/manager.py:505 +#: ../nova/api/ec2/cloud.py:766 #, python-format -msgid "Created project %s with manager %s" +msgid "Release address %s" msgstr "" -#: nova/auth/manager.py:523 +#: ../nova/api/ec2/cloud.py:771 #, python-format -msgid "modifying project %s" +msgid "Associate address %(public_ip)s to instance %(instance_id)s" msgstr "" -#: nova/auth/manager.py:553 +#: ../nova/api/ec2/cloud.py:780 #, python-format -msgid "Remove user %s from project %s" +msgid "Disassociate address %s" msgstr "" -#: nova/auth/manager.py:581 -#, python-format -msgid "Deleting project %s" +#: ../nova/api/ec2/cloud.py:807 +msgid "Going to start terminating instances" msgstr "" -#: nova/auth/manager.py:637 +#: ../nova/api/ec2/cloud.py:815 #, python-format -msgid "Created user %s (admin: %r)" +msgid "Reboot instance %r" msgstr "" -#: nova/auth/manager.py:645 +#: ../nova/api/ec2/cloud.py:867 #, python-format -msgid "Deleting user %s" +msgid "De-registering image %s" msgstr "" -#: nova/auth/manager.py:655 +#: ../nova/api/ec2/cloud.py:875 #, python-format -msgid "Access Key change for user %s" +msgid "Registered image %(image_location)s with id %(image_id)s" msgstr "" -#: nova/auth/manager.py:657 +#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900 #, python-format -msgid "Secret Key change for user %s" +msgid "attribute not supported: %s" msgstr "" -#: nova/auth/manager.py:659 +#: ../nova/api/ec2/cloud.py:890 #, python-format -msgid "Admin status set to %r for user %s" +msgid "invalid id: %s" msgstr "" -#: nova/auth/manager.py:708 -#, python-format -msgid "No vpn data for project %s" +#: ../nova/api/ec2/cloud.py:903 +msgid "user or group not specified" msgstr "" -#: nova/cloudpipe/pipelib.py:45 -msgid "Template for script to run on cloudpipe instance boot" +#: ../nova/api/ec2/cloud.py:905 +msgid "only group \"all\" is supported" msgstr "" -#: nova/cloudpipe/pipelib.py:48 -msgid "Network to push into openvpn config" +#: ../nova/api/ec2/cloud.py:907 +msgid "operation_type must be add or remove" msgstr "" -#: nova/cloudpipe/pipelib.py:51 -msgid "Netmask to push into openvpn config" +#: ../nova/api/ec2/cloud.py:908 +#, python-format +msgid "Updating image %s publicity" msgstr "" -#: nova/cloudpipe/pipelib.py:97 +#: ../bin/nova-api.py:52 #, python-format -msgid "Launching VPN for %s" +msgid "Using paste.deploy config at: %s" msgstr "" -#: nova/compute/api.py:67 +#: ../bin/nova-api.py:57 #, python-format -msgid "Instance %d was not found in get_network_topic" +msgid "No paste configuration for app: %s" msgstr "" -#: nova/compute/api.py:73 +#: ../bin/nova-api.py:59 #, python-format -msgid "Instance %d has no host" +msgid "" +"App Config: %(api)s\n" +"%(config)r" msgstr "" -#: nova/compute/api.py:92 +#: ../bin/nova-api.py:64 #, python-format -msgid "Quota exceeeded for %s, tried to run %s instances" +msgid "Running %s API" msgstr "" -#: nova/compute/api.py:94 +#: ../bin/nova-api.py:69 #, python-format -msgid "" -"Instance quota exceeded. You can only run %s more instances of this type." +msgid "No known API applications configured in %s." msgstr "" -#: nova/compute/api.py:109 -msgid "Creating a raw instance" +#: ../bin/nova-api.py:83 +#, python-format +msgid "Starting nova-api node (version %s)" msgstr "" -#: nova/compute/api.py:156 +#: ../bin/nova-api.py:89 #, python-format -msgid "Going to run %s instances..." +msgid "No paste configuration found for: %s" msgstr "" -#: nova/compute/api.py:180 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84 #, python-format -msgid "Casting to scheduler for %s/%s's instance %s" +msgid "Argument %(key)s value %(value)s is too short." msgstr "" -#: nova/compute/api.py:279 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89 #, python-format -msgid "Going to try and terminate %s" +msgid "Argument %(key)s value %(value)s contains invalid characters." msgstr "" -#: nova/compute/api.py:283 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94 #, python-format -msgid "Instance %d was not found during terminate" +msgid "Argument %(key)s value %(value)s starts with a hyphen." msgstr "" -#: nova/compute/api.py:288 +#: ../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 "Instance %d is already being terminated" +msgid "Argument %s is required." msgstr "" -#: nova/compute/api.py:450 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117 #, python-format -msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgid "" +"Argument %(key)s may not take value %(value)s. Valid values are ['true', " +"'false']." msgstr "" -#: nova/compute/api.py:465 -msgid "Volume isn't attached to anything!" +#: ../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/compute/disk.py:71 +#: ../nova/virt/xenapi/vmops.py:67 #, python-format -msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgid "Attempted to create non-unique name %s" msgstr "" -#: nova/compute/disk.py:75 +#: ../nova/virt/xenapi/vmops.py:73 #, python-format -msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgid "instance %(name)s: not enough free memory" msgstr "" -#: nova/compute/disk.py:128 +#: ../nova/virt/xenapi/vmops.py:148 #, python-format -msgid "Could not attach image to loopback: %s" +msgid "Starting VM %s..." msgstr "" -#: nova/compute/disk.py:136 +#: ../nova/virt/xenapi/vmops.py:151 #, python-format -msgid "Failed to load partition: %s" +msgid "Spawning VM %(instance_name)s created %(vm_ref)s." msgstr "" -#: nova/compute/disk.py:158 +#: ../nova/virt/xenapi/vmops.py:162 #, python-format -msgid "Failed to mount filesystem: %s" +msgid "Invalid value for onset_files: '%s'" msgstr "" -#: nova/compute/instance_types.py:41 +#: ../nova/virt/xenapi/vmops.py:167 #, python-format -msgid "Unknown instance type: %s" +msgid "Injecting file path: '%s'" msgstr "" -#: nova/compute/manager.py:69 +#: ../nova/virt/xenapi/vmops.py:180 #, python-format -msgid "check_instance_lock: decorating: |%s|" +msgid "Instance %s: booted" msgstr "" -#: nova/compute/manager.py:71 +#: ../nova/virt/xenapi/vmops.py:232 #, python-format -msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgid "Instance not present %s" msgstr "" -#: nova/compute/manager.py:75 +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vmops.py:261 #, python-format -msgid "check_instance_lock: locked: |%s|" +msgid "Starting snapshot for VM %s" msgstr "" -#: nova/compute/manager.py:77 +#: ../nova/virt/xenapi/vmops.py:269 #, python-format -msgid "check_instance_lock: admin: |%s|" +msgid "Unable to Snapshot %(vm_ref)s: %(exc)s" msgstr "" -#: nova/compute/manager.py:82 +#: ../nova/virt/xenapi/vmops.py:280 #, python-format -msgid "check_instance_lock: executing: |%s|" +msgid "Finished snapshot and upload for VM %s" msgstr "" -#: nova/compute/manager.py:86 +#: ../nova/virt/xenapi/vmops.py:356 #, python-format -msgid "check_instance_lock: not executing |%s|" +msgid "VM %(vm)s already halted, skipping shutdown..." msgstr "" -#: nova/compute/manager.py:157 -msgid "Instance has already been created" +#: ../nova/virt/xenapi/vmops.py:389 +msgid "Removing kernel/ramdisk files" msgstr "" -#: nova/compute/manager.py:158 -#, python-format -msgid "instance %s: starting..." +#: ../nova/virt/xenapi/vmops.py:399 +msgid "kernel/ramdisk files removed" msgstr "" -#: nova/compute/manager.py:197 +#: ../nova/virt/xenapi/vmops.py:561 #, python-format -msgid "instance %s: Failed to spawn" +msgid "" +"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#: ../nova/virt/xenapi/vmops.py:564 #, python-format -msgid "Terminating instance %s" +msgid "" +"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM " +"id=%(instance_id)s; args=%(strargs)s" msgstr "" -#: nova/compute/manager.py:217 +#: ../nova/virt/xenapi/vmops.py:569 #, python-format -msgid "Disassociating address %s" +msgid "" +"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/manager.py:230 +#: ../nova/virt/xenapi/vmops.py:760 #, python-format -msgid "Deallocating address %s" +msgid "OpenSSL error: %s" msgstr "" -#: nova/compute/manager.py:243 +#: ../nova/tests/test_compute.py:148 #, python-format -msgid "trying to destroy already destroyed instance: %s" +msgid "Running instances: %s" msgstr "" -#: nova/compute/manager.py:257 +#: ../nova/tests/test_compute.py:154 #, python-format -msgid "Rebooting instance %s" +msgid "After terminating instances: %s" msgstr "" -#: nova/compute/manager.py:260 -#, python-format -msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +#: ../nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" msgstr "" -#: nova/compute/manager.py:286 -#, python-format -msgid "instance %s: snapshotting" +#: ../nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" msgstr "" -#: nova/compute/manager.py:289 -#, python-format -msgid "" -"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +#: ../nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" msgstr "" -#: nova/compute/manager.py:301 +#: ../nova/cloudpipe/pipelib.py:97 #, python-format -msgid "instance %s: rescuing" +msgid "Launching VPN for %s" msgstr "" -#: nova/compute/manager.py:316 -#, python-format -msgid "instance %s: unrescuing" +#: ../nova/db/sqlalchemy/migration.py:35 +msgid "python-migrate is not installed. Exiting." msgstr "" -#: nova/compute/manager.py:335 +#: ../nova/image/s3.py:99 #, python-format -msgid "instance %s: pausing" +msgid "Image %s could not be found" msgstr "" -#: nova/compute/manager.py:352 -#, python-format -msgid "instance %s: unpausing" +#: ../nova/api/ec2/__init__.py:121 +msgid "Too many failed authentications." msgstr "" -#: nova/compute/manager.py:369 +#: ../nova/api/ec2/__init__.py:131 #, python-format -msgid "instance %s: retrieving diagnostics" +msgid "" +"Access key %(access_key)s has had %(failures)d failed authentications and " +"will be locked out for %(lock_mins)d minutes." msgstr "" -#: nova/compute/manager.py:382 +#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140 #, python-format -msgid "instance %s: suspending" +msgid "Authentication Failure: %s" msgstr "" -#: nova/compute/manager.py:401 +#: ../nova/api/ec2/__init__.py:182 #, python-format -msgid "instance %s: resuming" +msgid "Authenticated Request For %(uname)s:%(pname)s)" msgstr "" -#: nova/compute/manager.py:420 +#: ../nova/api/ec2/__init__.py:207 #, python-format -msgid "instance %s: locking" +msgid "action: %s" msgstr "" -#: nova/compute/manager.py:432 +#: ../nova/api/ec2/__init__.py:209 #, python-format -msgid "instance %s: unlocking" +msgid "arg: %(key)s\t\tval: %(value)s" msgstr "" -#: nova/compute/manager.py:442 +#: ../nova/api/ec2/__init__.py:281 #, python-format -msgid "instance %s: getting locked state" +msgid "" +"Unauthorized request for controller=%(controller)s and action=%(action)s" msgstr "" -#: nova/compute/manager.py:462 +#: ../nova/api/ec2/__init__.py:314 #, python-format -msgid "instance %s: attaching volume %s to %s" +msgid "InstanceNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:478 +#: ../nova/api/ec2/__init__.py:320 #, python-format -msgid "instance %s: attach failed %s, removing" +msgid "VolumeNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:493 +#: ../nova/api/ec2/__init__.py:326 #, python-format -msgid "Detach volume %s from mountpoint %s on instance %s" +msgid "NotFound raised: %s" msgstr "" -#: nova/compute/manager.py:497 +#: ../nova/api/ec2/__init__.py:329 #, python-format -msgid "Detaching volume from unknown instance %s" +msgid "ApiError raised: %s" msgstr "" -#: nova/compute/monitor.py:259 +#: ../nova/api/ec2/__init__.py:338 #, python-format -msgid "updating %s..." +msgid "Unexpected error raised: %s" msgstr "" -#: nova/compute/monitor.py:289 -msgid "unexpected error during update" +#: ../nova/api/ec2/__init__.py:343 +msgid "An unknown error has occurred. Please try your request again." msgstr "" -#: nova/compute/monitor.py:355 +#: ../nova/auth/dbdriver.py:84 #, python-format -msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgid "User %s already exists" msgstr "" -#: nova/compute/monitor.py:377 +#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232 #, python-format -msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgid "Project can't be created because manager %s doesn't exist" msgstr "" -#: nova/compute/monitor.py:412 -msgid "unexpected exception getting connection" +#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243 +#, python-format +msgid "Project can't be created because user %s doesn't exist" msgstr "" -#: nova/compute/monitor.py:427 +#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229 #, python-format -msgid "Found instance: %s" +msgid "Project can't be created because project %s already exists" msgstr "" -#: nova/db/sqlalchemy/api.py:43 -msgid "Use of empty request context is deprecated" +#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268 +#, python-format +msgid "Project can't be modified because manager %s doesn't exist" msgstr "" -#: nova/db/sqlalchemy/api.py:132 +#: ../nova/auth/dbdriver.py:245 #, python-format -msgid "No service for id %s" +msgid "User \"%s\" not found" msgstr "" -#: nova/db/sqlalchemy/api.py:229 +#: ../nova/auth/dbdriver.py:248 #, python-format -msgid "No service for %s, %s" +msgid "Project \"%s\" not found" msgstr "" -#: nova/db/sqlalchemy/api.py:574 -#, python-format -msgid "No floating ip for address %s" +#: ../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/db/sqlalchemy/api.py:668 +#: ../nova/virt/xenapi_conn.py:311 #, python-format -msgid "No instance for id %s" +msgid "Task [%(name)s] %(task)s status: success %(result)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 +#: ../nova/virt/xenapi_conn.py:317 #, python-format -msgid "Instance %s not found" +msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s" msgstr "" -#: nova/db/sqlalchemy/api.py:891 +#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344 #, python-format -msgid "no keypair for user %s, name %s" +msgid "Got exception: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#: ../nova/compute/monitor.py:259 #, python-format -msgid "No network for id %s" +msgid "updating %s..." msgstr "" -#: nova/db/sqlalchemy/api.py:1036 -#, python-format -msgid "No network for bridge %s" +#: ../nova/compute/monitor.py:289 +msgid "unexpected error during update" msgstr "" -#: nova/db/sqlalchemy/api.py:1050 +#: ../nova/compute/monitor.py:356 #, python-format -msgid "No network for instance %s" +msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\"" msgstr "" -#: nova/db/sqlalchemy/api.py:1180 +#: ../nova/compute/monitor.py:379 #, python-format -msgid "Token %s does not exist" +msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\"" msgstr "" -#: nova/db/sqlalchemy/api.py:1205 -#, python-format -msgid "No quota for project_id %s" +#: ../nova/compute/monitor.py:414 +msgid "unexpected exception getting connection" msgstr "" -#: nova/db/sqlalchemy/api.py:1356 +#: ../nova/compute/monitor.py:429 #, python-format -msgid "No volume for id %s" +msgid "Found instance: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1401 +#: ../nova/volume/san.py:67 #, python-format -msgid "Volume %s not found" +msgid "Could not find iSCSI export for volume %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1413 +#: ../nova/api/ec2/apirequest.py:100 #, python-format -msgid "No export device found for volume %s" +msgid "" +"Unsupported API request: controller = %(controller)s, action = %(action)s" msgstr "" -#: nova/db/sqlalchemy/api.py:1426 +#: ../nova/api/openstack/__init__.py:55 #, python-format -msgid "No target id found for volume %s" +msgid "Caught error: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1471 -#, python-format -msgid "No security group with id %s" +#: ../nova/api/openstack/__init__.py:76 +msgid "Including admin operations in API." msgstr "" -#: nova/db/sqlalchemy/api.py:1488 -#, python-format -msgid "No security group named %s for project: %s" +#: ../nova/console/xvp.py:99 +msgid "Rebuilding xvp conf" msgstr "" -#: nova/db/sqlalchemy/api.py:1576 +#: ../nova/console/xvp.py:116 #, python-format -msgid "No secuity group rule with id %s" +msgid "Re-wrote %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1650 -#, python-format -msgid "No user for id %s" +#: ../nova/console/xvp.py:121 +msgid "Stopping xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1666 -#, python-format -msgid "No user for access key %s" +#: ../nova/console/xvp.py:134 +msgid "Starting xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1728 +#: ../nova/console/xvp.py:141 #, python-format -msgid "No project with id %s" +msgid "Error starting xvp: %s" msgstr "" -#: nova/image/glance.py:78 -#, python-format -msgid "Parallax returned HTTP error %d from request for /images" +#: ../nova/console/xvp.py:144 +msgid "Restarting xvp" msgstr "" -#: nova/image/glance.py:97 -#, python-format -msgid "Parallax returned HTTP error %d from request for /images/detail" +#: ../nova/console/xvp.py:146 +msgid "xvp not running..." msgstr "" -#: nova/image/s3.py:82 -#, python-format -msgid "Image %s could not be found" +#: ../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 "" -#: nova/network/api.py:39 -#, python-format -msgid "Quota exceeeded for %s, tried to allocate address" +#: ../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 "" -#: nova/network/api.py:42 -msgid "Address quota exceeded. You cannot allocate any more addresses" +#: ../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/network/linux_net.py:176 -#, python-format -msgid "Starting VLAN inteface %s" +#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536 +msgid "network" msgstr "" -#: nova/network/linux_net.py:186 -#, python-format -msgid "Starting Bridge interface for %s" +#: ../bin/nova-manage.py:448 +msgid "IP address" msgstr "" -#: nova/network/linux_net.py:254 -#, python-format -msgid "Hupping dnsmasq threw %s" +#: ../bin/nova-manage.py:449 +msgid "MAC address" msgstr "" -#: nova/network/linux_net.py:256 -#, python-format -msgid "Pid %d is stale, relaunching dnsmasq" +#: ../bin/nova-manage.py:450 +msgid "hostname" msgstr "" -#: nova/network/linux_net.py:334 -#, python-format -msgid "Killing dnsmasq threw %s" +#: ../bin/nova-manage.py:451 +msgid "host" msgstr "" -#: nova/network/manager.py:135 -msgid "setting network host" +#: ../bin/nova-manage.py:537 +msgid "netmask" msgstr "" -#: nova/network/manager.py:190 -#, python-format -msgid "Leasing IP %s" +#: ../bin/nova-manage.py:538 +msgid "start address" msgstr "" -#: nova/network/manager.py:194 +#: ../nova/virt/disk.py:69 #, python-format -msgid "IP %s leased that isn't associated" +msgid "Failed to load partition: %s" msgstr "" -#: nova/network/manager.py:197 +#: ../nova/virt/disk.py:91 #, python-format -msgid "IP %s leased to bad mac %s vs %s" +msgid "Failed to mount filesystem: %s" msgstr "" -#: nova/network/manager.py:205 +#: ../nova/virt/disk.py:124 #, python-format -msgid "IP %s leased that was already deallocated" +msgid "nbd device %s did not show up" msgstr "" -#: nova/network/manager.py:214 +#: ../nova/virt/disk.py:128 #, python-format -msgid "IP %s released that isn't associated" +msgid "Could not attach image to loopback: %s" msgstr "" -#: nova/network/manager.py:217 -#, python-format -msgid "IP %s released from bad mac %s vs %s" +#: ../nova/virt/disk.py:151 +msgid "No free nbd devices" msgstr "" -#: nova/network/manager.py:220 +#: ../doc/ext/nova_todo.py:46 #, python-format -msgid "IP %s released that was not leased" +msgid "%(filename)s, line %(line_info)d" msgstr "" -#: nova/network/manager.py:442 -#, python-format -msgid "Dissassociated %s stale fixed ip(s)" +#. FIXME(chiradeep): implement this +#: ../nova/virt/hyperv.py:118 +msgid "In init host" msgstr "" -#: nova/objectstore/handler.py:106 +#: ../nova/virt/hyperv.py:131 #, python-format -msgid "Unknown S3 value type %r" +msgid "Attempt to create duplicate vm %s" msgstr "" -#: nova/objectstore/handler.py:137 -msgid "Authenticated request" +#: ../nova/virt/hyperv.py:148 +#, python-format +msgid "Starting VM %s " msgstr "" -#: nova/objectstore/handler.py:182 -msgid "List of buckets requested" +#: ../nova/virt/hyperv.py:150 +#, python-format +msgid "Started VM %s " msgstr "" -#: nova/objectstore/handler.py:209 +#: ../nova/virt/hyperv.py:152 #, python-format -msgid "List keys for bucket %s" +msgid "spawn vm failed: %s" msgstr "" -#: nova/objectstore/handler.py:217 +#: ../nova/virt/hyperv.py:169 #, python-format -msgid "Unauthorized attempt to access bucket %s" +msgid "Failed to create VM %s" msgstr "" -#: nova/objectstore/handler.py:235 +#: ../nova/virt/hyperv.py:188 #, python-format -msgid "Creating bucket %s" +msgid "Set memory for vm %s..." msgstr "" -#: nova/objectstore/handler.py:245 +#: ../nova/virt/hyperv.py:198 #, python-format -msgid "Deleting bucket %s" +msgid "Set vcpus for vm %s..." msgstr "" -#: nova/objectstore/handler.py:249 +#: ../nova/virt/hyperv.py:202 #, python-format -msgid "Unauthorized attempt to delete bucket %s" +msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s" msgstr "" -#: nova/objectstore/handler.py:271 +#: ../nova/virt/hyperv.py:227 #, python-format -msgid "Getting object: %s / %s" +msgid "Failed to add diskdrive to VM %s" msgstr "" -#: nova/objectstore/handler.py:274 +#: ../nova/virt/hyperv.py:230 #, python-format -msgid "Unauthorized attempt to get object %s from bucket %s" +msgid "New disk drive path is %s" msgstr "" -#: nova/objectstore/handler.py:292 +#: ../nova/virt/hyperv.py:247 #, python-format -msgid "Putting object: %s / %s" +msgid "Failed to add vhd file to VM %s" msgstr "" -#: nova/objectstore/handler.py:295 +#: ../nova/virt/hyperv.py:249 #, python-format -msgid "Unauthorized attempt to upload object %s to bucket %s" +msgid "Created disk for %s" msgstr "" -#: nova/objectstore/handler.py:314 +#: ../nova/virt/hyperv.py:253 #, python-format -msgid "Deleting object: %s / %s" +msgid "Creating nic for %s " +msgstr "" + +#: ../nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" msgstr "" -#: nova/objectstore/handler.py:393 +#: ../nova/virt/hyperv.py:273 #, python-format -msgid "Not authorized to upload image: invalid directory %s" +msgid "Failed creating port for %s" msgstr "" -#: nova/objectstore/handler.py:401 +#: ../nova/virt/hyperv.py:276 #, python-format -msgid "Not authorized to upload image: unauthorized bucket %s" +msgid "Created switch port %(vm_name)s on switch %(ext_path)s" msgstr "" -#: nova/objectstore/handler.py:406 +#: ../nova/virt/hyperv.py:286 #, python-format -msgid "Starting image upload: %s" +msgid "Failed to add nic to VM %s" msgstr "" -#: nova/objectstore/handler.py:420 +#: ../nova/virt/hyperv.py:288 #, python-format -msgid "Not authorized to update attributes of image %s" +msgid "Created nic for %s " msgstr "" -#: nova/objectstore/handler.py:428 +#: ../nova/virt/hyperv.py:321 #, python-format -msgid "Toggling publicity flag of image %s %r" +msgid "WMI job failed: %s" msgstr "" -#: nova/objectstore/handler.py:433 +#: ../nova/virt/hyperv.py:325 #, python-format -msgid "Updating user fields on image %s" +msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s " msgstr "" -#: nova/objectstore/handler.py:447 +#: ../nova/virt/hyperv.py:361 #, python-format -msgid "Unauthorized attempt to delete image %s" +msgid "Got request to destroy vm %s" msgstr "" -#: nova/objectstore/handler.py:452 +#: ../nova/virt/hyperv.py:386 #, python-format -msgid "Deleted image: %s" +msgid "Failed to destroy vm %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" +#: ../nova/virt/hyperv.py:393 +#, python-format +msgid "Del: disk %(vhdfile)s vm %(instance_name)s" msgstr "" -#: nova/scheduler/driver.py:66 -msgid "Must implement a fallback schedule" +#: ../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/scheduler/manager.py:69 +#: ../nova/virt/hyperv.py:451 #, python-format -msgid "Casting to %s %s for %s" +msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/scheduler/simple.py:63 -msgid "All hosts have too many cores" +#: ../nova/virt/hyperv.py:454 +#, python-format +msgid "Failed to change vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/scheduler/simple.py:95 -msgid "All hosts have too many gigabytes" +#: ../nova/compute/api.py:71 +#, python-format +msgid "Instance %d was not found in get_network_topic" msgstr "" -#: nova/scheduler/simple.py:115 -msgid "All hosts have too many networks" +#: ../nova/compute/api.py:77 +#, python-format +msgid "Instance %d has no host" msgstr "" -#: nova/tests/test_cloud.py:198 -msgid "Can't test instances without a real virtual env." +#: ../nova/compute/api.py:97 +#, python-format +msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances" msgstr "" -#: nova/tests/test_cloud.py:210 +#: ../nova/compute/api.py:99 #, python-format -msgid "Need to watch instance %s until it's running..." +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." +msgstr "" + +#: ../nova/compute/api.py:112 +msgid "Creating a raw instance" msgstr "" -#: nova/tests/test_compute.py:104 +#: ../nova/compute/api.py:160 #, python-format -msgid "Running instances: %s" +msgid "Going to run %s instances..." msgstr "" -#: nova/tests/test_compute.py:110 +#: ../nova/compute/api.py:187 #, python-format -msgid "After terminating instances: %s" +msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s" msgstr "" -#: nova/tests/test_rpc.py:89 +#: ../nova/compute/api.py:292 #, python-format -msgid "Nested received %s, %s" +msgid "Going to try to terminate %s" msgstr "" -#: nova/tests/test_rpc.py:94 +#: ../nova/compute/api.py:296 #, python-format -msgid "Nested return %s" +msgid "Instance %d was not found during terminate" msgstr "" -#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#: ../nova/compute/api.py:301 #, python-format -msgid "Received %s" +msgid "Instance %d is already being terminated" msgstr "" -#: nova/tests/test_volume.py:162 +#: ../nova/compute/api.py:481 #, python-format -msgid "Target %s allocated" +msgid "Invalid device specified: %s. Example device: /dev/vdb" msgstr "" -#: nova/virt/connection.py:73 -msgid "Failed to open connection to the hypervisor" +#: ../nova/compute/api.py:496 +msgid "Volume isn't attached to anything!" msgstr "" -#: nova/virt/fake.py:210 +#: ../nova/rpc.py:98 #, python-format -msgid "Instance %s Not Found" +msgid "" +"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in " +"%(fl_intv)d seconds." msgstr "" -#: nova/virt/hyperv.py:118 -msgid "In init host" +#: ../nova/rpc.py:103 +#, 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:122 +msgid "Reconnected to queue" +msgstr "Znovu připojeno k AMQP frontě" + +#: ../nova/rpc.py:129 +msgid "Failed to fetch message from queue" +msgstr "Selhalo získání zprávy z AMQP fronty" -#: nova/virt/hyperv.py:131 +#: ../nova/rpc.py:159 #, python-format -msgid "Attempt to create duplicate vm %s" +msgid "Initing the Adapter Consumer for %s" msgstr "" -#: nova/virt/hyperv.py:148 +#: ../nova/rpc.py:178 #, python-format -msgid "Starting VM %s " -msgstr "" +msgid "received %s" +msgstr "získáno: %s" -#: nova/virt/hyperv.py:150 +#. 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:191 #, python-format -msgid "Started VM %s " -msgstr "" +msgid "no method for message: %s" +msgstr "Není metoda pro zpracování zprávy: %s" -#: nova/virt/hyperv.py:152 +#: ../nova/rpc.py:192 #, python-format -msgid "spawn vm failed: %s" -msgstr "" +msgid "No method for message: %s" +msgstr "Není metoda pro zpracování zprávy: %s" -#: nova/virt/hyperv.py:169 +#: ../nova/rpc.py:253 #, python-format -msgid "Failed to create VM %s" -msgstr "" +msgid "Returning exception %s to caller" +msgstr "Volajícímu je vrácena výjimka: %s" -#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#: ../nova/rpc.py:294 #, python-format -msgid "Created VM %s..." -msgstr "" +msgid "unpacked context: %s" +msgstr "rozbalený obsah: %s" + +#: ../nova/rpc.py:313 +msgid "Making asynchronous call..." +msgstr "Volání asynchronní funkce..." -#: nova/virt/hyperv.py:188 +#: ../nova/rpc.py:316 #, python-format -msgid "Set memory for vm %s..." +msgid "MSG_ID is %s" +msgstr "MSG_ID je %s" + +#: ../nova/rpc.py:354 +msgid "Making asynchronous cast..." msgstr "" -#: nova/virt/hyperv.py:198 +#: ../nova/rpc.py:364 #, python-format -msgid "Set vcpus for vm %s..." -msgstr "" +msgid "response %s" +msgstr "odpověď %s" -#: nova/virt/hyperv.py:202 +#: ../nova/rpc.py:373 #, python-format -msgid "Creating disk for %s by attaching disk file %s" +msgid "topic is %s" msgstr "" -#: nova/virt/hyperv.py:227 +#: ../nova/rpc.py:374 #, python-format -msgid "Failed to add diskdrive to VM %s" -msgstr "" +msgid "message %s" +msgstr "zpráva %s" -#: nova/virt/hyperv.py:230 +#: ../nova/volume/driver.py:78 #, python-format -msgid "New disk drive path is %s" +msgid "Recovering from a failed execute. Try number %s" msgstr "" -#: nova/virt/hyperv.py:247 +#: ../nova/volume/driver.py:87 #, python-format -msgid "Failed to add vhd file to VM %s" +msgid "volume group %s doesn't exist" msgstr "" -#: nova/virt/hyperv.py:249 +#: ../nova/volume/driver.py:220 #, python-format -msgid "Created disk for %s" +msgid "FAKE AOE: %s" msgstr "" -#: nova/virt/hyperv.py:253 -#, python-format -msgid "Creating nic for %s " +#: ../nova/volume/driver.py:233 +msgid "Skipping ensure_export. No iscsi_target " msgstr "" -#: nova/virt/hyperv.py:272 -msgid "Failed creating a port on the external vswitch" +#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288 +msgid "Skipping remove_export. No iscsi_target " msgstr "" -#: nova/virt/hyperv.py:273 +#: ../nova/volume/driver.py:347 #, python-format -msgid "Failed creating port for %s" +msgid "FAKE ISCSI: %s" msgstr "" -#: nova/virt/hyperv.py:275 +#: ../nova/volume/driver.py:359 #, python-format -msgid "Created switch port %s on switch %s" +msgid "rbd has no pool %s" msgstr "" -#: nova/virt/hyperv.py:285 +#: ../nova/volume/driver.py:414 #, python-format -msgid "Failed to add nic to VM %s" +msgid "Sheepdog is not working: %s" msgstr "" -#: nova/virt/hyperv.py:287 -#, python-format -msgid "Created nic for %s " +#: ../nova/volume/driver.py:416 +msgid "Sheepdog is not working" msgstr "" -#: nova/virt/hyperv.py:320 +#: ../nova/wsgi.py:68 #, python-format -msgid "WMI job failed: %s" +msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: nova/virt/hyperv.py:322 -#, python-format -msgid "WMI job succeeded: %s, Elapsed=%s " +#: ../nova/wsgi.py:147 +msgid "You must implement __call__" msgstr "" -#: nova/virt/hyperv.py:358 -#, python-format -msgid "Got request to destroy vm %s" +#: ../bin/nova-instancemonitor.py:55 +msgid "Starting instance monitor" msgstr "" -#: nova/virt/hyperv.py:383 -#, python-format -msgid "Failed to destroy vm %s" +#: ../bin/nova-dhcpbridge.py:58 +msgid "leasing ip" msgstr "" -#: nova/virt/hyperv.py:389 -#, python-format -msgid "Del: disk %s vm %s" +#: ../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 "" -#: nova/virt/hyperv.py:405 +#: ../bin/nova-dhcpbridge.py:123 #, python-format msgid "" -"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " -"cpu_time=%s" +"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s " +"on interface %(interface)s" msgstr "" -#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#: ../nova/virt/fake.py:239 #, python-format -msgid "duplicate name found: %s" +msgid "Instance %s Not Found" msgstr "" -#: nova/virt/hyperv.py:444 +#: ../nova/network/manager.py:153 #, python-format -msgid "Successfully changed vm state of %s to %s" +msgid "Dissassociated %s stale fixed ip(s)" msgstr "" -#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 -#, python-format -msgid "Failed to change vm state of %s to %s" +#: ../nova/network/manager.py:157 +msgid "setting network host" msgstr "" -#: nova/virt/images.py:70 +#: ../nova/network/manager.py:212 #, python-format -msgid "Finished retreving %s -- placed in %s" +msgid "Leasing IP %s" msgstr "" -#: nova/virt/libvirt_conn.py:144 +#: ../nova/network/manager.py:216 #, python-format -msgid "Connecting to libvirt: %s" +msgid "IP %s leased that isn't associated" msgstr "" -#: nova/virt/libvirt_conn.py:157 -msgid "Connection to libvirt broke" +#: ../nova/network/manager.py:220 +#, python-format +msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/libvirt_conn.py:229 +#: ../nova/network/manager.py:228 #, python-format -msgid "instance %s: deleting instance files %s" +msgid "IP %s leased that was already deallocated" msgstr "" -#: nova/virt/libvirt_conn.py:271 +#: ../nova/network/manager.py:233 #, python-format -msgid "No disk at %s" +msgid "Releasing IP %s" msgstr "" -#: nova/virt/libvirt_conn.py:278 -msgid "Instance snapshotting is not supported for libvirtat this time" +#: ../nova/network/manager.py:237 +#, python-format +msgid "IP %s released that isn't associated" msgstr "" -#: nova/virt/libvirt_conn.py:294 +#: ../nova/network/manager.py:241 #, python-format -msgid "instance %s: rebooted" +msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/libvirt_conn.py:297 +#: ../nova/network/manager.py:244 #, python-format -msgid "_wait_for_reboot failed: %s" +msgid "IP %s released that was not leased" msgstr "" -#: nova/virt/libvirt_conn.py:340 -#, python-format -msgid "instance %s: rescued" +#: ../nova/network/manager.py:519 +msgid "" +"The sum between the number of networks and the vlan start cannot be greater " +"than 4094" msgstr "" -#: nova/virt/libvirt_conn.py:343 +#: ../nova/virt/xenapi/volume_utils.py:57 #, python-format -msgid "_wait_for_rescue failed: %s" +msgid "Introducing %s..." msgstr "" -#: nova/virt/libvirt_conn.py:370 +#: ../nova/virt/xenapi/volume_utils.py:74 #, python-format -msgid "instance %s: is running" +msgid "Introduced %(label)s as %(sr_ref)s." msgstr "" -#: nova/virt/libvirt_conn.py:381 -#, python-format -msgid "instance %s: booted" +#: ../nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" msgstr "" -#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#: ../nova/virt/xenapi/volume_utils.py:90 #, python-format -msgid "instance %s: failed to boot" +msgid "Unable to find SR from VBD %s" msgstr "" -#: nova/virt/libvirt_conn.py:395 +#: ../nova/virt/xenapi/volume_utils.py:96 #, python-format -msgid "virsh said: %r" +msgid "Forgetting SR %s ... " msgstr "" -#: nova/virt/libvirt_conn.py:399 -msgid "cool, it's a device" +#: ../nova/virt/xenapi/volume_utils.py:101 +#, python-format +msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s" msgstr "" -#: nova/virt/libvirt_conn.py:407 +#: ../nova/virt/xenapi/volume_utils.py:107 #, python-format -msgid "data: %r, fpath: %r" +msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s" msgstr "" -#: nova/virt/libvirt_conn.py:415 +#: ../nova/virt/xenapi/volume_utils.py:111 #, python-format -msgid "Contents of file %s: %r" +msgid "Forgetting SR %s done." msgstr "" -#: nova/virt/libvirt_conn.py:449 +#: ../nova/virt/xenapi/volume_utils.py:113 #, python-format -msgid "instance %s: Creating image" +msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s" msgstr "" -#: nova/virt/libvirt_conn.py:505 +#: ../nova/virt/xenapi/volume_utils.py:123 #, python-format -msgid "instance %s: injecting key into image %s" +msgid "Unable to introduce VDI on SR %s" msgstr "" -#: nova/virt/libvirt_conn.py:508 +#: ../nova/virt/xenapi/volume_utils.py:128 #, python-format -msgid "instance %s: injecting net into image %s" +msgid "Unable to get record of VDI %s on" msgstr "" -#: nova/virt/libvirt_conn.py:516 +#: ../nova/virt/xenapi/volume_utils.py:146 #, python-format -msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgid "Unable to introduce VDI for SR %s" msgstr "" -#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#: ../nova/virt/xenapi/volume_utils.py:175 #, python-format -msgid "instance %s: starting toXML method" +msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s" msgstr "" -#: nova/virt/libvirt_conn.py:589 +#: ../nova/virt/xenapi/volume_utils.py:197 #, python-format -msgid "instance %s: finished toXML method" +msgid "Mountpoint cannot be translated: %s" 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" +#: ../nova/objectstore/image.py:262 +#, python-format +msgid "Failed to decrypt private key: %s" msgstr "" -#: nova/virt/xenapi_conn.py:263 +#: ../nova/objectstore/image.py:269 #, python-format -msgid "Task [%s] %s status: success %s" +msgid "Failed to decrypt initialization vector: %s" msgstr "" -#: nova/virt/xenapi_conn.py:271 +#: ../nova/objectstore/image.py:277 #, python-format -msgid "Task [%s] %s status: %s %s" +msgid "Failed to decrypt image file %(image_file)s: %(err)s" msgstr "" -#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#: ../nova/objectstore/handler.py:106 #, python-format -msgid "Got exception: %s" +msgid "Unknown S3 value type %r" msgstr "" -#: nova/virt/xenapi/fake.py:72 -#, python-format -msgid "%s: _db_content => %s" +#: ../nova/objectstore/handler.py:137 +msgid "Authenticated request" 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" +#: ../nova/objectstore/handler.py:182 +msgid "List of buckets requested" msgstr "" -#: nova/virt/xenapi/fake.py:249 +#: ../nova/objectstore/handler.py:209 #, python-format -msgid "xenapi.fake does not have an implementation for %s" +msgid "List keys for bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:283 +#: ../nova/objectstore/handler.py:217 #, python-format -msgid "Calling %s %s" +msgid "Unauthorized attempt to access bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:288 +#: ../nova/objectstore/handler.py:235 #, python-format -msgid "Calling getter %s" +msgid "Creating bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:340 +#: ../nova/objectstore/handler.py:245 #, python-format -msgid "" -"xenapi.fake does not have an implementation for %s or it has been called " -"with the wrong number of arguments" +msgid "Deleting bucket %s" msgstr "" -#: nova/virt/xenapi/network_utils.py:40 +#: ../nova/objectstore/handler.py:249 #, python-format -msgid "Found non-unique network for bridge %s" +msgid "Unauthorized attempt to delete bucket %s" msgstr "" -#: nova/virt/xenapi/network_utils.py:43 +#: ../nova/objectstore/handler.py:273 #, python-format -msgid "Found no network for bridge %s" +msgid "Getting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:127 +#: ../nova/objectstore/handler.py:276 #, python-format -msgid "Created VM %s as %s." +msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:147 +#: ../nova/objectstore/handler.py:296 #, python-format -msgid "Creating VBD for VM %s, VDI %s ... " +msgid "Putting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:149 +#: ../nova/objectstore/handler.py:299 #, python-format -msgid "Created VBD %s for VM %s, VDI %s." +msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:165 +#: ../nova/objectstore/handler.py:318 #, python-format -msgid "VBD not found in instance %s" +msgid "Deleting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:175 +#: ../nova/objectstore/handler.py:322 #, python-format -msgid "Unable to unplug VBD %s" +msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:187 +#: ../nova/objectstore/handler.py:396 #, python-format -msgid "Unable to destroy VBD %s" +msgid "Not authorized to upload image: invalid directory %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:202 +#: ../nova/objectstore/handler.py:404 #, python-format -msgid "Creating VIF for VM %s, network %s." +msgid "Not authorized to upload image: unauthorized bucket %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:205 +#: ../nova/objectstore/handler.py:409 #, python-format -msgid "Created VIF %s for VM %s, network %s." +msgid "Starting image upload: %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:216 +#: ../nova/objectstore/handler.py:423 #, python-format -msgid "Snapshotting VM %s with label '%s'..." +msgid "Not authorized to update attributes of image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:229 +#: ../nova/objectstore/handler.py:431 #, python-format -msgid "Created snapshot %s from VM %s." +msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r" msgstr "" -#: nova/virt/xenapi/vm_utils.py:243 +#. other attributes imply update +#: ../nova/objectstore/handler.py:436 #, python-format -msgid "Asking xapi to upload %s as '%s'" +msgid "Updating user fields on image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:261 +#: ../nova/objectstore/handler.py:450 #, python-format -msgid "Asking xapi to fetch %s as %s" +msgid "Unauthorized attempt to delete image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:279 +#: ../nova/objectstore/handler.py:455 #, python-format -msgid "Looking up vdi %s for PV kernel" +msgid "Deleted image: %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:290 +#: ../nova/auth/manager.py:259 #, python-format -msgid "PV Kernel in VDI:%d" +msgid "Looking up user: %r" msgstr "" -#: nova/virt/xenapi/vm_utils.py:318 +#: ../nova/auth/manager.py:263 #, python-format -msgid "VDI %s is still available" +msgid "Failed authorization for access key %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:331 +#: ../nova/auth/manager.py:264 #, python-format -msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgid "No user found for access key %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:333 +#: ../nova/auth/manager.py:270 #, python-format -msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgid "Using project name = user name (%s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:390 +#: ../nova/auth/manager.py:277 #, python-format -msgid "VHD %s has parent %s" +msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:407 +#: ../nova/auth/manager.py:279 #, python-format -msgid "Re-scanning SR %s" +msgid "No project called %s could be found" msgstr "" -#: nova/virt/xenapi/vm_utils.py:431 +#: ../nova/auth/manager.py:287 #, python-format -msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgid "" +"Failed authorization: user %(uname)s not admin and not member of project " +"%(pjname)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:448 +#: ../nova/auth/manager.py:289 #, python-format -msgid "No VDIs found for VM %s" +msgid "User %(uid)s is not a member of project %(pjid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:452 +#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309 #, python-format -msgid "Unexpected number of VDIs (%s) found for VM %s" +msgid "Invalid signature for user %s" msgstr "" -#: nova/virt/xenapi/vmops.py:62 -#, python-format -msgid "Attempted to create non-unique name %s" +#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310 +msgid "Signature does not match" msgstr "" -#: nova/virt/xenapi/vmops.py:99 -#, python-format -msgid "Starting VM %s..." +#: ../nova/auth/manager.py:380 +msgid "Must specify project" msgstr "" -#: nova/virt/xenapi/vmops.py:101 +#: ../nova/auth/manager.py:414 #, python-format -msgid "Spawning VM %s created %s." +msgid "The %s role can not be found" msgstr "" -#: nova/virt/xenapi/vmops.py:112 +#: ../nova/auth/manager.py:416 #, python-format -msgid "Instance %s: booted" +msgid "The %s role is global only" msgstr "" -#: nova/virt/xenapi/vmops.py:137 +#: ../nova/auth/manager.py:420 #, python-format -msgid "Instance not present %s" +msgid "Adding role %(role)s to user %(uid)s in project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:166 +#: ../nova/auth/manager.py:423 #, python-format -msgid "Starting snapshot for VM %s" +msgid "Adding sitewide role %(role)s to user %(uid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:174 +#: ../nova/auth/manager.py:448 #, python-format -msgid "Unable to Snapshot %s: %s" +msgid "Removing role %(role)s from user %(uid)s on project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:184 +#: ../nova/auth/manager.py:451 #, python-format -msgid "Finished snapshot and upload for VM %s" +msgid "Removing sitewide role %(role)s from user %(uid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:252 +#: ../nova/auth/manager.py:515 #, python-format -msgid "suspend: instance not present %s" +msgid "Created project %(name)s with manager %(manager_user)s" msgstr "" -#: nova/virt/xenapi/vmops.py:262 +#: ../nova/auth/manager.py:533 #, python-format -msgid "resume: instance not present %s" +msgid "modifying project %s" msgstr "" -#: nova/virt/xenapi/vmops.py:271 +#: ../nova/auth/manager.py:545 #, python-format -msgid "Instance not found %s" +msgid "Adding user %(uid)s to project %(pid)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:57 +#: ../nova/auth/manager.py:566 #, python-format -msgid "Introducing %s..." +msgid "Remove user %(uid)s from project %(pid)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:74 +#: ../nova/auth/manager.py:592 #, python-format -msgid "Introduced %s as %s." +msgid "Deleting project %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:78 -msgid "Unable to create Storage Repository" +#: ../nova/auth/manager.py:650 +#, python-format +msgid "Created user %(rvname)s (admin: %(rvadmin)r)" msgstr "" -#: nova/virt/xenapi/volume_utils.py:90 +#: ../nova/auth/manager.py:659 #, python-format -msgid "Unable to find SR from VBD %s" +msgid "Deleting user %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:96 +#: ../nova/auth/manager.py:669 #, python-format -msgid "Forgetting SR %s ... " +msgid "Access Key change for user %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:101 +#: ../nova/auth/manager.py:671 #, python-format -msgid "Ignoring exception %s when getting PBDs for %s" +msgid "Secret Key change for user %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:107 +#: ../nova/auth/manager.py:673 #, python-format -msgid "Ignoring exception %s when unplugging PBD %s" +msgid "Admin status set to %(admin)r for user %(uid)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:111 +#: ../nova/auth/manager.py:722 #, python-format -msgid "Forgetting SR %s done." +msgid "No vpn data for project %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:113 +#: ../nova/service.py:161 #, python-format -msgid "Ignoring exception %s when forgetting SR %s" +msgid "Starting %(topic)s node (version %(vcs_string)s)" msgstr "" -#: nova/virt/xenapi/volume_utils.py:123 -#, python-format -msgid "Unable to introduce VDI on SR %s" +#: ../nova/service.py:174 +msgid "Service killed that has no database entry" msgstr "" -#: nova/virt/xenapi/volume_utils.py:128 -#, python-format -msgid "Unable to get record of VDI %s on" +#: ../nova/service.py:195 +msgid "The service database object disappeared, Recreating it." msgstr "" -#: nova/virt/xenapi/volume_utils.py:146 -#, python-format -msgid "Unable to introduce VDI for SR %s" +#: ../nova/service.py:207 +msgid "Recovered model server connection!" msgstr "" -#: nova/virt/xenapi/volume_utils.py:175 -#, python-format -msgid "Unable to obtain target information %s, %s" +#: ../nova/service.py:213 +msgid "model server went away" msgstr "" -#: nova/virt/xenapi/volume_utils.py:197 +#: ../nova/auth/ldapdriver.py:174 #, python-format -msgid "Mountpoint cannot be translated: %s" +msgid "LDAP user %s already exists" msgstr "" -#: nova/virt/xenapi/volumeops.py:51 +#: ../nova/auth/ldapdriver.py:205 #, python-format -msgid "Attach_volume: %s, %s, %s" +msgid "LDAP object for %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:69 +#: ../nova/auth/ldapdriver.py:348 #, python-format -msgid "Unable to create VDI on SR %s for instance %s" +msgid "User %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:81 +#: ../nova/auth/ldapdriver.py:472 #, python-format -msgid "Unable to use SR %s for instance %s" +msgid "Group can't be created because group %s already exists" msgstr "" -#: nova/virt/xenapi/volumeops.py:93 +#: ../nova/auth/ldapdriver.py:478 #, python-format -msgid "Unable to attach volume to instance %s" +msgid "Group can't be created because user %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:95 +#: ../nova/auth/ldapdriver.py:495 #, python-format -msgid "Mountpoint %s attached to instance %s" +msgid "User %s can't be searched in group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:106 +#: ../nova/auth/ldapdriver.py:507 #, python-format -msgid "Detach_volume: %s, %s" +msgid "User %s can't be added to the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:113 +#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521 #, python-format -msgid "Unable to locate volume %s" +msgid "The group at dn %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:121 +#: ../nova/auth/ldapdriver.py:513 #, python-format -msgid "Unable to detach volume %s" +msgid "User %(uid)s is already a member of the group %(group_dn)s" msgstr "" -#: nova/virt/xenapi/volumeops.py:128 +#: ../nova/auth/ldapdriver.py:524 #, python-format -msgid "Mountpoint %s detached from instance %s" +msgid "" +"User %s can't be removed from the group because the user doesn't exist" msgstr "" -#: nova/volume/api.py:44 +#: ../nova/auth/ldapdriver.py:528 #, python-format -msgid "Quota exceeeded for %s, tried to create %sG volume" +msgid "User %s is not a member of the group" msgstr "" -#: nova/volume/api.py:46 +#: ../nova/auth/ldapdriver.py:542 #, python-format -msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." msgstr "" -#: nova/volume/api.py:70 nova/volume/api.py:95 -msgid "Volume status must be available" +#: ../nova/auth/ldapdriver.py:549 +#, python-format +msgid "User %s can't be removed from all because the user doesn't exist" msgstr "" -#: nova/volume/api.py:97 -msgid "Volume is already attached" +#: ../nova/auth/ldapdriver.py:564 +#, python-format +msgid "Group at dn %s doesn't exist" msgstr "" -#: nova/volume/api.py:103 -msgid "Volume is already detached" +#: ../nova/virt/xenapi/network_utils.py:40 +#, python-format +msgid "Found non-unique network for bridge %s" msgstr "" -#: nova/volume/driver.py:76 +#: ../nova/virt/xenapi/network_utils.py:43 #, python-format -msgid "Recovering from a failed execute. Try number %s" +msgid "Found no network for bridge %s" msgstr "" -#: nova/volume/driver.py:85 +#: ../nova/api/ec2/admin.py:97 #, python-format -msgid "volume group %s doesn't exist" +msgid "Creating new user: %s" msgstr "" -#: nova/volume/driver.py:210 +#: ../nova/api/ec2/admin.py:105 #, python-format -msgid "FAKE AOE: %s" +msgid "Deleting user: %s" msgstr "" -#: nova/volume/driver.py:315 +#: ../nova/api/ec2/admin.py:127 #, python-format -msgid "FAKE ISCSI: %s" +msgid "Adding role %(role)s to user %(user)s for project %(project)s" msgstr "" -#: nova/volume/manager.py:85 +#: ../nova/api/ec2/admin.py:131 #, python-format -msgid "Re-exporting %s volumes" +msgid "Adding sitewide role %(role)s to user %(user)s" msgstr "" -#: nova/volume/manager.py:93 +#: ../nova/api/ec2/admin.py:137 #, python-format -msgid "volume %s: creating" +msgid "Removing role %(role)s from user %(user)s for project %(project)s" msgstr "" -#: nova/volume/manager.py:102 +#: ../nova/api/ec2/admin.py:141 #, python-format -msgid "volume %s: creating lv of size %sG" +msgid "Removing sitewide role %(role)s from user %(user)s" msgstr "" -#: nova/volume/manager.py:106 -#, python-format -msgid "volume %s: creating export" +#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223 +msgid "operation must be add or remove" msgstr "" -#: nova/volume/manager.py:113 +#: ../nova/api/ec2/admin.py:159 #, python-format -msgid "volume %s: created successfully" +msgid "Getting x509 for user: %(name)s on project: %(project)s" msgstr "" -#: nova/volume/manager.py:121 -msgid "Volume is still attached" +#: ../nova/api/ec2/admin.py:177 +#, python-format +msgid "Create project %(name)s managed by %(manager_user)s" msgstr "" -#: nova/volume/manager.py:123 -msgid "Volume is not local to this node" +#: ../nova/api/ec2/admin.py:190 +#, python-format +msgid "Modify project: %(name)s managed by %(manager_user)s" msgstr "" -#: nova/volume/manager.py:124 +#: ../nova/api/ec2/admin.py:200 #, python-format -msgid "volume %s: removing export" +msgid "Delete project: %s" msgstr "" -#: nova/volume/manager.py:126 +#: ../nova/api/ec2/admin.py:214 #, python-format -msgid "volume %s: deleting" +msgid "Adding user %(user)s to project %(project)s" msgstr "" -#: nova/volume/manager.py:129 +#: ../nova/api/ec2/admin.py:218 #, python-format -msgid "volume %s: deleted successfully" +msgid "Removing user %(user)s from project %(project)s" msgstr "" + +#, python-format +#~ msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +#~ msgstr "AMQP server na %s:%d není dosažitelný. Zkusím znovu za %d sekund." + +#, python-format +#~ msgid "" +#~ "%s\n" +#~ "Command: %s\n" +#~ "Exit code: %s\n" +#~ "Stdout: %r\n" +#~ "Stderr: %r" +#~ msgstr "" +#~ "%s\n" +#~ "Příkaz: %s\n" +#~ "Vrácená hodnota: %s\n" +#~ "Stdout: %r\n" +#~ "Stderr: %r" diff --git a/po/da.po b/po/da.po index f845f11b0..d24d89fd9 100644 --- a/po/da.po +++ b/po/da.po @@ -7,2124 +7,2842 @@ msgid "" msgstr "" "Project-Id-Version: nova\n" "Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"POT-Creation-Date: 2011-02-21 10:03-0500\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-02-05 05:36+0000\n" -"X-Generator: Launchpad (build 12177)\n" +"X-Launchpad-Export-Date: 2011-03-19 06:18+0000\n" +"X-Generator: Launchpad (build 12559)\n" -#: nova/crypto.py:46 +#: ../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 "" + +#: ../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/api/openstack/servers.py:72 +msgid "Failed to read private ip" +msgstr "" + +#: ../nova/api/openstack/servers.py:79 +msgid "Failed to read public ip(s)" +msgstr "" + +#: ../nova/api/openstack/servers.py:152 +#, python-format +msgid "%(param)s property not found for image %(_image_id)s" +msgstr "" + +#: ../nova/api/openstack/servers.py:168 +msgid "No keypairs defined" +msgstr "" + +#: ../nova/api/openstack/servers.py:238 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:253 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:267 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:281 +#, python-format +msgid "Compute.api::reset_network %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:292 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:303 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:314 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:325 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: ../nova/twistd.py:157 +msgid "Wrong number of arguments." +msgstr "" + +#: ../nova/twistd.py:209 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "" + +#: ../nova/twistd.py:221 +msgid "No such process" +msgstr "" + +#: ../nova/twistd.py:230 ../nova/service.py:224 +#, python-format +msgid "Serving %s" +msgstr "" + +#: ../nova/twistd.py:262 ../nova/service.py:225 +msgid "Full set of FLAGS:" +msgstr "" + +#: ../nova/twistd.py:266 +#, python-format +msgid "Starting %s" +msgstr "" + +#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101 +#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741 +#: ../nova/api/ec2/__init__.py:317 +#, 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 "Filnavn for privatnøgle" +#: ../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/scheduler/manager.py:69 +#, python-format +msgid "Casting to %(topic)s %(host)s for %(method)s" +msgstr "" + +#: ../nova/compute/manager.py:78 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:80 +#, python-format +msgid "" +"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|" +msgstr "" + +#: ../nova/compute/manager.py:84 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:91 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:95 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: ../nova/compute/manager.py:179 +msgid "Instance has already been created" +msgstr "" + +#: ../nova/compute/manager.py:180 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#. pylint: disable=W0702 +#: ../nova/compute/manager.py:219 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: ../nova/compute/manager.py:255 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: ../nova/compute/manager.py:268 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: ../nova/compute/manager.py:282 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: ../nova/compute/manager.py:287 +#, python-format +msgid "" +"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:311 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: ../nova/compute/manager.py:316 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:332 +#, python-format +msgid "" +"trying to reset the password on a non-running instance: %(instance_id)s " +"(state: %(instance_state)s expected: %(expected_state)s)" +msgstr "" + +#: ../nova/compute/manager.py:335 +#, python-format +msgid "instance %s: setting admin password" +msgstr "" + +#: ../nova/compute/manager.py:353 +#, python-format +msgid "" +"trying to inject a file into a non-running instance: %(instance_id)s (state: " +"%(instance_state)s expected: %(expected_state)s)" +msgstr "" + +#: ../nova/compute/manager.py:362 +#, python-format +msgid "instance %(nm)s: injecting file to %(plain_path)s" +msgstr "" + +#: ../nova/compute/manager.py:372 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: ../nova/compute/manager.py:387 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: ../nova/compute/manager.py:406 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: ../nova/compute/manager.py:423 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: ../nova/compute/manager.py:440 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: ../nova/compute/manager.py:453 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: ../nova/compute/manager.py:472 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: ../nova/compute/manager.py:491 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: ../nova/compute/manager.py:503 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: ../nova/compute/manager.py:513 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: ../nova/compute/manager.py:526 +#, python-format +msgid "instance %s: reset network" +msgstr "" + +#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: ../nova/compute/manager.py:543 +#, python-format +msgid "instance %s: getting ajax console" +msgstr "" + +#: ../nova/compute/manager.py:553 +#, python-format +msgid "" +"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s" +msgstr "" + +#. pylint: disable=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:569 +#, python-format +msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing" +msgstr "" + +#: ../nova/compute/manager.py:585 +#, python-format +msgid "" +"Detach volume %(volume_id)s from mountpoint %(mp)s on instance " +"%(instance_id)s" +msgstr "" + +#: ../nova/compute/manager.py:588 +#, 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 "bind %s: slettet" + +#: ../nova/virt/xenapi/fake.py:74 +#, python-format +msgid "%(text)s: _db_content => %(content)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:304 ../nova/virt/xenapi/fake.py:404 +#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478 +msgid "Raising NotImplemented" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:306 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:341 +#, python-format +msgid "Calling %(localname)s %(impl)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:346 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:406 +#, 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:187 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: ../nova/network/linux_net.py:208 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" -#: nova/crypto.py:51 -msgid "Filename of root Certificate Revokation List" +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:314 +#, python-format +msgid "Hupping dnsmasq threw %s" msgstr "" -#: nova/crypto.py:53 -msgid "Where we keep our keys" +#: ../nova/network/linux_net.py:316 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" msgstr "" -#: nova/crypto.py:55 -msgid "Where we keep our root CA" +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:358 +#, python-format +msgid "killing radvd threw %s" msgstr "" -#: nova/crypto.py:57 -msgid "Should we use a CA for each project?" +#: ../nova/network/linux_net.py:360 +#, python-format +msgid "Pid %d is stale, relaunching radvd" msgstr "" -#: nova/crypto.py:61 +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:449 #, python-format -msgid "Subject for certificate for users, %s for project, user, timestamp" +msgid "Killing dnsmasq threw %s" msgstr "" -#: nova/crypto.py:66 +#: ../nova/utils.py:58 #, python-format -msgid "Subject for certificate for projects, %s for project, timestamp" +msgid "Inner Exception: %s" msgstr "" -#: nova/crypto.py:71 +#: ../nova/utils.py:59 #, python-format -msgid "Subject for certificate for vpns, %s for project, timestamp" +msgid "Class %s cannot be found" msgstr "" -#: nova/crypto.py:258 +#: ../nova/utils.py:118 #, python-format -msgid "Flags path: %s" +msgid "Fetching %s" msgstr "" -#: nova/exception.py:33 -msgid "Unexpected error while running command." +#: ../nova/utils.py:130 +#, python-format +msgid "Running cmd (subprocess): %s" msgstr "" -#: nova/exception.py:36 +#: ../nova/utils.py:143 ../nova/utils.py:183 #, python-format -msgid "" -"%s\n" -"Command: %s\n" -"Exit code: %s\n" -"Stdout: %r\n" -"Stderr: %r" +msgid "Result was %s" msgstr "" -#: nova/exception.py:86 -msgid "Uncaught exception" +#: ../nova/utils.py:159 +#, python-format +msgid "Running cmd (SSH): %s" +msgstr "" + +#: ../nova/utils.py:217 +#, python-format +msgid "debug in callback: %s" +msgstr "" + +#: ../nova/utils.py:222 +#, python-format +msgid "Running %s" +msgstr "" + +#: ../nova/utils.py:262 +#, python-format +msgid "Link Local address is not found.:%s" +msgstr "" + +#: ../nova/utils.py:265 +#, python-format +msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s" +msgstr "" + +#: ../nova/utils.py:363 +#, python-format +msgid "Invalid backend: %s" +msgstr "" + +#: ../nova/utils.py:374 +#, python-format +msgid "backend %s" msgstr "" -#: nova/fakerabbit.py:48 +#: ../nova/fakerabbit.py:49 #, python-format -msgid "(%s) publish (key: %s) %s" +msgid "(%(nm)s) publish (key: %(routing_key)s) %(message)s" msgstr "" -#: nova/fakerabbit.py:53 +#: ../nova/fakerabbit.py:54 #, python-format msgid "Publishing to route %s" msgstr "" -#: nova/fakerabbit.py:83 +#: ../nova/fakerabbit.py:84 #, python-format msgid "Declaring queue %s" msgstr "" -#: nova/fakerabbit.py:89 +#: ../nova/fakerabbit.py:90 #, python-format msgid "Declaring exchange %s" msgstr "" -#: nova/fakerabbit.py:95 +#: ../nova/fakerabbit.py:96 #, python-format -msgid "Binding %s to %s with key %s" +msgid "Binding %(queue)s to %(exchange)s with key %(routing_key)s" msgstr "" -#: nova/fakerabbit.py:120 +#: ../nova/fakerabbit.py:121 #, python-format -msgid "Getting from %s: %s" +msgid "Getting from %(queue)s: %(message)s" msgstr "" -#: nova/rpc.py:92 +#: ../nova/virt/xenapi/vm_utils.py:135 ../nova/virt/hyperv.py:171 #, python-format -msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgid "Created VM %s..." msgstr "" -#: nova/rpc.py:99 +#: ../nova/virt/xenapi/vm_utils.py:138 #, python-format -msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgid "Created VM %(instance_name)s as %(vm_ref)s." msgstr "" -#: nova/rpc.py:118 -msgid "Reconnected to queue" +#: ../nova/virt/xenapi/vm_utils.py:168 +#, python-format +msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... " msgstr "" -#: nova/rpc.py:125 -msgid "Failed to fetch message from queue" +#: ../nova/virt/xenapi/vm_utils.py:171 +#, python-format +msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s." msgstr "" -#: nova/rpc.py:155 +#: ../nova/virt/xenapi/vm_utils.py:187 #, python-format -msgid "Initing the Adapter Consumer for %s" +msgid "VBD not found in instance %s" msgstr "" -#: nova/rpc.py:170 +#: ../nova/virt/xenapi/vm_utils.py:197 #, python-format -msgid "received %s" +msgid "Unable to unplug VBD %s" msgstr "" -#: nova/rpc.py:183 +#: ../nova/virt/xenapi/vm_utils.py:209 #, python-format -msgid "no method for message: %s" +msgid "Unable to destroy VBD %s" msgstr "" -#: nova/rpc.py:184 +#: ../nova/virt/xenapi/vm_utils.py:224 #, python-format -msgid "No method for message: %s" +msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s." msgstr "" -#: nova/rpc.py:245 +#: ../nova/virt/xenapi/vm_utils.py:227 #, python-format -msgid "Returning exception %s to caller" +msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s." msgstr "" -#: nova/rpc.py:286 +#: ../nova/virt/xenapi/vm_utils.py:246 #, python-format -msgid "unpacked context: %s" +msgid "" +"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on " +"%(sr_ref)s." msgstr "" -#: nova/rpc.py:305 -msgid "Making asynchronous call..." +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vm_utils.py:258 +#, python-format +msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..." msgstr "" -#: nova/rpc.py:308 +#: ../nova/virt/xenapi/vm_utils.py:272 #, python-format -msgid "MSG_ID is %s" +msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s." msgstr "" -#: nova/rpc.py:356 +#: ../nova/virt/xenapi/vm_utils.py:286 #, python-format -msgid "response %s" +msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s" msgstr "" -#: nova/rpc.py:365 +#: ../nova/virt/xenapi/vm_utils.py:327 #, python-format -msgid "topic is %s" +msgid "Size for image %(image)s:%(virtual_size)d" msgstr "" -#: nova/rpc.py:366 +#: ../nova/virt/xenapi/vm_utils.py:332 #, python-format -msgid "message %s" +msgid "Glance image %s" msgstr "" -#: nova/service.py:157 +#. we need to invoke a plugin for copying VDI's +#. content into proper path +#: ../nova/virt/xenapi/vm_utils.py:342 #, python-format -msgid "Starting %s node" +msgid "Copying VDI %s to /boot/guest on dom0" msgstr "" -#: nova/service.py:169 -msgid "Service killed that has no database entry" +#: ../nova/virt/xenapi/vm_utils.py:352 +#, python-format +msgid "Kernel/Ramdisk VDI %s destroyed" msgstr "" -#: nova/service.py:190 -msgid "The service database object disappeared, Recreating it." +#: ../nova/virt/xenapi/vm_utils.py:361 +#, python-format +msgid "Asking xapi to fetch %(url)s as %(access)s" msgstr "" -#: nova/service.py:202 -msgid "Recovered model server connection!" +#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402 +#, python-format +msgid "Looking up vdi %s for PV kernel" msgstr "" -#: nova/service.py:208 -msgid "model server went away" +#: ../nova/virt/xenapi/vm_utils.py:397 +#, python-format +msgid "PV Kernel in VDI:%s" msgstr "" -#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#: ../nova/virt/xenapi/vm_utils.py:405 #, python-format -msgid "Data store %s is unreachable. Trying again in %d seconds." +msgid "Running pygrub against %s" msgstr "" -#: nova/service.py:232 nova/twistd.py:232 +#: ../nova/virt/xenapi/vm_utils.py:411 #, python-format -msgid "Serving %s" +msgid "Found Xen kernel %s" msgstr "" -#: nova/service.py:234 nova/twistd.py:264 -msgid "Full set of FLAGS:" +#: ../nova/virt/xenapi/vm_utils.py:413 +msgid "No Xen kernel found. Booting HVM." msgstr "" -#: nova/twistd.py:211 +#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431 #, python-format -msgid "pidfile %s does not exist. Daemon not running?\n" +msgid "duplicate name found: %s" msgstr "" -#: nova/twistd.py:268 +#: ../nova/virt/xenapi/vm_utils.py:442 #, python-format -msgid "Starting %s" +msgid "VDI %s is still available" msgstr "" -#: nova/utils.py:53 +#: ../nova/virt/xenapi/vm_utils.py:463 #, python-format -msgid "Inner Exception: %s" +msgid "(VM_UTILS) xenserver vm state -> |%s|" msgstr "" -#: nova/utils.py:54 +#: ../nova/virt/xenapi/vm_utils.py:465 #, python-format -msgid "Class %s cannot be found" +msgid "(VM_UTILS) xenapi power_state -> |%s|" msgstr "" -#: nova/utils.py:113 +#: ../nova/virt/xenapi/vm_utils.py:525 #, python-format -msgid "Fetching %s" +msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s" msgstr "" -#: nova/utils.py:125 +#: ../nova/virt/xenapi/vm_utils.py:542 #, python-format -msgid "Running cmd (subprocess): %s" +msgid "Re-scanning SR %s" msgstr "" -#: nova/utils.py:138 +#: ../nova/virt/xenapi/vm_utils.py:567 #, python-format -msgid "Result was %s" +msgid "" +"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..." msgstr "" -#: nova/utils.py:171 +#: ../nova/virt/xenapi/vm_utils.py:574 #, python-format -msgid "debug in callback: %s" +msgid "" +"Parent %(parent_uuid)s doesn't match original parent " +"%(original_parent_uuid)s, waiting for coalesce..." msgstr "" -#: nova/utils.py:176 +#: ../nova/virt/xenapi/vm_utils.py:590 #, python-format -msgid "Running %s" +msgid "No VDIs found for VM %s" msgstr "" -#: nova/utils.py:207 +#: ../nova/virt/xenapi/vm_utils.py:594 #, python-format -msgid "Couldn't get IP, using 127.0.0.1 %s" +msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s" msgstr "" -#: nova/utils.py:289 +#: ../nova/virt/xenapi/vm_utils.py:653 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188 #, python-format -msgid "Invalid backend: %s" +msgid "Creating VBD for VDI %s ... " msgstr "" -#: nova/utils.py:300 +#: ../nova/virt/xenapi/vm_utils.py:655 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190 #, python-format -msgid "backend %s" +msgid "Creating VBD for VDI %s done." msgstr "" -#: nova/api/ec2/__init__.py:133 -msgid "Too many failed authentications." +#: ../nova/virt/xenapi/vm_utils.py:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192 +#, python-format +msgid "Plugging VBD %s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:659 +#: ../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:661 +#, python-format +msgid "VBD %(vbd)s plugged as %(orig_dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:664 +#, python-format +msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:668 +#: ../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:671 +#: ../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:683 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211 +msgid "VBD.unplug successful first time." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:688 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216 +msgid "VBD.unplug rejected: retrying..." msgstr "" -#: nova/api/ec2/__init__.py:142 +#: ../nova/virt/xenapi/vm_utils.py:692 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220 +msgid "VBD.unplug successful eventually." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:695 +#: ../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:704 +#: ../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:735 #, python-format msgid "" -"Access key %s has had %d failed authentications and will be locked out for " -"%d minutes." +"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..." msgstr "" -#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#: ../nova/virt/xenapi/vm_utils.py:747 #, python-format -msgid "Authentication Failure: %s" +msgid "Writing partition table %s done." msgstr "" -#: nova/api/ec2/__init__.py:190 +#: ../nova/tests/test_rpc.py:89 #, python-format -msgid "Authenticated Request For %s:%s)" +msgid "Nested received %(queue)s, %(value)s" msgstr "" -#: nova/api/ec2/__init__.py:227 +#: ../nova/tests/test_rpc.py:95 #, python-format -msgid "action: %s" +msgid "Nested return %s" msgstr "" -#: nova/api/ec2/__init__.py:229 +#: ../nova/tests/test_rpc.py:120 ../nova/tests/test_rpc.py:126 #, python-format -msgid "arg: %s\t\tval: %s" +msgid "Received %s" msgstr "" -#: nova/api/ec2/__init__.py:301 +#: ../nova/db/sqlalchemy/api.py:44 +msgid "Use of empty request context is deprecated" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:133 #, python-format -msgid "Unauthorized request for controller=%s and action=%s" +msgid "No service for id %s" msgstr "" -#: nova/api/ec2/__init__.py:339 +#: ../nova/db/sqlalchemy/api.py:251 #, python-format -msgid "NotFound raised: %s" +msgid "No service for %(host)s, %(binary)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:592 +msgid "No fixed ips defined" msgstr "" -#: nova/api/ec2/__init__.py:342 +#: ../nova/db/sqlalchemy/api.py:608 #, python-format -msgid "ApiError raised: %s" +msgid "No floating ip for address %s" msgstr "" -#: nova/api/ec2/__init__.py:349 +#: ../nova/db/sqlalchemy/api.py:629 #, python-format -msgid "Unexpected error raised: %s" +msgid "No address for instance %s" msgstr "" -#: nova/api/ec2/__init__.py:354 -msgid "An unknown error has occurred. Please try your request again." +#: ../nova/db/sqlalchemy/api.py:961 +#, python-format +msgid "no keypair for user %(user_id)s, name %(name)s" msgstr "" -#: nova/api/ec2/admin.py:84 +#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156 #, python-format -msgid "Creating new user: %s" +msgid "No network for id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1086 +msgid "No networks defined" msgstr "" -#: nova/api/ec2/admin.py:92 +#: ../nova/db/sqlalchemy/api.py:1115 #, python-format -msgid "Deleting user: %s" +msgid "No network for bridge %s" msgstr "" -#: nova/api/ec2/admin.py:114 +#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142 #, python-format -msgid "Adding role %s to user %s for project %s" +msgid "No network for instance %s" msgstr "" -#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#: ../nova/db/sqlalchemy/api.py:1277 #, python-format -msgid "Adding sitewide role %s to user %s" +msgid "Token %s does not exist" msgstr "" -#: nova/api/ec2/admin.py:122 +#: ../nova/db/sqlalchemy/api.py:1302 #, python-format -msgid "Removing role %s from user %s for project %s" +msgid "No quota for project_id %s" msgstr "" -#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501 +#: ../nova/api/ec2/__init__.py:323 #, python-format -msgid "Removing sitewide role %s from user %s" +msgid "Volume %s not found" msgstr "" -#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 -msgid "operation must be add or remove" +#: ../nova/db/sqlalchemy/api.py:1514 +#, python-format +msgid "No export device found for volume %s" msgstr "" -#: nova/api/ec2/admin.py:142 +#: ../nova/db/sqlalchemy/api.py:1527 #, python-format -msgid "Getting x509 for user: %s on project: %s" +msgid "No target id found for volume %s" msgstr "" -#: nova/api/ec2/admin.py:159 +#: ../nova/db/sqlalchemy/api.py:1572 #, python-format -msgid "Create project %s managed by %s" +msgid "No security group with id %s" msgstr "" -#: nova/api/ec2/admin.py:170 +#: ../nova/db/sqlalchemy/api.py:1589 #, python-format -msgid "Delete project: %s" +msgid "No security group named %(group_name)s for project: %(project_id)s" msgstr "" -#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#: ../nova/db/sqlalchemy/api.py:1682 #, python-format -msgid "Adding user %s to project %s" +msgid "No secuity group rule with id %s" msgstr "" -#: nova/api/ec2/admin.py:188 +#: ../nova/db/sqlalchemy/api.py:1756 #, python-format -msgid "Removing user %s from project %s" +msgid "No user for id %s" msgstr "" -#: nova/api/ec2/apirequest.py:95 +#: ../nova/db/sqlalchemy/api.py:1772 #, python-format -msgid "Unsupported API request: controller = %s,action = %s" +msgid "No user for access key %s" msgstr "" -#: nova/api/ec2/cloud.py:117 +#: ../nova/db/sqlalchemy/api.py:1834 #, python-format -msgid "Generating root CA: %s" +msgid "No project with id %s" msgstr "" -#: nova/api/ec2/cloud.py:277 +#: ../nova/db/sqlalchemy/api.py:1979 #, python-format -msgid "Create key pair %s" +msgid "No console pool with id %(pool_id)s" msgstr "" -#: nova/api/ec2/cloud.py:285 +#: ../nova/db/sqlalchemy/api.py:1996 #, python-format -msgid "Delete key pair %s" +msgid "" +"No console pool of type %(console_type)s for compute host %(compute_host)s " +"on proxy host %(host)s" msgstr "" -#: nova/api/ec2/cloud.py:357 +#: ../nova/db/sqlalchemy/api.py:2035 #, python-format -msgid "%s is not a valid ipProtocol" +msgid "No console for instance %(instance_id)s in pool %(pool_id)s" msgstr "" -#: nova/api/ec2/cloud.py:361 -msgid "Invalid port range" +#: ../nova/db/sqlalchemy/api.py:2057 +#, python-format +msgid "on instance %s" msgstr "" -#: nova/api/ec2/cloud.py:392 +#: ../nova/db/sqlalchemy/api.py:2058 #, python-format -msgid "Revoke security group ingress %s" +msgid "No console with id %(console_id)s %(idesc)s" msgstr "" -#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 -msgid "No rule for the specified parameters." +#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097 +#, python-format +msgid "No zone with id %(zone_id)s" msgstr "" -#: nova/api/ec2/cloud.py:421 +#: ../nova/virt/libvirt_conn.py:160 #, python-format -msgid "Authorize security group ingress %s" +msgid "Checking state of %s" msgstr "" -#: nova/api/ec2/cloud.py:432 +#: ../nova/virt/libvirt_conn.py:165 #, python-format -msgid "This rule already exists in group %s" +msgid "Current state of %(name)s was %(state)s." msgstr "" -#: nova/api/ec2/cloud.py:460 +#: ../nova/virt/libvirt_conn.py:183 #, python-format -msgid "Create Security Group %s" +msgid "Connecting to libvirt: %s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:196 +msgid "Connection to libvirt broke" msgstr "" -#: nova/api/ec2/cloud.py:463 +#: ../nova/virt/libvirt_conn.py:258 #, python-format -msgid "group %s already exists" +msgid "instance %(instance_name)s: deleting instance files %(target)s" msgstr "" -#: nova/api/ec2/cloud.py:475 +#: ../nova/virt/libvirt_conn.py:283 #, python-format -msgid "Delete security group %s" +msgid "Invalid device path %s" msgstr "" -#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#: ../nova/virt/libvirt_conn.py:313 #, python-format -msgid "Get console output for instance %s" +msgid "No disk at %s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:320 +msgid "Instance snapshotting is not supported for libvirtat this time" msgstr "" -#: nova/api/ec2/cloud.py:543 +#: ../nova/virt/libvirt_conn.py:336 #, python-format -msgid "Create volume of %s GB" +msgid "instance %s: rebooted" msgstr "" -#: nova/api/ec2/cloud.py:567 +#: ../nova/virt/libvirt_conn.py:339 #, python-format -msgid "Attach volume %s to instacne %s at %s" +msgid "_wait_for_reboot failed: %s" msgstr "" -#: nova/api/ec2/cloud.py:579 +#: ../nova/virt/libvirt_conn.py:382 #, python-format -msgid "Detach volume %s" +msgid "instance %s: rescued" msgstr "" -#: nova/api/ec2/cloud.py:686 -msgid "Allocate address" +#: ../nova/virt/libvirt_conn.py:385 +#, python-format +msgid "_wait_for_rescue failed: %s" msgstr "" -#: nova/api/ec2/cloud.py:691 +#: ../nova/virt/libvirt_conn.py:411 #, python-format -msgid "Release address %s" +msgid "instance %s: is running" msgstr "" -#: nova/api/ec2/cloud.py:696 +#: ../nova/virt/libvirt_conn.py:422 #, python-format -msgid "Associate address %s to instance %s" +msgid "instance %s: booted" msgstr "" -#: nova/api/ec2/cloud.py:703 +#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186 #, python-format -msgid "Disassociate address %s" +msgid "instance %s: failed to boot" msgstr "" -#: nova/api/ec2/cloud.py:730 -msgid "Going to start terminating instances" +#: ../nova/virt/libvirt_conn.py:436 +#, python-format +msgid "virsh said: %r" msgstr "" -#: nova/api/ec2/cloud.py:738 +#: ../nova/virt/libvirt_conn.py:440 +msgid "cool, it's a device" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:448 #, python-format -msgid "Reboot instance %r" +msgid "data: %(data)r, fpath: %(fpath)r" msgstr "" -#: nova/api/ec2/cloud.py:775 +#: ../nova/virt/libvirt_conn.py:456 #, python-format -msgid "De-registering image %s" +msgid "Contents of file %(fpath)s: %(contents)r" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:489 +msgid "Unable to find an open port" msgstr "" -#: nova/api/ec2/cloud.py:783 +#: ../nova/virt/libvirt_conn.py:563 #, python-format -msgid "Registered image %s with id %s" +msgid "instance %s: Creating image" msgstr "" -#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#: ../nova/virt/libvirt_conn.py:646 #, python-format -msgid "attribute not supported: %s" +msgid "instance %(inst_name)s: injecting key into image %(img_id)s" msgstr "" -#: nova/api/ec2/cloud.py:794 +#: ../nova/virt/libvirt_conn.py:649 #, python-format -msgid "invalid id: %s" +msgid "instance %(inst_name)s: injecting net into image %(img_id)s" msgstr "" -#: nova/api/ec2/cloud.py:807 -msgid "user or group not specified" +#. 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 "" -#: nova/api/ec2/cloud.py:809 -msgid "only group \"all\" is supported" +#. TODO(termie): cache? +#: ../nova/virt/libvirt_conn.py:665 +#, python-format +msgid "instance %s: starting toXML method" msgstr "" -#: nova/api/ec2/cloud.py:811 -msgid "operation_type must be add or remove" +#: ../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/api/ec2/cloud.py:812 +#: ../nova/virt/libvirt_conn.py:1225 #, python-format -msgid "Updating image %s publicity" +msgid "Attempted to unfilter instance %s which is not filtered" msgstr "" -#: nova/api/ec2/metadatarequesthandler.py:75 +#: ../nova/api/ec2/metadatarequesthandler.py:76 #, python-format msgid "Failed to get metadata for ip: %s" msgstr "" -#: nova/api/openstack/__init__.py:70 +#: ../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 "Caught error: %s" +msgid "Tried to remove non-existant console %(console_id)s." msgstr "" -#: nova/api/openstack/__init__.py:86 -msgid "Including admin operations in API." +#: ../nova/api/direct.py:149 +msgid "not available" msgstr "" -#: nova/api/openstack/servers.py:184 +#: ../nova/api/ec2/cloud.py:62 #, python-format -msgid "Compute.api::lock %s" +msgid "The key_pair %s already exists" msgstr "" -#: nova/api/openstack/servers.py:199 +#. TODO(vish): Do this with M2Crypto instead +#: ../nova/api/ec2/cloud.py:118 #, python-format -msgid "Compute.api::unlock %s" +msgid "Generating root CA: %s" msgstr "" -#: nova/api/openstack/servers.py:213 +#: ../nova/api/ec2/cloud.py:303 #, python-format -msgid "Compute.api::get_lock %s" +msgid "Create key pair %s" msgstr "" -#: nova/api/openstack/servers.py:224 +#: ../nova/api/ec2/cloud.py:311 #, python-format -msgid "Compute.api::pause %s" +msgid "Delete key pair %s" msgstr "" -#: nova/api/openstack/servers.py:235 +#: ../nova/api/ec2/cloud.py:386 #, python-format -msgid "Compute.api::unpause %s" +msgid "%s is not a valid ipProtocol" msgstr "" -#: nova/api/openstack/servers.py:246 -#, python-format -msgid "compute.api::suspend %s" +#: ../nova/api/ec2/cloud.py:390 +msgid "Invalid port range" msgstr "" -#: nova/api/openstack/servers.py:257 +#: ../nova/api/ec2/cloud.py:421 #, python-format -msgid "compute.api::resume %s" +msgid "Revoke security group ingress %s" msgstr "" -#: nova/auth/dbdriver.py:84 -#, python-format -msgid "User %s already exists" +#: ../nova/api/ec2/cloud.py:430 ../nova/api/ec2/cloud.py:459 +msgid "Not enough parameters to build a valid rule." 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" +#: ../nova/api/ec2/cloud.py:443 +msgid "No rule for the specified parameters." msgstr "" -#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#: ../nova/api/ec2/cloud.py:450 #, python-format -msgid "Project can't be created because project %s already exists" +msgid "Authorize security group ingress %s" msgstr "" -#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#: ../nova/api/ec2/cloud.py:464 #, python-format -msgid "Project can't be modified because manager %s doesn't exist" +msgid "This rule already exists in group %s" msgstr "" -#: nova/auth/dbdriver.py:245 +#: ../nova/api/ec2/cloud.py:492 #, python-format -msgid "User \"%s\" not found" +msgid "Create Security Group %s" msgstr "" -#: nova/auth/dbdriver.py:248 +#: ../nova/api/ec2/cloud.py:495 #, python-format -msgid "Project \"%s\" not found" -msgstr "" - -#: nova/auth/fakeldap.py:33 -msgid "Attempted to instantiate singleton" +msgid "group %s already exists" msgstr "" -#: nova/auth/ldapdriver.py:181 +#: ../nova/api/ec2/cloud.py:507 #, python-format -msgid "LDAP object for %s doesn't exist" +msgid "Delete security group %s" msgstr "" -#: nova/auth/ldapdriver.py:218 +#: ../nova/api/ec2/cloud.py:584 #, python-format -msgid "Project can't be created because user %s doesn't exist" +msgid "Create volume of %s GB" msgstr "" -#: nova/auth/ldapdriver.py:478 +#: ../nova/api/ec2/cloud.py:612 #, python-format -msgid "User %s is already a member of the group %s" +msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s" msgstr "" -#: nova/auth/ldapdriver.py:507 +#: ../nova/api/ec2/cloud.py:629 #, python-format -msgid "" -"Attempted to remove the last member of a group. Deleting the group at %s " -"instead." +msgid "Detach volume %s" msgstr "" -#: nova/auth/ldapdriver.py:528 -#, python-format -msgid "Group at dn %s doesn't exist" +#: ../nova/api/ec2/cloud.py:761 +msgid "Allocate address" msgstr "" -#: nova/auth/manager.py:259 +#: ../nova/api/ec2/cloud.py:766 #, python-format -msgid "Looking up user: %r" +msgid "Release address %s" msgstr "" -#: nova/auth/manager.py:263 +#: ../nova/api/ec2/cloud.py:771 #, python-format -msgid "Failed authorization for access key %s" +msgid "Associate address %(public_ip)s to instance %(instance_id)s" msgstr "" -#: nova/auth/manager.py:264 +#: ../nova/api/ec2/cloud.py:780 #, python-format -msgid "No user found for access key %s" +msgid "Disassociate address %s" msgstr "" -#: nova/auth/manager.py:270 -#, python-format -msgid "Using project name = user name (%s)" +#: ../nova/api/ec2/cloud.py:807 +msgid "Going to start terminating instances" msgstr "" -#: nova/auth/manager.py:275 +#: ../nova/api/ec2/cloud.py:815 #, python-format -msgid "failed authorization: no project named %s (user=%s)" +msgid "Reboot instance %r" msgstr "" -#: nova/auth/manager.py:277 +#: ../nova/api/ec2/cloud.py:867 #, python-format -msgid "No project called %s could be found" +msgid "De-registering image %s" msgstr "" -#: nova/auth/manager.py:281 +#: ../nova/api/ec2/cloud.py:875 #, python-format -msgid "Failed authorization: user %s not admin and not member of project %s" +msgid "Registered image %(image_location)s with id %(image_id)s" msgstr "" -#: nova/auth/manager.py:283 +#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900 #, python-format -msgid "User %s is not a member of project %s" +msgid "attribute not supported: %s" msgstr "" -#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#: ../nova/api/ec2/cloud.py:890 #, python-format -msgid "Invalid signature for user %s" +msgid "invalid id: %s" msgstr "" -#: nova/auth/manager.py:293 nova/auth/manager.py:304 -msgid "Signature does not match" +#: ../nova/api/ec2/cloud.py:903 +msgid "user or group not specified" msgstr "" -#: nova/auth/manager.py:374 -msgid "Must specify project" +#: ../nova/api/ec2/cloud.py:905 +msgid "only group \"all\" is supported" msgstr "" -#: nova/auth/manager.py:408 -#, python-format -msgid "The %s role can not be found" +#: ../nova/api/ec2/cloud.py:907 +msgid "operation_type must be add or remove" msgstr "" -#: nova/auth/manager.py:410 +#: ../nova/api/ec2/cloud.py:908 #, python-format -msgid "The %s role is global only" +msgid "Updating image %s publicity" msgstr "" -#: nova/auth/manager.py:412 +#: ../bin/nova-api.py:52 #, python-format -msgid "Adding role %s to user %s in project %s" +msgid "Using paste.deploy config at: %s" msgstr "" -#: nova/auth/manager.py:438 +#: ../bin/nova-api.py:57 #, python-format -msgid "Removing role %s from user %s on project %s" +msgid "No paste configuration for app: %s" msgstr "" -#: nova/auth/manager.py:505 +#: ../bin/nova-api.py:59 #, python-format -msgid "Created project %s with manager %s" +msgid "" +"App Config: %(api)s\n" +"%(config)r" msgstr "" -#: nova/auth/manager.py:523 +#: ../bin/nova-api.py:64 #, python-format -msgid "modifying project %s" +msgid "Running %s API" msgstr "" -#: nova/auth/manager.py:553 +#: ../bin/nova-api.py:69 #, python-format -msgid "Remove user %s from project %s" +msgid "No known API applications configured in %s." msgstr "" -#: nova/auth/manager.py:581 +#: ../bin/nova-api.py:83 #, python-format -msgid "Deleting project %s" +msgid "Starting nova-api node (version %s)" msgstr "" -#: nova/auth/manager.py:637 +#: ../bin/nova-api.py:89 #, python-format -msgid "Created user %s (admin: %r)" +msgid "No paste configuration found for: %s" msgstr "" -#: nova/auth/manager.py:645 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84 #, python-format -msgid "Deleting user %s" +msgid "Argument %(key)s value %(value)s is too short." msgstr "" -#: nova/auth/manager.py:655 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89 #, python-format -msgid "Access Key change for user %s" +msgid "Argument %(key)s value %(value)s contains invalid characters." msgstr "" -#: nova/auth/manager.py:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94 #, python-format -msgid "Secret Key change for user %s" +msgid "Argument %(key)s value %(value)s starts with a hyphen." msgstr "" -#: nova/auth/manager.py:659 +#: ../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 "Admin status set to %r for user %s" +msgid "Argument %s is required." msgstr "" -#: nova/auth/manager.py:708 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117 #, 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" +msgid "" +"Argument %(key)s may not take value %(value)s. Valid values are ['true', " +"'false']." msgstr "" -#: nova/cloudpipe/pipelib.py:51 -msgid "Netmask to push into openvpn config" +#: ../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/cloudpipe/pipelib.py:97 +#: ../nova/virt/xenapi/vmops.py:67 #, python-format -msgid "Launching VPN for %s" +msgid "Attempted to create non-unique name %s" msgstr "" -#: nova/compute/api.py:67 +#: ../nova/virt/xenapi/vmops.py:73 #, python-format -msgid "Instance %d was not found in get_network_topic" +msgid "instance %(name)s: not enough free memory" msgstr "" -#: nova/compute/api.py:73 +#: ../nova/virt/xenapi/vmops.py:148 #, python-format -msgid "Instance %d has no host" +msgid "Starting VM %s..." msgstr "" -#: nova/compute/api.py:92 +#: ../nova/virt/xenapi/vmops.py:151 #, python-format -msgid "Quota exceeeded for %s, tried to run %s instances" +msgid "Spawning VM %(instance_name)s created %(vm_ref)s." msgstr "" -#: nova/compute/api.py:94 +#: ../nova/virt/xenapi/vmops.py:162 #, python-format -msgid "" -"Instance quota exceeded. You can only run %s more instances of this type." +msgid "Invalid value for onset_files: '%s'" msgstr "" -#: nova/compute/api.py:109 -msgid "Creating a raw instance" +#: ../nova/virt/xenapi/vmops.py:167 +#, python-format +msgid "Injecting file path: '%s'" msgstr "" -#: nova/compute/api.py:156 +#: ../nova/virt/xenapi/vmops.py:180 #, python-format -msgid "Going to run %s instances..." +msgid "Instance %s: booted" msgstr "" -#: nova/compute/api.py:180 +#: ../nova/virt/xenapi/vmops.py:232 #, python-format -msgid "Casting to scheduler for %s/%s's instance %s" +msgid "Instance not present %s" msgstr "" -#: nova/compute/api.py:279 +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vmops.py:261 #, python-format -msgid "Going to try and terminate %s" +msgid "Starting snapshot for VM %s" msgstr "" -#: nova/compute/api.py:283 +#: ../nova/virt/xenapi/vmops.py:269 #, python-format -msgid "Instance %d was not found during terminate" +msgid "Unable to Snapshot %(vm_ref)s: %(exc)s" msgstr "" -#: nova/compute/api.py:288 +#: ../nova/virt/xenapi/vmops.py:280 #, python-format -msgid "Instance %d is already being terminated" +msgid "Finished snapshot and upload for VM %s" msgstr "" -#: nova/compute/api.py:450 +#: ../nova/virt/xenapi/vmops.py:356 #, python-format -msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgid "VM %(vm)s already halted, skipping shutdown..." msgstr "" -#: nova/compute/api.py:465 -msgid "Volume isn't attached to anything!" +#: ../nova/virt/xenapi/vmops.py:389 +msgid "Removing kernel/ramdisk files" msgstr "" -#: nova/compute/disk.py:71 -#, python-format -msgid "Input partition size not evenly divisible by sector size: %d / %d" +#: ../nova/virt/xenapi/vmops.py:399 +msgid "kernel/ramdisk files removed" msgstr "" -#: nova/compute/disk.py:75 +#: ../nova/virt/xenapi/vmops.py:561 #, python-format -msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgid "" +"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/disk.py:128 +#: ../nova/virt/xenapi/vmops.py:564 #, python-format -msgid "Could not attach image to loopback: %s" +msgid "" +"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM " +"id=%(instance_id)s; args=%(strargs)s" msgstr "" -#: nova/compute/disk.py:136 +#: ../nova/virt/xenapi/vmops.py:569 #, python-format -msgid "Failed to load partition: %s" +msgid "" +"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/disk.py:158 +#: ../nova/virt/xenapi/vmops.py:760 #, python-format -msgid "Failed to mount filesystem: %s" +msgid "OpenSSL error: %s" msgstr "" -#: nova/compute/instance_types.py:41 +#: ../nova/tests/test_compute.py:148 #, python-format -msgid "Unknown instance type: %s" +msgid "Running instances: %s" msgstr "" -#: nova/compute/manager.py:69 +#: ../nova/tests/test_compute.py:154 #, python-format -msgid "check_instance_lock: decorating: |%s|" +msgid "After terminating instances: %s" msgstr "" -#: nova/compute/manager.py:71 -#, python-format -msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +#: ../nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" msgstr "" -#: nova/compute/manager.py:75 -#, python-format -msgid "check_instance_lock: locked: |%s|" +#: ../nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" msgstr "" -#: nova/compute/manager.py:77 -#, python-format -msgid "check_instance_lock: admin: |%s|" +#: ../nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" msgstr "" -#: nova/compute/manager.py:82 +#: ../nova/cloudpipe/pipelib.py:97 #, python-format -msgid "check_instance_lock: executing: |%s|" +msgid "Launching VPN for %s" msgstr "" -#: nova/compute/manager.py:86 -#, python-format -msgid "check_instance_lock: not executing |%s|" +#: ../nova/db/sqlalchemy/migration.py:35 +msgid "python-migrate is not installed. Exiting." msgstr "" -#: nova/compute/manager.py:157 -msgid "Instance has already been created" +#: ../nova/image/s3.py:99 +#, python-format +msgid "Image %s could not be found" msgstr "" -#: nova/compute/manager.py:158 -#, python-format -msgid "instance %s: starting..." +#: ../nova/api/ec2/__init__.py:121 +msgid "Too many failed authentications." msgstr "" -#: nova/compute/manager.py:197 +#: ../nova/api/ec2/__init__.py:131 #, python-format -msgid "instance %s: Failed to spawn" +msgid "" +"Access key %(access_key)s has had %(failures)d failed authentications and " +"will be locked out for %(lock_mins)d minutes." msgstr "" -#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140 #, python-format -msgid "Terminating instance %s" +msgid "Authentication Failure: %s" msgstr "" -#: nova/compute/manager.py:217 +#: ../nova/api/ec2/__init__.py:182 #, python-format -msgid "Disassociating address %s" +msgid "Authenticated Request For %(uname)s:%(pname)s)" msgstr "" -#: nova/compute/manager.py:230 +#: ../nova/api/ec2/__init__.py:207 #, python-format -msgid "Deallocating address %s" +msgid "action: %s" msgstr "" -#: nova/compute/manager.py:243 +#: ../nova/api/ec2/__init__.py:209 #, python-format -msgid "trying to destroy already destroyed instance: %s" +msgid "arg: %(key)s\t\tval: %(value)s" msgstr "" -#: nova/compute/manager.py:257 +#: ../nova/api/ec2/__init__.py:281 #, python-format -msgid "Rebooting instance %s" +msgid "" +"Unauthorized request for controller=%(controller)s and action=%(action)s" msgstr "" -#: nova/compute/manager.py:260 +#: ../nova/api/ec2/__init__.py:314 #, python-format -msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgid "InstanceNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:286 +#: ../nova/api/ec2/__init__.py:320 #, python-format -msgid "instance %s: snapshotting" +msgid "VolumeNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:289 +#: ../nova/api/ec2/__init__.py:326 #, python-format -msgid "" -"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgid "NotFound raised: %s" msgstr "" -#: nova/compute/manager.py:301 +#: ../nova/api/ec2/__init__.py:329 #, python-format -msgid "instance %s: rescuing" +msgid "ApiError raised: %s" msgstr "" -#: nova/compute/manager.py:316 +#: ../nova/api/ec2/__init__.py:338 #, python-format -msgid "instance %s: unrescuing" +msgid "Unexpected error raised: %s" msgstr "" -#: nova/compute/manager.py:335 -#, python-format -msgid "instance %s: pausing" +#: ../nova/api/ec2/__init__.py:343 +msgid "An unknown error has occurred. Please try your request again." msgstr "" -#: nova/compute/manager.py:352 +#: ../nova/auth/dbdriver.py:84 #, python-format -msgid "instance %s: unpausing" +msgid "User %s already exists" msgstr "" -#: nova/compute/manager.py:369 +#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232 #, python-format -msgid "instance %s: retrieving diagnostics" +msgid "Project can't be created because manager %s doesn't exist" msgstr "" -#: nova/compute/manager.py:382 +#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243 #, python-format -msgid "instance %s: suspending" +msgid "Project can't be created because user %s doesn't exist" msgstr "" -#: nova/compute/manager.py:401 +#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229 #, python-format -msgid "instance %s: resuming" +msgid "Project can't be created because project %s already exists" msgstr "" -#: nova/compute/manager.py:420 +#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268 #, python-format -msgid "instance %s: locking" +msgid "Project can't be modified because manager %s doesn't exist" msgstr "" -#: nova/compute/manager.py:432 +#: ../nova/auth/dbdriver.py:245 #, python-format -msgid "instance %s: unlocking" +msgid "User \"%s\" not found" msgstr "" -#: nova/compute/manager.py:442 +#: ../nova/auth/dbdriver.py:248 #, python-format -msgid "instance %s: getting locked state" +msgid "Project \"%s\" not found" msgstr "" -#: nova/compute/manager.py:462 -#, python-format -msgid "instance %s: attaching volume %s to %s" +#: ../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/compute/manager.py:478 +#: ../nova/virt/xenapi_conn.py:311 #, python-format -msgid "instance %s: attach failed %s, removing" +msgid "Task [%(name)s] %(task)s status: success %(result)s" msgstr "" -#: nova/compute/manager.py:493 +#: ../nova/virt/xenapi_conn.py:317 #, python-format -msgid "Detach volume %s from mountpoint %s on instance %s" +msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s" msgstr "" -#: nova/compute/manager.py:497 +#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344 #, python-format -msgid "Detaching volume from unknown instance %s" +msgid "Got exception: %s" msgstr "" -#: nova/compute/monitor.py:259 +#: ../nova/compute/monitor.py:259 #, python-format msgid "updating %s..." msgstr "" -#: nova/compute/monitor.py:289 +#: ../nova/compute/monitor.py:289 msgid "unexpected error during update" msgstr "" -#: nova/compute/monitor.py:355 +#: ../nova/compute/monitor.py:356 #, python-format -msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/monitor.py:377 +#: ../nova/compute/monitor.py:379 #, python-format -msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/monitor.py:412 +#: ../nova/compute/monitor.py:414 msgid "unexpected exception getting connection" msgstr "" -#: nova/compute/monitor.py:427 +#: ../nova/compute/monitor.py:429 #, 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 +#: ../nova/volume/san.py:67 #, python-format -msgid "No service for id %s" +msgid "Could not find iSCSI export for volume %s" msgstr "" -#: nova/db/sqlalchemy/api.py:229 +#: ../nova/api/ec2/apirequest.py:100 #, python-format -msgid "No service for %s, %s" +msgid "" +"Unsupported API request: controller = %(controller)s, action = %(action)s" msgstr "" -#: nova/db/sqlalchemy/api.py:574 +#: ../nova/api/openstack/__init__.py:55 #, python-format -msgid "No floating ip for address %s" +msgid "Caught error: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:668 -#, python-format -msgid "No instance for id %s" +#: ../nova/api/openstack/__init__.py:76 +msgid "Including admin operations in API." 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" +#: ../nova/console/xvp.py:99 +msgid "Rebuilding xvp conf" msgstr "" -#: nova/db/sqlalchemy/api.py:891 +#: ../nova/console/xvp.py:116 #, python-format -msgid "no keypair for user %s, name %s" +msgid "Re-wrote %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 -#, python-format -msgid "No network for id %s" +#: ../nova/console/xvp.py:121 +msgid "Stopping xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1036 -#, python-format -msgid "No network for bridge %s" +#: ../nova/console/xvp.py:134 +msgid "Starting xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1050 +#: ../nova/console/xvp.py:141 #, python-format -msgid "No network for instance %s" +msgid "Error starting xvp: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1180 -#, python-format -msgid "Token %s does not exist" +#: ../nova/console/xvp.py:144 +msgid "Restarting xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1205 -#, python-format -msgid "No quota for project_id %s" +#: ../nova/console/xvp.py:146 +msgid "xvp not running..." msgstr "" -#: nova/db/sqlalchemy/api.py:1356 -#, python-format -msgid "No volume for id %s" +#: ../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 "" -#: nova/db/sqlalchemy/api.py:1401 -#, python-format -msgid "Volume %s not found" +#: ../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 "" -#: nova/db/sqlalchemy/api.py:1413 -#, python-format -msgid "No export device found for volume %s" +#: ../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/db/sqlalchemy/api.py:1426 -#, python-format -msgid "No target id found for volume %s" +#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536 +msgid "network" msgstr "" -#: nova/db/sqlalchemy/api.py:1471 -#, python-format -msgid "No security group with id %s" +#: ../bin/nova-manage.py:448 +msgid "IP address" msgstr "" -#: nova/db/sqlalchemy/api.py:1488 -#, python-format -msgid "No security group named %s for project: %s" +#: ../bin/nova-manage.py:449 +msgid "MAC address" msgstr "" -#: nova/db/sqlalchemy/api.py:1576 -#, python-format -msgid "No secuity group rule with id %s" +#: ../bin/nova-manage.py:450 +msgid "hostname" msgstr "" -#: nova/db/sqlalchemy/api.py:1650 -#, python-format -msgid "No user for id %s" +#: ../bin/nova-manage.py:451 +msgid "host" msgstr "" -#: nova/db/sqlalchemy/api.py:1666 -#, python-format -msgid "No user for access key %s" +#: ../bin/nova-manage.py:537 +msgid "netmask" msgstr "" -#: nova/db/sqlalchemy/api.py:1728 -#, python-format -msgid "No project with id %s" +#: ../bin/nova-manage.py:538 +msgid "start address" msgstr "" -#: nova/image/glance.py:78 +#: ../nova/virt/disk.py:69 #, python-format -msgid "Parallax returned HTTP error %d from request for /images" +msgid "Failed to load partition: %s" msgstr "" -#: nova/image/glance.py:97 +#: ../nova/virt/disk.py:91 #, python-format -msgid "Parallax returned HTTP error %d from request for /images/detail" +msgid "Failed to mount filesystem: %s" msgstr "" -#: nova/image/s3.py:82 +#: ../nova/virt/disk.py:124 #, python-format -msgid "Image %s could not be found" +msgid "nbd device %s did not show up" msgstr "" -#: nova/network/api.py:39 +#: ../nova/virt/disk.py:128 #, python-format -msgid "Quota exceeeded for %s, tried to allocate address" +msgid "Could not attach image to loopback: %s" msgstr "" -#: nova/network/api.py:42 -msgid "Address quota exceeded. You cannot allocate any more addresses" +#: ../nova/virt/disk.py:151 +msgid "No free nbd devices" msgstr "" -#: nova/network/linux_net.py:176 +#: ../doc/ext/nova_todo.py:46 #, python-format -msgid "Starting VLAN inteface %s" +msgid "%(filename)s, line %(line_info)d" msgstr "" -#: nova/network/linux_net.py:186 -#, python-format -msgid "Starting Bridge interface for %s" +#. FIXME(chiradeep): implement this +#: ../nova/virt/hyperv.py:118 +msgid "In init host" msgstr "" -#: nova/network/linux_net.py:254 +#: ../nova/virt/hyperv.py:131 #, python-format -msgid "Hupping dnsmasq threw %s" +msgid "Attempt to create duplicate vm %s" msgstr "" -#: nova/network/linux_net.py:256 +#: ../nova/virt/hyperv.py:148 #, python-format -msgid "Pid %d is stale, relaunching dnsmasq" +msgid "Starting VM %s " msgstr "" -#: nova/network/linux_net.py:334 +#: ../nova/virt/hyperv.py:150 #, python-format -msgid "Killing dnsmasq threw %s" +msgid "Started VM %s " msgstr "" -#: nova/network/manager.py:135 -msgid "setting network host" +#: ../nova/virt/hyperv.py:152 +#, python-format +msgid "spawn vm failed: %s" msgstr "" -#: nova/network/manager.py:190 +#: ../nova/virt/hyperv.py:169 #, python-format -msgid "Leasing IP %s" +msgid "Failed to create VM %s" msgstr "" -#: nova/network/manager.py:194 +#: ../nova/virt/hyperv.py:188 #, python-format -msgid "IP %s leased that isn't associated" +msgid "Set memory for vm %s..." msgstr "" -#: nova/network/manager.py:197 +#: ../nova/virt/hyperv.py:198 #, python-format -msgid "IP %s leased to bad mac %s vs %s" +msgid "Set vcpus for vm %s..." msgstr "" -#: nova/network/manager.py:205 +#: ../nova/virt/hyperv.py:202 #, python-format -msgid "IP %s leased that was already deallocated" +msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s" msgstr "" -#: nova/network/manager.py:214 +#: ../nova/virt/hyperv.py:227 #, python-format -msgid "IP %s released that isn't associated" +msgid "Failed to add diskdrive to VM %s" msgstr "" -#: nova/network/manager.py:217 +#: ../nova/virt/hyperv.py:230 #, python-format -msgid "IP %s released from bad mac %s vs %s" +msgid "New disk drive path is %s" msgstr "" -#: nova/network/manager.py:220 +#: ../nova/virt/hyperv.py:247 #, python-format -msgid "IP %s released that was not leased" +msgid "Failed to add vhd file to VM %s" msgstr "" -#: nova/network/manager.py:442 +#: ../nova/virt/hyperv.py:249 #, python-format -msgid "Dissassociated %s stale fixed ip(s)" +msgid "Created disk for %s" msgstr "" -#: nova/objectstore/handler.py:106 +#: ../nova/virt/hyperv.py:253 #, python-format -msgid "Unknown S3 value type %r" +msgid "Creating nic for %s " msgstr "" -#: nova/objectstore/handler.py:137 -msgid "Authenticated request" +#: ../nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" msgstr "" -#: nova/objectstore/handler.py:182 -msgid "List of buckets requested" +#: ../nova/virt/hyperv.py:273 +#, python-format +msgid "Failed creating port for %s" msgstr "" -#: nova/objectstore/handler.py:209 +#: ../nova/virt/hyperv.py:276 #, python-format -msgid "List keys for bucket %s" +msgid "Created switch port %(vm_name)s on switch %(ext_path)s" msgstr "" -#: nova/objectstore/handler.py:217 +#: ../nova/virt/hyperv.py:286 #, python-format -msgid "Unauthorized attempt to access bucket %s" +msgid "Failed to add nic to VM %s" +msgstr "" + +#: ../nova/virt/hyperv.py:288 +#, python-format +msgid "Created nic for %s " msgstr "" -#: nova/objectstore/handler.py:235 +#: ../nova/virt/hyperv.py:321 #, python-format -msgid "Creating bucket %s" +msgid "WMI job failed: %s" msgstr "" -#: nova/objectstore/handler.py:245 +#: ../nova/virt/hyperv.py:325 #, python-format -msgid "Deleting bucket %s" +msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s " msgstr "" -#: nova/objectstore/handler.py:249 +#: ../nova/virt/hyperv.py:361 #, python-format -msgid "Unauthorized attempt to delete bucket %s" +msgid "Got request to destroy vm %s" msgstr "" -#: nova/objectstore/handler.py:271 +#: ../nova/virt/hyperv.py:386 #, python-format -msgid "Getting object: %s / %s" +msgid "Failed to destroy vm %s" msgstr "" -#: nova/objectstore/handler.py:274 +#: ../nova/virt/hyperv.py:393 #, python-format -msgid "Unauthorized attempt to get object %s from bucket %s" +msgid "Del: disk %(vhdfile)s vm %(instance_name)s" msgstr "" -#: nova/objectstore/handler.py:292 +#: ../nova/virt/hyperv.py:415 #, python-format -msgid "Putting object: %s / %s" +msgid "" +"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, " +"num_cpu=%(numprocs)s, cpu_time=%(uptime)s" msgstr "" -#: nova/objectstore/handler.py:295 +#: ../nova/virt/hyperv.py:451 #, python-format -msgid "Unauthorized attempt to upload object %s to bucket %s" +msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/objectstore/handler.py:314 +#: ../nova/virt/hyperv.py:454 #, python-format -msgid "Deleting object: %s / %s" +msgid "Failed to change vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/objectstore/handler.py:393 +#: ../nova/compute/api.py:71 #, python-format -msgid "Not authorized to upload image: invalid directory %s" +msgid "Instance %d was not found in get_network_topic" msgstr "" -#: nova/objectstore/handler.py:401 +#: ../nova/compute/api.py:77 #, python-format -msgid "Not authorized to upload image: unauthorized bucket %s" +msgid "Instance %d has no host" msgstr "" -#: nova/objectstore/handler.py:406 +#: ../nova/compute/api.py:97 #, python-format -msgid "Starting image upload: %s" +msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances" msgstr "" -#: nova/objectstore/handler.py:420 +#: ../nova/compute/api.py:99 #, python-format -msgid "Not authorized to update attributes of image %s" +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." msgstr "" -#: nova/objectstore/handler.py:428 -#, python-format -msgid "Toggling publicity flag of image %s %r" +#: ../nova/compute/api.py:112 +msgid "Creating a raw instance" msgstr "" -#: nova/objectstore/handler.py:433 +#: ../nova/compute/api.py:160 #, python-format -msgid "Updating user fields on image %s" +msgid "Going to run %s instances..." msgstr "" -#: nova/objectstore/handler.py:447 +#: ../nova/compute/api.py:187 #, python-format -msgid "Unauthorized attempt to delete image %s" +msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s" msgstr "" -#: nova/objectstore/handler.py:452 +#: ../nova/compute/api.py:292 #, python-format -msgid "Deleted image: %s" +msgid "Going to try to terminate %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" +#: ../nova/compute/api.py:296 +#, python-format +msgid "Instance %d was not found during terminate" msgstr "" -#: nova/scheduler/driver.py:66 -msgid "Must implement a fallback schedule" +#: ../nova/compute/api.py:301 +#, python-format +msgid "Instance %d is already being terminated" msgstr "" -#: nova/scheduler/manager.py:69 +#: ../nova/compute/api.py:481 #, python-format -msgid "Casting to %s %s for %s" +msgid "Invalid device specified: %s. Example device: /dev/vdb" msgstr "" -#: nova/scheduler/simple.py:63 -msgid "All hosts have too many cores" +#: ../nova/compute/api.py:496 +msgid "Volume isn't attached to anything!" msgstr "" -#: nova/scheduler/simple.py:95 -msgid "All hosts have too many gigabytes" +#: ../nova/rpc.py:98 +#, python-format +msgid "" +"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in " +"%(fl_intv)d seconds." msgstr "" -#: nova/scheduler/simple.py:115 -msgid "All hosts have too many networks" +#: ../nova/rpc.py:103 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." msgstr "" -#: nova/tests/test_cloud.py:198 -msgid "Can't test instances without a real virtual env." +#: ../nova/rpc.py:122 +msgid "Reconnected to queue" msgstr "" -#: nova/tests/test_cloud.py:210 -#, python-format -msgid "Need to watch instance %s until it's running..." +#: ../nova/rpc.py:129 +msgid "Failed to fetch message from queue" msgstr "" -#: nova/tests/test_compute.py:104 +#: ../nova/rpc.py:159 #, python-format -msgid "Running instances: %s" +msgid "Initing the Adapter Consumer for %s" msgstr "" -#: nova/tests/test_compute.py:110 +#: ../nova/rpc.py:178 #, python-format -msgid "After terminating instances: %s" +msgid "received %s" msgstr "" -#: nova/tests/test_rpc.py:89 +#. 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:191 #, python-format -msgid "Nested received %s, %s" +msgid "no method for message: %s" msgstr "" -#: nova/tests/test_rpc.py:94 +#: ../nova/rpc.py:192 #, python-format -msgid "Nested return %s" +msgid "No method for message: %s" msgstr "" -#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#: ../nova/rpc.py:253 #, python-format -msgid "Received %s" +msgid "Returning exception %s to caller" msgstr "" -#: nova/tests/test_volume.py:162 +#: ../nova/rpc.py:294 #, python-format -msgid "Target %s allocated" +msgid "unpacked context: %s" msgstr "" -#: nova/virt/connection.py:73 -msgid "Failed to open connection to the hypervisor" +#: ../nova/rpc.py:313 +msgid "Making asynchronous call..." msgstr "" -#: nova/virt/fake.py:210 +#: ../nova/rpc.py:316 #, python-format -msgid "Instance %s Not Found" +msgid "MSG_ID is %s" msgstr "" -#: nova/virt/hyperv.py:118 -msgid "In init host" +#: ../nova/rpc.py:354 +msgid "Making asynchronous cast..." msgstr "" -#: nova/virt/hyperv.py:131 +#: ../nova/rpc.py:364 #, python-format -msgid "Attempt to create duplicate vm %s" +msgid "response %s" msgstr "" -#: nova/virt/hyperv.py:148 +#: ../nova/rpc.py:373 #, python-format -msgid "Starting VM %s " +msgid "topic is %s" msgstr "" -#: nova/virt/hyperv.py:150 +#: ../nova/rpc.py:374 #, python-format -msgid "Started VM %s " +msgid "message %s" msgstr "" -#: nova/virt/hyperv.py:152 +#: ../nova/volume/driver.py:78 #, python-format -msgid "spawn vm failed: %s" +msgid "Recovering from a failed execute. Try number %s" msgstr "" -#: nova/virt/hyperv.py:169 +#: ../nova/volume/driver.py:87 #, python-format -msgid "Failed to create VM %s" +msgid "volume group %s doesn't exist" msgstr "" -#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#: ../nova/volume/driver.py:220 #, python-format -msgid "Created VM %s..." +msgid "FAKE AOE: %s" msgstr "" -#: nova/virt/hyperv.py:188 -#, python-format -msgid "Set memory for vm %s..." +#: ../nova/volume/driver.py:233 +msgid "Skipping ensure_export. No iscsi_target " msgstr "" -#: nova/virt/hyperv.py:198 -#, python-format -msgid "Set vcpus for vm %s..." +#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288 +msgid "Skipping remove_export. No iscsi_target " msgstr "" -#: nova/virt/hyperv.py:202 +#: ../nova/volume/driver.py:347 #, python-format -msgid "Creating disk for %s by attaching disk file %s" +msgid "FAKE ISCSI: %s" msgstr "" -#: nova/virt/hyperv.py:227 +#: ../nova/volume/driver.py:359 #, python-format -msgid "Failed to add diskdrive to VM %s" +msgid "rbd has no pool %s" msgstr "" -#: nova/virt/hyperv.py:230 +#: ../nova/volume/driver.py:414 #, python-format -msgid "New disk drive path is %s" +msgid "Sheepdog is not working: %s" msgstr "" -#: nova/virt/hyperv.py:247 -#, python-format -msgid "Failed to add vhd file to VM %s" +#: ../nova/volume/driver.py:416 +msgid "Sheepdog is not working" msgstr "" -#: nova/virt/hyperv.py:249 +#: ../nova/wsgi.py:68 #, python-format -msgid "Created disk for %s" +msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: nova/virt/hyperv.py:253 -#, python-format -msgid "Creating nic for %s " +#: ../nova/wsgi.py:147 +msgid "You must implement __call__" msgstr "" -#: nova/virt/hyperv.py:272 -msgid "Failed creating a port on the external vswitch" +#: ../bin/nova-instancemonitor.py:55 +msgid "Starting instance monitor" msgstr "" -#: nova/virt/hyperv.py:273 -#, python-format -msgid "Failed creating port for %s" +#: ../bin/nova-dhcpbridge.py:58 +msgid "leasing ip" msgstr "" -#: nova/virt/hyperv.py:275 -#, python-format -msgid "Created switch port %s on switch %s" +#: ../bin/nova-dhcpbridge.py:73 +msgid "Adopted old lease or got a change of mac/hostname" msgstr "" -#: nova/virt/hyperv.py:285 -#, python-format -msgid "Failed to add nic to VM %s" +#: ../bin/nova-dhcpbridge.py:80 +msgid "releasing ip" msgstr "" -#: nova/virt/hyperv.py:287 +#: ../bin/nova-dhcpbridge.py:123 #, python-format -msgid "Created nic for %s " +msgid "" +"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s " +"on interface %(interface)s" msgstr "" -#: nova/virt/hyperv.py:320 +#: ../nova/virt/fake.py:239 #, python-format -msgid "WMI job failed: %s" +msgid "Instance %s Not Found" msgstr "" -#: nova/virt/hyperv.py:322 +#: ../nova/network/manager.py:153 #, python-format -msgid "WMI job succeeded: %s, Elapsed=%s " +msgid "Dissassociated %s stale fixed ip(s)" msgstr "" -#: nova/virt/hyperv.py:358 -#, python-format -msgid "Got request to destroy vm %s" +#: ../nova/network/manager.py:157 +msgid "setting network host" msgstr "" -#: nova/virt/hyperv.py:383 +#: ../nova/network/manager.py:212 #, python-format -msgid "Failed to destroy vm %s" +msgid "Leasing IP %s" msgstr "" -#: nova/virt/hyperv.py:389 +#: ../nova/network/manager.py:216 #, python-format -msgid "Del: disk %s vm %s" +msgid "IP %s leased that isn't associated" msgstr "" -#: nova/virt/hyperv.py:405 +#: ../nova/network/manager.py:220 #, python-format -msgid "" -"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " -"cpu_time=%s" +msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#: ../nova/network/manager.py:228 #, python-format -msgid "duplicate name found: %s" +msgid "IP %s leased that was already deallocated" msgstr "" -#: nova/virt/hyperv.py:444 +#: ../nova/network/manager.py:233 #, python-format -msgid "Successfully changed vm state of %s to %s" +msgid "Releasing IP %s" msgstr "" -#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#: ../nova/network/manager.py:237 #, python-format -msgid "Failed to change vm state of %s to %s" +msgid "IP %s released that isn't associated" msgstr "" -#: nova/virt/images.py:70 +#: ../nova/network/manager.py:241 #, python-format -msgid "Finished retreving %s -- placed in %s" +msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/libvirt_conn.py:144 +#: ../nova/network/manager.py:244 #, python-format -msgid "Connecting to libvirt: %s" +msgid "IP %s released that was not leased" msgstr "" -#: nova/virt/libvirt_conn.py:157 -msgid "Connection to libvirt broke" +#: ../nova/network/manager.py:519 +msgid "" +"The sum between the number of networks and the vlan start cannot be greater " +"than 4094" msgstr "" -#: nova/virt/libvirt_conn.py:229 +#: ../nova/virt/xenapi/volume_utils.py:57 #, python-format -msgid "instance %s: deleting instance files %s" +msgid "Introducing %s..." msgstr "" -#: nova/virt/libvirt_conn.py:271 +#: ../nova/virt/xenapi/volume_utils.py:74 #, python-format -msgid "No disk at %s" +msgid "Introduced %(label)s as %(sr_ref)s." msgstr "" -#: nova/virt/libvirt_conn.py:278 -msgid "Instance snapshotting is not supported for libvirtat this time" +#: ../nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" msgstr "" -#: nova/virt/libvirt_conn.py:294 +#: ../nova/virt/xenapi/volume_utils.py:90 #, python-format -msgid "instance %s: rebooted" +msgid "Unable to find SR from VBD %s" msgstr "" -#: nova/virt/libvirt_conn.py:297 +#: ../nova/virt/xenapi/volume_utils.py:96 #, python-format -msgid "_wait_for_reboot failed: %s" +msgid "Forgetting SR %s ... " msgstr "" -#: nova/virt/libvirt_conn.py:340 +#: ../nova/virt/xenapi/volume_utils.py:101 #, python-format -msgid "instance %s: rescued" +msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s" msgstr "" -#: nova/virt/libvirt_conn.py:343 +#: ../nova/virt/xenapi/volume_utils.py:107 #, python-format -msgid "_wait_for_rescue failed: %s" +msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s" msgstr "" -#: nova/virt/libvirt_conn.py:370 +#: ../nova/virt/xenapi/volume_utils.py:111 #, python-format -msgid "instance %s: is running" +msgid "Forgetting SR %s done." msgstr "" -#: nova/virt/libvirt_conn.py:381 +#: ../nova/virt/xenapi/volume_utils.py:113 #, python-format -msgid "instance %s: booted" +msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s" msgstr "" -#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#: ../nova/virt/xenapi/volume_utils.py:123 #, python-format -msgid "instance %s: failed to boot" +msgid "Unable to introduce VDI on SR %s" msgstr "" -#: nova/virt/libvirt_conn.py:395 +#: ../nova/virt/xenapi/volume_utils.py:128 #, python-format -msgid "virsh said: %r" -msgstr "" - -#: nova/virt/libvirt_conn.py:399 -msgid "cool, it's a device" +msgid "Unable to get record of VDI %s on" msgstr "" -#: nova/virt/libvirt_conn.py:407 +#: ../nova/virt/xenapi/volume_utils.py:146 #, python-format -msgid "data: %r, fpath: %r" +msgid "Unable to introduce VDI for SR %s" msgstr "" -#: nova/virt/libvirt_conn.py:415 +#: ../nova/virt/xenapi/volume_utils.py:175 #, python-format -msgid "Contents of file %s: %r" +msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s" msgstr "" -#: nova/virt/libvirt_conn.py:449 +#: ../nova/virt/xenapi/volume_utils.py:197 #, python-format -msgid "instance %s: Creating image" +msgid "Mountpoint cannot be translated: %s" msgstr "" -#: nova/virt/libvirt_conn.py:505 +#: ../nova/objectstore/image.py:262 #, python-format -msgid "instance %s: injecting key into image %s" +msgid "Failed to decrypt private key: %s" msgstr "" -#: nova/virt/libvirt_conn.py:508 +#: ../nova/objectstore/image.py:269 #, python-format -msgid "instance %s: injecting net into image %s" +msgid "Failed to decrypt initialization vector: %s" msgstr "" -#: nova/virt/libvirt_conn.py:516 +#: ../nova/objectstore/image.py:277 #, python-format -msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgid "Failed to decrypt image file %(image_file)s: %(err)s" msgstr "" -#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#: ../nova/objectstore/handler.py:106 #, python-format -msgid "instance %s: starting toXML method" +msgid "Unknown S3 value type %r" msgstr "" -#: nova/virt/libvirt_conn.py:589 -#, python-format -msgid "instance %s: finished toXML method" +#: ../nova/objectstore/handler.py:137 +msgid "Authenticated request" 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" +#: ../nova/objectstore/handler.py:182 +msgid "List of buckets requested" msgstr "" -#: nova/virt/xenapi_conn.py:263 +#: ../nova/objectstore/handler.py:209 #, python-format -msgid "Task [%s] %s status: success %s" +msgid "List keys for bucket %s" msgstr "" -#: nova/virt/xenapi_conn.py:271 +#: ../nova/objectstore/handler.py:217 #, python-format -msgid "Task [%s] %s status: %s %s" +msgid "Unauthorized attempt to access bucket %s" msgstr "" -#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#: ../nova/objectstore/handler.py:235 #, python-format -msgid "Got exception: %s" +msgid "Creating bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:72 +#: ../nova/objectstore/handler.py:245 #, 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" +msgid "Deleting bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:249 +#: ../nova/objectstore/handler.py:249 #, python-format -msgid "xenapi.fake does not have an implementation for %s" +msgid "Unauthorized attempt to delete bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:283 +#: ../nova/objectstore/handler.py:273 #, python-format -msgid "Calling %s %s" +msgid "Getting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/fake.py:288 +#: ../nova/objectstore/handler.py:276 #, python-format -msgid "Calling getter %s" +msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/fake.py:340 +#: ../nova/objectstore/handler.py:296 #, python-format -msgid "" -"xenapi.fake does not have an implementation for %s or it has been called " -"with the wrong number of arguments" +msgid "Putting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/network_utils.py:40 +#: ../nova/objectstore/handler.py:299 #, python-format -msgid "Found non-unique network for bridge %s" +msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/network_utils.py:43 +#: ../nova/objectstore/handler.py:318 #, python-format -msgid "Found no network for bridge %s" +msgid "Deleting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:127 +#: ../nova/objectstore/handler.py:322 #, python-format -msgid "Created VM %s as %s." +msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:147 +#: ../nova/objectstore/handler.py:396 #, python-format -msgid "Creating VBD for VM %s, VDI %s ... " +msgid "Not authorized to upload image: invalid directory %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:149 +#: ../nova/objectstore/handler.py:404 #, python-format -msgid "Created VBD %s for VM %s, VDI %s." +msgid "Not authorized to upload image: unauthorized bucket %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:165 +#: ../nova/objectstore/handler.py:409 #, python-format -msgid "VBD not found in instance %s" +msgid "Starting image upload: %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:175 +#: ../nova/objectstore/handler.py:423 #, python-format -msgid "Unable to unplug VBD %s" +msgid "Not authorized to update attributes of image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:187 +#: ../nova/objectstore/handler.py:431 #, python-format -msgid "Unable to destroy VBD %s" +msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r" msgstr "" -#: nova/virt/xenapi/vm_utils.py:202 +#. other attributes imply update +#: ../nova/objectstore/handler.py:436 #, python-format -msgid "Creating VIF for VM %s, network %s." +msgid "Updating user fields on image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:205 +#: ../nova/objectstore/handler.py:450 #, python-format -msgid "Created VIF %s for VM %s, network %s." +msgid "Unauthorized attempt to delete image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:216 +#: ../nova/objectstore/handler.py:455 #, python-format -msgid "Snapshotting VM %s with label '%s'..." +msgid "Deleted image: %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:229 +#: ../nova/auth/manager.py:259 #, python-format -msgid "Created snapshot %s from VM %s." +msgid "Looking up user: %r" msgstr "" -#: nova/virt/xenapi/vm_utils.py:243 +#: ../nova/auth/manager.py:263 #, python-format -msgid "Asking xapi to upload %s as '%s'" +msgid "Failed authorization for access key %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:261 +#: ../nova/auth/manager.py:264 #, python-format -msgid "Asking xapi to fetch %s as %s" +msgid "No user found for access key %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:279 +#: ../nova/auth/manager.py:270 #, python-format -msgid "Looking up vdi %s for PV kernel" +msgid "Using project name = user name (%s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:290 +#: ../nova/auth/manager.py:277 #, python-format -msgid "PV Kernel in VDI:%d" +msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:318 +#: ../nova/auth/manager.py:279 #, python-format -msgid "VDI %s is still available" +msgid "No project called %s could be found" msgstr "" -#: nova/virt/xenapi/vm_utils.py:331 +#: ../nova/auth/manager.py:287 #, python-format -msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgid "" +"Failed authorization: user %(uname)s not admin and not member of project " +"%(pjname)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:333 +#: ../nova/auth/manager.py:289 #, python-format -msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgid "User %(uid)s is not a member of project %(pjid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:390 +#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309 #, python-format -msgid "VHD %s has parent %s" +msgid "Invalid signature for user %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:407 -#, python-format -msgid "Re-scanning SR %s" +#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310 +msgid "Signature does not match" msgstr "" -#: nova/virt/xenapi/vm_utils.py:431 -#, python-format -msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +#: ../nova/auth/manager.py:380 +msgid "Must specify project" msgstr "" -#: nova/virt/xenapi/vm_utils.py:448 +#: ../nova/auth/manager.py:414 #, python-format -msgid "No VDIs found for VM %s" +msgid "The %s role can not be found" msgstr "" -#: nova/virt/xenapi/vm_utils.py:452 +#: ../nova/auth/manager.py:416 #, python-format -msgid "Unexpected number of VDIs (%s) found for VM %s" +msgid "The %s role is global only" msgstr "" -#: nova/virt/xenapi/vmops.py:62 +#: ../nova/auth/manager.py:420 #, python-format -msgid "Attempted to create non-unique name %s" +msgid "Adding role %(role)s to user %(uid)s in project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:99 +#: ../nova/auth/manager.py:423 #, python-format -msgid "Starting VM %s..." +msgid "Adding sitewide role %(role)s to user %(uid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:101 +#: ../nova/auth/manager.py:448 #, python-format -msgid "Spawning VM %s created %s." +msgid "Removing role %(role)s from user %(uid)s on project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:112 +#: ../nova/auth/manager.py:451 #, python-format -msgid "Instance %s: booted" +msgid "Removing sitewide role %(role)s from user %(uid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:137 +#: ../nova/auth/manager.py:515 #, python-format -msgid "Instance not present %s" +msgid "Created project %(name)s with manager %(manager_user)s" msgstr "" -#: nova/virt/xenapi/vmops.py:166 +#: ../nova/auth/manager.py:533 #, python-format -msgid "Starting snapshot for VM %s" +msgid "modifying project %s" msgstr "" -#: nova/virt/xenapi/vmops.py:174 +#: ../nova/auth/manager.py:545 #, python-format -msgid "Unable to Snapshot %s: %s" +msgid "Adding user %(uid)s to project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:184 +#: ../nova/auth/manager.py:566 #, python-format -msgid "Finished snapshot and upload for VM %s" +msgid "Remove user %(uid)s from project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:252 +#: ../nova/auth/manager.py:592 #, python-format -msgid "suspend: instance not present %s" +msgid "Deleting project %s" msgstr "" -#: nova/virt/xenapi/vmops.py:262 +#: ../nova/auth/manager.py:650 #, python-format -msgid "resume: instance not present %s" +msgid "Created user %(rvname)s (admin: %(rvadmin)r)" msgstr "" -#: nova/virt/xenapi/vmops.py:271 +#: ../nova/auth/manager.py:659 #, python-format -msgid "Instance not found %s" +msgid "Deleting user %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:57 +#: ../nova/auth/manager.py:669 #, python-format -msgid "Introducing %s..." +msgid "Access Key change for user %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:74 +#: ../nova/auth/manager.py:671 #, python-format -msgid "Introduced %s as %s." -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:78 -msgid "Unable to create Storage Repository" +msgid "Secret Key change for user %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:90 +#: ../nova/auth/manager.py:673 #, python-format -msgid "Unable to find SR from VBD %s" +msgid "Admin status set to %(admin)r for user %(uid)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:96 +#: ../nova/auth/manager.py:722 #, python-format -msgid "Forgetting SR %s ... " +msgid "No vpn data for project %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:101 +#: ../nova/service.py:161 #, python-format -msgid "Ignoring exception %s when getting PBDs for %s" +msgid "Starting %(topic)s node (version %(vcs_string)s)" msgstr "" -#: nova/virt/xenapi/volume_utils.py:107 -#, python-format -msgid "Ignoring exception %s when unplugging PBD %s" +#: ../nova/service.py:174 +msgid "Service killed that has no database entry" msgstr "" -#: nova/virt/xenapi/volume_utils.py:111 -#, python-format -msgid "Forgetting SR %s done." +#: ../nova/service.py:195 +msgid "The service database object disappeared, Recreating it." msgstr "" -#: nova/virt/xenapi/volume_utils.py:113 -#, python-format -msgid "Ignoring exception %s when forgetting SR %s" +#: ../nova/service.py:207 +msgid "Recovered model server connection!" msgstr "" -#: nova/virt/xenapi/volume_utils.py:123 -#, python-format -msgid "Unable to introduce VDI on SR %s" +#: ../nova/service.py:213 +msgid "model server went away" msgstr "" -#: nova/virt/xenapi/volume_utils.py:128 +#: ../nova/auth/ldapdriver.py:174 #, python-format -msgid "Unable to get record of VDI %s on" +msgid "LDAP user %s already exists" msgstr "" -#: nova/virt/xenapi/volume_utils.py:146 +#: ../nova/auth/ldapdriver.py:205 #, python-format -msgid "Unable to introduce VDI for SR %s" +msgid "LDAP object for %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:175 +#: ../nova/auth/ldapdriver.py:348 #, python-format -msgid "Unable to obtain target information %s, %s" +msgid "User %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:197 +#: ../nova/auth/ldapdriver.py:472 #, python-format -msgid "Mountpoint cannot be translated: %s" +msgid "Group can't be created because group %s already exists" msgstr "" -#: nova/virt/xenapi/volumeops.py:51 +#: ../nova/auth/ldapdriver.py:478 #, python-format -msgid "Attach_volume: %s, %s, %s" +msgid "Group can't be created because user %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:69 +#: ../nova/auth/ldapdriver.py:495 #, python-format -msgid "Unable to create VDI on SR %s for instance %s" +msgid "User %s can't be searched in group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:81 +#: ../nova/auth/ldapdriver.py:507 #, python-format -msgid "Unable to use SR %s for instance %s" +msgid "User %s can't be added to the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:93 +#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521 #, python-format -msgid "Unable to attach volume to instance %s" +msgid "The group at dn %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:95 +#: ../nova/auth/ldapdriver.py:513 #, python-format -msgid "Mountpoint %s attached to instance %s" +msgid "User %(uid)s is already a member of the group %(group_dn)s" msgstr "" -#: nova/virt/xenapi/volumeops.py:106 +#: ../nova/auth/ldapdriver.py:524 #, python-format -msgid "Detach_volume: %s, %s" +msgid "" +"User %s can't be removed from the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:113 +#: ../nova/auth/ldapdriver.py:528 #, python-format -msgid "Unable to locate volume %s" +msgid "User %s is not a member of the group" msgstr "" -#: nova/virt/xenapi/volumeops.py:121 +#: ../nova/auth/ldapdriver.py:542 #, python-format -msgid "Unable to detach volume %s" +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." msgstr "" -#: nova/virt/xenapi/volumeops.py:128 +#: ../nova/auth/ldapdriver.py:549 #, python-format -msgid "Mountpoint %s detached from instance %s" +msgid "User %s can't be removed from all because the user doesn't exist" msgstr "" -#: nova/volume/api.py:44 +#: ../nova/auth/ldapdriver.py:564 #, python-format -msgid "Quota exceeeded for %s, tried to create %sG volume" +msgid "Group at dn %s doesn't exist" msgstr "" -#: nova/volume/api.py:46 +#: ../nova/virt/xenapi/network_utils.py:40 #, 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" +msgid "Found non-unique network for bridge %s" msgstr "" -#: nova/volume/driver.py:76 +#: ../nova/virt/xenapi/network_utils.py:43 #, python-format -msgid "Recovering from a failed execute. Try number %s" +msgid "Found no network for bridge %s" msgstr "" -#: nova/volume/driver.py:85 +#: ../nova/api/ec2/admin.py:97 #, python-format -msgid "volume group %s doesn't exist" +msgid "Creating new user: %s" msgstr "" -#: nova/volume/driver.py:210 +#: ../nova/api/ec2/admin.py:105 #, python-format -msgid "FAKE AOE: %s" +msgid "Deleting user: %s" msgstr "" -#: nova/volume/driver.py:315 +#: ../nova/api/ec2/admin.py:127 #, python-format -msgid "FAKE ISCSI: %s" +msgid "Adding role %(role)s to user %(user)s for project %(project)s" msgstr "" -#: nova/volume/manager.py:85 +#: ../nova/api/ec2/admin.py:131 #, python-format -msgid "Re-exporting %s volumes" +msgid "Adding sitewide role %(role)s to user %(user)s" msgstr "" -#: nova/volume/manager.py:93 +#: ../nova/api/ec2/admin.py:137 #, python-format -msgid "volume %s: creating" +msgid "Removing role %(role)s from user %(user)s for project %(project)s" msgstr "" -#: nova/volume/manager.py:102 +#: ../nova/api/ec2/admin.py:141 #, python-format -msgid "volume %s: creating lv of size %sG" +msgid "Removing sitewide role %(role)s from user %(user)s" msgstr "" -#: nova/volume/manager.py:106 -#, python-format -msgid "volume %s: creating export" +#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223 +msgid "operation must be add or remove" msgstr "" -#: nova/volume/manager.py:113 +#: ../nova/api/ec2/admin.py:159 #, python-format -msgid "volume %s: created successfully" +msgid "Getting x509 for user: %(name)s on project: %(project)s" msgstr "" -#: nova/volume/manager.py:121 -msgid "Volume is still attached" +#: ../nova/api/ec2/admin.py:177 +#, python-format +msgid "Create project %(name)s managed by %(manager_user)s" msgstr "" -#: nova/volume/manager.py:123 -msgid "Volume is not local to this node" +#: ../nova/api/ec2/admin.py:190 +#, python-format +msgid "Modify project: %(name)s managed by %(manager_user)s" msgstr "" -#: nova/volume/manager.py:124 +#: ../nova/api/ec2/admin.py:200 #, python-format -msgid "volume %s: removing export" +msgid "Delete project: %s" msgstr "" -#: nova/volume/manager.py:126 +#: ../nova/api/ec2/admin.py:214 #, python-format -msgid "volume %s: deleting" +msgid "Adding user %(user)s to project %(project)s" msgstr "" -#: nova/volume/manager.py:129 +#: ../nova/api/ec2/admin.py:218 #, python-format -msgid "volume %s: deleted successfully" -msgstr "bind %s: slettet" +msgid "Removing user %(user)s from project %(project)s" +msgstr "" diff --git a/po/de.po b/po/de.po index 3b30c2fa9..8b4a00d72 100644 --- a/po/de.po +++ b/po/de.po @@ -7,2131 +7,2883 @@ 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-09 10:49+0000\n" -"Last-Translator: Christian Berendt \n" +"POT-Creation-Date: 2011-02-21 10:03-0500\n" +"PO-Revision-Date: 2011-04-03 19:42+0000\n" +"Last-Translator: Matthias Loidolt \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-10 05:13+0000\n" -"X-Generator: Launchpad (build 12177)\n" +"X-Launchpad-Export-Date: 2011-04-04 05:19+0000\n" +"X-Generator: Launchpad (build 12559)\n" -#: nova/crypto.py:46 +#: ../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 "Keine Computer gefunden." + +#: ../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 "" +"%(description)s\n" +"Command: %(cmd)s\n" +"Exit code: %(exit_code)s\n" +"Stdout: %(stdout)r\n" +"Stderr: %(stderr)r" +msgstr "" +"%(description)s\n" +"Befehl: %(cmd)s\n" +"Exit-Code: %(exit_code)s\n" +"Stdout: %(stdout)r\n" +"Stderr: %(stderr)r" + +#: ../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 "Nicht abgefangene Ausnahme" + +#: ../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/api/openstack/servers.py:72 +msgid "Failed to read private ip" +msgstr "" + +#: ../nova/api/openstack/servers.py:79 +msgid "Failed to read public ip(s)" +msgstr "" + +#: ../nova/api/openstack/servers.py:152 +#, python-format +msgid "%(param)s property not found for image %(_image_id)s" +msgstr "" + +#: ../nova/api/openstack/servers.py:168 +msgid "No keypairs defined" +msgstr "" + +#: ../nova/api/openstack/servers.py:238 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:253 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:267 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:281 +#, python-format +msgid "Compute.api::reset_network %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:292 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:303 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:314 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:325 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: ../nova/twistd.py:157 +msgid "Wrong number of arguments." +msgstr "" + +#: ../nova/twistd.py:209 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "PID-Datei %s existiert nicht. Läuft der Daemon nicht?\n" + +#: ../nova/twistd.py:221 +msgid "No such process" +msgstr "" + +#: ../nova/twistd.py:230 ../nova/service.py:224 +#, python-format +msgid "Serving %s" +msgstr "" + +#: ../nova/twistd.py:262 ../nova/service.py:225 +msgid "Full set of FLAGS:" +msgstr "Alle vorhandenen FLAGS:" + +#: ../nova/twistd.py:266 +#, python-format +msgid "Starting %s" +msgstr "%s wird gestartet" + +#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101 +#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741 +#: ../nova/api/ec2/__init__.py:317 +#, 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 "Dateiname der Root CA" -#: nova/crypto.py:49 -msgid "Filename of private key" -msgstr "Dateiname des Private Key" +#: ../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/scheduler/manager.py:69 +#, python-format +msgid "Casting to %(topic)s %(host)s for %(method)s" +msgstr "" + +#: ../nova/compute/manager.py:78 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:80 +#, python-format +msgid "" +"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|" +msgstr "" + +#: ../nova/compute/manager.py:84 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:91 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:95 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: ../nova/compute/manager.py:179 +msgid "Instance has already been created" +msgstr "" + +#: ../nova/compute/manager.py:180 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#. pylint: disable=W0702 +#: ../nova/compute/manager.py:219 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: ../nova/compute/manager.py:255 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: ../nova/compute/manager.py:268 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: ../nova/compute/manager.py:282 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: ../nova/compute/manager.py:287 +#, python-format +msgid "" +"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:311 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: ../nova/compute/manager.py:316 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:332 +#, python-format +msgid "" +"trying to reset the password on a non-running instance: %(instance_id)s " +"(state: %(instance_state)s expected: %(expected_state)s)" +msgstr "" + +#: ../nova/compute/manager.py:335 +#, python-format +msgid "instance %s: setting admin password" +msgstr "" + +#: ../nova/compute/manager.py:353 +#, python-format +msgid "" +"trying to inject a file into a non-running instance: %(instance_id)s (state: " +"%(instance_state)s expected: %(expected_state)s)" +msgstr "" + +#: ../nova/compute/manager.py:362 +#, python-format +msgid "instance %(nm)s: injecting file to %(plain_path)s" +msgstr "" + +#: ../nova/compute/manager.py:372 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: ../nova/compute/manager.py:387 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: ../nova/compute/manager.py:406 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: ../nova/compute/manager.py:423 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: ../nova/compute/manager.py:440 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: ../nova/compute/manager.py:453 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: ../nova/compute/manager.py:472 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: ../nova/compute/manager.py:491 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: ../nova/compute/manager.py:503 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: ../nova/compute/manager.py:513 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: ../nova/compute/manager.py:526 +#, python-format +msgid "instance %s: reset network" +msgstr "" + +#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: ../nova/compute/manager.py:543 +#, python-format +msgid "instance %s: getting ajax console" +msgstr "" + +#: ../nova/compute/manager.py:553 +#, python-format +msgid "" +"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s" +msgstr "" + +#. pylint: disable=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:569 +#, python-format +msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing" +msgstr "" + +#: ../nova/compute/manager.py:585 +#, python-format +msgid "" +"Detach volume %(volume_id)s from mountpoint %(mp)s on instance " +"%(instance_id)s" +msgstr "" + +#: ../nova/compute/manager.py:588 +#, 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 "Volume %s: wird erstellt" + +#: ../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 "Volume %s: erstelle Export" + +#: ../nova/volume/manager.py:123 +#, python-format +msgid "volume %s: created successfully" +msgstr "Volume %s: erfolgreich erstellt" + +#: ../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 "Volume %s: entferne Export" + +#: ../nova/volume/manager.py:138 +#, python-format +msgid "volume %s: deleting" +msgstr "Volume %s: wird entfernt" + +#: ../nova/volume/manager.py:147 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "Volume %s: erfolgreich entfernt" + +#: ../nova/virt/xenapi/fake.py:74 +#, python-format +msgid "%(text)s: _db_content => %(content)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:304 ../nova/virt/xenapi/fake.py:404 +#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478 +msgid "Raising NotImplemented" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:306 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:341 +#, python-format +msgid "Calling %(localname)s %(impl)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:346 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:406 +#, 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:187 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: ../nova/network/linux_net.py:208 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:314 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:316 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:358 +#, python-format +msgid "killing radvd threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:360 +#, python-format +msgid "Pid %d is stale, relaunching radvd" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:449 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: ../nova/utils.py:58 +#, python-format +msgid "Inner Exception: %s" +msgstr "" + +#: ../nova/utils.py:59 +#, python-format +msgid "Class %s cannot be found" +msgstr "Klasse %s konnte nicht gefunden werden" + +#: ../nova/utils.py:118 +#, python-format +msgid "Fetching %s" +msgstr "" + +#: ../nova/utils.py:130 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "Führe Kommando (subprocess) aus: %s" + +#: ../nova/utils.py:143 ../nova/utils.py:183 +#, python-format +msgid "Result was %s" +msgstr "Ergebnis war %s" + +#: ../nova/utils.py:159 +#, python-format +msgid "Running cmd (SSH): %s" +msgstr "" + +#: ../nova/utils.py:217 +#, python-format +msgid "debug in callback: %s" +msgstr "" + +#: ../nova/utils.py:222 +#, python-format +msgid "Running %s" +msgstr "" -#: nova/crypto.py:51 -msgid "Filename of root Certificate Revokation List" -msgstr "Dateiname der Certificate Revocation List" +#: ../nova/utils.py:262 +#, python-format +msgid "Link Local address is not found.:%s" +msgstr "" -#: nova/crypto.py:53 -msgid "Where we keep our keys" +#: ../nova/utils.py:265 +#, python-format +msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s" msgstr "" -#: nova/crypto.py:55 -msgid "Where we keep our root CA" +#: ../nova/utils.py:363 +#, python-format +msgid "Invalid backend: %s" 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/utils.py:374 +#, python-format +msgid "backend %s" +msgstr "" -#: nova/crypto.py:61 +#: ../nova/fakerabbit.py:49 #, python-format -msgid "Subject for certificate for users, %s for project, user, timestamp" +msgid "(%(nm)s) publish (key: %(routing_key)s) %(message)s" msgstr "" -#: nova/crypto.py:66 +#: ../nova/fakerabbit.py:54 #, python-format -msgid "Subject for certificate for projects, %s for project, timestamp" +msgid "Publishing to route %s" msgstr "" -#: nova/crypto.py:71 +#: ../nova/fakerabbit.py:84 #, python-format -msgid "Subject for certificate for vpns, %s for project, timestamp" +msgid "Declaring queue %s" msgstr "" -#: nova/crypto.py:258 +#: ../nova/fakerabbit.py:90 #, python-format -msgid "Flags path: %s" +msgid "Declaring exchange %s" msgstr "" -#: nova/exception.py:33 -msgid "Unexpected error while running command." -msgstr "Unerwarteter Fehler bei Ausführung des Kommandos." +#: ../nova/fakerabbit.py:96 +#, python-format +msgid "Binding %(queue)s to %(exchange)s with key %(routing_key)s" +msgstr "" -#: nova/exception.py:36 +#: ../nova/fakerabbit.py:121 #, 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" +msgid "Getting from %(queue)s: %(message)s" +msgstr "" -#: nova/fakerabbit.py:48 +#: ../nova/virt/xenapi/vm_utils.py:135 ../nova/virt/hyperv.py:171 #, python-format -msgid "(%s) publish (key: %s) %s" -msgstr "(%s) öffentlich (Schlüssel: %s) %s" +msgid "Created VM %s..." +msgstr "" -#: nova/fakerabbit.py:53 +#: ../nova/virt/xenapi/vm_utils.py:138 #, python-format -msgid "Publishing to route %s" +msgid "Created VM %(instance_name)s as %(vm_ref)s." msgstr "" -#: nova/fakerabbit.py:83 +#: ../nova/virt/xenapi/vm_utils.py:168 #, python-format -msgid "Declaring queue %s" +msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... " msgstr "" -#: nova/fakerabbit.py:89 +#: ../nova/virt/xenapi/vm_utils.py:171 #, python-format -msgid "Declaring exchange %s" +msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s." msgstr "" -#: nova/fakerabbit.py:95 +#: ../nova/virt/xenapi/vm_utils.py:187 #, python-format -msgid "Binding %s to %s with key %s" +msgid "VBD not found in instance %s" msgstr "" -#: nova/fakerabbit.py:120 +#: ../nova/virt/xenapi/vm_utils.py:197 #, python-format -msgid "Getting from %s: %s" -msgstr "Beziehe von %s: %s" +msgid "Unable to unplug VBD %s" +msgstr "" -#: nova/rpc.py:92 +#: ../nova/virt/xenapi/vm_utils.py:209 #, python-format -msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgid "Unable to destroy VBD %s" msgstr "" -"Der AMQP server %s:%d ist nicht erreichbar. Erneuter Versuch in %d Sekunden." -#: nova/rpc.py:99 +#: ../nova/virt/xenapi/vm_utils.py:224 #, python-format -msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s." msgstr "" -#: nova/rpc.py:118 -msgid "Reconnected to queue" +#: ../nova/virt/xenapi/vm_utils.py:227 +#, python-format +msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s." msgstr "" -#: nova/rpc.py:125 -msgid "Failed to fetch message from queue" +#: ../nova/virt/xenapi/vm_utils.py:246 +#, python-format +msgid "" +"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on " +"%(sr_ref)s." msgstr "" -#: nova/rpc.py:155 +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vm_utils.py:258 #, python-format -msgid "Initing the Adapter Consumer for %s" +msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..." msgstr "" -#: nova/rpc.py:170 +#: ../nova/virt/xenapi/vm_utils.py:272 #, python-format -msgid "received %s" +msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s." msgstr "" -#: nova/rpc.py:183 +#: ../nova/virt/xenapi/vm_utils.py:286 #, python-format -msgid "no method for message: %s" -msgstr "keine Methode für diese Nachricht gefunden: %s" +msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s" +msgstr "" -#: nova/rpc.py:184 +#: ../nova/virt/xenapi/vm_utils.py:327 #, python-format -msgid "No method for message: %s" -msgstr "keine Methode für diese Nachricht gefunden: %s" +msgid "Size for image %(image)s:%(virtual_size)d" +msgstr "" -#: nova/rpc.py:245 +#: ../nova/virt/xenapi/vm_utils.py:332 #, python-format -msgid "Returning exception %s to caller" +msgid "Glance image %s" msgstr "" -#: nova/rpc.py:286 +#. we need to invoke a plugin for copying VDI's +#. content into proper path +#: ../nova/virt/xenapi/vm_utils.py:342 #, python-format -msgid "unpacked context: %s" +msgid "Copying VDI %s to /boot/guest on dom0" msgstr "" -#: nova/rpc.py:305 -msgid "Making asynchronous call..." -msgstr "führe asynchronen Aufruf durch..." +#: ../nova/virt/xenapi/vm_utils.py:352 +#, python-format +msgid "Kernel/Ramdisk VDI %s destroyed" +msgstr "" -#: nova/rpc.py:308 +#: ../nova/virt/xenapi/vm_utils.py:361 #, python-format -msgid "MSG_ID is %s" -msgstr "MSG_ID ist %s" +msgid "Asking xapi to fetch %(url)s as %(access)s" +msgstr "" -#: nova/rpc.py:356 +#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402 #, python-format -msgid "response %s" +msgid "Looking up vdi %s for PV kernel" msgstr "" -#: nova/rpc.py:365 +#: ../nova/virt/xenapi/vm_utils.py:397 #, python-format -msgid "topic is %s" -msgstr "Betreff ist %s" +msgid "PV Kernel in VDI:%s" +msgstr "" -#: nova/rpc.py:366 +#: ../nova/virt/xenapi/vm_utils.py:405 #, python-format -msgid "message %s" -msgstr "Nachricht %s" +msgid "Running pygrub against %s" +msgstr "" -#: nova/service.py:157 +#: ../nova/virt/xenapi/vm_utils.py:411 #, python-format -msgid "Starting %s node" +msgid "Found Xen kernel %s" msgstr "" -#: nova/service.py:169 -msgid "Service killed that has no database entry" +#: ../nova/virt/xenapi/vm_utils.py:413 +msgid "No Xen kernel found. Booting HVM." msgstr "" -#: nova/service.py:190 -msgid "The service database object disappeared, Recreating it." +#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431 +#, python-format +msgid "duplicate name found: %s" msgstr "" -#: nova/service.py:202 -msgid "Recovered model server connection!" +#: ../nova/virt/xenapi/vm_utils.py:442 +#, python-format +msgid "VDI %s is still available" msgstr "" -#: nova/service.py:208 -msgid "model server went away" +#: ../nova/virt/xenapi/vm_utils.py:463 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" msgstr "" -#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#: ../nova/virt/xenapi/vm_utils.py:465 #, python-format -msgid "Data store %s is unreachable. Trying again in %d seconds." +msgid "(VM_UTILS) xenapi power_state -> |%s|" msgstr "" -"Datastore %s ist nicht erreichbar. Versuche es erneut in %d Sekunden." -#: nova/service.py:232 nova/twistd.py:232 +#: ../nova/virt/xenapi/vm_utils.py:525 #, python-format -msgid "Serving %s" +msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s" msgstr "" -#: nova/service.py:234 nova/twistd.py:264 -msgid "Full set of FLAGS:" -msgstr "Alle vorhandenen FLAGS:" +#: ../nova/virt/xenapi/vm_utils.py:542 +#, python-format +msgid "Re-scanning SR %s" +msgstr "" -#: nova/twistd.py:211 +#: ../nova/virt/xenapi/vm_utils.py:567 #, python-format -msgid "pidfile %s does not exist. Daemon not running?\n" -msgstr "PID-Datei %s existiert nicht. Läuft der Daemon nicht?\n" +msgid "" +"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..." +msgstr "" -#: nova/twistd.py:268 +#: ../nova/virt/xenapi/vm_utils.py:574 #, python-format -msgid "Starting %s" -msgstr "%s wird gestartet" +msgid "" +"Parent %(parent_uuid)s doesn't match original parent " +"%(original_parent_uuid)s, waiting for coalesce..." +msgstr "" -#: nova/utils.py:53 +#: ../nova/virt/xenapi/vm_utils.py:590 #, python-format -msgid "Inner Exception: %s" +msgid "No VDIs found for VM %s" msgstr "" -#: nova/utils.py:54 +#: ../nova/virt/xenapi/vm_utils.py:594 #, python-format -msgid "Class %s cannot be found" -msgstr "Klasse %s konnte nicht gefunden werden" +msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s" +msgstr "" -#: nova/utils.py:113 +#: ../nova/virt/xenapi/vm_utils.py:653 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188 #, python-format -msgid "Fetching %s" +msgid "Creating VBD for VDI %s ... " msgstr "" -#: nova/utils.py:125 +#: ../nova/virt/xenapi/vm_utils.py:655 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190 #, python-format -msgid "Running cmd (subprocess): %s" -msgstr "Führe Kommando (subprocess) aus: %s" +msgid "Creating VBD for VDI %s done." +msgstr "" -#: nova/utils.py:138 +#: ../nova/virt/xenapi/vm_utils.py:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192 #, python-format -msgid "Result was %s" -msgstr "Ergebnis war %s" +msgid "Plugging VBD %s ... " +msgstr "" -#: nova/utils.py:171 +#: ../nova/virt/xenapi/vm_utils.py:659 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:194 #, python-format -msgid "debug in callback: %s" +msgid "Plugging VBD %s done." msgstr "" -#: nova/utils.py:176 +#: ../nova/virt/xenapi/vm_utils.py:661 #, python-format -msgid "Running %s" +msgid "VBD %(vbd)s plugged as %(orig_dev)s" msgstr "" -#: nova/utils.py:207 +#: ../nova/virt/xenapi/vm_utils.py:664 #, python-format -msgid "Couldn't get IP, using 127.0.0.1 %s" +msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s" msgstr "" -#: nova/utils.py:289 +#: ../nova/virt/xenapi/vm_utils.py:668 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:197 #, python-format -msgid "Invalid backend: %s" +msgid "Destroying VBD for VDI %s ... " msgstr "" -#: nova/utils.py:300 +#: ../nova/virt/xenapi/vm_utils.py:671 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:200 #, python-format -msgid "backend %s" +msgid "Destroying VBD for VDI %s done." msgstr "" -#: nova/api/ec2/__init__.py:133 -msgid "Too many failed authentications." +#: ../nova/virt/xenapi/vm_utils.py:683 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211 +msgid "VBD.unplug successful first time." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:688 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216 +msgid "VBD.unplug rejected: retrying..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:692 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220 +msgid "VBD.unplug successful eventually." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:695 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:223 +#, python-format +msgid "Ignoring XenAPI.Failure in VBD.unplug: %s" msgstr "" -#: nova/api/ec2/__init__.py:142 +#: ../nova/virt/xenapi/vm_utils.py:704 +#: ../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:735 #, python-format msgid "" -"Access key %s has had %d failed authentications and will be locked out for " -"%d minutes." +"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..." msgstr "" -#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#: ../nova/virt/xenapi/vm_utils.py:747 #, python-format -msgid "Authentication Failure: %s" +msgid "Writing partition table %s done." msgstr "" -#: nova/api/ec2/__init__.py:190 +#: ../nova/tests/test_rpc.py:89 #, python-format -msgid "Authenticated Request For %s:%s)" +msgid "Nested received %(queue)s, %(value)s" msgstr "" -#: nova/api/ec2/__init__.py:227 +#: ../nova/tests/test_rpc.py:95 #, python-format -msgid "action: %s" +msgid "Nested return %s" msgstr "" -#: nova/api/ec2/__init__.py:229 +#: ../nova/tests/test_rpc.py:120 ../nova/tests/test_rpc.py:126 #, python-format -msgid "arg: %s\t\tval: %s" +msgid "Received %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:44 +msgid "Use of empty request context is deprecated" msgstr "" -#: nova/api/ec2/__init__.py:301 +#: ../nova/db/sqlalchemy/api.py:133 #, python-format -msgid "Unauthorized request for controller=%s and action=%s" +msgid "No service for id %s" msgstr "" -#: nova/api/ec2/__init__.py:339 +#: ../nova/db/sqlalchemy/api.py:251 #, python-format -msgid "NotFound raised: %s" +msgid "No service for %(host)s, %(binary)s" msgstr "" -#: nova/api/ec2/__init__.py:342 +#: ../nova/db/sqlalchemy/api.py:592 +msgid "No fixed ips defined" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:608 #, python-format -msgid "ApiError raised: %s" +msgid "No floating ip for address %s" msgstr "" -#: nova/api/ec2/__init__.py:349 +#: ../nova/db/sqlalchemy/api.py:629 #, python-format -msgid "Unexpected error raised: %s" +msgid "No address for instance %s" msgstr "" -#: nova/api/ec2/__init__.py:354 -msgid "An unknown error has occurred. Please try your request again." +#: ../nova/db/sqlalchemy/api.py:961 +#, python-format +msgid "no keypair for user %(user_id)s, name %(name)s" msgstr "" -#: nova/api/ec2/admin.py:84 +#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156 #, python-format -msgid "Creating new user: %s" +msgid "No network for id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1086 +msgid "No networks defined" msgstr "" -#: nova/api/ec2/admin.py:92 +#: ../nova/db/sqlalchemy/api.py:1115 #, python-format -msgid "Deleting user: %s" +msgid "No network for bridge %s" msgstr "" -#: nova/api/ec2/admin.py:114 +#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142 #, python-format -msgid "Adding role %s to user %s for project %s" +msgid "No network for instance %s" msgstr "" -#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#: ../nova/db/sqlalchemy/api.py:1277 #, python-format -msgid "Adding sitewide role %s to user %s" +msgid "Token %s does not exist" msgstr "" -#: nova/api/ec2/admin.py:122 +#: ../nova/db/sqlalchemy/api.py:1302 #, python-format -msgid "Removing role %s from user %s for project %s" +msgid "No quota for project_id %s" msgstr "" -#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501 +#: ../nova/api/ec2/__init__.py:323 #, python-format -msgid "Removing sitewide role %s from user %s" +msgid "Volume %s not found" msgstr "" -#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 -msgid "operation must be add or remove" +#: ../nova/db/sqlalchemy/api.py:1514 +#, python-format +msgid "No export device found for volume %s" msgstr "" -#: nova/api/ec2/admin.py:142 +#: ../nova/db/sqlalchemy/api.py:1527 #, python-format -msgid "Getting x509 for user: %s on project: %s" +msgid "No target id found for volume %s" msgstr "" -#: nova/api/ec2/admin.py:159 +#: ../nova/db/sqlalchemy/api.py:1572 #, python-format -msgid "Create project %s managed by %s" +msgid "No security group with id %s" msgstr "" -#: nova/api/ec2/admin.py:170 +#: ../nova/db/sqlalchemy/api.py:1589 #, python-format -msgid "Delete project: %s" +msgid "No security group named %(group_name)s for project: %(project_id)s" msgstr "" -#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#: ../nova/db/sqlalchemy/api.py:1682 #, python-format -msgid "Adding user %s to project %s" +msgid "No secuity group rule with id %s" msgstr "" -#: nova/api/ec2/admin.py:188 +#: ../nova/db/sqlalchemy/api.py:1756 #, python-format -msgid "Removing user %s from project %s" +msgid "No user for id %s" msgstr "" -#: nova/api/ec2/apirequest.py:95 +#: ../nova/db/sqlalchemy/api.py:1772 #, python-format -msgid "Unsupported API request: controller = %s,action = %s" +msgid "No user for access key %s" msgstr "" -#: nova/api/ec2/cloud.py:117 +#: ../nova/db/sqlalchemy/api.py:1834 #, python-format -msgid "Generating root CA: %s" +msgid "No project with id %s" msgstr "" -#: nova/api/ec2/cloud.py:277 +#: ../nova/db/sqlalchemy/api.py:1979 #, python-format -msgid "Create key pair %s" +msgid "No console pool with id %(pool_id)s" msgstr "" -#: nova/api/ec2/cloud.py:285 +#: ../nova/db/sqlalchemy/api.py:1996 #, python-format -msgid "Delete key pair %s" +msgid "" +"No console pool of type %(console_type)s for compute host %(compute_host)s " +"on proxy host %(host)s" msgstr "" -#: nova/api/ec2/cloud.py:357 +#: ../nova/db/sqlalchemy/api.py:2035 #, python-format -msgid "%s is not a valid ipProtocol" +msgid "No console for instance %(instance_id)s in pool %(pool_id)s" msgstr "" -#: nova/api/ec2/cloud.py:361 -msgid "Invalid port range" +#: ../nova/db/sqlalchemy/api.py:2057 +#, python-format +msgid "on instance %s" msgstr "" -#: nova/api/ec2/cloud.py:392 +#: ../nova/db/sqlalchemy/api.py:2058 #, python-format -msgid "Revoke security group ingress %s" +msgid "No console with id %(console_id)s %(idesc)s" msgstr "" -#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 -msgid "No rule for the specified parameters." +#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097 +#, python-format +msgid "No zone with id %(zone_id)s" msgstr "" -#: nova/api/ec2/cloud.py:421 +#: ../nova/virt/libvirt_conn.py:160 #, python-format -msgid "Authorize security group ingress %s" +msgid "Checking state of %s" msgstr "" -#: nova/api/ec2/cloud.py:432 +#: ../nova/virt/libvirt_conn.py:165 #, python-format -msgid "This rule already exists in group %s" +msgid "Current state of %(name)s was %(state)s." msgstr "" -#: nova/api/ec2/cloud.py:460 +#: ../nova/virt/libvirt_conn.py:183 #, python-format -msgid "Create Security Group %s" +msgid "Connecting to libvirt: %s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:196 +msgid "Connection to libvirt broke" msgstr "" -#: nova/api/ec2/cloud.py:463 +#: ../nova/virt/libvirt_conn.py:258 #, python-format -msgid "group %s already exists" +msgid "instance %(instance_name)s: deleting instance files %(target)s" msgstr "" -#: nova/api/ec2/cloud.py:475 +#: ../nova/virt/libvirt_conn.py:283 #, python-format -msgid "Delete security group %s" +msgid "Invalid device path %s" msgstr "" -#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#: ../nova/virt/libvirt_conn.py:313 #, python-format -msgid "Get console output for instance %s" +msgid "No disk at %s" msgstr "" -#: nova/api/ec2/cloud.py:543 +#: ../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 "Create volume of %s GB" +msgid "instance %s: rebooted" msgstr "" -#: nova/api/ec2/cloud.py:567 +#: ../nova/virt/libvirt_conn.py:339 #, python-format -msgid "Attach volume %s to instacne %s at %s" +msgid "_wait_for_reboot failed: %s" msgstr "" -#: nova/api/ec2/cloud.py:579 +#: ../nova/virt/libvirt_conn.py:382 #, python-format -msgid "Detach volume %s" +msgid "instance %s: rescued" msgstr "" -#: nova/api/ec2/cloud.py:686 -msgid "Allocate address" +#: ../nova/virt/libvirt_conn.py:385 +#, python-format +msgid "_wait_for_rescue failed: %s" msgstr "" -#: nova/api/ec2/cloud.py:691 +#: ../nova/virt/libvirt_conn.py:411 #, python-format -msgid "Release address %s" +msgid "instance %s: is running" msgstr "" -#: nova/api/ec2/cloud.py:696 +#: ../nova/virt/libvirt_conn.py:422 #, python-format -msgid "Associate address %s to instance %s" +msgid "instance %s: booted" msgstr "" -#: nova/api/ec2/cloud.py:703 +#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186 #, python-format -msgid "Disassociate address %s" +msgid "instance %s: failed to boot" msgstr "" -#: nova/api/ec2/cloud.py:730 -msgid "Going to start terminating instances" +#: ../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/api/ec2/cloud.py:738 +#: ../nova/virt/libvirt_conn.py:448 #, python-format -msgid "Reboot instance %r" +msgid "data: %(data)r, fpath: %(fpath)r" msgstr "" -#: nova/api/ec2/cloud.py:775 +#: ../nova/virt/libvirt_conn.py:456 #, python-format -msgid "De-registering image %s" +msgid "Contents of file %(fpath)s: %(contents)r" msgstr "" -#: nova/api/ec2/cloud.py:783 +#: ../nova/virt/libvirt_conn.py:489 +msgid "Unable to find an open port" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:563 #, python-format -msgid "Registered image %s with id %s" +msgid "instance %s: Creating image" msgstr "" -#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#: ../nova/virt/libvirt_conn.py:646 #, python-format -msgid "attribute not supported: %s" +msgid "instance %(inst_name)s: injecting key into image %(img_id)s" msgstr "" -#: nova/api/ec2/cloud.py:794 +#: ../nova/virt/libvirt_conn.py:649 #, python-format -msgid "invalid id: %s" +msgid "instance %(inst_name)s: injecting net into image %(img_id)s" msgstr "" -#: nova/api/ec2/cloud.py:807 -msgid "user or group not specified" +#. 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 "" -#: nova/api/ec2/cloud.py:809 -msgid "only group \"all\" is supported" +#. TODO(termie): cache? +#: ../nova/virt/libvirt_conn.py:665 +#, python-format +msgid "instance %s: starting toXML method" msgstr "" -#: nova/api/ec2/cloud.py:811 -msgid "operation_type must be add or remove" +#: ../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/api/ec2/cloud.py:812 +#: ../nova/virt/libvirt_conn.py:1225 #, python-format -msgid "Updating image %s publicity" +msgid "Attempted to unfilter instance %s which is not filtered" msgstr "" -#: nova/api/ec2/metadatarequesthandler.py:75 +#: ../nova/api/ec2/metadatarequesthandler.py:76 #, python-format msgid "Failed to get metadata for ip: %s" msgstr "" -#: nova/api/openstack/__init__.py:70 +#: ../nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "" + +#: ../nova/network/api.py:39 #, python-format -msgid "Caught error: %s" +msgid "Quota exceeeded for %s, tried to allocate address" msgstr "" -#: nova/api/openstack/__init__.py:86 -msgid "Including admin operations in API." +#: ../nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" msgstr "" -#: nova/api/openstack/servers.py:184 +#: ../nova/tests/test_volume.py:162 #, python-format -msgid "Compute.api::lock %s" +msgid "Target %s allocated" msgstr "" -#: nova/api/openstack/servers.py:199 +#: ../nova/virt/images.py:70 #, python-format -msgid "Compute.api::unlock %s" +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/api/openstack/servers.py:213 +#: ../nova/console/manager.py:90 #, python-format -msgid "Compute.api::get_lock %s" +msgid "Tried to remove non-existant console %(console_id)s." +msgstr "" + +#: ../nova/api/direct.py:149 +msgid "not available" msgstr "" -#: nova/api/openstack/servers.py:224 +#: ../nova/api/ec2/cloud.py:62 #, python-format -msgid "Compute.api::pause %s" +msgid "The key_pair %s already exists" msgstr "" -#: nova/api/openstack/servers.py:235 +#. TODO(vish): Do this with M2Crypto instead +#: ../nova/api/ec2/cloud.py:118 #, python-format -msgid "Compute.api::unpause %s" +msgid "Generating root CA: %s" msgstr "" -#: nova/api/openstack/servers.py:246 +#: ../nova/api/ec2/cloud.py:303 #, python-format -msgid "compute.api::suspend %s" +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:386 +#, python-format +msgid "%s is not a valid ipProtocol" msgstr "" -#: nova/api/openstack/servers.py:257 -#, python-format -msgid "compute.api::resume %s" +#: ../nova/api/ec2/cloud.py:390 +msgid "Invalid port range" msgstr "" -#: nova/auth/dbdriver.py:84 +#: ../nova/api/ec2/cloud.py:421 #, python-format -msgid "User %s already exists" +msgid "Revoke security group ingress %s" 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" +#: ../nova/api/ec2/cloud.py:430 ../nova/api/ec2/cloud.py:459 +msgid "Not enough parameters to build a valid rule." msgstr "" -#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 -#, python-format -msgid "Project can't be created because project %s already exists" +#: ../nova/api/ec2/cloud.py:443 +msgid "No rule for the specified parameters." msgstr "" -#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#: ../nova/api/ec2/cloud.py:450 #, python-format -msgid "Project can't be modified because manager %s doesn't exist" +msgid "Authorize security group ingress %s" msgstr "" -#: nova/auth/dbdriver.py:245 +#: ../nova/api/ec2/cloud.py:464 #, python-format -msgid "User \"%s\" not found" +msgid "This rule already exists in group %s" msgstr "" -#: nova/auth/dbdriver.py:248 +#: ../nova/api/ec2/cloud.py:492 #, python-format -msgid "Project \"%s\" not found" +msgid "Create Security Group %s" msgstr "" -#: nova/auth/fakeldap.py:33 -msgid "Attempted to instantiate singleton" +#: ../nova/api/ec2/cloud.py:495 +#, python-format +msgid "group %s already exists" msgstr "" -#: nova/auth/ldapdriver.py:181 +#: ../nova/api/ec2/cloud.py:507 #, python-format -msgid "LDAP object for %s doesn't exist" +msgid "Delete security group %s" msgstr "" -#: nova/auth/ldapdriver.py:218 +#: ../nova/api/ec2/cloud.py:584 #, python-format -msgid "Project can't be created because user %s doesn't exist" +msgid "Create volume of %s GB" msgstr "" -#: nova/auth/ldapdriver.py:478 +#: ../nova/api/ec2/cloud.py:612 #, python-format -msgid "User %s is already a member of the group %s" +msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s" msgstr "" -#: nova/auth/ldapdriver.py:507 +#: ../nova/api/ec2/cloud.py:629 #, python-format -msgid "" -"Attempted to remove the last member of a group. Deleting the group at %s " -"instead." +msgid "Detach volume %s" msgstr "" -#: nova/auth/ldapdriver.py:528 -#, python-format -msgid "Group at dn %s doesn't exist" +#: ../nova/api/ec2/cloud.py:761 +msgid "Allocate address" msgstr "" -#: nova/auth/manager.py:259 +#: ../nova/api/ec2/cloud.py:766 #, python-format -msgid "Looking up user: %r" +msgid "Release address %s" msgstr "" -#: nova/auth/manager.py:263 +#: ../nova/api/ec2/cloud.py:771 #, python-format -msgid "Failed authorization for access key %s" +msgid "Associate address %(public_ip)s to instance %(instance_id)s" msgstr "" -#: nova/auth/manager.py:264 +#: ../nova/api/ec2/cloud.py:780 #, python-format -msgid "No user found for access key %s" +msgid "Disassociate address %s" msgstr "" -#: nova/auth/manager.py:270 -#, python-format -msgid "Using project name = user name (%s)" +#: ../nova/api/ec2/cloud.py:807 +msgid "Going to start terminating instances" msgstr "" -#: nova/auth/manager.py:275 +#: ../nova/api/ec2/cloud.py:815 #, python-format -msgid "failed authorization: no project named %s (user=%s)" +msgid "Reboot instance %r" msgstr "" -#: nova/auth/manager.py:277 +#: ../nova/api/ec2/cloud.py:867 #, python-format -msgid "No project called %s could be found" +msgid "De-registering image %s" msgstr "" -#: nova/auth/manager.py:281 +#: ../nova/api/ec2/cloud.py:875 #, python-format -msgid "Failed authorization: user %s not admin and not member of project %s" +msgid "Registered image %(image_location)s with id %(image_id)s" msgstr "" -#: nova/auth/manager.py:283 +#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900 #, python-format -msgid "User %s is not a member of project %s" +msgid "attribute not supported: %s" msgstr "" -#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#: ../nova/api/ec2/cloud.py:890 #, python-format -msgid "Invalid signature for user %s" +msgid "invalid id: %s" msgstr "" -#: nova/auth/manager.py:293 nova/auth/manager.py:304 -msgid "Signature does not match" +#: ../nova/api/ec2/cloud.py:903 +msgid "user or group not specified" msgstr "" -#: nova/auth/manager.py:374 -msgid "Must specify project" +#: ../nova/api/ec2/cloud.py:905 +msgid "only group \"all\" is supported" msgstr "" -#: nova/auth/manager.py:408 -#, python-format -msgid "The %s role can not be found" +#: ../nova/api/ec2/cloud.py:907 +msgid "operation_type must be add or remove" msgstr "" -#: nova/auth/manager.py:410 +#: ../nova/api/ec2/cloud.py:908 #, python-format -msgid "The %s role is global only" +msgid "Updating image %s publicity" msgstr "" -#: nova/auth/manager.py:412 +#: ../bin/nova-api.py:52 #, python-format -msgid "Adding role %s to user %s in project %s" +msgid "Using paste.deploy config at: %s" msgstr "" -#: nova/auth/manager.py:438 +#: ../bin/nova-api.py:57 #, python-format -msgid "Removing role %s from user %s on project %s" +msgid "No paste configuration for app: %s" msgstr "" -#: nova/auth/manager.py:505 +#: ../bin/nova-api.py:59 #, python-format -msgid "Created project %s with manager %s" +msgid "" +"App Config: %(api)s\n" +"%(config)r" msgstr "" -#: nova/auth/manager.py:523 +#: ../bin/nova-api.py:64 #, python-format -msgid "modifying project %s" +msgid "Running %s API" msgstr "" -#: nova/auth/manager.py:553 +#: ../bin/nova-api.py:69 #, python-format -msgid "Remove user %s from project %s" +msgid "No known API applications configured in %s." msgstr "" -#: nova/auth/manager.py:581 +#: ../bin/nova-api.py:83 #, python-format -msgid "Deleting project %s" +msgid "Starting nova-api node (version %s)" msgstr "" -#: nova/auth/manager.py:637 +#: ../bin/nova-api.py:89 #, python-format -msgid "Created user %s (admin: %r)" +msgid "No paste configuration found for: %s" msgstr "" -#: nova/auth/manager.py:645 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84 #, python-format -msgid "Deleting user %s" +msgid "Argument %(key)s value %(value)s is too short." msgstr "" -#: nova/auth/manager.py:655 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89 #, python-format -msgid "Access Key change for user %s" +msgid "Argument %(key)s value %(value)s contains invalid characters." msgstr "" -#: nova/auth/manager.py:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94 #, python-format -msgid "Secret Key change for user %s" +msgid "Argument %(key)s value %(value)s starts with a hyphen." msgstr "" -#: nova/auth/manager.py:659 +#: ../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 "Admin status set to %r for user %s" +msgid "Argument %s is required." msgstr "" -#: nova/auth/manager.py:708 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117 #, 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" +msgid "" +"Argument %(key)s may not take value %(value)s. Valid values are ['true', " +"'false']." msgstr "" -#: nova/cloudpipe/pipelib.py:51 -msgid "Netmask to push into openvpn config" +#: ../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/cloudpipe/pipelib.py:97 +#: ../nova/virt/xenapi/vmops.py:67 #, python-format -msgid "Launching VPN for %s" +msgid "Attempted to create non-unique name %s" msgstr "" -#: nova/compute/api.py:67 +#: ../nova/virt/xenapi/vmops.py:73 #, python-format -msgid "Instance %d was not found in get_network_topic" +msgid "instance %(name)s: not enough free memory" msgstr "" -#: nova/compute/api.py:73 +#: ../nova/virt/xenapi/vmops.py:148 #, python-format -msgid "Instance %d has no host" +msgid "Starting VM %s..." msgstr "" -#: nova/compute/api.py:92 +#: ../nova/virt/xenapi/vmops.py:151 #, python-format -msgid "Quota exceeeded for %s, tried to run %s instances" +msgid "Spawning VM %(instance_name)s created %(vm_ref)s." msgstr "" -#: nova/compute/api.py:94 +#: ../nova/virt/xenapi/vmops.py:162 #, python-format -msgid "" -"Instance quota exceeded. You can only run %s more instances of this type." +msgid "Invalid value for onset_files: '%s'" msgstr "" -#: nova/compute/api.py:109 -msgid "Creating a raw instance" +#: ../nova/virt/xenapi/vmops.py:167 +#, python-format +msgid "Injecting file path: '%s'" msgstr "" -#: nova/compute/api.py:156 +#: ../nova/virt/xenapi/vmops.py:180 #, python-format -msgid "Going to run %s instances..." +msgid "Instance %s: booted" msgstr "" -#: nova/compute/api.py:180 +#: ../nova/virt/xenapi/vmops.py:232 #, python-format -msgid "Casting to scheduler for %s/%s's instance %s" +msgid "Instance not present %s" msgstr "" -#: nova/compute/api.py:279 +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vmops.py:261 #, python-format -msgid "Going to try and terminate %s" +msgid "Starting snapshot for VM %s" msgstr "" -#: nova/compute/api.py:283 +#: ../nova/virt/xenapi/vmops.py:269 #, python-format -msgid "Instance %d was not found during terminate" +msgid "Unable to Snapshot %(vm_ref)s: %(exc)s" msgstr "" -#: nova/compute/api.py:288 +#: ../nova/virt/xenapi/vmops.py:280 #, python-format -msgid "Instance %d is already being terminated" +msgid "Finished snapshot and upload for VM %s" msgstr "" -#: nova/compute/api.py:450 +#: ../nova/virt/xenapi/vmops.py:356 #, python-format -msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgid "VM %(vm)s already halted, skipping shutdown..." msgstr "" -#: nova/compute/api.py:465 -msgid "Volume isn't attached to anything!" +#: ../nova/virt/xenapi/vmops.py:389 +msgid "Removing kernel/ramdisk files" msgstr "" -#: nova/compute/disk.py:71 -#, python-format -msgid "Input partition size not evenly divisible by sector size: %d / %d" +#: ../nova/virt/xenapi/vmops.py:399 +msgid "kernel/ramdisk files removed" msgstr "" -#: nova/compute/disk.py:75 +#: ../nova/virt/xenapi/vmops.py:561 #, python-format -msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgid "" +"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/disk.py:128 +#: ../nova/virt/xenapi/vmops.py:564 #, python-format -msgid "Could not attach image to loopback: %s" +msgid "" +"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM " +"id=%(instance_id)s; args=%(strargs)s" msgstr "" -#: nova/compute/disk.py:136 +#: ../nova/virt/xenapi/vmops.py:569 #, python-format -msgid "Failed to load partition: %s" +msgid "" +"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/disk.py:158 +#: ../nova/virt/xenapi/vmops.py:760 #, python-format -msgid "Failed to mount filesystem: %s" +msgid "OpenSSL error: %s" msgstr "" -#: nova/compute/instance_types.py:41 +#: ../nova/tests/test_compute.py:148 #, python-format -msgid "Unknown instance type: %s" +msgid "Running instances: %s" msgstr "" -#: nova/compute/manager.py:69 +#: ../nova/tests/test_compute.py:154 #, python-format -msgid "check_instance_lock: decorating: |%s|" +msgid "After terminating instances: %s" msgstr "" -#: nova/compute/manager.py:71 -#, python-format -msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +#: ../nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" msgstr "" -#: nova/compute/manager.py:75 -#, python-format -msgid "check_instance_lock: locked: |%s|" +#: ../nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" msgstr "" -#: nova/compute/manager.py:77 -#, python-format -msgid "check_instance_lock: admin: |%s|" +#: ../nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" msgstr "" -#: nova/compute/manager.py:82 +#: ../nova/cloudpipe/pipelib.py:97 #, python-format -msgid "check_instance_lock: executing: |%s|" +msgid "Launching VPN for %s" msgstr "" -#: nova/compute/manager.py:86 -#, python-format -msgid "check_instance_lock: not executing |%s|" +#: ../nova/db/sqlalchemy/migration.py:35 +msgid "python-migrate is not installed. Exiting." msgstr "" -#: nova/compute/manager.py:157 -msgid "Instance has already been created" +#: ../nova/image/s3.py:99 +#, python-format +msgid "Image %s could not be found" msgstr "" -#: nova/compute/manager.py:158 -#, python-format -msgid "instance %s: starting..." +#: ../nova/api/ec2/__init__.py:121 +msgid "Too many failed authentications." msgstr "" -#: nova/compute/manager.py:197 +#: ../nova/api/ec2/__init__.py:131 #, python-format -msgid "instance %s: Failed to spawn" +msgid "" +"Access key %(access_key)s has had %(failures)d failed authentications and " +"will be locked out for %(lock_mins)d minutes." msgstr "" -#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140 #, python-format -msgid "Terminating instance %s" +msgid "Authentication Failure: %s" msgstr "" -#: nova/compute/manager.py:217 +#: ../nova/api/ec2/__init__.py:182 #, python-format -msgid "Disassociating address %s" +msgid "Authenticated Request For %(uname)s:%(pname)s)" msgstr "" -#: nova/compute/manager.py:230 +#: ../nova/api/ec2/__init__.py:207 #, python-format -msgid "Deallocating address %s" +msgid "action: %s" msgstr "" -#: nova/compute/manager.py:243 +#: ../nova/api/ec2/__init__.py:209 #, python-format -msgid "trying to destroy already destroyed instance: %s" +msgid "arg: %(key)s\t\tval: %(value)s" msgstr "" -#: nova/compute/manager.py:257 +#: ../nova/api/ec2/__init__.py:281 #, python-format -msgid "Rebooting instance %s" +msgid "" +"Unauthorized request for controller=%(controller)s and action=%(action)s" msgstr "" -#: nova/compute/manager.py:260 +#: ../nova/api/ec2/__init__.py:314 #, python-format -msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgid "InstanceNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:286 +#: ../nova/api/ec2/__init__.py:320 #, python-format -msgid "instance %s: snapshotting" +msgid "VolumeNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:289 +#: ../nova/api/ec2/__init__.py:326 #, python-format -msgid "" -"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgid "NotFound raised: %s" msgstr "" -#: nova/compute/manager.py:301 +#: ../nova/api/ec2/__init__.py:329 #, python-format -msgid "instance %s: rescuing" +msgid "ApiError raised: %s" msgstr "" -#: nova/compute/manager.py:316 +#: ../nova/api/ec2/__init__.py:338 #, python-format -msgid "instance %s: unrescuing" +msgid "Unexpected error raised: %s" msgstr "" -#: nova/compute/manager.py:335 -#, python-format -msgid "instance %s: pausing" +#: ../nova/api/ec2/__init__.py:343 +msgid "An unknown error has occurred. Please try your request again." msgstr "" -#: nova/compute/manager.py:352 +#: ../nova/auth/dbdriver.py:84 #, python-format -msgid "instance %s: unpausing" +msgid "User %s already exists" msgstr "" -#: nova/compute/manager.py:369 +#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232 #, python-format -msgid "instance %s: retrieving diagnostics" +msgid "Project can't be created because manager %s doesn't exist" msgstr "" -#: nova/compute/manager.py:382 +#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243 #, python-format -msgid "instance %s: suspending" +msgid "Project can't be created because user %s doesn't exist" msgstr "" -#: nova/compute/manager.py:401 +#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229 #, python-format -msgid "instance %s: resuming" +msgid "Project can't be created because project %s already exists" msgstr "" -#: nova/compute/manager.py:420 +#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268 #, python-format -msgid "instance %s: locking" +msgid "Project can't be modified because manager %s doesn't exist" msgstr "" -#: nova/compute/manager.py:432 +#: ../nova/auth/dbdriver.py:245 #, python-format -msgid "instance %s: unlocking" +msgid "User \"%s\" not found" msgstr "" -#: nova/compute/manager.py:442 +#: ../nova/auth/dbdriver.py:248 #, python-format -msgid "instance %s: getting locked state" +msgid "Project \"%s\" not found" msgstr "" -#: nova/compute/manager.py:462 -#, python-format -msgid "instance %s: attaching volume %s to %s" +#: ../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/compute/manager.py:478 +#: ../nova/virt/xenapi_conn.py:311 #, python-format -msgid "instance %s: attach failed %s, removing" +msgid "Task [%(name)s] %(task)s status: success %(result)s" msgstr "" -#: nova/compute/manager.py:493 +#: ../nova/virt/xenapi_conn.py:317 #, python-format -msgid "Detach volume %s from mountpoint %s on instance %s" +msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s" msgstr "" -#: nova/compute/manager.py:497 +#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344 #, python-format -msgid "Detaching volume from unknown instance %s" +msgid "Got exception: %s" msgstr "" -#: nova/compute/monitor.py:259 +#: ../nova/compute/monitor.py:259 #, python-format msgid "updating %s..." msgstr "" -#: nova/compute/monitor.py:289 +#: ../nova/compute/monitor.py:289 msgid "unexpected error during update" msgstr "" -#: nova/compute/monitor.py:355 +#: ../nova/compute/monitor.py:356 #, python-format -msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/monitor.py:377 +#: ../nova/compute/monitor.py:379 #, python-format -msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/monitor.py:412 +#: ../nova/compute/monitor.py:414 msgid "unexpected exception getting connection" msgstr "" -#: nova/compute/monitor.py:427 +#: ../nova/compute/monitor.py:429 #, python-format msgid "Found instance: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:43 -msgid "Use of empty request context is deprecated" +#: ../nova/volume/san.py:67 +#, python-format +msgid "Could not find iSCSI export for volume %s" msgstr "" -#: nova/db/sqlalchemy/api.py:132 +#: ../nova/api/ec2/apirequest.py:100 #, python-format -msgid "No service for id %s" +msgid "" +"Unsupported API request: controller = %(controller)s, action = %(action)s" msgstr "" -#: nova/db/sqlalchemy/api.py:229 +#: ../nova/api/openstack/__init__.py:55 #, python-format -msgid "No service for %s, %s" +msgid "Caught error: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:574 -#, python-format -msgid "No floating ip for address %s" +#: ../nova/api/openstack/__init__.py:76 +msgid "Including admin operations in API." msgstr "" -#: nova/db/sqlalchemy/api.py:668 -#, python-format -msgid "No instance for id %s" +#: ../nova/console/xvp.py:99 +msgid "Rebuilding xvp conf" 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 +#: ../nova/console/xvp.py:116 #, python-format -msgid "Instance %s not found" +msgid "Re-wrote %s" msgstr "" -#: nova/db/sqlalchemy/api.py:891 -#, python-format -msgid "no keypair for user %s, name %s" +#: ../nova/console/xvp.py:121 +msgid "Stopping xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 -#, python-format -msgid "No network for id %s" +#: ../nova/console/xvp.py:134 +msgid "Starting xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1036 +#: ../nova/console/xvp.py:141 #, python-format -msgid "No network for bridge %s" +msgid "Error starting xvp: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1050 -#, python-format -msgid "No network for instance %s" +#: ../nova/console/xvp.py:144 +msgid "Restarting xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1180 -#, python-format -msgid "Token %s does not exist" +#: ../nova/console/xvp.py:146 +msgid "xvp not running..." msgstr "" -#: nova/db/sqlalchemy/api.py:1205 -#, python-format -msgid "No quota for project_id %s" +#: ../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 "" -#: nova/db/sqlalchemy/api.py:1356 -#, python-format -msgid "No volume for id %s" +#: ../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 "" -#: nova/db/sqlalchemy/api.py:1401 -#, python-format -msgid "Volume %s not found" +#: ../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/db/sqlalchemy/api.py:1413 -#, python-format -msgid "No export device found for volume %s" +#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536 +msgid "network" msgstr "" -#: nova/db/sqlalchemy/api.py:1426 -#, python-format -msgid "No target id found for volume %s" +#: ../bin/nova-manage.py:448 +msgid "IP address" msgstr "" -#: nova/db/sqlalchemy/api.py:1471 -#, python-format -msgid "No security group with id %s" +#: ../bin/nova-manage.py:449 +msgid "MAC address" msgstr "" -#: nova/db/sqlalchemy/api.py:1488 -#, python-format -msgid "No security group named %s for project: %s" +#: ../bin/nova-manage.py:450 +msgid "hostname" msgstr "" -#: nova/db/sqlalchemy/api.py:1576 -#, python-format -msgid "No secuity group rule with id %s" +#: ../bin/nova-manage.py:451 +msgid "host" msgstr "" -#: nova/db/sqlalchemy/api.py:1650 -#, python-format -msgid "No user for id %s" +#: ../bin/nova-manage.py:537 +msgid "netmask" msgstr "" -#: nova/db/sqlalchemy/api.py:1666 -#, python-format -msgid "No user for access key %s" +#: ../bin/nova-manage.py:538 +msgid "start address" msgstr "" -#: nova/db/sqlalchemy/api.py:1728 +#: ../nova/virt/disk.py:69 #, python-format -msgid "No project with id %s" +msgid "Failed to load partition: %s" msgstr "" -#: nova/image/glance.py:78 +#: ../nova/virt/disk.py:91 #, python-format -msgid "Parallax returned HTTP error %d from request for /images" +msgid "Failed to mount filesystem: %s" msgstr "" -#: nova/image/glance.py:97 +#: ../nova/virt/disk.py:124 #, python-format -msgid "Parallax returned HTTP error %d from request for /images/detail" +msgid "nbd device %s did not show up" msgstr "" -#: nova/image/s3.py:82 +#: ../nova/virt/disk.py:128 #, python-format -msgid "Image %s could not be found" +msgid "Could not attach image to loopback: %s" msgstr "" -#: nova/network/api.py:39 +#: ../nova/virt/disk.py:151 +msgid "No free nbd devices" +msgstr "" + +#: ../doc/ext/nova_todo.py:46 #, python-format -msgid "Quota exceeeded for %s, tried to allocate address" +msgid "%(filename)s, line %(line_info)d" msgstr "" -#: nova/network/api.py:42 -msgid "Address quota exceeded. You cannot allocate any more addresses" +#. FIXME(chiradeep): implement this +#: ../nova/virt/hyperv.py:118 +msgid "In init host" msgstr "" -#: nova/network/linux_net.py:176 +#: ../nova/virt/hyperv.py:131 #, python-format -msgid "Starting VLAN inteface %s" +msgid "Attempt to create duplicate vm %s" msgstr "" -#: nova/network/linux_net.py:186 +#: ../nova/virt/hyperv.py:148 #, python-format -msgid "Starting Bridge interface for %s" +msgid "Starting VM %s " msgstr "" -#: nova/network/linux_net.py:254 +#: ../nova/virt/hyperv.py:150 #, python-format -msgid "Hupping dnsmasq threw %s" +msgid "Started VM %s " msgstr "" -#: nova/network/linux_net.py:256 +#: ../nova/virt/hyperv.py:152 #, python-format -msgid "Pid %d is stale, relaunching dnsmasq" +msgid "spawn vm failed: %s" msgstr "" -#: nova/network/linux_net.py:334 +#: ../nova/virt/hyperv.py:169 #, python-format -msgid "Killing dnsmasq threw %s" +msgid "Failed to create VM %s" msgstr "" -#: nova/network/manager.py:135 -msgid "setting network host" +#: ../nova/virt/hyperv.py:188 +#, python-format +msgid "Set memory for vm %s..." msgstr "" -#: nova/network/manager.py:190 +#: ../nova/virt/hyperv.py:198 #, python-format -msgid "Leasing IP %s" +msgid "Set vcpus for vm %s..." msgstr "" -#: nova/network/manager.py:194 +#: ../nova/virt/hyperv.py:202 #, python-format -msgid "IP %s leased that isn't associated" +msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s" msgstr "" -#: nova/network/manager.py:197 +#: ../nova/virt/hyperv.py:227 #, python-format -msgid "IP %s leased to bad mac %s vs %s" +msgid "Failed to add diskdrive to VM %s" msgstr "" -#: nova/network/manager.py:205 +#: ../nova/virt/hyperv.py:230 #, python-format -msgid "IP %s leased that was already deallocated" +msgid "New disk drive path is %s" msgstr "" -#: nova/network/manager.py:214 +#: ../nova/virt/hyperv.py:247 #, python-format -msgid "IP %s released that isn't associated" +msgid "Failed to add vhd file to VM %s" msgstr "" -#: nova/network/manager.py:217 +#: ../nova/virt/hyperv.py:249 #, python-format -msgid "IP %s released from bad mac %s vs %s" +msgid "Created disk for %s" msgstr "" -#: nova/network/manager.py:220 +#: ../nova/virt/hyperv.py:253 #, python-format -msgid "IP %s released that was not leased" +msgid "Creating nic for %s " msgstr "" -#: nova/network/manager.py:442 -#, python-format -msgid "Dissassociated %s stale fixed ip(s)" +#: ../nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" msgstr "" -#: nova/objectstore/handler.py:106 +#: ../nova/virt/hyperv.py:273 #, python-format -msgid "Unknown S3 value type %r" +msgid "Failed creating port for %s" msgstr "" -#: nova/objectstore/handler.py:137 -msgid "Authenticated request" +#: ../nova/virt/hyperv.py:276 +#, python-format +msgid "Created switch port %(vm_name)s on switch %(ext_path)s" msgstr "" -#: nova/objectstore/handler.py:182 -msgid "List of buckets requested" +#: ../nova/virt/hyperv.py:286 +#, python-format +msgid "Failed to add nic to VM %s" msgstr "" -#: nova/objectstore/handler.py:209 +#: ../nova/virt/hyperv.py:288 #, python-format -msgid "List keys for bucket %s" +msgid "Created nic for %s " msgstr "" -#: nova/objectstore/handler.py:217 +#: ../nova/virt/hyperv.py:321 #, python-format -msgid "Unauthorized attempt to access bucket %s" +msgid "WMI job failed: %s" msgstr "" -#: nova/objectstore/handler.py:235 +#: ../nova/virt/hyperv.py:325 #, python-format -msgid "Creating bucket %s" +msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s " msgstr "" -#: nova/objectstore/handler.py:245 +#: ../nova/virt/hyperv.py:361 #, python-format -msgid "Deleting bucket %s" +msgid "Got request to destroy vm %s" msgstr "" -#: nova/objectstore/handler.py:249 +#: ../nova/virt/hyperv.py:386 #, python-format -msgid "Unauthorized attempt to delete bucket %s" +msgid "Failed to destroy vm %s" msgstr "" -#: nova/objectstore/handler.py:271 +#: ../nova/virt/hyperv.py:393 #, python-format -msgid "Getting object: %s / %s" +msgid "Del: disk %(vhdfile)s vm %(instance_name)s" msgstr "" -#: nova/objectstore/handler.py:274 +#: ../nova/virt/hyperv.py:415 #, python-format -msgid "Unauthorized attempt to get object %s from bucket %s" +msgid "" +"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, " +"num_cpu=%(numprocs)s, cpu_time=%(uptime)s" msgstr "" -#: nova/objectstore/handler.py:292 +#: ../nova/virt/hyperv.py:451 #, python-format -msgid "Putting object: %s / %s" +msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/objectstore/handler.py:295 +#: ../nova/virt/hyperv.py:454 #, python-format -msgid "Unauthorized attempt to upload object %s to bucket %s" +msgid "Failed to change vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/objectstore/handler.py:314 +#: ../nova/compute/api.py:71 #, python-format -msgid "Deleting object: %s / %s" +msgid "Instance %d was not found in get_network_topic" msgstr "" -#: nova/objectstore/handler.py:393 +#: ../nova/compute/api.py:77 #, python-format -msgid "Not authorized to upload image: invalid directory %s" +msgid "Instance %d has no host" msgstr "" -#: nova/objectstore/handler.py:401 +#: ../nova/compute/api.py:97 #, python-format -msgid "Not authorized to upload image: unauthorized bucket %s" +msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances" msgstr "" -#: nova/objectstore/handler.py:406 +#: ../nova/compute/api.py:99 #, python-format -msgid "Starting image upload: %s" +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." msgstr "" -#: nova/objectstore/handler.py:420 -#, python-format -msgid "Not authorized to update attributes of image %s" +#: ../nova/compute/api.py:112 +msgid "Creating a raw instance" msgstr "" -#: nova/objectstore/handler.py:428 +#: ../nova/compute/api.py:160 #, python-format -msgid "Toggling publicity flag of image %s %r" +msgid "Going to run %s instances..." msgstr "" -#: nova/objectstore/handler.py:433 +#: ../nova/compute/api.py:187 #, python-format -msgid "Updating user fields on image %s" +msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s" msgstr "" -#: nova/objectstore/handler.py:447 +#: ../nova/compute/api.py:292 #, python-format -msgid "Unauthorized attempt to delete image %s" +msgid "Going to try to terminate %s" msgstr "" -#: nova/objectstore/handler.py:452 +#: ../nova/compute/api.py:296 #, 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" +msgid "Instance %d was not found during terminate" msgstr "" -#: nova/scheduler/driver.py:66 -msgid "Must implement a fallback schedule" +#: ../nova/compute/api.py:301 +#, python-format +msgid "Instance %d is already being terminated" msgstr "" -#: nova/scheduler/manager.py:69 +#: ../nova/compute/api.py:481 #, python-format -msgid "Casting to %s %s for %s" +msgid "Invalid device specified: %s. Example device: /dev/vdb" msgstr "" -#: nova/scheduler/simple.py:63 -msgid "All hosts have too many cores" +#: ../nova/compute/api.py:496 +msgid "Volume isn't attached to anything!" msgstr "" -#: nova/scheduler/simple.py:95 -msgid "All hosts have too many gigabytes" +#: ../nova/rpc.py:98 +#, python-format +msgid "" +"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in " +"%(fl_intv)d seconds." msgstr "" -#: nova/scheduler/simple.py:115 -msgid "All hosts have too many networks" +#: ../nova/rpc.py:103 +#, python-format +msgid "Unable to connect to AMQP server after %d tries. Shutting down." msgstr "" -#: nova/tests/test_cloud.py:198 -msgid "Can't test instances without a real virtual env." +#: ../nova/rpc.py:122 +msgid "Reconnected to queue" msgstr "" -#: nova/tests/test_cloud.py:210 -#, python-format -msgid "Need to watch instance %s until it's running..." +#: ../nova/rpc.py:129 +msgid "Failed to fetch message from queue" msgstr "" -#: nova/tests/test_compute.py:104 +#: ../nova/rpc.py:159 #, python-format -msgid "Running instances: %s" +msgid "Initing the Adapter Consumer for %s" msgstr "" -#: nova/tests/test_compute.py:110 +#: ../nova/rpc.py:178 #, python-format -msgid "After terminating instances: %s" +msgid "received %s" msgstr "" -#: nova/tests/test_rpc.py:89 +#. 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:191 #, python-format -msgid "Nested received %s, %s" -msgstr "" +msgid "no method for message: %s" +msgstr "keine Methode für diese Nachricht gefunden: %s" -#: nova/tests/test_rpc.py:94 +#: ../nova/rpc.py:192 #, python-format -msgid "Nested return %s" -msgstr "" +msgid "No method for message: %s" +msgstr "keine Methode für diese Nachricht gefunden: %s" -#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#: ../nova/rpc.py:253 #, python-format -msgid "Received %s" +msgid "Returning exception %s to caller" msgstr "" -#: nova/tests/test_volume.py:162 +#: ../nova/rpc.py:294 #, python-format -msgid "Target %s allocated" +msgid "unpacked context: %s" msgstr "" -#: nova/virt/connection.py:73 -msgid "Failed to open connection to the hypervisor" -msgstr "" +#: ../nova/rpc.py:313 +msgid "Making asynchronous call..." +msgstr "führe asynchronen Aufruf durch..." -#: nova/virt/fake.py:210 +#: ../nova/rpc.py:316 #, python-format -msgid "Instance %s Not Found" -msgstr "" +msgid "MSG_ID is %s" +msgstr "MSG_ID ist %s" -#: nova/virt/hyperv.py:118 -msgid "In init host" +#: ../nova/rpc.py:354 +msgid "Making asynchronous cast..." msgstr "" -#: nova/virt/hyperv.py:131 +#: ../nova/rpc.py:364 #, python-format -msgid "Attempt to create duplicate vm %s" +msgid "response %s" msgstr "" -#: nova/virt/hyperv.py:148 +#: ../nova/rpc.py:373 #, python-format -msgid "Starting VM %s " -msgstr "" +msgid "topic is %s" +msgstr "Betreff ist %s" -#: nova/virt/hyperv.py:150 +#: ../nova/rpc.py:374 #, python-format -msgid "Started VM %s " -msgstr "" +msgid "message %s" +msgstr "Nachricht %s" -#: nova/virt/hyperv.py:152 +#: ../nova/volume/driver.py:78 #, python-format -msgid "spawn vm failed: %s" +msgid "Recovering from a failed execute. Try number %s" msgstr "" -#: nova/virt/hyperv.py:169 +#: ../nova/volume/driver.py:87 #, python-format -msgid "Failed to create VM %s" +msgid "volume group %s doesn't exist" msgstr "" -#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#: ../nova/volume/driver.py:220 #, python-format -msgid "Created VM %s..." +msgid "FAKE AOE: %s" msgstr "" -#: nova/virt/hyperv.py:188 -#, python-format -msgid "Set memory for vm %s..." +#: ../nova/volume/driver.py:233 +msgid "Skipping ensure_export. No iscsi_target " msgstr "" -#: nova/virt/hyperv.py:198 -#, python-format -msgid "Set vcpus for vm %s..." +#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288 +msgid "Skipping remove_export. No iscsi_target " msgstr "" -#: nova/virt/hyperv.py:202 +#: ../nova/volume/driver.py:347 #, python-format -msgid "Creating disk for %s by attaching disk file %s" +msgid "FAKE ISCSI: %s" msgstr "" -#: nova/virt/hyperv.py:227 +#: ../nova/volume/driver.py:359 #, python-format -msgid "Failed to add diskdrive to VM %s" +msgid "rbd has no pool %s" msgstr "" -#: nova/virt/hyperv.py:230 +#: ../nova/volume/driver.py:414 #, python-format -msgid "New disk drive path is %s" +msgid "Sheepdog is not working: %s" msgstr "" -#: nova/virt/hyperv.py:247 -#, python-format -msgid "Failed to add vhd file to VM %s" +#: ../nova/volume/driver.py:416 +msgid "Sheepdog is not working" msgstr "" -#: nova/virt/hyperv.py:249 +#: ../nova/wsgi.py:68 #, python-format -msgid "Created disk for %s" +msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: nova/virt/hyperv.py:253 -#, python-format -msgid "Creating nic for %s " +#: ../nova/wsgi.py:147 +msgid "You must implement __call__" msgstr "" -#: nova/virt/hyperv.py:272 -msgid "Failed creating a port on the external vswitch" +#: ../bin/nova-instancemonitor.py:55 +msgid "Starting instance monitor" msgstr "" -#: nova/virt/hyperv.py:273 -#, python-format -msgid "Failed creating port for %s" +#: ../bin/nova-dhcpbridge.py:58 +msgid "leasing ip" msgstr "" -#: nova/virt/hyperv.py:275 -#, python-format -msgid "Created switch port %s on switch %s" +#: ../bin/nova-dhcpbridge.py:73 +msgid "Adopted old lease or got a change of mac/hostname" msgstr "" -#: nova/virt/hyperv.py:285 -#, python-format -msgid "Failed to add nic to VM %s" +#: ../bin/nova-dhcpbridge.py:80 +msgid "releasing ip" msgstr "" -#: nova/virt/hyperv.py:287 +#: ../bin/nova-dhcpbridge.py:123 #, python-format -msgid "Created nic for %s " +msgid "" +"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s " +"on interface %(interface)s" msgstr "" -#: nova/virt/hyperv.py:320 +#: ../nova/virt/fake.py:239 #, python-format -msgid "WMI job failed: %s" +msgid "Instance %s Not Found" msgstr "" -#: nova/virt/hyperv.py:322 +#: ../nova/network/manager.py:153 #, python-format -msgid "WMI job succeeded: %s, Elapsed=%s " +msgid "Dissassociated %s stale fixed ip(s)" msgstr "" -#: nova/virt/hyperv.py:358 -#, python-format -msgid "Got request to destroy vm %s" +#: ../nova/network/manager.py:157 +msgid "setting network host" msgstr "" -#: nova/virt/hyperv.py:383 +#: ../nova/network/manager.py:212 #, python-format -msgid "Failed to destroy vm %s" +msgid "Leasing IP %s" msgstr "" -#: nova/virt/hyperv.py:389 +#: ../nova/network/manager.py:216 #, python-format -msgid "Del: disk %s vm %s" +msgid "IP %s leased that isn't associated" msgstr "" -#: nova/virt/hyperv.py:405 +#: ../nova/network/manager.py:220 #, python-format -msgid "" -"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " -"cpu_time=%s" +msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#: ../nova/network/manager.py:228 #, python-format -msgid "duplicate name found: %s" +msgid "IP %s leased that was already deallocated" msgstr "" -#: nova/virt/hyperv.py:444 +#: ../nova/network/manager.py:233 #, python-format -msgid "Successfully changed vm state of %s to %s" +msgid "Releasing IP %s" msgstr "" -#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#: ../nova/network/manager.py:237 #, python-format -msgid "Failed to change vm state of %s to %s" +msgid "IP %s released that isn't associated" msgstr "" -#: nova/virt/images.py:70 +#: ../nova/network/manager.py:241 #, python-format -msgid "Finished retreving %s -- placed in %s" +msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/libvirt_conn.py:144 +#: ../nova/network/manager.py:244 #, python-format -msgid "Connecting to libvirt: %s" +msgid "IP %s released that was not leased" msgstr "" -#: nova/virt/libvirt_conn.py:157 -msgid "Connection to libvirt broke" +#: ../nova/network/manager.py:519 +msgid "" +"The sum between the number of networks and the vlan start cannot be greater " +"than 4094" msgstr "" -#: nova/virt/libvirt_conn.py:229 +#: ../nova/virt/xenapi/volume_utils.py:57 #, python-format -msgid "instance %s: deleting instance files %s" +msgid "Introducing %s..." msgstr "" -#: nova/virt/libvirt_conn.py:271 +#: ../nova/virt/xenapi/volume_utils.py:74 #, python-format -msgid "No disk at %s" +msgid "Introduced %(label)s as %(sr_ref)s." msgstr "" -#: nova/virt/libvirt_conn.py:278 -msgid "Instance snapshotting is not supported for libvirtat this time" +#: ../nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" msgstr "" -#: nova/virt/libvirt_conn.py:294 +#: ../nova/virt/xenapi/volume_utils.py:90 #, python-format -msgid "instance %s: rebooted" +msgid "Unable to find SR from VBD %s" msgstr "" -#: nova/virt/libvirt_conn.py:297 +#: ../nova/virt/xenapi/volume_utils.py:96 #, python-format -msgid "_wait_for_reboot failed: %s" +msgid "Forgetting SR %s ... " msgstr "" -#: nova/virt/libvirt_conn.py:340 +#: ../nova/virt/xenapi/volume_utils.py:101 #, python-format -msgid "instance %s: rescued" +msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s" msgstr "" -#: nova/virt/libvirt_conn.py:343 +#: ../nova/virt/xenapi/volume_utils.py:107 #, python-format -msgid "_wait_for_rescue failed: %s" +msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s" msgstr "" -#: nova/virt/libvirt_conn.py:370 +#: ../nova/virt/xenapi/volume_utils.py:111 #, python-format -msgid "instance %s: is running" +msgid "Forgetting SR %s done." msgstr "" -#: nova/virt/libvirt_conn.py:381 +#: ../nova/virt/xenapi/volume_utils.py:113 #, python-format -msgid "instance %s: booted" +msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s" msgstr "" -#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#: ../nova/virt/xenapi/volume_utils.py:123 #, python-format -msgid "instance %s: failed to boot" +msgid "Unable to introduce VDI on SR %s" msgstr "" -#: nova/virt/libvirt_conn.py:395 +#: ../nova/virt/xenapi/volume_utils.py:128 #, python-format -msgid "virsh said: %r" -msgstr "" - -#: nova/virt/libvirt_conn.py:399 -msgid "cool, it's a device" +msgid "Unable to get record of VDI %s on" msgstr "" -#: nova/virt/libvirt_conn.py:407 +#: ../nova/virt/xenapi/volume_utils.py:146 #, python-format -msgid "data: %r, fpath: %r" +msgid "Unable to introduce VDI for SR %s" msgstr "" -#: nova/virt/libvirt_conn.py:415 +#: ../nova/virt/xenapi/volume_utils.py:175 #, python-format -msgid "Contents of file %s: %r" +msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s" msgstr "" -#: nova/virt/libvirt_conn.py:449 +#: ../nova/virt/xenapi/volume_utils.py:197 #, python-format -msgid "instance %s: Creating image" +msgid "Mountpoint cannot be translated: %s" msgstr "" -#: nova/virt/libvirt_conn.py:505 +#: ../nova/objectstore/image.py:262 #, python-format -msgid "instance %s: injecting key into image %s" +msgid "Failed to decrypt private key: %s" msgstr "" -#: nova/virt/libvirt_conn.py:508 +#: ../nova/objectstore/image.py:269 #, python-format -msgid "instance %s: injecting net into image %s" +msgid "Failed to decrypt initialization vector: %s" msgstr "" -#: nova/virt/libvirt_conn.py:516 +#: ../nova/objectstore/image.py:277 #, python-format -msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgid "Failed to decrypt image file %(image_file)s: %(err)s" msgstr "" -#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#: ../nova/objectstore/handler.py:106 #, python-format -msgid "instance %s: starting toXML method" +msgid "Unknown S3 value type %r" msgstr "" -#: nova/virt/libvirt_conn.py:589 -#, python-format -msgid "instance %s: finished toXML method" +#: ../nova/objectstore/handler.py:137 +msgid "Authenticated request" 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" +#: ../nova/objectstore/handler.py:182 +msgid "List of buckets requested" msgstr "" -#: nova/virt/xenapi_conn.py:263 +#: ../nova/objectstore/handler.py:209 #, python-format -msgid "Task [%s] %s status: success %s" +msgid "List keys for bucket %s" msgstr "" -#: nova/virt/xenapi_conn.py:271 +#: ../nova/objectstore/handler.py:217 #, python-format -msgid "Task [%s] %s status: %s %s" +msgid "Unauthorized attempt to access bucket %s" msgstr "" -#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#: ../nova/objectstore/handler.py:235 #, python-format -msgid "Got exception: %s" +msgid "Creating bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:72 +#: ../nova/objectstore/handler.py:245 #, python-format -msgid "%s: _db_content => %s" +msgid "Deleting bucket %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" +#: ../nova/objectstore/handler.py:249 +#, python-format +msgid "Unauthorized attempt to delete bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:249 +#: ../nova/objectstore/handler.py:273 #, python-format -msgid "xenapi.fake does not have an implementation for %s" +msgid "Getting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/fake.py:283 +#: ../nova/objectstore/handler.py:276 #, python-format -msgid "Calling %s %s" +msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/fake.py:288 +#: ../nova/objectstore/handler.py:296 #, python-format -msgid "Calling getter %s" +msgid "Putting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/fake.py:340 +#: ../nova/objectstore/handler.py:299 #, python-format -msgid "" -"xenapi.fake does not have an implementation for %s or it has been called " -"with the wrong number of arguments" +msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/network_utils.py:40 +#: ../nova/objectstore/handler.py:318 #, python-format -msgid "Found non-unique network for bridge %s" +msgid "Deleting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/network_utils.py:43 +#: ../nova/objectstore/handler.py:322 #, python-format -msgid "Found no network for bridge %s" +msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:127 +#: ../nova/objectstore/handler.py:396 #, python-format -msgid "Created VM %s as %s." +msgid "Not authorized to upload image: invalid directory %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:147 +#: ../nova/objectstore/handler.py:404 #, python-format -msgid "Creating VBD for VM %s, VDI %s ... " +msgid "Not authorized to upload image: unauthorized bucket %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:149 +#: ../nova/objectstore/handler.py:409 #, python-format -msgid "Created VBD %s for VM %s, VDI %s." +msgid "Starting image upload: %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:165 +#: ../nova/objectstore/handler.py:423 #, python-format -msgid "VBD not found in instance %s" +msgid "Not authorized to update attributes of image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:175 +#: ../nova/objectstore/handler.py:431 #, python-format -msgid "Unable to unplug VBD %s" +msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r" msgstr "" -#: nova/virt/xenapi/vm_utils.py:187 +#. other attributes imply update +#: ../nova/objectstore/handler.py:436 #, python-format -msgid "Unable to destroy VBD %s" +msgid "Updating user fields on image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:202 +#: ../nova/objectstore/handler.py:450 #, python-format -msgid "Creating VIF for VM %s, network %s." +msgid "Unauthorized attempt to delete image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:205 +#: ../nova/objectstore/handler.py:455 #, python-format -msgid "Created VIF %s for VM %s, network %s." +msgid "Deleted image: %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:216 +#: ../nova/auth/manager.py:259 #, python-format -msgid "Snapshotting VM %s with label '%s'..." +msgid "Looking up user: %r" msgstr "" -#: nova/virt/xenapi/vm_utils.py:229 +#: ../nova/auth/manager.py:263 #, python-format -msgid "Created snapshot %s from VM %s." +msgid "Failed authorization for access key %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:243 +#: ../nova/auth/manager.py:264 #, python-format -msgid "Asking xapi to upload %s as '%s'" +msgid "No user found for access key %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:261 +#: ../nova/auth/manager.py:270 #, python-format -msgid "Asking xapi to fetch %s as %s" +msgid "Using project name = user name (%s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:279 +#: ../nova/auth/manager.py:277 #, python-format -msgid "Looking up vdi %s for PV kernel" +msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:290 +#: ../nova/auth/manager.py:279 #, python-format -msgid "PV Kernel in VDI:%d" +msgid "No project called %s could be found" msgstr "" -#: nova/virt/xenapi/vm_utils.py:318 +#: ../nova/auth/manager.py:287 #, python-format -msgid "VDI %s is still available" +msgid "" +"Failed authorization: user %(uname)s not admin and not member of project " +"%(pjname)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:331 +#: ../nova/auth/manager.py:289 #, python-format -msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgid "User %(uid)s is not a member of project %(pjid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:333 +#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309 #, python-format -msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgid "Invalid signature for user %s" +msgstr "" + +#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310 +msgid "Signature does not match" msgstr "" -#: nova/virt/xenapi/vm_utils.py:390 +#: ../nova/auth/manager.py:380 +msgid "Must specify project" +msgstr "" + +#: ../nova/auth/manager.py:414 #, python-format -msgid "VHD %s has parent %s" +msgid "The %s role can not be found" msgstr "" -#: nova/virt/xenapi/vm_utils.py:407 +#: ../nova/auth/manager.py:416 #, python-format -msgid "Re-scanning SR %s" +msgid "The %s role is global only" msgstr "" -#: nova/virt/xenapi/vm_utils.py:431 +#: ../nova/auth/manager.py:420 #, python-format -msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgid "Adding role %(role)s to user %(uid)s in project %(pid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:448 +#: ../nova/auth/manager.py:423 #, python-format -msgid "No VDIs found for VM %s" +msgid "Adding sitewide role %(role)s to user %(uid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:452 +#: ../nova/auth/manager.py:448 #, python-format -msgid "Unexpected number of VDIs (%s) found for VM %s" +msgid "Removing role %(role)s from user %(uid)s on project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:62 +#: ../nova/auth/manager.py:451 #, python-format -msgid "Attempted to create non-unique name %s" +msgid "Removing sitewide role %(role)s from user %(uid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:99 +#: ../nova/auth/manager.py:515 #, python-format -msgid "Starting VM %s..." +msgid "Created project %(name)s with manager %(manager_user)s" msgstr "" -#: nova/virt/xenapi/vmops.py:101 +#: ../nova/auth/manager.py:533 #, python-format -msgid "Spawning VM %s created %s." +msgid "modifying project %s" msgstr "" -#: nova/virt/xenapi/vmops.py:112 +#: ../nova/auth/manager.py:545 #, python-format -msgid "Instance %s: booted" +msgid "Adding user %(uid)s to project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:137 +#: ../nova/auth/manager.py:566 #, python-format -msgid "Instance not present %s" +msgid "Remove user %(uid)s from project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:166 +#: ../nova/auth/manager.py:592 #, python-format -msgid "Starting snapshot for VM %s" +msgid "Deleting project %s" msgstr "" -#: nova/virt/xenapi/vmops.py:174 +#: ../nova/auth/manager.py:650 #, python-format -msgid "Unable to Snapshot %s: %s" +msgid "Created user %(rvname)s (admin: %(rvadmin)r)" msgstr "" -#: nova/virt/xenapi/vmops.py:184 +#: ../nova/auth/manager.py:659 #, python-format -msgid "Finished snapshot and upload for VM %s" +msgid "Deleting user %s" msgstr "" -#: nova/virt/xenapi/vmops.py:252 +#: ../nova/auth/manager.py:669 #, python-format -msgid "suspend: instance not present %s" +msgid "Access Key change for user %s" msgstr "" -#: nova/virt/xenapi/vmops.py:262 +#: ../nova/auth/manager.py:671 #, python-format -msgid "resume: instance not present %s" +msgid "Secret Key change for user %s" msgstr "" -#: nova/virt/xenapi/vmops.py:271 +#: ../nova/auth/manager.py:673 #, python-format -msgid "Instance not found %s" +msgid "Admin status set to %(admin)r for user %(uid)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:57 +#: ../nova/auth/manager.py:722 #, python-format -msgid "Introducing %s..." +msgid "No vpn data for project %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:74 +#: ../nova/service.py:161 #, python-format -msgid "Introduced %s as %s." +msgid "Starting %(topic)s node (version %(vcs_string)s)" msgstr "" -#: nova/virt/xenapi/volume_utils.py:78 -msgid "Unable to create Storage Repository" +#: ../nova/service.py:174 +msgid "Service killed that has no database entry" msgstr "" -#: nova/virt/xenapi/volume_utils.py:90 -#, python-format -msgid "Unable to find SR from VBD %s" +#: ../nova/service.py:195 +msgid "The service database object disappeared, Recreating it." msgstr "" -#: nova/virt/xenapi/volume_utils.py:96 -#, python-format -msgid "Forgetting SR %s ... " +#: ../nova/service.py:207 +msgid "Recovered model server connection!" msgstr "" -#: nova/virt/xenapi/volume_utils.py:101 +#: ../nova/service.py:213 +msgid "model server went away" +msgstr "" + +#: ../nova/auth/ldapdriver.py:174 #, python-format -msgid "Ignoring exception %s when getting PBDs for %s" +msgid "LDAP user %s already exists" msgstr "" -#: nova/virt/xenapi/volume_utils.py:107 +#: ../nova/auth/ldapdriver.py:205 #, python-format -msgid "Ignoring exception %s when unplugging PBD %s" +msgid "LDAP object for %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:111 +#: ../nova/auth/ldapdriver.py:348 #, python-format -msgid "Forgetting SR %s done." +msgid "User %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:113 +#: ../nova/auth/ldapdriver.py:472 #, python-format -msgid "Ignoring exception %s when forgetting SR %s" +msgid "Group can't be created because group %s already exists" msgstr "" -#: nova/virt/xenapi/volume_utils.py:123 +#: ../nova/auth/ldapdriver.py:478 #, python-format -msgid "Unable to introduce VDI on SR %s" +msgid "Group can't be created because user %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:128 +#: ../nova/auth/ldapdriver.py:495 #, python-format -msgid "Unable to get record of VDI %s on" +msgid "User %s can't be searched in group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:146 +#: ../nova/auth/ldapdriver.py:507 #, python-format -msgid "Unable to introduce VDI for SR %s" +msgid "User %s can't be added to the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:175 +#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521 #, python-format -msgid "Unable to obtain target information %s, %s" +msgid "The group at dn %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:197 +#: ../nova/auth/ldapdriver.py:513 #, python-format -msgid "Mountpoint cannot be translated: %s" +msgid "User %(uid)s is already a member of the group %(group_dn)s" msgstr "" -#: nova/virt/xenapi/volumeops.py:51 +#: ../nova/auth/ldapdriver.py:524 #, python-format -msgid "Attach_volume: %s, %s, %s" +msgid "" +"User %s can't be removed from the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:69 +#: ../nova/auth/ldapdriver.py:528 #, python-format -msgid "Unable to create VDI on SR %s for instance %s" +msgid "User %s is not a member of the group" msgstr "" -#: nova/virt/xenapi/volumeops.py:81 +#: ../nova/auth/ldapdriver.py:542 #, python-format -msgid "Unable to use SR %s for instance %s" +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." msgstr "" -#: nova/virt/xenapi/volumeops.py:93 +#: ../nova/auth/ldapdriver.py:549 #, python-format -msgid "Unable to attach volume to instance %s" +msgid "User %s can't be removed from all because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:95 +#: ../nova/auth/ldapdriver.py:564 #, python-format -msgid "Mountpoint %s attached to instance %s" +msgid "Group at dn %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:106 +#: ../nova/virt/xenapi/network_utils.py:40 #, python-format -msgid "Detach_volume: %s, %s" +msgid "Found non-unique network for bridge %s" msgstr "" -#: nova/virt/xenapi/volumeops.py:113 +#: ../nova/virt/xenapi/network_utils.py:43 #, python-format -msgid "Unable to locate volume %s" +msgid "Found no network for bridge %s" msgstr "" -#: nova/virt/xenapi/volumeops.py:121 +#: ../nova/api/ec2/admin.py:97 #, python-format -msgid "Unable to detach volume %s" +msgid "Creating new user: %s" msgstr "" -#: nova/virt/xenapi/volumeops.py:128 +#: ../nova/api/ec2/admin.py:105 #, python-format -msgid "Mountpoint %s detached from instance %s" +msgid "Deleting user: %s" msgstr "" -#: nova/volume/api.py:44 +#: ../nova/api/ec2/admin.py:127 #, python-format -msgid "Quota exceeeded for %s, tried to create %sG volume" +msgid "Adding role %(role)s to user %(user)s for project %(project)s" msgstr "" -#: nova/volume/api.py:46 +#: ../nova/api/ec2/admin.py:131 #, python-format -msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgid "Adding sitewide role %(role)s to user %(user)s" msgstr "" -#: nova/volume/api.py:70 nova/volume/api.py:95 -msgid "Volume status must be available" +#: ../nova/api/ec2/admin.py:137 +#, python-format +msgid "Removing role %(role)s from user %(user)s for project %(project)s" msgstr "" -#: nova/volume/api.py:97 -msgid "Volume is already attached" +#: ../nova/api/ec2/admin.py:141 +#, python-format +msgid "Removing sitewide role %(role)s from user %(user)s" msgstr "" -#: nova/volume/api.py:103 -msgid "Volume is already detached" +#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223 +msgid "operation must be add or remove" msgstr "" -#: nova/volume/driver.py:76 +#: ../nova/api/ec2/admin.py:159 #, python-format -msgid "Recovering from a failed execute. Try number %s" +msgid "Getting x509 for user: %(name)s on project: %(project)s" msgstr "" -#: nova/volume/driver.py:85 +#: ../nova/api/ec2/admin.py:177 #, python-format -msgid "volume group %s doesn't exist" +msgid "Create project %(name)s managed by %(manager_user)s" msgstr "" -#: nova/volume/driver.py:210 +#: ../nova/api/ec2/admin.py:190 #, python-format -msgid "FAKE AOE: %s" +msgid "Modify project: %(name)s managed by %(manager_user)s" msgstr "" -#: nova/volume/driver.py:315 +#: ../nova/api/ec2/admin.py:200 #, python-format -msgid "FAKE ISCSI: %s" +msgid "Delete project: %s" msgstr "" -#: nova/volume/manager.py:85 +#: ../nova/api/ec2/admin.py:214 #, python-format -msgid "Re-exporting %s volumes" +msgid "Adding user %(user)s to project %(project)s" msgstr "" -#: nova/volume/manager.py:93 +#: ../nova/api/ec2/admin.py:218 #, python-format -msgid "volume %s: creating" -msgstr "Volume %s: wird erstellt" +msgid "Removing user %(user)s from project %(project)s" +msgstr "" -#: nova/volume/manager.py:102 #, python-format -msgid "volume %s: creating lv of size %sG" -msgstr "Volume %s: erstelle LV mit %sG" +#~ 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/volume/manager.py:106 #, python-format -msgid "volume %s: creating export" -msgstr "Volume %s: erstelle Export" +#~ msgid "(%s) publish (key: %s) %s" +#~ msgstr "(%s) öffentlich (Schlüssel: %s) %s" -#: nova/volume/manager.py:113 #, python-format -msgid "volume %s: created successfully" -msgstr "Volume %s: erfolgreich erstellt" - -#: 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 "" +#~ msgid "Getting from %s: %s" +#~ msgstr "Beziehe von %s: %s" -#: nova/volume/manager.py:124 #, python-format -msgid "volume %s: removing export" -msgstr "Volume %s: entferne Export" +#~ 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/volume/manager.py:126 #, python-format -msgid "volume %s: deleting" -msgstr "Volume %s: wird entfernt" +#~ msgid "volume %s: creating lv of size %sG" +#~ msgstr "Volume %s: erstelle LV mit %sG" -#: nova/volume/manager.py:129 #, python-format -msgid "volume %s: deleted successfully" -msgstr "Volume %s: erfolgreich entfernt" +#~ msgid "Data store %s is unreachable. Trying again in %d seconds." +#~ msgstr "" +#~ "Datastore %s ist nicht erreichbar. Versuche es erneut in %d Sekunden." diff --git a/po/es.po b/po/es.po index 8d4f90b26..a54260db8 100644 --- a/po/es.po +++ b/po/es.po @@ -7,827 +7,2104 @@ 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" +"POT-Creation-Date: 2011-02-21 10:03-0500\n" +"PO-Revision-Date: 2011-03-17 15:54+0000\n" +"Last-Translator: Erick Huezo \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-02-05 05:36+0000\n" -"X-Generator: Launchpad (build 12177)\n" +"X-Launchpad-Export-Date: 2011-03-19 06:19+0000\n" +"X-Generator: Launchpad (build 12559)\n" -#: nova/crypto.py:46 +#: ../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 "No se han encontrado hosts" + +#: ../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 "" +"%(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 "Excepción no controlada" + +#: ../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 "Cuota excedida. No puedes crear un volumen con tamaño %sG" + +#: ../nova/volume/api.py:71 ../nova/volume/api.py:96 +msgid "Volume status must be available" +msgstr "El estado del volumen debe estar disponible" + +#: ../nova/volume/api.py:98 +msgid "Volume is already attached" +msgstr "El volumen ya está asociado previamente" + +#: ../nova/volume/api.py:104 +msgid "Volume is already detached" +msgstr "El volumen ya ha sido desasociado previamente" + +#: ../nova/api/openstack/servers.py:72 +msgid "Failed to read private ip" +msgstr "Fallo lectura de IP Privada" + +#: ../nova/api/openstack/servers.py:79 +msgid "Failed to read public ip(s)" +msgstr "Fallo lectura de IP(s) Publicas" + +#: ../nova/api/openstack/servers.py:152 +#, python-format +msgid "%(param)s property not found for image %(_image_id)s" +msgstr "%(param)s propiedad no encontrada para la imagen %(_image_id)s" + +#: ../nova/api/openstack/servers.py:168 +msgid "No keypairs defined" +msgstr "No se definio una Keypairs" + +#: ../nova/api/openstack/servers.py:238 +#, python-format +msgid "Compute.api::lock %s" +msgstr "Compute.api::lock %s" + +#: ../nova/api/openstack/servers.py:253 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "Compute.api::unlock %s" + +#: ../nova/api/openstack/servers.py:267 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "Compute.api::get_lock %s" + +#: ../nova/api/openstack/servers.py:281 +#, python-format +msgid "Compute.api::reset_network %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:292 +#, python-format +msgid "Compute.api::pause %s" +msgstr "Compute.api::pause %s" + +#: ../nova/api/openstack/servers.py:303 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "Compute.api::unpause %s" + +#: ../nova/api/openstack/servers.py:314 +#, python-format +msgid "compute.api::suspend %s" +msgstr "compute.api::suspend %s" + +#: ../nova/api/openstack/servers.py:325 +#, python-format +msgid "compute.api::resume %s" +msgstr "compute.api::resume %s" + +#: ../nova/twistd.py:157 +msgid "Wrong number of arguments." +msgstr "Numero de argumentos incorrectos" + +#: ../nova/twistd.py:209 +#, 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:221 +msgid "No such process" +msgstr "No se encontró proceso" + +#: ../nova/twistd.py:230 ../nova/service.py:224 +#, python-format +msgid "Serving %s" +msgstr "Sirviendo %s" + +#: ../nova/twistd.py:262 ../nova/service.py:225 +msgid "Full set of FLAGS:" +msgstr "Conjunto completo de opciones:" + +#: ../nova/twistd.py:266 +#, python-format +msgid "Starting %s" +msgstr "Comenzando %s" + +#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101 +#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741 +#: ../nova/api/ec2/__init__.py:317 +#, python-format +msgid "Instance %s not found" +msgstr "La instancia %s no se ha encontrado" + +#. 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 "Imposible adjuntar volumen a la instancia %s" + +#: ../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 "Imposible encontrar volumen %s" + +#: ../nova/virt/xenapi/volumeops.py:120 +#, python-format +msgid "Unable to detach volume %s" +msgstr "Imposible desasociar volumen %s" + +#: ../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 "Tipo de instancia desconocido: %s" + +#: ../nova/crypto.py:46 msgid "Filename of root CA" msgstr "Nombre de fichero de la CA raíz" -#: nova/crypto.py:49 +#: ../nova/crypto.py:49 msgid "Filename of private key" msgstr "Nombre de fichero de la clave privada" -#: nova/crypto.py:51 +#: ../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 +#: ../nova/crypto.py:53 msgid "Where we keep our keys" msgstr "Donde guardamos nuestras claves" -#: nova/crypto.py:55 +#: ../nova/crypto.py:55 msgid "Where we keep our root CA" msgstr "Dónde guardamos nuestra CA raíz" -#: nova/crypto.py:57 +#: ../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 +#: ../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 +#: ../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 +#: ../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 +#: ../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/scheduler/manager.py:69 +#, python-format +msgid "Casting to %(topic)s %(host)s for %(method)s" +msgstr "" + +#: ../nova/compute/manager.py:78 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "check_instance_lock: decorating: |%s|" -#: nova/exception.py:36 +#: ../nova/compute/manager.py:80 #, 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" +"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|" +msgstr "" -#: nova/fakerabbit.py:48 +#: ../nova/compute/manager.py:84 #, python-format -msgid "(%s) publish (key: %s) %s" -msgstr "(%s) públicar (clave: %s) %s" +msgid "check_instance_lock: locked: |%s|" +msgstr "check_instance_lock: locked: |%s|" -#: nova/fakerabbit.py:53 +#: ../nova/compute/manager.py:86 #, python-format -msgid "Publishing to route %s" -msgstr "Publicando la ruta %s" +msgid "check_instance_lock: admin: |%s|" +msgstr "check_instance_lock: admin: |%s|" -#: nova/fakerabbit.py:83 +#: ../nova/compute/manager.py:91 #, python-format -msgid "Declaring queue %s" -msgstr "Declarando cola %s" +msgid "check_instance_lock: executing: |%s|" +msgstr "check_instance_lock: ejecutando: |%s|" -#: nova/fakerabbit.py:89 +#: ../nova/compute/manager.py:95 #, python-format -msgid "Declaring exchange %s" -msgstr "Declarando intercambio %s" +msgid "check_instance_lock: not executing |%s|" +msgstr "check_instance_lock: no ejecutando |%s|" + +#: ../nova/compute/manager.py:179 +msgid "Instance has already been created" +msgstr "La instancia ha sido creada previamente" -#: nova/fakerabbit.py:95 +#: ../nova/compute/manager.py:180 #, python-format -msgid "Binding %s to %s with key %s" -msgstr "Asociando %s a %s con clave %s" +msgid "instance %s: starting..." +msgstr "instancia %s: iniciando..." -#: nova/fakerabbit.py:120 +#. pylint: disable=W0702 +#: ../nova/compute/manager.py:219 #, python-format -msgid "Getting from %s: %s" -msgstr "Obteniendo desde %s: %s" +msgid "instance %s: Failed to spawn" +msgstr "Instancia %s: no se pudo iniciar" -#: nova/rpc.py:92 +#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286 #, 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." +msgid "Terminating instance %s" +msgstr "Finalizando la instancia %s" -#: nova/rpc.py:99 +#: ../nova/compute/manager.py:255 #, 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." +msgid "Deallocating address %s" +msgstr "Desasociando la dirección %s" -#: nova/rpc.py:118 -msgid "Reconnected to queue" -msgstr "Reconectado a la cola" +#: ../nova/compute/manager.py:268 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "intentando finalizar una instancia que ya había sido finalizada: %s" -#: nova/rpc.py:125 -msgid "Failed to fetch message from queue" -msgstr "Fallo al obtener el mensaje de la cola" +#: ../nova/compute/manager.py:282 +#, python-format +msgid "Rebooting instance %s" +msgstr "Reiniciando instancia %s" -#: nova/rpc.py:155 +#: ../nova/compute/manager.py:287 #, python-format -msgid "Initing the Adapter Consumer for %s" +msgid "" +"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" msgstr "" -#: nova/rpc.py:170 +#: ../nova/compute/manager.py:311 #, python-format -msgid "received %s" -msgstr "recibido %s" +msgid "instance %s: snapshotting" +msgstr "instancia %s: creando snapshot" -#: nova/rpc.py:183 +#: ../nova/compute/manager.py:316 #, python-format -msgid "no method for message: %s" -msgstr "no hay método para el mensaje: %s" +msgid "" +"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" -#: nova/rpc.py:184 +#: ../nova/compute/manager.py:332 #, python-format -msgid "No method for message: %s" -msgstr "No hay método para el mensaje: %s" +msgid "" +"trying to reset the password on a non-running instance: %(instance_id)s " +"(state: %(instance_state)s expected: %(expected_state)s)" +msgstr "" -#: nova/rpc.py:245 +#: ../nova/compute/manager.py:335 #, python-format -msgid "Returning exception %s to caller" +msgid "instance %s: setting admin password" msgstr "" -#: nova/rpc.py:286 +#: ../nova/compute/manager.py:353 #, python-format -msgid "unpacked context: %s" -msgstr "contenido desempaquetado: %s" - -#: nova/rpc.py:305 -msgid "Making asynchronous call..." -msgstr "Haciendo una llamada asíncrona..." +msgid "" +"trying to inject a file into a non-running instance: %(instance_id)s (state: " +"%(instance_state)s expected: %(expected_state)s)" +msgstr "" -#: nova/rpc.py:308 +#: ../nova/compute/manager.py:362 #, python-format -msgid "MSG_ID is %s" -msgstr "MSG_ID es %s" +msgid "instance %(nm)s: injecting file to %(plain_path)s" +msgstr "" -#: nova/rpc.py:356 +#: ../nova/compute/manager.py:372 #, python-format -msgid "response %s" -msgstr "respuesta %s" +msgid "instance %s: rescuing" +msgstr "instancia %s: rescatando" -#: nova/rpc.py:365 +#: ../nova/compute/manager.py:387 #, python-format -msgid "topic is %s" +msgid "instance %s: unrescuing" msgstr "" -#: nova/rpc.py:366 +#: ../nova/compute/manager.py:406 #, python-format -msgid "message %s" -msgstr "mensaje %s" +msgid "instance %s: pausing" +msgstr "instancia %s: pausando" -#: nova/service.py:157 +#: ../nova/compute/manager.py:423 #, 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." +msgid "instance %s: unpausing" +msgstr "instnacia %s: continuando tras pausa" -#: nova/service.py:208 -msgid "model server went away" -msgstr "el servidor de modelos se ha ido" +#: ../nova/compute/manager.py:440 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "instancia %s: obteniendo los diagnosticos" -#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#: ../nova/compute/manager.py:453 #, python-format -msgid "Data store %s is unreachable. Trying again in %d seconds." +msgid "instance %s: suspending" msgstr "" -"El almacen de datos %s es inalcanzable. Reintentandolo en %d segundos." -#: nova/service.py:232 nova/twistd.py:232 +#: ../nova/compute/manager.py:472 #, 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:" +msgid "instance %s: resuming" +msgstr "instancia %s: continuando" -#: nova/twistd.py:211 +#: ../nova/compute/manager.py:491 #, python-format -msgid "pidfile %s does not exist. Daemon not running?\n" -msgstr "el pidfile %s no existe. ¿No estará el demonio parado?\n" +msgid "instance %s: locking" +msgstr "instancia %s: bloqueando" -#: nova/twistd.py:268 +#: ../nova/compute/manager.py:503 #, python-format -msgid "Starting %s" -msgstr "Comenzando %s" +msgid "instance %s: unlocking" +msgstr "instancia %s: desbloqueando" -#: nova/utils.py:53 +#: ../nova/compute/manager.py:513 #, python-format -msgid "Inner Exception: %s" -msgstr "Excepción interna: %s" +msgid "instance %s: getting locked state" +msgstr "instancia %s: pasando a estado bloqueado" -#: nova/utils.py:54 +#: ../nova/compute/manager.py:526 #, python-format -msgid "Class %s cannot be found" -msgstr "La clase %s no ha podido ser encontrada." +msgid "instance %s: reset network" +msgstr "instancia %s: reiniciar redes" -#: nova/utils.py:113 +#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515 #, python-format -msgid "Fetching %s" -msgstr "Obteniendo %s" +msgid "Get console output for instance %s" +msgstr "Obtener salida de la consola para la instancia %s" -#: nova/utils.py:125 +#: ../nova/compute/manager.py:543 #, python-format -msgid "Running cmd (subprocess): %s" -msgstr "Ejecutando cmd (subprocesos): %s" +msgid "instance %s: getting ajax console" +msgstr "instancia %s: obteniendo consola ajax" -#: nova/utils.py:138 +#: ../nova/compute/manager.py:553 #, python-format -msgid "Result was %s" -msgstr "El resultado fue %s" +msgid "" +"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s" +msgstr "" +"instancia %(instance_id)s: adjuntando volumen %(volume_id)s a %(mountpoint)s" -#: nova/utils.py:171 +#. pylint: disable=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:569 #, python-format -msgid "debug in callback: %s" -msgstr "Depuración de la devolución de llamada: %s" +msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing" +msgstr "" +"instancia %(instance_id)s: adjuntar fallo %(mountpoint)s, removiendo" -#: nova/utils.py:176 +#: ../nova/compute/manager.py:585 +#, python-format +msgid "" +"Detach volume %(volume_id)s from mountpoint %(mp)s on instance " +"%(instance_id)s" +msgstr "" +"Quitar el volumen %(volume_id)s del punto de montaje %(mp)s en la instancia " +"%(instance_id)s" + +#: ../nova/compute/manager.py:588 +#, python-format +msgid "Detaching volume from unknown instance %s" +msgstr "Desvinculando volumen de instancia desconocida %s" + +#: ../nova/scheduler/simple.py:53 +#, python-format +msgid "Host %s is not alive" +msgstr "Host %s no responde" + +#: ../nova/scheduler/simple.py:65 +msgid "All hosts have too many cores" +msgstr "Todos los hosts tienen demasiados cores" + +#: ../nova/scheduler/simple.py:87 +#, python-format +msgid "Host %s not available" +msgstr "Host %s no disponible" + +#: ../nova/scheduler/simple.py:99 +msgid "All hosts have too many gigabytes" +msgstr "Todos los hosts tienen demasiados gigabytes" + +#: ../nova/scheduler/simple.py:119 +msgid "All hosts have too many networks" +msgstr "Todos los hosts tienen demasiadas redes" + +#: ../nova/volume/manager.py:85 +#, python-format +msgid "Re-exporting %s volumes" +msgstr "Exportando de nuevo los volumenes %s" + +#: ../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 "volumen %s: creando" + +#: ../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 "volumen %s: exportando" + +#: ../nova/volume/manager.py:123 +#, python-format +msgid "volume %s: created successfully" +msgstr "volumen %s: creado satisfactoriamente" + +#: ../nova/volume/manager.py:131 +msgid "Volume is still attached" +msgstr "El volumen todavía está asociado" + +#: ../nova/volume/manager.py:133 +msgid "Volume is not local to this node" +msgstr "Volumen no local a este nodo" + +#: ../nova/volume/manager.py:136 +#, python-format +msgid "volume %s: removing export" +msgstr "volumen %s: eliminando exportación" + +#: ../nova/volume/manager.py:138 +#, python-format +msgid "volume %s: deleting" +msgstr "volumen %s: eliminando" + +#: ../nova/volume/manager.py:147 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "volumen %s: eliminado satisfactoriamente" + +#: ../nova/virt/xenapi/fake.py:74 +#, python-format +msgid "%(text)s: _db_content => %(content)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:304 ../nova/virt/xenapi/fake.py:404 +#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478 +msgid "Raising NotImplemented" +msgstr "Lanzando NotImplemented" + +#: ../nova/virt/xenapi/fake.py:306 +#, 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:341 +#, python-format +msgid "Calling %(localname)s %(impl)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:346 +#, python-format +msgid "Calling getter %s" +msgstr "Llanado al adquiridor %s" + +#: ../nova/virt/xenapi/fake.py:406 +#, 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/tests/test_cloud.py:256 +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:268 +#, 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/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "Fallo al abrir conexión con el hypervisor" + +#: ../nova/network/linux_net.py:187 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "Iniciando interfaz VLAN %s" + +#: ../nova/network/linux_net.py:208 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "Iniciando interfaz puente para %s" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:314 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "Excepción al recargar la configuración de dnsmasq: %s" + +#: ../nova/network/linux_net.py:316 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "El pid %d está pasado, relanzando dnsmasq" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:358 +#, python-format +msgid "killing radvd threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:360 +#, python-format +msgid "Pid %d is stale, relaunching radvd" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:449 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "Al matar dnsmasq se lanzó %s" + +#: ../nova/utils.py:58 +#, python-format +msgid "Inner Exception: %s" +msgstr "Excepción interna: %s" + +#: ../nova/utils.py:59 +#, python-format +msgid "Class %s cannot be found" +msgstr "La clase %s no ha podido ser encontrada." + +#: ../nova/utils.py:118 +#, python-format +msgid "Fetching %s" +msgstr "Obteniendo %s" + +#: ../nova/utils.py:130 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "Ejecutando cmd (subprocesos): %s" + +#: ../nova/utils.py:143 ../nova/utils.py:183 +#, python-format +msgid "Result was %s" +msgstr "El resultado fue %s" + +#: ../nova/utils.py:159 +#, python-format +msgid "Running cmd (SSH): %s" +msgstr "" + +#: ../nova/utils.py:217 +#, python-format +msgid "debug in callback: %s" +msgstr "Depuración de la devolución de llamada: %s" + +#: ../nova/utils.py:222 #, python-format msgid "Running %s" msgstr "Ejecutando %s" -#: nova/utils.py:207 +#: ../nova/utils.py:262 +#, python-format +msgid "Link Local address is not found.:%s" +msgstr "" + +#: ../nova/utils.py:265 #, python-format -msgid "Couldn't get IP, using 127.0.0.1 %s" -msgstr "No puedo obtener IP, usando 127.0.0.1 %s" +msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s" +msgstr "" -#: nova/utils.py:289 +#: ../nova/utils.py:363 #, python-format msgid "Invalid backend: %s" msgstr "backend inválido: %s" -#: nova/utils.py:300 +#: ../nova/utils.py:374 #, 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/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 "Publicando la ruta %s" + +#: ../nova/fakerabbit.py:84 +#, python-format +msgid "Declaring queue %s" +msgstr "Declarando cola %s" + +#: ../nova/fakerabbit.py:90 +#, python-format +msgid "Declaring exchange %s" +msgstr "Declarando intercambio %s" + +#: ../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 "Creada VM %s..." + +#: ../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:168 +#, python-format +msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:171 +#, python-format +msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "VBD not found in instance %s" +msgstr "VBD no encontrado en la instancia %s" + +#: ../nova/virt/xenapi/vm_utils.py:197 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "Imposible desconectar VBD %s" + +#: ../nova/virt/xenapi/vm_utils.py:209 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "Imposible destruir VBD %s" + +#: ../nova/virt/xenapi/vm_utils.py:224 +#, python-format +msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:227 +#, python-format +msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:246 +#, 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:258 +#, python-format +msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:272 +#, python-format +msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:286 +#, python-format +msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:327 +#, python-format +msgid "Size for image %(image)s:%(virtual_size)d" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:332 +#, 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:342 +#, python-format +msgid "Copying VDI %s to /boot/guest on dom0" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:352 +#, python-format +msgid "Kernel/Ramdisk VDI %s destroyed" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:361 +#, python-format +msgid "Asking xapi to fetch %(url)s as %(access)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "Buscando vid %s para el kernel PV" + +#: ../nova/virt/xenapi/vm_utils.py:397 +#, python-format +msgid "PV Kernel in VDI:%s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:405 +#, python-format +msgid "Running pygrub against %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:411 +#, python-format +msgid "Found Xen kernel %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:413 +msgid "No Xen kernel found. Booting HVM." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431 +#, python-format +msgid "duplicate name found: %s" +msgstr "se ha encontrado un nombre duplicado: %s" + +#: ../nova/virt/xenapi/vm_utils.py:442 +#, python-format +msgid "VDI %s is still available" +msgstr "VDI %s está todavía disponible" + +#: ../nova/virt/xenapi/vm_utils.py:463 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "(VM_UTILS) xenserver vm state -> |%s|" + +#: ../nova/virt/xenapi/vm_utils.py:465 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "(VM_UTILS) xenapi power_state -> |%s|" + +#: ../nova/virt/xenapi/vm_utils.py:525 +#, python-format +msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:542 +#, python-format +msgid "Re-scanning SR %s" +msgstr "Re-escaneando SR %s" + +#: ../nova/virt/xenapi/vm_utils.py:567 +#, python-format +msgid "" +"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:574 +#, 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:590 +#, 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:594 +#, python-format +msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:653 +#: ../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:655 +#: ../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:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192 +#, python-format +msgid "Plugging VBD %s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:659 +#: ../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:661 +#, python-format +msgid "VBD %(vbd)s plugged as %(orig_dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:664 +#, python-format +msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:668 +#: ../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:671 +#: ../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:683 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211 +msgid "VBD.unplug successful first time." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:688 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216 +msgid "VBD.unplug rejected: retrying..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:692 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220 +msgid "VBD.unplug successful eventually." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:695 +#: ../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:704 +#: ../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:735 +#, python-format +msgid "" +"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:747 +#, 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 "Recibido %s" + +#: ../nova/db/sqlalchemy/api.py:44 +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:133 +#, python-format +msgid "No service for id %s" +msgstr "No hay servicio para el id %s" + +#: ../nova/db/sqlalchemy/api.py:251 +#, python-format +msgid "No service for %(host)s, %(binary)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:592 +msgid "No fixed ips defined" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:608 +#, python-format +msgid "No floating ip for address %s" +msgstr "No hay ip flotante para la dirección %s" + +#: ../nova/db/sqlalchemy/api.py:629 +#, python-format +msgid "No address for instance %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:961 +#, python-format +msgid "no keypair for user %(user_id)s, name %(name)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156 +#, python-format +msgid "No network for id %s" +msgstr "No hay red para el id %s" + +#: ../nova/db/sqlalchemy/api.py:1086 +msgid "No networks defined" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1115 +#, python-format +msgid "No network for bridge %s" +msgstr "No hay red para el puente %s" + +#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142 +#, python-format +msgid "No network for instance %s" +msgstr "No hay red para la instancia %s" + +#: ../nova/db/sqlalchemy/api.py:1277 +#, python-format +msgid "Token %s does not exist" +msgstr "El token %s no existe" + +#: ../nova/db/sqlalchemy/api.py:1302 +#, python-format +msgid "No quota for project_id %s" +msgstr "No hay quota para el project:id %s" + +#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501 +#: ../nova/api/ec2/__init__.py:323 +#, python-format +msgid "Volume %s not found" +msgstr "El volumen %s no se ha encontrado" + +#: ../nova/db/sqlalchemy/api.py:1514 +#, 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:1527 +#, 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:1572 +#, 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:1589 +#, python-format +msgid "No security group named %(group_name)s for project: %(project_id)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1682 +#, 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:1756 +#, python-format +msgid "No user for id %s" +msgstr "No hay un usuario con el id %s" + +#: ../nova/db/sqlalchemy/api.py:1772 +#, 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:1834 +#, python-format +msgid "No project with id %s" +msgstr "No hay proyecto con id %s" + +#: ../nova/db/sqlalchemy/api.py:1979 +#, python-format +msgid "No console pool with id %(pool_id)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1996 +#, 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:2035 +#, python-format +msgid "No console for instance %(instance_id)s in pool %(pool_id)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:2057 +#, python-format +msgid "on instance %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:2058 +#, python-format +msgid "No console with id %(console_id)s %(idesc)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097 +#, python-format +msgid "No zone with id %(zone_id)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 "Conectando a libvirt: %s" + +#: ../nova/virt/libvirt_conn.py:196 +msgid "Connection to libvirt broke" +msgstr "Conexión a libvirt rota" + +#: ../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 "No hay disco en %s" + +#: ../nova/virt/libvirt_conn.py:320 +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:336 +#, python-format +msgid "instance %s: rebooted" +msgstr "instancia %s: reiniciada" + +#: ../nova/virt/libvirt_conn.py:339 +#, python-format +msgid "_wait_for_reboot failed: %s" +msgstr "_wait_for_reboot falló: %s" + +#: ../nova/virt/libvirt_conn.py:382 +#, python-format +msgid "instance %s: rescued" +msgstr "instancia %s: rescatada" + +#: ../nova/virt/libvirt_conn.py:385 +#, python-format +msgid "_wait_for_rescue failed: %s" +msgstr "_wait_for_rescue falló: %s" + +#: ../nova/virt/libvirt_conn.py:411 +#, python-format +msgid "instance %s: is running" +msgstr "instancia %s: está ejecutándose" + +#: ../nova/virt/libvirt_conn.py:422 +#, python-format +msgid "instance %s: booted" +msgstr "instancia %s: arrancada" + +#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186 +#, python-format +msgid "instance %s: failed to boot" +msgstr "insntancia %s: falló al arrancar" + +#: ../nova/virt/libvirt_conn.py:436 +#, python-format +msgid "virsh said: %r" +msgstr "virsh dijo: %r" + +#: ../nova/virt/libvirt_conn.py:440 +msgid "cool, it's a device" +msgstr "genial, es un dispositivo" + +#: ../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 "instancia %s: Creando imagen" + +#: ../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 "instancia %s: comenzando método toXML" + +#: ../nova/virt/libvirt_conn.py:732 +#, python-format +msgid "instance %s: finished toXML method" +msgstr "instancia %s: finalizado método toXML" + +#: ../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 "Fallo al generar metadatos para la ip %s" + +#: ../nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "Intento de instanciar sigleton" + +#: ../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/tests/test_volume.py:162 +#, python-format +msgid "Target %s allocated" +msgstr "Destino %s asignado" + +#: ../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 "Debe de implementar un horario de reserva" + +#: ../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 "Generando CA raiz: %s" + +#: ../nova/api/ec2/cloud.py:303 +#, python-format +msgid "Create key pair %s" +msgstr "Creando par de claves %s" + +#: ../nova/api/ec2/cloud.py:311 +#, python-format +msgid "Delete key pair %s" +msgstr "Borrar para de claves %s" + +#: ../nova/api/ec2/cloud.py:386 +#, python-format +msgid "%s is not a valid ipProtocol" +msgstr "%s no es un ipProtocol valido" + +#: ../nova/api/ec2/cloud.py:390 +msgid "Invalid port range" +msgstr "Rango de puerto inválido" + +#: ../nova/api/ec2/cloud.py:421 +#, python-format +msgid "Revoke security group ingress %s" +msgstr "Revocar ingreso al grupo de seguridad %s" + +#: ../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:443 +msgid "No rule for the specified parameters." +msgstr "No hay regla para los parámetros especificados." + +#: ../nova/api/ec2/cloud.py:450 +#, python-format +msgid "Authorize security group ingress %s" +msgstr "Autorizar ingreso al grupo de seguridad %s" + +#: ../nova/api/ec2/cloud.py:464 +#, python-format +msgid "This rule already exists in group %s" +msgstr "Esta regla ya existe en el grupo %s" + +#: ../nova/api/ec2/cloud.py:492 +#, python-format +msgid "Create Security Group %s" +msgstr "Crear Grupo de Seguridad %s" + +#: ../nova/api/ec2/cloud.py:495 +#, python-format +msgid "group %s already exists" +msgstr "el grupo %s ya existe" + +#: ../nova/api/ec2/cloud.py:507 +#, python-format +msgid "Delete security group %s" +msgstr "Borrar grupo de seguridad %s" + +#: ../nova/api/ec2/cloud.py:584 +#, python-format +msgid "Create volume of %s GB" +msgstr "Crear volumen de %s GB" + +#: ../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:629 +#, python-format +msgid "Detach volume %s" +msgstr "Desasociar volumen %s" + +#: ../nova/api/ec2/cloud.py:761 +msgid "Allocate address" +msgstr "Asignar dirección" + +#: ../nova/api/ec2/cloud.py:766 +#, python-format +msgid "Release address %s" +msgstr "Liberar dirección %s" + +#: ../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:780 +#, python-format +msgid "Disassociate address %s" +msgstr "Desasociar dirección %s" + +#: ../nova/api/ec2/cloud.py:807 +msgid "Going to start terminating instances" +msgstr "Se va a iniciar la finalización de las instancias" + +#: ../nova/api/ec2/cloud.py:815 +#, python-format +msgid "Reboot instance %r" +msgstr "Reiniciar instancia %r" + +#: ../nova/api/ec2/cloud.py:867 +#, python-format +msgid "De-registering image %s" +msgstr "Des-registrando la imagen %s" + +#: ../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:882 ../nova/api/ec2/cloud.py:900 +#, python-format +msgid "attribute not supported: %s" +msgstr "atributo no soportado: %s" + +#: ../nova/api/ec2/cloud.py:890 +#, python-format +msgid "invalid id: %s" +msgstr "id no valido: %s" + +#: ../nova/api/ec2/cloud.py:903 +msgid "user or group not specified" +msgstr "usuario o grupo no especificado" + +#: ../nova/api/ec2/cloud.py:905 +msgid "only group \"all\" is supported" +msgstr "sólo el grupo \"all\" está soportado" + +#: ../nova/api/ec2/cloud.py:907 +msgid "operation_type must be add or remove" +msgstr "operation_type debe ser añadir o eliminar" + +#: ../nova/api/ec2/cloud.py:908 +#, python-format +msgid "Updating image %s publicity" +msgstr "Actualizando imagen %s públicamente" + +#: ../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 "Intentado la creación del nombre no único %s" + +#: ../nova/virt/xenapi/vmops.py:73 +#, python-format +msgid "instance %(name)s: not enough free memory" +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:148 +#, python-format +msgid "Starting VM %s..." +msgstr "Iniciando VM %s..." -#: nova/api/ec2/__init__.py:142 +#: ../nova/virt/xenapi/vmops.py:151 #, python-format -msgid "" -"Access key %s has had %d failed authentications and will be locked out for " -"%d minutes." +msgid "Spawning VM %(instance_name)s created %(vm_ref)s." 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 +#: ../nova/virt/xenapi/vmops.py:162 #, python-format -msgid "Authentication Failure: %s" -msgstr "Fallo de autenticación: %s" +msgid "Invalid value for onset_files: '%s'" +msgstr "" -#: nova/api/ec2/__init__.py:190 +#: ../nova/virt/xenapi/vmops.py:167 #, python-format -msgid "Authenticated Request For %s:%s)" -msgstr "Solicitud de autenticación para %s:%s" +msgid "Injecting file path: '%s'" +msgstr "" -#: nova/api/ec2/__init__.py:227 +#: ../nova/virt/xenapi/vmops.py:180 #, python-format -msgid "action: %s" -msgstr "acción: %s" +msgid "Instance %s: booted" +msgstr "Instancia %s: iniciada" -#: nova/api/ec2/__init__.py:229 +#: ../nova/virt/xenapi/vmops.py:232 #, python-format -msgid "arg: %s\t\tval: %s" -msgstr "arg: %s \t \t val: %s" +msgid "Instance not present %s" +msgstr "Instancia no existente %s" -#: nova/api/ec2/__init__.py:301 +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vmops.py:261 #, python-format -msgid "Unauthorized request for controller=%s and action=%s" -msgstr "Solicitud no autorizada para controller=%s y action=%s" +msgid "Starting snapshot for VM %s" +msgstr "Comenzando snapshot para la VM %s" -#: nova/api/ec2/__init__.py:339 +#: ../nova/virt/xenapi/vmops.py:269 #, python-format -msgid "NotFound raised: %s" -msgstr "No encontrado: %s" +msgid "Unable to Snapshot %(vm_ref)s: %(exc)s" +msgstr "" -#: nova/api/ec2/__init__.py:342 +#: ../nova/virt/xenapi/vmops.py:280 #, python-format -msgid "ApiError raised: %s" -msgstr "Sucedió un ApiError: %s" +msgid "Finished snapshot and upload for VM %s" +msgstr "Finalizado el snapshot y la subida de la VM %s" -#: nova/api/ec2/__init__.py:349 +#: ../nova/virt/xenapi/vmops.py:356 #, python-format -msgid "Unexpected error raised: %s" -msgstr "Sucedió un error inexperado: %s" +msgid "VM %(vm)s already halted, skipping shutdown..." +msgstr "" -#: nova/api/ec2/__init__.py:354 -msgid "An unknown error has occurred. Please try your request again." +#: ../nova/virt/xenapi/vmops.py:389 +msgid "Removing kernel/ramdisk files" +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:399 +msgid "kernel/ramdisk files removed" msgstr "" -"Ha sucedido un error desconocido. Por favor repite el intento de nuevo." -#: nova/api/ec2/admin.py:84 +#: ../nova/virt/xenapi/vmops.py:561 #, python-format -msgid "Creating new user: %s" -msgstr "Creando nuevo usuario: %s" +msgid "" +"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; " +"args=%(strargs)s" +msgstr "" -#: nova/api/ec2/admin.py:92 +#: ../nova/virt/xenapi/vmops.py:564 #, python-format -msgid "Deleting user: %s" -msgstr "Eliminando usuario: %s" +msgid "" +"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM " +"id=%(instance_id)s; args=%(strargs)s" +msgstr "" -#: nova/api/ec2/admin.py:114 +#: ../nova/virt/xenapi/vmops.py:569 #, python-format -msgid "Adding role %s to user %s for project %s" -msgstr "Añadiendo rol %s al usuario %s para el proyecto %s" +msgid "" +"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; " +"args=%(strargs)s" +msgstr "" -#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#: ../nova/virt/xenapi/vmops.py:760 #, python-format -msgid "Adding sitewide role %s to user %s" -msgstr "Añadiendo rol global %s al usuario %s" +msgid "OpenSSL error: %s" +msgstr "" -#: nova/api/ec2/admin.py:122 +#: ../nova/tests/test_compute.py:148 #, python-format -msgid "Removing role %s from user %s for project %s" -msgstr "Eliminando rol %s del usuario %s para el proyecto %s" +msgid "Running instances: %s" +msgstr "Ejecutando instancias: %s" -#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#: ../nova/tests/test_compute.py:154 #, python-format -msgid "Removing sitewide role %s from user %s" -msgstr "Eliminando rol global %s del usuario %s" +msgid "After terminating instances: %s" +msgstr "Después de terminar las instancias: %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/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" +msgstr "" -#: 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/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" +msgstr "Red a insertar en la configuración de openvpn" -#: 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/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" +msgstr "Mascara de red a insertar en la configuración de openvpn" -#: nova/api/ec2/admin.py:170 +#: ../nova/cloudpipe/pipelib.py:97 #, python-format -msgid "Delete project: %s" -msgstr "Borrar proyecto: %s" +msgid "Launching VPN for %s" +msgstr "Lanzando VPN para %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/db/sqlalchemy/migration.py:35 +msgid "python-migrate is not installed. Exiting." +msgstr "" -#: nova/api/ec2/admin.py:188 +#: ../nova/image/s3.py:99 #, python-format -msgid "Removing user %s from project %s" -msgstr "Eliminando usuario %s del proyecto %s" +msgid "Image %s could not be found" +msgstr "La imagen %s no ha podido ser encontrada" -#: 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/__init__.py:121 +msgid "Too many failed authentications." +msgstr "Demasiados intentos de autenticacion fallidos." -#: nova/api/ec2/cloud.py:117 +#: ../nova/api/ec2/__init__.py:131 #, python-format -msgid "Generating root CA: %s" -msgstr "Generando CA raiz: %s" +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/cloud.py:277 +#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140 #, python-format -msgid "Create key pair %s" -msgstr "Creando par de claves %s" +msgid "Authentication Failure: %s" +msgstr "Fallo de autenticación: %s" -#: nova/api/ec2/cloud.py:285 +#: ../nova/api/ec2/__init__.py:182 #, python-format -msgid "Delete key pair %s" -msgstr "Borrar para de claves %s" +msgid "Authenticated Request For %(uname)s:%(pname)s)" +msgstr "" -#: nova/api/ec2/cloud.py:357 +#: ../nova/api/ec2/__init__.py:207 #, 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" +msgid "action: %s" +msgstr "acción: %s" -#: nova/api/ec2/cloud.py:392 +#: ../nova/api/ec2/__init__.py:209 #, 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." +msgid "arg: %(key)s\t\tval: %(value)s" +msgstr "" -#: nova/api/ec2/cloud.py:421 +#: ../nova/api/ec2/__init__.py:281 #, python-format -msgid "Authorize security group ingress %s" -msgstr "Autorizar ingreso al grupo de seguridad %s" +msgid "" +"Unauthorized request for controller=%(controller)s and action=%(action)s" +msgstr "" -#: nova/api/ec2/cloud.py:432 +#: ../nova/api/ec2/__init__.py:314 #, python-format -msgid "This rule already exists in group %s" -msgstr "Esta regla ya existe en el grupo %s" +msgid "InstanceNotFound raised: %s" +msgstr "" -#: nova/api/ec2/cloud.py:460 +#: ../nova/api/ec2/__init__.py:320 #, python-format -msgid "Create Security Group %s" -msgstr "Crear Grupo de Seguridad %s" +msgid "VolumeNotFound raised: %s" +msgstr "" -#: nova/api/ec2/cloud.py:463 +#: ../nova/api/ec2/__init__.py:326 #, python-format -msgid "group %s already exists" -msgstr "el grupo %s ya existe" +msgid "NotFound raised: %s" +msgstr "No encontrado: %s" -#: nova/api/ec2/cloud.py:475 +#: ../nova/api/ec2/__init__.py:329 #, python-format -msgid "Delete security group %s" -msgstr "Borrar grupo de seguridad %s" +msgid "ApiError raised: %s" +msgstr "Sucedió un ApiError: %s" -#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#: ../nova/api/ec2/__init__.py:338 #, python-format -msgid "Get console output for instance %s" -msgstr "Obtener salida de la consola para la instancia %s" +msgid "Unexpected error raised: %s" +msgstr "Sucedió un error inexperado: %s" + +#: ../nova/api/ec2/__init__.py:343 +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/cloud.py:543 +#: ../nova/auth/dbdriver.py:84 #, python-format -msgid "Create volume of %s GB" -msgstr "Crear volumen de %s GB" +msgid "User %s already exists" +msgstr "El usuario %s ya existe" -#: nova/api/ec2/cloud.py:567 +#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232 #, python-format -msgid "Attach volume %s to instacne %s at %s" -msgstr "Asociar volumen %s a la instancia %s en %s" +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/api/ec2/cloud.py:579 +#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243 #, python-format -msgid "Detach volume %s" -msgstr "Desasociar volumen %s" +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/api/ec2/cloud.py:686 -msgid "Allocate address" -msgstr "Asignar dirección" +#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229 +#, 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/api/ec2/cloud.py:691 +#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268 #, python-format -msgid "Release address %s" -msgstr "Liberar dirección %s" +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/api/ec2/cloud.py:696 +#: ../nova/auth/dbdriver.py:245 #, python-format -msgid "Associate address %s to instance %s" -msgstr "Asociar dirección %s a la instancia %s" +msgid "User \"%s\" not found" +msgstr "No se ha encontrado el usuario \"%s\"" -#: nova/api/ec2/cloud.py:703 +#: ../nova/auth/dbdriver.py:248 #, python-format -msgid "Disassociate address %s" -msgstr "Desasociar dirección %s" +msgid "Project \"%s\" not found" +msgstr "No se ha encontrado el proyecto \"%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/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 "" +"Debes especificar xenapi_connection_url, xenapi_connection_username " +"(opcional), y xenapi_connection_password para usar connection_type=xenapi" -#: nova/api/ec2/cloud.py:738 +#: ../nova/virt/xenapi_conn.py:311 #, python-format -msgid "Reboot instance %r" -msgstr "Reiniciar instancia %r" +msgid "Task [%(name)s] %(task)s status: success %(result)s" +msgstr "" -#: nova/api/ec2/cloud.py:775 +#: ../nova/virt/xenapi_conn.py:317 #, python-format -msgid "De-registering image %s" -msgstr "Des-registrando la imagen %s" +msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s" +msgstr "" -#: nova/api/ec2/cloud.py:783 +#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344 #, python-format -msgid "Registered image %s with id %s" -msgstr "Registrada imagen %s con id %s" +msgid "Got exception: %s" +msgstr "Obtenida excepción %s" -#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#: ../nova/compute/monitor.py:259 #, python-format -msgid "attribute not supported: %s" -msgstr "atributo no soportado: %s" +msgid "updating %s..." +msgstr "actualizando %s..." + +#: ../nova/compute/monitor.py:289 +msgid "unexpected error during update" +msgstr "error inesperado durante la actualización" -#: nova/api/ec2/cloud.py:794 +#: ../nova/compute/monitor.py:356 #, python-format -msgid "invalid id: %s" -msgstr "id no valido: %s" +msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\"" +msgstr "" -#: nova/api/ec2/cloud.py:807 -msgid "user or group not specified" -msgstr "usuario o grupo no especificado" +#: ../nova/compute/monitor.py:379 +#, python-format +msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\"" +msgstr "" -#: nova/api/ec2/cloud.py:809 -msgid "only group \"all\" is supported" -msgstr "sólo el grupo \"all\" está soportado" +#: ../nova/compute/monitor.py:414 +msgid "unexpected exception getting connection" +msgstr "excepción inexperada al obtener la conexión" -#: nova/api/ec2/cloud.py:811 -msgid "operation_type must be add or remove" -msgstr "operation_type debe ser añadir o eliminar" +#: ../nova/compute/monitor.py:429 +#, python-format +msgid "Found instance: %s" +msgstr "Encontrada interfaz: %s" -#: nova/api/ec2/cloud.py:812 +#: ../nova/volume/san.py:67 #, python-format -msgid "Updating image %s publicity" -msgstr "Actualizando imagen %s públicamente" +msgid "Could not find iSCSI export for volume %s" +msgstr "" -#: nova/api/ec2/metadatarequesthandler.py:75 +#: ../nova/api/ec2/apirequest.py:100 #, python-format -msgid "Failed to get metadata for ip: %s" -msgstr "Fallo al generar metadatos para la ip %s" +msgid "" +"Unsupported API request: controller = %(controller)s, action = %(action)s" +msgstr "" -#: nova/api/openstack/__init__.py:70 +#: ../nova/api/openstack/__init__.py:55 #, python-format msgid "Caught error: %s" msgstr "Capturado error: %s" -#: nova/api/openstack/__init__.py:86 +#: ../nova/api/openstack/__init__.py:76 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/console/xvp.py:99 +msgid "Rebuilding xvp conf" +msgstr "" -#: nova/api/openstack/servers.py:199 +#: ../nova/console/xvp.py:116 #, python-format -msgid "Compute.api::unlock %s" -msgstr "Compute.api::unlock %s" +msgid "Re-wrote %s" +msgstr "" -#: nova/api/openstack/servers.py:213 -#, python-format -msgid "Compute.api::get_lock %s" -msgstr "Compute.api::get_lock %s" +#: ../nova/console/xvp.py:121 +msgid "Stopping xvp" +msgstr "" -#: nova/api/openstack/servers.py:224 -#, python-format -msgid "Compute.api::pause %s" -msgstr "Compute.api::pause %s" +#: ../nova/console/xvp.py:134 +msgid "Starting xvp" +msgstr "" -#: nova/api/openstack/servers.py:235 +#: ../nova/console/xvp.py:141 #, python-format -msgid "Compute.api::unpause %s" -msgstr "Compute.api::unpause %s" +msgid "Error starting xvp: %s" +msgstr "" -#: nova/api/openstack/servers.py:246 -#, python-format -msgid "compute.api::suspend %s" -msgstr "compute.api::suspend %s" +#: ../nova/console/xvp.py:144 +msgid "Restarting xvp" +msgstr "" -#: nova/api/openstack/servers.py:257 -#, python-format -msgid "compute.api::resume %s" -msgstr "compute.api::resume %s" +#: ../nova/console/xvp.py:146 +msgid "xvp not running..." +msgstr "" -#: nova/auth/dbdriver.py:84 -#, python-format -msgid "User %s already exists" -msgstr "El usuario %s ya existe" +#: ../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 "" -#: 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" +#: ../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 "" -#: 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" +#: ../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/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 -#, python-format -msgid "Project can't be modified because manager %s doesn't exist" +#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536 +msgid "network" 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\"" +#: ../bin/nova-manage.py:448 +msgid "IP address" +msgstr "" -#: nova/auth/dbdriver.py:248 -#, python-format -msgid "Project \"%s\" not found" -msgstr "No se ha encontrado el proyecto \"%s\"" +#: ../bin/nova-manage.py:449 +msgid "MAC address" +msgstr "" -#: nova/auth/fakeldap.py:33 -msgid "Attempted to instantiate singleton" -msgstr "Intento de instanciar sigleton" +#: ../bin/nova-manage.py:450 +msgid "hostname" +msgstr "" -#: nova/auth/ldapdriver.py:181 +#: ../bin/nova-manage.py:451 +msgid "host" +msgstr "" + +#: ../bin/nova-manage.py:537 +msgid "netmask" +msgstr "" + +#: ../bin/nova-manage.py:538 +msgid "start address" +msgstr "" + +#: ../nova/virt/disk.py:69 #, python-format -msgid "LDAP object for %s doesn't exist" -msgstr "El objeto LDAP para %s no existe" +msgid "Failed to load partition: %s" +msgstr "Fallo al cargar la partición: %s" -#: nova/auth/ldapdriver.py:218 +#: ../nova/virt/disk.py:91 #, 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" +msgid "Failed to mount filesystem: %s" +msgstr "Fallo al montar el sistema de ficheros: %s" + +#: ../nova/virt/disk.py:124 +#, python-format +msgid "nbd device %s did not show up" +msgstr "" -#: nova/auth/ldapdriver.py:478 +#: ../nova/virt/disk.py:128 #, python-format -msgid "User %s is already a member of the group %s" -msgstr "El usuario %s ya es miembro de el grupo %s" +msgid "Could not attach image to loopback: %s" +msgstr "No se puede unir la imagen con el loopback: %s" + +#: ../nova/virt/disk.py:151 +msgid "No free nbd devices" +msgstr "" -#: nova/auth/ldapdriver.py:507 +#: ../doc/ext/nova_todo.py:46 #, python-format -msgid "" -"Attempted to remove the last member of a group. Deleting the group at %s " -"instead." +msgid "%(filename)s, line %(line_info)d" msgstr "" -"Se ha intentado eliminar el último miembro de un grupo. Eliminando el grupo " -"%s en su lugar." -#: nova/auth/ldapdriver.py:528 +#. FIXME(chiradeep): implement this +#: ../nova/virt/hyperv.py:118 +msgid "In init host" +msgstr "En el host inicial" + +#: ../nova/virt/hyperv.py:131 #, python-format -msgid "Group at dn %s doesn't exist" -msgstr "El grupo con dn %s no existe" +msgid "Attempt to create duplicate vm %s" +msgstr "Intento de crear una vm duplicada %s" -#: nova/auth/manager.py:259 +#: ../nova/virt/hyperv.py:148 #, python-format -msgid "Looking up user: %r" -msgstr "Buscando usuario: %r" +msgid "Starting VM %s " +msgstr "Comenzando VM %s " -#: nova/auth/manager.py:263 +#: ../nova/virt/hyperv.py:150 #, python-format -msgid "Failed authorization for access key %s" -msgstr "Fallo de autorización para la clave de acceso %s" +msgid "Started VM %s " +msgstr "VM %s iniciada " -#: nova/auth/manager.py:264 +#: ../nova/virt/hyperv.py:152 #, python-format -msgid "No user found for access key %s" -msgstr "No se ha encontrado usuario para la clave de acceso %s" +msgid "spawn vm failed: %s" +msgstr "Inicio de vm fallido: %s" -#: nova/auth/manager.py:270 +#: ../nova/virt/hyperv.py:169 #, python-format -msgid "Using project name = user name (%s)" -msgstr "Utilizando nombre de proyecto = nombre de usuario (%s)" +msgid "Failed to create VM %s" +msgstr "Fallo al crear la VM %s" -#: nova/auth/manager.py:275 +#: ../nova/virt/hyperv.py:188 #, 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)" +msgid "Set memory for vm %s..." +msgstr "Se ha establecido la memoria para vm %s..." -#: nova/auth/manager.py:277 +#: ../nova/virt/hyperv.py:198 #, python-format -msgid "No project called %s could be found" -msgstr "No se ha podido encontrar un proyecto con nombre %s" +msgid "Set vcpus for vm %s..." +msgstr "Establecidas vcpus para vm %s..." -#: nova/auth/manager.py:281 +#: ../nova/virt/hyperv.py:202 #, python-format -msgid "Failed authorization: user %s not admin and not member of project %s" +msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s" msgstr "" -"Fallo de autorización: el usuario %s no es administrador y no es miembro del " -"proyecto %s" -#: nova/auth/manager.py:283 +#: ../nova/virt/hyperv.py:227 #, python-format -msgid "User %s is not a member of project %s" -msgstr "El usuario %s no es miembro del proyecto %s" +msgid "Failed to add diskdrive to VM %s" +msgstr "Fallo al añadir unidad de disco a la VM %s" -#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#: ../nova/virt/hyperv.py:230 #, 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" +msgid "New disk drive path is %s" +msgstr "La nueva ruta para unidad de disco es %s" -#: nova/auth/manager.py:408 +#: ../nova/virt/hyperv.py:247 #, python-format -msgid "The %s role can not be found" -msgstr "El rol %s no se ha podido encontrar" +msgid "Failed to add vhd file to VM %s" +msgstr "Fallo al añadir el fichero vhd a la VM %s" -#: nova/auth/manager.py:410 +#: ../nova/virt/hyperv.py:249 #, python-format -msgid "The %s role is global only" -msgstr "El rol %s es únicamente global" +msgid "Created disk for %s" +msgstr "Discos creados para %s" -#: nova/auth/manager.py:412 +#: ../nova/virt/hyperv.py:253 #, python-format -msgid "Adding role %s to user %s in project %s" -msgstr "Añadiendo rol %s al usuario %s en el proyecto %s" +msgid "Creating nic for %s " +msgstr "Creando nic para %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/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" +msgstr "Fallo al crear un puerto en el vswitch externo" -#: nova/auth/manager.py:505 +#: ../nova/virt/hyperv.py:273 #, python-format -msgid "Created project %s with manager %s" -msgstr "Proyecto %s creado con administrador %s" +msgid "Failed creating port for %s" +msgstr "Fallo creando puerto para %s" -#: nova/auth/manager.py:523 +#: ../nova/virt/hyperv.py:276 #, python-format -msgid "modifying project %s" -msgstr "modificando proyecto %s" +msgid "Created switch port %(vm_name)s on switch %(ext_path)s" +msgstr "" -#: nova/auth/manager.py:553 +#: ../nova/virt/hyperv.py:286 #, python-format -msgid "Remove user %s from project %s" -msgstr "Eliminar usuario %s del proyecto %s" +msgid "Failed to add nic to VM %s" +msgstr "Fallo al añadir nic a la VM %s" -#: nova/auth/manager.py:581 +#: ../nova/virt/hyperv.py:288 #, python-format -msgid "Deleting project %s" -msgstr "Eliminando proyecto %s" +msgid "Created nic for %s " +msgstr "Creando nic para %s " -#: nova/auth/manager.py:637 +#: ../nova/virt/hyperv.py:321 #, python-format -msgid "Created user %s (admin: %r)" -msgstr "Creado usuario %s (administrador: %r)" +msgid "WMI job failed: %s" +msgstr "Trabajo WMI falló: %s" -#: nova/auth/manager.py:645 +#: ../nova/virt/hyperv.py:325 #, python-format -msgid "Deleting user %s" -msgstr "Eliminando usuario %s" +msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s " +msgstr "" -#: nova/auth/manager.py:655 +#: ../nova/virt/hyperv.py:361 #, python-format -msgid "Access Key change for user %s" -msgstr "Cambio de clave de acceso para el usuario %s" +msgid "Got request to destroy vm %s" +msgstr "Recibida solicitud para destruir vm %s" -#: nova/auth/manager.py:657 +#: ../nova/virt/hyperv.py:386 #, python-format -msgid "Secret Key change for user %s" -msgstr "Cambio de clave secreta para el usuario %s" +msgid "Failed to destroy vm %s" +msgstr "Fallo al destruir vm %s" -#: nova/auth/manager.py:659 +#: ../nova/virt/hyperv.py:393 #, 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" +msgid "Del: disk %(vhdfile)s vm %(instance_name)s" +msgstr "" -#: nova/auth/manager.py:708 +#: ../nova/virt/hyperv.py:415 #, 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" +msgid "" +"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, " +"num_cpu=%(numprocs)s, cpu_time=%(uptime)s" 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/virt/hyperv.py:451 +#, python-format +msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s" +msgstr "" -#: nova/cloudpipe/pipelib.py:97 +#: ../nova/virt/hyperv.py:454 #, python-format -msgid "Launching VPN for %s" -msgstr "Lanzando VPN para %s" +msgid "Failed to change vm state of %(vm_name)s to %(req_state)s" +msgstr "" -#: nova/compute/api.py:67 +#: ../nova/compute/api.py:71 #, 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 +#: ../nova/compute/api.py:77 #, python-format msgid "Instance %d has no host" msgstr "La instancia %d no tiene host" -#: nova/compute/api.py:92 +#: ../nova/compute/api.py:97 #, python-format -msgid "Quota exceeeded for %s, tried to run %s instances" -msgstr "Quota superada por %s, intentando lanzar %s instancias" +msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances" +msgstr "" -#: nova/compute/api.py:94 +#: ../nova/compute/api.py:99 #, python-format msgid "" "Instance quota exceeded. You can only run %s more instances of this type." @@ -835,1343 +2112,1246 @@ msgstr "" "Quota de instancias superada. Sólo puedes ejecutar %s instancias más de este " "tipo." -#: nova/compute/api.py:109 +#: ../nova/compute/api.py:112 msgid "Creating a raw instance" msgstr "Creando una instancia raw" -#: nova/compute/api.py:156 +#: ../nova/compute/api.py:160 #, python-format msgid "Going to run %s instances..." msgstr "Vamos a ejecutar %s insntacias..." -#: nova/compute/api.py:180 +#: ../nova/compute/api.py:187 #, python-format -msgid "Casting to scheduler for %s/%s's instance %s" -msgstr "Llamando al planificar para %s/%s insntancia %s" +msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s" +msgstr "" -#: nova/compute/api.py:279 +#: ../nova/compute/api.py:292 #, python-format -msgid "Going to try and terminate %s" -msgstr "Se va a probar y terminar %s" +msgid "Going to try to terminate %s" +msgstr "" -#: nova/compute/api.py:283 +#: ../nova/compute/api.py:296 #, 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 +#: ../nova/compute/api.py:301 #, python-format msgid "Instance %d is already being terminated" msgstr "La instancia %d ha sido finalizada" -#: nova/compute/api.py:450 +#: ../nova/compute/api.py:481 #, 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 +#: ../nova/compute/api.py:496 msgid "Volume isn't attached to anything!" msgstr "¡El volumen no está unido a nada!" -#: nova/compute/disk.py:71 +#: ../nova/rpc.py:98 #, python-format -msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgid "" +"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in " +"%(fl_intv)d seconds." 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 +#: ../nova/rpc.py:103 #, python-format -msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgid "Unable to connect to AMQP server after %d tries. Shutting down." 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" +"Imposible conectar al servidor AMQP después de %d intentos. Apagando." -#: 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/rpc.py:122 +msgid "Reconnected to queue" +msgstr "Reconectado a la cola" -#: nova/compute/manager.py:257 -#, python-format -msgid "Rebooting instance %s" -msgstr "Reiniciando instancia %s" +#: ../nova/rpc.py:129 +msgid "Failed to fetch message from queue" +msgstr "Fallo al obtener el mensaje de la cola" -#: nova/compute/manager.py:260 +#: ../nova/rpc.py:159 #, python-format -msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgid "Initing the Adapter Consumer for %s" msgstr "" -"intentando reiniciar una instancia que no está en ejecución: %s (estado: %s " -"esperado: %s)" -#: nova/compute/manager.py:286 +#: ../nova/rpc.py:178 #, python-format -msgid "instance %s: snapshotting" -msgstr "instancia %s: creando snapshot" +msgid "received %s" +msgstr "recibido %s" -#: nova/compute/manager.py:289 +#. 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:191 #, 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)" +msgid "no method for message: %s" +msgstr "no hay método para el mensaje: %s" -#: nova/compute/manager.py:301 +#: ../nova/rpc.py:192 #, python-format -msgid "instance %s: rescuing" -msgstr "instancia %s: rescatando" +msgid "No method for message: %s" +msgstr "No hay método para el mensaje: %s" -#: nova/compute/manager.py:316 +#: ../nova/rpc.py:253 #, python-format -msgid "instance %s: unrescuing" +msgid "Returning exception %s to caller" 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 +#: ../nova/rpc.py:294 #, 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" +msgid "unpacked context: %s" +msgstr "contenido desempaquetado: %s" -#: nova/compute/manager.py:432 -#, python-format -msgid "instance %s: unlocking" -msgstr "instancia %s: desbloqueando" +#: ../nova/rpc.py:313 +msgid "Making asynchronous call..." +msgstr "Haciendo una llamada asíncrona..." -#: nova/compute/manager.py:442 +#: ../nova/rpc.py:316 #, python-format -msgid "instance %s: getting locked state" -msgstr "instancia %s: pasando a estado bloqueado" +msgid "MSG_ID is %s" +msgstr "MSG_ID es %s" -#: nova/compute/manager.py:462 -#, python-format -msgid "instance %s: attaching volume %s to %s" -msgstr "instancia %s: asociando volumen %s a %s" +#: ../nova/rpc.py:354 +msgid "Making asynchronous cast..." +msgstr "" -#: nova/compute/manager.py:478 +#: ../nova/rpc.py:364 #, python-format -msgid "instance %s: attach failed %s, removing" -msgstr "instalación %s: asociación fallida %s, eliminando" +msgid "response %s" +msgstr "respuesta %s" -#: nova/compute/manager.py:493 +#: ../nova/rpc.py:373 #, 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" +msgid "topic is %s" +msgstr "" -#: nova/compute/manager.py:497 +#: ../nova/rpc.py:374 #, python-format -msgid "Detaching volume from unknown instance %s" -msgstr "Desvinculando volumen de instancia desconocida %s" +msgid "message %s" +msgstr "mensaje %s" -#: nova/compute/monitor.py:259 +#: ../nova/volume/driver.py:78 #, 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" +msgid "Recovering from a failed execute. Try number %s" +msgstr "Recuperandose de una ejecución fallida. Intenta el número %s" -#: nova/compute/monitor.py:355 +#: ../nova/volume/driver.py:87 #, python-format -msgid "Cannot get blockstats for \"%s\" on \"%s\"" -msgstr "No puedo obtener estadísticas del bloque para \"%s\" en \"%s\"" +msgid "volume group %s doesn't exist" +msgstr "el grupo de volumenes %s no existe" -#: nova/compute/monitor.py:377 +#: ../nova/volume/driver.py:220 #, 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" +msgid "FAKE AOE: %s" +msgstr "Falso AOE: %s" -#: nova/compute/monitor.py:427 -#, python-format -msgid "Found instance: %s" -msgstr "Encontrada interfaz: %s" +#: ../nova/volume/driver.py:233 +msgid "Skipping ensure_export. No iscsi_target " +msgstr "" -#: 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/volume/driver.py:279 ../nova/volume/driver.py:288 +msgid "Skipping remove_export. No iscsi_target " +msgstr "" -#: nova/db/sqlalchemy/api.py:132 +#: ../nova/volume/driver.py:347 #, python-format -msgid "No service for id %s" -msgstr "No hay servicio para el id %s" +msgid "FAKE ISCSI: %s" +msgstr "Falso ISCSI: %s" -#: nova/db/sqlalchemy/api.py:229 +#: ../nova/volume/driver.py:359 #, python-format -msgid "No service for %s, %s" -msgstr "No hay servicio para %s, %s" +msgid "rbd has no pool %s" +msgstr "" -#: nova/db/sqlalchemy/api.py:574 +#: ../nova/volume/driver.py:414 #, python-format -msgid "No floating ip for address %s" -msgstr "No hay ip flotante para la dirección %s" +msgid "Sheepdog is not working: %s" +msgstr "" -#: nova/db/sqlalchemy/api.py:668 -#, python-format -msgid "No instance for id %s" -msgstr "No hay instancia con id %s" +#: ../nova/volume/driver.py:416 +msgid "Sheepdog is not working" +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 +#: ../nova/wsgi.py:68 #, python-format -msgid "Instance %s not found" -msgstr "La instancia %s no se ha encontrado" +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" -#: 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/wsgi.py:147 +msgid "You must implement __call__" +msgstr "" -#: 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" +#: ../bin/nova-instancemonitor.py:55 +msgid "Starting instance monitor" +msgstr "" -#: nova/db/sqlalchemy/api.py:1036 -#, python-format -msgid "No network for bridge %s" -msgstr "No hay red para el puente %s" +#: ../bin/nova-dhcpbridge.py:58 +msgid "leasing ip" +msgstr "" -#: nova/db/sqlalchemy/api.py:1050 -#, python-format -msgid "No network for instance %s" -msgstr "No hay red para la instancia %s" +#: ../bin/nova-dhcpbridge.py:73 +msgid "Adopted old lease or got a change of mac/hostname" +msgstr "" -#: nova/db/sqlalchemy/api.py:1180 -#, python-format -msgid "Token %s does not exist" -msgstr "El token %s no existe" +#: ../bin/nova-dhcpbridge.py:80 +msgid "releasing ip" +msgstr "" -#: nova/db/sqlalchemy/api.py:1205 +#: ../bin/nova-dhcpbridge.py:123 #, python-format -msgid "No quota for project_id %s" -msgstr "No hay quota para el project:id %s" +msgid "" +"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s " +"on interface %(interface)s" +msgstr "" -#: nova/db/sqlalchemy/api.py:1356 +#: ../nova/virt/fake.py:239 #, python-format -msgid "No volume for id %s" -msgstr "No hay volumen para el id %s" +msgid "Instance %s Not Found" +msgstr "La instancia %s no ha sido encontrada" -#: nova/db/sqlalchemy/api.py:1401 +#: ../nova/network/manager.py:153 #, python-format -msgid "Volume %s not found" -msgstr "El volumen %s no se ha encontrado" +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "" -#: 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/network/manager.py:157 +msgid "setting network host" +msgstr "configurando la red del host" -#: nova/db/sqlalchemy/api.py:1426 +#: ../nova/network/manager.py:212 #, python-format -msgid "No target id found for volume %s" -msgstr "No se ha encontrado id de destino para el volumen %s" +msgid "Leasing IP %s" +msgstr "Liberando IP %s" -#: nova/db/sqlalchemy/api.py:1471 +#: ../nova/network/manager.py:216 #, python-format -msgid "No security group with id %s" -msgstr "No hay un grupo de seguridad con el id %s" +msgid "IP %s leased that isn't associated" +msgstr "" -#: nova/db/sqlalchemy/api.py:1488 +#: ../nova/network/manager.py:220 #, 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" +msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s" +msgstr "" -#: nova/db/sqlalchemy/api.py:1576 +#: ../nova/network/manager.py:228 #, python-format -msgid "No secuity group rule with id %s" -msgstr "No hay una regla para el grupo de seguridad con el id %s" +msgid "IP %s leased that was already deallocated" +msgstr "" -#: nova/db/sqlalchemy/api.py:1650 +#: ../nova/network/manager.py:233 #, python-format -msgid "No user for id %s" -msgstr "No hay un usuario con el id %s" +msgid "Releasing IP %s" +msgstr "" -#: nova/db/sqlalchemy/api.py:1666 +#: ../nova/network/manager.py:237 #, python-format -msgid "No user for access key %s" -msgstr "No hay un usuario para la clave de acceso %s" +msgid "IP %s released that isn't associated" +msgstr "" -#: nova/db/sqlalchemy/api.py:1728 +#: ../nova/network/manager.py:241 #, python-format -msgid "No project with id %s" -msgstr "No hay proyecto con id %s" +msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s" +msgstr "" -#: nova/image/glance.py:78 +#: ../nova/network/manager.py:244 #, 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" +msgid "IP %s released that was not leased" +msgstr "" -#: nova/image/glance.py:97 -#, python-format -msgid "Parallax returned HTTP error %d from request for /images/detail" +#: ../nova/network/manager.py:519 +msgid "" +"The sum between the number of networks and the vlan start cannot be greater " +"than 4094" msgstr "" -"Parallax ha devuelto un error HTTP %d para la petición para /images/detail" -#: nova/image/s3.py:82 +#: ../nova/virt/xenapi/volume_utils.py:57 #, python-format -msgid "Image %s could not be found" -msgstr "La imagen %s no ha podido ser encontrada" +msgid "Introducing %s..." +msgstr "Introduciendo %s..." -#: nova/network/api.py:39 +#: ../nova/virt/xenapi/volume_utils.py:74 #, 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" +msgid "Introduced %(label)s as %(sr_ref)s." msgstr "" -"La quota de direcciones ha sido excedida. No puedes asignar más direcciones" -#: nova/network/linux_net.py:176 +#: ../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 "Starting VLAN inteface %s" -msgstr "Iniciando interfaz VLAN %s" +msgid "Unable to find SR from VBD %s" +msgstr "Imposible encontrar SR en VBD %s" -#: nova/network/linux_net.py:186 +#: ../nova/virt/xenapi/volume_utils.py:96 #, python-format -msgid "Starting Bridge interface for %s" -msgstr "Iniciando interfaz puente para %s" +msgid "Forgetting SR %s ... " +msgstr "Olvidando SR %s... " -#: nova/network/linux_net.py:254 +#: ../nova/virt/xenapi/volume_utils.py:101 #, python-format -msgid "Hupping dnsmasq threw %s" -msgstr "Excepción al recargar la configuración de dnsmasq: %s" +msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s" +msgstr "" -#: nova/network/linux_net.py:256 +#: ../nova/virt/xenapi/volume_utils.py:107 #, python-format -msgid "Pid %d is stale, relaunching dnsmasq" -msgstr "El pid %d está pasado, relanzando dnsmasq" +msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s" +msgstr "" -#: nova/network/linux_net.py:334 +#: ../nova/virt/xenapi/volume_utils.py:111 #, python-format -msgid "Killing dnsmasq threw %s" -msgstr "Al matar dnsmasq se lanzó %s" +msgid "Forgetting SR %s done." +msgstr "Olvidando SR %s completado." -#: nova/network/manager.py:135 -msgid "setting network host" -msgstr "configurando la red del host" +#: ../nova/virt/xenapi/volume_utils.py:113 +#, python-format +msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s" +msgstr "" -#: nova/network/manager.py:190 +#: ../nova/virt/xenapi/volume_utils.py:123 #, python-format -msgid "Leasing IP %s" -msgstr "Liberando IP %s" +msgid "Unable to introduce VDI on SR %s" +msgstr "Incapaz de insertar VDI en SR %s" -#: nova/network/manager.py:194 +#: ../nova/virt/xenapi/volume_utils.py:128 #, python-format -msgid "IP %s leased that isn't associated" -msgstr "" +msgid "Unable to get record of VDI %s on" +msgstr "Imposible obtener copia del VDI %s en" -#: nova/network/manager.py:197 +#: ../nova/virt/xenapi/volume_utils.py:146 #, python-format -msgid "IP %s leased to bad mac %s vs %s" -msgstr "IP %s asociada a una mac incorrecta %s vs %s" +msgid "Unable to introduce VDI for SR %s" +msgstr "Inposible insertar VDI para SR %s" -#: nova/network/manager.py:205 +#: ../nova/virt/xenapi/volume_utils.py:175 #, python-format -msgid "IP %s leased that was already deallocated" +msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s" msgstr "" -#: nova/network/manager.py:214 +#: ../nova/virt/xenapi/volume_utils.py:197 #, python-format -msgid "IP %s released that isn't associated" -msgstr "" +msgid "Mountpoint cannot be translated: %s" +msgstr "Punto de montaje no puede ser traducido: %s" -#: nova/network/manager.py:217 +#: ../nova/objectstore/image.py:262 #, python-format -msgid "IP %s released from bad mac %s vs %s" +msgid "Failed to decrypt private key: %s" msgstr "" -#: nova/network/manager.py:220 +#: ../nova/objectstore/image.py:269 #, python-format -msgid "IP %s released that was not leased" +msgid "Failed to decrypt initialization vector: %s" msgstr "" -#: nova/network/manager.py:442 +#: ../nova/objectstore/image.py:277 #, python-format -msgid "Dissassociated %s stale fixed ip(s)" +msgid "Failed to decrypt image file %(image_file)s: %(err)s" msgstr "" -#: nova/objectstore/handler.py:106 +#: ../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 +#: ../nova/objectstore/handler.py:137 msgid "Authenticated request" msgstr "Petición autenticada" -#: nova/objectstore/handler.py:182 +#: ../nova/objectstore/handler.py:182 msgid "List of buckets requested" msgstr "Listado de cubos solicitado" -#: nova/objectstore/handler.py:209 +#: ../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 +#: ../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 +#: ../nova/objectstore/handler.py:235 #, python-format msgid "Creating bucket %s" msgstr "Creando el cubo %s" -#: nova/objectstore/handler.py:245 +#: ../nova/objectstore/handler.py:245 #, python-format msgid "Deleting bucket %s" msgstr "Eliminando el cubo %s" -#: nova/objectstore/handler.py:249 +#: ../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 +#: ../nova/objectstore/handler.py:273 +#, python-format +msgid "Getting object: %(bname)s / %(nm)s" +msgstr "" + +#: ../nova/objectstore/handler.py:276 #, python-format -msgid "Getting object: %s / %s" -msgstr "Obteniendo objeto: %s / %s" +msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s" +msgstr "" -#: nova/objectstore/handler.py:274 +#: ../nova/objectstore/handler.py:296 #, 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" +msgid "Putting object: %(bname)s / %(nm)s" +msgstr "" -#: nova/objectstore/handler.py:292 +#: ../nova/objectstore/handler.py:299 #, python-format -msgid "Putting object: %s / %s" -msgstr "Colocando objeto: %s / %s" +msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s" +msgstr "" -#: nova/objectstore/handler.py:295 +#: ../nova/objectstore/handler.py:318 #, python-format -msgid "Unauthorized attempt to upload object %s to bucket %s" -msgstr "Intento no autorizado de subir el objeto %s al cubo %s" +msgid "Deleting object: %(bname)s / %(nm)s" +msgstr "" -#: nova/objectstore/handler.py:314 +#: ../nova/objectstore/handler.py:322 #, python-format -msgid "Deleting object: %s / %s" -msgstr "Eliminando objeto: %s / %s" +msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s" +msgstr "" -#: nova/objectstore/handler.py:393 +#: ../nova/objectstore/handler.py:396 #, 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 +#: ../nova/objectstore/handler.py:404 #, 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 +#: ../nova/objectstore/handler.py:409 #, python-format msgid "Starting image upload: %s" msgstr "Comenzando la subida de la imagen: %s" -#: nova/objectstore/handler.py:420 +#: ../nova/objectstore/handler.py:423 #, 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 +#: ../nova/objectstore/handler.py:431 #, python-format -msgid "Toggling publicity flag of image %s %r" -msgstr "Cambiando los atributos de publicidad de la imagen %s %r" +msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r" +msgstr "" -#: nova/objectstore/handler.py:433 +#. other attributes imply update +#: ../nova/objectstore/handler.py:436 #, python-format msgid "Updating user fields on image %s" msgstr "Actualizando los campos de usuario de la imagen %s" -#: nova/objectstore/handler.py:447 +#: ../nova/objectstore/handler.py:450 #, python-format msgid "Unauthorized attempt to delete image %s" msgstr "Intento no autorizado de borrar la imagen %s" -#: nova/objectstore/handler.py:452 +#: ../nova/objectstore/handler.py:455 #, 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/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "Buscando usuario: %r" -#: nova/scheduler/driver.py:66 -msgid "Must implement a fallback schedule" -msgstr "Debe de implementar un horario de reserva" +#: ../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/scheduler/manager.py:69 +#: ../nova/auth/manager.py:277 #, python-format -msgid "Casting to %s %s for %s" +msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)" msgstr "" -#: nova/scheduler/simple.py:63 -msgid "All hosts have too many cores" -msgstr "Todos los hosts tienen demasiados cores" +#: ../nova/auth/manager.py:279 +#, python-format +msgid "No project called %s could be found" +msgstr "No se ha podido encontrar un proyecto con nombre %s" -#: nova/scheduler/simple.py:95 -msgid "All hosts have too many gigabytes" -msgstr "Todos los hosts tienen demasiados gigabytes" +#: ../nova/auth/manager.py:287 +#, python-format +msgid "" +"Failed authorization: user %(uname)s not admin and not member of project " +"%(pjname)s" +msgstr "" -#: nova/scheduler/simple.py:115 -msgid "All hosts have too many networks" -msgstr "Todos los hosts tienen demasiadas redes" +#: ../nova/auth/manager.py:289 +#, python-format +msgid "User %(uid)s is not a member of project %(pjid)s" +msgstr "" -#: 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/auth/manager.py:298 ../nova/auth/manager.py:309 +#, python-format +msgid "Invalid signature for user %s" +msgstr "Firma invalida para el usuario %s" + +#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310 +msgid "Signature does not match" +msgstr "Las firmas no concuerdan" -#: nova/tests/test_cloud.py:210 +#: ../nova/auth/manager.py:380 +msgid "Must specify project" +msgstr "Debes especificar un proyecto" + +#: ../nova/auth/manager.py:414 #, 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..." +msgid "The %s role can not be found" +msgstr "El rol %s no se ha podido encontrar" -#: nova/tests/test_compute.py:104 +#: ../nova/auth/manager.py:416 #, python-format -msgid "Running instances: %s" -msgstr "Ejecutando instancias: %s" +msgid "The %s role is global only" +msgstr "El rol %s es únicamente global" + +#: ../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 "modificando proyecto %s" + +#: ../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 "Eliminando proyecto %s" + +#: ../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 "Eliminando usuario %s" + +#: ../nova/auth/manager.py:669 +#, python-format +msgid "Access Key change for user %s" +msgstr "Cambio de clave de acceso para el usuario %s" + +#: ../nova/auth/manager.py:671 +#, python-format +msgid "Secret Key change for user %s" +msgstr "Cambio de clave secreta para el usuario %s" + +#: ../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 "No hay datos vpn para el proyecto %s" + +#: ../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 "Se detuvo un servicio sin entrada en la base de datos" + +#: ../nova/service.py:195 +msgid "The service database object disappeared, Recreating it." +msgstr "El servicio objeto de base de datos ha desaparecido, recreándolo." + +#: ../nova/service.py:207 +msgid "Recovered model server connection!" +msgstr "Recuperada la conexión al servidor de modelos." + +#: ../nova/service.py:213 +msgid "model server went away" +msgstr "el servidor de modelos se ha ido" + +#: ../nova/auth/ldapdriver.py:174 +#, python-format +msgid "LDAP user %s already exists" +msgstr "" -#: nova/tests/test_compute.py:110 +#: ../nova/auth/ldapdriver.py:205 #, python-format -msgid "After terminating instances: %s" -msgstr "Después de terminar las instancias: %s" +msgid "LDAP object for %s doesn't exist" +msgstr "El objeto LDAP para %s no existe" -#: nova/tests/test_rpc.py:89 +#: ../nova/auth/ldapdriver.py:348 #, python-format -msgid "Nested received %s, %s" +msgid "User %s doesn't exist" msgstr "" -#: nova/tests/test_rpc.py:94 +#: ../nova/auth/ldapdriver.py:472 #, python-format -msgid "Nested return %s" +msgid "Group can't be created because group %s already exists" msgstr "" -#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#: ../nova/auth/ldapdriver.py:478 #, python-format -msgid "Received %s" -msgstr "Recibido %s" +msgid "Group can't be created because user %s doesn't exist" +msgstr "" -#: nova/tests/test_volume.py:162 +#: ../nova/auth/ldapdriver.py:495 #, 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" +msgid "User %s can't be searched in group because the user doesn't exist" +msgstr "" -#: nova/virt/fake.py:210 +#: ../nova/auth/ldapdriver.py:507 #, python-format -msgid "Instance %s Not Found" -msgstr "La instancia %s no ha sido encontrada" +msgid "User %s can't be added to the group because the user doesn't exist" +msgstr "" -#: nova/virt/hyperv.py:118 -msgid "In init host" -msgstr "En el host inicial" +#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521 +#, python-format +msgid "The group at dn %s doesn't exist" +msgstr "" -#: nova/virt/hyperv.py:131 +#: ../nova/auth/ldapdriver.py:513 #, python-format -msgid "Attempt to create duplicate vm %s" -msgstr "Intento de crear una vm duplicada %s" +msgid "User %(uid)s is already a member of the group %(group_dn)s" +msgstr "" -#: nova/virt/hyperv.py:148 +#: ../nova/auth/ldapdriver.py:524 #, python-format -msgid "Starting VM %s " -msgstr "Comenzando VM %s " +msgid "" +"User %s can't be removed from the group because the user doesn't exist" +msgstr "" -#: nova/virt/hyperv.py:150 +#: ../nova/auth/ldapdriver.py:528 #, python-format -msgid "Started VM %s " -msgstr "VM %s iniciada " +msgid "User %s is not a member of the group" +msgstr "" -#: nova/virt/hyperv.py:152 +#: ../nova/auth/ldapdriver.py:542 #, python-format -msgid "spawn vm failed: %s" -msgstr "Inicio de vm fallido: %s" +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/virt/hyperv.py:169 +#: ../nova/auth/ldapdriver.py:549 #, python-format -msgid "Failed to create VM %s" -msgstr "Fallo al crear la VM %s" +msgid "User %s can't be removed from all because the user doesn't exist" +msgstr "" -#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#: ../nova/auth/ldapdriver.py:564 #, python-format -msgid "Created VM %s..." -msgstr "Creada VM %s..." +msgid "Group at dn %s doesn't exist" +msgstr "El grupo con dn %s no existe" -#: nova/virt/hyperv.py:188 +#: ../nova/virt/xenapi/network_utils.py:40 #, python-format -msgid "Set memory for vm %s..." -msgstr "Se ha establecido la memoria para vm %s..." +msgid "Found non-unique network for bridge %s" +msgstr "Encontrada una red no única para el puente %s" -#: nova/virt/hyperv.py:198 +#: ../nova/virt/xenapi/network_utils.py:43 #, python-format -msgid "Set vcpus for vm %s..." -msgstr "Establecidas vcpus para vm %s..." +msgid "Found no network for bridge %s" +msgstr "No se ha encontrado red para el puente %s" -#: nova/virt/hyperv.py:202 +#: ../nova/api/ec2/admin.py:97 #, 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" +msgid "Creating new user: %s" +msgstr "Creando nuevo usuario: %s" -#: nova/virt/hyperv.py:227 +#: ../nova/api/ec2/admin.py:105 #, python-format -msgid "Failed to add diskdrive to VM %s" -msgstr "Fallo al añadir unidad de disco a la VM %s" +msgid "Deleting user: %s" +msgstr "Eliminando usuario: %s" -#: nova/virt/hyperv.py:230 +#: ../nova/api/ec2/admin.py:127 #, python-format -msgid "New disk drive path is %s" -msgstr "La nueva ruta para unidad de disco es %s" +msgid "Adding role %(role)s to user %(user)s for project %(project)s" +msgstr "" -#: nova/virt/hyperv.py:247 +#: ../nova/api/ec2/admin.py:131 #, python-format -msgid "Failed to add vhd file to VM %s" -msgstr "Fallo al añadir el fichero vhd a la VM %s" +msgid "Adding sitewide role %(role)s to user %(user)s" +msgstr "" -#: nova/virt/hyperv.py:249 +#: ../nova/api/ec2/admin.py:137 #, python-format -msgid "Created disk for %s" -msgstr "Discos creados para %s" +msgid "Removing role %(role)s from user %(user)s for project %(project)s" +msgstr "" -#: nova/virt/hyperv.py:253 +#: ../nova/api/ec2/admin.py:141 #, python-format -msgid "Creating nic for %s " -msgstr "Creando nic para %s " +msgid "Removing sitewide role %(role)s from user %(user)s" +msgstr "" -#: 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/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223 +msgid "operation must be add or remove" +msgstr "la operación debe ser añadir o eliminar" -#: nova/virt/hyperv.py:273 +#: ../nova/api/ec2/admin.py:159 #, python-format -msgid "Failed creating port for %s" -msgstr "Fallo creando puerto para %s" +msgid "Getting x509 for user: %(name)s on project: %(project)s" +msgstr "" -#: nova/virt/hyperv.py:275 +#: ../nova/api/ec2/admin.py:177 #, python-format -msgid "Created switch port %s on switch %s" -msgstr "Creado puerto %s en el switch %s" +msgid "Create project %(name)s managed by %(manager_user)s" +msgstr "" -#: nova/virt/hyperv.py:285 +#: ../nova/api/ec2/admin.py:190 #, python-format -msgid "Failed to add nic to VM %s" -msgstr "Fallo al añadir nic a la VM %s" +msgid "Modify project: %(name)s managed by %(manager_user)s" +msgstr "" -#: nova/virt/hyperv.py:287 +#: ../nova/api/ec2/admin.py:200 #, python-format -msgid "Created nic for %s " -msgstr "Creando nic para %s " +msgid "Delete project: %s" +msgstr "Borrar proyecto: %s" -#: nova/virt/hyperv.py:320 +#: ../nova/api/ec2/admin.py:214 #, python-format -msgid "WMI job failed: %s" -msgstr "Trabajo WMI falló: %s" +msgid "Adding user %(user)s to project %(project)s" +msgstr "" -#: nova/virt/hyperv.py:322 +#: ../nova/api/ec2/admin.py:218 #, python-format -msgid "WMI job succeeded: %s, Elapsed=%s " -msgstr "Trabajo WMI ha tenido exito: %s, Transcurrido=%s " +msgid "Removing user %(user)s from project %(project)s" +msgstr "" -#: nova/virt/hyperv.py:358 #, python-format -msgid "Got request to destroy vm %s" -msgstr "Recibida solicitud para destruir vm %s" +#~ 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/virt/hyperv.py:383 #, python-format -msgid "Failed to destroy vm %s" -msgstr "Fallo al destruir vm %s" +#~ msgid "(%s) publish (key: %s) %s" +#~ msgstr "(%s) públicar (clave: %s) %s" -#: nova/virt/hyperv.py:389 #, python-format -msgid "Del: disk %s vm %s" -msgstr "Del: disco %s vm %s" +#~ 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/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" +#~ msgid "Binding %s to %s with key %s" +#~ msgstr "Asociando %s a %s con clave %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" +#~ msgid "Getting from %s: %s" +#~ msgstr "Obteniendo desde %s: %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" +#~ msgid "Starting %s node" +#~ msgstr "Inciando nodo %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" +#~ msgid "Data store %s is unreachable. Trying again in %d seconds." +#~ msgstr "" +#~ "El almacen de datos %s es inalcanzable. Reintentandolo en %d segundos." -#: nova/virt/images.py:70 #, python-format -msgid "Finished retreving %s -- placed in %s" -msgstr "Finalizada la obtención de %s -- coloado en %s" +#~ msgid "Couldn't get IP, using 127.0.0.1 %s" +#~ msgstr "No puedo obtener IP, usando 127.0.0.1 %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" +#~ 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/virt/libvirt_conn.py:229 #, python-format -msgid "instance %s: deleting instance files %s" -msgstr "instancia %s: eliminando los ficheros de la instancia %s" +#~ msgid "arg: %s\t\tval: %s" +#~ msgstr "arg: %s \t \t val: %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" +#~ msgid "Authenticated Request For %s:%s)" +#~ msgstr "Solicitud de autenticación para %s:%s" -#: nova/virt/libvirt_conn.py:294 #, python-format -msgid "instance %s: rebooted" -msgstr "instancia %s: reiniciada" +#~ msgid "Adding role %s to user %s for project %s" +#~ msgstr "Añadiendo rol %s al usuario %s para el proyecto %s" -#: nova/virt/libvirt_conn.py:297 #, python-format -msgid "_wait_for_reboot failed: %s" -msgstr "_wait_for_reboot falló: %s" +#~ msgid "Removing role %s from user %s for project %s" +#~ msgstr "Eliminando rol %s del usuario %s para el proyecto %s" -#: nova/virt/libvirt_conn.py:340 #, python-format -msgid "instance %s: rescued" -msgstr "instancia %s: rescatada" +#~ msgid "Unauthorized request for controller=%s and action=%s" +#~ msgstr "Solicitud no autorizada para controller=%s y action=%s" -#: nova/virt/libvirt_conn.py:343 #, python-format -msgid "_wait_for_rescue failed: %s" -msgstr "_wait_for_rescue falló: %s" +#~ msgid "Getting x509 for user: %s on project: %s" +#~ msgstr "Obteniendo x509 para el usuario: %s en el proyecto %s" -#: nova/virt/libvirt_conn.py:370 #, python-format -msgid "instance %s: is running" -msgstr "instancia %s: está ejecutándose" +#~ msgid "Create project %s managed by %s" +#~ msgstr "Creación del proyecto %s gestionada por %s" -#: nova/virt/libvirt_conn.py:381 #, python-format -msgid "instance %s: booted" -msgstr "instancia %s: arrancada" +#~ msgid "Removing user %s from project %s" +#~ msgstr "Eliminando usuario %s del proyecto %s" -#: 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" +#~ msgid "Adding user %s to project %s" +#~ msgstr "Añadiendo usuario %s al proyecto %s" -#: 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" +#~ msgid "Unsupported API request: controller = %s,action = %s" +#~ msgstr "Solicitud de API no soportada: controller=%s,action=%s" -#: nova/virt/libvirt_conn.py:407 #, python-format -msgid "data: %r, fpath: %r" -msgstr "datos: %r, fpath: %r" +#~ msgid "Associate address %s to instance %s" +#~ msgstr "Asociar dirección %s a la instancia %s" -#: nova/virt/libvirt_conn.py:415 #, python-format -msgid "Contents of file %s: %r" -msgstr "Contenidos del fichero %s: %r" +#~ msgid "Attach volume %s to instacne %s at %s" +#~ msgstr "Asociar volumen %s a la instancia %s en %s" -#: nova/virt/libvirt_conn.py:449 #, python-format -msgid "instance %s: Creating image" -msgstr "instancia %s: Creando imagen" +#~ msgid "Registered image %s with id %s" +#~ msgstr "Registrada imagen %s con id %s" -#: 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" +#~ msgid "User %s is already a member of the group %s" +#~ msgstr "El usuario %s ya es miembro de el grupo %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" +#~ msgid "User %s is not a member of project %s" +#~ msgstr "El usuario %s no es miembro del proyecto %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)" +#~ msgid "failed authorization: no project named %s (user=%s)" +#~ msgstr "" +#~ "fallo de autorización: no existe proyecto con el nombre %s (usuario=%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" +#~ 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/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" +#~ msgid "Created user %s (admin: %r)" +#~ msgstr "Creado usuario %s (administrador: %r)" -#: nova/virt/xenapi_conn.py:263 #, python-format -msgid "Task [%s] %s status: success %s" -msgstr "Tarea [%s] %s estado: éxito %s" +#~ msgid "Created project %s with manager %s" +#~ msgstr "Proyecto %s creado con administrador %s" -#: nova/virt/xenapi_conn.py:271 #, python-format -msgid "Task [%s] %s status: %s %s" -msgstr "Tarea [%s] %s estado: %s %s" +#~ msgid "Removing role %s from user %s on project %s" +#~ msgstr "Eliminando rol %s al usuario %s en el proyecto %s" -#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 #, python-format -msgid "Got exception: %s" -msgstr "Obtenida excepción %s" +#~ msgid "Adding role %s to user %s in project %s" +#~ msgstr "Añadiendo rol %s al usuario %s en el proyecto %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" +#~ msgid "Remove user %s from project %s" +#~ msgstr "Eliminar usuario %s del proyecto %s" -#: 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" +#~ msgid "Admin status set to %r for user %s" +#~ msgstr "El estado del administrador se ha fijado a %r para el usuario %s" -#: nova/virt/xenapi/fake.py:283 #, python-format -msgid "Calling %s %s" -msgstr "Llamando %s %s" +#~ msgid "Going to try and terminate %s" +#~ msgstr "Se va a probar y terminar %s" -#: nova/virt/xenapi/fake.py:288 #, python-format -msgid "Calling getter %s" -msgstr "Llanado al adquiridor %s" +#~ msgid "Casting to scheduler for %s/%s's instance %s" +#~ msgstr "Llamando al planificar para %s/%s insntancia %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" +#~ msgid "Quota exceeeded for %s, tried to run %s instances" +#~ msgstr "Quota superada por %s, intentando lanzar %s instancias" -#: 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" +#~ msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +#~ msgstr "check_instance_lock: arguments: |%s| |%s| |%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" +#~ 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/virt/xenapi/vm_utils.py:127 #, python-format -msgid "Created VM %s as %s." -msgstr "Creada VM %s cómo %s" +#~ 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/virt/xenapi/vm_utils.py:147 #, python-format -msgid "Creating VBD for VM %s, VDI %s ... " -msgstr "Creando VBD para VM %s, VDI %s... " +#~ msgid "volume %s: creating lv of size %sG" +#~ msgstr "volumen %s: creando lv de tamaño %sG" -#: 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." +#~ msgid "Disassociating address %s" +#~ msgstr "Desasociando la dirección %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" +#~ 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/virt/xenapi/vm_utils.py:175 #, python-format -msgid "Unable to unplug VBD %s" -msgstr "Imposible desconectar VBD %s" +#~ 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/virt/xenapi/vm_utils.py:187 #, python-format -msgid "Unable to destroy VBD %s" -msgstr "Imposible destruir VBD %s" +#~ msgid "Detach volume %s from mountpoint %s on instance %s" +#~ msgstr "Desvinculando volumen %s del punto de montaje %s en la instancia %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." +#~ msgid "Cannot get blockstats for \"%s\" on \"%s\"" +#~ msgstr "No puedo obtener estadísticas del bloque para \"%s\" en \"%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." +#~ msgid "Cannot get ifstats for \"%s\" on \"%s\"" +#~ msgstr "No puedo obtener estadísticas de la interfaz para \"%s\" en \"%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'..." +#~ msgid "No instance for id %s" +#~ msgstr "No hay instancia con id %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" +#~ msgid "no keypair for user %s, name %s" +#~ msgstr "no hay par de claves para el usuario %s, nombre %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'" +#~ msgid "No service for %s, %s" +#~ msgstr "No hay servicio para %s, %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" +#~ msgid "No volume for id %s" +#~ msgstr "No hay volumen para el id %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" +#~ msgid "No security group named %s for project: %s" +#~ msgstr "No hay un grupo de seguridad con nombre %s para el proyecto: %s" -#: nova/virt/xenapi/vm_utils.py:290 #, python-format -msgid "PV Kernel in VDI:%d" -msgstr "PV Kernel en VDI:%d" +#~ 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/virt/xenapi/vm_utils.py:318 #, python-format -msgid "VDI %s is still available" -msgstr "VDI %s está todavía disponible" +#~ 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/virt/xenapi/vm_utils.py:331 #, python-format -msgid "(VM_UTILS) xenserver vm state -> |%s|" -msgstr "(VM_UTILS) xenserver vm state -> |%s|" +#~ msgid "IP %s leased to bad mac %s vs %s" +#~ msgstr "IP %s asociada a una mac incorrecta %s vs %s" -#: nova/virt/xenapi/vm_utils.py:333 #, python-format -msgid "(VM_UTILS) xenapi power_state -> |%s|" -msgstr "(VM_UTILS) xenapi power_state -> |%s|" +#~ msgid "Unauthorized attempt to get object %s from bucket %s" +#~ msgstr "Intento no autorizado de obtener el objeto %s en el cubo %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" +#~ msgid "Getting object: %s / %s" +#~ msgstr "Obteniendo objeto: %s / %s" -#: nova/virt/xenapi/vm_utils.py:407 #, python-format -msgid "Re-scanning SR %s" -msgstr "Re-escaneando SR %s" +#~ msgid "Putting object: %s / %s" +#~ msgstr "Colocando objeto: %s / %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..." +#~ msgid "Unauthorized attempt to upload object %s to bucket %s" +#~ msgstr "Intento no autorizado de subir el objeto %s al cubo %s" -#: 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" +#~ msgid "Deleting object: %s / %s" +#~ msgstr "Eliminando objeto: %s / %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" +#~ msgid "Toggling publicity flag of image %s %r" +#~ msgstr "Cambiando los atributos de publicidad de la imagen %s %r" -#: 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" +#~ 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/xenapi/vmops.py:99 #, python-format -msgid "Starting VM %s..." -msgstr "Iniciando VM %s..." +#~ msgid "WMI job succeeded: %s, Elapsed=%s " +#~ msgstr "Trabajo WMI ha tenido exito: %s, Transcurrido=%s " -#: nova/virt/xenapi/vmops.py:101 #, python-format -msgid "Spawning VM %s created %s." -msgstr "Iniciando VM %s creado %s." +#~ msgid "Created switch port %s on switch %s" +#~ msgstr "Creado puerto %s en el switch %s" -#: nova/virt/xenapi/vmops.py:112 #, python-format -msgid "Instance %s: booted" -msgstr "Instancia %s: iniciada" +#~ msgid "instance %s: deleting instance files %s" +#~ msgstr "instancia %s: eliminando los ficheros de la instancia %s" -#: nova/virt/xenapi/vmops.py:137 #, python-format -msgid "Instance not present %s" -msgstr "Instancia no existente %s" +#~ msgid "Finished retreving %s -- placed in %s" +#~ msgstr "Finalizada la obtención de %s -- coloado en %s" -#: nova/virt/xenapi/vmops.py:166 #, python-format -msgid "Starting snapshot for VM %s" -msgstr "Comenzando snapshot para la VM %s" +#~ 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/xenapi/vmops.py:174 #, python-format -msgid "Unable to Snapshot %s: %s" -msgstr "Incapaz de realizar snapshot %s: %s" +#~ msgid "Successfully changed vm state of %s to %s" +#~ msgstr "Cambio de estado de la vm con éxito de %s a %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" +#~ 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/xenapi/vmops.py:252 #, python-format -msgid "suspend: instance not present %s" -msgstr "suspendido: instancia no encontrada: %s" +#~ 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/xenapi/vmops.py:262 #, python-format -msgid "resume: instance not present %s" -msgstr "reanudar: instancia no encontrada %s" +#~ msgid "Contents of file %s: %r" +#~ msgstr "Contenidos del fichero %s: %r" -#: nova/virt/xenapi/vmops.py:271 #, python-format -msgid "Instance not found %s" -msgstr "instancia no encontrada %s" +#~ msgid "instance %s: injecting net into image %s" +#~ msgstr "instancia %s: inyectando red en la imagen %s" -#: nova/virt/xenapi/volume_utils.py:57 #, python-format -msgid "Introducing %s..." -msgstr "Introduciendo %s..." +#~ msgid "instance %s: injecting key into image %s" +#~ msgstr "instancia %s: inyectando clave en la imagen %s" -#: nova/virt/xenapi/volume_utils.py:74 #, python-format -msgid "Introduced %s as %s." -msgstr "Introducido %s cómo %s." +#~ msgid "data: %r, fpath: %r" +#~ msgstr "datos: %r, fpath: %r" -#: nova/virt/xenapi/volume_utils.py:78 -msgid "Unable to create Storage Repository" -msgstr "Imposible crear el repositorio de almacenamiento" +#, python-format +#~ msgid "Task [%s] %s status: %s %s" +#~ msgstr "Tarea [%s] %s estado: %s %s" -#: nova/virt/xenapi/volume_utils.py:90 #, python-format -msgid "Unable to find SR from VBD %s" -msgstr "Imposible encontrar SR en VBD %s" +#~ msgid "Task [%s] %s status: success %s" +#~ msgstr "Tarea [%s] %s estado: éxito %s" -#: nova/virt/xenapi/volume_utils.py:96 #, python-format -msgid "Forgetting SR %s ... " -msgstr "Olvidando SR %s... " +#~ msgid "Calling %s %s" +#~ msgstr "Llamando %s %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" +#~ msgid "%s: _db_content => %s" +#~ msgstr "%s: _db_content => %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" +#~ msgid "Created VBD %s for VM %s, VDI %s." +#~ msgstr "Creado VBD %s for VM %s, VDI %s." -#: nova/virt/xenapi/volume_utils.py:111 #, python-format -msgid "Forgetting SR %s done." -msgstr "Olvidando SR %s completado." +#~ msgid "Creating VBD for VM %s, VDI %s ... " +#~ msgstr "Creando VBD para VM %s, VDI %s... " -#: 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" +#~ msgid "Created VIF %s for VM %s, network %s." +#~ msgstr "Creado VIF %s para VM %s, red %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" +#~ msgid "Creating VIF for VM %s, network %s." +#~ msgstr "Creando VIF para VM %s, red %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" +#~ msgid "Created VM %s as %s." +#~ msgstr "Creada VM %s cómo %s" -#: nova/virt/xenapi/volume_utils.py:146 #, python-format -msgid "Unable to introduce VDI for SR %s" -msgstr "Inposible insertar VDI para SR %s" +#~ msgid "Asking xapi to upload %s as '%s'" +#~ msgstr "Solicitando a xapi la subida de %s cómo %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" +#~ msgid "VHD %s has parent %s" +#~ msgstr "VHD %s tiene cómo padre a %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" +#~ msgid "Asking xapi to fetch %s as %s" +#~ msgstr "Solicitando a xapi obtener %s cómo %s" -#: nova/virt/xenapi/volumeops.py:51 #, python-format -msgid "Attach_volume: %s, %s, %s" -msgstr "Attach_volume: %s, %s, %s" +#~ msgid "PV Kernel in VDI:%d" +#~ msgstr "PV Kernel en VDI:%d" -#: 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" +#~ 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/volumeops.py:81 #, python-format -msgid "Unable to use SR %s for instance %s" -msgstr "Imposible utilizar SR %s para la instancia %s" +#~ 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/volumeops.py:93 #, python-format -msgid "Unable to attach volume to instance %s" -msgstr "Imposible adjuntar volumen a la instancia %s" +#~ msgid "suspend: instance not present %s" +#~ msgstr "suspendido: instancia no encontrada: %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" +#~ msgid "Introduced %s as %s." +#~ msgstr "Introducido %s cómo %s." -#: nova/virt/xenapi/volumeops.py:106 #, python-format -msgid "Detach_volume: %s, %s" -msgstr "Detach_volume: %s, %s" +#~ msgid "resume: instance not present %s" +#~ msgstr "reanudar: instancia no encontrada %s" -#: nova/virt/xenapi/volumeops.py:113 #, python-format -msgid "Unable to locate volume %s" -msgstr "Imposible encontrar volumen %s" +#~ msgid "Instance not found %s" +#~ msgstr "instancia no encontrada %s" -#: nova/virt/xenapi/volumeops.py:121 #, python-format -msgid "Unable to detach volume %s" -msgstr "Imposible desasociar volumen %s" +#~ msgid "Ignoring exception %s when getting PBDs for %s" +#~ msgstr "Ignorando excepción %s al obtener PBDs de %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" +#~ msgid "Unable to create VDI on SR %s for instance %s" +#~ msgstr "Inpoisble crear VDI en SR %s para 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" +#~ msgid "Unable to obtain target information %s, %s" +#~ msgstr "Imposible obtener información del destino %s, %s" -#: 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" +#~ msgid "Ignoring exception %s when forgetting SR %s" +#~ msgstr "Ignorando excepción %s al olvidar SR %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" +#, python-format +#~ msgid "Ignoring exception %s when unplugging PBD %s" +#~ msgstr "Ignorando excepción %s al desconectar PBD %s" -#: nova/volume/api.py:97 -msgid "Volume is already attached" -msgstr "El volumen ya está asociado previamente" +#, python-format +#~ msgid "Attach_volume: %s, %s, %s" +#~ msgstr "Attach_volume: %s, %s, %s" -#: nova/volume/api.py:103 -msgid "Volume is already detached" -msgstr "El volumen ya ha sido desasociado previamente" +#, python-format +#~ msgid "Unable to use SR %s for instance %s" +#~ msgstr "Imposible utilizar SR %s para la instancia %s" -#: 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" +#~ msgid "Mountpoint %s attached to instance %s" +#~ msgstr "Punto de montaje %s unido a la instancia %s" -#: nova/volume/driver.py:85 #, python-format -msgid "volume group %s doesn't exist" -msgstr "el grupo de volumenes %s no existe" +#~ msgid "Detach_volume: %s, %s" +#~ msgstr "Detach_volume: %s, %s" -#: nova/volume/driver.py:210 #, python-format -msgid "FAKE AOE: %s" -msgstr "Falso AOE: %s" +#~ msgid "Mountpoint %s detached from instance %s" +#~ msgstr "Punto d emontaje %s desasociado de la instancia %s" -#: nova/volume/driver.py:315 #, python-format -msgid "FAKE ISCSI: %s" -msgstr "Falso ISCSI: %s" +#~ msgid "Quota exceeeded for %s, tried to create %sG volume" +#~ msgstr "Quota excedida para %s, intentando crear el volumen %sG" -#: nova/volume/manager.py:85 #, python-format -msgid "Re-exporting %s volumes" -msgstr "Exportando de nuevo los volumenes %s" +#~ 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/manager.py:93 #, python-format -msgid "volume %s: creating" -msgstr "volumen %s: creando" +#~ msgid "instance %s: attach failed %s, removing" +#~ msgstr "instalación %s: asociación fallida %s, eliminando" -#: nova/volume/manager.py:102 #, python-format -msgid "volume %s: creating lv of size %sG" -msgstr "volumen %s: creando lv de tamaño %sG" +#~ msgid "instance %s: attaching volume %s to %s" +#~ msgstr "instancia %s: asociando volumen %s a %s" -#: nova/volume/manager.py:106 #, python-format -msgid "volume %s: creating export" -msgstr "volumen %s: exportando" +#~ msgid "Snapshotting VM %s with label '%s'..." +#~ msgstr "Creando snapshot de la VM %s con la etiqueta '%s'..." -#: nova/volume/manager.py:113 #, python-format -msgid "volume %s: created successfully" -msgstr "volumen %s: creado satisfactoriamente" +#~ msgid "Created snapshot %s from VM %s." +#~ msgstr "Creando snapshot %s de la VM %s" -#: nova/volume/manager.py:121 -msgid "Volume is still attached" -msgstr "El volumen todavía está asociado" +#, python-format +#~ msgid "Unable to Snapshot %s: %s" +#~ msgstr "Incapaz de realizar snapshot %s: %s" -#: nova/volume/manager.py:123 -msgid "Volume is not local to this node" -msgstr "Volumen no local a este nodo" +#, python-format +#~ msgid "Adding sitewide role %s to user %s" +#~ msgstr "Añadiendo rol global %s al usuario %s" -#: nova/volume/manager.py:124 #, python-format -msgid "volume %s: removing export" -msgstr "volumen %s: eliminando exportación" +#~ msgid "Removing sitewide role %s from user %s" +#~ msgstr "Eliminando rol global %s del usuario %s" -#: nova/volume/manager.py:126 #, python-format -msgid "volume %s: deleting" -msgstr "volumen %s: eliminando" +#~ msgid "Del: disk %s vm %s" +#~ msgstr "Del: disco %s vm %s" -#: nova/volume/manager.py:129 #, python-format -msgid "volume %s: deleted successfully" -msgstr "volumen %s: eliminado satisfactoriamente" +#~ msgid "Spawning VM %s created %s." +#~ msgstr "Iniciando VM %s creado %s." diff --git a/po/it.po b/po/it.po index 3f439f9dd..1beb116a3 100644 --- a/po/it.po +++ b/po/it.po @@ -7,2135 +7,2892 @@ 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" +"POT-Creation-Date: 2011-02-21 10:03-0500\n" +"PO-Revision-Date: 2011-02-22 19:34+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-02-05 05:36+0000\n" -"X-Generator: Launchpad (build 12177)\n" +"X-Launchpad-Export-Date: 2011-03-19 06:19+0000\n" +"X-Generator: Launchpad (build 12559)\n" -#: nova/crypto.py:46 +#: ../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 "Nessun host trovato" + +#: ../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 "" +"%(description)s\n" +"Command: %(cmd)s\n" +"Exit code: %(exit_code)s\n" +"Stdout: %(stdout)r\n" +"Stderr: %(stderr)r" +msgstr "" +"%(description)s\n" +"Comando: %(cmd)s\n" +"Exit code: %(exit_code)s\n" +"Stdout: %(stdout)r\n" +"Stderr: %(stderr)r" + +#: ../nova/exception.py:107 +msgid "DB exception wrapped" +msgstr "DB eccezione wrappata" + +#. exc_type, exc_value, exc_traceback = sys.exc_info() +#: ../nova/exception.py:120 +msgid "Uncaught exception" +msgstr "Eccezione non gestita" + +#: ../nova/volume/api.py:45 +#, python-format +msgid "Quota exceeeded for %(pid)s, tried to create %(size)sG volume" +msgstr "" +"Quota ecceduta per %(pid)s, tentato di creare un volume di dimensione " +"%(size)sG" + +#: ../nova/volume/api.py:47 +#, python-format +msgid "Volume quota exceeded. You cannot create a volume of size %sG" +msgstr "Quota volume ecceduta. Non puoi creare un volume di dimensione %sG" + +#: ../nova/volume/api.py:71 ../nova/volume/api.py:96 +msgid "Volume status must be available" +msgstr "Lo stato del volume deve essere disponibile" + +#: ../nova/volume/api.py:98 +msgid "Volume is already attached" +msgstr "Il volume é già collegato" + +#: ../nova/volume/api.py:104 +msgid "Volume is already detached" +msgstr "Il volume é già scollegato" + +#: ../nova/api/openstack/servers.py:72 +msgid "Failed to read private ip" +msgstr "Impossibile leggere l'indirizzo IP privato" + +#: ../nova/api/openstack/servers.py:79 +msgid "Failed to read public ip(s)" +msgstr "Impossibile leggere gli indirizzi IP pubblici" + +#: ../nova/api/openstack/servers.py:152 +#, python-format +msgid "%(param)s property not found for image %(_image_id)s" +msgstr "" +"La proprietà %(param)s non é stata trovata per l'immagine %(_image_id)s" + +#: ../nova/api/openstack/servers.py:168 +msgid "No keypairs defined" +msgstr "No keypairs definita" + +#: ../nova/api/openstack/servers.py:238 +#, python-format +msgid "Compute.api::lock %s" +msgstr "Compute.api::lock %s" + +#: ../nova/api/openstack/servers.py:253 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "Compute.api::unlock %s" + +#: ../nova/api/openstack/servers.py:267 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "Compute.api::get_lock %s" + +#: ../nova/api/openstack/servers.py:281 +#, python-format +msgid "Compute.api::reset_network %s" +msgstr "Compute.api::reset_network %s" + +#: ../nova/api/openstack/servers.py:292 +#, python-format +msgid "Compute.api::pause %s" +msgstr "Compute.api::pause %s" + +#: ../nova/api/openstack/servers.py:303 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "Compute.api::unpause %s" + +#: ../nova/api/openstack/servers.py:314 +#, python-format +msgid "compute.api::suspend %s" +msgstr "compute.api::suspend %s" + +#: ../nova/api/openstack/servers.py:325 +#, python-format +msgid "compute.api::resume %s" +msgstr "compute.api::resume %s" + +#: ../nova/twistd.py:157 +msgid "Wrong number of arguments." +msgstr "Numero errato di argomenti" + +#: ../nova/twistd.py:209 +#, 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:221 +msgid "No such process" +msgstr "Nessun processo trovato" + +#: ../nova/twistd.py:230 ../nova/service.py:224 +#, python-format +msgid "Serving %s" +msgstr "Servire %s" + +#: ../nova/twistd.py:262 ../nova/service.py:225 +msgid "Full set of FLAGS:" +msgstr "Insieme di FLAGS:" + +#: ../nova/twistd.py:266 +#, python-format +msgid "Starting %s" +msgstr "Avvio di %s" + +#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101 +#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741 +#: ../nova/api/ec2/__init__.py:317 +#, python-format +msgid "Instance %s not found" +msgstr "Istanza %s non trovata" + +#. 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 "Attach_volume: %(instance_name)s, %(device_path)s, %(mountpoint)s" + +#: ../nova/virt/xenapi/volumeops.py:69 +#, python-format +msgid "Unable to create VDI on SR %(sr_ref)s for instance %(instance_name)s" +msgstr "" +"Impossible creare il VDI su SR %(sr_ref)s per l'istanza %(instance_name)s" + +#: ../nova/virt/xenapi/volumeops.py:80 +#, python-format +msgid "Unable to use SR %(sr_ref)s for instance %(instance_name)s" +msgstr "Impossibile usare SR %(sr_ref)s per l'istanza %(instance_name)s" + +#: ../nova/virt/xenapi/volumeops.py:91 +#, python-format +msgid "Unable to attach volume to instance %s" +msgstr "Impossibile montare il volume all'istanza %s" + +#: ../nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Mountpoint %(mountpoint)s attached to instance %(instance_name)s" +msgstr "Mountpoint %(mountpoint)s montato all'istanza %(instance_name)s" + +#. Detach VBD from VM +#: ../nova/virt/xenapi/volumeops.py:104 +#, python-format +msgid "Detach_volume: %(instance_name)s, %(mountpoint)s" +msgstr "Detach_volume: %(instance_name)s, %(mountpoint)s" + +#: ../nova/virt/xenapi/volumeops.py:112 +#, python-format +msgid "Unable to locate volume %s" +msgstr "Impossibile localizzare il volume %s" + +#: ../nova/virt/xenapi/volumeops.py:120 +#, python-format +msgid "Unable to detach volume %s" +msgstr "Impossibile smontare il volume %s" + +#: ../nova/virt/xenapi/volumeops.py:127 +#, python-format +msgid "Mountpoint %(mountpoint)s detached from instance %(instance_name)s" +msgstr "Mountpoint %(mountpoint)s smontato dall'istanza %(instance_name)s" + +#: ../nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "Tipo dell'istanza sconosciuto: %s" + +#: ../nova/crypto.py:46 msgid "Filename of root CA" -msgstr "Nome del file root CA" +msgstr "Filename di root CA" -#: nova/crypto.py:49 +#: ../nova/crypto.py:49 msgid "Filename of private key" -msgstr "Nome del file della chiave privata" +msgstr "Nome file della chiave privata" -#: nova/crypto.py:51 +#: ../nova/crypto.py:51 msgid "Filename of root Certificate Revokation List" -msgstr "" +msgstr "Nome file di root Certificate Revokation List" -#: nova/crypto.py:53 +#: ../nova/crypto.py:53 msgid "Where we keep our keys" msgstr "Dove si conservano le chiavi" -#: nova/crypto.py:55 +#: ../nova/crypto.py:55 msgid "Where we keep our root CA" msgstr "Dove si conserva root CA" -#: nova/crypto.py:57 +#: ../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 +#: ../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/scheduler/manager.py:69 +#, python-format +msgid "Casting to %(topic)s %(host)s for %(method)s" +msgstr "Trasmissione asincrona a %(topic)s %(host)s for %(method)s" + +#: ../nova/compute/manager.py:78 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "check_instance_lock: decorazione: |%s|" + +#: ../nova/compute/manager.py:80 +#, python-format +msgid "" +"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|" +msgstr "" +"check_instance_lock: argomenti: |%(self)s| |%(context)s| |%(instance_id)s|" + +#: ../nova/compute/manager.py:84 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "check_instance_lock: bloccato: |%s|" + +#: ../nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "check_instance_lock: admin: |%s|" + +#: ../nova/compute/manager.py:91 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "check_instance_lock: esecuzione: |%s|" + +#: ../nova/compute/manager.py:95 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "check_instance_lock: non esecuzione |%s|" + +#: ../nova/compute/manager.py:179 +msgid "Instance has already been created" +msgstr "L'istanza é stata già creata" + +#: ../nova/compute/manager.py:180 +#, python-format +msgid "instance %s: starting..." +msgstr "Istanza %s: in esecuzione..." + +#. pylint: disable=W0702 +#: ../nova/compute/manager.py:219 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "Istanza %s: esecuzione fallita..." + +#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286 +#, python-format +msgid "Terminating instance %s" +msgstr "Terminando l'istanza %s" + +#: ../nova/compute/manager.py:255 +#, python-format +msgid "Deallocating address %s" +msgstr "Deallocando l'indirizzo %s" + +#: ../nova/compute/manager.py:268 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "Provando a distruggere una istanza già distrutta: %s" + +#: ../nova/compute/manager.py:282 +#, python-format +msgid "Rebooting instance %s" +msgstr "Riavviando l'istanza %s" + +#: ../nova/compute/manager.py:287 +#, python-format +msgid "" +"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:311 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: ../nova/compute/manager.py:316 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:332 +#, python-format +msgid "" +"trying to reset the password on a non-running instance: %(instance_id)s " +"(state: %(instance_state)s expected: %(expected_state)s)" +msgstr "" + +#: ../nova/compute/manager.py:335 +#, python-format +msgid "instance %s: setting admin password" +msgstr "" + +#: ../nova/compute/manager.py:353 +#, python-format +msgid "" +"trying to inject a file into a non-running instance: %(instance_id)s (state: " +"%(instance_state)s expected: %(expected_state)s)" +msgstr "" + +#: ../nova/compute/manager.py:362 +#, python-format +msgid "instance %(nm)s: injecting file to %(plain_path)s" +msgstr "" + +#: ../nova/compute/manager.py:372 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: ../nova/compute/manager.py:387 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: ../nova/compute/manager.py:406 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: ../nova/compute/manager.py:423 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: ../nova/compute/manager.py:440 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: ../nova/compute/manager.py:453 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: ../nova/compute/manager.py:472 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: ../nova/compute/manager.py:491 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: ../nova/compute/manager.py:503 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: ../nova/compute/manager.py:513 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: ../nova/compute/manager.py:526 +#, python-format +msgid "instance %s: reset network" +msgstr "" + +#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: ../nova/compute/manager.py:543 +#, python-format +msgid "instance %s: getting ajax console" +msgstr "" + +#: ../nova/compute/manager.py:553 +#, python-format +msgid "" +"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s" +msgstr "" + +#. pylint: disable=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:569 +#, python-format +msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing" +msgstr "" + +#: ../nova/compute/manager.py:585 +#, python-format +msgid "" +"Detach volume %(volume_id)s from mountpoint %(mp)s on instance " +"%(instance_id)s" +msgstr "" + +#: ../nova/compute/manager.py:588 +#, 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:304 ../nova/virt/xenapi/fake.py:404 +#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478 +msgid "Raising NotImplemented" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:306 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:341 +#, python-format +msgid "Calling %(localname)s %(impl)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:346 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:406 +#, 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:187 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: ../nova/network/linux_net.py:208 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:314 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:316 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:358 +#, python-format +msgid "killing radvd threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:360 +#, python-format +msgid "Pid %d is stale, relaunching radvd" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:449 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: ../nova/utils.py:58 +#, python-format +msgid "Inner Exception: %s" +msgstr "Eccezione interna: %s" + +#: ../nova/utils.py:59 +#, python-format +msgid "Class %s cannot be found" +msgstr "Classe %s non può essere trovata" + +#: ../nova/utils.py:118 +#, python-format +msgid "Fetching %s" +msgstr "Prelievo %s" + +#: ../nova/utils.py:130 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "Esecuzione del comando (sottoprocesso): %s" + +#: ../nova/utils.py:143 ../nova/utils.py:183 +#, python-format +msgid "Result was %s" +msgstr "Il risultato é %s" + +#: ../nova/utils.py:159 +#, python-format +msgid "Running cmd (SSH): %s" +msgstr "" + +#: ../nova/utils.py:217 +#, python-format +msgid "debug in callback: %s" +msgstr "debug in callback: %s" + +#: ../nova/utils.py:222 +#, python-format +msgid "Running %s" +msgstr "" + +#: ../nova/utils.py:262 +#, python-format +msgid "Link Local address is not found.:%s" +msgstr "" + +#: ../nova/utils.py:265 +#, python-format +msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s" +msgstr "" + +#: ../nova/utils.py:363 +#, python-format +msgid "Invalid backend: %s" +msgstr "" + +#: ../nova/utils.py:374 +#, 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 "Pubblicando sulla route %s" + +#: ../nova/fakerabbit.py:84 +#, python-format +msgid "Declaring queue %s" +msgstr "Dichiarando la coda %s" + +#: ../nova/fakerabbit.py:90 +#, python-format +msgid "Declaring exchange %s" +msgstr "Dichiarando il centralino %s" + +#: ../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:168 +#, python-format +msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:171 +#, python-format +msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "VBD not found in instance %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:197 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:209 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:224 +#, python-format +msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:227 +#, python-format +msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:246 +#, 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:258 +#, python-format +msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:272 +#, python-format +msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:286 +#, python-format +msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:327 +#, python-format +msgid "Size for image %(image)s:%(virtual_size)d" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:332 #, python-format -msgid "Subject for certificate for users, %s for project, user, timestamp" +msgid "Glance image %s" msgstr "" -"Soggetto per il certificato degli utenti, %s per progetto, utente, orario" -#: nova/crypto.py:66 +#. we need to invoke a plugin for copying VDI's +#. content into proper path +#: ../nova/virt/xenapi/vm_utils.py:342 #, python-format -msgid "Subject for certificate for projects, %s for project, timestamp" -msgstr "Soggetto per il certificato dei progetti, %s per progetto, orario" +msgid "Copying VDI %s to /boot/guest on dom0" +msgstr "" -#: nova/crypto.py:71 +#: ../nova/virt/xenapi/vm_utils.py:352 #, python-format -msgid "Subject for certificate for vpns, %s for project, timestamp" -msgstr "Soggetto per il certificato delle vpn, %s per progetto, orario" +msgid "Kernel/Ramdisk VDI %s destroyed" +msgstr "" -#: nova/crypto.py:258 +#: ../nova/virt/xenapi/vm_utils.py:361 #, python-format -msgid "Flags path: %s" -msgstr "Percorso dei flags: %s" - -#: nova/exception.py:33 -msgid "Unexpected error while running command." +msgid "Asking xapi to fetch %(url)s as %(access)s" msgstr "" -"Si e' verificato un errore inatteso durante l'esecuzione del comando." -#: nova/exception.py:36 +#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402 #, 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" +msgid "Looking up vdi %s for PV kernel" +msgstr "" -#: nova/fakerabbit.py:48 +#: ../nova/virt/xenapi/vm_utils.py:397 #, python-format -msgid "(%s) publish (key: %s) %s" -msgstr "(%s) pubblica (chiave: %s) %s" +msgid "PV Kernel in VDI:%s" +msgstr "" -#: nova/fakerabbit.py:53 +#: ../nova/virt/xenapi/vm_utils.py:405 #, python-format -msgid "Publishing to route %s" -msgstr "Pubblicando sulla route %s" +msgid "Running pygrub against %s" +msgstr "" -#: nova/fakerabbit.py:83 +#: ../nova/virt/xenapi/vm_utils.py:411 #, python-format -msgid "Declaring queue %s" -msgstr "Dichiarando la coda %s" +msgid "Found Xen kernel %s" +msgstr "" -#: nova/fakerabbit.py:89 -#, python-format -msgid "Declaring exchange %s" -msgstr "Dichiarando il centralino %s" +#: ../nova/virt/xenapi/vm_utils.py:413 +msgid "No Xen kernel found. Booting HVM." +msgstr "" -#: nova/fakerabbit.py:95 +#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431 #, python-format -msgid "Binding %s to %s with key %s" -msgstr "Collegando %s a %s con la chiave %s" +msgid "duplicate name found: %s" +msgstr "" -#: nova/fakerabbit.py:120 +#: ../nova/virt/xenapi/vm_utils.py:442 #, python-format -msgid "Getting from %s: %s" +msgid "VDI %s is still available" msgstr "" -#: nova/rpc.py:92 +#: ../nova/virt/xenapi/vm_utils.py:463 #, python-format -msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +msgid "(VM_UTILS) xenserver vm state -> |%s|" msgstr "" -"Il server AMQP su %s:%d non é raggiungibile. Riprovare in %d secondi." -#: nova/rpc.py:99 +#: ../nova/virt/xenapi/vm_utils.py:465 #, python-format -msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgid "(VM_UTILS) xenapi power_state -> |%s|" 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/virt/xenapi/vm_utils.py:525 +#, python-format +msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s" +msgstr "" -#: nova/rpc.py:155 +#: ../nova/virt/xenapi/vm_utils.py:542 #, python-format -msgid "Initing the Adapter Consumer for %s" -msgstr "Inizializzando il Consumer Adapter per %s" +msgid "Re-scanning SR %s" +msgstr "" -#: nova/rpc.py:170 +#: ../nova/virt/xenapi/vm_utils.py:567 #, python-format -msgid "received %s" -msgstr "ricevuto %s" +msgid "" +"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..." +msgstr "" -#: nova/rpc.py:183 +#: ../nova/virt/xenapi/vm_utils.py:574 #, python-format -msgid "no method for message: %s" -msgstr "nessun metodo per il messaggio: %s" +msgid "" +"Parent %(parent_uuid)s doesn't match original parent " +"%(original_parent_uuid)s, waiting for coalesce..." +msgstr "" -#: nova/rpc.py:184 +#: ../nova/virt/xenapi/vm_utils.py:590 #, python-format -msgid "No method for message: %s" -msgstr "nessun metodo per il messagggio: %s" +msgid "No VDIs found for VM %s" +msgstr "" -#: nova/rpc.py:245 +#: ../nova/virt/xenapi/vm_utils.py:594 #, python-format -msgid "Returning exception %s to caller" -msgstr "Sollevando eccezione %s al chiamante" +msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s" +msgstr "" -#: nova/rpc.py:286 +#: ../nova/virt/xenapi/vm_utils.py:653 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188 #, python-format -msgid "unpacked context: %s" -msgstr "contesto decompresso: %s" +msgid "Creating VBD for VDI %s ... " +msgstr "" -#: nova/rpc.py:305 -msgid "Making asynchronous call..." -msgstr "Facendo chiamata asincrona..." +#: ../nova/virt/xenapi/vm_utils.py:655 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190 +#, python-format +msgid "Creating VBD for VDI %s done." +msgstr "" -#: nova/rpc.py:308 +#: ../nova/virt/xenapi/vm_utils.py:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192 #, python-format -msgid "MSG_ID is %s" -msgstr "MSG_ID é %s" +msgid "Plugging VBD %s ... " +msgstr "" -#: nova/rpc.py:356 +#: ../nova/virt/xenapi/vm_utils.py:659 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:194 #, python-format -msgid "response %s" -msgstr "risposta %s" +msgid "Plugging VBD %s done." +msgstr "" -#: nova/rpc.py:365 +#: ../nova/virt/xenapi/vm_utils.py:661 #, python-format -msgid "topic is %s" -msgstr "argomento é %s" +msgid "VBD %(vbd)s plugged as %(orig_dev)s" +msgstr "" -#: nova/rpc.py:366 +#: ../nova/virt/xenapi/vm_utils.py:664 #, python-format -msgid "message %s" -msgstr "messaggio %s" +msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s" +msgstr "" -#: nova/service.py:157 +#: ../nova/virt/xenapi/vm_utils.py:668 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:197 #, python-format -msgid "Starting %s node" -msgstr "Avviando il nodo %s" +msgid "Destroying VBD for VDI %s ... " +msgstr "" -#: nova/service.py:169 -msgid "Service killed that has no database entry" -msgstr "Servizio terminato che non ha entry nel database" +#: ../nova/virt/xenapi/vm_utils.py:671 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:200 +#, python-format +msgid "Destroying VBD for VDI %s done." +msgstr "" -#: nova/service.py:190 -msgid "The service database object disappeared, Recreating it." -msgstr "Il servizio é scomparso dal database, ricreo." +#: ../nova/virt/xenapi/vm_utils.py:683 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211 +msgid "VBD.unplug successful first time." +msgstr "" -#: nova/service.py:202 -msgid "Recovered model server connection!" -msgstr "Connessione al model server ripristinata!" +#: ../nova/virt/xenapi/vm_utils.py:688 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216 +msgid "VBD.unplug rejected: retrying..." +msgstr "" -#: nova/service.py:208 -msgid "model server went away" -msgstr "model server é scomparso" +#: ../nova/virt/xenapi/vm_utils.py:692 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220 +msgid "VBD.unplug successful eventually." +msgstr "" -#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#: ../nova/virt/xenapi/vm_utils.py:695 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:223 #, python-format -msgid "Data store %s is unreachable. Trying again in %d seconds." -msgstr "Datastore %s é irrangiungibile. Riprovare in %d seconds." +msgid "Ignoring XenAPI.Failure in VBD.unplug: %s" +msgstr "" -#: nova/service.py:232 nova/twistd.py:232 +#: ../nova/virt/xenapi/vm_utils.py:704 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:66 #, 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:" +msgid "Ignoring XenAPI.Failure %s" +msgstr "" -#: nova/twistd.py:211 +#: ../nova/virt/xenapi/vm_utils.py:735 #, python-format -msgid "pidfile %s does not exist. Daemon not running?\n" +msgid "" +"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..." msgstr "" -"Il pidfile %s non esiste. Assicurarsi che il demone é in esecuzione.\n" -#: nova/twistd.py:268 +#: ../nova/virt/xenapi/vm_utils.py:747 #, python-format -msgid "Starting %s" -msgstr "Avvio di %s" +msgid "Writing partition table %s done." +msgstr "" -#: nova/utils.py:53 +#: ../nova/tests/test_rpc.py:89 #, python-format -msgid "Inner Exception: %s" -msgstr "Eccezione interna: %s" +msgid "Nested received %(queue)s, %(value)s" +msgstr "" -#: nova/utils.py:54 +#: ../nova/tests/test_rpc.py:95 #, python-format -msgid "Class %s cannot be found" -msgstr "Classe %s non può essere trovata" +msgid "Nested return %s" +msgstr "" -#: nova/utils.py:113 +#: ../nova/tests/test_rpc.py:120 ../nova/tests/test_rpc.py:126 #, python-format -msgid "Fetching %s" -msgstr "Prelievo %s" +msgid "Received %s" +msgstr "" -#: nova/utils.py:125 -#, python-format -msgid "Running cmd (subprocess): %s" -msgstr "Esecuzione del comando (sottoprocesso): %s" +#: ../nova/db/sqlalchemy/api.py:44 +msgid "Use of empty request context is deprecated" +msgstr "" -#: nova/utils.py:138 +#: ../nova/db/sqlalchemy/api.py:133 #, python-format -msgid "Result was %s" -msgstr "Il risultato é %s" +msgid "No service for id %s" +msgstr "" -#: nova/utils.py:171 +#: ../nova/db/sqlalchemy/api.py:251 #, python-format -msgid "debug in callback: %s" -msgstr "debug in callback: %s" +msgid "No service for %(host)s, %(binary)s" +msgstr "" -#: nova/utils.py:176 -#, python-format -msgid "Running %s" +#: ../nova/db/sqlalchemy/api.py:592 +msgid "No fixed ips defined" msgstr "" -#: nova/utils.py:207 +#: ../nova/db/sqlalchemy/api.py:608 #, python-format -msgid "Couldn't get IP, using 127.0.0.1 %s" +msgid "No floating ip for address %s" msgstr "" -#: nova/utils.py:289 +#: ../nova/db/sqlalchemy/api.py:629 #, python-format -msgid "Invalid backend: %s" +msgid "No address for instance %s" msgstr "" -#: nova/utils.py:300 +#: ../nova/db/sqlalchemy/api.py:961 #, python-format -msgid "backend %s" +msgid "no keypair for user %(user_id)s, name %(name)s" msgstr "" -#: nova/api/ec2/__init__.py:133 -msgid "Too many failed authentications." +#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156 +#, python-format +msgid "No network for id %s" 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." +#: ../nova/db/sqlalchemy/api.py:1086 +msgid "No networks defined" msgstr "" -#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#: ../nova/db/sqlalchemy/api.py:1115 #, python-format -msgid "Authentication Failure: %s" +msgid "No network for bridge %s" msgstr "" -#: nova/api/ec2/__init__.py:190 +#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142 #, python-format -msgid "Authenticated Request For %s:%s)" +msgid "No network for instance %s" msgstr "" -#: nova/api/ec2/__init__.py:227 +#: ../nova/db/sqlalchemy/api.py:1277 #, python-format -msgid "action: %s" +msgid "Token %s does not exist" msgstr "" -#: nova/api/ec2/__init__.py:229 +#: ../nova/db/sqlalchemy/api.py:1302 #, python-format -msgid "arg: %s\t\tval: %s" +msgid "No quota for project_id %s" msgstr "" -#: nova/api/ec2/__init__.py:301 +#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501 +#: ../nova/api/ec2/__init__.py:323 #, python-format -msgid "Unauthorized request for controller=%s and action=%s" +msgid "Volume %s not found" msgstr "" -#: nova/api/ec2/__init__.py:339 +#: ../nova/db/sqlalchemy/api.py:1514 #, python-format -msgid "NotFound raised: %s" +msgid "No export device found for volume %s" msgstr "" -#: nova/api/ec2/__init__.py:342 +#: ../nova/db/sqlalchemy/api.py:1527 #, python-format -msgid "ApiError raised: %s" +msgid "No target id found for volume %s" msgstr "" -#: nova/api/ec2/__init__.py:349 +#: ../nova/db/sqlalchemy/api.py:1572 #, python-format -msgid "Unexpected error raised: %s" +msgid "No security group with id %s" msgstr "" -#: nova/api/ec2/__init__.py:354 -msgid "An unknown error has occurred. Please try your request again." +#: ../nova/db/sqlalchemy/api.py:1589 +#, python-format +msgid "No security group named %(group_name)s for project: %(project_id)s" msgstr "" -#: nova/api/ec2/admin.py:84 +#: ../nova/db/sqlalchemy/api.py:1682 #, python-format -msgid "Creating new user: %s" +msgid "No secuity group rule with id %s" msgstr "" -#: nova/api/ec2/admin.py:92 +#: ../nova/db/sqlalchemy/api.py:1756 #, python-format -msgid "Deleting user: %s" +msgid "No user for id %s" msgstr "" -#: nova/api/ec2/admin.py:114 +#: ../nova/db/sqlalchemy/api.py:1772 #, python-format -msgid "Adding role %s to user %s for project %s" +msgid "No user for access key %s" msgstr "" -#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#: ../nova/db/sqlalchemy/api.py:1834 #, python-format -msgid "Adding sitewide role %s to user %s" +msgid "No project with id %s" msgstr "" -#: nova/api/ec2/admin.py:122 +#: ../nova/db/sqlalchemy/api.py:1979 #, python-format -msgid "Removing role %s from user %s for project %s" +msgid "No console pool with id %(pool_id)s" msgstr "" -#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#: ../nova/db/sqlalchemy/api.py:1996 #, python-format -msgid "Removing sitewide role %s from user %s" +msgid "" +"No console pool of type %(console_type)s for compute host %(compute_host)s " +"on proxy host %(host)s" msgstr "" -#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 -msgid "operation must be add or remove" +#: ../nova/db/sqlalchemy/api.py:2035 +#, python-format +msgid "No console for instance %(instance_id)s in pool %(pool_id)s" msgstr "" -#: nova/api/ec2/admin.py:142 +#: ../nova/db/sqlalchemy/api.py:2057 #, python-format -msgid "Getting x509 for user: %s on project: %s" +msgid "on instance %s" msgstr "" -#: nova/api/ec2/admin.py:159 +#: ../nova/db/sqlalchemy/api.py:2058 #, python-format -msgid "Create project %s managed by %s" +msgid "No console with id %(console_id)s %(idesc)s" msgstr "" -#: nova/api/ec2/admin.py:170 +#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097 #, python-format -msgid "Delete project: %s" +msgid "No zone with id %(zone_id)s" msgstr "" -#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#: ../nova/virt/libvirt_conn.py:160 #, python-format -msgid "Adding user %s to project %s" +msgid "Checking state of %s" msgstr "" -#: nova/api/ec2/admin.py:188 +#: ../nova/virt/libvirt_conn.py:165 #, python-format -msgid "Removing user %s from project %s" +msgid "Current state of %(name)s was %(state)s." msgstr "" -#: nova/api/ec2/apirequest.py:95 +#: ../nova/virt/libvirt_conn.py:183 #, python-format -msgid "Unsupported API request: controller = %s,action = %s" +msgid "Connecting to libvirt: %s" msgstr "" -#: nova/api/ec2/cloud.py:117 -#, python-format -msgid "Generating root CA: %s" +#: ../nova/virt/libvirt_conn.py:196 +msgid "Connection to libvirt broke" msgstr "" -#: nova/api/ec2/cloud.py:277 +#: ../nova/virt/libvirt_conn.py:258 #, python-format -msgid "Create key pair %s" +msgid "instance %(instance_name)s: deleting instance files %(target)s" msgstr "" -#: nova/api/ec2/cloud.py:285 +#: ../nova/virt/libvirt_conn.py:283 #, python-format -msgid "Delete key pair %s" +msgid "Invalid device path %s" msgstr "" -#: nova/api/ec2/cloud.py:357 +#: ../nova/virt/libvirt_conn.py:313 #, python-format -msgid "%s is not a valid ipProtocol" +msgid "No disk at %s" msgstr "" -#: nova/api/ec2/cloud.py:361 -msgid "Invalid port range" +#: ../nova/virt/libvirt_conn.py:320 +msgid "Instance snapshotting is not supported for libvirtat this time" msgstr "" -#: nova/api/ec2/cloud.py:392 +#: ../nova/virt/libvirt_conn.py:336 #, python-format -msgid "Revoke security group ingress %s" +msgid "instance %s: rebooted" msgstr "" -#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 -msgid "No rule for the specified parameters." +#: ../nova/virt/libvirt_conn.py:339 +#, python-format +msgid "_wait_for_reboot failed: %s" msgstr "" -#: nova/api/ec2/cloud.py:421 +#: ../nova/virt/libvirt_conn.py:382 #, python-format -msgid "Authorize security group ingress %s" +msgid "instance %s: rescued" msgstr "" -#: nova/api/ec2/cloud.py:432 +#: ../nova/virt/libvirt_conn.py:385 #, python-format -msgid "This rule already exists in group %s" +msgid "_wait_for_rescue failed: %s" msgstr "" -#: nova/api/ec2/cloud.py:460 +#: ../nova/virt/libvirt_conn.py:411 #, python-format -msgid "Create Security Group %s" +msgid "instance %s: is running" msgstr "" -#: nova/api/ec2/cloud.py:463 +#: ../nova/virt/libvirt_conn.py:422 #, python-format -msgid "group %s already exists" +msgid "instance %s: booted" msgstr "" -#: nova/api/ec2/cloud.py:475 +#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186 #, python-format -msgid "Delete security group %s" +msgid "instance %s: failed to boot" msgstr "" -#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#: ../nova/virt/libvirt_conn.py:436 #, python-format -msgid "Get console output for instance %s" +msgid "virsh said: %r" msgstr "" -#: nova/api/ec2/cloud.py:543 -#, python-format -msgid "Create volume of %s GB" +#: ../nova/virt/libvirt_conn.py:440 +msgid "cool, it's a device" msgstr "" -#: nova/api/ec2/cloud.py:567 +#: ../nova/virt/libvirt_conn.py:448 #, python-format -msgid "Attach volume %s to instacne %s at %s" +msgid "data: %(data)r, fpath: %(fpath)r" msgstr "" -#: nova/api/ec2/cloud.py:579 +#: ../nova/virt/libvirt_conn.py:456 #, python-format -msgid "Detach volume %s" +msgid "Contents of file %(fpath)s: %(contents)r" msgstr "" -#: nova/api/ec2/cloud.py:686 -msgid "Allocate address" +#: ../nova/virt/libvirt_conn.py:489 +msgid "Unable to find an open port" msgstr "" -#: nova/api/ec2/cloud.py:691 +#: ../nova/virt/libvirt_conn.py:563 #, python-format -msgid "Release address %s" +msgid "instance %s: Creating image" msgstr "" -#: nova/api/ec2/cloud.py:696 +#: ../nova/virt/libvirt_conn.py:646 #, python-format -msgid "Associate address %s to instance %s" +msgid "instance %(inst_name)s: injecting key into image %(img_id)s" msgstr "" -#: nova/api/ec2/cloud.py:703 +#: ../nova/virt/libvirt_conn.py:649 #, python-format -msgid "Disassociate address %s" +msgid "instance %(inst_name)s: injecting net into image %(img_id)s" msgstr "" -#: nova/api/ec2/cloud.py:730 -msgid "Going to start terminating instances" +#. 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 "" -#: nova/api/ec2/cloud.py:738 +#. TODO(termie): cache? +#: ../nova/virt/libvirt_conn.py:665 #, python-format -msgid "Reboot instance %r" +msgid "instance %s: starting toXML method" msgstr "" -#: nova/api/ec2/cloud.py:775 +#: ../nova/virt/libvirt_conn.py:732 #, python-format -msgid "De-registering image %s" +msgid "instance %s: finished toXML method" msgstr "" -#: nova/api/ec2/cloud.py:783 -#, python-format -msgid "Registered image %s with id %s" +#: ../nova/virt/libvirt_conn.py:751 +msgid "diagnostics are not supported for libvirt" msgstr "" -#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#: ../nova/virt/libvirt_conn.py:1225 #, python-format -msgid "attribute not supported: %s" +msgid "Attempted to unfilter instance %s which is not filtered" msgstr "" -#: nova/api/ec2/cloud.py:794 +#: ../nova/api/ec2/metadatarequesthandler.py:76 #, python-format -msgid "invalid id: %s" +msgid "Failed to get metadata for ip: %s" msgstr "" -#: nova/api/ec2/cloud.py:807 -msgid "user or group not specified" +#: ../nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" msgstr "" -#: nova/api/ec2/cloud.py:809 -msgid "only group \"all\" is supported" +#: ../nova/network/api.py:39 +#, python-format +msgid "Quota exceeeded for %s, tried to allocate address" msgstr "" -#: nova/api/ec2/cloud.py:811 -msgid "operation_type must be add or remove" +#: ../nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" msgstr "" -#: nova/api/ec2/cloud.py:812 +#: ../nova/tests/test_volume.py:162 #, python-format -msgid "Updating image %s publicity" +msgid "Target %s allocated" msgstr "" -#: nova/api/ec2/metadatarequesthandler.py:75 +#: ../nova/virt/images.py:70 #, python-format -msgid "Failed to get metadata for ip: %s" +msgid "Finished retreving %(url)s -- placed in %(path)s" msgstr "" -#: nova/api/openstack/__init__.py:70 -#, python-format -msgid "Caught error: %s" +#: ../nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" msgstr "" -#: nova/api/openstack/__init__.py:86 -msgid "Including admin operations in API." +#: ../nova/console/manager.py:70 +msgid "Adding console" msgstr "" -#: nova/api/openstack/servers.py:184 +#: ../nova/console/manager.py:90 #, python-format -msgid "Compute.api::lock %s" +msgid "Tried to remove non-existant console %(console_id)s." msgstr "" -#: nova/api/openstack/servers.py:199 -#, python-format -msgid "Compute.api::unlock %s" +#: ../nova/api/direct.py:149 +msgid "not available" msgstr "" -#: nova/api/openstack/servers.py:213 +#: ../nova/api/ec2/cloud.py:62 #, python-format -msgid "Compute.api::get_lock %s" +msgid "The key_pair %s already exists" msgstr "" -#: nova/api/openstack/servers.py:224 +#. TODO(vish): Do this with M2Crypto instead +#: ../nova/api/ec2/cloud.py:118 #, python-format -msgid "Compute.api::pause %s" +msgid "Generating root CA: %s" msgstr "" -#: nova/api/openstack/servers.py:235 +#: ../nova/api/ec2/cloud.py:303 #, python-format -msgid "Compute.api::unpause %s" +msgid "Create key pair %s" msgstr "" -#: nova/api/openstack/servers.py:246 +#: ../nova/api/ec2/cloud.py:311 #, python-format -msgid "compute.api::suspend %s" +msgid "Delete key pair %s" msgstr "" -#: nova/api/openstack/servers.py:257 +#: ../nova/api/ec2/cloud.py:386 #, python-format -msgid "compute.api::resume %s" +msgid "%s is not a valid ipProtocol" msgstr "" -#: nova/auth/dbdriver.py:84 -#, python-format -msgid "User %s already exists" +#: ../nova/api/ec2/cloud.py:390 +msgid "Invalid port range" msgstr "" -#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#: ../nova/api/ec2/cloud.py:421 #, python-format -msgid "Project can't be created because manager %s doesn't exist" +msgid "Revoke security group ingress %s" msgstr "" -#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 -#, python-format -msgid "Project can't be created because project %s already exists" +#: ../nova/api/ec2/cloud.py:430 ../nova/api/ec2/cloud.py:459 +msgid "Not enough parameters to build a valid rule." 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" +#: ../nova/api/ec2/cloud.py:443 +msgid "No rule for the specified parameters." msgstr "" -#: nova/auth/dbdriver.py:245 +#: ../nova/api/ec2/cloud.py:450 #, python-format -msgid "User \"%s\" not found" +msgid "Authorize security group ingress %s" msgstr "" -#: nova/auth/dbdriver.py:248 +#: ../nova/api/ec2/cloud.py:464 #, python-format -msgid "Project \"%s\" not found" +msgid "This rule already exists in group %s" msgstr "" -#: nova/auth/fakeldap.py:33 -msgid "Attempted to instantiate singleton" +#: ../nova/api/ec2/cloud.py:492 +#, python-format +msgid "Create Security Group %s" msgstr "" -#: nova/auth/ldapdriver.py:181 +#: ../nova/api/ec2/cloud.py:495 #, python-format -msgid "LDAP object for %s doesn't exist" +msgid "group %s already exists" msgstr "" -#: nova/auth/ldapdriver.py:218 +#: ../nova/api/ec2/cloud.py:507 #, python-format -msgid "Project can't be created because user %s doesn't exist" +msgid "Delete security group %s" msgstr "" -#: nova/auth/ldapdriver.py:478 +#: ../nova/api/ec2/cloud.py:584 #, python-format -msgid "User %s is already a member of the group %s" +msgid "Create volume of %s GB" msgstr "" -#: nova/auth/ldapdriver.py:507 +#: ../nova/api/ec2/cloud.py:612 #, python-format -msgid "" -"Attempted to remove the last member of a group. Deleting the group at %s " -"instead." +msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s" msgstr "" -#: nova/auth/ldapdriver.py:528 +#: ../nova/api/ec2/cloud.py:629 #, python-format -msgid "Group at dn %s doesn't exist" +msgid "Detach volume %s" msgstr "" -#: nova/auth/manager.py:259 -#, python-format -msgid "Looking up user: %r" +#: ../nova/api/ec2/cloud.py:761 +msgid "Allocate address" msgstr "" -#: nova/auth/manager.py:263 +#: ../nova/api/ec2/cloud.py:766 #, python-format -msgid "Failed authorization for access key %s" +msgid "Release address %s" msgstr "" -#: nova/auth/manager.py:264 +#: ../nova/api/ec2/cloud.py:771 #, python-format -msgid "No user found for access key %s" +msgid "Associate address %(public_ip)s to instance %(instance_id)s" msgstr "" -#: nova/auth/manager.py:270 +#: ../nova/api/ec2/cloud.py:780 #, python-format -msgid "Using project name = user name (%s)" +msgid "Disassociate address %s" msgstr "" -#: nova/auth/manager.py:275 -#, python-format -msgid "failed authorization: no project named %s (user=%s)" +#: ../nova/api/ec2/cloud.py:807 +msgid "Going to start terminating instances" msgstr "" -#: nova/auth/manager.py:277 +#: ../nova/api/ec2/cloud.py:815 #, python-format -msgid "No project called %s could be found" +msgid "Reboot instance %r" msgstr "" -#: nova/auth/manager.py:281 +#: ../nova/api/ec2/cloud.py:867 #, python-format -msgid "Failed authorization: user %s not admin and not member of project %s" +msgid "De-registering image %s" msgstr "" -#: nova/auth/manager.py:283 +#: ../nova/api/ec2/cloud.py:875 #, python-format -msgid "User %s is not a member of project %s" +msgid "Registered image %(image_location)s with id %(image_id)s" msgstr "" -#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900 #, python-format -msgid "Invalid signature for user %s" +msgid "attribute not supported: %s" msgstr "" -#: nova/auth/manager.py:293 nova/auth/manager.py:304 -msgid "Signature does not match" +#: ../nova/api/ec2/cloud.py:890 +#, python-format +msgid "invalid id: %s" msgstr "" -#: nova/auth/manager.py:374 -msgid "Must specify project" +#: ../nova/api/ec2/cloud.py:903 +msgid "user or group not specified" msgstr "" -#: nova/auth/manager.py:408 -#, python-format -msgid "The %s role can not be found" +#: ../nova/api/ec2/cloud.py:905 +msgid "only group \"all\" is supported" msgstr "" -#: nova/auth/manager.py:410 -#, python-format -msgid "The %s role is global only" +#: ../nova/api/ec2/cloud.py:907 +msgid "operation_type must be add or remove" msgstr "" -#: nova/auth/manager.py:412 +#: ../nova/api/ec2/cloud.py:908 #, python-format -msgid "Adding role %s to user %s in project %s" +msgid "Updating image %s publicity" msgstr "" -#: nova/auth/manager.py:438 +#: ../bin/nova-api.py:52 #, python-format -msgid "Removing role %s from user %s on project %s" +msgid "Using paste.deploy config at: %s" msgstr "" -#: nova/auth/manager.py:505 +#: ../bin/nova-api.py:57 #, python-format -msgid "Created project %s with manager %s" +msgid "No paste configuration for app: %s" msgstr "" -#: nova/auth/manager.py:523 +#: ../bin/nova-api.py:59 #, python-format -msgid "modifying project %s" +msgid "" +"App Config: %(api)s\n" +"%(config)r" msgstr "" -#: nova/auth/manager.py:553 +#: ../bin/nova-api.py:64 #, python-format -msgid "Remove user %s from project %s" +msgid "Running %s API" msgstr "" -#: nova/auth/manager.py:581 +#: ../bin/nova-api.py:69 #, python-format -msgid "Deleting project %s" +msgid "No known API applications configured in %s." msgstr "" -#: nova/auth/manager.py:637 +#: ../bin/nova-api.py:83 #, python-format -msgid "Created user %s (admin: %r)" +msgid "Starting nova-api node (version %s)" msgstr "" -#: nova/auth/manager.py:645 +#: ../bin/nova-api.py:89 #, python-format -msgid "Deleting user %s" +msgid "No paste configuration found for: %s" msgstr "" -#: nova/auth/manager.py:655 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84 #, python-format -msgid "Access Key change for user %s" +msgid "Argument %(key)s value %(value)s is too short." msgstr "" -#: nova/auth/manager.py:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89 #, python-format -msgid "Secret Key change for user %s" +msgid "Argument %(key)s value %(value)s contains invalid characters." msgstr "" -#: nova/auth/manager.py:659 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94 #, python-format -msgid "Admin status set to %r for user %s" +msgid "Argument %(key)s value %(value)s starts with a hyphen." msgstr "" -#: nova/auth/manager.py:708 +#: ../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 "No vpn data for project %s" +msgid "Argument %s is required." 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" +#: ../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 "" -#: nova/cloudpipe/pipelib.py:51 -msgid "Netmask to push into openvpn config" +#: ../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/cloudpipe/pipelib.py:97 +#: ../nova/virt/xenapi/vmops.py:67 #, python-format -msgid "Launching VPN for %s" +msgid "Attempted to create non-unique name %s" msgstr "" -#: nova/compute/api.py:67 +#: ../nova/virt/xenapi/vmops.py:73 #, python-format -msgid "Instance %d was not found in get_network_topic" +msgid "instance %(name)s: not enough free memory" msgstr "" -#: nova/compute/api.py:73 +#: ../nova/virt/xenapi/vmops.py:148 #, python-format -msgid "Instance %d has no host" +msgid "Starting VM %s..." msgstr "" -#: nova/compute/api.py:92 +#: ../nova/virt/xenapi/vmops.py:151 #, python-format -msgid "Quota exceeeded for %s, tried to run %s instances" +msgid "Spawning VM %(instance_name)s created %(vm_ref)s." msgstr "" -#: nova/compute/api.py:94 +#: ../nova/virt/xenapi/vmops.py:162 #, python-format -msgid "" -"Instance quota exceeded. You can only run %s more instances of this type." +msgid "Invalid value for onset_files: '%s'" msgstr "" -#: nova/compute/api.py:109 -msgid "Creating a raw instance" +#: ../nova/virt/xenapi/vmops.py:167 +#, python-format +msgid "Injecting file path: '%s'" msgstr "" -#: nova/compute/api.py:156 +#: ../nova/virt/xenapi/vmops.py:180 #, python-format -msgid "Going to run %s instances..." +msgid "Instance %s: booted" msgstr "" -#: nova/compute/api.py:180 +#: ../nova/virt/xenapi/vmops.py:232 #, python-format -msgid "Casting to scheduler for %s/%s's instance %s" +msgid "Instance not present %s" msgstr "" -#: nova/compute/api.py:279 +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vmops.py:261 #, python-format -msgid "Going to try and terminate %s" +msgid "Starting snapshot for VM %s" msgstr "" -#: nova/compute/api.py:283 +#: ../nova/virt/xenapi/vmops.py:269 #, python-format -msgid "Instance %d was not found during terminate" +msgid "Unable to Snapshot %(vm_ref)s: %(exc)s" msgstr "" -#: nova/compute/api.py:288 +#: ../nova/virt/xenapi/vmops.py:280 #, python-format -msgid "Instance %d is already being terminated" +msgid "Finished snapshot and upload for VM %s" msgstr "" -#: nova/compute/api.py:450 +#: ../nova/virt/xenapi/vmops.py:356 #, python-format -msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgid "VM %(vm)s already halted, skipping shutdown..." msgstr "" -#: nova/compute/api.py:465 -msgid "Volume isn't attached to anything!" +#: ../nova/virt/xenapi/vmops.py:389 +msgid "Removing kernel/ramdisk files" msgstr "" -#: nova/compute/disk.py:71 -#, python-format -msgid "Input partition size not evenly divisible by sector size: %d / %d" +#: ../nova/virt/xenapi/vmops.py:399 +msgid "kernel/ramdisk files removed" msgstr "" -#: nova/compute/disk.py:75 +#: ../nova/virt/xenapi/vmops.py:561 #, python-format -msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgid "" +"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/disk.py:128 +#: ../nova/virt/xenapi/vmops.py:564 #, python-format -msgid "Could not attach image to loopback: %s" +msgid "" +"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM " +"id=%(instance_id)s; args=%(strargs)s" msgstr "" -#: nova/compute/disk.py:136 +#: ../nova/virt/xenapi/vmops.py:569 #, python-format -msgid "Failed to load partition: %s" +msgid "" +"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/disk.py:158 +#: ../nova/virt/xenapi/vmops.py:760 #, python-format -msgid "Failed to mount filesystem: %s" +msgid "OpenSSL error: %s" msgstr "" -#: nova/compute/instance_types.py:41 +#: ../nova/tests/test_compute.py:148 #, python-format -msgid "Unknown instance type: %s" +msgid "Running instances: %s" msgstr "" -#: nova/compute/manager.py:69 +#: ../nova/tests/test_compute.py:154 #, python-format -msgid "check_instance_lock: decorating: |%s|" +msgid "After terminating instances: %s" msgstr "" -#: nova/compute/manager.py:71 -#, python-format -msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +#: ../nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" msgstr "" -#: nova/compute/manager.py:75 -#, python-format -msgid "check_instance_lock: locked: |%s|" +#: ../nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" msgstr "" -#: nova/compute/manager.py:77 -#, python-format -msgid "check_instance_lock: admin: |%s|" +#: ../nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" msgstr "" -#: nova/compute/manager.py:82 +#: ../nova/cloudpipe/pipelib.py:97 #, python-format -msgid "check_instance_lock: executing: |%s|" +msgid "Launching VPN for %s" msgstr "" -#: nova/compute/manager.py:86 -#, python-format -msgid "check_instance_lock: not executing |%s|" +#: ../nova/db/sqlalchemy/migration.py:35 +msgid "python-migrate is not installed. Exiting." msgstr "" -#: nova/compute/manager.py:157 -msgid "Instance has already been created" +#: ../nova/image/s3.py:99 +#, python-format +msgid "Image %s could not be found" msgstr "" -#: nova/compute/manager.py:158 -#, python-format -msgid "instance %s: starting..." +#: ../nova/api/ec2/__init__.py:121 +msgid "Too many failed authentications." msgstr "" -#: nova/compute/manager.py:197 +#: ../nova/api/ec2/__init__.py:131 #, python-format -msgid "instance %s: Failed to spawn" +msgid "" +"Access key %(access_key)s has had %(failures)d failed authentications and " +"will be locked out for %(lock_mins)d minutes." msgstr "" -#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140 #, python-format -msgid "Terminating instance %s" +msgid "Authentication Failure: %s" msgstr "" -#: nova/compute/manager.py:217 +#: ../nova/api/ec2/__init__.py:182 #, python-format -msgid "Disassociating address %s" +msgid "Authenticated Request For %(uname)s:%(pname)s)" msgstr "" -#: nova/compute/manager.py:230 +#: ../nova/api/ec2/__init__.py:207 #, python-format -msgid "Deallocating address %s" +msgid "action: %s" msgstr "" -#: nova/compute/manager.py:243 +#: ../nova/api/ec2/__init__.py:209 #, python-format -msgid "trying to destroy already destroyed instance: %s" +msgid "arg: %(key)s\t\tval: %(value)s" msgstr "" -#: nova/compute/manager.py:257 +#: ../nova/api/ec2/__init__.py:281 #, python-format -msgid "Rebooting instance %s" +msgid "" +"Unauthorized request for controller=%(controller)s and action=%(action)s" msgstr "" -#: nova/compute/manager.py:260 +#: ../nova/api/ec2/__init__.py:314 #, python-format -msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgid "InstanceNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:286 +#: ../nova/api/ec2/__init__.py:320 #, python-format -msgid "instance %s: snapshotting" +msgid "VolumeNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:289 +#: ../nova/api/ec2/__init__.py:326 #, python-format -msgid "" -"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgid "NotFound raised: %s" msgstr "" -#: nova/compute/manager.py:301 +#: ../nova/api/ec2/__init__.py:329 #, python-format -msgid "instance %s: rescuing" +msgid "ApiError raised: %s" msgstr "" -#: nova/compute/manager.py:316 +#: ../nova/api/ec2/__init__.py:338 #, python-format -msgid "instance %s: unrescuing" +msgid "Unexpected error raised: %s" msgstr "" -#: nova/compute/manager.py:335 -#, python-format -msgid "instance %s: pausing" +#: ../nova/api/ec2/__init__.py:343 +msgid "An unknown error has occurred. Please try your request again." msgstr "" -#: nova/compute/manager.py:352 +#: ../nova/auth/dbdriver.py:84 #, python-format -msgid "instance %s: unpausing" +msgid "User %s already exists" msgstr "" -#: nova/compute/manager.py:369 +#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232 #, python-format -msgid "instance %s: retrieving diagnostics" +msgid "Project can't be created because manager %s doesn't exist" msgstr "" -#: nova/compute/manager.py:382 +#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243 #, python-format -msgid "instance %s: suspending" +msgid "Project can't be created because user %s doesn't exist" msgstr "" -#: nova/compute/manager.py:401 +#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229 #, python-format -msgid "instance %s: resuming" +msgid "Project can't be created because project %s already exists" msgstr "" -#: nova/compute/manager.py:420 +#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268 #, python-format -msgid "instance %s: locking" +msgid "Project can't be modified because manager %s doesn't exist" msgstr "" -#: nova/compute/manager.py:432 +#: ../nova/auth/dbdriver.py:245 #, python-format -msgid "instance %s: unlocking" +msgid "User \"%s\" not found" msgstr "" -#: nova/compute/manager.py:442 +#: ../nova/auth/dbdriver.py:248 #, python-format -msgid "instance %s: getting locked state" +msgid "Project \"%s\" not found" msgstr "" -#: nova/compute/manager.py:462 -#, python-format -msgid "instance %s: attaching volume %s to %s" +#: ../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/compute/manager.py:478 +#: ../nova/virt/xenapi_conn.py:311 #, python-format -msgid "instance %s: attach failed %s, removing" +msgid "Task [%(name)s] %(task)s status: success %(result)s" msgstr "" -#: nova/compute/manager.py:493 +#: ../nova/virt/xenapi_conn.py:317 #, python-format -msgid "Detach volume %s from mountpoint %s on instance %s" +msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s" msgstr "" -#: nova/compute/manager.py:497 +#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344 #, python-format -msgid "Detaching volume from unknown instance %s" +msgid "Got exception: %s" msgstr "" -#: nova/compute/monitor.py:259 +#: ../nova/compute/monitor.py:259 #, python-format msgid "updating %s..." msgstr "" -#: nova/compute/monitor.py:289 +#: ../nova/compute/monitor.py:289 msgid "unexpected error during update" msgstr "" -#: nova/compute/monitor.py:355 +#: ../nova/compute/monitor.py:356 #, python-format -msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/monitor.py:377 +#: ../nova/compute/monitor.py:379 #, python-format -msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/monitor.py:412 +#: ../nova/compute/monitor.py:414 msgid "unexpected exception getting connection" msgstr "" -#: nova/compute/monitor.py:427 +#: ../nova/compute/monitor.py:429 #, 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 +#: ../nova/volume/san.py:67 #, python-format -msgid "No service for id %s" +msgid "Could not find iSCSI export for volume %s" msgstr "" -#: nova/db/sqlalchemy/api.py:229 +#: ../nova/api/ec2/apirequest.py:100 #, python-format -msgid "No service for %s, %s" +msgid "" +"Unsupported API request: controller = %(controller)s, action = %(action)s" msgstr "" -#: nova/db/sqlalchemy/api.py:574 +#: ../nova/api/openstack/__init__.py:55 #, python-format -msgid "No floating ip for address %s" +msgid "Caught error: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:668 -#, python-format -msgid "No instance for id %s" +#: ../nova/api/openstack/__init__.py:76 +msgid "Including admin operations in API." 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" +#: ../nova/console/xvp.py:99 +msgid "Rebuilding xvp conf" msgstr "" -#: nova/db/sqlalchemy/api.py:891 +#: ../nova/console/xvp.py:116 #, python-format -msgid "no keypair for user %s, name %s" +msgid "Re-wrote %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 -#, python-format -msgid "No network for id %s" +#: ../nova/console/xvp.py:121 +msgid "Stopping xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1036 -#, python-format -msgid "No network for bridge %s" +#: ../nova/console/xvp.py:134 +msgid "Starting xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1050 +#: ../nova/console/xvp.py:141 #, python-format -msgid "No network for instance %s" +msgid "Error starting xvp: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1180 -#, python-format -msgid "Token %s does not exist" +#: ../nova/console/xvp.py:144 +msgid "Restarting xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1205 -#, python-format -msgid "No quota for project_id %s" +#: ../nova/console/xvp.py:146 +msgid "xvp not running..." msgstr "" -#: nova/db/sqlalchemy/api.py:1356 -#, python-format -msgid "No volume for id %s" +#: ../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 "" -#: nova/db/sqlalchemy/api.py:1401 -#, python-format -msgid "Volume %s not found" +#: ../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 "" -#: nova/db/sqlalchemy/api.py:1413 -#, python-format -msgid "No export device found for volume %s" +#: ../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/db/sqlalchemy/api.py:1426 -#, python-format -msgid "No target id found for volume %s" +#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536 +msgid "network" msgstr "" -#: nova/db/sqlalchemy/api.py:1471 -#, python-format -msgid "No security group with id %s" +#: ../bin/nova-manage.py:448 +msgid "IP address" msgstr "" -#: nova/db/sqlalchemy/api.py:1488 -#, python-format -msgid "No security group named %s for project: %s" +#: ../bin/nova-manage.py:449 +msgid "MAC address" msgstr "" -#: nova/db/sqlalchemy/api.py:1576 -#, python-format -msgid "No secuity group rule with id %s" +#: ../bin/nova-manage.py:450 +msgid "hostname" msgstr "" -#: nova/db/sqlalchemy/api.py:1650 -#, python-format -msgid "No user for id %s" +#: ../bin/nova-manage.py:451 +msgid "host" msgstr "" -#: nova/db/sqlalchemy/api.py:1666 -#, python-format -msgid "No user for access key %s" +#: ../bin/nova-manage.py:537 +msgid "netmask" msgstr "" -#: nova/db/sqlalchemy/api.py:1728 -#, python-format -msgid "No project with id %s" +#: ../bin/nova-manage.py:538 +msgid "start address" msgstr "" -#: nova/image/glance.py:78 +#: ../nova/virt/disk.py:69 #, python-format -msgid "Parallax returned HTTP error %d from request for /images" +msgid "Failed to load partition: %s" msgstr "" -#: nova/image/glance.py:97 +#: ../nova/virt/disk.py:91 #, python-format -msgid "Parallax returned HTTP error %d from request for /images/detail" +msgid "Failed to mount filesystem: %s" msgstr "" -#: nova/image/s3.py:82 +#: ../nova/virt/disk.py:124 #, python-format -msgid "Image %s could not be found" +msgid "nbd device %s did not show up" msgstr "" -#: nova/network/api.py:39 +#: ../nova/virt/disk.py:128 #, python-format -msgid "Quota exceeeded for %s, tried to allocate address" +msgid "Could not attach image to loopback: %s" msgstr "" -#: nova/network/api.py:42 -msgid "Address quota exceeded. You cannot allocate any more addresses" +#: ../nova/virt/disk.py:151 +msgid "No free nbd devices" msgstr "" -#: nova/network/linux_net.py:176 +#: ../doc/ext/nova_todo.py:46 #, python-format -msgid "Starting VLAN inteface %s" +msgid "%(filename)s, line %(line_info)d" msgstr "" -#: nova/network/linux_net.py:186 -#, python-format -msgid "Starting Bridge interface for %s" +#. FIXME(chiradeep): implement this +#: ../nova/virt/hyperv.py:118 +msgid "In init host" msgstr "" -#: nova/network/linux_net.py:254 +#: ../nova/virt/hyperv.py:131 #, python-format -msgid "Hupping dnsmasq threw %s" +msgid "Attempt to create duplicate vm %s" msgstr "" -#: nova/network/linux_net.py:256 +#: ../nova/virt/hyperv.py:148 #, python-format -msgid "Pid %d is stale, relaunching dnsmasq" +msgid "Starting VM %s " msgstr "" -#: nova/network/linux_net.py:334 +#: ../nova/virt/hyperv.py:150 #, python-format -msgid "Killing dnsmasq threw %s" -msgstr "" - -#: nova/network/manager.py:135 -msgid "setting network host" +msgid "Started VM %s " msgstr "" -#: nova/network/manager.py:190 +#: ../nova/virt/hyperv.py:152 #, python-format -msgid "Leasing IP %s" +msgid "spawn vm failed: %s" msgstr "" -#: nova/network/manager.py:194 +#: ../nova/virt/hyperv.py:169 #, python-format -msgid "IP %s leased that isn't associated" +msgid "Failed to create VM %s" msgstr "" -#: nova/network/manager.py:197 +#: ../nova/virt/hyperv.py:188 #, python-format -msgid "IP %s leased to bad mac %s vs %s" +msgid "Set memory for vm %s..." msgstr "" -#: nova/network/manager.py:205 +#: ../nova/virt/hyperv.py:198 #, python-format -msgid "IP %s leased that was already deallocated" +msgid "Set vcpus for vm %s..." msgstr "" -#: nova/network/manager.py:214 +#: ../nova/virt/hyperv.py:202 #, python-format -msgid "IP %s released that isn't associated" +msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s" msgstr "" -#: nova/network/manager.py:217 +#: ../nova/virt/hyperv.py:227 #, python-format -msgid "IP %s released from bad mac %s vs %s" +msgid "Failed to add diskdrive to VM %s" msgstr "" -#: nova/network/manager.py:220 +#: ../nova/virt/hyperv.py:230 #, python-format -msgid "IP %s released that was not leased" +msgid "New disk drive path is %s" msgstr "" -#: nova/network/manager.py:442 +#: ../nova/virt/hyperv.py:247 #, python-format -msgid "Dissassociated %s stale fixed ip(s)" +msgid "Failed to add vhd file to VM %s" msgstr "" -#: nova/objectstore/handler.py:106 +#: ../nova/virt/hyperv.py:249 #, python-format -msgid "Unknown S3 value type %r" +msgid "Created disk for %s" msgstr "" -#: nova/objectstore/handler.py:137 -msgid "Authenticated request" +#: ../nova/virt/hyperv.py:253 +#, python-format +msgid "Creating nic for %s " msgstr "" -#: nova/objectstore/handler.py:182 -msgid "List of buckets requested" +#: ../nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" msgstr "" -#: nova/objectstore/handler.py:209 +#: ../nova/virt/hyperv.py:273 #, python-format -msgid "List keys for bucket %s" +msgid "Failed creating port for %s" msgstr "" -#: nova/objectstore/handler.py:217 +#: ../nova/virt/hyperv.py:276 #, python-format -msgid "Unauthorized attempt to access bucket %s" +msgid "Created switch port %(vm_name)s on switch %(ext_path)s" msgstr "" -#: nova/objectstore/handler.py:235 +#: ../nova/virt/hyperv.py:286 #, python-format -msgid "Creating bucket %s" +msgid "Failed to add nic to VM %s" msgstr "" -#: nova/objectstore/handler.py:245 +#: ../nova/virt/hyperv.py:288 #, python-format -msgid "Deleting bucket %s" +msgid "Created nic for %s " msgstr "" -#: nova/objectstore/handler.py:249 +#: ../nova/virt/hyperv.py:321 #, python-format -msgid "Unauthorized attempt to delete bucket %s" +msgid "WMI job failed: %s" msgstr "" -#: nova/objectstore/handler.py:271 +#: ../nova/virt/hyperv.py:325 #, python-format -msgid "Getting object: %s / %s" +msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s " msgstr "" -#: nova/objectstore/handler.py:274 +#: ../nova/virt/hyperv.py:361 #, python-format -msgid "Unauthorized attempt to get object %s from bucket %s" +msgid "Got request to destroy vm %s" msgstr "" -#: nova/objectstore/handler.py:292 +#: ../nova/virt/hyperv.py:386 #, python-format -msgid "Putting object: %s / %s" +msgid "Failed to destroy vm %s" msgstr "" -#: nova/objectstore/handler.py:295 +#: ../nova/virt/hyperv.py:393 #, python-format -msgid "Unauthorized attempt to upload object %s to bucket %s" +msgid "Del: disk %(vhdfile)s vm %(instance_name)s" msgstr "" -#: nova/objectstore/handler.py:314 +#: ../nova/virt/hyperv.py:415 #, python-format -msgid "Deleting object: %s / %s" +msgid "" +"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, " +"num_cpu=%(numprocs)s, cpu_time=%(uptime)s" msgstr "" -#: nova/objectstore/handler.py:393 +#: ../nova/virt/hyperv.py:451 #, python-format -msgid "Not authorized to upload image: invalid directory %s" +msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/objectstore/handler.py:401 +#: ../nova/virt/hyperv.py:454 #, python-format -msgid "Not authorized to upload image: unauthorized bucket %s" +msgid "Failed to change vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/objectstore/handler.py:406 +#: ../nova/compute/api.py:71 #, python-format -msgid "Starting image upload: %s" +msgid "Instance %d was not found in get_network_topic" msgstr "" -#: nova/objectstore/handler.py:420 +#: ../nova/compute/api.py:77 #, python-format -msgid "Not authorized to update attributes of image %s" +msgid "Instance %d has no host" msgstr "" -#: nova/objectstore/handler.py:428 +#: ../nova/compute/api.py:97 #, python-format -msgid "Toggling publicity flag of image %s %r" +msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances" msgstr "" -#: nova/objectstore/handler.py:433 +#: ../nova/compute/api.py:99 #, python-format -msgid "Updating user fields on image %s" +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." msgstr "" -#: nova/objectstore/handler.py:447 -#, python-format -msgid "Unauthorized attempt to delete image %s" +#: ../nova/compute/api.py:112 +msgid "Creating a raw instance" msgstr "" -#: nova/objectstore/handler.py:452 +#: ../nova/compute/api.py:160 #, python-format -msgid "Deleted image: %s" +msgid "Going to run %s instances..." 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" +#: ../nova/compute/api.py:187 +#, python-format +msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s" msgstr "" -#: nova/scheduler/driver.py:66 -msgid "Must implement a fallback schedule" +#: ../nova/compute/api.py:292 +#, python-format +msgid "Going to try to terminate %s" msgstr "" -#: nova/scheduler/manager.py:69 +#: ../nova/compute/api.py:296 #, python-format -msgid "Casting to %s %s for %s" +msgid "Instance %d was not found during terminate" msgstr "" -#: nova/scheduler/simple.py:63 -msgid "All hosts have too many cores" +#: ../nova/compute/api.py:301 +#, python-format +msgid "Instance %d is already being terminated" msgstr "" -#: nova/scheduler/simple.py:95 -msgid "All hosts have too many gigabytes" +#: ../nova/compute/api.py:481 +#, python-format +msgid "Invalid device specified: %s. Example device: /dev/vdb" msgstr "" -#: nova/scheduler/simple.py:115 -msgid "All hosts have too many networks" +#: ../nova/compute/api.py:496 +msgid "Volume isn't attached to anything!" msgstr "" -#: nova/tests/test_cloud.py:198 -msgid "Can't test instances without a real virtual env." +#: ../nova/rpc.py:98 +#, python-format +msgid "" +"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in " +"%(fl_intv)d seconds." msgstr "" -#: nova/tests/test_cloud.py:210 +#: ../nova/rpc.py:103 #, python-format -msgid "Need to watch instance %s until it's running..." +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:122 +msgid "Reconnected to queue" +msgstr "Riconnesso alla coda" -#: nova/tests/test_compute.py:104 +#: ../nova/rpc.py:129 +msgid "Failed to fetch message from queue" +msgstr "Impossibile prelevare il messaggio dalla coda" + +#: ../nova/rpc.py:159 #, python-format -msgid "Running instances: %s" -msgstr "" +msgid "Initing the Adapter Consumer for %s" +msgstr "Inizializzando il Consumer Adapter per %s" -#: nova/tests/test_compute.py:110 +#: ../nova/rpc.py:178 #, python-format -msgid "After terminating instances: %s" -msgstr "" +msgid "received %s" +msgstr "ricevuto %s" -#: nova/tests/test_rpc.py:89 +#. 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:191 #, python-format -msgid "Nested received %s, %s" -msgstr "" +msgid "no method for message: %s" +msgstr "nessun metodo per il messaggio: %s" -#: nova/tests/test_rpc.py:94 +#: ../nova/rpc.py:192 #, python-format -msgid "Nested return %s" -msgstr "" +msgid "No method for message: %s" +msgstr "nessun metodo per il messagggio: %s" -#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#: ../nova/rpc.py:253 #, python-format -msgid "Received %s" -msgstr "" +msgid "Returning exception %s to caller" +msgstr "Sollevando eccezione %s al chiamante" -#: nova/tests/test_volume.py:162 +#: ../nova/rpc.py:294 #, python-format -msgid "Target %s allocated" -msgstr "" +msgid "unpacked context: %s" +msgstr "contesto decompresso: %s" -#: nova/virt/connection.py:73 -msgid "Failed to open connection to the hypervisor" -msgstr "" +#: ../nova/rpc.py:313 +msgid "Making asynchronous call..." +msgstr "Facendo chiamata asincrona..." -#: nova/virt/fake.py:210 +#: ../nova/rpc.py:316 #, python-format -msgid "Instance %s Not Found" -msgstr "" +msgid "MSG_ID is %s" +msgstr "MSG_ID é %s" -#: nova/virt/hyperv.py:118 -msgid "In init host" +#: ../nova/rpc.py:354 +msgid "Making asynchronous cast..." msgstr "" -#: nova/virt/hyperv.py:131 +#: ../nova/rpc.py:364 #, python-format -msgid "Attempt to create duplicate vm %s" -msgstr "" +msgid "response %s" +msgstr "risposta %s" -#: nova/virt/hyperv.py:148 +#: ../nova/rpc.py:373 #, python-format -msgid "Starting VM %s " -msgstr "" +msgid "topic is %s" +msgstr "argomento é %s" -#: nova/virt/hyperv.py:150 +#: ../nova/rpc.py:374 #, python-format -msgid "Started VM %s " -msgstr "" +msgid "message %s" +msgstr "messaggio %s" -#: nova/virt/hyperv.py:152 +#: ../nova/volume/driver.py:78 #, python-format -msgid "spawn vm failed: %s" +msgid "Recovering from a failed execute. Try number %s" msgstr "" -#: nova/virt/hyperv.py:169 +#: ../nova/volume/driver.py:87 #, python-format -msgid "Failed to create VM %s" +msgid "volume group %s doesn't exist" msgstr "" -#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#: ../nova/volume/driver.py:220 #, python-format -msgid "Created VM %s..." +msgid "FAKE AOE: %s" msgstr "" -#: nova/virt/hyperv.py:188 -#, python-format -msgid "Set memory for vm %s..." +#: ../nova/volume/driver.py:233 +msgid "Skipping ensure_export. No iscsi_target " msgstr "" -#: nova/virt/hyperv.py:198 -#, python-format -msgid "Set vcpus for vm %s..." +#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288 +msgid "Skipping remove_export. No iscsi_target " msgstr "" -#: nova/virt/hyperv.py:202 +#: ../nova/volume/driver.py:347 #, python-format -msgid "Creating disk for %s by attaching disk file %s" +msgid "FAKE ISCSI: %s" msgstr "" -#: nova/virt/hyperv.py:227 +#: ../nova/volume/driver.py:359 #, python-format -msgid "Failed to add diskdrive to VM %s" +msgid "rbd has no pool %s" msgstr "" -#: nova/virt/hyperv.py:230 +#: ../nova/volume/driver.py:414 #, python-format -msgid "New disk drive path is %s" +msgid "Sheepdog is not working: %s" msgstr "" -#: nova/virt/hyperv.py:247 -#, python-format -msgid "Failed to add vhd file to VM %s" +#: ../nova/volume/driver.py:416 +msgid "Sheepdog is not working" msgstr "" -#: nova/virt/hyperv.py:249 +#: ../nova/wsgi.py:68 #, python-format -msgid "Created disk for %s" +msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: nova/virt/hyperv.py:253 -#, python-format -msgid "Creating nic for %s " +#: ../nova/wsgi.py:147 +msgid "You must implement __call__" msgstr "" -#: nova/virt/hyperv.py:272 -msgid "Failed creating a port on the external vswitch" +#: ../bin/nova-instancemonitor.py:55 +msgid "Starting instance monitor" msgstr "" -#: nova/virt/hyperv.py:273 -#, python-format -msgid "Failed creating port for %s" +#: ../bin/nova-dhcpbridge.py:58 +msgid "leasing ip" msgstr "" -#: nova/virt/hyperv.py:275 -#, python-format -msgid "Created switch port %s on switch %s" +#: ../bin/nova-dhcpbridge.py:73 +msgid "Adopted old lease or got a change of mac/hostname" msgstr "" -#: nova/virt/hyperv.py:285 -#, python-format -msgid "Failed to add nic to VM %s" +#: ../bin/nova-dhcpbridge.py:80 +msgid "releasing ip" msgstr "" -#: nova/virt/hyperv.py:287 +#: ../bin/nova-dhcpbridge.py:123 #, python-format -msgid "Created nic for %s " +msgid "" +"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s " +"on interface %(interface)s" msgstr "" -#: nova/virt/hyperv.py:320 +#: ../nova/virt/fake.py:239 #, python-format -msgid "WMI job failed: %s" +msgid "Instance %s Not Found" msgstr "" -#: nova/virt/hyperv.py:322 +#: ../nova/network/manager.py:153 #, python-format -msgid "WMI job succeeded: %s, Elapsed=%s " +msgid "Dissassociated %s stale fixed ip(s)" msgstr "" -#: nova/virt/hyperv.py:358 -#, python-format -msgid "Got request to destroy vm %s" +#: ../nova/network/manager.py:157 +msgid "setting network host" msgstr "" -#: nova/virt/hyperv.py:383 +#: ../nova/network/manager.py:212 #, python-format -msgid "Failed to destroy vm %s" +msgid "Leasing IP %s" msgstr "" -#: nova/virt/hyperv.py:389 +#: ../nova/network/manager.py:216 #, python-format -msgid "Del: disk %s vm %s" +msgid "IP %s leased that isn't associated" msgstr "" -#: nova/virt/hyperv.py:405 +#: ../nova/network/manager.py:220 #, python-format -msgid "" -"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " -"cpu_time=%s" +msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#: ../nova/network/manager.py:228 #, python-format -msgid "duplicate name found: %s" +msgid "IP %s leased that was already deallocated" msgstr "" -#: nova/virt/hyperv.py:444 +#: ../nova/network/manager.py:233 #, python-format -msgid "Successfully changed vm state of %s to %s" +msgid "Releasing IP %s" msgstr "" -#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#: ../nova/network/manager.py:237 #, python-format -msgid "Failed to change vm state of %s to %s" +msgid "IP %s released that isn't associated" msgstr "" -#: nova/virt/images.py:70 +#: ../nova/network/manager.py:241 #, python-format -msgid "Finished retreving %s -- placed in %s" +msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/libvirt_conn.py:144 +#: ../nova/network/manager.py:244 #, python-format -msgid "Connecting to libvirt: %s" +msgid "IP %s released that was not leased" msgstr "" -#: nova/virt/libvirt_conn.py:157 -msgid "Connection to libvirt broke" +#: ../nova/network/manager.py:519 +msgid "" +"The sum between the number of networks and the vlan start cannot be greater " +"than 4094" msgstr "" -#: nova/virt/libvirt_conn.py:229 +#: ../nova/virt/xenapi/volume_utils.py:57 #, python-format -msgid "instance %s: deleting instance files %s" +msgid "Introducing %s..." msgstr "" -#: nova/virt/libvirt_conn.py:271 +#: ../nova/virt/xenapi/volume_utils.py:74 #, python-format -msgid "No disk at %s" +msgid "Introduced %(label)s as %(sr_ref)s." msgstr "" -#: nova/virt/libvirt_conn.py:278 -msgid "Instance snapshotting is not supported for libvirtat this time" +#: ../nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" msgstr "" -#: nova/virt/libvirt_conn.py:294 +#: ../nova/virt/xenapi/volume_utils.py:90 #, python-format -msgid "instance %s: rebooted" +msgid "Unable to find SR from VBD %s" msgstr "" -#: nova/virt/libvirt_conn.py:297 +#: ../nova/virt/xenapi/volume_utils.py:96 #, python-format -msgid "_wait_for_reboot failed: %s" +msgid "Forgetting SR %s ... " msgstr "" -#: nova/virt/libvirt_conn.py:340 +#: ../nova/virt/xenapi/volume_utils.py:101 #, python-format -msgid "instance %s: rescued" +msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s" msgstr "" -#: nova/virt/libvirt_conn.py:343 +#: ../nova/virt/xenapi/volume_utils.py:107 #, python-format -msgid "_wait_for_rescue failed: %s" +msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s" msgstr "" -#: nova/virt/libvirt_conn.py:370 +#: ../nova/virt/xenapi/volume_utils.py:111 #, python-format -msgid "instance %s: is running" +msgid "Forgetting SR %s done." msgstr "" -#: nova/virt/libvirt_conn.py:381 +#: ../nova/virt/xenapi/volume_utils.py:113 #, python-format -msgid "instance %s: booted" +msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s" msgstr "" -#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#: ../nova/virt/xenapi/volume_utils.py:123 #, python-format -msgid "instance %s: failed to boot" +msgid "Unable to introduce VDI on SR %s" msgstr "" -#: nova/virt/libvirt_conn.py:395 +#: ../nova/virt/xenapi/volume_utils.py:128 #, python-format -msgid "virsh said: %r" -msgstr "" - -#: nova/virt/libvirt_conn.py:399 -msgid "cool, it's a device" +msgid "Unable to get record of VDI %s on" msgstr "" -#: nova/virt/libvirt_conn.py:407 +#: ../nova/virt/xenapi/volume_utils.py:146 #, python-format -msgid "data: %r, fpath: %r" +msgid "Unable to introduce VDI for SR %s" msgstr "" -#: nova/virt/libvirt_conn.py:415 +#: ../nova/virt/xenapi/volume_utils.py:175 #, python-format -msgid "Contents of file %s: %r" +msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s" msgstr "" -#: nova/virt/libvirt_conn.py:449 +#: ../nova/virt/xenapi/volume_utils.py:197 #, python-format -msgid "instance %s: Creating image" +msgid "Mountpoint cannot be translated: %s" msgstr "" -#: nova/virt/libvirt_conn.py:505 +#: ../nova/objectstore/image.py:262 #, python-format -msgid "instance %s: injecting key into image %s" +msgid "Failed to decrypt private key: %s" msgstr "" -#: nova/virt/libvirt_conn.py:508 +#: ../nova/objectstore/image.py:269 #, python-format -msgid "instance %s: injecting net into image %s" +msgid "Failed to decrypt initialization vector: %s" msgstr "" -#: nova/virt/libvirt_conn.py:516 +#: ../nova/objectstore/image.py:277 #, python-format -msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgid "Failed to decrypt image file %(image_file)s: %(err)s" msgstr "" -#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#: ../nova/objectstore/handler.py:106 #, python-format -msgid "instance %s: starting toXML method" +msgid "Unknown S3 value type %r" msgstr "" -#: nova/virt/libvirt_conn.py:589 -#, python-format -msgid "instance %s: finished toXML method" +#: ../nova/objectstore/handler.py:137 +msgid "Authenticated request" 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" +#: ../nova/objectstore/handler.py:182 +msgid "List of buckets requested" msgstr "" -#: nova/virt/xenapi_conn.py:263 +#: ../nova/objectstore/handler.py:209 #, python-format -msgid "Task [%s] %s status: success %s" +msgid "List keys for bucket %s" msgstr "" -#: nova/virt/xenapi_conn.py:271 +#: ../nova/objectstore/handler.py:217 #, python-format -msgid "Task [%s] %s status: %s %s" +msgid "Unauthorized attempt to access bucket %s" msgstr "" -#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#: ../nova/objectstore/handler.py:235 #, python-format -msgid "Got exception: %s" +msgid "Creating bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:72 +#: ../nova/objectstore/handler.py:245 #, 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" +msgid "Deleting bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:249 +#: ../nova/objectstore/handler.py:249 #, python-format -msgid "xenapi.fake does not have an implementation for %s" +msgid "Unauthorized attempt to delete bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:283 +#: ../nova/objectstore/handler.py:273 #, python-format -msgid "Calling %s %s" +msgid "Getting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/fake.py:288 +#: ../nova/objectstore/handler.py:276 #, python-format -msgid "Calling getter %s" +msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/fake.py:340 +#: ../nova/objectstore/handler.py:296 #, python-format -msgid "" -"xenapi.fake does not have an implementation for %s or it has been called " -"with the wrong number of arguments" +msgid "Putting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/network_utils.py:40 +#: ../nova/objectstore/handler.py:299 #, python-format -msgid "Found non-unique network for bridge %s" +msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/network_utils.py:43 +#: ../nova/objectstore/handler.py:318 #, python-format -msgid "Found no network for bridge %s" +msgid "Deleting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:127 +#: ../nova/objectstore/handler.py:322 #, python-format -msgid "Created VM %s as %s." +msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:147 +#: ../nova/objectstore/handler.py:396 #, python-format -msgid "Creating VBD for VM %s, VDI %s ... " +msgid "Not authorized to upload image: invalid directory %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:149 +#: ../nova/objectstore/handler.py:404 #, python-format -msgid "Created VBD %s for VM %s, VDI %s." +msgid "Not authorized to upload image: unauthorized bucket %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:165 +#: ../nova/objectstore/handler.py:409 #, python-format -msgid "VBD not found in instance %s" +msgid "Starting image upload: %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:175 +#: ../nova/objectstore/handler.py:423 #, python-format -msgid "Unable to unplug VBD %s" +msgid "Not authorized to update attributes of image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:187 +#: ../nova/objectstore/handler.py:431 #, python-format -msgid "Unable to destroy VBD %s" +msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r" msgstr "" -#: nova/virt/xenapi/vm_utils.py:202 +#. other attributes imply update +#: ../nova/objectstore/handler.py:436 #, python-format -msgid "Creating VIF for VM %s, network %s." +msgid "Updating user fields on image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:205 +#: ../nova/objectstore/handler.py:450 #, python-format -msgid "Created VIF %s for VM %s, network %s." +msgid "Unauthorized attempt to delete image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:216 +#: ../nova/objectstore/handler.py:455 #, python-format -msgid "Snapshotting VM %s with label '%s'..." +msgid "Deleted image: %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:229 +#: ../nova/auth/manager.py:259 #, python-format -msgid "Created snapshot %s from VM %s." +msgid "Looking up user: %r" msgstr "" -#: nova/virt/xenapi/vm_utils.py:243 +#: ../nova/auth/manager.py:263 #, python-format -msgid "Asking xapi to upload %s as '%s'" +msgid "Failed authorization for access key %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:261 +#: ../nova/auth/manager.py:264 #, python-format -msgid "Asking xapi to fetch %s as %s" +msgid "No user found for access key %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:279 +#: ../nova/auth/manager.py:270 #, python-format -msgid "Looking up vdi %s for PV kernel" +msgid "Using project name = user name (%s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:290 +#: ../nova/auth/manager.py:277 #, python-format -msgid "PV Kernel in VDI:%d" +msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:318 +#: ../nova/auth/manager.py:279 #, python-format -msgid "VDI %s is still available" +msgid "No project called %s could be found" msgstr "" -#: nova/virt/xenapi/vm_utils.py:331 +#: ../nova/auth/manager.py:287 #, python-format -msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgid "" +"Failed authorization: user %(uname)s not admin and not member of project " +"%(pjname)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:333 +#: ../nova/auth/manager.py:289 #, python-format -msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgid "User %(uid)s is not a member of project %(pjid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:390 +#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309 #, python-format -msgid "VHD %s has parent %s" +msgid "Invalid signature for user %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:407 -#, python-format -msgid "Re-scanning SR %s" +#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310 +msgid "Signature does not match" msgstr "" -#: nova/virt/xenapi/vm_utils.py:431 -#, python-format -msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +#: ../nova/auth/manager.py:380 +msgid "Must specify project" msgstr "" -#: nova/virt/xenapi/vm_utils.py:448 +#: ../nova/auth/manager.py:414 #, python-format -msgid "No VDIs found for VM %s" +msgid "The %s role can not be found" msgstr "" -#: nova/virt/xenapi/vm_utils.py:452 +#: ../nova/auth/manager.py:416 #, python-format -msgid "Unexpected number of VDIs (%s) found for VM %s" +msgid "The %s role is global only" msgstr "" -#: nova/virt/xenapi/vmops.py:62 +#: ../nova/auth/manager.py:420 #, python-format -msgid "Attempted to create non-unique name %s" +msgid "Adding role %(role)s to user %(uid)s in project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:99 +#: ../nova/auth/manager.py:423 #, python-format -msgid "Starting VM %s..." +msgid "Adding sitewide role %(role)s to user %(uid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:101 +#: ../nova/auth/manager.py:448 #, python-format -msgid "Spawning VM %s created %s." +msgid "Removing role %(role)s from user %(uid)s on project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:112 +#: ../nova/auth/manager.py:451 #, python-format -msgid "Instance %s: booted" +msgid "Removing sitewide role %(role)s from user %(uid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:137 +#: ../nova/auth/manager.py:515 #, python-format -msgid "Instance not present %s" +msgid "Created project %(name)s with manager %(manager_user)s" msgstr "" -#: nova/virt/xenapi/vmops.py:166 +#: ../nova/auth/manager.py:533 #, python-format -msgid "Starting snapshot for VM %s" +msgid "modifying project %s" msgstr "" -#: nova/virt/xenapi/vmops.py:174 +#: ../nova/auth/manager.py:545 #, python-format -msgid "Unable to Snapshot %s: %s" +msgid "Adding user %(uid)s to project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:184 +#: ../nova/auth/manager.py:566 #, python-format -msgid "Finished snapshot and upload for VM %s" +msgid "Remove user %(uid)s from project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:252 +#: ../nova/auth/manager.py:592 #, python-format -msgid "suspend: instance not present %s" +msgid "Deleting project %s" msgstr "" -#: nova/virt/xenapi/vmops.py:262 +#: ../nova/auth/manager.py:650 #, python-format -msgid "resume: instance not present %s" +msgid "Created user %(rvname)s (admin: %(rvadmin)r)" msgstr "" -#: nova/virt/xenapi/vmops.py:271 +#: ../nova/auth/manager.py:659 #, python-format -msgid "Instance not found %s" +msgid "Deleting user %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:57 +#: ../nova/auth/manager.py:669 #, python-format -msgid "Introducing %s..." +msgid "Access Key change for user %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:74 +#: ../nova/auth/manager.py:671 #, python-format -msgid "Introduced %s as %s." +msgid "Secret Key change for user %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:78 -msgid "Unable to create Storage Repository" +#: ../nova/auth/manager.py:673 +#, python-format +msgid "Admin status set to %(admin)r for user %(uid)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:90 +#: ../nova/auth/manager.py:722 #, python-format -msgid "Unable to find SR from VBD %s" +msgid "No vpn data for project %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:96 +#: ../nova/service.py:161 #, python-format -msgid "Forgetting SR %s ... " +msgid "Starting %(topic)s node (version %(vcs_string)s)" msgstr "" -#: nova/virt/xenapi/volume_utils.py:101 +#: ../nova/service.py:174 +msgid "Service killed that has no database entry" +msgstr "Servizio terminato che non ha entry nel database" + +#: ../nova/service.py:195 +msgid "The service database object disappeared, Recreating it." +msgstr "Il servizio é scomparso dal database, ricreo." + +#: ../nova/service.py:207 +msgid "Recovered model server connection!" +msgstr "Connessione al model server ripristinata!" + +#: ../nova/service.py:213 +msgid "model server went away" +msgstr "model server é scomparso" + +#: ../nova/auth/ldapdriver.py:174 #, python-format -msgid "Ignoring exception %s when getting PBDs for %s" +msgid "LDAP user %s already exists" msgstr "" -#: nova/virt/xenapi/volume_utils.py:107 +#: ../nova/auth/ldapdriver.py:205 #, python-format -msgid "Ignoring exception %s when unplugging PBD %s" +msgid "LDAP object for %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:111 +#: ../nova/auth/ldapdriver.py:348 #, python-format -msgid "Forgetting SR %s done." +msgid "User %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:113 +#: ../nova/auth/ldapdriver.py:472 #, python-format -msgid "Ignoring exception %s when forgetting SR %s" +msgid "Group can't be created because group %s already exists" msgstr "" -#: nova/virt/xenapi/volume_utils.py:123 +#: ../nova/auth/ldapdriver.py:478 #, python-format -msgid "Unable to introduce VDI on SR %s" +msgid "Group can't be created because user %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:128 +#: ../nova/auth/ldapdriver.py:495 #, python-format -msgid "Unable to get record of VDI %s on" +msgid "User %s can't be searched in group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:146 +#: ../nova/auth/ldapdriver.py:507 #, python-format -msgid "Unable to introduce VDI for SR %s" +msgid "User %s can't be added to the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:175 +#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521 #, python-format -msgid "Unable to obtain target information %s, %s" +msgid "The group at dn %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:197 +#: ../nova/auth/ldapdriver.py:513 #, python-format -msgid "Mountpoint cannot be translated: %s" +msgid "User %(uid)s is already a member of the group %(group_dn)s" msgstr "" -#: nova/virt/xenapi/volumeops.py:51 +#: ../nova/auth/ldapdriver.py:524 #, python-format -msgid "Attach_volume: %s, %s, %s" +msgid "" +"User %s can't be removed from the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:69 +#: ../nova/auth/ldapdriver.py:528 #, python-format -msgid "Unable to create VDI on SR %s for instance %s" +msgid "User %s is not a member of the group" msgstr "" -#: nova/virt/xenapi/volumeops.py:81 +#: ../nova/auth/ldapdriver.py:542 #, python-format -msgid "Unable to use SR %s for instance %s" +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." msgstr "" -#: nova/virt/xenapi/volumeops.py:93 +#: ../nova/auth/ldapdriver.py:549 #, python-format -msgid "Unable to attach volume to instance %s" +msgid "User %s can't be removed from all because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:95 +#: ../nova/auth/ldapdriver.py:564 #, python-format -msgid "Mountpoint %s attached to instance %s" +msgid "Group at dn %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:106 +#: ../nova/virt/xenapi/network_utils.py:40 #, python-format -msgid "Detach_volume: %s, %s" +msgid "Found non-unique network for bridge %s" msgstr "" -#: nova/virt/xenapi/volumeops.py:113 +#: ../nova/virt/xenapi/network_utils.py:43 #, python-format -msgid "Unable to locate volume %s" +msgid "Found no network for bridge %s" msgstr "" -#: nova/virt/xenapi/volumeops.py:121 +#: ../nova/api/ec2/admin.py:97 #, python-format -msgid "Unable to detach volume %s" +msgid "Creating new user: %s" msgstr "" -#: nova/virt/xenapi/volumeops.py:128 +#: ../nova/api/ec2/admin.py:105 #, python-format -msgid "Mountpoint %s detached from instance %s" +msgid "Deleting user: %s" msgstr "" -#: nova/volume/api.py:44 +#: ../nova/api/ec2/admin.py:127 #, python-format -msgid "Quota exceeeded for %s, tried to create %sG volume" +msgid "Adding role %(role)s to user %(user)s for project %(project)s" msgstr "" -#: nova/volume/api.py:46 +#: ../nova/api/ec2/admin.py:131 #, python-format -msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgid "Adding sitewide role %(role)s to user %(user)s" msgstr "" -#: nova/volume/api.py:70 nova/volume/api.py:95 -msgid "Volume status must be available" +#: ../nova/api/ec2/admin.py:137 +#, python-format +msgid "Removing role %(role)s from user %(user)s for project %(project)s" msgstr "" -#: nova/volume/api.py:97 -msgid "Volume is already attached" +#: ../nova/api/ec2/admin.py:141 +#, python-format +msgid "Removing sitewide role %(role)s from user %(user)s" msgstr "" -#: nova/volume/api.py:103 -msgid "Volume is already detached" +#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223 +msgid "operation must be add or remove" msgstr "" -#: nova/volume/driver.py:76 +#: ../nova/api/ec2/admin.py:159 #, python-format -msgid "Recovering from a failed execute. Try number %s" +msgid "Getting x509 for user: %(name)s on project: %(project)s" msgstr "" -#: nova/volume/driver.py:85 +#: ../nova/api/ec2/admin.py:177 #, python-format -msgid "volume group %s doesn't exist" +msgid "Create project %(name)s managed by %(manager_user)s" msgstr "" -#: nova/volume/driver.py:210 +#: ../nova/api/ec2/admin.py:190 #, python-format -msgid "FAKE AOE: %s" +msgid "Modify project: %(name)s managed by %(manager_user)s" msgstr "" -#: nova/volume/driver.py:315 +#: ../nova/api/ec2/admin.py:200 #, python-format -msgid "FAKE ISCSI: %s" +msgid "Delete project: %s" msgstr "" -#: nova/volume/manager.py:85 +#: ../nova/api/ec2/admin.py:214 #, python-format -msgid "Re-exporting %s volumes" +msgid "Adding user %(user)s to project %(project)s" msgstr "" -#: nova/volume/manager.py:93 +#: ../nova/api/ec2/admin.py:218 #, python-format -msgid "volume %s: creating" +msgid "Removing user %(user)s from project %(project)s" msgstr "" -#: nova/volume/manager.py:102 #, python-format -msgid "volume %s: creating lv of size %sG" -msgstr "" +#~ 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/volume/manager.py:106 #, python-format -msgid "volume %s: creating export" -msgstr "" +#~ msgid "(%s) publish (key: %s) %s" +#~ msgstr "(%s) pubblica (chiave: %s) %s" -#: 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 "" +#~ 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/volume/manager.py:124 #, python-format -msgid "volume %s: removing export" -msgstr "" +#~ msgid "Binding %s to %s with key %s" +#~ msgstr "Collegando %s a %s con la chiave %s" -#: nova/volume/manager.py:126 #, python-format -msgid "volume %s: deleting" -msgstr "" +#~ msgid "Starting %s node" +#~ msgstr "Avviando il nodo %s" -#: nova/volume/manager.py:129 #, python-format -msgid "volume %s: deleted successfully" -msgstr "" +#~ msgid "Data store %s is unreachable. Trying again in %d seconds." +#~ msgstr "Datastore %s é irrangiungibile. Riprovare in %d seconds." diff --git a/po/ja.po b/po/ja.po index 2cea24640..87065d778 100644 --- a/po/ja.po +++ b/po/ja.po @@ -7,2137 +7,3335 @@ 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" +"POT-Creation-Date: 2011-02-21 10:03-0500\n" +"PO-Revision-Date: 2011-03-29 07:27+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-02-05 05:36+0000\n" -"X-Generator: Launchpad (build 12177)\n" +"X-Launchpad-Export-Date: 2011-03-30 05:22+0000\n" +"X-Generator: Launchpad (build 12559)\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/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 "適切なホストが見つかりません。" -#: nova/exception.py:33 +#: ../nova/exception.py:33 msgid "Unexpected error while running command." msgstr "コマンド実行において予期しないエラーが発生しました。" -#: nova/exception.py:36 +#: ../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 +"%(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/fakerabbit.py:48 +#: ../nova/volume/api.py:45 #, python-format -msgid "(%s) publish (key: %s) %s" -msgstr "(%s) パブリッシュ (key: %s) %s" +msgid "Quota exceeeded for %(pid)s, tried to create %(size)sG volume" +msgstr "サイズ %(size)sG のボリュームの作成を行おうとしましたが、%(pid)sのクオータを超えています。" -#: nova/fakerabbit.py:53 +#: ../nova/volume/api.py:47 #, python-format -msgid "Publishing to route %s" -msgstr "ルート %s へパブリッシュ" +msgid "Volume quota exceeded. You cannot create a volume of size %sG" +msgstr "ボリュームのクオータを超えています。%sの大きさのボリュームは作成できません。" -#: nova/fakerabbit.py:83 -#, python-format -msgid "Declaring queue %s" -msgstr "queue %s の宣言" +#: ../nova/volume/api.py:71 ../nova/volume/api.py:96 +msgid "Volume status must be available" +msgstr "ボリュームのステータス(status)が available でなければなりません。" -#: nova/fakerabbit.py:89 -#, python-format -msgid "Declaring exchange %s" -msgstr "exchange %s の宣言" +#: ../nova/volume/api.py:98 +msgid "Volume is already attached" +msgstr "ボリュームは既にアタッチされています(attached)。" -#: nova/fakerabbit.py:95 -#, python-format -msgid "Binding %s to %s with key %s" -msgstr "%s を %s にキー %s でバインドします。" +#: ../nova/volume/api.py:104 +msgid "Volume is already detached" +msgstr "ボリュームは既にデタッチされています(detached)。" -#: nova/fakerabbit.py:120 -#, python-format -msgid "Getting from %s: %s" -msgstr "%s から %s を取得" +#: ../nova/api/openstack/servers.py:72 +msgid "Failed to read private ip" +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/api/openstack/servers.py:79 +msgid "Failed to read public ip(s)" +msgstr "" -#: nova/rpc.py:99 +#: ../nova/api/openstack/servers.py:152 #, 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 "キューに再接続しました。" +msgid "%(param)s property not found for image %(_image_id)s" +msgstr "イメージ %(_image_id)s に対するプロパティ %(param)s が見つかりません" -#: 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/api/openstack/servers.py:168 +msgid "No keypairs defined" +msgstr "キーペアが定義されていません。" -#: nova/rpc.py:170 +#: ../nova/api/openstack/servers.py:238 #, python-format -msgid "received %s" -msgstr "受信: %s" +msgid "Compute.api::lock %s" +msgstr "例外: Compute.api::lock %s" -#: nova/rpc.py:183 +#: ../nova/api/openstack/servers.py:253 #, python-format -msgid "no method for message: %s" -msgstr "メッセージ %s に対するメソッドが存在しません。" +msgid "Compute.api::unlock %s" +msgstr "例外: Compute.api::unlock %s" -#: nova/rpc.py:184 +#: ../nova/api/openstack/servers.py:267 #, python-format -msgid "No method for message: %s" -msgstr "メッセージ %s に対するメソッドが存在しません。" +msgid "Compute.api::get_lock %s" +msgstr "例外: Compute.api::get_lock %s" -#: nova/rpc.py:245 +#: ../nova/api/openstack/servers.py:281 #, python-format -msgid "Returning exception %s to caller" -msgstr "呼び出し元に 例外 %s を返却します。" +msgid "Compute.api::reset_network %s" +msgstr "" -#: nova/rpc.py:286 +#: ../nova/api/openstack/servers.py:292 #, python-format -msgid "unpacked context: %s" -msgstr "context %s をアンパックしました。" - -#: nova/rpc.py:305 -msgid "Making asynchronous call..." -msgstr "非同期呼び出しを実行します…" +msgid "Compute.api::pause %s" +msgstr "例外: Compute.api::pause %s" -#: nova/rpc.py:308 +#: ../nova/api/openstack/servers.py:303 #, python-format -msgid "MSG_ID is %s" -msgstr "MSG_IDは %s です。" +msgid "Compute.api::unpause %s" +msgstr "例外: Compute.api::unpause %s" -#: nova/rpc.py:356 +#: ../nova/api/openstack/servers.py:314 #, python-format -msgid "response %s" -msgstr "応答 %s" +msgid "compute.api::suspend %s" +msgstr "例外: compute.api::suspend %s" -#: nova/rpc.py:365 +#: ../nova/api/openstack/servers.py:325 #, python-format -msgid "topic is %s" -msgstr "topic は %s です。" +msgid "compute.api::resume %s" +msgstr "例外: compute.api::resume %s" -#: nova/rpc.py:366 -#, python-format -msgid "message %s" -msgstr "メッセージ %s" +#: ../nova/twistd.py:157 +msgid "Wrong number of arguments." +msgstr "引数の数が異なります。" -#: nova/service.py:157 +#: ../nova/twistd.py:209 #, 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 "モデルサーバが消滅しました。" +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "pidfile %s が存在しません。デーモンは実行中ですか?\n" -#: 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/twistd.py:221 +msgid "No such process" +msgstr "そのようなプロセスはありません" -#: nova/service.py:232 nova/twistd.py:232 +#: ../nova/twistd.py:230 ../nova/service.py:224 #, python-format msgid "Serving %s" msgstr "%s サービスの開始" -#: nova/service.py:234 nova/twistd.py:264 +#: ../nova/twistd.py:262 ../nova/service.py:225 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 +#: ../nova/twistd.py:266 #, python-format msgid "Starting %s" msgstr "%s を開始します。" -#: nova/utils.py:53 +#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101 +#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741 +#: ../nova/api/ec2/__init__.py:317 #, python-format -msgid "Inner Exception: %s" -msgstr "内側で発生した例外: %s" +msgid "Instance %s not found" +msgstr "インスタンス %s が見つかりません。" -#: nova/utils.py:54 +#. NOTE: No Resource Pool concept so far +#: ../nova/virt/xenapi/volumeops.py:51 #, python-format -msgid "Class %s cannot be found" -msgstr "クラス %s が見つかりません。" +msgid "Attach_volume: %(instance_name)s, %(device_path)s, %(mountpoint)s" +msgstr "" -#: nova/utils.py:113 +#: ../nova/virt/xenapi/volumeops.py:69 #, python-format -msgid "Fetching %s" -msgstr "ファイルをフェッチ: %s" +msgid "Unable to create VDI on SR %(sr_ref)s for instance %(instance_name)s" +msgstr "" -#: nova/utils.py:125 +#: ../nova/virt/xenapi/volumeops.py:80 #, python-format -msgid "Running cmd (subprocess): %s" -msgstr "コマンド実行(subprocess): %s" +msgid "Unable to use SR %(sr_ref)s for instance %(instance_name)s" +msgstr "" -#: nova/utils.py:138 +#: ../nova/virt/xenapi/volumeops.py:91 #, python-format -msgid "Result was %s" -msgstr "コマンド実行結果: %s" +msgid "Unable to attach volume to instance %s" +msgstr "インスタンス %s にボリュームをアタッチできません。" -#: nova/utils.py:171 +#: ../nova/virt/xenapi/volumeops.py:93 #, python-format -msgid "debug in callback: %s" -msgstr "コールバック中のデバッグ: %s" +msgid "Mountpoint %(mountpoint)s attached to instance %(instance_name)s" +msgstr "インスタンス %(instance_name)s にマウントポイント %(mountpoint)s をアタッチしました。" -#: nova/utils.py:176 +#. Detach VBD from VM +#: ../nova/virt/xenapi/volumeops.py:104 #, python-format -msgid "Running %s" -msgstr "コマンド実行: %s" +msgid "Detach_volume: %(instance_name)s, %(mountpoint)s" +msgstr "" -#: nova/utils.py:207 +#: ../nova/virt/xenapi/volumeops.py:112 #, python-format -msgid "Couldn't get IP, using 127.0.0.1 %s" -msgstr "IPを取得できません。127.0.0.1 を %s として使います。" +msgid "Unable to locate volume %s" +msgstr "ボリューム %s の存在が確認できません。" -#: nova/utils.py:289 +#: ../nova/virt/xenapi/volumeops.py:120 #, python-format -msgid "Invalid backend: %s" -msgstr "不正なバックエンドです: %s" +msgid "Unable to detach volume %s" +msgstr "ボリューム %s のデタッチができません。" -#: nova/utils.py:300 +#: ../nova/virt/xenapi/volumeops.py:127 #, python-format -msgid "backend %s" -msgstr "バックエンドは %s です。" +msgid "Mountpoint %(mountpoint)s detached from instance %(instance_name)s" +msgstr "インスタンス %(instance_name)s からマウントポイント %(mountpoint)s をデタッチしました。" -#: nova/api/ec2/__init__.py:133 -msgid "Too many failed authentications." -msgstr "認証失敗の回数が多すぎます。" - -#: nova/api/ec2/__init__.py:142 +#: ../nova/compute/instance_types.py:41 #, python-format -msgid "" -"Access key %s has had %d failed authentications and will be locked out for " -"%d minutes." -msgstr "アクセスキー %s は %d 回認証に失敗したため、%d 分間ロックされます。" +msgid "Unknown instance type: %s" +msgstr "%s は未知のインスタンスタイプです。" + +#: ../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/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#: ../nova/crypto.py:61 #, python-format -msgid "Authentication Failure: %s" -msgstr "%s の認証に失敗しました。" +msgid "Subject for certificate for users, %s for project, user, timestamp" +msgstr "ユーザの証明書のサブジェクト、%s はプロジェクト、ユーザ、タイムスタンプ" -#: nova/api/ec2/__init__.py:190 +#: ../nova/crypto.py:66 #, python-format -msgid "Authenticated Request For %s:%s)" -msgstr "リクエストを認証しました: %s:%s" +msgid "Subject for certificate for projects, %s for project, timestamp" +msgstr "プロジェクトの証明書のサブジェクト、%s はプロジェクト、およびタイムスタンプ" -#: nova/api/ec2/__init__.py:227 +#: ../nova/crypto.py:71 #, python-format -msgid "action: %s" -msgstr "アクション(action): %s" +msgid "Subject for certificate for vpns, %s for project, timestamp" +msgstr "vpnの証明書のサブジェクト、%sはプロジェクト、およびタイムスタンプ" -#: nova/api/ec2/__init__.py:229 +#: ../nova/crypto.py:258 #, python-format -msgid "arg: %s\t\tval: %s" -msgstr "引数(arg): %s\t値(val): %s" +msgid "Flags path: %s" +msgstr "Flags のパス: %s" -#: nova/api/ec2/__init__.py:301 +#: ../nova/scheduler/manager.py:69 #, python-format -msgid "Unauthorized request for controller=%s and action=%s" -msgstr "許可されていないリクエスト: controller=%s, action %sです。" +msgid "Casting to %(topic)s %(host)s for %(method)s" +msgstr "" -#: nova/api/ec2/__init__.py:339 +#: ../nova/compute/manager.py:78 #, python-format -msgid "NotFound raised: %s" -msgstr "NotFound 発生: %s" +msgid "check_instance_lock: decorating: |%s|" +msgstr "check_instance_lock: decorating: |%s|" -#: nova/api/ec2/__init__.py:342 +#: ../nova/compute/manager.py:80 #, python-format -msgid "ApiError raised: %s" -msgstr "APIエラー発生: %s" +msgid "" +"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|" +msgstr "" -#: nova/api/ec2/__init__.py:349 +#: ../nova/compute/manager.py:84 #, python-format -msgid "Unexpected error raised: %s" -msgstr "予期しないエラー発生: %s" +msgid "check_instance_lock: locked: |%s|" +msgstr "check_instance_lock: locked: |%s|" -#: nova/api/ec2/__init__.py:354 -msgid "An unknown error has occurred. Please try your request again." -msgstr "未知のエラーが発生しました。再度リクエストを実行してください。" +#: ../nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "check_instance_lock: admin: |%s|" -#: nova/api/ec2/admin.py:84 +#: ../nova/compute/manager.py:91 #, python-format -msgid "Creating new user: %s" -msgstr "Creating new user: 新しいユーザ %s を作成します。" +msgid "check_instance_lock: executing: |%s|" +msgstr "check_instance_lock: executing: |%s|" -#: nova/api/ec2/admin.py:92 +#: ../nova/compute/manager.py:95 #, python-format -msgid "Deleting user: %s" -msgstr "Deleting user: ユーザ %s を削除します。" +msgid "check_instance_lock: not executing |%s|" +msgstr "check_instance_lock: not executing |%s|" + +#: ../nova/compute/manager.py:179 +msgid "Instance has already been created" +msgstr "インスタンスは既に生成されています。" -#: nova/api/ec2/admin.py:114 +#: ../nova/compute/manager.py:180 #, python-format -msgid "Adding role %s to user %s for project %s" -msgstr "Adding role: ロール %s をユーザ %s、プロジェクト %s に追加します。" +msgid "instance %s: starting..." +msgstr "インスタンス %s を開始します。" -#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#. pylint: disable=W0702 +#: ../nova/compute/manager.py:219 #, python-format -msgid "Adding sitewide role %s to user %s" -msgstr "Adding sitewide role: サイトワイドのロール %s をユーザ %s に追加します。" +msgid "instance %s: Failed to spawn" +msgstr "インスタンス %s の起動に失敗しました。" -#: nova/api/ec2/admin.py:122 +#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286 #, python-format -msgid "Removing role %s from user %s for project %s" -msgstr "Removing role: ロール %s をユーザ %s プロジェクト %s から削除します。" +msgid "Terminating instance %s" +msgstr "Terminating instance: インスタンス %s を終了します。" -#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#: ../nova/compute/manager.py:255 #, python-format -msgid "Removing sitewide role %s from user %s" -msgstr "Removing sitewide role: サイトワイドのロール %s をユーザ %s から削除します。" +msgid "Deallocating address %s" +msgstr "アドレス %s の割当を解除(deallocate)します。" -#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 -msgid "operation must be add or remove" -msgstr "operation は add または remove の何れかである必要があります。" +#: ../nova/compute/manager.py:268 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "既に消去済みのインスタンス%sを消去しようとしました。" -#: nova/api/ec2/admin.py:142 +#: ../nova/compute/manager.py:282 #, python-format -msgid "Getting x509 for user: %s on project: %s" -msgstr "Getting X509: x509の取得: ユーザ %s, プロジェクト %s" +msgid "Rebooting instance %s" +msgstr "Rebooting instance: インスタンス %s を再起動します。" -#: nova/api/ec2/admin.py:159 +#: ../nova/compute/manager.py:287 #, python-format -msgid "Create project %s managed by %s" -msgstr "Create project: プロジェクト %s (%s により管理される)を作成します。" +msgid "" +"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" +"実行していないインスタンスを再起動しようとしました: %(instance_id)s (state: %(state)s 期待される状態: " +"%(running)s)" -#: nova/api/ec2/admin.py:170 +#: ../nova/compute/manager.py:311 #, python-format -msgid "Delete project: %s" -msgstr "Delete project: プロジェクト %s を削除しました。" +msgid "instance %s: snapshotting" +msgstr "snapshotting: インスタンス %s のスナップショットを取得します。" -#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#: ../nova/compute/manager.py:316 #, python-format -msgid "Adding user %s to project %s" -msgstr "Adding user: ユーザ %s をプロジェクト %s に追加します。" +msgid "" +"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" +"実行していないインスタンスのスナップショットを取得しようとしました: %(instance_id)s (state: %(state)s " +"期待される状態: %(running)s)" -#: nova/api/ec2/admin.py:188 +#: ../nova/compute/manager.py:332 #, python-format -msgid "Removing user %s from project %s" -msgstr "Removing user: ユーザ %s をプロジェクト %s から削除します。" +msgid "" +"trying to reset the password on a non-running instance: %(instance_id)s " +"(state: %(instance_state)s expected: %(expected_state)s)" +msgstr "" +"実行していないインスタンスのパスワードをリセットしようとしました: %(instance_id)s (state: %(instance_state)s " +"期待される状態: %(expected_state)s)" -#: nova/api/ec2/apirequest.py:95 +#: ../nova/compute/manager.py:335 #, python-format -msgid "Unsupported API request: controller = %s,action = %s" -msgstr "サポートされていないAPIリクエストです。 controller = %s,action = %s" +msgid "instance %s: setting admin password" +msgstr "インスタンス %s: admin password をセットします" -#: nova/api/ec2/cloud.py:117 +#: ../nova/compute/manager.py:353 #, python-format -msgid "Generating root CA: %s" -msgstr "ルートCA %s を生成しています。" +msgid "" +"trying to inject a file into a non-running instance: %(instance_id)s (state: " +"%(instance_state)s expected: %(expected_state)s)" +msgstr "" +"実行していないインスタンスにファイルをインジェクトしようとしました: %(instance_id)s (state: " +"%(instance_state)s 期待される状態: %(expected_state)s)" -#: nova/api/ec2/cloud.py:277 +#: ../nova/compute/manager.py:362 #, python-format -msgid "Create key pair %s" -msgstr "Create key pair: キーペア %s を作成します。" +msgid "instance %(nm)s: injecting file to %(plain_path)s" +msgstr "インスタンス %(nm)s: ファイルを %(plain_path)s にインジェクトします" -#: nova/api/ec2/cloud.py:285 +#: ../nova/compute/manager.py:372 #, python-format -msgid "Delete key pair %s" -msgstr "Delete key pair: キーペア %s を削除します。" +msgid "instance %s: rescuing" +msgstr "Rescuing: インスタンス %s をレスキューします。" -#: nova/api/ec2/cloud.py:357 +#: ../nova/compute/manager.py:387 +#, python-format +msgid "instance %s: unrescuing" +msgstr "Unrescuing: インスタンス %s をアンレスキューします。" + +#: ../nova/compute/manager.py:406 +#, python-format +msgid "instance %s: pausing" +msgstr "pausing: インスタンス %s を一時停止します。" + +#: ../nova/compute/manager.py:423 +#, python-format +msgid "instance %s: unpausing" +msgstr "unpausing: インスタンス %s の一時停止を解除します。" + +#: ../nova/compute/manager.py:440 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "retrieving diagnostics: インスタンス %s の診断情報を取得します。" + +#: ../nova/compute/manager.py:453 +#, python-format +msgid "instance %s: suspending" +msgstr "suspending: インスタンス %s をサスペンドします。" + +#: ../nova/compute/manager.py:472 +#, python-format +msgid "instance %s: resuming" +msgstr "resuming: インスタンス %s をレジュームします。" + +#: ../nova/compute/manager.py:491 +#, python-format +msgid "instance %s: locking" +msgstr "locking: インスタンス %s をロックします。" + +#: ../nova/compute/manager.py:503 +#, python-format +msgid "instance %s: unlocking" +msgstr "unlocking: インスタンス %s のロックを解除します。" + +#: ../nova/compute/manager.py:513 +#, python-format +msgid "instance %s: getting locked state" +msgstr "getting locked state: インスタンス %s のロックを取得しました。" + +#: ../nova/compute/manager.py:526 +#, python-format +msgid "instance %s: reset network" +msgstr "インスタンス %s: ネットワークをリセットします" + +#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515 +#, python-format +msgid "Get console output for instance %s" +msgstr "Get console output: インスタンス %s のコンソール出力を取得します。" + +#: ../nova/compute/manager.py:543 +#, python-format +msgid "instance %s: getting ajax console" +msgstr "インスタンス %s: ajax consoleを接続します" + +#: ../nova/compute/manager.py:553 +#, python-format +msgid "" +"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s" +msgstr "" +"インスタンス %(instance_id)s: ボリューム %(volume_id)s を %(mountpoint)s にアタッチします" + +#. pylint: disable=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:569 +#, python-format +msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing" +msgstr "インスタンス %(instance_id)s: %(mountpoint)s へのアタッチに失敗しました。削除します。" + +#: ../nova/compute/manager.py:585 +#, python-format +msgid "" +"Detach volume %(volume_id)s from mountpoint %(mp)s on instance " +"%(instance_id)s" +msgstr "" +"インスタンス%(instance_id)s のマウントポイント %(mp)s からボリューム %(volume_id)s をデタッチします。" + +#: ../nova/compute/manager.py:588 +#, python-format +msgid "Detaching volume from unknown instance %s" +msgstr "ボリュームを未知のインスタンス %s からデタッチします。" + +#: ../nova/scheduler/simple.py:53 +#, python-format +msgid "Host %s is not alive" +msgstr "ホスト %s は稼働していません。" + +#: ../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 "ホスト %s は利用可能ではありません。" + +#: ../nova/scheduler/simple.py:99 +msgid "All hosts have too many gigabytes" +msgstr "全てのホストが利用可能な容量(gigabytes)に達しています。" + +#: ../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 "%s 個のボリュームを再エクスポートします。" + +#: ../nova/volume/manager.py:90 +#, python-format +msgid "volume %s: skipping export" +msgstr "ボリューム %s のエキスポートをスキップします。" + +#: ../nova/volume/manager.py:96 +#, python-format +msgid "volume %s: creating" +msgstr "ボリューム%sを作成します。" + +#: ../nova/volume/manager.py:108 +#, python-format +msgid "volume %(vol_name)s: creating lv of size %(vol_size)sG" +msgstr "ボリューム %(vol_name)s: サイズ %(vol_size)sG のlvを作成します。" + +#: ../nova/volume/manager.py:112 +#, python-format +msgid "volume %s: creating export" +msgstr "ボリューム %s をエクスポートします。" + +#: ../nova/volume/manager.py:123 +#, python-format +msgid "volume %s: created successfully" +msgstr "ボリューム %s の作成に成功しました。" + +#: ../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 "ボリューム %s のエクスポートを解除します。" + +#: ../nova/volume/manager.py:138 +#, python-format +msgid "volume %s: deleting" +msgstr "ボリューム %s を削除します。" + +#: ../nova/volume/manager.py:147 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "ボリューム %s の削除に成功しました。" + +#: ../nova/virt/xenapi/fake.py:74 +#, python-format +msgid "%(text)s: _db_content => %(content)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:304 ../nova/virt/xenapi/fake.py:404 +#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478 +msgid "Raising NotImplemented" +msgstr "NotImplemented 例外を発生させます。" + +#: ../nova/virt/xenapi/fake.py:306 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "xenapi.fake には %s が実装されていません。" + +#: ../nova/virt/xenapi/fake.py:341 +#, python-format +msgid "Calling %(localname)s %(impl)s" +msgstr "%(localname)s %(impl)s を呼び出します。" + +#: ../nova/virt/xenapi/fake.py:346 +#, python-format +msgid "Calling getter %s" +msgstr "getter %s をコールします。" + +#: ../nova/virt/xenapi/fake.py:406 +#, 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/tests/test_cloud.py:256 +msgid "Can't test instances without a real virtual env." +msgstr "インスタンスのテストには実際の仮想環境が必要です。(fakeでは実行できません。)" + +#: ../nova/tests/test_cloud.py:268 +#, python-format +msgid "Need to watch instance %s until it's running..." +msgstr "インスタンス %s が実行するまで監視します…" + +#: ../nova/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "ハイパーバイザへの接続に失敗しました。" + +#: ../nova/network/linux_net.py:187 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "VLANインタフェース %s を開始します。" + +#: ../nova/network/linux_net.py:208 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "%s 用のブリッジインタフェースを開始します。" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:314 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "dnsmasqに対してhupを送信しましたが %s が発生しました。" + +#: ../nova/network/linux_net.py:316 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "Pid %d は無効です。dnsmasqを再実行します。" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:358 +#, python-format +msgid "killing radvd threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:360 +#, python-format +msgid "Pid %d is stale, relaunching radvd" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:449 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "dnsmasq をkillしましたが、 %s が発生しました。" + +#: ../nova/utils.py:58 +#, python-format +msgid "Inner Exception: %s" +msgstr "内側で発生した例外: %s" + +#: ../nova/utils.py:59 +#, python-format +msgid "Class %s cannot be found" +msgstr "クラス %s が見つかりません。" + +#: ../nova/utils.py:118 +#, python-format +msgid "Fetching %s" +msgstr "ファイルをフェッチ: %s" + +#: ../nova/utils.py:130 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "コマンド実行(subprocess): %s" + +#: ../nova/utils.py:143 ../nova/utils.py:183 +#, python-format +msgid "Result was %s" +msgstr "コマンド実行結果: %s" + +#: ../nova/utils.py:159 +#, python-format +msgid "Running cmd (SSH): %s" +msgstr "コマンド(SSH)を実行: %s" + +#: ../nova/utils.py:217 +#, python-format +msgid "debug in callback: %s" +msgstr "コールバック中のデバッグ: %s" + +#: ../nova/utils.py:222 +#, python-format +msgid "Running %s" +msgstr "コマンド実行: %s" + +#: ../nova/utils.py:262 +#, python-format +msgid "Link Local address is not found.:%s" +msgstr "リンクローカルアドレスが見つかりません: %s" + +#: ../nova/utils.py:265 +#, python-format +msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s" +msgstr "" + +#: ../nova/utils.py:363 +#, python-format +msgid "Invalid backend: %s" +msgstr "不正なバックエンドです: %s" + +#: ../nova/utils.py:374 +#, python-format +msgid "backend %s" +msgstr "バックエンドは %s です。" + +#: ../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 "ルート %s へパブリッシュ" + +#: ../nova/fakerabbit.py:84 +#, python-format +msgid "Declaring queue %s" +msgstr "queue %s の宣言" + +#: ../nova/fakerabbit.py:90 +#, python-format +msgid "Declaring exchange %s" +msgstr "exchange %s の宣言" + +#: ../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 "VM %s を作成します。" + +#: ../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:168 +#, python-format +msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:171 +#, python-format +msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "VBD not found in instance %s" +msgstr "インスタンス %s のVBDが見つかりません。" + +#: ../nova/virt/xenapi/vm_utils.py:197 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "VBD %s の unplug に失敗しました。" + +#: ../nova/virt/xenapi/vm_utils.py:209 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "VBD %s の削除に失敗しました。" + +#: ../nova/virt/xenapi/vm_utils.py:224 +#, python-format +msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:227 +#, python-format +msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:246 +#, 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:258 +#, python-format +msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:272 +#, python-format +msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:286 +#, python-format +msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:327 +#, python-format +msgid "Size for image %(image)s:%(virtual_size)d" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:332 +#, 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:342 +#, python-format +msgid "Copying VDI %s to /boot/guest on dom0" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:352 +#, python-format +msgid "Kernel/Ramdisk VDI %s destroyed" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:361 +#, python-format +msgid "Asking xapi to fetch %(url)s as %(access)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "PV kernelのvdi %s を取得します。" + +#: ../nova/virt/xenapi/vm_utils.py:397 +#, python-format +msgid "PV Kernel in VDI:%s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:405 +#, python-format +msgid "Running pygrub against %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:411 +#, python-format +msgid "Found Xen kernel %s" +msgstr "Xen Kernel %s が見つかりました。" + +#: ../nova/virt/xenapi/vm_utils.py:413 +msgid "No Xen kernel found. Booting HVM." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431 +#, python-format +msgid "duplicate name found: %s" +msgstr "%s は重複しています。" + +#: ../nova/virt/xenapi/vm_utils.py:442 +#, python-format +msgid "VDI %s is still available" +msgstr "VDI %s は依然として存在しています。" + +#: ../nova/virt/xenapi/vm_utils.py:463 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "(VM_UTILS) xenserver の vm state -> |%s|" + +#: ../nova/virt/xenapi/vm_utils.py:465 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "(VM_UTILS) xenapi の power_state -> |%s|" + +#: ../nova/virt/xenapi/vm_utils.py:525 +#, python-format +msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:542 +#, python-format +msgid "Re-scanning SR %s" +msgstr "SR %s を再スキャンします。" + +#: ../nova/virt/xenapi/vm_utils.py:567 +#, python-format +msgid "" +"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:574 +#, 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:590 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "VM %s にVDIが存在しません。" + +#: ../nova/virt/xenapi/vm_utils.py:594 +#, python-format +msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:653 +#: ../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:655 +#: ../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:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192 +#, python-format +msgid "Plugging VBD %s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:659 +#: ../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:661 +#, python-format +msgid "VBD %(vbd)s plugged as %(orig_dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:664 +#, python-format +msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:668 +#: ../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:671 +#: ../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:683 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211 +msgid "VBD.unplug successful first time." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:688 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216 +msgid "VBD.unplug rejected: retrying..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:692 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220 +msgid "VBD.unplug successful eventually." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:695 +#: ../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:704 +#: ../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:735 +#, python-format +msgid "" +"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:747 +#, 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 "ネストした戻り値: %s" + +#: ../nova/tests/test_rpc.py:120 ../nova/tests/test_rpc.py:126 +#, python-format +msgid "Received %s" +msgstr "%s を受信。" + +#: ../nova/db/sqlalchemy/api.py:44 +msgid "Use of empty request context is deprecated" +msgstr "Request context を空とすることは非推奨です。" + +#: ../nova/db/sqlalchemy/api.py:133 +#, python-format +msgid "No service for id %s" +msgstr "id %s のserviceが存在しません。" + +#: ../nova/db/sqlalchemy/api.py:251 +#, python-format +msgid "No service for %(host)s, %(binary)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:592 +msgid "No fixed ips defined" +msgstr "fixed ipが一つも定義されていません。" + +#: ../nova/db/sqlalchemy/api.py:608 +#, python-format +msgid "No floating ip for address %s" +msgstr "アドレス %s の floating ip が存在しません。" + +#: ../nova/db/sqlalchemy/api.py:629 +#, python-format +msgid "No address for instance %s" +msgstr "インスタンス %s に対するアドレスが見つかりません。" + +#: ../nova/db/sqlalchemy/api.py:961 +#, python-format +msgid "no keypair for user %(user_id)s, name %(name)s" +msgstr "ユーザ %(user_id)s 名前 %(name)s のキーペアがありません。" + +#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156 +#, python-format +msgid "No network for id %s" +msgstr "id %s に該当するnetwork が存在しません。" + +#: ../nova/db/sqlalchemy/api.py:1086 +msgid "No networks defined" +msgstr "ネットワークが定義されていません。" + +#: ../nova/db/sqlalchemy/api.py:1115 +#, python-format +msgid "No network for bridge %s" +msgstr "ブリッジ %s に該当する network が存在しません。" + +#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142 +#, python-format +msgid "No network for instance %s" +msgstr "instance %s に該当する network が存在しません。" + +#: ../nova/db/sqlalchemy/api.py:1277 +#, python-format +msgid "Token %s does not exist" +msgstr "トークン %s が存在しません。" + +#: ../nova/db/sqlalchemy/api.py:1302 +#, python-format +msgid "No quota for project_id %s" +msgstr "project_id %s に対するクオータが存在しません。" + +#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501 +#: ../nova/api/ec2/__init__.py:323 +#, python-format +msgid "Volume %s not found" +msgstr "ボリューム %s が見つかりません。" + +#: ../nova/db/sqlalchemy/api.py:1514 +#, python-format +msgid "No export device found for volume %s" +msgstr "ボリューム %s に関してエクスポートされているデバイスがありません。" + +#: ../nova/db/sqlalchemy/api.py:1527 +#, python-format +msgid "No target id found for volume %s" +msgstr "ボリューム %s に対する target idが存在しません。" + +#: ../nova/db/sqlalchemy/api.py:1572 +#, python-format +msgid "No security group with id %s" +msgstr "id %s のセキュリティグループが存在しません。" + +#: ../nova/db/sqlalchemy/api.py:1589 +#, python-format +msgid "No security group named %(group_name)s for project: %(project_id)s" +msgstr "プロジェクト %(project_id)s に対する名称 %(group_name)s のセキュリティグループが存在しません。" + +#: ../nova/db/sqlalchemy/api.py:1682 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "id %s のセキュリティグループルールが存在しません。" + +#: ../nova/db/sqlalchemy/api.py:1756 +#, python-format +msgid "No user for id %s" +msgstr "id %s のユーザが存在しません。" + +#: ../nova/db/sqlalchemy/api.py:1772 +#, python-format +msgid "No user for access key %s" +msgstr "アクセスキー %s に該当するユーザが存在しません。" + +#: ../nova/db/sqlalchemy/api.py:1834 +#, python-format +msgid "No project with id %s" +msgstr "id %s のプロジェクトが存在しません。" + +#: ../nova/db/sqlalchemy/api.py:1979 +#, python-format +msgid "No console pool with id %(pool_id)s" +msgstr "Id %(pool_id)s のコンソールプールがありません。" + +#: ../nova/db/sqlalchemy/api.py:1996 +#, 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:2035 +#, python-format +msgid "No console for instance %(instance_id)s in pool %(pool_id)s" +msgstr "プール %(pool_id)s に %(instance_id)s のコンソールがありません。" + +#: ../nova/db/sqlalchemy/api.py:2057 +#, python-format +msgid "on instance %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:2058 +#, python-format +msgid "No console with id %(console_id)s %(idesc)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097 +#, python-format +msgid "No zone with id %(zone_id)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 "libvirt %s へ接続します。" + +#: ../nova/virt/libvirt_conn.py:196 +msgid "Connection to libvirt broke" +msgstr "libvirtへの接続が切れています。" + +#: ../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 "%s にディスクが存在しません。" + +#: ../nova/virt/libvirt_conn.py:320 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "インスタンスのスナップショットは現在libvirtに対してはサポートされていません。" + +#: ../nova/virt/libvirt_conn.py:336 +#, python-format +msgid "instance %s: rebooted" +msgstr "インスタンス%s: 再起動しました。" + +#: ../nova/virt/libvirt_conn.py:339 +#, python-format +msgid "_wait_for_reboot failed: %s" +msgstr "_wait_for_reboot 失敗: %s" + +#: ../nova/virt/libvirt_conn.py:382 +#, python-format +msgid "instance %s: rescued" +msgstr "インスタンス %s: rescued" + +#: ../nova/virt/libvirt_conn.py:385 +#, python-format +msgid "_wait_for_rescue failed: %s" +msgstr "_wait_for_rescue 失敗: %s" + +#: ../nova/virt/libvirt_conn.py:411 +#, python-format +msgid "instance %s: is running" +msgstr "インスタンス %s を起動中です。" + +#: ../nova/virt/libvirt_conn.py:422 +#, python-format +msgid "instance %s: booted" +msgstr "インスタンス %s: 起動しました。" + +#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186 +#, python-format +msgid "instance %s: failed to boot" +msgstr "インスタンス %s の起動に失敗しました。" + +#: ../nova/virt/libvirt_conn.py:436 +#, python-format +msgid "virsh said: %r" +msgstr "virsh の出力: %r" + +#: ../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 "インスタンス %s のイメージを生成します。" + +#: ../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 "インスタンス %s: toXML メソッドを開始。" + +#: ../nova/virt/libvirt_conn.py:732 +#, python-format +msgid "instance %s: finished toXML method" +msgstr "インスタンス %s: toXML メソッドを完了。" + +#: ../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 "ip %s に対するメタデータの取得に失敗しました。" + +#: ../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 "アドレスを割り当てようとしましたが、%s のクオータを超えました。" + +#: ../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 "ターゲット %s をアロケートしました。" + +#: ../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 "予備の(fallback)スケジューラを実装する必要があります。" + +#: ../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 "ルートCA %s を生成しています。" + +#: ../nova/api/ec2/cloud.py:303 +#, python-format +msgid "Create key pair %s" +msgstr "Create key pair: キーペア %s を作成します。" + +#: ../nova/api/ec2/cloud.py:311 +#, python-format +msgid "Delete key pair %s" +msgstr "Delete key pair: キーペア %s を削除します。" + +#: ../nova/api/ec2/cloud.py:386 #, python-format msgid "%s is not a valid ipProtocol" msgstr "%s は適切なipProtocolではありません。" -#: nova/api/ec2/cloud.py:361 +#: ../nova/api/ec2/cloud.py:390 msgid "Invalid port range" msgstr "ポートの範囲が不正です。" -#: nova/api/ec2/cloud.py:392 +#: ../nova/api/ec2/cloud.py:421 +#, python-format +msgid "Revoke security group ingress %s" +msgstr "Revoke security group ingress: セキュリティグループ許可 %s の取消" + +#: ../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:443 +msgid "No rule for the specified parameters." +msgstr "指定されたパラメータに該当するルールがありません。" + +#: ../nova/api/ec2/cloud.py:450 +#, python-format +msgid "Authorize security group ingress %s" +msgstr "Authorize security group ingress: セキュリティグループ許可 %s" + +#: ../nova/api/ec2/cloud.py:464 +#, python-format +msgid "This rule already exists in group %s" +msgstr "指定されたルールは既にグループ %s に存在しています。" + +#: ../nova/api/ec2/cloud.py:492 +#, python-format +msgid "Create Security Group %s" +msgstr "Create Security Group: セキュリティグループ %s を作成します。" + +#: ../nova/api/ec2/cloud.py:495 +#, python-format +msgid "group %s already exists" +msgstr "グループ %s は既に存在しています。" + +#: ../nova/api/ec2/cloud.py:507 +#, python-format +msgid "Delete security group %s" +msgstr "Delete security group: セキュリティグループ %s を削除します。" + +#: ../nova/api/ec2/cloud.py:584 +#, python-format +msgid "Create volume of %s GB" +msgstr "Create volume: %s GBのボリュームを作成します。" + +#: ../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:629 +#, python-format +msgid "Detach volume %s" +msgstr "Detach volume: ボリューム %s をデタッチします" + +#: ../nova/api/ec2/cloud.py:761 +msgid "Allocate address" +msgstr "Allocate address: アドレスを割り当てます。" + +#: ../nova/api/ec2/cloud.py:766 +#, python-format +msgid "Release address %s" +msgstr "Release address: アドレス %s を開放します。" + +#: ../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:780 +#, python-format +msgid "Disassociate address %s" +msgstr "Disassociate address: アドレス %s の関連付けを解除します。" + +#: ../nova/api/ec2/cloud.py:807 +msgid "Going to start terminating instances" +msgstr "インスタンス終了処理を開始します。" + +#: ../nova/api/ec2/cloud.py:815 +#, python-format +msgid "Reboot instance %r" +msgstr "Reboot instance: インスタンス %r を再起動します。" + +#: ../nova/api/ec2/cloud.py:867 +#, python-format +msgid "De-registering image %s" +msgstr "De-registering image: イメージ %s を登録解除します。" + +#: ../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:882 ../nova/api/ec2/cloud.py:900 +#, python-format +msgid "attribute not supported: %s" +msgstr "アトリビュート %s はサポートされていません。" + +#: ../nova/api/ec2/cloud.py:890 +#, python-format +msgid "invalid id: %s" +msgstr "id %s は不正です。" + +#: ../nova/api/ec2/cloud.py:903 +msgid "user or group not specified" +msgstr "ユーザまたはグループが指定されていません。" + +#: ../nova/api/ec2/cloud.py:905 +msgid "only group \"all\" is supported" +msgstr "グループ \"all\" のみサポートされています。" + +#: ../nova/api/ec2/cloud.py:907 +msgid "operation_type must be add or remove" +msgstr "operation_type は add または remove の何れかである必要があります。" + +#: ../nova/api/ec2/cloud.py:908 +#, python-format +msgid "Updating image %s publicity" +msgstr "イメージ %s の公開設定を更新します。" + +#: ../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 "Revoke security group ingress %s" -msgstr "Revoke security group ingress: セキュリティグループ許可 %s の取消" +msgid "Argument %s is required." +msgstr "" -#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 -msgid "No rule for the specified parameters." -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 "" -#: nova/api/ec2/cloud.py:421 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:163 #, python-format -msgid "Authorize security group ingress %s" -msgstr "Authorize security group ingress: セキュリティグループ許可 %s" +msgid "" +"Created VDI %(vdi_ref)s (%(label)s, %(size)s, %(read_only)s) on %(sr_ref)s." +msgstr "" -#: nova/api/ec2/cloud.py:432 +#: ../nova/virt/xenapi/vmops.py:67 #, python-format -msgid "This rule already exists in group %s" -msgstr "指定されたルールは既にグループ %s に存在しています。" +msgid "Attempted to create non-unique name %s" +msgstr "ユニークではないname %s を作成しようとしました。" -#: nova/api/ec2/cloud.py:460 +#: ../nova/virt/xenapi/vmops.py:73 #, python-format -msgid "Create Security Group %s" -msgstr "Create Security Group: セキュリティグループ %s を作成します。" +msgid "instance %(name)s: not enough free memory" +msgstr "" -#: nova/api/ec2/cloud.py:463 +#: ../nova/virt/xenapi/vmops.py:148 #, python-format -msgid "group %s already exists" -msgstr "グループ %s は既に存在しています。" +msgid "Starting VM %s..." +msgstr "VM %s を開始します…" -#: nova/api/ec2/cloud.py:475 +#: ../nova/virt/xenapi/vmops.py:151 #, python-format -msgid "Delete security group %s" -msgstr "Delete security group: セキュリティグループ %s を削除します。" +msgid "Spawning VM %(instance_name)s created %(vm_ref)s." +msgstr "" -#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#: ../nova/virt/xenapi/vmops.py:162 #, python-format -msgid "Get console output for instance %s" -msgstr "Get console output: インスタンス %s のコンソール出力を取得します。" +msgid "Invalid value for onset_files: '%s'" +msgstr "" -#: nova/api/ec2/cloud.py:543 +#: ../nova/virt/xenapi/vmops.py:167 #, python-format -msgid "Create volume of %s GB" -msgstr "Create volume: %s GBのボリュームを作成します。" +msgid "Injecting file path: '%s'" +msgstr "" -#: nova/api/ec2/cloud.py:567 +#: ../nova/virt/xenapi/vmops.py:180 #, python-format -msgid "Attach volume %s to instacne %s at %s" -msgstr "Attach volume: ボリューム%s をインスタンス %s にデバイス %s でアタッチします。" +msgid "Instance %s: booted" +msgstr "インスタンス%s: ブートしました。" -#: nova/api/ec2/cloud.py:579 +#: ../nova/virt/xenapi/vmops.py:232 #, python-format -msgid "Detach volume %s" -msgstr "Detach volume: ボリューム %s をデタッチします" +msgid "Instance not present %s" +msgstr "インスタンス%s が存在しません。" -#: nova/api/ec2/cloud.py:686 -msgid "Allocate address" -msgstr "Allocate address: アドレスを割り当てます。" +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vmops.py:261 +#, python-format +msgid "Starting snapshot for VM %s" +msgstr "VM %s に対するスナップショットを開始します。" -#: nova/api/ec2/cloud.py:691 +#: ../nova/virt/xenapi/vmops.py:269 #, python-format -msgid "Release address %s" -msgstr "Release address: アドレス %s を開放します。" +msgid "Unable to Snapshot %(vm_ref)s: %(exc)s" +msgstr "" -#: nova/api/ec2/cloud.py:696 +#: ../nova/virt/xenapi/vmops.py:280 #, python-format -msgid "Associate address %s to instance %s" -msgstr "Associate address: アドレス %s をインスタンス %s に関連付けます。" +msgid "Finished snapshot and upload for VM %s" +msgstr "VM %s のスナップショットとアップロードが完了しました。" -#: nova/api/ec2/cloud.py:703 +#: ../nova/virt/xenapi/vmops.py:356 #, python-format -msgid "Disassociate address %s" -msgstr "Disassociate address: アドレス %s の関連付けを解除します。" +msgid "VM %(vm)s already halted, skipping shutdown..." +msgstr "" -#: nova/api/ec2/cloud.py:730 -msgid "Going to start terminating instances" -msgstr "インスタンス終了処理を開始します。" +#: ../nova/virt/xenapi/vmops.py:389 +msgid "Removing kernel/ramdisk files" +msgstr "" + +#: ../nova/virt/xenapi/vmops.py:399 +msgid "kernel/ramdisk files removed" +msgstr "" -#: nova/api/ec2/cloud.py:738 +#: ../nova/virt/xenapi/vmops.py:561 #, python-format -msgid "Reboot instance %r" -msgstr "Reboot instance: インスタンス %r を再起動します。" +msgid "" +"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; " +"args=%(strargs)s" +msgstr "" -#: nova/api/ec2/cloud.py:775 +#: ../nova/virt/xenapi/vmops.py:564 #, python-format -msgid "De-registering image %s" -msgstr "De-registering image: イメージ %s を登録解除します。" +msgid "" +"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM " +"id=%(instance_id)s; args=%(strargs)s" +msgstr "" -#: nova/api/ec2/cloud.py:783 +#: ../nova/virt/xenapi/vmops.py:569 #, python-format -msgid "Registered image %s with id %s" -msgstr "Registered image: イメージ %s をid %s で登録します。" +msgid "" +"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; " +"args=%(strargs)s" +msgstr "" -#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#: ../nova/virt/xenapi/vmops.py:760 #, python-format -msgid "attribute not supported: %s" -msgstr "アトリビュート %s はサポートされていません。" +msgid "OpenSSL error: %s" +msgstr "" -#: nova/api/ec2/cloud.py:794 +#: ../nova/tests/test_compute.py:148 #, python-format -msgid "invalid id: %s" -msgstr "id %s は不正です。" +msgid "Running instances: %s" +msgstr "インスタンス %s は実行中です。" -#: nova/api/ec2/cloud.py:807 -msgid "user or group not specified" -msgstr "ユーザまたはグループが指定されていません。" +#: ../nova/tests/test_compute.py:154 +#, python-format +msgid "After terminating instances: %s" +msgstr "インスタンス %s を終了した後です。" -#: nova/api/ec2/cloud.py:809 -msgid "only group \"all\" is supported" -msgstr "グループ \"all\" のみサポートされています。" +#: ../nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" +msgstr "cloudpipeインスタンス起動時に実行するスクリプトのテンプレート" -#: nova/api/ec2/cloud.py:811 -msgid "operation_type must be add or remove" -msgstr "operation_type は add または remove の何れかである必要があります。" +#: ../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/api/ec2/cloud.py:812 +#: ../nova/cloudpipe/pipelib.py:97 #, python-format -msgid "Updating image %s publicity" -msgstr "イメージ %s の公開設定を更新します。" +msgid "Launching VPN for %s" +msgstr "%s 用のVPNを起動します。" + +#: ../nova/db/sqlalchemy/migration.py:35 +msgid "python-migrate is not installed. Exiting." +msgstr "" -#: nova/api/ec2/metadatarequesthandler.py:75 +#: ../nova/image/s3.py:99 #, python-format -msgid "Failed to get metadata for ip: %s" -msgstr "ip %s に対するメタデータの取得に失敗しました。" +msgid "Image %s could not be found" +msgstr "イメージ %s が見つかりませんでした。" + +#: ../nova/api/ec2/__init__.py:121 +msgid "Too many failed authentications." +msgstr "認証失敗の回数が多すぎます。" -#: nova/api/openstack/__init__.py:70 +#: ../nova/api/ec2/__init__.py:131 #, python-format -msgid "Caught error: %s" -msgstr "エラー %s をキャッチしました。" +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/openstack/__init__.py:86 -msgid "Including admin operations in API." -msgstr "管理用オペレーション(admin operation)をAPIに登録します。" +#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140 +#, python-format +msgid "Authentication Failure: %s" +msgstr "%s の認証に失敗しました。" -#: nova/api/openstack/servers.py:184 +#: ../nova/api/ec2/__init__.py:182 #, python-format -msgid "Compute.api::lock %s" -msgstr "例外: Compute.api::lock %s" +msgid "Authenticated Request For %(uname)s:%(pname)s)" +msgstr "" -#: nova/api/openstack/servers.py:199 +#: ../nova/api/ec2/__init__.py:207 #, python-format -msgid "Compute.api::unlock %s" -msgstr "例外: Compute.api::unlock %s" +msgid "action: %s" +msgstr "アクション(action): %s" -#: nova/api/openstack/servers.py:213 +#: ../nova/api/ec2/__init__.py:209 #, python-format -msgid "Compute.api::get_lock %s" -msgstr "例外: Compute.api::get_lock %s" +msgid "arg: %(key)s\t\tval: %(value)s" +msgstr "" -#: nova/api/openstack/servers.py:224 +#: ../nova/api/ec2/__init__.py:281 #, python-format -msgid "Compute.api::pause %s" -msgstr "例外: Compute.api::pause %s" +msgid "" +"Unauthorized request for controller=%(controller)s and action=%(action)s" +msgstr "" -#: nova/api/openstack/servers.py:235 +#: ../nova/api/ec2/__init__.py:314 #, python-format -msgid "Compute.api::unpause %s" -msgstr "例外: Compute.api::unpause %s" +msgid "InstanceNotFound raised: %s" +msgstr "" -#: nova/api/openstack/servers.py:246 +#: ../nova/api/ec2/__init__.py:320 #, python-format -msgid "compute.api::suspend %s" -msgstr "例外: compute.api::suspend %s" +msgid "VolumeNotFound raised: %s" +msgstr "" -#: nova/api/openstack/servers.py:257 +#: ../nova/api/ec2/__init__.py:326 #, python-format -msgid "compute.api::resume %s" -msgstr "例外: compute.api::resume %s" +msgid "NotFound raised: %s" +msgstr "NotFound 発生: %s" + +#: ../nova/api/ec2/__init__.py:329 +#, python-format +msgid "ApiError raised: %s" +msgstr "APIエラー発生: %s" + +#: ../nova/api/ec2/__init__.py:338 +#, python-format +msgid "Unexpected error raised: %s" +msgstr "予期しないエラー発生: %s" + +#: ../nova/api/ec2/__init__.py:343 +msgid "An unknown error has occurred. Please try your request again." +msgstr "未知のエラーが発生しました。再度リクエストを実行してください。" -#: nova/auth/dbdriver.py:84 +#: ../nova/auth/dbdriver.py:84 #, python-format msgid "User %s already exists" msgstr "ユーザー %s は既に存在しています。" -#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232 #, 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 +#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243 +#, python-format +msgid "Project can't be created because user %s doesn't exist" +msgstr "ユーザ %s が存在しないためプロジェクトを作成できません。" + +#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229 #, 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 +#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268 #, python-format msgid "Project can't be modified because manager %s doesn't exist" msgstr "マネージャ %s が存在しないためプロジェクトを更新できません。" -#: nova/auth/dbdriver.py:245 +#: ../nova/auth/dbdriver.py:245 #, python-format msgid "User \"%s\" not found" msgstr "ユーザ \"%s\" が見つかりません。" -#: nova/auth/dbdriver.py:248 +#: ../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/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 "" +"connection_type=xenapi を使用するには、以下の指定が必要です: xenapi_connection_url, " +"xenapi_connection_username (オプション), xenapi_connection_password" -#: nova/auth/ldapdriver.py:181 +#: ../nova/virt/xenapi_conn.py:311 #, python-format -msgid "LDAP object for %s doesn't exist" -msgstr "LDAPオブジェクト %s が存在しません。" +msgid "Task [%(name)s] %(task)s status: success %(result)s" +msgstr "" -#: nova/auth/ldapdriver.py:218 +#: ../nova/virt/xenapi_conn.py:317 #, python-format -msgid "Project can't be created because user %s doesn't exist" -msgstr "ユーザ %s が存在しないためプロジェクトを作成できません。" +msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s" +msgstr "" + +#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344 +#, python-format +msgid "Got exception: %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: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/auth/ldapdriver.py:478 +#: ../nova/compute/monitor.py:429 #, python-format -msgid "User %s is already a member of the group %s" -msgstr "ユーザ %s は既にグループ %s のメンバーです。" +msgid "Found instance: %s" +msgstr "インスタンス %s が見つかりました。" + +#: ../nova/volume/san.py:67 +#, python-format +msgid "Could not find iSCSI export for volume %s" +msgstr "" -#: nova/auth/ldapdriver.py:507 +#: ../nova/api/ec2/apirequest.py:100 #, python-format msgid "" -"Attempted to remove the last member of a group. Deleting the group at %s " -"instead." -msgstr "グループの最後のメンバーを削除しようとしました。代わりにグループ %s を削除してください。" +"Unsupported API request: controller = %(controller)s, action = %(action)s" +msgstr "" + +#: ../nova/api/openstack/__init__.py:55 +#, python-format +msgid "Caught error: %s" +msgstr "エラー %s をキャッチしました。" + +#: ../nova/api/openstack/__init__.py:76 +msgid "Including admin operations in API." +msgstr "管理用オペレーション(admin operation)をAPIに登録します。" + +#: ../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 "" + +#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536 +msgid "network" +msgstr "" + +#: ../bin/nova-manage.py:448 +msgid "IP address" +msgstr "" + +#: ../bin/nova-manage.py:449 +msgid "MAC address" +msgstr "" + +#: ../bin/nova-manage.py:450 +msgid "hostname" +msgstr "" + +#: ../bin/nova-manage.py:451 +msgid "host" +msgstr "" + +#: ../bin/nova-manage.py:537 +msgid "netmask" +msgstr "" + +#: ../bin/nova-manage.py:538 +msgid "start address" +msgstr "" + +#: ../nova/virt/disk.py:69 +#, python-format +msgid "Failed to load partition: %s" +msgstr "パーティション %s のロードに失敗しました。" + +#: ../nova/virt/disk.py:91 +#, python-format +msgid "Failed to mount filesystem: %s" +msgstr "ファイルシステム %s のマウントに失敗しました。" + +#: ../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 "イメージをループバック %s にアタッチできません。" + +#: ../nova/virt/disk.py:151 +msgid "No free nbd devices" +msgstr "" -#: nova/auth/ldapdriver.py:528 +#: ../doc/ext/nova_todo.py:46 #, python-format -msgid "Group at dn %s doesn't exist" -msgstr "dnが %s のグループは存在しません。" +msgid "%(filename)s, line %(line_info)d" +msgstr "" -#: nova/auth/manager.py:259 -#, python-format -msgid "Looking up user: %r" -msgstr "ユーザ %r を検索します。" +#. FIXME(chiradeep): implement this +#: ../nova/virt/hyperv.py:118 +msgid "In init host" +msgstr "In init host" -#: nova/auth/manager.py:263 +#: ../nova/virt/hyperv.py:131 #, python-format -msgid "Failed authorization for access key %s" -msgstr "Failed authorization: アクセスキー %s の認証に失敗しました。" +msgid "Attempt to create duplicate vm %s" +msgstr "VM %s を二重に作成しようとしました。" -#: nova/auth/manager.py:264 +#: ../nova/virt/hyperv.py:148 #, python-format -msgid "No user found for access key %s" -msgstr "アクセスキー %s に対するユーザが見つかりませんでした。" +msgid "Starting VM %s " +msgstr "VM %s を開始します。 " -#: nova/auth/manager.py:270 +#: ../nova/virt/hyperv.py:150 #, python-format -msgid "Using project name = user name (%s)" -msgstr "ユーザ名 (%s) をプロジェクト名として使用します。" +msgid "Started VM %s " +msgstr "VM %s を開始しました。 " -#: nova/auth/manager.py:275 +#: ../nova/virt/hyperv.py:152 #, python-format -msgid "failed authorization: no project named %s (user=%s)" -msgstr "Failed authorization: 認証に失敗しました。プロジェクト名 %s (ユーザ = %s) は存在しません。" +msgid "spawn vm failed: %s" +msgstr "vmの生成(spawn)に失敗しました: %s" -#: nova/auth/manager.py:277 +#: ../nova/virt/hyperv.py:169 #, python-format -msgid "No project called %s could be found" -msgstr "プロジェクト %s は見つかりませんでした。" +msgid "Failed to create VM %s" +msgstr "VM %s の作成に失敗しました。" -#: nova/auth/manager.py:281 +#: ../nova/virt/hyperv.py:188 #, python-format -msgid "Failed authorization: user %s not admin and not member of project %s" -msgstr "" -"Failed authorization: 認証に失敗しました: ユーザ %s は管理者ではなくかつプロジェクト %s のメンバーではありません。" +msgid "Set memory for vm %s..." +msgstr "vm %s のメモリを設定します。" -#: nova/auth/manager.py:283 +#: ../nova/virt/hyperv.py:198 #, python-format -msgid "User %s is not a member of project %s" -msgstr "ユーザ %s はプロジェクト %s のメンバーではありません。" +msgid "Set vcpus for vm %s..." +msgstr "vm %s のvcpus を設定します。" -#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#: ../nova/virt/hyperv.py:202 #, 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 "プロジェクトを指定してください。" +msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s" +msgstr "" -#: nova/auth/manager.py:408 +#: ../nova/virt/hyperv.py:227 #, python-format -msgid "The %s role can not be found" -msgstr "ロール %s が見つかりません。" +msgid "Failed to add diskdrive to VM %s" +msgstr "VM %s へのディスクドライブの追加に失敗しました。" -#: nova/auth/manager.py:410 +#: ../nova/virt/hyperv.py:230 #, python-format -msgid "The %s role is global only" -msgstr "ロール %s はグローバルでのみ使用可能です。" +msgid "New disk drive path is %s" +msgstr "新しいドライブパスは %s です。" -#: nova/auth/manager.py:412 +#: ../nova/virt/hyperv.py:247 #, python-format -msgid "Adding role %s to user %s in project %s" -msgstr "Adding role: ロール %s をユーザ %s (プロジェクト %s の) に追加します。" +msgid "Failed to add vhd file to VM %s" +msgstr "vhdファイルの VM %s への追加に失敗しました。" -#: nova/auth/manager.py:438 +#: ../nova/virt/hyperv.py:249 #, python-format -msgid "Removing role %s from user %s on project %s" -msgstr "Removing role: ロール %s をユーザ %s (プロジェクト %s の)から削除します。" +msgid "Created disk for %s" +msgstr "%s に diskを作成します。" -#: nova/auth/manager.py:505 +#: ../nova/virt/hyperv.py:253 #, python-format -msgid "Created project %s with manager %s" -msgstr "Created project: プロジェクト %s (マネージャ %s)を作成します。" +msgid "Creating nic for %s " +msgstr "%s にNICを作成します。 " -#: nova/auth/manager.py:523 -#, python-format -msgid "modifying project %s" -msgstr "modifying project: プロジェクト %s を更新します。" +#: ../nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" +msgstr "外部vswitchへのポート作成に失敗しました。" -#: nova/auth/manager.py:553 +#: ../nova/virt/hyperv.py:273 #, python-format -msgid "Remove user %s from project %s" -msgstr "Remove user: ユーザ %s をプロジェクト %s から削除します。" +msgid "Failed creating port for %s" +msgstr "ポート %s の作成に失敗しました。" -#: nova/auth/manager.py:581 +#: ../nova/virt/hyperv.py:276 #, python-format -msgid "Deleting project %s" -msgstr "Deleting project: プロジェクト %s を削除します。" +msgid "Created switch port %(vm_name)s on switch %(ext_path)s" +msgstr "" -#: nova/auth/manager.py:637 +#: ../nova/virt/hyperv.py:286 #, python-format -msgid "Created user %s (admin: %r)" -msgstr "Created user: ユーザ %s (admin: %r) を作成しました。" +msgid "Failed to add nic to VM %s" +msgstr "VM %s に対してNICの追加に失敗しました。" -#: nova/auth/manager.py:645 +#: ../nova/virt/hyperv.py:288 #, python-format -msgid "Deleting user %s" -msgstr "Deleting user: ユーザ %s を削除します。" +msgid "Created nic for %s " +msgstr "%s のNICを作成しました。 " -#: nova/auth/manager.py:655 +#: ../nova/virt/hyperv.py:321 #, python-format -msgid "Access Key change for user %s" -msgstr "Access Key change: ユーザ %s のアクセスキーを更新します。" +msgid "WMI job failed: %s" +msgstr "WMIジョブに失敗しました: %s" -#: nova/auth/manager.py:657 +#: ../nova/virt/hyperv.py:325 #, python-format -msgid "Secret Key change for user %s" -msgstr "Secret Key change: ユーザ %s のシークレットキーを更新します。" +msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s " +msgstr "" -#: nova/auth/manager.py:659 +#: ../nova/virt/hyperv.py:361 #, python-format -msgid "Admin status set to %r for user %s" -msgstr "Admin status set: 管理者ステータス %r をユーザ %s に設定します。" +msgid "Got request to destroy vm %s" +msgstr "destroy vm %s リクエストを受信しました。" -#: nova/auth/manager.py:708 +#: ../nova/virt/hyperv.py:386 #, python-format -msgid "No vpn data for project %s" -msgstr "プロジェクト %s に関するvpnデータがありません。" +msgid "Failed to destroy vm %s" +msgstr "vm %s の削除に失敗しました。" -#: nova/cloudpipe/pipelib.py:45 -msgid "Template for script to run on cloudpipe instance boot" -msgstr "cloudpipeインスタンス起動時に実行するスクリプトのテンプレート" +#: ../nova/virt/hyperv.py:393 +#, python-format +msgid "Del: disk %(vhdfile)s vm %(instance_name)s" +msgstr "" -#: nova/cloudpipe/pipelib.py:48 -msgid "Network to push into openvpn config" -msgstr "openvpnの設定に入れるネットワークの値" +#: ../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/cloudpipe/pipelib.py:51 -msgid "Netmask to push into openvpn config" -msgstr "openvpnの設定に入れるネットマスクの値" +#: ../nova/virt/hyperv.py:451 +#, python-format +msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s" +msgstr "" -#: nova/cloudpipe/pipelib.py:97 +#: ../nova/virt/hyperv.py:454 #, python-format -msgid "Launching VPN for %s" -msgstr "%s 用のVPNを起動します。" +msgid "Failed to change vm state of %(vm_name)s to %(req_state)s" +msgstr "" -#: nova/compute/api.py:67 +#: ../nova/compute/api.py:71 #, python-format msgid "Instance %d was not found in get_network_topic" msgstr "get_network_topicにおいてインスタンス %d が見つかりませんでした。" -#: nova/compute/api.py:73 +#: ../nova/compute/api.py:77 #, python-format msgid "Instance %d has no host" msgstr "インスタンス %d にホストが登録されていません。" -#: nova/compute/api.py:92 +#: ../nova/compute/api.py:97 #, python-format -msgid "Quota exceeeded for %s, tried to run %s instances" -msgstr "%s のクオータ上限を超えました。%s インスタンスを実行しようとしました。" +msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances" +msgstr "" -#: nova/compute/api.py:94 +#: ../nova/compute/api.py:99 #, python-format msgid "" "Instance quota exceeded. You can only run %s more instances of this type." msgstr "インスタンスのクオータを超えました。このタイプにおいてはあと %s インスタンスしか実行できません。" -#: nova/compute/api.py:109 +#: ../nova/compute/api.py:112 msgid "Creating a raw instance" msgstr "raw instanceを生成します。" -#: nova/compute/api.py:156 +#: ../nova/compute/api.py:160 #, python-format msgid "Going to run %s instances..." msgstr "%s 個のインスタンスの起動を始めます…" -#: nova/compute/api.py:180 +#: ../nova/compute/api.py:187 #, python-format -msgid "Casting to scheduler for %s/%s's instance %s" -msgstr "スケジューラに対して %s/%s のインスタンス %s を送信します。" +msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s" +msgstr "" -#: nova/compute/api.py:279 +#: ../nova/compute/api.py:292 #, python-format -msgid "Going to try and terminate %s" -msgstr "%s を終了します。" +msgid "Going to try to terminate %s" +msgstr "" -#: nova/compute/api.py:283 +#: ../nova/compute/api.py:296 #, python-format msgid "Instance %d was not found during terminate" msgstr "インスタンス %d が終了処理において見つかりませんでした。" -#: nova/compute/api.py:288 +#: ../nova/compute/api.py:301 #, python-format msgid "Instance %d is already being terminated" msgstr "インスタンス %d は既に終了済みです。" -#: nova/compute/api.py:450 +#: ../nova/compute/api.py:481 #, python-format msgid "Invalid device specified: %s. Example device: /dev/vdb" msgstr "デバイスの指定 %s が不正です: デバイス指定の例: /dev/vdb" -#: nova/compute/api.py:465 +#: ../nova/compute/api.py:496 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 +#: ../nova/rpc.py:98 #, python-format msgid "" -"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" -msgstr "実行していないインスタンスのスナップショット取得を試みます。%s (状態: %s 期待する状態: %s)" +"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in " +"%(fl_intv)d seconds." +msgstr "" -#: nova/compute/manager.py:301 +#: ../nova/rpc.py:103 #, python-format -msgid "instance %s: rescuing" -msgstr "Rescuing: インスタンス %s をレスキューします。" +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "AMQPサーバーに %d 回接続を試みましたが、接続できませんでした。シャットダウンします。" -#: nova/compute/manager.py:316 -#, python-format -msgid "instance %s: unrescuing" -msgstr "Unrescuing: インスタンス %s をアンレスキューします。" +#: ../nova/rpc.py:122 +msgid "Reconnected to queue" +msgstr "キューに再接続しました。" -#: nova/compute/manager.py:335 -#, python-format -msgid "instance %s: pausing" -msgstr "pausing: インスタンス %s を一時停止します。" +#: ../nova/rpc.py:129 +msgid "Failed to fetch message from queue" +msgstr "キューからメッセージの取得に失敗しました。" -#: nova/compute/manager.py:352 +#: ../nova/rpc.py:159 #, python-format -msgid "instance %s: unpausing" -msgstr "unpausing: インスタンス %s の一時停止を解除します。" +msgid "Initing the Adapter Consumer for %s" +msgstr "%sのアダプターコンシューマー(Adapter Consumer)を初期化しています。" -#: nova/compute/manager.py:369 +#: ../nova/rpc.py:178 #, python-format -msgid "instance %s: retrieving diagnostics" -msgstr "retrieving diagnostics: インスタンス %s の診断情報を取得します。" +msgid "received %s" +msgstr "受信: %s" -#: nova/compute/manager.py:382 +#. 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:191 #, python-format -msgid "instance %s: suspending" -msgstr "suspending: インスタンス %s をサスペンドします。" +msgid "no method for message: %s" +msgstr "メッセージ %s に対するメソッドが存在しません。" -#: nova/compute/manager.py:401 +#: ../nova/rpc.py:192 #, python-format -msgid "instance %s: resuming" -msgstr "resuming: インスタンス %s をレジュームします。" +msgid "No method for message: %s" +msgstr "メッセージ %s に対するメソッドが存在しません。" -#: nova/compute/manager.py:420 +#: ../nova/rpc.py:253 #, python-format -msgid "instance %s: locking" -msgstr "locking: インスタンス %s をロックします。" +msgid "Returning exception %s to caller" +msgstr "呼び出し元に 例外 %s を返却します。" -#: nova/compute/manager.py:432 +#: ../nova/rpc.py:294 #, python-format -msgid "instance %s: unlocking" -msgstr "unlocking: インスタンス %s のロックを解除します。" +msgid "unpacked context: %s" +msgstr "context %s をアンパックしました。" -#: nova/compute/manager.py:442 -#, python-format -msgid "instance %s: getting locked state" -msgstr "getting locked state: インスタンス %s のロックを取得しました。" +#: ../nova/rpc.py:313 +msgid "Making asynchronous call..." +msgstr "非同期呼び出しを実行します…" -#: nova/compute/manager.py:462 +#: ../nova/rpc.py:316 #, python-format -msgid "instance %s: attaching volume %s to %s" -msgstr "attaching volume: インスタンス %s についてボリューム %s を %s にアタッチします。" +msgid "MSG_ID is %s" +msgstr "MSG_IDは %s です。" -#: nova/compute/manager.py:478 -#, python-format -msgid "instance %s: attach failed %s, removing" -msgstr "インスタンス %s: %sのアタッチに失敗しました。リムーブします。" +#: ../nova/rpc.py:354 +msgid "Making asynchronous cast..." +msgstr "" -#: nova/compute/manager.py:493 +#: ../nova/rpc.py:364 #, python-format -msgid "Detach volume %s from mountpoint %s on instance %s" -msgstr "Detach volume: ボリューム %s をマウントポイント %s (インスタンス%s)からデタッチします。" +msgid "response %s" +msgstr "応答 %s" -#: nova/compute/manager.py:497 +#: ../nova/rpc.py:373 #, python-format -msgid "Detaching volume from unknown instance %s" -msgstr "ボリュームを未知のインスタンス %s からデタッチします。" +msgid "topic is %s" +msgstr "topic は %s です。" -#: nova/compute/monitor.py:259 +#: ../nova/rpc.py:374 #, python-format -msgid "updating %s..." -msgstr "%s の情報の更新…" - -#: nova/compute/monitor.py:289 -msgid "unexpected error during update" -msgstr "更新の最中に予期しないエラーが発生しました。" +msgid "message %s" +msgstr "メッセージ %s" -#: nova/compute/monitor.py:355 +#: ../nova/volume/driver.py:78 #, python-format -msgid "Cannot get blockstats for \"%s\" on \"%s\"" -msgstr "ブロックデバイス \"%s\" の統計を \"%s\" について取得できません。" +msgid "Recovering from a failed execute. Try number %s" +msgstr "実行失敗からリカバリーします。%s 回目のトライ。" -#: nova/compute/monitor.py:377 +#: ../nova/volume/driver.py:87 #, python-format -msgid "Cannot get ifstats for \"%s\" on \"%s\"" -msgstr "インタフェース \"%s\" の統計を \"%s\" について取得できません。" - -#: nova/compute/monitor.py:412 -msgid "unexpected exception getting connection" -msgstr "接続に際し予期しないエラーが発生しました。" +msgid "volume group %s doesn't exist" +msgstr "ボリュームグループ%sが存在しません。" -#: nova/compute/monitor.py:427 +#: ../nova/volume/driver.py:220 #, python-format -msgid "Found instance: %s" -msgstr "インスタンス %s が見つかりました。" +msgid "FAKE AOE: %s" +msgstr "偽のAOE: %s" -#: nova/db/sqlalchemy/api.py:43 -msgid "Use of empty request context is deprecated" -msgstr "Request context を空とすることは非推奨です。" +#: ../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/db/sqlalchemy/api.py:132 +#: ../nova/volume/driver.py:347 #, python-format -msgid "No service for id %s" -msgstr "id %s のserviceが存在しません。" +msgid "FAKE ISCSI: %s" +msgstr "偽のISCSI: %s" -#: nova/db/sqlalchemy/api.py:229 +#: ../nova/volume/driver.py:359 #, python-format -msgid "No service for %s, %s" -msgstr "%s, %s のserviceが存在しません。" +msgid "rbd has no pool %s" +msgstr "" -#: nova/db/sqlalchemy/api.py:574 +#: ../nova/volume/driver.py:414 #, python-format -msgid "No floating ip for address %s" -msgstr "アドレス %s の floating ip が存在しません。" +msgid "Sheepdog is not working: %s" +msgstr "" -#: nova/db/sqlalchemy/api.py:668 -#, python-format -msgid "No instance for id %s" -msgstr "id %s のinstanceが存在しません。" +#: ../nova/volume/driver.py:416 +msgid "Sheepdog is not working" +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 +#: ../nova/wsgi.py:68 #, python-format -msgid "Instance %s not found" -msgstr "インスタンス %s が見つかりません。" +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" -#: nova/db/sqlalchemy/api.py:891 -#, python-format -msgid "no keypair for user %s, name %s" -msgstr "ユーザ %s, ネーム%s に該当するキーペアが存在しません。" +#: ../nova/wsgi.py:147 +msgid "You must implement __call__" +msgstr "" -#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 -#, python-format -msgid "No network for id %s" -msgstr "id %s に該当するnetwork が存在しません。" +#: ../bin/nova-instancemonitor.py:55 +msgid "Starting instance monitor" +msgstr "" -#: nova/db/sqlalchemy/api.py:1036 -#, python-format -msgid "No network for bridge %s" -msgstr "ブリッジ %s に該当する network が存在しません。" +#: ../bin/nova-dhcpbridge.py:58 +msgid "leasing ip" +msgstr "" -#: nova/db/sqlalchemy/api.py:1050 -#, python-format -msgid "No network for instance %s" -msgstr "instance %s に該当する network が存在しません。" +#: ../bin/nova-dhcpbridge.py:73 +msgid "Adopted old lease or got a change of mac/hostname" +msgstr "" -#: nova/db/sqlalchemy/api.py:1180 -#, python-format -msgid "Token %s does not exist" -msgstr "トークン %s が存在しません。" +#: ../bin/nova-dhcpbridge.py:80 +msgid "releasing ip" +msgstr "" -#: nova/db/sqlalchemy/api.py:1205 +#: ../bin/nova-dhcpbridge.py:123 #, python-format -msgid "No quota for project_id %s" -msgstr "project_id %s に対するクオータが存在しません。" +msgid "" +"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s " +"on interface %(interface)s" +msgstr "" -#: nova/db/sqlalchemy/api.py:1356 +#: ../nova/virt/fake.py:239 #, python-format -msgid "No volume for id %s" -msgstr "id %s に該当するボリュームが存在しません。" +msgid "Instance %s Not Found" +msgstr "インスタンス %s が見つかりません。" -#: nova/db/sqlalchemy/api.py:1401 +#: ../nova/network/manager.py:153 #, python-format -msgid "Volume %s not found" -msgstr "ボリューム %s が見つかりません。" +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "無効になった %s 個の fixed ip を割当解除しました。" -#: nova/db/sqlalchemy/api.py:1413 -#, python-format -msgid "No export device found for volume %s" -msgstr "ボリューム %s に関してエクスポートされているデバイスがありません。" +#: ../nova/network/manager.py:157 +msgid "setting network host" +msgstr "ネットワークホストの設定をします。" -#: nova/db/sqlalchemy/api.py:1426 +#: ../nova/network/manager.py:212 #, python-format -msgid "No target id found for volume %s" -msgstr "ボリューム %s に対する target idが存在しません。" +msgid "Leasing IP %s" +msgstr "IP %s をリースします。" -#: nova/db/sqlalchemy/api.py:1471 +#: ../nova/network/manager.py:216 #, python-format -msgid "No security group with id %s" -msgstr "id %s のセキュリティグループが存在しません。" +msgid "IP %s leased that isn't associated" +msgstr "IP %s がリースされましたが関連付けられていません。" -#: nova/db/sqlalchemy/api.py:1488 +#: ../nova/network/manager.py:220 #, python-format -msgid "No security group named %s for project: %s" -msgstr "セキュリティグループ名 %s がプロジェクト %s に存在しません。" +msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s" +msgstr "" -#: nova/db/sqlalchemy/api.py:1576 +#: ../nova/network/manager.py:228 #, python-format -msgid "No secuity group rule with id %s" -msgstr "id %s のセキュリティグループルールが存在しません。" +msgid "IP %s leased that was already deallocated" +msgstr "既に割当解除しているIP %s がリースされました。" -#: nova/db/sqlalchemy/api.py:1650 +#: ../nova/network/manager.py:233 #, python-format -msgid "No user for id %s" -msgstr "id %s のユーザが存在しません。" +msgid "Releasing IP %s" +msgstr "" -#: nova/db/sqlalchemy/api.py:1666 +#: ../nova/network/manager.py:237 #, python-format -msgid "No user for access key %s" -msgstr "アクセスキー %s に該当するユーザが存在しません。" +msgid "IP %s released that isn't associated" +msgstr "割り当てていないIP %s が開放されました。" -#: nova/db/sqlalchemy/api.py:1728 +#: ../nova/network/manager.py:241 #, python-format -msgid "No project with id %s" -msgstr "id %s のプロジェクトが存在しません。" +msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s" +msgstr "" -#: nova/image/glance.py:78 +#: ../nova/network/manager.py:244 #, python-format -msgid "Parallax returned HTTP error %d from request for /images" -msgstr "Parallax がHTTPエラー%d を /images に対するリクエストに対して返しました。" +msgid "IP %s released that was not leased" +msgstr "リースしていないIP %s が開放されました。" -#: 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/network/manager.py:519 +msgid "" +"The sum between the number of networks and the vlan start cannot be greater " +"than 4094" +msgstr "" -#: nova/image/s3.py:82 +#: ../nova/virt/xenapi/volume_utils.py:57 #, python-format -msgid "Image %s could not be found" -msgstr "イメージ %s が見つかりませんでした。" +msgid "Introducing %s..." +msgstr "%s を introduce します…" -#: nova/network/api.py:39 +#: ../nova/virt/xenapi/volume_utils.py:74 #, python-format -msgid "Quota exceeeded for %s, tried to allocate address" -msgstr "アドレスを割り当てようとしましたが、%s のクオータを超えました。" +msgid "Introduced %(label)s as %(sr_ref)s." +msgstr "" -#: nova/network/api.py:42 -msgid "Address quota exceeded. You cannot allocate any more addresses" -msgstr "アドレスのクオータを超えました。これ以上アドレスを割り当てることはできません。" +#: ../nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" +msgstr "Storage Repository を作成できません。" -#: nova/network/linux_net.py:176 +#: ../nova/virt/xenapi/volume_utils.py:90 #, python-format -msgid "Starting VLAN inteface %s" -msgstr "VLANインタフェース %s を開始します。" +msgid "Unable to find SR from VBD %s" +msgstr "VBD %s から SRを取得できません。" -#: nova/network/linux_net.py:186 +#: ../nova/virt/xenapi/volume_utils.py:96 #, python-format -msgid "Starting Bridge interface for %s" -msgstr "%s 用のブリッジインタフェースを開始します。" +msgid "Forgetting SR %s ... " +msgstr "SR %s をforgetします。 " -#: nova/network/linux_net.py:254 +#: ../nova/virt/xenapi/volume_utils.py:101 #, python-format -msgid "Hupping dnsmasq threw %s" -msgstr "dnsmasqに対してhupを送信しましたが %s が発生しました。" +msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s" +msgstr "" -#: nova/network/linux_net.py:256 +#: ../nova/virt/xenapi/volume_utils.py:107 #, python-format -msgid "Pid %d is stale, relaunching dnsmasq" -msgstr "Pid %d は無効です。dnsmasqを再実行します。" +msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s" +msgstr "" -#: nova/network/linux_net.py:334 +#: ../nova/virt/xenapi/volume_utils.py:111 #, python-format -msgid "Killing dnsmasq threw %s" -msgstr "dnsmasq をkillしましたが、 %s が発生しました。" +msgid "Forgetting SR %s done." +msgstr "SR %s のforgetが完了。" -#: nova/network/manager.py:135 -msgid "setting network host" -msgstr "ネットワークホストの設定をします。" +#: ../nova/virt/xenapi/volume_utils.py:113 +#, python-format +msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s" +msgstr "" -#: nova/network/manager.py:190 +#: ../nova/virt/xenapi/volume_utils.py:123 #, python-format -msgid "Leasing IP %s" -msgstr "IP %s をリースします。" +msgid "Unable to introduce VDI on SR %s" +msgstr "SR %s のVDIのintroduceができません。" -#: nova/network/manager.py:194 +#: ../nova/virt/xenapi/volume_utils.py:128 #, python-format -msgid "IP %s leased that isn't associated" -msgstr "IP %s がリースされましたが関連付けられていません。" +msgid "Unable to get record of VDI %s on" +msgstr "VDI %s のレコードを取得できません。" -#: nova/network/manager.py:197 +#: ../nova/virt/xenapi/volume_utils.py:146 #, python-format -msgid "IP %s leased to bad mac %s vs %s" -msgstr "IP %s が期待した mac %s ではなく %s にリースされました。" +msgid "Unable to introduce VDI for SR %s" +msgstr "SR %s のVDIをintroduceできません。" -#: nova/network/manager.py:205 +#: ../nova/virt/xenapi/volume_utils.py:175 #, python-format -msgid "IP %s leased that was already deallocated" -msgstr "既に割当解除しているIP %s がリースされました。" +msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s" +msgstr "" -#: nova/network/manager.py:214 +#: ../nova/virt/xenapi/volume_utils.py:197 #, python-format -msgid "IP %s released that isn't associated" -msgstr "割り当てていないIP %s が開放されました。" +msgid "Mountpoint cannot be translated: %s" +msgstr "マウントポイントを変換できません。 %s" -#: nova/network/manager.py:217 +#: ../nova/objectstore/image.py:262 #, python-format -msgid "IP %s released from bad mac %s vs %s" -msgstr "IP %s がmac %s ではない mac %s への割当から開放されました。" +msgid "Failed to decrypt private key: %s" +msgstr "" -#: nova/network/manager.py:220 +#: ../nova/objectstore/image.py:269 #, python-format -msgid "IP %s released that was not leased" -msgstr "リースしていないIP %s が開放されました。" +msgid "Failed to decrypt initialization vector: %s" +msgstr "" -#: nova/network/manager.py:442 +#: ../nova/objectstore/image.py:277 #, python-format -msgid "Dissassociated %s stale fixed ip(s)" -msgstr "無効になった %s 個の fixed ip を割当解除しました。" +msgid "Failed to decrypt image file %(image_file)s: %(err)s" +msgstr "" -#: nova/objectstore/handler.py:106 +#: ../nova/objectstore/handler.py:106 #, python-format msgid "Unknown S3 value type %r" msgstr "未知のS3 value type %r です。" -#: nova/objectstore/handler.py:137 +#: ../nova/objectstore/handler.py:137 msgid "Authenticated request" msgstr "認証リクエスト" -#: nova/objectstore/handler.py:182 +#: ../nova/objectstore/handler.py:182 msgid "List of buckets requested" msgstr "List of buckets が呼ばれました。" -#: nova/objectstore/handler.py:209 +#: ../nova/objectstore/handler.py:209 #, python-format msgid "List keys for bucket %s" msgstr "バケット %s のキーの一覧" -#: nova/objectstore/handler.py:217 +#: ../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 +#: ../nova/objectstore/handler.py:235 #, python-format msgid "Creating bucket %s" msgstr "バケットを作成します。 %s" -#: nova/objectstore/handler.py:245 +#: ../nova/objectstore/handler.py:245 #, python-format msgid "Deleting bucket %s" msgstr "バケットを削除します。 %s" -#: nova/objectstore/handler.py:249 +#: ../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 +#: ../nova/objectstore/handler.py:273 +#, python-format +msgid "Getting object: %(bname)s / %(nm)s" +msgstr "" + +#: ../nova/objectstore/handler.py:276 #, python-format -msgid "Getting object: %s / %s" -msgstr "オブジェクトの取得: %s / %s" +msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s" +msgstr "" -#: nova/objectstore/handler.py:274 +#: ../nova/objectstore/handler.py:296 #, python-format -msgid "Unauthorized attempt to get object %s from bucket %s" +msgid "Putting object: %(bname)s / %(nm)s" msgstr "" -"Unauthorized attempt to get object: オブジェクト %s のバケット %s からの取得は許可されていません。" -#: nova/objectstore/handler.py:292 +#: ../nova/objectstore/handler.py:299 #, python-format -msgid "Putting object: %s / %s" -msgstr "オブジェクトの格納:: %s / %s" +msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s" +msgstr "" -#: nova/objectstore/handler.py:295 +#: ../nova/objectstore/handler.py:318 #, python-format -msgid "Unauthorized attempt to upload object %s to bucket %s" +msgid "Deleting object: %(bname)s / %(nm)s" msgstr "" -"Unauthorized attempt to upload: オブジェクト %s のバケット %s へのアップロードは許可されていません。" -#: nova/objectstore/handler.py:314 +#: ../nova/objectstore/handler.py:322 #, python-format -msgid "Deleting object: %s / %s" -msgstr "オブジェクトを削除しています。: %s / %s" +msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s" +msgstr "" -#: nova/objectstore/handler.py:393 +#: ../nova/objectstore/handler.py:396 #, python-format msgid "Not authorized to upload image: invalid directory %s" msgstr "" "Not authorized to upload image: イメージの格納は許可されていません。ディレクトリ %s は正しくありません。" -#: nova/objectstore/handler.py:401 +#: ../nova/objectstore/handler.py:404 #, python-format msgid "Not authorized to upload image: unauthorized bucket %s" msgstr "" "Not authorized to upload image: イメージの格納は許可されていません。バケット %s への格納は許可されていません。" -#: nova/objectstore/handler.py:406 +#: ../nova/objectstore/handler.py:409 #, python-format msgid "Starting image upload: %s" msgstr "イメージのアップロードを開始しました。 %s" -#: nova/objectstore/handler.py:420 +#: ../nova/objectstore/handler.py:423 #, python-format msgid "Not authorized to update attributes of image %s" msgstr "Not authorized to update attributes: イメージ %s のアトリビュートの更新は許可されていません。" -#: nova/objectstore/handler.py:428 +#: ../nova/objectstore/handler.py:431 #, python-format -msgid "Toggling publicity flag of image %s %r" -msgstr "Toggling publicity flag: イメージ %s の公開フラグを %r に更新します。" +msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r" +msgstr "" -#: nova/objectstore/handler.py:433 +#. other attributes imply update +#: ../nova/objectstore/handler.py:436 #, python-format msgid "Updating user fields on image %s" msgstr "Updating user fields: イメージ %s のユーザフィールドを更新します。" -#: nova/objectstore/handler.py:447 +#: ../nova/objectstore/handler.py:450 #, python-format msgid "Unauthorized attempt to delete image %s" msgstr "Unauthorized attempt to delete image: イメージ %s の削除は許可されていません。" -#: nova/objectstore/handler.py:452 +#: ../nova/objectstore/handler.py:455 #, 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/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "ユーザ %r を検索します。" -#: nova/scheduler/driver.py:66 -msgid "Must implement a fallback schedule" -msgstr "予備の(fallback)スケジューラを実装する必要があります。" +#: ../nova/auth/manager.py:263 +#, python-format +msgid "Failed authorization for access key %s" +msgstr "Failed authorization: アクセスキー %s の認証に失敗しました。" -#: nova/scheduler/manager.py:69 +#: ../nova/auth/manager.py:264 #, python-format -msgid "Casting to %s %s for %s" -msgstr "メッセージのcast: %s %s for %s" +msgid "No user found for access key %s" +msgstr "アクセスキー %s に対するユーザが見つかりませんでした。" -#: nova/scheduler/simple.py:63 -msgid "All hosts have too many cores" -msgstr "全てのホストにコア数の空きがありません。" +#: ../nova/auth/manager.py:270 +#, python-format +msgid "Using project name = user name (%s)" +msgstr "ユーザ名 (%s) をプロジェクト名として使用します。" -#: nova/scheduler/simple.py:95 -msgid "All hosts have too many gigabytes" -msgstr "全てのホストが利用可能な容量(gigabytes)に達しています。" +#: ../nova/auth/manager.py:277 +#, python-format +msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)" +msgstr "" -#: nova/scheduler/simple.py:115 -msgid "All hosts have too many networks" -msgstr "全てのホストがネットワークの最大数に達しています。" +#: ../nova/auth/manager.py:279 +#, python-format +msgid "No project called %s could be found" +msgstr "プロジェクト %s は見つかりませんでした。" -#: nova/tests/test_cloud.py:198 -msgid "Can't test instances without a real virtual env." -msgstr "インスタンスのテストには実際の仮想環境が必要です。(fakeでは実行できません。)" +#: ../nova/auth/manager.py:287 +#, python-format +msgid "" +"Failed authorization: user %(uname)s not admin and not member of project " +"%(pjname)s" +msgstr "" -#: nova/tests/test_cloud.py:210 +#: ../nova/auth/manager.py:289 #, python-format -msgid "Need to watch instance %s until it's running..." -msgstr "インスタンス %s が実行するまで監視します…" +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 "Invalid signature: ユーザ %s の署名が不正です。" + +#: ../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 "ロール %s が見つかりません。" + +#: ../nova/auth/manager.py:416 +#, python-format +msgid "The %s role is global only" +msgstr "ロール %s はグローバルでのみ使用可能です。" + +#: ../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 "modifying project: プロジェクト %s を更新します。" + +#: ../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 "Deleting project: プロジェクト %s を削除します。" + +#: ../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 "Deleting user: ユーザ %s を削除します。" + +#: ../nova/auth/manager.py:669 +#, python-format +msgid "Access Key change for user %s" +msgstr "Access Key change: ユーザ %s のアクセスキーを更新します。" + +#: ../nova/auth/manager.py:671 +#, python-format +msgid "Secret Key change for user %s" +msgstr "Secret Key change: ユーザ %s のシークレットキーを更新します。" + +#: ../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 "プロジェクト %s に関するvpnデータがありません。" + +#: ../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/tests/test_compute.py:104 +#: ../nova/auth/ldapdriver.py:174 #, python-format -msgid "Running instances: %s" -msgstr "インスタンス %s は実行中です。" +msgid "LDAP user %s already exists" +msgstr "" -#: nova/tests/test_compute.py:110 +#: ../nova/auth/ldapdriver.py:205 #, python-format -msgid "After terminating instances: %s" -msgstr "インスタンス %s を終了した後です。" +msgid "LDAP object for %s doesn't exist" +msgstr "LDAPオブジェクト %s が存在しません。" -#: nova/tests/test_rpc.py:89 +#: ../nova/auth/ldapdriver.py:348 #, python-format -msgid "Nested received %s, %s" -msgstr "ネスとした受信: %s, %s" +msgid "User %s doesn't exist" +msgstr "" -#: nova/tests/test_rpc.py:94 +#: ../nova/auth/ldapdriver.py:472 #, python-format -msgid "Nested return %s" -msgstr "ネストした戻り値: %s" +msgid "Group can't be created because group %s already exists" +msgstr "" -#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#: ../nova/auth/ldapdriver.py:478 #, python-format -msgid "Received %s" -msgstr "%s を受信。" +msgid "Group can't be created because user %s doesn't exist" +msgstr "" -#: nova/tests/test_volume.py:162 +#: ../nova/auth/ldapdriver.py:495 #, python-format -msgid "Target %s allocated" -msgstr "ターゲット %s をアロケートしました。" - -#: nova/virt/connection.py:73 -msgid "Failed to open connection to the hypervisor" -msgstr "ハイパーバイザへの接続に失敗しました。" +msgid "User %s can't be searched in group because the user doesn't exist" +msgstr "" -#: nova/virt/fake.py:210 +#: ../nova/auth/ldapdriver.py:507 #, python-format -msgid "Instance %s Not Found" -msgstr "インスタンス %s が見つかりません。" +msgid "User %s can't be added to the group because the user doesn't exist" +msgstr "" -#: nova/virt/hyperv.py:118 -msgid "In init host" -msgstr "In init host" +#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521 +#, python-format +msgid "The group at dn %s doesn't exist" +msgstr "" -#: nova/virt/hyperv.py:131 +#: ../nova/auth/ldapdriver.py:513 #, python-format -msgid "Attempt to create duplicate vm %s" -msgstr "VM %s を二重に作成しようとしました。" +msgid "User %(uid)s is already a member of the group %(group_dn)s" +msgstr "" -#: nova/virt/hyperv.py:148 +#: ../nova/auth/ldapdriver.py:524 #, python-format -msgid "Starting VM %s " -msgstr "VM %s を開始します。 " +msgid "" +"User %s can't be removed from the group because the user doesn't exist" +msgstr "" -#: nova/virt/hyperv.py:150 +#: ../nova/auth/ldapdriver.py:528 #, python-format -msgid "Started VM %s " -msgstr "VM %s を開始しました。 " +msgid "User %s is not a member of the group" +msgstr "" -#: nova/virt/hyperv.py:152 +#: ../nova/auth/ldapdriver.py:542 #, python-format -msgid "spawn vm failed: %s" -msgstr "vmの生成(spawn)に失敗しました: %s" +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." +msgstr "グループの最後のメンバーを削除しようとしました。代わりにグループ %s を削除してください。" -#: nova/virt/hyperv.py:169 +#: ../nova/auth/ldapdriver.py:549 #, python-format -msgid "Failed to create VM %s" -msgstr "VM %s の作成に失敗しました。" +msgid "User %s can't be removed from all because the user doesn't exist" +msgstr "" -#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#: ../nova/auth/ldapdriver.py:564 #, python-format -msgid "Created VM %s..." -msgstr "VM %s を作成します。" +msgid "Group at dn %s doesn't exist" +msgstr "dnが %s のグループは存在しません。" -#: nova/virt/hyperv.py:188 +#: ../nova/virt/xenapi/network_utils.py:40 #, python-format -msgid "Set memory for vm %s..." -msgstr "vm %s のメモリを設定します。" +msgid "Found non-unique network for bridge %s" +msgstr "ブリッジ %s に対してブリッジが複数存在します。" -#: nova/virt/hyperv.py:198 +#: ../nova/virt/xenapi/network_utils.py:43 #, python-format -msgid "Set vcpus for vm %s..." -msgstr "vm %s のvcpus を設定します。" +msgid "Found no network for bridge %s" +msgstr "ブリッジ %s に対するネットワークが存在しません。" -#: nova/virt/hyperv.py:202 +#: ../nova/api/ec2/admin.py:97 #, python-format -msgid "Creating disk for %s by attaching disk file %s" -msgstr "%s のディスクをディスクファイル %s をアタッチして作成します。" +msgid "Creating new user: %s" +msgstr "Creating new user: 新しいユーザ %s を作成します。" -#: nova/virt/hyperv.py:227 +#: ../nova/api/ec2/admin.py:105 #, python-format -msgid "Failed to add diskdrive to VM %s" -msgstr "VM %s へのディスクドライブの追加に失敗しました。" +msgid "Deleting user: %s" +msgstr "Deleting user: ユーザ %s を削除します。" -#: nova/virt/hyperv.py:230 +#: ../nova/api/ec2/admin.py:127 #, python-format -msgid "New disk drive path is %s" -msgstr "新しいドライブパスは %s です。" +msgid "Adding role %(role)s to user %(user)s for project %(project)s" +msgstr "" -#: nova/virt/hyperv.py:247 +#: ../nova/api/ec2/admin.py:131 #, python-format -msgid "Failed to add vhd file to VM %s" -msgstr "vhdファイルの VM %s への追加に失敗しました。" +msgid "Adding sitewide role %(role)s to user %(user)s" +msgstr "" -#: nova/virt/hyperv.py:249 +#: ../nova/api/ec2/admin.py:137 #, python-format -msgid "Created disk for %s" -msgstr "%s に diskを作成します。" +msgid "Removing role %(role)s from user %(user)s for project %(project)s" +msgstr "" -#: nova/virt/hyperv.py:253 +#: ../nova/api/ec2/admin.py:141 #, python-format -msgid "Creating nic for %s " -msgstr "%s にNICを作成します。 " +msgid "Removing sitewide role %(role)s from user %(user)s" +msgstr "" -#: nova/virt/hyperv.py:272 -msgid "Failed creating a port on the external vswitch" -msgstr "外部vswitchへのポート作成に失敗しました。" +#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223 +msgid "operation must be add or remove" +msgstr "operation は add または remove の何れかである必要があります。" -#: nova/virt/hyperv.py:273 +#: ../nova/api/ec2/admin.py:159 #, python-format -msgid "Failed creating port for %s" -msgstr "ポート %s の作成に失敗しました。" +msgid "Getting x509 for user: %(name)s on project: %(project)s" +msgstr "" -#: nova/virt/hyperv.py:275 +#: ../nova/api/ec2/admin.py:177 #, python-format -msgid "Created switch port %s on switch %s" -msgstr "スイッチポート %s をスイッチ %s に作成しました。" +msgid "Create project %(name)s managed by %(manager_user)s" +msgstr "" -#: nova/virt/hyperv.py:285 +#: ../nova/api/ec2/admin.py:190 #, python-format -msgid "Failed to add nic to VM %s" -msgstr "VM %s に対してNICの追加に失敗しました。" +msgid "Modify project: %(name)s managed by %(manager_user)s" +msgstr "" -#: nova/virt/hyperv.py:287 +#: ../nova/api/ec2/admin.py:200 #, python-format -msgid "Created nic for %s " -msgstr "%s のNICを作成しました。 " +msgid "Delete project: %s" +msgstr "Delete project: プロジェクト %s を削除しました。" -#: nova/virt/hyperv.py:320 +#: ../nova/api/ec2/admin.py:214 #, python-format -msgid "WMI job failed: %s" -msgstr "WMIジョブに失敗しました: %s" +msgid "Adding user %(user)s to project %(project)s" +msgstr "" -#: nova/virt/hyperv.py:322 +#: ../nova/api/ec2/admin.py:218 #, python-format -msgid "WMI job succeeded: %s, Elapsed=%s " -msgstr "WMIジョブが成功しました: %s, 経過時間=%s " +msgid "Removing user %(user)s from project %(project)s" +msgstr "" -#: nova/virt/hyperv.py:358 #, python-format -msgid "Got request to destroy vm %s" -msgstr "destroy vm %s リクエストを受信しました。" +#~ 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/virt/hyperv.py:383 #, python-format -msgid "Failed to destroy vm %s" -msgstr "vm %s の削除に失敗しました。" +#~ msgid "(%s) publish (key: %s) %s" +#~ msgstr "(%s) パブリッシュ (key: %s) %s" -#: nova/virt/hyperv.py:389 #, python-format -msgid "Del: disk %s vm %s" -msgstr "Del: 削除: disk %s vm %s" +#~ msgid "Binding %s to %s with key %s" +#~ msgstr "%s を %s にキー %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" +#~ msgid "Getting from %s: %s" +#~ msgstr "%s から %s を取得" -#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 #, python-format -msgid "duplicate name found: %s" -msgstr "%s は重複しています。" +#~ msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +#~ msgstr "AMQPサーバ %s:%d に接続できません。 %d 秒後に再度試みます。" -#: nova/virt/hyperv.py:444 #, python-format -msgid "Successfully changed vm state of %s to %s" -msgstr "vmの状態の %s から %s への変更に成功しました。" +#~ msgid "Starting %s node" +#~ msgstr "ノード %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 への変更に失敗しました。" +#~ msgid "Data store %s is unreachable. Trying again in %d seconds." +#~ msgstr "データストア %s に接続できません。 %d 秒後に再接続します。" -#: nova/virt/images.py:70 #, python-format -msgid "Finished retreving %s -- placed in %s" -msgstr "%s を取得しました。格納先: %s" +#~ msgid "Couldn't get IP, using 127.0.0.1 %s" +#~ msgstr "IPを取得できません。127.0.0.1 を %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への接続が切れています。" +#~ msgid "" +#~ "Access key %s has had %d failed authentications and will be locked out for " +#~ "%d minutes." +#~ msgstr "アクセスキー %s は %d 回認証に失敗したため、%d 分間ロックされます。" -#: nova/virt/libvirt_conn.py:229 #, python-format -msgid "instance %s: deleting instance files %s" -msgstr "インスタンス %s: インスタンスファイル %s を削除しています。" +#~ msgid "Authenticated Request For %s:%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に対してはサポートされていません。" +#~ msgid "arg: %s\t\tval: %s" +#~ msgstr "引数(arg): %s\t値(val): %s" -#: nova/virt/libvirt_conn.py:294 #, python-format -msgid "instance %s: rebooted" -msgstr "インスタンス%s: 再起動しました。" +#~ msgid "Unauthorized request for controller=%s and action=%s" +#~ msgstr "許可されていないリクエスト: controller=%s, action %sです。" -#: nova/virt/libvirt_conn.py:297 #, python-format -msgid "_wait_for_reboot failed: %s" -msgstr "_wait_for_reboot 失敗: %s" +#~ msgid "Adding role %s to user %s for project %s" +#~ msgstr "Adding role: ロール %s をユーザ %s、プロジェクト %s に追加します。" -#: nova/virt/libvirt_conn.py:340 #, python-format -msgid "instance %s: rescued" -msgstr "インスタンス %s: rescued" +#~ msgid "Adding sitewide role %s to user %s" +#~ msgstr "Adding sitewide role: サイトワイドのロール %s をユーザ %s に追加します。" -#: nova/virt/libvirt_conn.py:343 #, python-format -msgid "_wait_for_rescue failed: %s" -msgstr "_wait_for_rescue 失敗: %s" +#~ msgid "Removing role %s from user %s for project %s" +#~ msgstr "Removing role: ロール %s をユーザ %s プロジェクト %s から削除します。" -#: nova/virt/libvirt_conn.py:370 #, python-format -msgid "instance %s: is running" -msgstr "インスタンス %s を起動中です。" +#~ msgid "Removing sitewide role %s from user %s" +#~ msgstr "Removing sitewide role: サイトワイドのロール %s をユーザ %s から削除します。" -#: nova/virt/libvirt_conn.py:381 #, python-format -msgid "instance %s: booted" -msgstr "インスタンス %s: 起動しました。" +#~ msgid "Getting x509 for user: %s on project: %s" +#~ msgstr "Getting X509: x509の取得: ユーザ %s, プロジェクト %s" -#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 #, python-format -msgid "instance %s: failed to boot" -msgstr "インスタンス %s の起動に失敗しました。" +#~ msgid "Create project %s managed by %s" +#~ msgstr "Create project: プロジェクト %s (%s により管理される)を作成します。" -#: nova/virt/libvirt_conn.py:395 #, python-format -msgid "virsh said: %r" -msgstr "virsh の出力: %r" +#~ msgid "Adding user %s to project %s" +#~ msgstr "Adding user: ユーザ %s をプロジェクト %s に追加します。" -#: nova/virt/libvirt_conn.py:399 -msgid "cool, it's a device" -msgstr "デバイスです。" +#, python-format +#~ msgid "Removing user %s from project %s" +#~ msgstr "Removing user: ユーザ %s をプロジェクト %s から削除します。" -#: nova/virt/libvirt_conn.py:407 #, python-format -msgid "data: %r, fpath: %r" -msgstr "データ:%r ファイルパス: %r" +#~ msgid "Unsupported API request: controller = %s,action = %s" +#~ msgstr "サポートされていないAPIリクエストです。 controller = %s,action = %s" -#: nova/virt/libvirt_conn.py:415 #, python-format -msgid "Contents of file %s: %r" -msgstr "ファイル %s の中身: %r" +#~ msgid "Attach volume %s to instacne %s at %s" +#~ msgstr "Attach volume: ボリューム%s をインスタンス %s にデバイス %s でアタッチします。" -#: nova/virt/libvirt_conn.py:449 #, python-format -msgid "instance %s: Creating image" -msgstr "インスタンス %s のイメージを生成します。" +#~ msgid "Associate address %s to instance %s" +#~ msgstr "Associate address: アドレス %s をインスタンス %s に関連付けます。" -#: nova/virt/libvirt_conn.py:505 #, python-format -msgid "instance %s: injecting key into image %s" -msgstr "インスタンス %s にキー %s をインジェクトします。" +#~ msgid "Registered image %s with id %s" +#~ msgstr "Registered image: イメージ %s をid %s で登録します。" -#: nova/virt/libvirt_conn.py:508 #, python-format -msgid "instance %s: injecting net into image %s" -msgstr "インスタンス %s のネットワーク設定をイメージ %s にインジェクトします。" +#~ msgid "User %s is already a member of the group %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)" +#~ msgid "failed authorization: no project named %s (user=%s)" +#~ msgstr "Failed authorization: 認証に失敗しました。プロジェクト名 %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 メソッドを開始。" +#~ msgid "Failed authorization: user %s not admin and not member of project %s" +#~ msgstr "" +#~ "Failed authorization: 認証に失敗しました: ユーザ %s は管理者ではなくかつプロジェクト %s のメンバーではありません。" -#: nova/virt/libvirt_conn.py:589 #, python-format -msgid "instance %s: finished toXML method" -msgstr "インスタンス %s: toXML メソッドを完了。" +#~ msgid "User %s is not a member of project %s" +#~ msgstr "ユーザ %s はプロジェクト %s のメンバーではありません。" -#: 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" +#, python-format +#~ msgid "Adding role %s to user %s in project %s" +#~ msgstr "Adding role: ロール %s をユーザ %s (プロジェクト %s の) に追加します。" -#: nova/virt/xenapi_conn.py:263 #, python-format -msgid "Task [%s] %s status: success %s" -msgstr "タスク [%s] %s ステータス: success %s" +#~ msgid "Removing role %s from user %s on project %s" +#~ msgstr "Removing role: ロール %s をユーザ %s (プロジェクト %s の)から削除します。" -#: nova/virt/xenapi_conn.py:271 #, python-format -msgid "Task [%s] %s status: %s %s" -msgstr "タスク [%s] %s ステータス: %s %s" +#~ msgid "Created project %s with manager %s" +#~ msgstr "Created project: プロジェクト %s (マネージャ %s)を作成します。" -#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 #, python-format -msgid "Got exception: %s" -msgstr "例外 %s が発生しました。" +#~ msgid "Remove user %s from project %s" +#~ msgstr "Remove user: ユーザ %s をプロジェクト %s から削除します。" -#: nova/virt/xenapi/fake.py:72 #, python-format -msgid "%s: _db_content => %s" -msgstr "%s: _db_content => %s" +#~ msgid "Created user %s (admin: %r)" +#~ msgstr "Created user: ユーザ %s (admin: %r) を作成しました。" -#: 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 例外を発生させます。" +#, python-format +#~ msgid "Admin status set to %r for user %s" +#~ msgstr "Admin status set: 管理者ステータス %r をユーザ %s に設定します。" -#: nova/virt/xenapi/fake.py:249 #, python-format -msgid "xenapi.fake does not have an implementation for %s" -msgstr "xenapi.fake には %s が実装されていません。" +#~ msgid "Quota exceeeded for %s, tried to run %s instances" +#~ msgstr "%s のクオータ上限を超えました。%s インスタンスを実行しようとしました。" -#: nova/virt/xenapi/fake.py:283 #, python-format -msgid "Calling %s %s" -msgstr "呼び出し: %s %s" +#~ msgid "Casting to scheduler for %s/%s's instance %s" +#~ msgstr "スケジューラに対して %s/%s のインスタンス %s を送信します。" -#: nova/virt/xenapi/fake.py:288 #, python-format -msgid "Calling getter %s" -msgstr "getter %s をコールします。" +#~ msgid "Going to try and terminate %s" +#~ msgstr "%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 に関する実装がないか、引数の数が誤っています。" +#~ msgid "Input partition size not evenly divisible by sector size: %d / %d" +#~ msgstr "インプットパーティションサイズがセクターサイズで割り切れません。 %d / %d" -#: nova/virt/xenapi/network_utils.py:40 #, python-format -msgid "Found non-unique network for bridge %s" -msgstr "ブリッジ %s に対してブリッジが複数存在します。" +#~ msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +#~ msgstr "ローカルストレージのバイト数がセクターサイズで割り切れません: %d / %d" -#: nova/virt/xenapi/network_utils.py:43 #, python-format -msgid "Found no network for bridge %s" -msgstr "ブリッジ %s に対するネットワークが存在しません。" +#~ msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +#~ msgstr "check_instance_lock: arguments: |%s| |%s| |%s|" -#: nova/virt/xenapi/vm_utils.py:127 #, python-format -msgid "Created VM %s as %s." -msgstr "VM %s を %s として作成しました。" +#~ msgid "Disassociating address %s" +#~ msgstr "アドレス %s の関連付けを解除(disassociate)しています。" -#: nova/virt/xenapi/vm_utils.py:147 #, python-format -msgid "Creating VBD for VM %s, VDI %s ... " -msgstr "VM %s, VDI %s のVBDを作成します… " +#~ msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +#~ msgstr "実行していないインスタンスの再起動を試みます。%s (状態: %s 期待する状態: %s)" -#: 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 に対して作成しました。" +#~ msgid "" +#~ "trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +#~ msgstr "実行していないインスタンスのスナップショット取得を試みます。%s (状態: %s 期待する状態: %s)" -#: nova/virt/xenapi/vm_utils.py:165 #, python-format -msgid "VBD not found in instance %s" -msgstr "インスタンス %s のVBDが見つかりません。" +#~ msgid "instance %s: attaching volume %s to %s" +#~ msgstr "attaching volume: インスタンス %s についてボリューム %s を %s にアタッチします。" -#: nova/virt/xenapi/vm_utils.py:175 #, python-format -msgid "Unable to unplug VBD %s" -msgstr "VBD %s の unplug に失敗しました。" +#~ msgid "instance %s: attach failed %s, removing" +#~ msgstr "インスタンス %s: %sのアタッチに失敗しました。リムーブします。" -#: nova/virt/xenapi/vm_utils.py:187 #, python-format -msgid "Unable to destroy VBD %s" -msgstr "VBD %s の削除に失敗しました。" +#~ msgid "Detach volume %s from mountpoint %s on instance %s" +#~ msgstr "Detach volume: ボリューム %s をマウントポイント %s (インスタンス%s)からデタッチします。" -#: nova/virt/xenapi/vm_utils.py:202 #, python-format -msgid "Creating VIF for VM %s, network %s." -msgstr "VM %s, ネットワーク %s を作成します。" +#~ msgid "Cannot get blockstats for \"%s\" on \"%s\"" +#~ msgstr "ブロックデバイス \"%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 に作成しました。" +#~ msgid "Cannot get ifstats for \"%s\" on \"%s\"" +#~ msgstr "インタフェース \"%s\" の統計を \"%s\" について取得できません。" -#: nova/virt/xenapi/vm_utils.py:216 #, python-format -msgid "Snapshotting VM %s with label '%s'..." -msgstr "VM %s のスナップショットをラベル '%s' で作成します。" +#~ msgid "No service for %s, %s" +#~ msgstr "%s, %s のserviceが存在しません。" -#: nova/virt/xenapi/vm_utils.py:229 #, python-format -msgid "Created snapshot %s from VM %s." -msgstr "スナップショット %s を VM %s について作成しました。" +#~ msgid "No instance for id %s" +#~ msgstr "id %s のinstanceが存在しません。" -#: nova/virt/xenapi/vm_utils.py:243 #, python-format -msgid "Asking xapi to upload %s as '%s'" -msgstr "xapiに対して %s を '%s' としてアップロードするように指示します。" +#~ msgid "no keypair for user %s, name %s" +#~ msgstr "ユーザ %s, ネーム%s に該当するキーペアが存在しません。" -#: nova/virt/xenapi/vm_utils.py:261 #, python-format -msgid "Asking xapi to fetch %s as %s" -msgstr "xapi に対して %s を %s として取得するように指示します。" +#~ msgid "No volume for id %s" +#~ msgstr "id %s に該当するボリュームが存在しません。" -#: nova/virt/xenapi/vm_utils.py:279 #, python-format -msgid "Looking up vdi %s for PV kernel" -msgstr "PV kernelのvdi %s を取得します。" +#~ msgid "No security group named %s for project: %s" +#~ msgstr "セキュリティグループ名 %s がプロジェクト %s に存在しません。" -#: nova/virt/xenapi/vm_utils.py:290 #, python-format -msgid "PV Kernel in VDI:%d" -msgstr "VDIのPV Kernel: %d" +#~ msgid "Parallax returned HTTP error %d from request for /images" +#~ msgstr "Parallax がHTTPエラー%d を /images に対するリクエストに対して返しました。" -#: nova/virt/xenapi/vm_utils.py:318 #, python-format -msgid "VDI %s is still available" -msgstr "VDI %s は依然として存在しています。" +#~ msgid "Parallax returned HTTP error %d from request for /images/detail" +#~ msgstr "Parallax がHTTPエラー %d を /images/detail に対するリクエストに対して返しました" -#: nova/virt/xenapi/vm_utils.py:331 #, python-format -msgid "(VM_UTILS) xenserver vm state -> |%s|" -msgstr "(VM_UTILS) xenserver の vm state -> |%s|" +#~ msgid "IP %s leased to bad mac %s vs %s" +#~ msgstr "IP %s が期待した mac %s ではなく %s にリースされました。" -#: nova/virt/xenapi/vm_utils.py:333 #, python-format -msgid "(VM_UTILS) xenapi power_state -> |%s|" -msgstr "(VM_UTILS) xenapi の power_state -> |%s|" +#~ msgid "IP %s released from bad mac %s vs %s" +#~ msgstr "IP %s がmac %s ではない mac %s への割当から開放されました。" -#: nova/virt/xenapi/vm_utils.py:390 #, python-format -msgid "VHD %s has parent %s" -msgstr "VHD %s のペアレントは %s です。" +#~ msgid "Getting object: %s / %s" +#~ msgstr "オブジェクトの取得: %s / %s" -#: nova/virt/xenapi/vm_utils.py:407 #, python-format -msgid "Re-scanning SR %s" -msgstr "SR %s を再スキャンします。" +#~ msgid "Unauthorized attempt to get object %s from bucket %s" +#~ msgstr "" +#~ "Unauthorized attempt to get object: オブジェクト %s のバケット %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 と一致しません。合致するのを待ちます…" +#~ msgid "Putting object: %s / %s" +#~ msgstr "オブジェクトの格納:: %s / %s" -#: nova/virt/xenapi/vm_utils.py:448 #, python-format -msgid "No VDIs found for VM %s" -msgstr "VM %s にVDIが存在しません。" +#~ msgid "Unauthorized attempt to upload object %s to bucket %s" +#~ msgstr "" +#~ "Unauthorized attempt to upload: オブジェクト %s のバケット %s へのアップロードは許可されていません。" -#: nova/virt/xenapi/vm_utils.py:452 #, python-format -msgid "Unexpected number of VDIs (%s) found for VM %s" -msgstr "予期しない数 (%s) のVDIがVM %s に存在します。" +#~ msgid "Deleting object: %s / %s" +#~ msgstr "オブジェクトを削除しています。: %s / %s" -#: nova/virt/xenapi/vmops.py:62 #, python-format -msgid "Attempted to create non-unique name %s" -msgstr "ユニークではないname %s を作成しようとしました。" +#~ msgid "Toggling publicity flag of image %s %r" +#~ msgstr "Toggling publicity flag: イメージ %s の公開フラグを %r に更新します。" -#: nova/virt/xenapi/vmops.py:99 #, python-format -msgid "Starting VM %s..." -msgstr "VM %s を開始します…" +#~ msgid "Casting to %s %s for %s" +#~ msgstr "メッセージのcast: %s %s for %s" -#: nova/virt/xenapi/vmops.py:101 #, python-format -msgid "Spawning VM %s created %s." -msgstr "VM %s の生成(spawning) により %s を作成しました。" +#~ msgid "Nested received %s, %s" +#~ msgstr "ネスとした受信: %s, %s" -#: nova/virt/xenapi/vmops.py:112 #, python-format -msgid "Instance %s: booted" -msgstr "インスタンス%s: ブートしました。" +#~ msgid "Creating disk for %s by attaching disk file %s" +#~ msgstr "%s のディスクをディスクファイル %s をアタッチして作成します。" -#: nova/virt/xenapi/vmops.py:137 #, python-format -msgid "Instance not present %s" -msgstr "インスタンス%s が存在しません。" +#~ msgid "Created switch port %s on switch %s" +#~ msgstr "スイッチポート %s をスイッチ %s に作成しました。" -#: nova/virt/xenapi/vmops.py:166 #, python-format -msgid "Starting snapshot for VM %s" -msgstr "VM %s に対するスナップショットを開始します。" +#~ msgid "WMI job succeeded: %s, Elapsed=%s " +#~ msgstr "WMIジョブが成功しました: %s, 経過時間=%s " -#: nova/virt/xenapi/vmops.py:174 #, python-format -msgid "Unable to Snapshot %s: %s" -msgstr "%s のスナップショットに失敗しました: %s" +#~ msgid "Del: disk %s vm %s" +#~ msgstr "Del: 削除: disk %s vm %s" -#: nova/virt/xenapi/vmops.py:184 #, python-format -msgid "Finished snapshot and upload for VM %s" -msgstr "VM %s のスナップショットとアップロードが完了しました。" +#~ 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/xenapi/vmops.py:252 #, python-format -msgid "suspend: instance not present %s" -msgstr "suspend: インスタンス %s は存在しません。" +#~ msgid "Successfully changed vm state of %s to %s" +#~ msgstr "vmの状態の %s から %s への変更に成功しました。" -#: nova/virt/xenapi/vmops.py:262 #, python-format -msgid "resume: instance not present %s" -msgstr "resume: インスタンス %s は存在しません。" +#~ msgid "Failed to change vm state of %s to %s" +#~ msgstr "VMの状態の %s から %s への変更に失敗しました。" -#: nova/virt/xenapi/vmops.py:271 #, python-format -msgid "Instance not found %s" -msgstr "インスタンス %s が見つかりません。" +#~ msgid "Finished retreving %s -- placed in %s" +#~ msgstr "%s を取得しました。格納先: %s" -#: nova/virt/xenapi/volume_utils.py:57 #, python-format -msgid "Introducing %s..." -msgstr "%s を introduce します…" +#~ msgid "instance %s: deleting instance files %s" +#~ msgstr "インスタンス %s: インスタンスファイル %s を削除しています。" -#: nova/virt/xenapi/volume_utils.py:74 #, python-format -msgid "Introduced %s as %s." -msgstr "%s を %s として introduce しました。" +#~ msgid "data: %r, fpath: %r" +#~ msgstr "データ:%r ファイルパス: %r" -#: nova/virt/xenapi/volume_utils.py:78 -msgid "Unable to create Storage Repository" -msgstr "Storage Repository を作成できません。" +#, python-format +#~ msgid "Contents of file %s: %r" +#~ msgstr "ファイル %s の中身: %r" -#: nova/virt/xenapi/volume_utils.py:90 #, python-format -msgid "Unable to find SR from VBD %s" -msgstr "VBD %s から SRを取得できません。" +#~ msgid "instance %s: injecting key into image %s" +#~ msgstr "インスタンス %s にキー %s をインジェクトします。" -#: nova/virt/xenapi/volume_utils.py:96 #, python-format -msgid "Forgetting SR %s ... " -msgstr "SR %s をforgetします。 " +#~ msgid "instance %s: injecting net into image %s" +#~ msgstr "インスタンス %s のネットワーク設定をイメージ %s にインジェクトします。" -#: nova/virt/xenapi/volume_utils.py:101 #, python-format -msgid "Ignoring exception %s when getting PBDs for %s" -msgstr "例外 %s が %s のPBDを取得する際に発生しましたが無視します。" +#~ msgid "instance %s: ignoring error injecting data into image %s (%s)" +#~ msgstr "インスタンス %s: データをイメージ %s にインジェクトする際にエラーが発生しました。(%s)" -#: nova/virt/xenapi/volume_utils.py:107 #, python-format -msgid "Ignoring exception %s when unplugging PBD %s" -msgstr "例外 %s が %s のPBDをunplugする際に発生しましたが無視します。" +#~ msgid "Task [%s] %s status: success %s" +#~ msgstr "タスク [%s] %s ステータス: success %s" -#: nova/virt/xenapi/volume_utils.py:111 #, python-format -msgid "Forgetting SR %s done." -msgstr "SR %s のforgetが完了。" +#~ msgid "Task [%s] %s status: %s %s" +#~ msgstr "タスク [%s] %s ステータス: %s %s" -#: nova/virt/xenapi/volume_utils.py:113 #, python-format -msgid "Ignoring exception %s when forgetting SR %s" -msgstr "例外 %s がSR %s をforgetする際に発生しましたが無視します。" +#~ msgid "%s: _db_content => %s" +#~ msgstr "%s: _db_content => %s" -#: nova/virt/xenapi/volume_utils.py:123 #, python-format -msgid "Unable to introduce VDI on SR %s" -msgstr "SR %s のVDIのintroduceができません。" +#~ msgid "Calling %s %s" +#~ msgstr "呼び出し: %s %s" -#: nova/virt/xenapi/volume_utils.py:128 #, python-format -msgid "Unable to get record of VDI %s on" -msgstr "VDI %s のレコードを取得できません。" +#~ msgid "Created VM %s as %s." +#~ msgstr "VM %s を %s として作成しました。" -#: nova/virt/xenapi/volume_utils.py:146 #, python-format -msgid "Unable to introduce VDI for SR %s" -msgstr "SR %s のVDIをintroduceできません。" +#~ msgid "Creating VBD for VM %s, VDI %s ... " +#~ msgstr "VM %s, VDI %s のVBDを作成します… " -#: nova/virt/xenapi/volume_utils.py:175 #, python-format -msgid "Unable to obtain target information %s, %s" -msgstr "ターゲットの情報を取得できません。 %s, %s" +#~ msgid "Created VBD %s for VM %s, VDI %s." +#~ msgstr "VBD %s を VM %s, VDI %s に対して作成しました。" -#: nova/virt/xenapi/volume_utils.py:197 #, python-format -msgid "Mountpoint cannot be translated: %s" -msgstr "マウントポイントを変換できません。 %s" +#~ msgid "Creating VIF for VM %s, network %s." +#~ msgstr "VM %s, ネットワーク %s を作成します。" -#: nova/virt/xenapi/volumeops.py:51 #, python-format -msgid "Attach_volume: %s, %s, %s" -msgstr "Attach_volume: ボリュームのアタッチ: %s, %s, %s" +#~ msgid "Created VIF %s for VM %s, network %s." +#~ msgstr "VIF %s を VM %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を作成できません。" +#~ msgid "Snapshotting VM %s with label '%s'..." +#~ msgstr "VM %s のスナップショットをラベル '%s' で作成します。" -#: nova/virt/xenapi/volumeops.py:81 #, python-format -msgid "Unable to use SR %s for instance %s" -msgstr "SR %s をインスタンス %s に対して利用できません。" +#~ msgid "Created snapshot %s from VM %s." +#~ msgstr "スナップショット %s を VM %s について作成しました。" -#: nova/virt/xenapi/volumeops.py:93 #, python-format -msgid "Unable to attach volume to instance %s" -msgstr "インスタンス %s にボリュームをアタッチできません。" +#~ msgid "Asking xapi to upload %s as '%s'" +#~ msgstr "xapiに対して %s を '%s' としてアップロードするように指示します。" -#: nova/virt/xenapi/volumeops.py:95 #, python-format -msgid "Mountpoint %s attached to instance %s" -msgstr "マウントポイント %s をインスタンス %s にアタッチしました。" +#~ msgid "Asking xapi to fetch %s as %s" +#~ msgstr "xapi に対して %s を %s として取得するように指示します。" -#: nova/virt/xenapi/volumeops.py:106 #, python-format -msgid "Detach_volume: %s, %s" -msgstr "Detach_volume: ボリュームのデタッチ: %s, %s" +#~ msgid "PV Kernel in VDI:%d" +#~ msgstr "VDIのPV Kernel: %d" -#: nova/virt/xenapi/volumeops.py:113 #, python-format -msgid "Unable to locate volume %s" -msgstr "ボリューム %s の存在が確認できません。" +#~ msgid "VHD %s has parent %s" +#~ msgstr "VHD %s のペアレントは %s です。" -#: nova/virt/xenapi/volumeops.py:121 #, python-format -msgid "Unable to detach volume %s" -msgstr "ボリューム %s のデタッチができません。" +#~ msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +#~ msgstr "ペアレント %s がオリジナルのペアレント %s と一致しません。合致するのを待ちます…" -#: nova/virt/xenapi/volumeops.py:128 #, python-format -msgid "Mountpoint %s detached from instance %s" -msgstr "マウントポイント %s をインスタンス %s からデタッチしました。" +#~ msgid "Unexpected number of VDIs (%s) found for VM %s" +#~ msgstr "予期しない数 (%s) のVDIがVM %s に存在します。" -#: nova/volume/api.py:44 #, python-format -msgid "Quota exceeeded for %s, tried to create %sG volume" -msgstr "%sのクオータを超えています。サイズ %sG のボリュームの作成を行おうとしました。" +#~ msgid "Spawning VM %s created %s." +#~ msgstr "VM %s の生成(spawning) により %s を作成しました。" -#: nova/volume/api.py:46 #, python-format -msgid "Volume quota exceeded. You cannot create a volume of size %s" -msgstr "ボリュームのクオータを超えています。%sの大きさのボリュームは作成できません。" +#~ msgid "Unable to Snapshot %s: %s" +#~ msgstr "%s のスナップショットに失敗しました: %s" -#: nova/volume/api.py:70 nova/volume/api.py:95 -msgid "Volume status must be available" -msgstr "ボリュームのステータス(status)が available でなければなりません。" +#, python-format +#~ msgid "suspend: instance not present %s" +#~ msgstr "suspend: インスタンス %s は存在しません。" -#: nova/volume/api.py:97 -msgid "Volume is already attached" -msgstr "ボリュームは既にアタッチされています(attached)。" +#, python-format +#~ msgid "resume: instance not present %s" +#~ msgstr "resume: インスタンス %s は存在しません。" -#: nova/volume/api.py:103 -msgid "Volume is already detached" -msgstr "ボリュームは既にデタッチされています(detached)。" +#, python-format +#~ msgid "Instance not found %s" +#~ msgstr "インスタンス %s が見つかりません。" -#: nova/volume/driver.py:76 #, python-format -msgid "Recovering from a failed execute. Try number %s" -msgstr "実行失敗からリカバリーします。%s 回目のトライ。" +#~ msgid "Introduced %s as %s." +#~ msgstr "%s を %s として introduce しました。" -#: nova/volume/driver.py:85 #, python-format -msgid "volume group %s doesn't exist" -msgstr "ボリュームグループ%sが存在しません。" +#~ msgid "Ignoring exception %s when getting PBDs for %s" +#~ msgstr "例外 %s が %s のPBDを取得する際に発生しましたが無視します。" -#: nova/volume/driver.py:210 #, python-format -msgid "FAKE AOE: %s" -msgstr "偽のAOE: %s" +#~ msgid "Ignoring exception %s when unplugging PBD %s" +#~ msgstr "例外 %s が %s のPBDをunplugする際に発生しましたが無視します。" -#: nova/volume/driver.py:315 #, python-format -msgid "FAKE ISCSI: %s" -msgstr "偽のISCSI: %s" +#~ msgid "Ignoring exception %s when forgetting SR %s" +#~ msgstr "例外 %s がSR %s をforgetする際に発生しましたが無視します。" -#: nova/volume/manager.py:85 #, python-format -msgid "Re-exporting %s volumes" -msgstr "%s 個のボリュームを再エクスポートします。" +#~ msgid "Unable to obtain target information %s, %s" +#~ msgstr "ターゲットの情報を取得できません。 %s, %s" -#: nova/volume/manager.py:93 #, python-format -msgid "volume %s: creating" -msgstr "ボリューム%sを作成します。" +#~ msgid "Attach_volume: %s, %s, %s" +#~ msgstr "Attach_volume: ボリュームのアタッチ: %s, %s, %s" -#: nova/volume/manager.py:102 #, python-format -msgid "volume %s: creating lv of size %sG" -msgstr "ボリューム%sの%sGのlv (論理ボリューム) を作成します。" +#~ msgid "Unable to create VDI on SR %s for instance %s" +#~ msgstr "SR %s にインスタンス %s のVDIを作成できません。" -#: nova/volume/manager.py:106 #, python-format -msgid "volume %s: creating export" -msgstr "ボリューム %s をエクスポートします。" +#~ msgid "Unable to use SR %s for instance %s" +#~ msgstr "SR %s をインスタンス %s に対して利用できません。" -#: nova/volume/manager.py:113 #, python-format -msgid "volume %s: created successfully" -msgstr "ボリューム %s の作成に成功しました。" +#~ msgid "Mountpoint %s attached to instance %s" +#~ msgstr "マウントポイント %s をインスタンス %s にアタッチしました。" -#: nova/volume/manager.py:121 -msgid "Volume is still attached" -msgstr "ボリュームはアタッチされたままです。" +#, python-format +#~ msgid "Detach_volume: %s, %s" +#~ msgstr "Detach_volume: ボリュームのデタッチ: %s, %s" -#: nova/volume/manager.py:123 -msgid "Volume is not local to this node" -msgstr "ボリュームはこのノードのローカルではありません。" +#, python-format +#~ msgid "Mountpoint %s detached from instance %s" +#~ msgstr "マウントポイント %s をインスタンス %s からデタッチしました。" -#: nova/volume/manager.py:124 #, python-format -msgid "volume %s: removing export" -msgstr "ボリューム %s のエクスポートを解除します。" +#~ msgid "Quota exceeeded for %s, tried to create %sG volume" +#~ msgstr "%sのクオータを超えています。サイズ %sG のボリュームの作成を行おうとしました。" -#: nova/volume/manager.py:126 #, python-format -msgid "volume %s: deleting" -msgstr "ボリューム %s を削除します。" +#~ msgid "Volume quota exceeded. You cannot create a volume of size %s" +#~ msgstr "ボリュームのクオータを超えています。%sの大きさのボリュームは作成できません。" -#: nova/volume/manager.py:129 #, python-format -msgid "volume %s: deleted successfully" -msgstr "ボリューム %s の削除に成功しました。" +#~ msgid "volume %s: creating lv of size %sG" +#~ msgstr "ボリューム%sの%sGのlv (論理ボリューム) を作成します。" diff --git a/po/pt_BR.po b/po/pt_BR.po index e57f7304a..887c32597 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -7,2142 +7,3021 @@ 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-03 20:32+0000\n" -"Last-Translator: André Gondim \n" +"POT-Creation-Date: 2011-02-21 10:03-0500\n" +"PO-Revision-Date: 2011-03-24 14:51+0000\n" +"Last-Translator: msinhore \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-02-05 05:36+0000\n" -"X-Generator: Launchpad (build 12177)\n" +"X-Launchpad-Export-Date: 2011-03-25 05:22+0000\n" +"X-Generator: Launchpad (build 12559)\n" -#: nova/crypto.py:46 +#: ../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 "Hosts não encontrados" + +#: ../nova/exception.py:33 +msgid "Unexpected error while running command." +msgstr "Erro inesperado ao executar o comando." + +#: ../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 "Exceção não capturada" + +#: ../nova/volume/api.py:45 +#, python-format +msgid "Quota exceeeded for %(pid)s, tried to create %(size)sG volume" +msgstr "Cota excedida para %(pid)s, tentando criar volume com %(size)sG" + +#: ../nova/volume/api.py:47 +#, python-format +msgid "Volume quota exceeded. You cannot create a volume of size %sG" +msgstr "" +"Cota excedida para o volume. Você não pode criar um volume com o tamanho %sG" + +#: ../nova/volume/api.py:71 ../nova/volume/api.py:96 +msgid "Volume status must be available" +msgstr "O status do volume parece estar disponível" + +#: ../nova/volume/api.py:98 +msgid "Volume is already attached" +msgstr "O Volume já está anexado" + +#: ../nova/volume/api.py:104 +msgid "Volume is already detached" +msgstr "O Volume já está desanexado" + +#: ../nova/api/openstack/servers.py:72 +msgid "Failed to read private ip" +msgstr "Falha ao ler o IP privado" + +#: ../nova/api/openstack/servers.py:79 +msgid "Failed to read public ip(s)" +msgstr "Falha ao ler o(s) IP(s) público(s)" + +#: ../nova/api/openstack/servers.py:152 +#, python-format +msgid "%(param)s property not found for image %(_image_id)s" +msgstr "%(param)s propriedade não foi encontrada para %(_image_id)s" + +#: ../nova/api/openstack/servers.py:168 +msgid "No keypairs defined" +msgstr "Os keypairs não foram definidos" + +#: ../nova/api/openstack/servers.py:238 +#, python-format +msgid "Compute.api::lock %s" +msgstr "Compute.api::lock %s" + +#: ../nova/api/openstack/servers.py:253 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "Compute.api::unlock %s" + +#: ../nova/api/openstack/servers.py:267 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "Compute.api::get_lock %s" + +#: ../nova/api/openstack/servers.py:281 +#, python-format +msgid "Compute.api::reset_network %s" +msgstr "Compute.api::reset_network %s" + +#: ../nova/api/openstack/servers.py:292 +#, python-format +msgid "Compute.api::pause %s" +msgstr "Compute.api::pause %s" + +#: ../nova/api/openstack/servers.py:303 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "Compute.api::unpause %s" + +#: ../nova/api/openstack/servers.py:314 +#, python-format +msgid "compute.api::suspend %s" +msgstr "compute.api::suspend %s" + +#: ../nova/api/openstack/servers.py:325 +#, python-format +msgid "compute.api::resume %s" +msgstr "compute.api::resume %s" + +#: ../nova/twistd.py:157 +msgid "Wrong number of arguments." +msgstr "Número errado de argumentos." + +#: ../nova/twistd.py:209 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "" +"Arquivo do id do processo (pidfile) %s não existe. O Daemon está parado?\n" + +#: ../nova/twistd.py:221 +msgid "No such process" +msgstr "Processo inexistente" + +#: ../nova/twistd.py:230 ../nova/service.py:224 +#, python-format +msgid "Serving %s" +msgstr "Servindo %s" + +#: ../nova/twistd.py:262 ../nova/service.py:225 +msgid "Full set of FLAGS:" +msgstr "Conjunto completo de FLAGS:" + +#: ../nova/twistd.py:266 +#, python-format +msgid "Starting %s" +msgstr "Iniciando %s" + +#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101 +#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741 +#: ../nova/api/ec2/__init__.py:317 +#, python-format +msgid "Instance %s not found" +msgstr "Instancia %s não encontrada" + +#. 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 "Attach_volume: %(instance_name)s, %(device_path)s, %(mountpoint)s" + +#: ../nova/virt/xenapi/volumeops.py:69 +#, python-format +msgid "Unable to create VDI on SR %(sr_ref)s for instance %(instance_name)s" +msgstr "" +"Não é possível criar o VDI no SR %(sr_ref)s para a instância " +"%(instance_name)s" + +#: ../nova/virt/xenapi/volumeops.py:80 +#, python-format +msgid "Unable to use SR %(sr_ref)s for instance %(instance_name)s" +msgstr "" +"Não é possível usar o SR %(sr_ref)s para a instância %(instance_name)s" + +#: ../nova/virt/xenapi/volumeops.py:91 +#, python-format +msgid "Unable to attach volume to instance %s" +msgstr "Não é possível anexar o volume na instância %s" + +#: ../nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Mountpoint %(mountpoint)s attached to instance %(instance_name)s" +msgstr "" +"Ponto de montagem %(mountpoint)s conectada à instância %(instance_name)s" + +#. Detach VBD from VM +#: ../nova/virt/xenapi/volumeops.py:104 +#, python-format +msgid "Detach_volume: %(instance_name)s, %(mountpoint)s" +msgstr "Detach_volume: %(instance_name)s, %(mountpoint)s" + +#: ../nova/virt/xenapi/volumeops.py:112 +#, python-format +msgid "Unable to locate volume %s" +msgstr "Não é possível localizar o volume %s" + +#: ../nova/virt/xenapi/volumeops.py:120 +#, python-format +msgid "Unable to detach volume %s" +msgstr "Não é possível desconectar o volume %s" + +#: ../nova/virt/xenapi/volumeops.py:127 +#, python-format +msgid "Mountpoint %(mountpoint)s detached from instance %(instance_name)s" +msgstr "" +"Ponto de montagem %(mountpoint)s desanexada da instância %(instance_name)s" + +#: ../nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "Tipo de instância desconhecido: %s" + +#: ../nova/crypto.py:46 msgid "Filename of root CA" msgstr "Nome do arquivo da CA raiz" -#: nova/crypto.py:49 +#: ../nova/crypto.py:49 msgid "Filename of private key" msgstr "Nome do arquivo da chave privada" -#: nova/crypto.py:51 +#: ../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 +#: ../nova/crypto.py:53 msgid "Where we keep our keys" msgstr "Aonde armazenamos nossas chaves" -#: nova/crypto.py:55 +#: ../nova/crypto.py:55 msgid "Where we keep our root CA" -msgstr "Aonde mantemos nosso CA raiz" +msgstr "Onde mantemos nosso CA raiz" -#: nova/crypto.py:57 +#: ../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 +#: ../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" +"Assunto do certificado para usuários, %s para projeto, usuário, timestamp" -#: nova/crypto.py:66 +#: ../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" +msgstr "Assunto do certificado para projetos, %s para projeto, timestamp" -#: nova/crypto.py:71 +#: ../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" +msgstr "Assunto do certificado para vpns, %s para projeto, timestamp" -#: nova/crypto.py:258 +#: ../nova/crypto.py:258 #, python-format msgid "Flags path: %s" -msgstr "Caminho da sinalização: %s" +msgstr "Localização dos sinalizadores: %s" -#: nova/exception.py:33 -msgid "Unexpected error while running command." -msgstr "Erro inesperado ao executar o comando." +#: ../nova/scheduler/manager.py:69 +#, python-format +msgid "Casting to %(topic)s %(host)s for %(method)s" +msgstr "Moldagem para %(topic)s %(host)s para %(method)s" + +#: ../nova/compute/manager.py:78 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "check_instance_lock: decorating: |%s|" -#: nova/exception.py:36 +#: ../nova/compute/manager.py:80 #, 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" +"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|" +msgstr "" +"check_instance_lock: argumentos: |%(self)s| |%(context)s| |%(instance_id)s|" -#: nova/fakerabbit.py:48 +#: ../nova/compute/manager.py:84 #, python-format -msgid "(%s) publish (key: %s) %s" -msgstr "(%s) publicar (key: %s) %s" +msgid "check_instance_lock: locked: |%s|" +msgstr "check_instance_lock: locked: |%s|" -#: nova/fakerabbit.py:53 +#: ../nova/compute/manager.py:86 #, python-format -msgid "Publishing to route %s" -msgstr "Publicando para rota %s" +msgid "check_instance_lock: admin: |%s|" +msgstr "check_instance_lock: admin: |%s|" -#: nova/fakerabbit.py:83 +#: ../nova/compute/manager.py:91 #, python-format -msgid "Declaring queue %s" -msgstr "Declarando fila %s" +msgid "check_instance_lock: executing: |%s|" +msgstr "check_instance_lock: executando: |%s|" -#: nova/fakerabbit.py:89 +#: ../nova/compute/manager.py:95 #, python-format -msgid "Declaring exchange %s" -msgstr "Declarando troca %s" +msgid "check_instance_lock: not executing |%s|" +msgstr "check_instance_lock: not executando |%s|" + +#: ../nova/compute/manager.py:179 +msgid "Instance has already been created" +msgstr "A instância já foi criada" -#: nova/fakerabbit.py:95 +#: ../nova/compute/manager.py:180 #, python-format -msgid "Binding %s to %s with key %s" -msgstr "Atribuindo %s para %s com chave %s" +msgid "instance %s: starting..." +msgstr "instância %s: iniciando..." -#: nova/fakerabbit.py:120 +#. pylint: disable=W0702 +#: ../nova/compute/manager.py:219 #, python-format -msgid "Getting from %s: %s" -msgstr "Obtendo de %s: %s" +msgid "instance %s: Failed to spawn" +msgstr "instância %s: falha na geração" -#: nova/rpc.py:92 +#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286 #, 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." +msgid "Terminating instance %s" +msgstr "Terminando a instância %s" -#: nova/rpc.py:99 +#: ../nova/compute/manager.py:255 #, 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." +msgid "Deallocating address %s" +msgstr "Desalocando o endereço %s" -#: nova/rpc.py:118 -msgid "Reconnected to queue" -msgstr "Reconectado à fila" +#: ../nova/compute/manager.py:268 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "tentando destruir instância já destruida: %s" -#: nova/rpc.py:125 -msgid "Failed to fetch message from queue" -msgstr "Falha ao obter mensagem da fila" +#: ../nova/compute/manager.py:282 +#, python-format +msgid "Rebooting instance %s" +msgstr "Reiniciando a instância %s" -#: nova/rpc.py:155 +#: ../nova/compute/manager.py:287 #, python-format -msgid "Initing the Adapter Consumer for %s" -msgstr "Iniciando o Adaptador Consumidor para %s" +msgid "" +"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" +"tentando reiniciar uma instancia com estado diferente de running: " +"%(instance_id)s (estado: %(state)s esperado: %(running)s)" -#: nova/rpc.py:170 +#: ../nova/compute/manager.py:311 #, python-format -msgid "received %s" -msgstr "recebido %s" +msgid "instance %s: snapshotting" +msgstr "instância %s: fazendo um snapshot" -#: nova/rpc.py:183 +#: ../nova/compute/manager.py:316 #, python-format -msgid "no method for message: %s" -msgstr "sem método para mensagem: %s" +msgid "" +"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" +"tentando fazer um snapshot de uma instância com estado diferente de running: " +" %(instance_id)s (estado: %(state)s esperado: %(running)s)" -#: nova/rpc.py:184 +#: ../nova/compute/manager.py:332 #, python-format -msgid "No method for message: %s" -msgstr "Sem método para mensagem: %s" +msgid "" +"trying to reset the password on a non-running instance: %(instance_id)s " +"(state: %(instance_state)s expected: %(expected_state)s)" +msgstr "" +"tentando limpar a senha de uma instância com estado diferente de running: " +"%(instance_id)s (estado: %(instance_state)s esperado: %(expected_state)s)" -#: nova/rpc.py:245 +#: ../nova/compute/manager.py:335 #, python-format -msgid "Returning exception %s to caller" -msgstr "Retornando exceção %s ao método de origem" +msgid "instance %s: setting admin password" +msgstr "instância %s: configurando a senha do administrador" -#: nova/rpc.py:286 +#: ../nova/compute/manager.py:353 #, python-format -msgid "unpacked context: %s" -msgstr "conteúdo descompactado: %s" +msgid "" +"trying to inject a file into a non-running instance: %(instance_id)s (state: " +"%(instance_state)s expected: %(expected_state)s)" +msgstr "" +"tentando injetar o arquivo dentro de uma instância com estado diferente de " +"running: %(instance_id)s (estado: %(instance_state)s esperado: " +"%(expected_state)s)" -#: nova/rpc.py:305 -msgid "Making asynchronous call..." -msgstr "Fazendo chamada assíncrona..." +#: ../nova/compute/manager.py:362 +#, python-format +msgid "instance %(nm)s: injecting file to %(plain_path)s" +msgstr "instância %(nm)s: injetando um arquivo para %(plain_path)s" -#: nova/rpc.py:308 +#: ../nova/compute/manager.py:372 #, python-format -msgid "MSG_ID is %s" -msgstr "MSG_ID é %s" +msgid "instance %s: rescuing" +msgstr "instância %s: resgatando" -#: nova/rpc.py:356 +#: ../nova/compute/manager.py:387 #, python-format -msgid "response %s" -msgstr "resposta %s" +msgid "instance %s: unrescuing" +msgstr "instância %s: desfazendo o resgate" -#: nova/rpc.py:365 +#: ../nova/compute/manager.py:406 #, python-format -msgid "topic is %s" -msgstr "topico é %s" +msgid "instance %s: pausing" +msgstr "instância %s: pausando" -#: nova/rpc.py:366 +#: ../nova/compute/manager.py:423 #, python-format -msgid "message %s" -msgstr "mensagem %s" +msgid "instance %s: unpausing" +msgstr "instância %s: saindo do pause" -#: nova/service.py:157 +#: ../nova/compute/manager.py:440 #, python-format -msgid "Starting %s node" -msgstr "Iniciando nó %s" +msgid "instance %s: retrieving diagnostics" +msgstr "instância %s: recuperando os diagnósticos" -#: 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/compute/manager.py:453 +#, python-format +msgid "instance %s: suspending" +msgstr "instância %s: suspendendo" -#: 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/compute/manager.py:472 +#, python-format +msgid "instance %s: resuming" +msgstr "" -#: nova/service.py:202 -msgid "Recovered model server connection!" -msgstr "Recuperada conexão servidor de modelo." +#: ../nova/compute/manager.py:491 +#, python-format +msgid "instance %s: locking" +msgstr "instância %s: bloqueando" -#: nova/service.py:208 -msgid "model server went away" -msgstr "servidor de modelo perdido" +#: ../nova/compute/manager.py:503 +#, python-format +msgid "instance %s: unlocking" +msgstr "instância %s: desbloqueando" -#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#: ../nova/compute/manager.py:513 #, python-format -msgid "Data store %s is unreachable. Trying again in %d seconds." +msgid "instance %s: getting locked state" msgstr "" -"Repositório de dados %s não pode ser atingido. Tentando novamente em %d " -"segundos." -#: nova/service.py:232 nova/twistd.py:232 +#: ../nova/compute/manager.py:526 #, python-format -msgid "Serving %s" -msgstr "Servindo %s" +msgid "instance %s: reset network" +msgstr "" -#: nova/service.py:234 nova/twistd.py:264 -msgid "Full set of FLAGS:" -msgstr "Conjunto completo de FLAGS:" +#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515 +#, python-format +msgid "Get console output for instance %s" +msgstr "Obter saída do console para instância %s" -#: nova/twistd.py:211 +#: ../nova/compute/manager.py:543 #, python-format -msgid "pidfile %s does not exist. Daemon not running?\n" +msgid "instance %s: getting ajax console" +msgstr "instância %s: obtendo console ajax" + +#: ../nova/compute/manager.py:553 +#, python-format +msgid "" +"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s" msgstr "" -"Arquivo de id de processo (pidfile) %s não existe. Daemon não está " -"executando?\n" -#: nova/twistd.py:268 +#. pylint: disable=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:569 #, python-format -msgid "Starting %s" -msgstr "Iniciando %s" +msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing" +msgstr "" -#: nova/utils.py:53 +#: ../nova/compute/manager.py:585 #, python-format -msgid "Inner Exception: %s" -msgstr "Exceção interna: %s" +msgid "" +"Detach volume %(volume_id)s from mountpoint %(mp)s on instance " +"%(instance_id)s" +msgstr "" -#: nova/utils.py:54 +#: ../nova/compute/manager.py:588 #, python-format -msgid "Class %s cannot be found" -msgstr "Classe %s não pode ser encontrada" +msgid "Detaching volume from unknown instance %s" +msgstr "" -#: nova/utils.py:113 +#: ../nova/scheduler/simple.py:53 #, python-format -msgid "Fetching %s" -msgstr "Obtendo %s" +msgid "Host %s is not alive" +msgstr "Host %s não está ativo" + +#: ../nova/scheduler/simple.py:65 +msgid "All hosts have too many cores" +msgstr "" -#: nova/utils.py:125 +#: ../nova/scheduler/simple.py:87 #, python-format -msgid "Running cmd (subprocess): %s" -msgstr "Executando comando (subprocesso): %s" +msgid "Host %s not available" +msgstr "O host %s não está disponível" + +#: ../nova/scheduler/simple.py:99 +msgid "All hosts have too many gigabytes" +msgstr "Todos os hosts tem muitos gigabytes" -#: nova/utils.py:138 +#: ../nova/scheduler/simple.py:119 +msgid "All hosts have too many networks" +msgstr "Todos os hosts tem muitas interfaces de rede" + +#: ../nova/volume/manager.py:85 #, python-format -msgid "Result was %s" -msgstr "Resultado foi %s" +msgid "Re-exporting %s volumes" +msgstr "Re-exportando %s volumes" -#: nova/utils.py:171 +#: ../nova/volume/manager.py:90 #, python-format -msgid "debug in callback: %s" -msgstr "debug em callback: %s" +msgid "volume %s: skipping export" +msgstr "volume %s: ignorando export" -#: nova/utils.py:176 +#: ../nova/volume/manager.py:96 #, python-format -msgid "Running %s" -msgstr "Executando %s" +msgid "volume %s: creating" +msgstr "volume %s: criando" -#: nova/utils.py:207 +#: ../nova/volume/manager.py:108 #, 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" +msgid "volume %(vol_name)s: creating lv of size %(vol_size)sG" +msgstr "volume %(vol_name)s: criando lv com tamanho %(vol_size)sG" -#: nova/utils.py:289 +#: ../nova/volume/manager.py:112 #, python-format -msgid "Invalid backend: %s" -msgstr "Backend inválido: %s" +msgid "volume %s: creating export" +msgstr "volume %s: criando o export" -#: nova/utils.py:300 +#: ../nova/volume/manager.py:123 #, python-format -msgid "backend %s" -msgstr "backend %s" +msgid "volume %s: created successfully" +msgstr "volume %s: criado com sucesso" -#: nova/api/ec2/__init__.py:133 -msgid "Too many failed authentications." -msgstr "Muitas falhas de autenticação." +#: ../nova/volume/manager.py:131 +msgid "Volume is still attached" +msgstr "O volume continua atachado" + +#: ../nova/volume/manager.py:133 +msgid "Volume is not local to this node" +msgstr "O volume não pertence à este node" + +#: ../nova/volume/manager.py:136 +#, python-format +msgid "volume %s: removing export" +msgstr "volume %s: removendo export" + +#: ../nova/volume/manager.py:138 +#, python-format +msgid "volume %s: deleting" +msgstr "volume %s: removendo" + +#: ../nova/volume/manager.py:147 +#, python-format +msgid "volume %s: deleted successfully" +msgstr "volume %s: remoção realizada com sucesso" + +#: ../nova/virt/xenapi/fake.py:74 +#, python-format +msgid "%(text)s: _db_content => %(content)s" +msgstr "%(text)s: _db_content => %(content)s" + +#: ../nova/virt/xenapi/fake.py:304 ../nova/virt/xenapi/fake.py:404 +#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478 +msgid "Raising NotImplemented" +msgstr "Aumento não implementado" + +#: ../nova/virt/xenapi/fake.py:306 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "xenapi.fake não tem uma implementação para %s" + +#: ../nova/virt/xenapi/fake.py:341 +#, python-format +msgid "Calling %(localname)s %(impl)s" +msgstr "Chamando %(localname)s %(impl)s" + +#: ../nova/virt/xenapi/fake.py:346 +#, python-format +msgid "Calling getter %s" +msgstr "Chamando o pai %s" + +#: ../nova/virt/xenapi/fake.py:406 +#, 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 não tem implementação para %s ou isto foi chamado com um número " +"de argumentos inválidos" + +#: ../nova/tests/test_cloud.py:256 +msgid "Can't test instances without a real virtual env." +msgstr "Não é possível testar instâncias sem um ambiente virtual real" + +#: ../nova/tests/test_cloud.py:268 +#, python-format +msgid "Need to watch instance %s until it's running..." +msgstr "É necessário assistir a instância %s até ela estar rodando..." + +#: ../nova/virt/connection.py:73 +msgid "Failed to open connection to the hypervisor" +msgstr "Falha ao abrir a conexão com o hypervisor" + +#: ../nova/network/linux_net.py:187 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "Iniciando a VLAN %s" + +#: ../nova/network/linux_net.py:208 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "Iniciando a Bridge para %s" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:314 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:316 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "Pid %d está ultrapassado, reiniciando dnsmasq" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:358 +#, python-format +msgid "killing radvd threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:360 +#, python-format +msgid "Pid %d is stale, relaunching radvd" +msgstr "Pid %d está ultrapassado, reiniciando radvd" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:449 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: ../nova/utils.py:58 +#, python-format +msgid "Inner Exception: %s" +msgstr "Exceção interna: %s" + +#: ../nova/utils.py:59 +#, python-format +msgid "Class %s cannot be found" +msgstr "Classe %s não pode ser encontrada" + +#: ../nova/utils.py:118 +#, python-format +msgid "Fetching %s" +msgstr "Obtendo %s" + +#: ../nova/utils.py:130 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "Executando comando (subprocesso): %s" + +#: ../nova/utils.py:143 ../nova/utils.py:183 +#, python-format +msgid "Result was %s" +msgstr "Resultado foi %s" + +#: ../nova/utils.py:159 +#, python-format +msgid "Running cmd (SSH): %s" +msgstr "Rodando o comando (SSH): %s" + +#: ../nova/utils.py:217 +#, python-format +msgid "debug in callback: %s" +msgstr "debug em callback: %s" + +#: ../nova/utils.py:222 +#, python-format +msgid "Running %s" +msgstr "Executando %s" + +#: ../nova/utils.py:262 +#, python-format +msgid "Link Local address is not found.:%s" +msgstr "Endereço para Link Local não encontrado: %s" + +#: ../nova/utils.py:265 +#, python-format +msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s" +msgstr "" +"Não foi possível atribuir um IP para o Link Local de %(interface)s :%(ex)s" + +#: ../nova/utils.py:363 +#, python-format +msgid "Invalid backend: %s" +msgstr "Backend inválido: %s" + +#: ../nova/utils.py:374 +#, python-format +msgid "backend %s" +msgstr "backend %s" + +#: ../nova/fakerabbit.py:49 +#, python-format +msgid "(%(nm)s) publish (key: %(routing_key)s) %(message)s" +msgstr "(%(nm)s) publicar (key: %(routing_key)s) %(message)s" + +#: ../nova/fakerabbit.py:54 +#, python-format +msgid "Publishing to route %s" +msgstr "Publicando para rota %s" + +#: ../nova/fakerabbit.py:84 +#, python-format +msgid "Declaring queue %s" +msgstr "Declarando fila %s" + +#: ../nova/fakerabbit.py:90 +#, python-format +msgid "Declaring exchange %s" +msgstr "Declarando troca %s" + +#: ../nova/fakerabbit.py:96 +#, python-format +msgid "Binding %(queue)s to %(exchange)s with key %(routing_key)s" +msgstr "Ligação %(queue)s para %(exchange)s com chave %(routing_key)s" + +#: ../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 "VM %s criada..." + +#: ../nova/virt/xenapi/vm_utils.py:138 +#, python-format +msgid "Created VM %(instance_name)s as %(vm_ref)s." +msgstr "VM %(instance_name)s criada como %(vm_ref)s." + +#: ../nova/virt/xenapi/vm_utils.py:168 +#, python-format +msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... " +msgstr "Criando VBD para VM %(vm_ref)s, VDI %(vdi_ref)s ... " + +#: ../nova/virt/xenapi/vm_utils.py:171 +#, python-format +msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s." +msgstr "VBD %(vbd_ref)s criado para VM %(vm_ref)s, VDI %(vdi_ref)s." + +#: ../nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "VBD not found in instance %s" +msgstr "O VBD não foi encontrado na instância %s" + +#: ../nova/virt/xenapi/vm_utils.py:197 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "Não é possível desconectar o VBD %s" + +#: ../nova/virt/xenapi/vm_utils.py:209 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "Não é possível destruir o VBD %s" + +#: ../nova/virt/xenapi/vm_utils.py:224 +#, python-format +msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s." +msgstr "Criando a VIF para VM %(vm_ref)s, rede %(network_ref)s." + +#: ../nova/virt/xenapi/vm_utils.py:227 +#, python-format +msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s." +msgstr "VIF %(vif_ref)s criada para VM %(vm_ref)s, rede %(network_ref)s." + +#: ../nova/virt/xenapi/vm_utils.py:246 +#, python-format +msgid "" +"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on " +"%(sr_ref)s." +msgstr "" +"VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) no SR " +"%(sr_ref)s criada com sucesso." + +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vm_utils.py:258 +#, python-format +msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..." +msgstr "Fazendo um snapshot da VM %(vm_ref)s com rótulo '%(label)s'..." + +#: ../nova/virt/xenapi/vm_utils.py:272 +#, python-format +msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s." +msgstr "Snapshot %(template_vm_ref)s criado a partir da VM %(vm_ref)s." + +#: ../nova/virt/xenapi/vm_utils.py:286 +#, python-format +msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s" +msgstr "" +"Solicitando à xapi para realizar upload da imagem %(vdi_uuids)s com ID " +"%(image_id)s" + +#: ../nova/virt/xenapi/vm_utils.py:327 +#, python-format +msgid "Size for image %(image)s:%(virtual_size)d" +msgstr "Tamanho da imagem %(image)s:%(virtual_size)d" + +#: ../nova/virt/xenapi/vm_utils.py:332 +#, 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:342 +#, python-format +msgid "Copying VDI %s to /boot/guest on dom0" +msgstr "Copiando o VDI %s de /boot/guest no dom0" + +#: ../nova/virt/xenapi/vm_utils.py:352 +#, python-format +msgid "Kernel/Ramdisk VDI %s destroyed" +msgstr "Kernel/Ramdisk %s destruidos" + +#: ../nova/virt/xenapi/vm_utils.py:361 +#, python-format +msgid "Asking xapi to fetch %(url)s as %(access)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "Verificando o vdi %s para kernel PV" + +#: ../nova/virt/xenapi/vm_utils.py:397 +#, python-format +msgid "PV Kernel in VDI:%s" +msgstr "Kernel PV no VDI: %s" + +#: ../nova/virt/xenapi/vm_utils.py:405 +#, python-format +msgid "Running pygrub against %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:411 +#, python-format +msgid "Found Xen kernel %s" +msgstr "Kernel Xen encontrado: %s" + +#: ../nova/virt/xenapi/vm_utils.py:413 +msgid "No Xen kernel found. Booting HVM." +msgstr "Kernel Xen não encontrado. Iniciando como HVM." + +#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431 +#, python-format +msgid "duplicate name found: %s" +msgstr "nome duplicado encontrado: %s" + +#: ../nova/virt/xenapi/vm_utils.py:442 +#, python-format +msgid "VDI %s is still available" +msgstr "O VDI %s continua disponível" + +#: ../nova/virt/xenapi/vm_utils.py:463 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "(VM_UTILS) xenserver vm state -> |%s|" + +#: ../nova/virt/xenapi/vm_utils.py:465 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "(VM_UTILS) xenapi power_state -> |%s|" + +#: ../nova/virt/xenapi/vm_utils.py:525 +#, python-format +msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:542 +#, python-format +msgid "Re-scanning SR %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:567 +#, python-format +msgid "" +"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:574 +#, 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:590 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:594 +#, python-format +msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:653 +#: ../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:655 +#: ../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:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192 +#, python-format +msgid "Plugging VBD %s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:659 +#: ../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:661 +#, python-format +msgid "VBD %(vbd)s plugged as %(orig_dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:664 +#, python-format +msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:668 +#: ../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:671 +#: ../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:683 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211 +msgid "VBD.unplug successful first time." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:688 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216 +msgid "VBD.unplug rejected: retrying..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:692 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220 +msgid "VBD.unplug successful eventually." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:695 +#: ../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:704 +#: ../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:735 +#, python-format +msgid "" +"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:747 +#, 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:592 +msgid "No fixed ips defined" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:608 +#, python-format +msgid "No floating ip for address %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:629 +#, python-format +msgid "No address for instance %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:961 +#, python-format +msgid "no keypair for user %(user_id)s, name %(name)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156 +#, python-format +msgid "No network for id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1086 +msgid "No networks defined" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1115 +#, python-format +msgid "No network for bridge %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142 +#, python-format +msgid "No network for instance %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1277 +#, python-format +msgid "Token %s does not exist" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1302 +#, python-format +msgid "No quota for project_id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501 +#: ../nova/api/ec2/__init__.py:323 +#, python-format +msgid "Volume %s not found" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1514 +#, python-format +msgid "No export device found for volume %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1527 +#, python-format +msgid "No target id found for volume %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1572 +#, python-format +msgid "No security group with id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1589 +#, python-format +msgid "No security group named %(group_name)s for project: %(project_id)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1682 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1756 +#, python-format +msgid "No user for id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1772 +#, python-format +msgid "No user for access key %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1834 +#, python-format +msgid "No project with id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1979 +#, python-format +msgid "No console pool with id %(pool_id)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1996 +#, 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:2035 +#, python-format +msgid "No console for instance %(instance_id)s in pool %(pool_id)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:2057 +#, python-format +msgid "on instance %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:2058 +#, python-format +msgid "No console with id %(console_id)s %(idesc)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097 +#, python-format +msgid "No zone with id %(zone_id)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:186 +#, python-format +msgid "instance %s: failed to boot" +msgstr "" -#: nova/api/ec2/__init__.py:142 +#: ../nova/virt/libvirt_conn.py:436 #, python-format -msgid "" -"Access key %s has had %d failed authentications and will be locked out for " -"%d minutes." +msgid "virsh said: %r" 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/virt/libvirt_conn.py:440 +msgid "cool, it's a device" +msgstr "" -#: nova/api/ec2/__init__.py:190 +#: ../nova/virt/libvirt_conn.py:448 #, python-format -msgid "Authenticated Request For %s:%s)" -msgstr "Pedido de Autenticação Para: %s:%s" +msgid "data: %(data)r, fpath: %(fpath)r" +msgstr "" -#: nova/api/ec2/__init__.py:227 +#: ../nova/virt/libvirt_conn.py:456 #, python-format -msgid "action: %s" -msgstr "ação: %s" +msgid "Contents of file %(fpath)s: %(contents)r" +msgstr "" -#: nova/api/ec2/__init__.py:229 -#, python-format -msgid "arg: %s\t\tval: %s" -msgstr "argumento: %s\t\tvalor: %s" +#: ../nova/virt/libvirt_conn.py:489 +msgid "Unable to find an open port" +msgstr "" -#: nova/api/ec2/__init__.py:301 +#: ../nova/virt/libvirt_conn.py:563 #, python-format -msgid "Unauthorized request for controller=%s and action=%s" -msgstr "Requisição não autorizada para controlador=%s e ação=%s" +msgid "instance %s: Creating image" +msgstr "" -#: nova/api/ec2/__init__.py:339 +#: ../nova/virt/libvirt_conn.py:646 #, python-format -msgid "NotFound raised: %s" -msgstr "NotFound lançado: %s" +msgid "instance %(inst_name)s: injecting key into image %(img_id)s" +msgstr "" -#: nova/api/ec2/__init__.py:342 +#: ../nova/virt/libvirt_conn.py:649 #, python-format -msgid "ApiError raised: %s" -msgstr "ApiError lançado: %s" +msgid "instance %(inst_name)s: injecting net into image %(img_id)s" +msgstr "" -#: nova/api/ec2/__init__.py:349 +#. This could be a windows image, or a vmdk format disk +#: ../nova/virt/libvirt_conn.py:657 #, 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." +msgid "" +"instance %(inst_name)s: ignoring error injecting data into image %(img_id)s " +"(%(e)s)" msgstr "" -"Ocorreu um erro desconhecido. Por favor tente sua requisição novamente." -#: nova/api/ec2/admin.py:84 +#. TODO(termie): cache? +#: ../nova/virt/libvirt_conn.py:665 #, python-format -msgid "Creating new user: %s" -msgstr "Criando novo usuário: %s" +msgid "instance %s: starting toXML method" +msgstr "" -#: nova/api/ec2/admin.py:92 +#: ../nova/virt/libvirt_conn.py:732 #, python-format -msgid "Deleting user: %s" -msgstr "Excluindo usuário: %s" +msgid "instance %s: finished toXML method" +msgstr "" -#: 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/virt/libvirt_conn.py:751 +msgid "diagnostics are not supported for libvirt" +msgstr "" -#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#: ../nova/virt/libvirt_conn.py:1225 #, python-format -msgid "Adding sitewide role %s to user %s" -msgstr "Adicionando papel em todo site %s ao usuário %s" +msgid "Attempted to unfilter instance %s which is not filtered" +msgstr "" -#: nova/api/ec2/admin.py:122 +#: ../nova/api/ec2/metadatarequesthandler.py:76 #, python-format -msgid "Removing role %s from user %s for project %s" -msgstr "Removendo papel %s do usuário %s para o projeto %s" +msgid "Failed to get metadata for ip: %s" +msgstr "Falha ao obter metadados para o ip: %s" -#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#: ../nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "Tentativa de instanciar singleton" + +#: ../nova/network/api.py:39 #, python-format -msgid "Removing sitewide role %s from user %s" -msgstr "Removendo papel %s em todo site do usuário %s" +msgid "Quota exceeeded for %s, tried to allocate address" +msgstr "" -#: 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/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" +msgstr "" -#: nova/api/ec2/admin.py:142 +#: ../nova/tests/test_volume.py:162 #, python-format -msgid "Getting x509 for user: %s on project: %s" -msgstr "Obtendo x509 para usuário: %s do projeto: %s" +msgid "Target %s allocated" +msgstr "" -#: nova/api/ec2/admin.py:159 +#: ../nova/virt/images.py:70 #, python-format -msgid "Create project %s managed by %s" -msgstr "Criar projeto %s gerenciado por %s" +msgid "Finished retreving %(url)s -- placed in %(path)s" +msgstr "" -#: nova/api/ec2/admin.py:170 -#, python-format -msgid "Delete project: %s" -msgstr "Excluir projeto: %s" +#: ../nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "" -#: 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/console/manager.py:70 +msgid "Adding console" +msgstr "" -#: nova/api/ec2/admin.py:188 +#: ../nova/console/manager.py:90 #, python-format -msgid "Removing user %s from project %s" -msgstr "Excluindo usuário %s do projeto %s" +msgid "Tried to remove non-existant console %(console_id)s." +msgstr "" -#: nova/api/ec2/apirequest.py:95 +#: ../nova/api/direct.py:149 +msgid "not available" +msgstr "" + +#: ../nova/api/ec2/cloud.py:62 #, python-format -msgid "Unsupported API request: controller = %s,action = %s" -msgstr "Requisição de API não suportada: controlador = %s,ação = %s" +msgid "The key_pair %s already exists" +msgstr "" -#: nova/api/ec2/cloud.py:117 +#. TODO(vish): Do this with M2Crypto instead +#: ../nova/api/ec2/cloud.py:118 #, python-format msgid "Generating root CA: %s" msgstr "Gerando CA raiz: %s" -#: nova/api/ec2/cloud.py:277 +#: ../nova/api/ec2/cloud.py:303 #, python-format msgid "Create key pair %s" msgstr "Criar par de chaves %s" -#: nova/api/ec2/cloud.py:285 +#: ../nova/api/ec2/cloud.py:311 #, python-format msgid "Delete key pair %s" msgstr "Remover par de chaves %s" -#: nova/api/ec2/cloud.py:357 +#: ../nova/api/ec2/cloud.py:386 #, python-format msgid "%s is not a valid ipProtocol" msgstr "%s não é um ipProtocol válido" -#: nova/api/ec2/cloud.py:361 +#: ../nova/api/ec2/cloud.py:390 msgid "Invalid port range" msgstr "Intervalo de porta inválido" -#: nova/api/ec2/cloud.py:392 +#: ../nova/api/ec2/cloud.py:421 #, 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 +#: ../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:443 msgid "No rule for the specified parameters." msgstr "Não existe regra para os parâmetros especificados" -#: nova/api/ec2/cloud.py:421 +#: ../nova/api/ec2/cloud.py:450 #, python-format msgid "Authorize security group ingress %s" msgstr "Autorizada entrada do grupo de segurança %s" -#: nova/api/ec2/cloud.py:432 +#: ../nova/api/ec2/cloud.py:464 #, python-format msgid "This rule already exists in group %s" msgstr "Esta regra já existe no grupo %s" -#: nova/api/ec2/cloud.py:460 +#: ../nova/api/ec2/cloud.py:492 #, python-format msgid "Create Security Group %s" msgstr "Criar Grupo de Segurança %s" -#: nova/api/ec2/cloud.py:463 +#: ../nova/api/ec2/cloud.py:495 #, python-format msgid "group %s already exists" msgstr "group %s já existe" -#: nova/api/ec2/cloud.py:475 +#: ../nova/api/ec2/cloud.py:507 #, 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 +#: ../nova/api/ec2/cloud.py:584 #, python-format msgid "Create volume of %s GB" msgstr "Criar volume de %s GB" -#: nova/api/ec2/cloud.py:567 +#: ../nova/api/ec2/cloud.py:612 #, python-format -msgid "Attach volume %s to instacne %s at %s" -msgstr "Anexar volume %s para instância %s em %s" +msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s" +msgstr "" -#: nova/api/ec2/cloud.py:579 +#: ../nova/api/ec2/cloud.py:629 #, python-format msgid "Detach volume %s" msgstr "Desanexar volume %s" -#: nova/api/ec2/cloud.py:686 +#: ../nova/api/ec2/cloud.py:761 msgid "Allocate address" msgstr "Alocar endereço" -#: nova/api/ec2/cloud.py:691 +#: ../nova/api/ec2/cloud.py:766 #, python-format msgid "Release address %s" msgstr "Liberar endereço %s" -#: nova/api/ec2/cloud.py:696 +#: ../nova/api/ec2/cloud.py:771 #, python-format -msgid "Associate address %s to instance %s" -msgstr "Atribuir endereço %s à instância %s" +msgid "Associate address %(public_ip)s to instance %(instance_id)s" +msgstr "" -#: nova/api/ec2/cloud.py:703 +#: ../nova/api/ec2/cloud.py:780 #, python-format msgid "Disassociate address %s" msgstr "Desatribuir endereço %s" -#: nova/api/ec2/cloud.py:730 +#: ../nova/api/ec2/cloud.py:807 msgid "Going to start terminating instances" msgstr "Começando a terminar instâncias" -#: nova/api/ec2/cloud.py:738 +#: ../nova/api/ec2/cloud.py:815 #, python-format msgid "Reboot instance %r" msgstr "Reiniciar instância %r" -#: nova/api/ec2/cloud.py:775 +#: ../nova/api/ec2/cloud.py:867 #, python-format msgid "De-registering image %s" msgstr "Removendo o registro da imagem %s" -#: nova/api/ec2/cloud.py:783 +#: ../nova/api/ec2/cloud.py:875 #, python-format -msgid "Registered image %s with id %s" -msgstr "Registrada imagem %s com id %s" +msgid "Registered image %(image_location)s with id %(image_id)s" +msgstr "" -#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900 #, python-format msgid "attribute not supported: %s" msgstr "atributo não suportado: %s" -#: nova/api/ec2/cloud.py:794 +#: ../nova/api/ec2/cloud.py:890 #, python-format msgid "invalid id: %s" msgstr "id inválido: %s" -#: nova/api/ec2/cloud.py:807 +#: ../nova/api/ec2/cloud.py:903 msgid "user or group not specified" msgstr "usuário ou grupo não especificado" -#: nova/api/ec2/cloud.py:809 +#: ../nova/api/ec2/cloud.py:905 msgid "only group \"all\" is supported" msgstr "apenas o grupo \"all\" é suportado" -#: nova/api/ec2/cloud.py:811 +#: ../nova/api/ec2/cloud.py:907 msgid "operation_type must be add or remove" msgstr "operation_type deve ser add ou remove" -#: nova/api/ec2/cloud.py:812 +#: ../nova/api/ec2/cloud.py:908 #, 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 +#: ../bin/nova-api.py:52 #, 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" +msgid "Using paste.deploy config at: %s" +msgstr "" -#: nova/auth/ldapdriver.py:478 +#: ../bin/nova-api.py:57 #, python-format -msgid "User %s is already a member of the group %s" -msgstr "Usuário %s já pertence ao grupo %s" +msgid "No paste configuration for app: %s" +msgstr "" -#: nova/auth/ldapdriver.py:507 +#: ../bin/nova-api.py:59 #, python-format msgid "" -"Attempted to remove the last member of a group. Deleting the group at %s " -"instead." +"App Config: %(api)s\n" +"%(config)r" 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 +#: ../bin/nova-api.py:64 #, python-format -msgid "Using project name = user name (%s)" -msgstr "Usando nome do projeto = nome do usuário (%s)" +msgid "Running %s API" +msgstr "" -#: nova/auth/manager.py:275 +#: ../bin/nova-api.py:69 #, python-format -msgid "failed authorization: no project named %s (user=%s)" -msgstr "falha de autorização: nenhum projeto de nome %s (usuário=%s)" +msgid "No known API applications configured in %s." +msgstr "" -#: nova/auth/manager.py:277 +#: ../bin/nova-api.py:83 #, python-format -msgid "No project called %s could be found" -msgstr "Nenhum projeto chamado %s pode ser encontrado." +msgid "Starting nova-api node (version %s)" +msgstr "" -#: nova/auth/manager.py:281 +#: ../bin/nova-api.py:89 #, python-format -msgid "Failed authorization: user %s not admin and not member of project %s" +msgid "No paste configuration found for: %s" msgstr "" -"Falha de autorização: usuário %s não é administrador nem membro do projeto %s" -#: nova/auth/manager.py:283 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84 #, python-format -msgid "User %s is not a member of project %s" -msgstr "Usuário %s não é membro do projeto %s" +msgid "Argument %(key)s value %(value)s is too short." +msgstr "" -#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89 #, 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" +msgid "Argument %(key)s value %(value)s contains invalid characters." +msgstr "" -#: nova/auth/manager.py:408 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94 #, python-format -msgid "The %s role can not be found" -msgstr "O papel %s não foi encontrado" +msgid "Argument %(key)s value %(value)s starts with a hyphen." +msgstr "" -#: nova/auth/manager.py:410 +#: ../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 "The %s role is global only" -msgstr "O papel %s é apenas global" +msgid "Argument %s is required." +msgstr "" -#: nova/auth/manager.py:412 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117 #, python-format -msgid "Adding role %s to user %s in project %s" -msgstr "Adicionando papel %s ao usuário %s no projeto %s" +msgid "" +"Argument %(key)s may not take value %(value)s. Valid values are ['true', " +"'false']." +msgstr "" -#: nova/auth/manager.py:438 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:163 #, python-format -msgid "Removing role %s from user %s on project %s" -msgstr "Removendo papel %s do usuário %s no projeto %s" +msgid "" +"Created VDI %(vdi_ref)s (%(label)s, %(size)s, %(read_only)s) on %(sr_ref)s." +msgstr "" -#: nova/auth/manager.py:505 +#: ../nova/virt/xenapi/vmops.py:67 #, python-format -msgid "Created project %s with manager %s" -msgstr "Criado projeto %s com gerente %s" +msgid "Attempted to create non-unique name %s" +msgstr "" -#: nova/auth/manager.py:523 +#: ../nova/virt/xenapi/vmops.py:73 #, python-format -msgid "modifying project %s" -msgstr "modificando projeto %s" +msgid "instance %(name)s: not enough free memory" +msgstr "" -#: nova/auth/manager.py:553 +#: ../nova/virt/xenapi/vmops.py:148 #, python-format -msgid "Remove user %s from project %s" -msgstr "Remover usuário %s do projeto %s" +msgid "Starting VM %s..." +msgstr "" -#: nova/auth/manager.py:581 +#: ../nova/virt/xenapi/vmops.py:151 #, python-format -msgid "Deleting project %s" -msgstr "Excluindo projeto %s" +msgid "Spawning VM %(instance_name)s created %(vm_ref)s." +msgstr "" -#: nova/auth/manager.py:637 +#: ../nova/virt/xenapi/vmops.py:162 #, python-format -msgid "Created user %s (admin: %r)" -msgstr "Criado usuário %s (administrador: %r)" +msgid "Invalid value for onset_files: '%s'" +msgstr "" -#: nova/auth/manager.py:645 +#: ../nova/virt/xenapi/vmops.py:167 #, python-format -msgid "Deleting user %s" -msgstr "Apagando usuário %s" +msgid "Injecting file path: '%s'" +msgstr "" -#: nova/auth/manager.py:655 +#: ../nova/virt/xenapi/vmops.py:180 #, python-format -msgid "Access Key change for user %s" +msgid "Instance %s: booted" msgstr "" -#: nova/auth/manager.py:657 +#: ../nova/virt/xenapi/vmops.py:232 #, python-format -msgid "Secret Key change for user %s" +msgid "Instance not present %s" msgstr "" -#: nova/auth/manager.py:659 +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vmops.py:261 #, python-format -msgid "Admin status set to %r for user %s" +msgid "Starting snapshot for VM %s" msgstr "" -#: nova/auth/manager.py:708 +#: ../nova/virt/xenapi/vmops.py:269 #, python-format -msgid "No vpn data for project %s" +msgid "Unable to Snapshot %(vm_ref)s: %(exc)s" msgstr "" -#: nova/cloudpipe/pipelib.py:45 -msgid "Template for script to run on cloudpipe instance boot" +#: ../nova/virt/xenapi/vmops.py:280 +#, python-format +msgid "Finished snapshot and upload for VM %s" msgstr "" -#: nova/cloudpipe/pipelib.py:48 -msgid "Network to push into openvpn config" +#: ../nova/virt/xenapi/vmops.py:356 +#, python-format +msgid "VM %(vm)s already halted, skipping shutdown..." msgstr "" -#: nova/cloudpipe/pipelib.py:51 -msgid "Netmask to push into openvpn config" +#: ../nova/virt/xenapi/vmops.py:389 +msgid "Removing kernel/ramdisk files" msgstr "" -#: nova/cloudpipe/pipelib.py:97 -#, python-format -msgid "Launching VPN for %s" -msgstr "Executando VPN para %s" - -#: nova/compute/api.py:67 -#, python-format -msgid "Instance %d was not found in get_network_topic" +#: ../nova/virt/xenapi/vmops.py:399 +msgid "kernel/ramdisk files removed" msgstr "" -#: nova/compute/api.py:73 +#: ../nova/virt/xenapi/vmops.py:561 #, python-format -msgid "Instance %d has no host" +msgid "" +"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/api.py:92 +#: ../nova/virt/xenapi/vmops.py:564 #, python-format -msgid "Quota exceeeded for %s, tried to run %s instances" +msgid "" +"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM " +"id=%(instance_id)s; args=%(strargs)s" msgstr "" -#: nova/compute/api.py:94 +#: ../nova/virt/xenapi/vmops.py:569 #, python-format msgid "" -"Instance quota exceeded. You can only run %s more instances of this type." +"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/api.py:109 -msgid "Creating a raw instance" +#: ../nova/virt/xenapi/vmops.py:760 +#, python-format +msgid "OpenSSL error: %s" msgstr "" -#: nova/compute/api.py:156 +#: ../nova/tests/test_compute.py:148 #, python-format -msgid "Going to run %s instances..." +msgid "Running instances: %s" msgstr "" -#: nova/compute/api.py:180 +#: ../nova/tests/test_compute.py:154 #, python-format -msgid "Casting to scheduler for %s/%s's instance %s" +msgid "After terminating instances: %s" msgstr "" -#: nova/compute/api.py:279 -#, python-format -msgid "Going to try and terminate %s" +#: ../nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" msgstr "" -#: nova/compute/api.py:283 -#, python-format -msgid "Instance %d was not found during terminate" +#: ../nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" msgstr "" -#: nova/compute/api.py:288 -#, python-format -msgid "Instance %d is already being terminated" +#: ../nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" msgstr "" -#: nova/compute/api.py:450 +#: ../nova/cloudpipe/pipelib.py:97 #, python-format -msgid "Invalid device specified: %s. Example device: /dev/vdb" -msgstr "" +msgid "Launching VPN for %s" +msgstr "Executando VPN para %s" -#: nova/compute/api.py:465 -msgid "Volume isn't attached to anything!" +#: ../nova/db/sqlalchemy/migration.py:35 +msgid "python-migrate is not installed. Exiting." msgstr "" -#: nova/compute/disk.py:71 +#: ../nova/image/s3.py:99 #, python-format -msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgid "Image %s could not be found" msgstr "" -#: nova/compute/disk.py:75 +#: ../nova/api/ec2/__init__.py:121 +msgid "Too many failed authentications." +msgstr "Muitas falhas de autenticação." + +#: ../nova/api/ec2/__init__.py:131 #, python-format -msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgid "" +"Access key %(access_key)s has had %(failures)d failed authentications and " +"will be locked out for %(lock_mins)d minutes." msgstr "" -#: nova/compute/disk.py:128 +#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140 #, python-format -msgid "Could not attach image to loopback: %s" -msgstr "" +msgid "Authentication Failure: %s" +msgstr "Falha de Autenticação: %s" -#: nova/compute/disk.py:136 +#: ../nova/api/ec2/__init__.py:182 #, python-format -msgid "Failed to load partition: %s" +msgid "Authenticated Request For %(uname)s:%(pname)s)" msgstr "" -#: nova/compute/disk.py:158 +#: ../nova/api/ec2/__init__.py:207 #, python-format -msgid "Failed to mount filesystem: %s" -msgstr "" +msgid "action: %s" +msgstr "ação: %s" -#: nova/compute/instance_types.py:41 +#: ../nova/api/ec2/__init__.py:209 #, python-format -msgid "Unknown instance type: %s" +msgid "arg: %(key)s\t\tval: %(value)s" msgstr "" -#: nova/compute/manager.py:69 +#: ../nova/api/ec2/__init__.py:281 #, python-format -msgid "check_instance_lock: decorating: |%s|" +msgid "" +"Unauthorized request for controller=%(controller)s and action=%(action)s" msgstr "" -#: nova/compute/manager.py:71 +#: ../nova/api/ec2/__init__.py:314 #, python-format -msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgid "InstanceNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:75 +#: ../nova/api/ec2/__init__.py:320 #, python-format -msgid "check_instance_lock: locked: |%s|" +msgid "VolumeNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:77 +#: ../nova/api/ec2/__init__.py:326 #, python-format -msgid "check_instance_lock: admin: |%s|" -msgstr "" +msgid "NotFound raised: %s" +msgstr "NotFound lançado: %s" -#: nova/compute/manager.py:82 +#: ../nova/api/ec2/__init__.py:329 #, python-format -msgid "check_instance_lock: executing: |%s|" -msgstr "" +msgid "ApiError raised: %s" +msgstr "ApiError lançado: %s" -#: nova/compute/manager.py:86 +#: ../nova/api/ec2/__init__.py:338 #, python-format -msgid "check_instance_lock: not executing |%s|" -msgstr "" +msgid "Unexpected error raised: %s" +msgstr "Erro inexperado lançado: %s" -#: nova/compute/manager.py:157 -msgid "Instance has already been created" +#: ../nova/api/ec2/__init__.py:343 +msgid "An unknown error has occurred. Please try your request again." msgstr "" +"Ocorreu um erro desconhecido. Por favor tente sua requisição novamente." -#: nova/compute/manager.py:158 +#: ../nova/auth/dbdriver.py:84 #, python-format -msgid "instance %s: starting..." -msgstr "" +msgid "User %s already exists" +msgstr "Usuário %s já existe" -#: nova/compute/manager.py:197 +#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232 #, python-format -msgid "instance %s: Failed to spawn" -msgstr "" +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/compute/manager.py:211 nova/tests/test_cloud.py:228 +#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243 #, python-format -msgid "Terminating instance %s" -msgstr "" +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/compute/manager.py:217 +#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229 #, python-format -msgid "Disassociating address %s" -msgstr "" +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/compute/manager.py:230 +#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268 #, python-format -msgid "Deallocating address %s" -msgstr "" +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/compute/manager.py:243 +#: ../nova/auth/dbdriver.py:245 #, python-format -msgid "trying to destroy already destroyed instance: %s" -msgstr "" +msgid "User \"%s\" not found" +msgstr "Usuário \"%s\" não encontrado" -#: nova/compute/manager.py:257 +#: ../nova/auth/dbdriver.py:248 #, python-format -msgid "Rebooting instance %s" -msgstr "" +msgid "Project \"%s\" not found" +msgstr "Projeto \"%s\" não encontrado" -#: nova/compute/manager.py:260 -#, python-format -msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +#: ../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/compute/manager.py:286 +#: ../nova/virt/xenapi_conn.py:311 #, python-format -msgid "instance %s: snapshotting" +msgid "Task [%(name)s] %(task)s status: success %(result)s" msgstr "" -#: nova/compute/manager.py:289 +#: ../nova/virt/xenapi_conn.py:317 #, python-format -msgid "" -"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s" msgstr "" -#: nova/compute/manager.py:301 +#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344 #, python-format -msgid "instance %s: rescuing" +msgid "Got exception: %s" msgstr "" -#: nova/compute/manager.py:316 +#: ../nova/compute/monitor.py:259 #, python-format -msgid "instance %s: unrescuing" +msgid "updating %s..." msgstr "" -#: nova/compute/manager.py:335 -#, python-format -msgid "instance %s: pausing" +#: ../nova/compute/monitor.py:289 +msgid "unexpected error during update" msgstr "" -#: nova/compute/manager.py:352 +#: ../nova/compute/monitor.py:356 #, python-format -msgid "instance %s: unpausing" +msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/manager.py:369 +#: ../nova/compute/monitor.py:379 #, python-format -msgid "instance %s: retrieving diagnostics" +msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/manager.py:382 -#, python-format -msgid "instance %s: suspending" +#: ../nova/compute/monitor.py:414 +msgid "unexpected exception getting connection" msgstr "" -#: nova/compute/manager.py:401 +#: ../nova/compute/monitor.py:429 #, python-format -msgid "instance %s: resuming" +msgid "Found instance: %s" msgstr "" -#: nova/compute/manager.py:420 +#: ../nova/volume/san.py:67 #, python-format -msgid "instance %s: locking" +msgid "Could not find iSCSI export for volume %s" msgstr "" -#: nova/compute/manager.py:432 +#: ../nova/api/ec2/apirequest.py:100 #, python-format -msgid "instance %s: unlocking" +msgid "" +"Unsupported API request: controller = %(controller)s, action = %(action)s" msgstr "" -#: nova/compute/manager.py:442 +#: ../nova/api/openstack/__init__.py:55 #, python-format -msgid "instance %s: getting locked state" +msgid "Caught error: %s" +msgstr "Capturado o erro: %s" + +#: ../nova/api/openstack/__init__.py:76 +msgid "Including admin operations in API." +msgstr "Incluindo operações administrativas na API." + +#: ../nova/console/xvp.py:99 +msgid "Rebuilding xvp conf" msgstr "" -#: nova/compute/manager.py:462 +#: ../nova/console/xvp.py:116 #, python-format -msgid "instance %s: attaching volume %s to %s" +msgid "Re-wrote %s" msgstr "" -#: nova/compute/manager.py:478 -#, python-format -msgid "instance %s: attach failed %s, removing" +#: ../nova/console/xvp.py:121 +msgid "Stopping xvp" msgstr "" -#: nova/compute/manager.py:493 -#, python-format -msgid "Detach volume %s from mountpoint %s on instance %s" +#: ../nova/console/xvp.py:134 +msgid "Starting xvp" msgstr "" -#: nova/compute/manager.py:497 +#: ../nova/console/xvp.py:141 #, python-format -msgid "Detaching volume from unknown instance %s" +msgid "Error starting xvp: %s" msgstr "" -#: nova/compute/monitor.py:259 -#, python-format -msgid "updating %s..." +#: ../nova/console/xvp.py:144 +msgid "Restarting xvp" msgstr "" -#: nova/compute/monitor.py:289 -msgid "unexpected error during update" +#: ../nova/console/xvp.py:146 +msgid "xvp not running..." msgstr "" -#: nova/compute/monitor.py:355 -#, python-format -msgid "Cannot get blockstats for \"%s\" on \"%s\"" +#: ../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 "" -#: nova/compute/monitor.py:377 -#, python-format -msgid "Cannot get ifstats for \"%s\" on \"%s\"" +#: ../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 "" -#: nova/compute/monitor.py:412 -msgid "unexpected exception getting connection" +#: ../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/compute/monitor.py:427 -#, python-format -msgid "Found instance: %s" +#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536 +msgid "network" msgstr "" -#: nova/db/sqlalchemy/api.py:43 -msgid "Use of empty request context is deprecated" +#: ../bin/nova-manage.py:448 +msgid "IP address" msgstr "" -#: nova/db/sqlalchemy/api.py:132 -#, python-format -msgid "No service for id %s" +#: ../bin/nova-manage.py:449 +msgid "MAC address" msgstr "" -#: nova/db/sqlalchemy/api.py:229 -#, python-format -msgid "No service for %s, %s" +#: ../bin/nova-manage.py:450 +msgid "hostname" msgstr "" -#: nova/db/sqlalchemy/api.py:574 -#, python-format -msgid "No floating ip for address %s" +#: ../bin/nova-manage.py:451 +msgid "host" msgstr "" -#: nova/db/sqlalchemy/api.py:668 -#, python-format -msgid "No instance for id %s" +#: ../bin/nova-manage.py:537 +msgid "netmask" 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" +#: ../bin/nova-manage.py:538 +msgid "start address" msgstr "" -#: nova/db/sqlalchemy/api.py:891 +#: ../nova/virt/disk.py:69 #, python-format -msgid "no keypair for user %s, name %s" +msgid "Failed to load partition: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#: ../nova/virt/disk.py:91 #, python-format -msgid "No network for id %s" +msgid "Failed to mount filesystem: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1036 +#: ../nova/virt/disk.py:124 #, python-format -msgid "No network for bridge %s" +msgid "nbd device %s did not show up" msgstr "" -#: nova/db/sqlalchemy/api.py:1050 +#: ../nova/virt/disk.py:128 #, python-format -msgid "No network for instance %s" +msgid "Could not attach image to loopback: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1180 -#, python-format -msgid "Token %s does not exist" +#: ../nova/virt/disk.py:151 +msgid "No free nbd devices" msgstr "" -#: nova/db/sqlalchemy/api.py:1205 +#: ../doc/ext/nova_todo.py:46 #, python-format -msgid "No quota for project_id %s" +msgid "%(filename)s, line %(line_info)d" msgstr "" -#: nova/db/sqlalchemy/api.py:1356 -#, python-format -msgid "No volume for id %s" +#. FIXME(chiradeep): implement this +#: ../nova/virt/hyperv.py:118 +msgid "In init host" msgstr "" -#: nova/db/sqlalchemy/api.py:1401 +#: ../nova/virt/hyperv.py:131 #, python-format -msgid "Volume %s not found" +msgid "Attempt to create duplicate vm %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1413 +#: ../nova/virt/hyperv.py:148 #, python-format -msgid "No export device found for volume %s" +msgid "Starting VM %s " msgstr "" -#: nova/db/sqlalchemy/api.py:1426 +#: ../nova/virt/hyperv.py:150 #, python-format -msgid "No target id found for volume %s" +msgid "Started VM %s " msgstr "" -#: nova/db/sqlalchemy/api.py:1471 +#: ../nova/virt/hyperv.py:152 #, python-format -msgid "No security group with id %s" +msgid "spawn vm failed: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1488 +#: ../nova/virt/hyperv.py:169 #, python-format -msgid "No security group named %s for project: %s" +msgid "Failed to create VM %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1576 +#: ../nova/virt/hyperv.py:188 #, python-format -msgid "No secuity group rule with id %s" +msgid "Set memory for vm %s..." msgstr "" -#: nova/db/sqlalchemy/api.py:1650 +#: ../nova/virt/hyperv.py:198 #, python-format -msgid "No user for id %s" +msgid "Set vcpus for vm %s..." msgstr "" -#: nova/db/sqlalchemy/api.py:1666 +#: ../nova/virt/hyperv.py:202 #, python-format -msgid "No user for access key %s" +msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s" msgstr "" -#: nova/db/sqlalchemy/api.py:1728 +#: ../nova/virt/hyperv.py:227 #, python-format -msgid "No project with id %s" +msgid "Failed to add diskdrive to VM %s" msgstr "" -#: nova/image/glance.py:78 +#: ../nova/virt/hyperv.py:230 #, python-format -msgid "Parallax returned HTTP error %d from request for /images" +msgid "New disk drive path is %s" msgstr "" -#: nova/image/glance.py:97 +#: ../nova/virt/hyperv.py:247 #, python-format -msgid "Parallax returned HTTP error %d from request for /images/detail" +msgid "Failed to add vhd file to VM %s" msgstr "" -#: nova/image/s3.py:82 +#: ../nova/virt/hyperv.py:249 #, python-format -msgid "Image %s could not be found" +msgid "Created disk for %s" msgstr "" -#: nova/network/api.py:39 +#: ../nova/virt/hyperv.py:253 #, python-format -msgid "Quota exceeeded for %s, tried to allocate address" +msgid "Creating nic for %s " msgstr "" -#: nova/network/api.py:42 -msgid "Address quota exceeded. You cannot allocate any more addresses" +#: ../nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" msgstr "" -#: nova/network/linux_net.py:176 +#: ../nova/virt/hyperv.py:273 #, python-format -msgid "Starting VLAN inteface %s" +msgid "Failed creating port for %s" msgstr "" -#: nova/network/linux_net.py:186 +#: ../nova/virt/hyperv.py:276 #, python-format -msgid "Starting Bridge interface for %s" +msgid "Created switch port %(vm_name)s on switch %(ext_path)s" msgstr "" -#: nova/network/linux_net.py:254 +#: ../nova/virt/hyperv.py:286 #, python-format -msgid "Hupping dnsmasq threw %s" +msgid "Failed to add nic to VM %s" msgstr "" -#: nova/network/linux_net.py:256 +#: ../nova/virt/hyperv.py:288 #, python-format -msgid "Pid %d is stale, relaunching dnsmasq" +msgid "Created nic for %s " msgstr "" -#: nova/network/linux_net.py:334 +#: ../nova/virt/hyperv.py:321 #, python-format -msgid "Killing dnsmasq threw %s" +msgid "WMI job failed: %s" msgstr "" -#: nova/network/manager.py:135 -msgid "setting network host" +#: ../nova/virt/hyperv.py:325 +#, python-format +msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s " msgstr "" -#: nova/network/manager.py:190 +#: ../nova/virt/hyperv.py:361 #, python-format -msgid "Leasing IP %s" +msgid "Got request to destroy vm %s" msgstr "" -#: nova/network/manager.py:194 +#: ../nova/virt/hyperv.py:386 #, python-format -msgid "IP %s leased that isn't associated" +msgid "Failed to destroy vm %s" msgstr "" -#: nova/network/manager.py:197 +#: ../nova/virt/hyperv.py:393 #, python-format -msgid "IP %s leased to bad mac %s vs %s" +msgid "Del: disk %(vhdfile)s vm %(instance_name)s" msgstr "" -#: nova/network/manager.py:205 +#: ../nova/virt/hyperv.py:415 #, python-format -msgid "IP %s leased that was already deallocated" +msgid "" +"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, " +"num_cpu=%(numprocs)s, cpu_time=%(uptime)s" msgstr "" -#: nova/network/manager.py:214 +#: ../nova/virt/hyperv.py:451 #, python-format -msgid "IP %s released that isn't associated" +msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/network/manager.py:217 +#: ../nova/virt/hyperv.py:454 #, python-format -msgid "IP %s released from bad mac %s vs %s" +msgid "Failed to change vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/network/manager.py:220 +#: ../nova/compute/api.py:71 #, python-format -msgid "IP %s released that was not leased" +msgid "Instance %d was not found in get_network_topic" msgstr "" -#: nova/network/manager.py:442 +#: ../nova/compute/api.py:77 #, python-format -msgid "Dissassociated %s stale fixed ip(s)" +msgid "Instance %d has no host" msgstr "" -#: nova/objectstore/handler.py:106 +#: ../nova/compute/api.py:97 #, python-format -msgid "Unknown S3 value type %r" +msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances" msgstr "" -#: nova/objectstore/handler.py:137 -msgid "Authenticated request" +#: ../nova/compute/api.py:99 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." msgstr "" -#: nova/objectstore/handler.py:182 -msgid "List of buckets requested" +#: ../nova/compute/api.py:112 +msgid "Creating a raw instance" msgstr "" -#: nova/objectstore/handler.py:209 +#: ../nova/compute/api.py:160 #, python-format -msgid "List keys for bucket %s" +msgid "Going to run %s instances..." msgstr "" -#: nova/objectstore/handler.py:217 +#: ../nova/compute/api.py:187 #, python-format -msgid "Unauthorized attempt to access bucket %s" +msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s" msgstr "" -#: nova/objectstore/handler.py:235 +#: ../nova/compute/api.py:292 #, python-format -msgid "Creating bucket %s" +msgid "Going to try to terminate %s" msgstr "" -#: nova/objectstore/handler.py:245 +#: ../nova/compute/api.py:296 #, python-format -msgid "Deleting bucket %s" +msgid "Instance %d was not found during terminate" msgstr "" -#: nova/objectstore/handler.py:249 +#: ../nova/compute/api.py:301 #, python-format -msgid "Unauthorized attempt to delete bucket %s" +msgid "Instance %d is already being terminated" msgstr "" -#: nova/objectstore/handler.py:271 +#: ../nova/compute/api.py:481 #, python-format -msgid "Getting object: %s / %s" +msgid "Invalid device specified: %s. Example device: /dev/vdb" msgstr "" -#: nova/objectstore/handler.py:274 -#, python-format -msgid "Unauthorized attempt to get object %s from bucket %s" +#: ../nova/compute/api.py:496 +msgid "Volume isn't attached to anything!" msgstr "" -#: nova/objectstore/handler.py:292 +#: ../nova/rpc.py:98 #, python-format -msgid "Putting object: %s / %s" +msgid "" +"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in " +"%(fl_intv)d seconds." msgstr "" -#: nova/objectstore/handler.py:295 +#: ../nova/rpc.py:103 #, python-format -msgid "Unauthorized attempt to upload object %s to bucket %s" +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/objectstore/handler.py:314 -#, python-format -msgid "Deleting object: %s / %s" -msgstr "" +#: ../nova/rpc.py:122 +msgid "Reconnected to queue" +msgstr "Reconectado à fila" + +#: ../nova/rpc.py:129 +msgid "Failed to fetch message from queue" +msgstr "Falha ao obter mensagem da fila" -#: nova/objectstore/handler.py:393 +#: ../nova/rpc.py:159 #, python-format -msgid "Not authorized to upload image: invalid directory %s" -msgstr "" +msgid "Initing the Adapter Consumer for %s" +msgstr "Iniciando o Adaptador Consumidor para %s" -#: nova/objectstore/handler.py:401 +#: ../nova/rpc.py:178 #, python-format -msgid "Not authorized to upload image: unauthorized bucket %s" -msgstr "" +msgid "received %s" +msgstr "recebido %s" -#: nova/objectstore/handler.py:406 +#. 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:191 #, python-format -msgid "Starting image upload: %s" -msgstr "" +msgid "no method for message: %s" +msgstr "sem método para mensagem: %s" -#: nova/objectstore/handler.py:420 +#: ../nova/rpc.py:192 #, python-format -msgid "Not authorized to update attributes of image %s" -msgstr "" +msgid "No method for message: %s" +msgstr "Sem método para mensagem: %s" -#: nova/objectstore/handler.py:428 +#: ../nova/rpc.py:253 #, python-format -msgid "Toggling publicity flag of image %s %r" -msgstr "" +msgid "Returning exception %s to caller" +msgstr "Retornando exceção %s ao método de origem" -#: nova/objectstore/handler.py:433 +#: ../nova/rpc.py:294 #, python-format -msgid "Updating user fields on image %s" -msgstr "" +msgid "unpacked context: %s" +msgstr "conteúdo descompactado: %s" -#: nova/objectstore/handler.py:447 +#: ../nova/rpc.py:313 +msgid "Making asynchronous call..." +msgstr "Fazendo chamada assíncrona..." + +#: ../nova/rpc.py:316 #, python-format -msgid "Unauthorized attempt to delete image %s" +msgid "MSG_ID is %s" +msgstr "MSG_ID é %s" + +#: ../nova/rpc.py:354 +msgid "Making asynchronous cast..." msgstr "" -#: nova/objectstore/handler.py:452 +#: ../nova/rpc.py:364 #, python-format -msgid "Deleted image: %s" -msgstr "" +msgid "response %s" +msgstr "resposta %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/rpc.py:373 +#, python-format +msgid "topic is %s" +msgstr "topico é %s" -#: nova/scheduler/driver.py:66 -msgid "Must implement a fallback schedule" -msgstr "" +#: ../nova/rpc.py:374 +#, python-format +msgid "message %s" +msgstr "mensagem %s" -#: nova/scheduler/manager.py:69 +#: ../nova/volume/driver.py:78 #, python-format -msgid "Casting to %s %s for %s" +msgid "Recovering from a failed execute. Try number %s" msgstr "" -#: nova/scheduler/simple.py:63 -msgid "All hosts have too many cores" +#: ../nova/volume/driver.py:87 +#, python-format +msgid "volume group %s doesn't exist" msgstr "" -#: nova/scheduler/simple.py:95 -msgid "All hosts have too many gigabytes" +#: ../nova/volume/driver.py:220 +#, python-format +msgid "FAKE AOE: %s" msgstr "" -#: nova/scheduler/simple.py:115 -msgid "All hosts have too many networks" +#: ../nova/volume/driver.py:233 +msgid "Skipping ensure_export. No iscsi_target " msgstr "" -#: nova/tests/test_cloud.py:198 -msgid "Can't test instances without a real virtual env." +#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288 +msgid "Skipping remove_export. No iscsi_target " msgstr "" -#: nova/tests/test_cloud.py:210 +#: ../nova/volume/driver.py:347 #, python-format -msgid "Need to watch instance %s until it's running..." +msgid "FAKE ISCSI: %s" msgstr "" -#: nova/tests/test_compute.py:104 +#: ../nova/volume/driver.py:359 #, python-format -msgid "Running instances: %s" +msgid "rbd has no pool %s" msgstr "" -#: nova/tests/test_compute.py:110 +#: ../nova/volume/driver.py:414 #, python-format -msgid "After terminating instances: %s" +msgid "Sheepdog is not working: %s" msgstr "" -#: nova/tests/test_rpc.py:89 -#, python-format -msgid "Nested received %s, %s" +#: ../nova/volume/driver.py:416 +msgid "Sheepdog is not working" msgstr "" -#: nova/tests/test_rpc.py:94 +#: ../nova/wsgi.py:68 #, python-format -msgid "Nested return %s" +msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 -#, python-format -msgid "Received %s" +#: ../nova/wsgi.py:147 +msgid "You must implement __call__" msgstr "" -#: nova/tests/test_volume.py:162 -#, python-format -msgid "Target %s allocated" +#: ../bin/nova-instancemonitor.py:55 +msgid "Starting instance monitor" msgstr "" -#: nova/virt/connection.py:73 -msgid "Failed to open connection to the hypervisor" +#: ../bin/nova-dhcpbridge.py:58 +msgid "leasing ip" msgstr "" -#: nova/virt/fake.py:210 -#, python-format -msgid "Instance %s Not Found" +#: ../bin/nova-dhcpbridge.py:73 +msgid "Adopted old lease or got a change of mac/hostname" msgstr "" -#: nova/virt/hyperv.py:118 -msgid "In init host" +#: ../bin/nova-dhcpbridge.py:80 +msgid "releasing ip" msgstr "" -#: nova/virt/hyperv.py:131 +#: ../bin/nova-dhcpbridge.py:123 #, python-format -msgid "Attempt to create duplicate vm %s" +msgid "" +"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s " +"on interface %(interface)s" msgstr "" -#: nova/virt/hyperv.py:148 +#: ../nova/virt/fake.py:239 #, python-format -msgid "Starting VM %s " +msgid "Instance %s Not Found" msgstr "" -#: nova/virt/hyperv.py:150 +#: ../nova/network/manager.py:153 #, python-format -msgid "Started VM %s " +msgid "Dissassociated %s stale fixed ip(s)" msgstr "" -#: nova/virt/hyperv.py:152 -#, python-format -msgid "spawn vm failed: %s" +#: ../nova/network/manager.py:157 +msgid "setting network host" msgstr "" -#: nova/virt/hyperv.py:169 +#: ../nova/network/manager.py:212 #, python-format -msgid "Failed to create VM %s" +msgid "Leasing IP %s" msgstr "" -#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#: ../nova/network/manager.py:216 #, python-format -msgid "Created VM %s..." +msgid "IP %s leased that isn't associated" msgstr "" -#: nova/virt/hyperv.py:188 +#: ../nova/network/manager.py:220 #, python-format -msgid "Set memory for vm %s..." +msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/hyperv.py:198 +#: ../nova/network/manager.py:228 #, python-format -msgid "Set vcpus for vm %s..." +msgid "IP %s leased that was already deallocated" msgstr "" -#: nova/virt/hyperv.py:202 +#: ../nova/network/manager.py:233 #, python-format -msgid "Creating disk for %s by attaching disk file %s" +msgid "Releasing IP %s" msgstr "" -#: nova/virt/hyperv.py:227 +#: ../nova/network/manager.py:237 #, python-format -msgid "Failed to add diskdrive to VM %s" +msgid "IP %s released that isn't associated" msgstr "" -#: nova/virt/hyperv.py:230 +#: ../nova/network/manager.py:241 #, python-format -msgid "New disk drive path is %s" +msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/hyperv.py:247 +#: ../nova/network/manager.py:244 #, python-format -msgid "Failed to add vhd file to VM %s" +msgid "IP %s released that was not leased" +msgstr "" + +#: ../nova/network/manager.py:519 +msgid "" +"The sum between the number of networks and the vlan start cannot be greater " +"than 4094" msgstr "" -#: nova/virt/hyperv.py:249 +#: ../nova/virt/xenapi/volume_utils.py:57 #, python-format -msgid "Created disk for %s" +msgid "Introducing %s..." msgstr "" -#: nova/virt/hyperv.py:253 +#: ../nova/virt/xenapi/volume_utils.py:74 #, python-format -msgid "Creating nic for %s " +msgid "Introduced %(label)s as %(sr_ref)s." msgstr "" -#: nova/virt/hyperv.py:272 -msgid "Failed creating a port on the external vswitch" +#: ../nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" msgstr "" -#: nova/virt/hyperv.py:273 +#: ../nova/virt/xenapi/volume_utils.py:90 #, python-format -msgid "Failed creating port for %s" +msgid "Unable to find SR from VBD %s" msgstr "" -#: nova/virt/hyperv.py:275 +#: ../nova/virt/xenapi/volume_utils.py:96 #, python-format -msgid "Created switch port %s on switch %s" +msgid "Forgetting SR %s ... " msgstr "" -#: nova/virt/hyperv.py:285 +#: ../nova/virt/xenapi/volume_utils.py:101 #, python-format -msgid "Failed to add nic to VM %s" +msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s" msgstr "" -#: nova/virt/hyperv.py:287 +#: ../nova/virt/xenapi/volume_utils.py:107 #, python-format -msgid "Created nic for %s " +msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s" msgstr "" -#: nova/virt/hyperv.py:320 +#: ../nova/virt/xenapi/volume_utils.py:111 #, python-format -msgid "WMI job failed: %s" +msgid "Forgetting SR %s done." msgstr "" -#: nova/virt/hyperv.py:322 +#: ../nova/virt/xenapi/volume_utils.py:113 #, python-format -msgid "WMI job succeeded: %s, Elapsed=%s " +msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s" msgstr "" -#: nova/virt/hyperv.py:358 +#: ../nova/virt/xenapi/volume_utils.py:123 #, python-format -msgid "Got request to destroy vm %s" +msgid "Unable to introduce VDI on SR %s" msgstr "" -#: nova/virt/hyperv.py:383 +#: ../nova/virt/xenapi/volume_utils.py:128 #, python-format -msgid "Failed to destroy vm %s" +msgid "Unable to get record of VDI %s on" msgstr "" -#: nova/virt/hyperv.py:389 +#: ../nova/virt/xenapi/volume_utils.py:146 #, python-format -msgid "Del: disk %s vm %s" +msgid "Unable to introduce VDI for SR %s" msgstr "" -#: nova/virt/hyperv.py:405 +#: ../nova/virt/xenapi/volume_utils.py:175 #, python-format -msgid "" -"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " -"cpu_time=%s" +msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s" msgstr "" -#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#: ../nova/virt/xenapi/volume_utils.py:197 #, python-format -msgid "duplicate name found: %s" +msgid "Mountpoint cannot be translated: %s" msgstr "" -#: nova/virt/hyperv.py:444 +#: ../nova/objectstore/image.py:262 #, python-format -msgid "Successfully changed vm state of %s to %s" +msgid "Failed to decrypt private key: %s" msgstr "" -#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#: ../nova/objectstore/image.py:269 #, python-format -msgid "Failed to change vm state of %s to %s" +msgid "Failed to decrypt initialization vector: %s" msgstr "" -#: nova/virt/images.py:70 +#: ../nova/objectstore/image.py:277 #, python-format -msgid "Finished retreving %s -- placed in %s" +msgid "Failed to decrypt image file %(image_file)s: %(err)s" msgstr "" -#: nova/virt/libvirt_conn.py:144 +#: ../nova/objectstore/handler.py:106 #, python-format -msgid "Connecting to libvirt: %s" +msgid "Unknown S3 value type %r" msgstr "" -#: nova/virt/libvirt_conn.py:157 -msgid "Connection to libvirt broke" +#: ../nova/objectstore/handler.py:137 +msgid "Authenticated request" msgstr "" -#: nova/virt/libvirt_conn.py:229 -#, python-format -msgid "instance %s: deleting instance files %s" +#: ../nova/objectstore/handler.py:182 +msgid "List of buckets requested" msgstr "" -#: nova/virt/libvirt_conn.py:271 +#: ../nova/objectstore/handler.py:209 #, python-format -msgid "No disk at %s" +msgid "List keys for bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:278 -msgid "Instance snapshotting is not supported for libvirtat this time" +#: ../nova/objectstore/handler.py:217 +#, python-format +msgid "Unauthorized attempt to access bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:294 +#: ../nova/objectstore/handler.py:235 #, python-format -msgid "instance %s: rebooted" +msgid "Creating bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:297 +#: ../nova/objectstore/handler.py:245 #, python-format -msgid "_wait_for_reboot failed: %s" +msgid "Deleting bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:340 +#: ../nova/objectstore/handler.py:249 #, python-format -msgid "instance %s: rescued" +msgid "Unauthorized attempt to delete bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:343 +#: ../nova/objectstore/handler.py:273 #, python-format -msgid "_wait_for_rescue failed: %s" +msgid "Getting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/libvirt_conn.py:370 +#: ../nova/objectstore/handler.py:276 #, python-format -msgid "instance %s: is running" +msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/libvirt_conn.py:381 +#: ../nova/objectstore/handler.py:296 #, python-format -msgid "instance %s: booted" +msgid "Putting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#: ../nova/objectstore/handler.py:299 #, python-format -msgid "instance %s: failed to boot" +msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s" msgstr "" -#: nova/virt/libvirt_conn.py:395 +#: ../nova/objectstore/handler.py:318 #, python-format -msgid "virsh said: %r" +msgid "Deleting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/libvirt_conn.py:399 -msgid "cool, it's a device" +#: ../nova/objectstore/handler.py:322 +#, python-format +msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/libvirt_conn.py:407 +#: ../nova/objectstore/handler.py:396 #, python-format -msgid "data: %r, fpath: %r" +msgid "Not authorized to upload image: invalid directory %s" msgstr "" -#: nova/virt/libvirt_conn.py:415 +#: ../nova/objectstore/handler.py:404 #, python-format -msgid "Contents of file %s: %r" +msgid "Not authorized to upload image: unauthorized bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:449 +#: ../nova/objectstore/handler.py:409 #, python-format -msgid "instance %s: Creating image" +msgid "Starting image upload: %s" msgstr "" -#: nova/virt/libvirt_conn.py:505 +#: ../nova/objectstore/handler.py:423 #, python-format -msgid "instance %s: injecting key into image %s" +msgid "Not authorized to update attributes of image %s" msgstr "" -#: nova/virt/libvirt_conn.py:508 +#: ../nova/objectstore/handler.py:431 #, python-format -msgid "instance %s: injecting net into image %s" +msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r" msgstr "" -#: nova/virt/libvirt_conn.py:516 +#. other attributes imply update +#: ../nova/objectstore/handler.py:436 #, python-format -msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgid "Updating user fields on image %s" msgstr "" -#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#: ../nova/objectstore/handler.py:450 #, python-format -msgid "instance %s: starting toXML method" +msgid "Unauthorized attempt to delete image %s" msgstr "" -#: nova/virt/libvirt_conn.py:589 +#: ../nova/objectstore/handler.py:455 #, python-format -msgid "instance %s: finished toXML method" +msgid "Deleted image: %s" 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/auth/manager.py:259 +#, python-format +msgid "Looking up user: %r" +msgstr "Procurando usuário: %r" -#: nova/virt/xenapi_conn.py:263 +#: ../nova/auth/manager.py:263 #, python-format -msgid "Task [%s] %s status: success %s" -msgstr "" +msgid "Failed authorization for access key %s" +msgstr "Falha de autorização para chave de acesso %s" -#: nova/virt/xenapi_conn.py:271 +#: ../nova/auth/manager.py:264 #, python-format -msgid "Task [%s] %s status: %s %s" -msgstr "" +msgid "No user found for access key %s" +msgstr "Nenhum usuário encontrado para chave de acesso %s" -#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#: ../nova/auth/manager.py:270 #, python-format -msgid "Got exception: %s" -msgstr "" +msgid "Using project name = user name (%s)" +msgstr "Usando nome do projeto = nome do usuário (%s)" -#: nova/virt/xenapi/fake.py:72 +#: ../nova/auth/manager.py:277 #, python-format -msgid "%s: _db_content => %s" +msgid "failed authorization: no project named %(pjid)s (user=%(uname)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/auth/manager.py:279 +#, python-format +msgid "No project called %s could be found" +msgstr "Nenhum projeto chamado %s pode ser encontrado." -#: nova/virt/xenapi/fake.py:249 +#: ../nova/auth/manager.py:287 #, python-format -msgid "xenapi.fake does not have an implementation for %s" +msgid "" +"Failed authorization: user %(uname)s not admin and not member of project " +"%(pjname)s" msgstr "" -#: nova/virt/xenapi/fake.py:283 +#: ../nova/auth/manager.py:289 #, python-format -msgid "Calling %s %s" +msgid "User %(uid)s is not a member of project %(pjid)s" msgstr "" -#: nova/virt/xenapi/fake.py:288 +#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309 #, python-format -msgid "Calling getter %s" -msgstr "" +msgid "Invalid signature for user %s" +msgstr "Assinatura inválida para usuário %s" + +#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310 +msgid "Signature does not match" +msgstr "Assinatura não confere" + +#: ../nova/auth/manager.py:380 +msgid "Must specify project" +msgstr "Deve especificar projeto" -#: nova/virt/xenapi/fake.py:340 +#: ../nova/auth/manager.py:414 #, python-format -msgid "" -"xenapi.fake does not have an implementation for %s or it has been called " -"with the wrong number of arguments" -msgstr "" +msgid "The %s role can not be found" +msgstr "O papel %s não foi encontrado" -#: nova/virt/xenapi/network_utils.py:40 +#: ../nova/auth/manager.py:416 #, python-format -msgid "Found non-unique network for bridge %s" -msgstr "" +msgid "The %s role is global only" +msgstr "O papel %s é apenas global" -#: nova/virt/xenapi/network_utils.py:43 +#: ../nova/auth/manager.py:420 #, python-format -msgid "Found no network for bridge %s" +msgid "Adding role %(role)s to user %(uid)s in project %(pid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:127 +#: ../nova/auth/manager.py:423 #, python-format -msgid "Created VM %s as %s." +msgid "Adding sitewide role %(role)s to user %(uid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:147 +#: ../nova/auth/manager.py:448 #, python-format -msgid "Creating VBD for VM %s, VDI %s ... " +msgid "Removing role %(role)s from user %(uid)s on project %(pid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:149 +#: ../nova/auth/manager.py:451 #, python-format -msgid "Created VBD %s for VM %s, VDI %s." +msgid "Removing sitewide role %(role)s from user %(uid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:165 +#: ../nova/auth/manager.py:515 #, python-format -msgid "VBD not found in instance %s" +msgid "Created project %(name)s with manager %(manager_user)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:175 +#: ../nova/auth/manager.py:533 #, python-format -msgid "Unable to unplug VBD %s" -msgstr "" +msgid "modifying project %s" +msgstr "modificando projeto %s" -#: nova/virt/xenapi/vm_utils.py:187 +#: ../nova/auth/manager.py:545 #, python-format -msgid "Unable to destroy VBD %s" +msgid "Adding user %(uid)s to project %(pid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:202 +#: ../nova/auth/manager.py:566 #, python-format -msgid "Creating VIF for VM %s, network %s." +msgid "Remove user %(uid)s from project %(pid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:205 +#: ../nova/auth/manager.py:592 #, python-format -msgid "Created VIF %s for VM %s, network %s." -msgstr "" +msgid "Deleting project %s" +msgstr "Excluindo projeto %s" -#: nova/virt/xenapi/vm_utils.py:216 +#: ../nova/auth/manager.py:650 #, python-format -msgid "Snapshotting VM %s with label '%s'..." +msgid "Created user %(rvname)s (admin: %(rvadmin)r)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:229 +#: ../nova/auth/manager.py:659 #, python-format -msgid "Created snapshot %s from VM %s." -msgstr "" +msgid "Deleting user %s" +msgstr "Apagando usuário %s" -#: nova/virt/xenapi/vm_utils.py:243 +#: ../nova/auth/manager.py:669 #, python-format -msgid "Asking xapi to upload %s as '%s'" +msgid "Access Key change for user %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:261 +#: ../nova/auth/manager.py:671 #, python-format -msgid "Asking xapi to fetch %s as %s" +msgid "Secret Key change for user %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:279 +#: ../nova/auth/manager.py:673 #, python-format -msgid "Looking up vdi %s for PV kernel" +msgid "Admin status set to %(admin)r for user %(uid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:290 +#: ../nova/auth/manager.py:722 #, python-format -msgid "PV Kernel in VDI:%d" +msgid "No vpn data for project %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:318 +#: ../nova/service.py:161 #, python-format -msgid "VDI %s is still available" +msgid "Starting %(topic)s node (version %(vcs_string)s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:331 +#: ../nova/service.py:174 +msgid "Service killed that has no database entry" +msgstr "Encerrado serviço que não tem entrada na base de dados" + +#: ../nova/service.py:195 +msgid "The service database object disappeared, Recreating it." +msgstr "O objeto da base de dados do serviço desapareceu, Recriando." + +#: ../nova/service.py:207 +msgid "Recovered model server connection!" +msgstr "Recuperada conexão servidor de modelo." + +#: ../nova/service.py:213 +msgid "model server went away" +msgstr "servidor de modelo perdido" + +#: ../nova/auth/ldapdriver.py:174 #, python-format -msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgid "LDAP user %s already exists" msgstr "" -#: nova/virt/xenapi/vm_utils.py:333 +#: ../nova/auth/ldapdriver.py:205 #, python-format -msgid "(VM_UTILS) xenapi power_state -> |%s|" -msgstr "" +msgid "LDAP object for %s doesn't exist" +msgstr "Objeto LDAP para %s não existe" -#: nova/virt/xenapi/vm_utils.py:390 +#: ../nova/auth/ldapdriver.py:348 #, python-format -msgid "VHD %s has parent %s" +msgid "User %s doesn't exist" msgstr "" -#: nova/virt/xenapi/vm_utils.py:407 +#: ../nova/auth/ldapdriver.py:472 #, python-format -msgid "Re-scanning SR %s" +msgid "Group can't be created because group %s already exists" msgstr "" -#: nova/virt/xenapi/vm_utils.py:431 +#: ../nova/auth/ldapdriver.py:478 #, python-format -msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgid "Group can't be created because user %s doesn't exist" msgstr "" -#: nova/virt/xenapi/vm_utils.py:448 +#: ../nova/auth/ldapdriver.py:495 #, python-format -msgid "No VDIs found for VM %s" +msgid "User %s can't be searched in group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/vm_utils.py:452 +#: ../nova/auth/ldapdriver.py:507 #, python-format -msgid "Unexpected number of VDIs (%s) found for VM %s" +msgid "User %s can't be added to the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:62 +#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521 #, python-format -msgid "Attempted to create non-unique name %s" +msgid "The group at dn %s doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:99 +#: ../nova/auth/ldapdriver.py:513 #, python-format -msgid "Starting VM %s..." +msgid "User %(uid)s is already a member of the group %(group_dn)s" msgstr "" -#: nova/virt/xenapi/vmops.py:101 +#: ../nova/auth/ldapdriver.py:524 #, python-format -msgid "Spawning VM %s created %s." +msgid "" +"User %s can't be removed from the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:112 +#: ../nova/auth/ldapdriver.py:528 #, python-format -msgid "Instance %s: booted" +msgid "User %s is not a member of the group" msgstr "" -#: nova/virt/xenapi/vmops.py:137 +#: ../nova/auth/ldapdriver.py:542 #, python-format -msgid "Instance not present %s" +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/virt/xenapi/vmops.py:166 +#: ../nova/auth/ldapdriver.py:549 #, python-format -msgid "Starting snapshot for VM %s" +msgid "User %s can't be removed from all because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:174 +#: ../nova/auth/ldapdriver.py:564 #, python-format -msgid "Unable to Snapshot %s: %s" -msgstr "" +msgid "Group at dn %s doesn't exist" +msgstr "Grupo no dn %s não existe" -#: nova/virt/xenapi/vmops.py:184 +#: ../nova/virt/xenapi/network_utils.py:40 #, python-format -msgid "Finished snapshot and upload for VM %s" +msgid "Found non-unique network for bridge %s" msgstr "" -#: nova/virt/xenapi/vmops.py:252 +#: ../nova/virt/xenapi/network_utils.py:43 #, python-format -msgid "suspend: instance not present %s" +msgid "Found no network for bridge %s" msgstr "" -#: nova/virt/xenapi/vmops.py:262 +#: ../nova/api/ec2/admin.py:97 #, python-format -msgid "resume: instance not present %s" -msgstr "" +msgid "Creating new user: %s" +msgstr "Criando novo usuário: %s" -#: nova/virt/xenapi/vmops.py:271 +#: ../nova/api/ec2/admin.py:105 #, python-format -msgid "Instance not found %s" -msgstr "" +msgid "Deleting user: %s" +msgstr "Excluindo usuário: %s" -#: nova/virt/xenapi/volume_utils.py:57 +#: ../nova/api/ec2/admin.py:127 #, python-format -msgid "Introducing %s..." +msgid "Adding role %(role)s to user %(user)s for project %(project)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:74 +#: ../nova/api/ec2/admin.py:131 #, python-format -msgid "Introduced %s as %s." +msgid "Adding sitewide role %(role)s to user %(user)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:78 -msgid "Unable to create Storage Repository" +#: ../nova/api/ec2/admin.py:137 +#, python-format +msgid "Removing role %(role)s from user %(user)s for project %(project)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:90 +#: ../nova/api/ec2/admin.py:141 #, python-format -msgid "Unable to find SR from VBD %s" +msgid "Removing sitewide role %(role)s from user %(user)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:96 +#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223 +msgid "operation must be add or remove" +msgstr "operações devem ser adicionar e excluir" + +#: ../nova/api/ec2/admin.py:159 #, python-format -msgid "Forgetting SR %s ... " +msgid "Getting x509 for user: %(name)s on project: %(project)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:101 +#: ../nova/api/ec2/admin.py:177 #, python-format -msgid "Ignoring exception %s when getting PBDs for %s" +msgid "Create project %(name)s managed by %(manager_user)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:107 +#: ../nova/api/ec2/admin.py:190 #, python-format -msgid "Ignoring exception %s when unplugging PBD %s" +msgid "Modify project: %(name)s managed by %(manager_user)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:111 +#: ../nova/api/ec2/admin.py:200 #, python-format -msgid "Forgetting SR %s done." -msgstr "" +msgid "Delete project: %s" +msgstr "Excluir projeto: %s" -#: nova/virt/xenapi/volume_utils.py:113 +#: ../nova/api/ec2/admin.py:214 #, python-format -msgid "Ignoring exception %s when forgetting SR %s" +msgid "Adding user %(user)s to project %(project)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:123 +#: ../nova/api/ec2/admin.py:218 #, python-format -msgid "Unable to introduce VDI on SR %s" +msgid "Removing user %(user)s from project %(project)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:128 #, python-format -msgid "Unable to get record of VDI %s on" -msgstr "" +#~ 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/virt/xenapi/volume_utils.py:146 #, python-format -msgid "Unable to introduce VDI for SR %s" -msgstr "" +#~ msgid "(%s) publish (key: %s) %s" +#~ msgstr "(%s) publicar (key: %s) %s" -#: nova/virt/xenapi/volume_utils.py:175 #, python-format -msgid "Unable to obtain target information %s, %s" -msgstr "" +#~ 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/virt/xenapi/volume_utils.py:197 #, python-format -msgid "Mountpoint cannot be translated: %s" -msgstr "" +#~ msgid "Binding %s to %s with key %s" +#~ msgstr "Atribuindo %s para %s com chave %s" -#: nova/virt/xenapi/volumeops.py:51 #, python-format -msgid "Attach_volume: %s, %s, %s" -msgstr "" +#~ msgid "Getting from %s: %s" +#~ msgstr "Obtendo de %s: %s" -#: nova/virt/xenapi/volumeops.py:69 #, python-format -msgid "Unable to create VDI on SR %s for instance %s" -msgstr "" +#~ msgid "Starting %s node" +#~ msgstr "Iniciando nó %s" -#: nova/virt/xenapi/volumeops.py:81 #, python-format -msgid "Unable to use SR %s for instance %s" -msgstr "" +#~ 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/virt/xenapi/volumeops.py:93 #, python-format -msgid "Unable to attach volume to instance %s" -msgstr "" +#~ 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/virt/xenapi/volumeops.py:95 #, python-format -msgid "Mountpoint %s attached to instance %s" -msgstr "" +#~ 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/virt/xenapi/volumeops.py:106 #, python-format -msgid "Detach_volume: %s, %s" -msgstr "" +#~ msgid "arg: %s\t\tval: %s" +#~ msgstr "argumento: %s\t\tvalor: %s" -#: nova/virt/xenapi/volumeops.py:113 #, python-format -msgid "Unable to locate volume %s" -msgstr "" +#~ msgid "Authenticated Request For %s:%s)" +#~ msgstr "Pedido de Autenticação Para: %s:%s" -#: nova/virt/xenapi/volumeops.py:121 #, python-format -msgid "Unable to detach volume %s" -msgstr "" +#~ msgid "Adding sitewide role %s to user %s" +#~ msgstr "Adicionando papel em todo site %s ao usuário %s" -#: nova/virt/xenapi/volumeops.py:128 #, python-format -msgid "Mountpoint %s detached from instance %s" -msgstr "" +#~ msgid "Adding role %s to user %s for project %s" +#~ msgstr "Adicionando papel %s ao usuário %s para o projeto %s" -#: nova/volume/api.py:44 #, python-format -msgid "Quota exceeeded for %s, tried to create %sG volume" -msgstr "" +#~ msgid "Unauthorized request for controller=%s and action=%s" +#~ msgstr "Requisição não autorizada para controlador=%s e ação=%s" -#: nova/volume/api.py:46 #, python-format -msgid "Volume quota exceeded. You cannot create a volume of size %s" -msgstr "" +#~ msgid "Removing role %s from user %s for project %s" +#~ msgstr "Removendo papel %s do usuário %s para o projeto %s" -#: nova/volume/api.py:70 nova/volume/api.py:95 -msgid "Volume status must be available" -msgstr "" +#, python-format +#~ msgid "Getting x509 for user: %s on project: %s" +#~ msgstr "Obtendo x509 para usuário: %s do projeto: %s" -#: nova/volume/api.py:97 -msgid "Volume is already attached" -msgstr "" +#, python-format +#~ msgid "Create project %s managed by %s" +#~ msgstr "Criar projeto %s gerenciado por %s" -#: nova/volume/api.py:103 -msgid "Volume is already detached" -msgstr "" +#, python-format +#~ msgid "Removing user %s from project %s" +#~ msgstr "Excluindo usuário %s do projeto %s" -#: nova/volume/driver.py:76 #, python-format -msgid "Recovering from a failed execute. Try number %s" -msgstr "" +#~ msgid "Adding user %s to project %s" +#~ msgstr "Adicionando usuário %s ao projeto %s" -#: nova/volume/driver.py:85 #, python-format -msgid "volume group %s doesn't exist" -msgstr "" +#~ msgid "Unsupported API request: controller = %s,action = %s" +#~ msgstr "Requisição de API não suportada: controlador = %s,ação = %s" -#: nova/volume/driver.py:210 #, python-format -msgid "FAKE AOE: %s" -msgstr "" +#~ msgid "Removing sitewide role %s from user %s" +#~ msgstr "Removendo papel %s em todo site do usuário %s" -#: nova/volume/driver.py:315 #, python-format -msgid "FAKE ISCSI: %s" -msgstr "" +#~ msgid "Associate address %s to instance %s" +#~ msgstr "Atribuir endereço %s à instância %s" -#: nova/volume/manager.py:85 #, python-format -msgid "Re-exporting %s volumes" -msgstr "" +#~ msgid "Attach volume %s to instacne %s at %s" +#~ msgstr "Anexar volume %s para instância %s em %s" -#: nova/volume/manager.py:93 #, python-format -msgid "volume %s: creating" -msgstr "" +#~ msgid "Registered image %s with id %s" +#~ msgstr "Registrada imagem %s com id %s" -#: nova/volume/manager.py:102 #, python-format -msgid "volume %s: creating lv of size %sG" -msgstr "" +#~ msgid "User %s is already a member of the group %s" +#~ msgstr "Usuário %s já pertence ao grupo %s" -#: nova/volume/manager.py:106 #, python-format -msgid "volume %s: creating export" -msgstr "" +#~ msgid "User %s is not a member of project %s" +#~ msgstr "Usuário %s não é membro do projeto %s" -#: nova/volume/manager.py:113 #, python-format -msgid "volume %s: created successfully" -msgstr "" +#~ msgid "failed authorization: no project named %s (user=%s)" +#~ msgstr "falha de autorização: nenhum projeto de nome %s (usuário=%s)" -#: nova/volume/manager.py:121 -msgid "Volume is still attached" -msgstr "" +#, 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/volume/manager.py:123 -msgid "Volume is not local to this node" -msgstr "" +#, python-format +#~ msgid "Created project %s with manager %s" +#~ msgstr "Criado projeto %s com gerente %s" -#: nova/volume/manager.py:124 #, python-format -msgid "volume %s: removing export" -msgstr "" +#~ msgid "Removing role %s from user %s on project %s" +#~ msgstr "Removendo papel %s do usuário %s no projeto %s" -#: nova/volume/manager.py:126 #, python-format -msgid "volume %s: deleting" -msgstr "" +#~ msgid "Adding role %s to user %s in project %s" +#~ msgstr "Adicionando papel %s ao usuário %s no projeto %s" -#: nova/volume/manager.py:129 #, python-format -msgid "volume %s: deleted successfully" -msgstr "" +#~ msgid "Remove user %s from project %s" +#~ msgstr "Remover usuário %s do projeto %s" + +#, python-format +#~ msgid "Created user %s (admin: %r)" +#~ msgstr "Criado usuário %s (administrador: %r)" diff --git a/po/ru.po b/po/ru.po index 5d031ac08..bbfcfb19f 100644 --- a/po/ru.po +++ b/po/ru.po @@ -7,2132 +7,2961 @@ 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-31 06:53+0000\n" +"POT-Creation-Date: 2011-02-21 10:03-0500\n" +"PO-Revision-Date: 2011-03-30 07:06+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-02-05 05:36+0000\n" -"X-Generator: Launchpad (build 12177)\n" +"X-Launchpad-Export-Date: 2011-03-31 05:58+0000\n" +"X-Generator: Launchpad (build 12559)\n" -#: nova/crypto.py:46 +#: ../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 "" + +#: ../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/api/openstack/servers.py:72 +msgid "Failed to read private ip" +msgstr "" + +#: ../nova/api/openstack/servers.py:79 +msgid "Failed to read public ip(s)" +msgstr "" + +#: ../nova/api/openstack/servers.py:152 +#, python-format +msgid "%(param)s property not found for image %(_image_id)s" +msgstr "" + +#: ../nova/api/openstack/servers.py:168 +msgid "No keypairs defined" +msgstr "" + +#: ../nova/api/openstack/servers.py:238 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:253 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:267 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:281 +#, python-format +msgid "Compute.api::reset_network %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:292 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:303 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:314 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:325 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: ../nova/twistd.py:157 +msgid "Wrong number of arguments." +msgstr "Неверное число аргументов." + +#: ../nova/twistd.py:209 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "pidfile %s не обнаружен. Демон не запущен?\n" + +#: ../nova/twistd.py:221 +msgid "No such process" +msgstr "" + +#: ../nova/twistd.py:230 ../nova/service.py:224 +#, python-format +msgid "Serving %s" +msgstr "" + +#: ../nova/twistd.py:262 ../nova/service.py:225 +msgid "Full set of FLAGS:" +msgstr "" + +#: ../nova/twistd.py:266 +#, python-format +msgid "Starting %s" +msgstr "Запускается %s" + +#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101 +#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741 +#: ../nova/api/ec2/__init__.py:317 +#, 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 +#: ../nova/crypto.py:49 msgid "Filename of private key" msgstr "Имя файла секретного ключа" -#: nova/crypto.py:51 +#: ../nova/crypto.py:51 msgid "Filename of root Certificate Revokation List" msgstr "" -#: nova/crypto.py:53 +#: ../nova/crypto.py:53 msgid "Where we keep our keys" msgstr "Путь к ключам" -#: nova/crypto.py:55 +#: ../nova/crypto.py:55 msgid "Where we keep our root CA" msgstr "" -#: nova/crypto.py:57 +#: ../nova/crypto.py:57 msgid "Should we use a CA for each project?" msgstr "" -#: nova/crypto.py:61 +#: ../nova/crypto.py:61 #, python-format msgid "Subject for certificate for users, %s for project, user, timestamp" msgstr "" -#: nova/crypto.py:66 +#: ../nova/crypto.py:66 #, python-format msgid "Subject for certificate for projects, %s for project, timestamp" msgstr "" -#: nova/crypto.py:71 +#: ../nova/crypto.py:71 #, python-format msgid "Subject for certificate for vpns, %s for project, timestamp" msgstr "" -#: nova/crypto.py:258 +#: ../nova/crypto.py:258 #, python-format msgid "Flags path: %s" msgstr "" -#: nova/exception.py:33 -msgid "Unexpected error while running command." -msgstr "Неожиданная ошибка при выполнении команды." +#: ../nova/scheduler/manager.py:69 +#, python-format +msgid "Casting to %(topic)s %(host)s for %(method)s" +msgstr "" + +#: ../nova/compute/manager.py:78 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" -#: nova/exception.py:36 +#: ../nova/compute/manager.py:80 #, 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 "Необработанное исключение" +"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|" +msgstr "" -#: nova/fakerabbit.py:48 +#: ../nova/compute/manager.py:84 #, python-format -msgid "(%s) publish (key: %s) %s" +msgid "check_instance_lock: locked: |%s|" msgstr "" -#: nova/fakerabbit.py:53 +#: ../nova/compute/manager.py:86 #, python-format -msgid "Publishing to route %s" +msgid "check_instance_lock: admin: |%s|" msgstr "" -#: nova/fakerabbit.py:83 +#: ../nova/compute/manager.py:91 #, python-format -msgid "Declaring queue %s" -msgstr "Объявление очереди %s" +msgid "check_instance_lock: executing: |%s|" +msgstr "" -#: nova/fakerabbit.py:89 +#: ../nova/compute/manager.py:95 #, python-format -msgid "Declaring exchange %s" -msgstr "Объявление точки обмена %s" +msgid "check_instance_lock: not executing |%s|" +msgstr "" -#: nova/fakerabbit.py:95 +#: ../nova/compute/manager.py:179 +msgid "Instance has already been created" +msgstr "" + +#: ../nova/compute/manager.py:180 #, python-format -msgid "Binding %s to %s with key %s" +msgid "instance %s: starting..." msgstr "" -#: nova/fakerabbit.py:120 +#. pylint: disable=W0702 +#: ../nova/compute/manager.py:219 #, python-format -msgid "Getting from %s: %s" -msgstr "Получение из %s: %s" +msgid "instance %s: Failed to spawn" +msgstr "" -#: nova/rpc.py:92 +#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286 #, python-format -msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." -msgstr "AMQP сервер %s:%d недоступен. Повторная попытка через %d секунд." +msgid "Terminating instance %s" +msgstr "" -#: nova/rpc.py:99 +#: ../nova/compute/manager.py:255 #, python-format -msgid "Unable to connect to AMQP server after %d tries. Shutting down." -msgstr "Не удалось подключиться к серверу AMQP после %d попыток. Выключение." +msgid "Deallocating address %s" +msgstr "" -#: nova/rpc.py:118 -msgid "Reconnected to queue" -msgstr "Переподлючено к очереди" +#: ../nova/compute/manager.py:268 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" -#: nova/rpc.py:125 -msgid "Failed to fetch message from queue" -msgstr "Не удалось получить сообщение из очереди" +#: ../nova/compute/manager.py:282 +#, python-format +msgid "Rebooting instance %s" +msgstr "" -#: nova/rpc.py:155 +#: ../nova/compute/manager.py:287 #, python-format -msgid "Initing the Adapter Consumer for %s" +msgid "" +"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" msgstr "" -#: nova/rpc.py:170 +#: ../nova/compute/manager.py:311 #, python-format -msgid "received %s" -msgstr "получено %s" +msgid "instance %s: snapshotting" +msgstr "" -#: nova/rpc.py:183 +#: ../nova/compute/manager.py:316 #, python-format -msgid "no method for message: %s" -msgstr "не определен метод для сообщения: %s" +msgid "" +"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" -#: nova/rpc.py:184 +#: ../nova/compute/manager.py:332 #, python-format -msgid "No method for message: %s" -msgstr "Не определен метод для сообщения: %s" +msgid "" +"trying to reset the password on a non-running instance: %(instance_id)s " +"(state: %(instance_state)s expected: %(expected_state)s)" +msgstr "" -#: nova/rpc.py:245 +#: ../nova/compute/manager.py:335 #, python-format -msgid "Returning exception %s to caller" +msgid "instance %s: setting admin password" msgstr "" -#: nova/rpc.py:286 +#: ../nova/compute/manager.py:353 #, python-format -msgid "unpacked context: %s" +msgid "" +"trying to inject a file into a non-running instance: %(instance_id)s (state: " +"%(instance_state)s expected: %(expected_state)s)" msgstr "" -#: nova/rpc.py:305 -msgid "Making asynchronous call..." -msgstr "Выполняется асинхронный вызов..." +#: ../nova/compute/manager.py:362 +#, python-format +msgid "instance %(nm)s: injecting file to %(plain_path)s" +msgstr "" + +#: ../nova/compute/manager.py:372 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: ../nova/compute/manager.py:387 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: ../nova/compute/manager.py:406 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: ../nova/compute/manager.py:423 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: ../nova/compute/manager.py:440 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: ../nova/compute/manager.py:453 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: ../nova/compute/manager.py:472 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: ../nova/compute/manager.py:491 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: ../nova/compute/manager.py:503 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: ../nova/compute/manager.py:513 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: ../nova/compute/manager.py:526 +#, python-format +msgid "instance %s: reset network" +msgstr "" + +#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: ../nova/compute/manager.py:543 +#, python-format +msgid "instance %s: getting ajax console" +msgstr "" + +#: ../nova/compute/manager.py:553 +#, python-format +msgid "" +"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s" +msgstr "" + +#. pylint: disable=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:569 +#, python-format +msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing" +msgstr "" + +#: ../nova/compute/manager.py:585 +#, python-format +msgid "" +"Detach volume %(volume_id)s from mountpoint %(mp)s on instance " +"%(instance_id)s" +msgstr "" + +#: ../nova/compute/manager.py:588 +#, 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:304 ../nova/virt/xenapi/fake.py:404 +#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478 +msgid "Raising NotImplemented" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:306 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:341 +#, python-format +msgid "Calling %(localname)s %(impl)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:346 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:406 +#, 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:187 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: ../nova/network/linux_net.py:208 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:314 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:316 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:358 +#, python-format +msgid "killing radvd threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:360 +#, python-format +msgid "Pid %d is stale, relaunching radvd" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:449 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: ../nova/utils.py:58 +#, python-format +msgid "Inner Exception: %s" +msgstr "Вложенное исключение: %s" + +#: ../nova/utils.py:59 +#, python-format +msgid "Class %s cannot be found" +msgstr "Класс %s не найден" + +#: ../nova/utils.py:118 +#, python-format +msgid "Fetching %s" +msgstr "" + +#: ../nova/utils.py:130 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "" + +#: ../nova/utils.py:143 ../nova/utils.py:183 +#, python-format +msgid "Result was %s" +msgstr "Результат %s" + +#: ../nova/utils.py:159 +#, python-format +msgid "Running cmd (SSH): %s" +msgstr "" + +#: ../nova/utils.py:217 +#, python-format +msgid "debug in callback: %s" +msgstr "" + +#: ../nova/utils.py:222 +#, python-format +msgid "Running %s" +msgstr "Выполняется %s" + +#: ../nova/utils.py:262 +#, python-format +msgid "Link Local address is not found.:%s" +msgstr "" + +#: ../nova/utils.py:265 +#, python-format +msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s" +msgstr "" + +#: ../nova/utils.py:363 +#, python-format +msgid "Invalid backend: %s" +msgstr "" + +#: ../nova/utils.py:374 +#, 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 "Объявление очереди %s" + +#: ../nova/fakerabbit.py:90 +#, python-format +msgid "Declaring exchange %s" +msgstr "Объявление точки обмена %s" + +#: ../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:168 +#, python-format +msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:171 +#, python-format +msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "VBD not found in instance %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:197 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:209 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:224 +#, python-format +msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:227 +#, python-format +msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:246 +#, 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:258 +#, python-format +msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:272 +#, python-format +msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:286 +#, python-format +msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:327 +#, python-format +msgid "Size for image %(image)s:%(virtual_size)d" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:332 +#, 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:342 +#, python-format +msgid "Copying VDI %s to /boot/guest on dom0" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:352 +#, python-format +msgid "Kernel/Ramdisk VDI %s destroyed" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:361 +#, python-format +msgid "Asking xapi to fetch %(url)s as %(access)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:397 +#, python-format +msgid "PV Kernel in VDI:%s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:405 +#, python-format +msgid "Running pygrub against %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:411 +#, python-format +msgid "Found Xen kernel %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:413 +msgid "No Xen kernel found. Booting HVM." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431 +#, python-format +msgid "duplicate name found: %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:442 +#, python-format +msgid "VDI %s is still available" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:463 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:465 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:525 +#, python-format +msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:542 +#, python-format +msgid "Re-scanning SR %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:567 +#, python-format +msgid "" +"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:574 +#, 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:590 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:594 +#, python-format +msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:653 +#: ../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:655 +#: ../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:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192 +#, python-format +msgid "Plugging VBD %s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:659 +#: ../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:661 +#, python-format +msgid "VBD %(vbd)s plugged as %(orig_dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:664 +#, python-format +msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:668 +#: ../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:671 +#: ../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:683 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211 +msgid "VBD.unplug successful first time." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:688 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216 +msgid "VBD.unplug rejected: retrying..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:692 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220 +msgid "VBD.unplug successful eventually." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:695 +#: ../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:704 +#: ../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:735 +#, python-format +msgid "" +"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:747 +#, 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 "Получено %s" + +#: ../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:592 +msgid "No fixed ips defined" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:608 +#, python-format +msgid "No floating ip for address %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:629 +#, python-format +msgid "No address for instance %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:961 +#, python-format +msgid "no keypair for user %(user_id)s, name %(name)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156 +#, python-format +msgid "No network for id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1086 +msgid "No networks defined" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1115 +#, python-format +msgid "No network for bridge %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142 +#, python-format +msgid "No network for instance %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1277 +#, python-format +msgid "Token %s does not exist" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1302 +#, python-format +msgid "No quota for project_id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501 +#: ../nova/api/ec2/__init__.py:323 +#, python-format +msgid "Volume %s not found" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1514 +#, python-format +msgid "No export device found for volume %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1527 +#, python-format +msgid "No target id found for volume %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1572 +#, python-format +msgid "No security group with id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1589 +#, python-format +msgid "No security group named %(group_name)s for project: %(project_id)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1682 +#, python-format +msgid "No secuity group rule with id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1756 +#, python-format +msgid "No user for id %s" +msgstr "" -#: nova/rpc.py:308 +#: ../nova/db/sqlalchemy/api.py:1772 #, python-format -msgid "MSG_ID is %s" -msgstr "MSG_ID is %s" +msgid "No user for access key %s" +msgstr "" -#: nova/rpc.py:356 +#: ../nova/db/sqlalchemy/api.py:1834 #, python-format -msgid "response %s" -msgstr "ответ %s" +msgid "No project with id %s" +msgstr "" -#: nova/rpc.py:365 +#: ../nova/db/sqlalchemy/api.py:1979 #, python-format -msgid "topic is %s" -msgstr "тема %s" +msgid "No console pool with id %(pool_id)s" +msgstr "" -#: nova/rpc.py:366 +#: ../nova/db/sqlalchemy/api.py:1996 #, python-format -msgid "message %s" -msgstr "сообщение %s" +msgid "" +"No console pool of type %(console_type)s for compute host %(compute_host)s " +"on proxy host %(host)s" +msgstr "" -#: nova/service.py:157 +#: ../nova/db/sqlalchemy/api.py:2035 #, python-format -msgid "Starting %s node" -msgstr "Запускается нода %s" +msgid "No console for instance %(instance_id)s in pool %(pool_id)s" +msgstr "" -#: nova/service.py:169 -msgid "Service killed that has no database entry" +#: ../nova/db/sqlalchemy/api.py:2057 +#, python-format +msgid "on instance %s" msgstr "" -#: nova/service.py:190 -msgid "The service database object disappeared, Recreating it." -msgstr "Объект сервиса в базе данных отсутствует, Повторное создание." +#: ../nova/db/sqlalchemy/api.py:2058 +#, python-format +msgid "No console with id %(console_id)s %(idesc)s" +msgstr "" -#: nova/service.py:202 -msgid "Recovered model server connection!" +#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097 +#, python-format +msgid "No zone with id %(zone_id)s" msgstr "" -#: nova/service.py:208 -msgid "model server went away" +#: ../nova/virt/libvirt_conn.py:160 +#, python-format +msgid "Checking state of %s" msgstr "" -#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#: ../nova/virt/libvirt_conn.py:165 #, python-format -msgid "Data store %s is unreachable. Trying again in %d seconds." -msgstr "Хранилище данных %s недоступно. Повторная попытка через %d секунд." +msgid "Current state of %(name)s was %(state)s." +msgstr "" -#: nova/service.py:232 nova/twistd.py:232 +#: ../nova/virt/libvirt_conn.py:183 #, python-format -msgid "Serving %s" +msgid "Connecting to libvirt: %s" msgstr "" -#: nova/service.py:234 nova/twistd.py:264 -msgid "Full set of FLAGS:" +#: ../nova/virt/libvirt_conn.py:196 +msgid "Connection to libvirt broke" msgstr "" -#: nova/twistd.py:211 +#: ../nova/virt/libvirt_conn.py:258 #, python-format -msgid "pidfile %s does not exist. Daemon not running?\n" -msgstr "pidfile %s не обнаружен. Демон не запущен?\n" +msgid "instance %(instance_name)s: deleting instance files %(target)s" +msgstr "" -#: nova/twistd.py:268 +#: ../nova/virt/libvirt_conn.py:283 #, python-format -msgid "Starting %s" -msgstr "Запускается %s" +msgid "Invalid device path %s" +msgstr "" -#: nova/utils.py:53 +#: ../nova/virt/libvirt_conn.py:313 #, python-format -msgid "Inner Exception: %s" -msgstr "Вложенное исключение: %s" +msgid "No disk at %s" +msgstr "Нет диска в %s" -#: nova/utils.py:54 -#, python-format -msgid "Class %s cannot be found" -msgstr "Класс %s не найден" +#: ../nova/virt/libvirt_conn.py:320 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "" -#: nova/utils.py:113 +#: ../nova/virt/libvirt_conn.py:336 #, python-format -msgid "Fetching %s" +msgid "instance %s: rebooted" msgstr "" -#: nova/utils.py:125 +#: ../nova/virt/libvirt_conn.py:339 #, python-format -msgid "Running cmd (subprocess): %s" +msgid "_wait_for_reboot failed: %s" msgstr "" -#: nova/utils.py:138 +#: ../nova/virt/libvirt_conn.py:382 #, python-format -msgid "Result was %s" -msgstr "Результат %s" +msgid "instance %s: rescued" +msgstr "" -#: nova/utils.py:171 +#: ../nova/virt/libvirt_conn.py:385 #, python-format -msgid "debug in callback: %s" +msgid "_wait_for_rescue failed: %s" msgstr "" -#: nova/utils.py:176 +#: ../nova/virt/libvirt_conn.py:411 #, python-format -msgid "Running %s" -msgstr "Выполняется %s" +msgid "instance %s: is running" +msgstr "" -#: nova/utils.py:207 +#: ../nova/virt/libvirt_conn.py:422 #, python-format -msgid "Couldn't get IP, using 127.0.0.1 %s" -msgstr "Не удалось получить IP, используем 127.0.0.1 %s" +msgid "instance %s: booted" +msgstr "" -#: nova/utils.py:289 +#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186 #, python-format -msgid "Invalid backend: %s" +msgid "instance %s: failed to boot" msgstr "" -#: nova/utils.py:300 +#: ../nova/virt/libvirt_conn.py:436 #, python-format -msgid "backend %s" +msgid "virsh said: %r" msgstr "" -#: nova/api/ec2/__init__.py:133 -msgid "Too many failed authentications." -msgstr "Слишком много неудачных попыток аутентификации." +#: ../nova/virt/libvirt_conn.py:440 +msgid "cool, it's a device" +msgstr "" -#: nova/api/ec2/__init__.py:142 +#: ../nova/virt/libvirt_conn.py:448 #, python-format -msgid "" -"Access key %s has had %d failed authentications and will be locked out for " -"%d minutes." +msgid "data: %(data)r, fpath: %(fpath)r" msgstr "" -"Ключ доступа %s имеет %d неудачных попыток аутентификации и будет " -"заблокирован на %d минут." -#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#: ../nova/virt/libvirt_conn.py:456 #, python-format -msgid "Authentication Failure: %s" -msgstr "Ошибка аутентификации: %s" +msgid "Contents of file %(fpath)s: %(contents)r" +msgstr "" -#: nova/api/ec2/__init__.py:190 -#, python-format -msgid "Authenticated Request For %s:%s)" -msgstr "Запрос аутентификации для %s:%s)" +#: ../nova/virt/libvirt_conn.py:489 +msgid "Unable to find an open port" +msgstr "" -#: nova/api/ec2/__init__.py:227 +#: ../nova/virt/libvirt_conn.py:563 #, python-format -msgid "action: %s" -msgstr "действие: %s" +msgid "instance %s: Creating image" +msgstr "" -#: nova/api/ec2/__init__.py:229 +#: ../nova/virt/libvirt_conn.py:646 #, python-format -msgid "arg: %s\t\tval: %s" -msgstr "arg: %s\t\tval: %s" +msgid "instance %(inst_name)s: injecting key into image %(img_id)s" +msgstr "" -#: nova/api/ec2/__init__.py:301 +#: ../nova/virt/libvirt_conn.py:649 #, python-format -msgid "Unauthorized request for controller=%s and action=%s" +msgid "instance %(inst_name)s: injecting net into image %(img_id)s" msgstr "" -#: nova/api/ec2/__init__.py:339 +#. This could be a windows image, or a vmdk format disk +#: ../nova/virt/libvirt_conn.py:657 #, python-format -msgid "NotFound raised: %s" +msgid "" +"instance %(inst_name)s: ignoring error injecting data into image %(img_id)s " +"(%(e)s)" msgstr "" -#: nova/api/ec2/__init__.py:342 +#. TODO(termie): cache? +#: ../nova/virt/libvirt_conn.py:665 #, python-format -msgid "ApiError raised: %s" +msgid "instance %s: starting toXML method" msgstr "" -#: nova/api/ec2/__init__.py:349 +#: ../nova/virt/libvirt_conn.py:732 #, python-format -msgid "Unexpected error raised: %s" +msgid "instance %s: finished toXML method" msgstr "" -#: nova/api/ec2/__init__.py:354 -msgid "An unknown error has occurred. Please try your request again." +#: ../nova/virt/libvirt_conn.py:751 +msgid "diagnostics are not supported for libvirt" msgstr "" -"Произошла неизвестная ошибка. Пожалуйста, попытайтесь повторить ваш запрос." - -#: nova/api/ec2/admin.py:84 -#, python-format -msgid "Creating new user: %s" -msgstr "Создание нового пользователя: %s" -#: nova/api/ec2/admin.py:92 +#: ../nova/virt/libvirt_conn.py:1225 #, python-format -msgid "Deleting user: %s" -msgstr "Удаление пользователя: %s" +msgid "Attempted to unfilter instance %s which is not filtered" +msgstr "" -#: nova/api/ec2/admin.py:114 +#: ../nova/api/ec2/metadatarequesthandler.py:76 #, python-format -msgid "Adding role %s to user %s for project %s" -msgstr "Добавление роли %s для пользователя %s для проекта %s" +msgid "Failed to get metadata for ip: %s" +msgstr "Ошибка получения метаданных для ip: %s" -#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 -#, python-format -msgid "Adding sitewide role %s to user %s" +#: ../nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" msgstr "" -#: nova/api/ec2/admin.py:122 +#: ../nova/network/api.py:39 #, 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" +msgid "Quota exceeeded for %s, tried to allocate address" msgstr "" -#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 -msgid "operation must be add or remove" +#: ../nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" msgstr "" -#: nova/api/ec2/admin.py:142 +#: ../nova/tests/test_volume.py:162 #, python-format -msgid "Getting x509 for user: %s on project: %s" +msgid "Target %s allocated" msgstr "" -#: nova/api/ec2/admin.py:159 +#: ../nova/virt/images.py:70 #, python-format -msgid "Create project %s managed by %s" -msgstr "Создать проект %s под управлением %s" +msgid "Finished retreving %(url)s -- placed in %(path)s" +msgstr "" -#: nova/api/ec2/admin.py:170 -#, python-format -msgid "Delete project: %s" -msgstr "Удалить проект: %s" +#: ../nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "" -#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 -#, python-format -msgid "Adding user %s to project %s" -msgstr "Добавление пользователя %s к проекту %s" +#: ../nova/console/manager.py:70 +msgid "Adding console" +msgstr "" -#: nova/api/ec2/admin.py:188 +#: ../nova/console/manager.py:90 #, python-format -msgid "Removing user %s from project %s" -msgstr "Удаление пользователя %s с проекта %s" +msgid "Tried to remove non-existant console %(console_id)s." +msgstr "" + +#: ../nova/api/direct.py:149 +msgid "not available" +msgstr "" -#: nova/api/ec2/apirequest.py:95 +#: ../nova/api/ec2/cloud.py:62 #, python-format -msgid "Unsupported API request: controller = %s,action = %s" +msgid "The key_pair %s already exists" msgstr "" -#: nova/api/ec2/cloud.py:117 +#. 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:277 +#: ../nova/api/ec2/cloud.py:303 #, python-format msgid "Create key pair %s" msgstr "Создание пары ключей %s" -#: nova/api/ec2/cloud.py:285 +#: ../nova/api/ec2/cloud.py:311 #, python-format msgid "Delete key pair %s" msgstr "Удаление пары ключей %s" -#: nova/api/ec2/cloud.py:357 +#: ../nova/api/ec2/cloud.py:386 #, python-format msgid "%s is not a valid ipProtocol" msgstr "" -#: nova/api/ec2/cloud.py:361 +#: ../nova/api/ec2/cloud.py:390 msgid "Invalid port range" msgstr "Неверный диапазон портов" -#: nova/api/ec2/cloud.py:392 +#: ../nova/api/ec2/cloud.py:421 #, python-format msgid "Revoke security group ingress %s" msgstr "" -#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 +#: ../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:443 msgid "No rule for the specified parameters." msgstr "" -#: nova/api/ec2/cloud.py:421 +#: ../nova/api/ec2/cloud.py:450 #, python-format msgid "Authorize security group ingress %s" msgstr "" -#: nova/api/ec2/cloud.py:432 +#: ../nova/api/ec2/cloud.py:464 #, python-format msgid "This rule already exists in group %s" msgstr "Это правило уже существует в группе %s" -#: nova/api/ec2/cloud.py:460 +#: ../nova/api/ec2/cloud.py:492 #, python-format msgid "Create Security Group %s" msgstr "" -#: nova/api/ec2/cloud.py:463 +#: ../nova/api/ec2/cloud.py:495 #, python-format msgid "group %s already exists" msgstr "группа %s уже существует" -#: nova/api/ec2/cloud.py:475 +#: ../nova/api/ec2/cloud.py:507 #, 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 +#: ../nova/api/ec2/cloud.py:584 #, python-format msgid "Create volume of %s GB" msgstr "Создание раздела %s ГБ" -#: nova/api/ec2/cloud.py:567 +#: ../nova/api/ec2/cloud.py:612 #, python-format -msgid "Attach volume %s to instacne %s at %s" +msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s" msgstr "" -#: nova/api/ec2/cloud.py:579 +#: ../nova/api/ec2/cloud.py:629 #, python-format msgid "Detach volume %s" msgstr "" -#: nova/api/ec2/cloud.py:686 +#: ../nova/api/ec2/cloud.py:761 msgid "Allocate address" msgstr "" -#: nova/api/ec2/cloud.py:691 +#: ../nova/api/ec2/cloud.py:766 #, python-format msgid "Release address %s" msgstr "" -#: nova/api/ec2/cloud.py:696 +#: ../nova/api/ec2/cloud.py:771 #, python-format -msgid "Associate address %s to instance %s" +msgid "Associate address %(public_ip)s to instance %(instance_id)s" msgstr "" -#: nova/api/ec2/cloud.py:703 +#: ../nova/api/ec2/cloud.py:780 #, python-format msgid "Disassociate address %s" msgstr "" -#: nova/api/ec2/cloud.py:730 +#: ../nova/api/ec2/cloud.py:807 msgid "Going to start terminating instances" msgstr "" -#: nova/api/ec2/cloud.py:738 +#: ../nova/api/ec2/cloud.py:815 #, python-format msgid "Reboot instance %r" msgstr "" -#: nova/api/ec2/cloud.py:775 +#: ../nova/api/ec2/cloud.py:867 #, python-format msgid "De-registering image %s" msgstr "" -#: nova/api/ec2/cloud.py:783 +#: ../nova/api/ec2/cloud.py:875 #, python-format -msgid "Registered image %s with id %s" +msgid "Registered image %(image_location)s with id %(image_id)s" msgstr "" -#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900 #, python-format msgid "attribute not supported: %s" msgstr "аттрибут не поддерживается: %s" -#: nova/api/ec2/cloud.py:794 +#: ../nova/api/ec2/cloud.py:890 #, python-format msgid "invalid id: %s" msgstr "" -#: nova/api/ec2/cloud.py:807 +#: ../nova/api/ec2/cloud.py:903 msgid "user or group not specified" msgstr "не указан пользователь или группа" -#: nova/api/ec2/cloud.py:809 +#: ../nova/api/ec2/cloud.py:905 msgid "only group \"all\" is supported" msgstr "" -#: nova/api/ec2/cloud.py:811 +#: ../nova/api/ec2/cloud.py:907 msgid "operation_type must be add or remove" msgstr "" -#: nova/api/ec2/cloud.py:812 +#: ../nova/api/ec2/cloud.py:908 #, 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 "Ошибка получения метаданных для ip: %s" - -#: nova/api/openstack/__init__.py:70 +#: ../bin/nova-api.py:52 #, python-format -msgid "Caught error: %s" +msgid "Using paste.deploy config at: %s" msgstr "" -#: nova/api/openstack/__init__.py:86 -msgid "Including admin operations in API." -msgstr "" - -#: nova/api/openstack/servers.py:184 +#: ../bin/nova-api.py:57 #, python-format -msgid "Compute.api::lock %s" +msgid "No paste configuration for app: %s" msgstr "" -#: nova/api/openstack/servers.py:199 +#: ../bin/nova-api.py:59 #, python-format -msgid "Compute.api::unlock %s" +msgid "" +"App Config: %(api)s\n" +"%(config)r" msgstr "" -#: nova/api/openstack/servers.py:213 +#: ../bin/nova-api.py:64 #, python-format -msgid "Compute.api::get_lock %s" +msgid "Running %s API" msgstr "" -#: nova/api/openstack/servers.py:224 +#: ../bin/nova-api.py:69 #, python-format -msgid "Compute.api::pause %s" +msgid "No known API applications configured in %s." msgstr "" -#: nova/api/openstack/servers.py:235 +#: ../bin/nova-api.py:83 #, python-format -msgid "Compute.api::unpause %s" +msgid "Starting nova-api node (version %s)" msgstr "" -#: nova/api/openstack/servers.py:246 +#: ../bin/nova-api.py:89 #, python-format -msgid "compute.api::suspend %s" +msgid "No paste configuration found for: %s" msgstr "" -#: nova/api/openstack/servers.py:257 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84 #, python-format -msgid "compute.api::resume %s" +msgid "Argument %(key)s value %(value)s is too short." 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 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89 #, python-format -msgid "Project can't be modified because manager %s doesn't exist" +msgid "Argument %(key)s value %(value)s contains invalid characters." msgstr "" -#: nova/auth/dbdriver.py:245 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94 #, 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" +msgid "Argument %(key)s value %(value)s starts with a hyphen." msgstr "" -#: nova/auth/ldapdriver.py:181 +#: ../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 "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" +msgid "Argument %s is required." +msgstr "" -#: nova/auth/ldapdriver.py:507 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117 #, python-format msgid "" -"Attempted to remove the last member of a group. Deleting the group at %s " -"instead." +"Argument %(key)s may not take value %(value)s. Valid values are ['true', " +"'false']." msgstr "" -#: nova/auth/ldapdriver.py:528 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:163 #, python-format -msgid "Group at dn %s doesn't exist" +msgid "" +"Created VDI %(vdi_ref)s (%(label)s, %(size)s, %(read_only)s) on %(sr_ref)s." msgstr "" -#: nova/auth/manager.py:259 +#: ../nova/virt/xenapi/vmops.py:67 #, python-format -msgid "Looking up user: %r" +msgid "Attempted to create non-unique name %s" msgstr "" -#: nova/auth/manager.py:263 +#: ../nova/virt/xenapi/vmops.py:73 #, python-format -msgid "Failed authorization for access key %s" +msgid "instance %(name)s: not enough free memory" msgstr "" -#: nova/auth/manager.py:264 +#: ../nova/virt/xenapi/vmops.py:148 #, python-format -msgid "No user found for access key %s" +msgid "Starting VM %s..." msgstr "" -#: nova/auth/manager.py:270 +#: ../nova/virt/xenapi/vmops.py:151 #, python-format -msgid "Using project name = user name (%s)" +msgid "Spawning VM %(instance_name)s created %(vm_ref)s." msgstr "" -#: nova/auth/manager.py:275 +#: ../nova/virt/xenapi/vmops.py:162 #, python-format -msgid "failed authorization: no project named %s (user=%s)" +msgid "Invalid value for onset_files: '%s'" msgstr "" -#: nova/auth/manager.py:277 +#: ../nova/virt/xenapi/vmops.py:167 #, python-format -msgid "No project called %s could be found" +msgid "Injecting file path: '%s'" msgstr "" -#: nova/auth/manager.py:281 +#: ../nova/virt/xenapi/vmops.py:180 #, python-format -msgid "Failed authorization: user %s not admin and not member of project %s" +msgid "Instance %s: booted" 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 +#: ../nova/virt/xenapi/vmops.py:232 #, python-format -msgid "The %s role is global only" +msgid "Instance not present %s" 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 +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vmops.py:261 #, python-format -msgid "Access Key change for user %s" +msgid "Starting snapshot for VM %s" msgstr "" -#: nova/auth/manager.py:657 +#: ../nova/virt/xenapi/vmops.py:269 #, python-format -msgid "Secret Key change for user %s" +msgid "Unable to Snapshot %(vm_ref)s: %(exc)s" msgstr "" -#: nova/auth/manager.py:659 +#: ../nova/virt/xenapi/vmops.py:280 #, python-format -msgid "Admin status set to %r for user %s" +msgid "Finished snapshot and upload for VM %s" msgstr "" -#: nova/auth/manager.py:708 +#: ../nova/virt/xenapi/vmops.py:356 #, 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" +msgid "VM %(vm)s already halted, skipping shutdown..." msgstr "" -#: nova/cloudpipe/pipelib.py:51 -msgid "Netmask to push into openvpn config" +#: ../nova/virt/xenapi/vmops.py:389 +msgid "Removing kernel/ramdisk files" 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" +#: ../nova/virt/xenapi/vmops.py:399 +msgid "kernel/ramdisk files removed" msgstr "" -#: nova/compute/api.py:73 +#: ../nova/virt/xenapi/vmops.py:561 #, python-format -msgid "Instance %d has no host" +msgid "" +"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/api.py:92 +#: ../nova/virt/xenapi/vmops.py:564 #, python-format -msgid "Quota exceeeded for %s, tried to run %s instances" +msgid "" +"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM " +"id=%(instance_id)s; args=%(strargs)s" msgstr "" -#: nova/compute/api.py:94 +#: ../nova/virt/xenapi/vmops.py:569 #, python-format msgid "" -"Instance quota exceeded. You can only run %s more instances of this type." +"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/api.py:109 -msgid "Creating a raw instance" +#: ../nova/virt/xenapi/vmops.py:760 +#, python-format +msgid "OpenSSL error: %s" msgstr "" -#: nova/compute/api.py:156 +#: ../nova/tests/test_compute.py:148 #, python-format -msgid "Going to run %s instances..." +msgid "Running instances: %s" msgstr "" -#: nova/compute/api.py:180 +#: ../nova/tests/test_compute.py:154 #, python-format -msgid "Casting to scheduler for %s/%s's instance %s" +msgid "After terminating instances: %s" msgstr "" -#: nova/compute/api.py:279 -#, python-format -msgid "Going to try and terminate %s" +#: ../nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" msgstr "" -#: nova/compute/api.py:283 -#, python-format -msgid "Instance %d was not found during terminate" +#: ../nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" msgstr "" -#: nova/compute/api.py:288 -#, python-format -msgid "Instance %d is already being terminated" +#: ../nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" msgstr "" -#: nova/compute/api.py:450 +#: ../nova/cloudpipe/pipelib.py:97 #, python-format -msgid "Invalid device specified: %s. Example device: /dev/vdb" -msgstr "" +msgid "Launching VPN for %s" +msgstr "Запуск VPN для %s" -#: nova/compute/api.py:465 -msgid "Volume isn't attached to anything!" +#: ../nova/db/sqlalchemy/migration.py:35 +msgid "python-migrate is not installed. Exiting." msgstr "" -#: nova/compute/disk.py:71 +#: ../nova/image/s3.py:99 #, python-format -msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgid "Image %s could not be found" msgstr "" -#: nova/compute/disk.py:75 +#: ../nova/api/ec2/__init__.py:121 +msgid "Too many failed authentications." +msgstr "Слишком много неудачных попыток аутентификации." + +#: ../nova/api/ec2/__init__.py:131 #, python-format -msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgid "" +"Access key %(access_key)s has had %(failures)d failed authentications and " +"will be locked out for %(lock_mins)d minutes." msgstr "" -#: nova/compute/disk.py:128 +#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140 #, python-format -msgid "Could not attach image to loopback: %s" -msgstr "" +msgid "Authentication Failure: %s" +msgstr "Ошибка аутентификации: %s" -#: nova/compute/disk.py:136 +#: ../nova/api/ec2/__init__.py:182 #, python-format -msgid "Failed to load partition: %s" +msgid "Authenticated Request For %(uname)s:%(pname)s)" msgstr "" -#: nova/compute/disk.py:158 +#: ../nova/api/ec2/__init__.py:207 #, python-format -msgid "Failed to mount filesystem: %s" -msgstr "Ошибка монтирования файловой системы: %s" +msgid "action: %s" +msgstr "действие: %s" -#: nova/compute/instance_types.py:41 +#: ../nova/api/ec2/__init__.py:209 #, python-format -msgid "Unknown instance type: %s" +msgid "arg: %(key)s\t\tval: %(value)s" msgstr "" -#: nova/compute/manager.py:69 +#: ../nova/api/ec2/__init__.py:281 #, python-format -msgid "check_instance_lock: decorating: |%s|" +msgid "" +"Unauthorized request for controller=%(controller)s and action=%(action)s" msgstr "" -#: nova/compute/manager.py:71 +#: ../nova/api/ec2/__init__.py:314 #, python-format -msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgid "InstanceNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:75 +#: ../nova/api/ec2/__init__.py:320 #, python-format -msgid "check_instance_lock: locked: |%s|" +msgid "VolumeNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:77 +#: ../nova/api/ec2/__init__.py:326 #, python-format -msgid "check_instance_lock: admin: |%s|" +msgid "NotFound raised: %s" msgstr "" -#: nova/compute/manager.py:82 +#: ../nova/api/ec2/__init__.py:329 #, python-format -msgid "check_instance_lock: executing: |%s|" +msgid "ApiError raised: %s" msgstr "" -#: nova/compute/manager.py:86 +#: ../nova/api/ec2/__init__.py:338 #, python-format -msgid "check_instance_lock: not executing |%s|" +msgid "Unexpected error raised: %s" msgstr "" -#: nova/compute/manager.py:157 -msgid "Instance has already been created" +#: ../nova/api/ec2/__init__.py:343 +msgid "An unknown error has occurred. Please try your request again." msgstr "" +"Произошла неизвестная ошибка. Пожалуйста, попытайтесь повторить ваш запрос." -#: nova/compute/manager.py:158 +#: ../nova/auth/dbdriver.py:84 #, python-format -msgid "instance %s: starting..." -msgstr "" +msgid "User %s already exists" +msgstr "Пользователь %s уже существует" -#: nova/compute/manager.py:197 +#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232 #, python-format -msgid "instance %s: Failed to spawn" -msgstr "" +msgid "Project can't be created because manager %s doesn't exist" +msgstr "Проект не может быть создан поскольку менеджер %s не существует" -#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243 #, python-format -msgid "Terminating instance %s" -msgstr "" +msgid "Project can't be created because user %s doesn't exist" +msgstr "Проект не может быть создан поскольку пользователь %s не существует" -#: nova/compute/manager.py:217 +#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229 #, python-format -msgid "Disassociating address %s" -msgstr "" +msgid "Project can't be created because project %s already exists" +msgstr "Проект не может быть созан поскольку проект %s уже существует" -#: nova/compute/manager.py:230 +#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268 #, python-format -msgid "Deallocating address %s" +msgid "Project can't be modified because manager %s doesn't exist" msgstr "" -#: nova/compute/manager.py:243 +#: ../nova/auth/dbdriver.py:245 #, python-format -msgid "trying to destroy already destroyed instance: %s" -msgstr "" +msgid "User \"%s\" not found" +msgstr "Пользователь \"%s\" не существует" -#: nova/compute/manager.py:257 +#: ../nova/auth/dbdriver.py:248 #, python-format -msgid "Rebooting instance %s" +msgid "Project \"%s\" not found" +msgstr "Проект \"%s\" не найден" + +#: ../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/compute/manager.py:260 +#: ../nova/virt/xenapi_conn.py:311 #, python-format -msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgid "Task [%(name)s] %(task)s status: success %(result)s" msgstr "" -#: nova/compute/manager.py:286 +#: ../nova/virt/xenapi_conn.py:317 #, python-format -msgid "instance %s: snapshotting" +msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s" msgstr "" -#: nova/compute/manager.py:289 +#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344 #, python-format -msgid "" -"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgid "Got exception: %s" msgstr "" -#: nova/compute/manager.py:301 +#: ../nova/compute/monitor.py:259 #, python-format -msgid "instance %s: rescuing" -msgstr "" +msgid "updating %s..." +msgstr "обновление %s..." + +#: ../nova/compute/monitor.py:289 +msgid "unexpected error during update" +msgstr "неожиданная ошибка во время обновления" -#: nova/compute/manager.py:316 +#: ../nova/compute/monitor.py:356 #, python-format -msgid "instance %s: unrescuing" +msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/manager.py:335 +#: ../nova/compute/monitor.py:379 #, python-format -msgid "instance %s: pausing" +msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/manager.py:352 -#, python-format -msgid "instance %s: unpausing" +#: ../nova/compute/monitor.py:414 +msgid "unexpected exception getting connection" msgstr "" -#: nova/compute/manager.py:369 +#: ../nova/compute/monitor.py:429 #, python-format -msgid "instance %s: retrieving diagnostics" +msgid "Found instance: %s" msgstr "" -#: nova/compute/manager.py:382 +#: ../nova/volume/san.py:67 #, python-format -msgid "instance %s: suspending" +msgid "Could not find iSCSI export for volume %s" msgstr "" -#: nova/compute/manager.py:401 +#: ../nova/api/ec2/apirequest.py:100 #, python-format -msgid "instance %s: resuming" +msgid "" +"Unsupported API request: controller = %(controller)s, action = %(action)s" msgstr "" -#: nova/compute/manager.py:420 +#: ../nova/api/openstack/__init__.py:55 #, python-format -msgid "instance %s: locking" +msgid "Caught error: %s" msgstr "" -#: nova/compute/manager.py:432 -#, python-format -msgid "instance %s: unlocking" +#: ../nova/api/openstack/__init__.py:76 +msgid "Including admin operations in API." msgstr "" -#: nova/compute/manager.py:442 -#, python-format -msgid "instance %s: getting locked state" +#: ../nova/console/xvp.py:99 +msgid "Rebuilding xvp conf" msgstr "" -#: nova/compute/manager.py:462 +#: ../nova/console/xvp.py:116 #, python-format -msgid "instance %s: attaching volume %s to %s" +msgid "Re-wrote %s" msgstr "" -#: nova/compute/manager.py:478 -#, python-format -msgid "instance %s: attach failed %s, removing" +#: ../nova/console/xvp.py:121 +msgid "Stopping xvp" msgstr "" -#: nova/compute/manager.py:493 -#, python-format -msgid "Detach volume %s from mountpoint %s on instance %s" +#: ../nova/console/xvp.py:134 +msgid "Starting xvp" msgstr "" -#: nova/compute/manager.py:497 +#: ../nova/console/xvp.py:141 #, python-format -msgid "Detaching volume from unknown instance %s" +msgid "Error starting xvp: %s" msgstr "" -#: nova/compute/monitor.py:259 -#, python-format -msgid "updating %s..." -msgstr "обновление %s..." +#: ../nova/console/xvp.py:144 +msgid "Restarting xvp" +msgstr "" -#: nova/compute/monitor.py:289 -msgid "unexpected error during update" -msgstr "неожиданная ошибка во время обновления" +#: ../nova/console/xvp.py:146 +msgid "xvp not running..." +msgstr "" -#: nova/compute/monitor.py:355 -#, python-format -msgid "Cannot get blockstats for \"%s\" on \"%s\"" +#: ../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 "" -#: nova/compute/monitor.py:377 -#, python-format -msgid "Cannot get ifstats for \"%s\" on \"%s\"" +#: ../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 "" -#: nova/compute/monitor.py:412 -msgid "unexpected exception getting connection" +#: ../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/compute/monitor.py:427 -#, python-format -msgid "Found instance: %s" +#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536 +msgid "network" msgstr "" -#: nova/db/sqlalchemy/api.py:43 -msgid "Use of empty request context is deprecated" +#: ../bin/nova-manage.py:448 +msgid "IP address" msgstr "" -#: nova/db/sqlalchemy/api.py:132 -#, python-format -msgid "No service for id %s" +#: ../bin/nova-manage.py:449 +msgid "MAC address" msgstr "" -#: nova/db/sqlalchemy/api.py:229 -#, python-format -msgid "No service for %s, %s" +#: ../bin/nova-manage.py:450 +msgid "hostname" msgstr "" -#: nova/db/sqlalchemy/api.py:574 -#, python-format -msgid "No floating ip for address %s" +#: ../bin/nova-manage.py:451 +msgid "host" msgstr "" -#: nova/db/sqlalchemy/api.py:668 -#, python-format -msgid "No instance for id %s" +#: ../bin/nova-manage.py:537 +msgid "netmask" 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" +#: ../bin/nova-manage.py:538 +msgid "start address" msgstr "" -#: nova/db/sqlalchemy/api.py:891 +#: ../nova/virt/disk.py:69 #, python-format -msgid "no keypair for user %s, name %s" +msgid "Failed to load partition: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#: ../nova/virt/disk.py:91 #, python-format -msgid "No network for id %s" -msgstr "" +msgid "Failed to mount filesystem: %s" +msgstr "Ошибка монтирования файловой системы: %s" -#: nova/db/sqlalchemy/api.py:1036 +#: ../nova/virt/disk.py:124 #, python-format -msgid "No network for bridge %s" +msgid "nbd device %s did not show up" msgstr "" -#: nova/db/sqlalchemy/api.py:1050 +#: ../nova/virt/disk.py:128 #, python-format -msgid "No network for instance %s" +msgid "Could not attach image to loopback: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1180 -#, python-format -msgid "Token %s does not exist" +#: ../nova/virt/disk.py:151 +msgid "No free nbd devices" msgstr "" -#: nova/db/sqlalchemy/api.py:1205 +#: ../doc/ext/nova_todo.py:46 #, python-format -msgid "No quota for project_id %s" +msgid "%(filename)s, line %(line_info)d" msgstr "" -#: nova/db/sqlalchemy/api.py:1356 -#, python-format -msgid "No volume for id %s" +#. FIXME(chiradeep): implement this +#: ../nova/virt/hyperv.py:118 +msgid "In init host" msgstr "" -#: nova/db/sqlalchemy/api.py:1401 +#: ../nova/virt/hyperv.py:131 #, python-format -msgid "Volume %s not found" +msgid "Attempt to create duplicate vm %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1413 +#: ../nova/virt/hyperv.py:148 #, python-format -msgid "No export device found for volume %s" -msgstr "" +msgid "Starting VM %s " +msgstr "Запускается VM %s " -#: nova/db/sqlalchemy/api.py:1426 +#: ../nova/virt/hyperv.py:150 #, python-format -msgid "No target id found for volume %s" -msgstr "" +msgid "Started VM %s " +msgstr "Запущен VM %s " -#: nova/db/sqlalchemy/api.py:1471 +#: ../nova/virt/hyperv.py:152 #, python-format -msgid "No security group with id %s" +msgid "spawn vm failed: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1488 +#: ../nova/virt/hyperv.py:169 #, python-format -msgid "No security group named %s for project: %s" +msgid "Failed to create VM %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1576 +#: ../nova/virt/hyperv.py:188 #, python-format -msgid "No secuity group rule with id %s" +msgid "Set memory for vm %s..." msgstr "" -#: nova/db/sqlalchemy/api.py:1650 +#: ../nova/virt/hyperv.py:198 #, python-format -msgid "No user for id %s" +msgid "Set vcpus for vm %s..." msgstr "" -#: nova/db/sqlalchemy/api.py:1666 +#: ../nova/virt/hyperv.py:202 #, python-format -msgid "No user for access key %s" +msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s" msgstr "" -#: nova/db/sqlalchemy/api.py:1728 +#: ../nova/virt/hyperv.py:227 #, python-format -msgid "No project with id %s" +msgid "Failed to add diskdrive to VM %s" msgstr "" -#: nova/image/glance.py:78 +#: ../nova/virt/hyperv.py:230 #, python-format -msgid "Parallax returned HTTP error %d from request for /images" +msgid "New disk drive path is %s" msgstr "" -#: nova/image/glance.py:97 +#: ../nova/virt/hyperv.py:247 #, python-format -msgid "Parallax returned HTTP error %d from request for /images/detail" +msgid "Failed to add vhd file to VM %s" msgstr "" -#: nova/image/s3.py:82 +#: ../nova/virt/hyperv.py:249 #, python-format -msgid "Image %s could not be found" -msgstr "" +msgid "Created disk for %s" +msgstr "Создан диск для %s" -#: nova/network/api.py:39 +#: ../nova/virt/hyperv.py:253 #, python-format -msgid "Quota exceeeded for %s, tried to allocate address" +msgid "Creating nic for %s " msgstr "" -#: nova/network/api.py:42 -msgid "Address quota exceeded. You cannot allocate any more addresses" +#: ../nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" msgstr "" -#: nova/network/linux_net.py:176 +#: ../nova/virt/hyperv.py:273 #, python-format -msgid "Starting VLAN inteface %s" +msgid "Failed creating port for %s" msgstr "" -#: nova/network/linux_net.py:186 +#: ../nova/virt/hyperv.py:276 #, python-format -msgid "Starting Bridge interface for %s" +msgid "Created switch port %(vm_name)s on switch %(ext_path)s" msgstr "" -#: nova/network/linux_net.py:254 +#: ../nova/virt/hyperv.py:286 #, python-format -msgid "Hupping dnsmasq threw %s" +msgid "Failed to add nic to VM %s" msgstr "" -#: nova/network/linux_net.py:256 +#: ../nova/virt/hyperv.py:288 #, python-format -msgid "Pid %d is stale, relaunching dnsmasq" +msgid "Created nic for %s " msgstr "" -#: nova/network/linux_net.py:334 +#: ../nova/virt/hyperv.py:321 #, python-format -msgid "Killing dnsmasq threw %s" +msgid "WMI job failed: %s" msgstr "" -#: nova/network/manager.py:135 -msgid "setting network host" +#: ../nova/virt/hyperv.py:325 +#, python-format +msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s " msgstr "" -#: nova/network/manager.py:190 +#: ../nova/virt/hyperv.py:361 #, python-format -msgid "Leasing IP %s" +msgid "Got request to destroy vm %s" msgstr "" -#: nova/network/manager.py:194 +#: ../nova/virt/hyperv.py:386 #, python-format -msgid "IP %s leased that isn't associated" +msgid "Failed to destroy vm %s" msgstr "" -#: nova/network/manager.py:197 +#: ../nova/virt/hyperv.py:393 #, python-format -msgid "IP %s leased to bad mac %s vs %s" +msgid "Del: disk %(vhdfile)s vm %(instance_name)s" msgstr "" -#: nova/network/manager.py:205 +#: ../nova/virt/hyperv.py:415 #, python-format -msgid "IP %s leased that was already deallocated" +msgid "" +"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, " +"num_cpu=%(numprocs)s, cpu_time=%(uptime)s" msgstr "" -#: nova/network/manager.py:214 +#: ../nova/virt/hyperv.py:451 #, python-format -msgid "IP %s released that isn't associated" +msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/network/manager.py:217 +#: ../nova/virt/hyperv.py:454 #, python-format -msgid "IP %s released from bad mac %s vs %s" +msgid "Failed to change vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/network/manager.py:220 +#: ../nova/compute/api.py:71 #, python-format -msgid "IP %s released that was not leased" +msgid "Instance %d was not found in get_network_topic" msgstr "" -#: nova/network/manager.py:442 +#: ../nova/compute/api.py:77 #, python-format -msgid "Dissassociated %s stale fixed ip(s)" +msgid "Instance %d has no host" msgstr "" -#: nova/objectstore/handler.py:106 +#: ../nova/compute/api.py:97 #, python-format -msgid "Unknown S3 value type %r" +msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances" msgstr "" -#: nova/objectstore/handler.py:137 -msgid "Authenticated request" +#: ../nova/compute/api.py:99 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." msgstr "" -#: nova/objectstore/handler.py:182 -msgid "List of buckets requested" +#: ../nova/compute/api.py:112 +msgid "Creating a raw instance" msgstr "" -#: nova/objectstore/handler.py:209 +#: ../nova/compute/api.py:160 #, python-format -msgid "List keys for bucket %s" +msgid "Going to run %s instances..." msgstr "" -#: nova/objectstore/handler.py:217 +#: ../nova/compute/api.py:187 #, python-format -msgid "Unauthorized attempt to access bucket %s" +msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s" msgstr "" -#: nova/objectstore/handler.py:235 +#: ../nova/compute/api.py:292 #, python-format -msgid "Creating bucket %s" +msgid "Going to try to terminate %s" msgstr "" -#: nova/objectstore/handler.py:245 +#: ../nova/compute/api.py:296 #, python-format -msgid "Deleting bucket %s" +msgid "Instance %d was not found during terminate" msgstr "" -#: nova/objectstore/handler.py:249 +#: ../nova/compute/api.py:301 #, python-format -msgid "Unauthorized attempt to delete bucket %s" +msgid "Instance %d is already being terminated" msgstr "" -#: nova/objectstore/handler.py:271 -#, python-format -msgid "Getting object: %s / %s" -msgstr "Получение объекта: %s / %s" - -#: nova/objectstore/handler.py:274 +#: ../nova/compute/api.py:481 #, python-format -msgid "Unauthorized attempt to get object %s from bucket %s" +msgid "Invalid device specified: %s. Example device: /dev/vdb" msgstr "" -#: nova/objectstore/handler.py:292 -#, python-format -msgid "Putting object: %s / %s" -msgstr "Вставка объекта: %s / %s" +#: ../nova/compute/api.py:496 +msgid "Volume isn't attached to anything!" +msgstr "" -#: nova/objectstore/handler.py:295 +#: ../nova/rpc.py:98 #, python-format -msgid "Unauthorized attempt to upload object %s to bucket %s" +msgid "" +"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in " +"%(fl_intv)d seconds." msgstr "" -#: nova/objectstore/handler.py:314 +#: ../nova/rpc.py:103 #, python-format -msgid "Deleting object: %s / %s" -msgstr "Удаление объекта: %s / %s" +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "Не удалось подключиться к серверу AMQP после %d попыток. Выключение." + +#: ../nova/rpc.py:122 +msgid "Reconnected to queue" +msgstr "Переподлючено к очереди" + +#: ../nova/rpc.py:129 +msgid "Failed to fetch message from queue" +msgstr "Не удалось получить сообщение из очереди" -#: nova/objectstore/handler.py:393 +#: ../nova/rpc.py:159 #, python-format -msgid "Not authorized to upload image: invalid directory %s" +msgid "Initing the Adapter Consumer for %s" msgstr "" -#: nova/objectstore/handler.py:401 +#: ../nova/rpc.py:178 #, python-format -msgid "Not authorized to upload image: unauthorized bucket %s" -msgstr "" +msgid "received %s" +msgstr "получено %s" -#: nova/objectstore/handler.py:406 +#. 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:191 #, python-format -msgid "Starting image upload: %s" -msgstr "" +msgid "no method for message: %s" +msgstr "не определен метод для сообщения: %s" -#: nova/objectstore/handler.py:420 +#: ../nova/rpc.py:192 #, python-format -msgid "Not authorized to update attributes of image %s" -msgstr "" +msgid "No method for message: %s" +msgstr "Не определен метод для сообщения: %s" -#: nova/objectstore/handler.py:428 +#: ../nova/rpc.py:253 #, python-format -msgid "Toggling publicity flag of image %s %r" +msgid "Returning exception %s to caller" msgstr "" -#: nova/objectstore/handler.py:433 +#: ../nova/rpc.py:294 #, python-format -msgid "Updating user fields on image %s" +msgid "unpacked context: %s" msgstr "" -#: nova/objectstore/handler.py:447 +#: ../nova/rpc.py:313 +msgid "Making asynchronous call..." +msgstr "Выполняется асинхронный вызов..." + +#: ../nova/rpc.py:316 #, python-format -msgid "Unauthorized attempt to delete image %s" +msgid "MSG_ID is %s" +msgstr "MSG_ID is %s" + +#: ../nova/rpc.py:354 +msgid "Making asynchronous cast..." msgstr "" -#: nova/objectstore/handler.py:452 +#: ../nova/rpc.py:364 #, python-format -msgid "Deleted image: %s" -msgstr "Удаленное изображение: %s" +msgid "response %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/rpc.py:373 +#, python-format +msgid "topic is %s" +msgstr "тема %s" -#: nova/scheduler/driver.py:66 -msgid "Must implement a fallback schedule" -msgstr "" +#: ../nova/rpc.py:374 +#, python-format +msgid "message %s" +msgstr "сообщение %s" -#: nova/scheduler/manager.py:69 +#: ../nova/volume/driver.py:78 #, python-format -msgid "Casting to %s %s for %s" +msgid "Recovering from a failed execute. Try number %s" msgstr "" -#: nova/scheduler/simple.py:63 -msgid "All hosts have too many cores" +#: ../nova/volume/driver.py:87 +#, python-format +msgid "volume group %s doesn't exist" msgstr "" -#: nova/scheduler/simple.py:95 -msgid "All hosts have too many gigabytes" +#: ../nova/volume/driver.py:220 +#, python-format +msgid "FAKE AOE: %s" msgstr "" -#: nova/scheduler/simple.py:115 -msgid "All hosts have too many networks" +#: ../nova/volume/driver.py:233 +msgid "Skipping ensure_export. No iscsi_target " msgstr "" -#: nova/tests/test_cloud.py:198 -msgid "Can't test instances without a real virtual env." +#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288 +msgid "Skipping remove_export. No iscsi_target " msgstr "" -#: nova/tests/test_cloud.py:210 +#: ../nova/volume/driver.py:347 #, python-format -msgid "Need to watch instance %s until it's running..." +msgid "FAKE ISCSI: %s" msgstr "" -#: nova/tests/test_compute.py:104 +#: ../nova/volume/driver.py:359 #, python-format -msgid "Running instances: %s" +msgid "rbd has no pool %s" msgstr "" -#: nova/tests/test_compute.py:110 +#: ../nova/volume/driver.py:414 #, python-format -msgid "After terminating instances: %s" +msgid "Sheepdog is not working: %s" msgstr "" -#: nova/tests/test_rpc.py:89 -#, python-format -msgid "Nested received %s, %s" +#: ../nova/volume/driver.py:416 +msgid "Sheepdog is not working" msgstr "" -#: nova/tests/test_rpc.py:94 +#: ../nova/wsgi.py:68 #, python-format -msgid "Nested return %s" +msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 -#, python-format -msgid "Received %s" -msgstr "Получено %s" +#: ../nova/wsgi.py:147 +msgid "You must implement __call__" +msgstr "" -#: nova/tests/test_volume.py:162 -#, python-format -msgid "Target %s allocated" +#: ../bin/nova-instancemonitor.py:55 +msgid "Starting instance monitor" msgstr "" -#: nova/virt/connection.py:73 -msgid "Failed to open connection to the hypervisor" +#: ../bin/nova-dhcpbridge.py:58 +msgid "leasing ip" msgstr "" -#: nova/virt/fake.py:210 -#, python-format -msgid "Instance %s Not Found" +#: ../bin/nova-dhcpbridge.py:73 +msgid "Adopted old lease or got a change of mac/hostname" msgstr "" -#: nova/virt/hyperv.py:118 -msgid "In init host" +#: ../bin/nova-dhcpbridge.py:80 +msgid "releasing ip" msgstr "" -#: nova/virt/hyperv.py:131 +#: ../bin/nova-dhcpbridge.py:123 #, python-format -msgid "Attempt to create duplicate vm %s" +msgid "" +"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s " +"on interface %(interface)s" msgstr "" -#: nova/virt/hyperv.py:148 +#: ../nova/virt/fake.py:239 #, python-format -msgid "Starting VM %s " -msgstr "Запускается VM %s " +msgid "Instance %s Not Found" +msgstr "" -#: nova/virt/hyperv.py:150 +#: ../nova/network/manager.py:153 #, python-format -msgid "Started VM %s " -msgstr "Запущен VM %s " +msgid "Dissassociated %s stale fixed ip(s)" +msgstr "" -#: nova/virt/hyperv.py:152 -#, python-format -msgid "spawn vm failed: %s" +#: ../nova/network/manager.py:157 +msgid "setting network host" msgstr "" -#: nova/virt/hyperv.py:169 +#: ../nova/network/manager.py:212 #, python-format -msgid "Failed to create VM %s" +msgid "Leasing IP %s" msgstr "" -#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#: ../nova/network/manager.py:216 #, python-format -msgid "Created VM %s..." +msgid "IP %s leased that isn't associated" msgstr "" -#: nova/virt/hyperv.py:188 +#: ../nova/network/manager.py:220 #, python-format -msgid "Set memory for vm %s..." +msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/hyperv.py:198 +#: ../nova/network/manager.py:228 #, python-format -msgid "Set vcpus for vm %s..." +msgid "IP %s leased that was already deallocated" msgstr "" -#: nova/virt/hyperv.py:202 +#: ../nova/network/manager.py:233 #, python-format -msgid "Creating disk for %s by attaching disk file %s" +msgid "Releasing IP %s" msgstr "" -#: nova/virt/hyperv.py:227 +#: ../nova/network/manager.py:237 #, python-format -msgid "Failed to add diskdrive to VM %s" +msgid "IP %s released that isn't associated" msgstr "" -#: nova/virt/hyperv.py:230 +#: ../nova/network/manager.py:241 #, python-format -msgid "New disk drive path is %s" +msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/hyperv.py:247 +#: ../nova/network/manager.py:244 #, python-format -msgid "Failed to add vhd file to VM %s" +msgid "IP %s released that was not leased" +msgstr "" + +#: ../nova/network/manager.py:519 +msgid "" +"The sum between the number of networks and the vlan start cannot be greater " +"than 4094" msgstr "" -#: nova/virt/hyperv.py:249 +#: ../nova/virt/xenapi/volume_utils.py:57 #, python-format -msgid "Created disk for %s" -msgstr "Создан диск для %s" +msgid "Introducing %s..." +msgstr "" -#: nova/virt/hyperv.py:253 +#: ../nova/virt/xenapi/volume_utils.py:74 #, python-format -msgid "Creating nic for %s " +msgid "Introduced %(label)s as %(sr_ref)s." msgstr "" -#: nova/virt/hyperv.py:272 -msgid "Failed creating a port on the external vswitch" +#: ../nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" msgstr "" -#: nova/virt/hyperv.py:273 +#: ../nova/virt/xenapi/volume_utils.py:90 #, python-format -msgid "Failed creating port for %s" +msgid "Unable to find SR from VBD %s" msgstr "" -#: nova/virt/hyperv.py:275 +#: ../nova/virt/xenapi/volume_utils.py:96 #, python-format -msgid "Created switch port %s on switch %s" +msgid "Forgetting SR %s ... " msgstr "" -#: nova/virt/hyperv.py:285 +#: ../nova/virt/xenapi/volume_utils.py:101 #, python-format -msgid "Failed to add nic to VM %s" +msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s" msgstr "" -#: nova/virt/hyperv.py:287 +#: ../nova/virt/xenapi/volume_utils.py:107 #, python-format -msgid "Created nic for %s " +msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s" msgstr "" -#: nova/virt/hyperv.py:320 +#: ../nova/virt/xenapi/volume_utils.py:111 #, python-format -msgid "WMI job failed: %s" +msgid "Forgetting SR %s done." msgstr "" -#: nova/virt/hyperv.py:322 +#: ../nova/virt/xenapi/volume_utils.py:113 #, python-format -msgid "WMI job succeeded: %s, Elapsed=%s " +msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s" msgstr "" -#: nova/virt/hyperv.py:358 +#: ../nova/virt/xenapi/volume_utils.py:123 #, python-format -msgid "Got request to destroy vm %s" +msgid "Unable to introduce VDI on SR %s" msgstr "" -#: nova/virt/hyperv.py:383 +#: ../nova/virt/xenapi/volume_utils.py:128 #, python-format -msgid "Failed to destroy vm %s" +msgid "Unable to get record of VDI %s on" msgstr "" -#: nova/virt/hyperv.py:389 +#: ../nova/virt/xenapi/volume_utils.py:146 #, python-format -msgid "Del: disk %s vm %s" +msgid "Unable to introduce VDI for SR %s" msgstr "" -#: nova/virt/hyperv.py:405 +#: ../nova/virt/xenapi/volume_utils.py:175 #, python-format -msgid "" -"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " -"cpu_time=%s" +msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s" msgstr "" -#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#: ../nova/virt/xenapi/volume_utils.py:197 #, python-format -msgid "duplicate name found: %s" +msgid "Mountpoint cannot be translated: %s" msgstr "" -#: nova/virt/hyperv.py:444 +#: ../nova/objectstore/image.py:262 #, python-format -msgid "Successfully changed vm state of %s to %s" +msgid "Failed to decrypt private key: %s" msgstr "" -#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#: ../nova/objectstore/image.py:269 #, python-format -msgid "Failed to change vm state of %s to %s" +msgid "Failed to decrypt initialization vector: %s" msgstr "" -#: nova/virt/images.py:70 +#: ../nova/objectstore/image.py:277 #, python-format -msgid "Finished retreving %s -- placed in %s" +msgid "Failed to decrypt image file %(image_file)s: %(err)s" msgstr "" -#: nova/virt/libvirt_conn.py:144 +#: ../nova/objectstore/handler.py:106 #, python-format -msgid "Connecting to libvirt: %s" +msgid "Unknown S3 value type %r" msgstr "" -#: nova/virt/libvirt_conn.py:157 -msgid "Connection to libvirt broke" +#: ../nova/objectstore/handler.py:137 +msgid "Authenticated request" msgstr "" -#: nova/virt/libvirt_conn.py:229 -#, python-format -msgid "instance %s: deleting instance files %s" +#: ../nova/objectstore/handler.py:182 +msgid "List of buckets requested" msgstr "" -#: nova/virt/libvirt_conn.py:271 +#: ../nova/objectstore/handler.py:209 #, 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" +msgid "List keys for bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:294 +#: ../nova/objectstore/handler.py:217 #, python-format -msgid "instance %s: rebooted" +msgid "Unauthorized attempt to access bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:297 +#: ../nova/objectstore/handler.py:235 #, python-format -msgid "_wait_for_reboot failed: %s" +msgid "Creating bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:340 +#: ../nova/objectstore/handler.py:245 #, python-format -msgid "instance %s: rescued" +msgid "Deleting bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:343 +#: ../nova/objectstore/handler.py:249 #, python-format -msgid "_wait_for_rescue failed: %s" +msgid "Unauthorized attempt to delete bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:370 +#: ../nova/objectstore/handler.py:273 #, python-format -msgid "instance %s: is running" +msgid "Getting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/libvirt_conn.py:381 +#: ../nova/objectstore/handler.py:276 #, python-format -msgid "instance %s: booted" +msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#: ../nova/objectstore/handler.py:296 #, python-format -msgid "instance %s: failed to boot" +msgid "Putting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/libvirt_conn.py:395 +#: ../nova/objectstore/handler.py:299 #, python-format -msgid "virsh said: %r" -msgstr "" - -#: nova/virt/libvirt_conn.py:399 -msgid "cool, it's a device" +msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s" msgstr "" -#: nova/virt/libvirt_conn.py:407 +#: ../nova/objectstore/handler.py:318 #, python-format -msgid "data: %r, fpath: %r" +msgid "Deleting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/libvirt_conn.py:415 +#: ../nova/objectstore/handler.py:322 #, python-format -msgid "Contents of file %s: %r" +msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/libvirt_conn.py:449 +#: ../nova/objectstore/handler.py:396 #, python-format -msgid "instance %s: Creating image" +msgid "Not authorized to upload image: invalid directory %s" msgstr "" -#: nova/virt/libvirt_conn.py:505 +#: ../nova/objectstore/handler.py:404 #, python-format -msgid "instance %s: injecting key into image %s" +msgid "Not authorized to upload image: unauthorized bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:508 +#: ../nova/objectstore/handler.py:409 #, python-format -msgid "instance %s: injecting net into image %s" +msgid "Starting image upload: %s" msgstr "" -#: nova/virt/libvirt_conn.py:516 +#: ../nova/objectstore/handler.py:423 #, python-format -msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgid "Not authorized to update attributes of image %s" msgstr "" -#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#: ../nova/objectstore/handler.py:431 #, python-format -msgid "instance %s: starting toXML method" +msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r" msgstr "" -#: nova/virt/libvirt_conn.py:589 +#. other attributes imply update +#: ../nova/objectstore/handler.py:436 #, python-format -msgid "instance %s: finished toXML method" +msgid "Updating user fields on image %s" 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" +#: ../nova/objectstore/handler.py:450 +#, python-format +msgid "Unauthorized attempt to delete image %s" msgstr "" -#: nova/virt/xenapi_conn.py:263 +#: ../nova/objectstore/handler.py:455 #, python-format -msgid "Task [%s] %s status: success %s" -msgstr "" +msgid "Deleted image: %s" +msgstr "Удаленное изображение: %s" -#: nova/virt/xenapi_conn.py:271 +#: ../nova/auth/manager.py:259 #, python-format -msgid "Task [%s] %s status: %s %s" +msgid "Looking up user: %r" msgstr "" -#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#: ../nova/auth/manager.py:263 #, python-format -msgid "Got exception: %s" +msgid "Failed authorization for access key %s" msgstr "" -#: nova/virt/xenapi/fake.py:72 +#: ../nova/auth/manager.py:264 #, 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" +msgid "No user found for access key %s" msgstr "" -#: nova/virt/xenapi/fake.py:249 +#: ../nova/auth/manager.py:270 #, python-format -msgid "xenapi.fake does not have an implementation for %s" +msgid "Using project name = user name (%s)" msgstr "" -#: nova/virt/xenapi/fake.py:283 +#: ../nova/auth/manager.py:277 #, python-format -msgid "Calling %s %s" -msgstr "Звонок %s %s" +msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)" +msgstr "" -#: nova/virt/xenapi/fake.py:288 +#: ../nova/auth/manager.py:279 #, python-format -msgid "Calling getter %s" +msgid "No project called %s could be found" msgstr "" -#: nova/virt/xenapi/fake.py:340 +#: ../nova/auth/manager.py:287 #, python-format msgid "" -"xenapi.fake does not have an implementation for %s or it has been called " -"with the wrong number of arguments" +"Failed authorization: user %(uname)s not admin and not member of project " +"%(pjname)s" msgstr "" -#: nova/virt/xenapi/network_utils.py:40 +#: ../nova/auth/manager.py:289 #, python-format -msgid "Found non-unique network for bridge %s" +msgid "User %(uid)s is not a member of project %(pjid)s" msgstr "" -#: nova/virt/xenapi/network_utils.py:43 +#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309 #, python-format -msgid "Found no network for bridge %s" -msgstr "" +msgid "Invalid signature for user %s" +msgstr "Не допустимая подпись для пользователя %s" + +#: ../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/virt/xenapi/vm_utils.py:127 +#: ../nova/auth/manager.py:414 #, python-format -msgid "Created VM %s as %s." -msgstr "" +msgid "The %s role can not be found" +msgstr "Роль %s не может быть найдена" -#: nova/virt/xenapi/vm_utils.py:147 +#: ../nova/auth/manager.py:416 #, python-format -msgid "Creating VBD for VM %s, VDI %s ... " +msgid "The %s role is global only" msgstr "" -#: nova/virt/xenapi/vm_utils.py:149 +#: ../nova/auth/manager.py:420 #, python-format -msgid "Created VBD %s for VM %s, VDI %s." +msgid "Adding role %(role)s to user %(uid)s in project %(pid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:165 +#: ../nova/auth/manager.py:423 #, python-format -msgid "VBD not found in instance %s" +msgid "Adding sitewide role %(role)s to user %(uid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:175 +#: ../nova/auth/manager.py:448 #, python-format -msgid "Unable to unplug VBD %s" +msgid "Removing role %(role)s from user %(uid)s on project %(pid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:187 +#: ../nova/auth/manager.py:451 #, python-format -msgid "Unable to destroy VBD %s" +msgid "Removing sitewide role %(role)s from user %(uid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:202 +#: ../nova/auth/manager.py:515 #, python-format -msgid "Creating VIF for VM %s, network %s." +msgid "Created project %(name)s with manager %(manager_user)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:205 +#: ../nova/auth/manager.py:533 #, python-format -msgid "Created VIF %s for VM %s, network %s." -msgstr "" +msgid "modifying project %s" +msgstr "изменение проекта %s" -#: nova/virt/xenapi/vm_utils.py:216 +#: ../nova/auth/manager.py:545 #, python-format -msgid "Snapshotting VM %s with label '%s'..." +msgid "Adding user %(uid)s to project %(pid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:229 +#: ../nova/auth/manager.py:566 #, python-format -msgid "Created snapshot %s from VM %s." +msgid "Remove user %(uid)s from project %(pid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:243 +#: ../nova/auth/manager.py:592 #, python-format -msgid "Asking xapi to upload %s as '%s'" -msgstr "" +msgid "Deleting project %s" +msgstr "Удаление проекта %s" -#: nova/virt/xenapi/vm_utils.py:261 +#: ../nova/auth/manager.py:650 #, python-format -msgid "Asking xapi to fetch %s as %s" +msgid "Created user %(rvname)s (admin: %(rvadmin)r)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:279 +#: ../nova/auth/manager.py:659 #, python-format -msgid "Looking up vdi %s for PV kernel" -msgstr "" +msgid "Deleting user %s" +msgstr "Удаление пользователя %s" -#: nova/virt/xenapi/vm_utils.py:290 +#: ../nova/auth/manager.py:669 #, python-format -msgid "PV Kernel in VDI:%d" +msgid "Access Key change for user %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:318 +#: ../nova/auth/manager.py:671 #, python-format -msgid "VDI %s is still available" +msgid "Secret Key change for user %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:331 +#: ../nova/auth/manager.py:673 #, python-format -msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgid "Admin status set to %(admin)r for user %(uid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:333 +#: ../nova/auth/manager.py:722 #, python-format -msgid "(VM_UTILS) xenapi power_state -> |%s|" -msgstr "" +msgid "No vpn data for project %s" +msgstr "Нет vpn данных для проекта %s" -#: nova/virt/xenapi/vm_utils.py:390 +#: ../nova/service.py:161 #, python-format -msgid "VHD %s has parent %s" +msgid "Starting %(topic)s node (version %(vcs_string)s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:407 -#, python-format -msgid "Re-scanning SR %s" +#: ../nova/service.py:174 +msgid "Service killed that has no database entry" msgstr "" -#: nova/virt/xenapi/vm_utils.py:431 -#, python-format -msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +#: ../nova/service.py:195 +msgid "The service database object disappeared, Recreating it." +msgstr "Объект сервиса в базе данных отсутствует, Повторное создание." + +#: ../nova/service.py:207 +msgid "Recovered model server connection!" msgstr "" -#: nova/virt/xenapi/vm_utils.py:448 -#, python-format -msgid "No VDIs found for VM %s" +#: ../nova/service.py:213 +msgid "model server went away" msgstr "" -#: nova/virt/xenapi/vm_utils.py:452 +#: ../nova/auth/ldapdriver.py:174 #, python-format -msgid "Unexpected number of VDIs (%s) found for VM %s" +msgid "LDAP user %s already exists" msgstr "" -#: nova/virt/xenapi/vmops.py:62 +#: ../nova/auth/ldapdriver.py:205 #, python-format -msgid "Attempted to create non-unique name %s" -msgstr "" +msgid "LDAP object for %s doesn't exist" +msgstr "Объект LDAP %s не существует" -#: nova/virt/xenapi/vmops.py:99 +#: ../nova/auth/ldapdriver.py:348 #, python-format -msgid "Starting VM %s..." +msgid "User %s doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:101 +#: ../nova/auth/ldapdriver.py:472 #, python-format -msgid "Spawning VM %s created %s." +msgid "Group can't be created because group %s already exists" msgstr "" -#: nova/virt/xenapi/vmops.py:112 +#: ../nova/auth/ldapdriver.py:478 #, python-format -msgid "Instance %s: booted" +msgid "Group can't be created because user %s doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:137 +#: ../nova/auth/ldapdriver.py:495 #, python-format -msgid "Instance not present %s" +msgid "User %s can't be searched in group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:166 +#: ../nova/auth/ldapdriver.py:507 #, python-format -msgid "Starting snapshot for VM %s" +msgid "User %s can't be added to the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:174 +#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521 #, python-format -msgid "Unable to Snapshot %s: %s" +msgid "The group at dn %s doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:184 +#: ../nova/auth/ldapdriver.py:513 #, python-format -msgid "Finished snapshot and upload for VM %s" +msgid "User %(uid)s is already a member of the group %(group_dn)s" msgstr "" -#: nova/virt/xenapi/vmops.py:252 +#: ../nova/auth/ldapdriver.py:524 #, python-format -msgid "suspend: instance not present %s" +msgid "" +"User %s can't be removed from the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:262 +#: ../nova/auth/ldapdriver.py:528 #, python-format -msgid "resume: instance not present %s" +msgid "User %s is not a member of the group" msgstr "" -#: nova/virt/xenapi/vmops.py:271 +#: ../nova/auth/ldapdriver.py:542 #, python-format -msgid "Instance not found %s" +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." msgstr "" -#: nova/virt/xenapi/volume_utils.py:57 +#: ../nova/auth/ldapdriver.py:549 #, python-format -msgid "Introducing %s..." +msgid "User %s can't be removed from all because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:74 +#: ../nova/auth/ldapdriver.py:564 #, python-format -msgid "Introduced %s as %s." +msgid "Group at dn %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:78 -msgid "Unable to create Storage Repository" +#: ../nova/virt/xenapi/network_utils.py:40 +#, python-format +msgid "Found non-unique network for bridge %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:90 +#: ../nova/virt/xenapi/network_utils.py:43 #, python-format -msgid "Unable to find SR from VBD %s" +msgid "Found no network for bridge %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:96 +#: ../nova/api/ec2/admin.py:97 #, python-format -msgid "Forgetting SR %s ... " -msgstr "" +msgid "Creating new user: %s" +msgstr "Создание нового пользователя: %s" -#: nova/virt/xenapi/volume_utils.py:101 +#: ../nova/api/ec2/admin.py:105 #, python-format -msgid "Ignoring exception %s when getting PBDs for %s" -msgstr "" +msgid "Deleting user: %s" +msgstr "Удаление пользователя: %s" -#: nova/virt/xenapi/volume_utils.py:107 +#: ../nova/api/ec2/admin.py:127 #, python-format -msgid "Ignoring exception %s when unplugging PBD %s" +msgid "Adding role %(role)s to user %(user)s for project %(project)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:111 +#: ../nova/api/ec2/admin.py:131 #, python-format -msgid "Forgetting SR %s done." +msgid "Adding sitewide role %(role)s to user %(user)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:113 +#: ../nova/api/ec2/admin.py:137 #, python-format -msgid "Ignoring exception %s when forgetting SR %s" +msgid "Removing role %(role)s from user %(user)s for project %(project)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:123 +#: ../nova/api/ec2/admin.py:141 #, python-format -msgid "Unable to introduce VDI on SR %s" +msgid "Removing sitewide role %(role)s from user %(user)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:128 -#, python-format -msgid "Unable to get record of VDI %s on" +#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223 +msgid "operation must be add or remove" msgstr "" -#: nova/virt/xenapi/volume_utils.py:146 +#: ../nova/api/ec2/admin.py:159 #, python-format -msgid "Unable to introduce VDI for SR %s" +msgid "Getting x509 for user: %(name)s on project: %(project)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:175 +#: ../nova/api/ec2/admin.py:177 #, python-format -msgid "Unable to obtain target information %s, %s" +msgid "Create project %(name)s managed by %(manager_user)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:197 +#: ../nova/api/ec2/admin.py:190 #, python-format -msgid "Mountpoint cannot be translated: %s" +msgid "Modify project: %(name)s managed by %(manager_user)s" msgstr "" -#: nova/virt/xenapi/volumeops.py:51 +#: ../nova/api/ec2/admin.py:200 #, python-format -msgid "Attach_volume: %s, %s, %s" -msgstr "" +msgid "Delete project: %s" +msgstr "Удалить проект: %s" -#: nova/virt/xenapi/volumeops.py:69 +#: ../nova/api/ec2/admin.py:214 #, python-format -msgid "Unable to create VDI on SR %s for instance %s" +msgid "Adding user %(user)s to project %(project)s" msgstr "" -#: nova/virt/xenapi/volumeops.py:81 +#: ../nova/api/ec2/admin.py:218 #, python-format -msgid "Unable to use SR %s for instance %s" +msgid "Removing user %(user)s from project %(project)s" msgstr "" -#: nova/virt/xenapi/volumeops.py:93 #, python-format -msgid "Unable to attach volume to instance %s" -msgstr "" +#~ msgid "arg: %s\t\tval: %s" +#~ msgstr "arg: %s\t\tval: %s" -#: nova/virt/xenapi/volumeops.py:95 #, python-format -msgid "Mountpoint %s attached to instance %s" -msgstr "" +#~ msgid "Adding role %s to user %s for project %s" +#~ msgstr "Добавление роли %s для пользователя %s для проекта %s" -#: nova/virt/xenapi/volumeops.py:106 #, python-format -msgid "Detach_volume: %s, %s" -msgstr "" +#~ msgid "Removing role %s from user %s for project %s" +#~ msgstr "Удаление роли %s пользователя %s для проекта %s" -#: nova/virt/xenapi/volumeops.py:113 #, python-format -msgid "Unable to locate volume %s" -msgstr "" +#~ msgid "Create project %s managed by %s" +#~ msgstr "Создать проект %s под управлением %s" -#: nova/virt/xenapi/volumeops.py:121 #, python-format -msgid "Unable to detach volume %s" -msgstr "" +#~ msgid "Removing user %s from project %s" +#~ msgstr "Удаление пользователя %s с проекта %s" -#: nova/virt/xenapi/volumeops.py:128 #, python-format -msgid "Mountpoint %s detached from instance %s" -msgstr "" +#~ msgid "Adding user %s to project %s" +#~ msgstr "Добавление пользователя %s к проекту %s" -#: nova/volume/api.py:44 #, python-format -msgid "Quota exceeeded for %s, tried to create %sG volume" -msgstr "" +#~ msgid "User %s is already a member of the group %s" +#~ msgstr "Пользователь %s уже член группы %s" -#: nova/volume/api.py:46 #, python-format -msgid "Volume quota exceeded. You cannot create a volume of size %s" -msgstr "" +#~ msgid "User %s is not a member of project %s" +#~ msgstr "Пользователь %s не является членом группы %s" -#: nova/volume/api.py:70 nova/volume/api.py:95 -msgid "Volume status must be available" -msgstr "" +#, python-format +#~ msgid "Created project %s with manager %s" +#~ msgstr "Создан проект %s под управлением %s" -#: nova/volume/api.py:97 -msgid "Volume is already attached" -msgstr "" +#, python-format +#~ msgid "Removing role %s from user %s on project %s" +#~ msgstr "Удаление роли %s пользователя %s в проекте %s" -#: nova/volume/api.py:103 -msgid "Volume is already detached" -msgstr "" +#, python-format +#~ msgid "Remove user %s from project %s" +#~ msgstr "Удалить пользователя %s из проекта %s" -#: nova/volume/driver.py:76 #, python-format -msgid "Recovering from a failed execute. Try number %s" -msgstr "" +#~ msgid "Created user %s (admin: %r)" +#~ msgstr "Создан пользователь %s (администратор: %r)" -#: nova/volume/driver.py:85 #, python-format -msgid "volume group %s doesn't exist" -msgstr "" +#~ msgid "Adding role %s to user %s in project %s" +#~ msgstr "Добавление роли %s для пользователя %s в проект %s" -#: nova/volume/driver.py:210 #, python-format -msgid "FAKE AOE: %s" -msgstr "" +#~ msgid "Getting object: %s / %s" +#~ msgstr "Получение объекта: %s / %s" -#: nova/volume/driver.py:315 #, python-format -msgid "FAKE ISCSI: %s" -msgstr "" +#~ msgid "Deleting object: %s / %s" +#~ msgstr "Удаление объекта: %s / %s" -#: nova/volume/manager.py:85 #, python-format -msgid "Re-exporting %s volumes" -msgstr "" +#~ msgid "%s: _db_content => %s" +#~ msgstr "%s: _db_content => %s" -#: nova/volume/manager.py:93 #, python-format -msgid "volume %s: creating" -msgstr "" +#~ msgid "Calling %s %s" +#~ msgstr "Звонок %s %s" -#: nova/volume/manager.py:102 #, python-format -msgid "volume %s: creating lv of size %sG" -msgstr "" +#~ 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/volume/manager.py:106 #, python-format -msgid "volume %s: creating export" -msgstr "" +#~ msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +#~ msgstr "AMQP сервер %s:%d недоступен. Повторная попытка через %d секунд." -#: nova/volume/manager.py:113 #, python-format -msgid "volume %s: created successfully" -msgstr "" +#~ msgid "Putting object: %s / %s" +#~ msgstr "Вставка объекта: %s / %s" -#: nova/volume/manager.py:121 -msgid "Volume is still attached" -msgstr "" +#, python-format +#~ msgid "Starting %s node" +#~ msgstr "Запускается нода %s" -#: nova/volume/manager.py:123 -msgid "Volume is not local to this node" -msgstr "" +#, python-format +#~ msgid "Data store %s is unreachable. Trying again in %d seconds." +#~ msgstr "Хранилище данных %s недоступно. Повторная попытка через %d секунд." -#: nova/volume/manager.py:124 #, python-format -msgid "volume %s: removing export" -msgstr "" +#~ msgid "Couldn't get IP, using 127.0.0.1 %s" +#~ msgstr "Не удалось получить IP, используем 127.0.0.1 %s" -#: nova/volume/manager.py:126 #, python-format -msgid "volume %s: deleting" -msgstr "" +#~ msgid "Getting from %s: %s" +#~ msgstr "Получение из %s: %s" -#: nova/volume/manager.py:129 #, python-format -msgid "volume %s: deleted successfully" -msgstr "" +#~ msgid "" +#~ "Access key %s has had %d failed authentications and will be locked out for " +#~ "%d minutes." +#~ msgstr "" +#~ "Ключ доступа %s имеет %d неудачных попыток аутентификации и будет " +#~ "заблокирован на %d минут." + +#, python-format +#~ msgid "Authenticated Request For %s:%s)" +#~ msgstr "Запрос аутентификации для %s:%s)" diff --git a/po/uk.po b/po/uk.po index f3e217690..d28860c9b 100644 --- a/po/uk.po +++ b/po/uk.po @@ -7,2129 +7,2876 @@ msgid "" msgstr "" "Project-Id-Version: nova\n" "Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2011-01-10 11:25-0800\n" +"POT-Creation-Date: 2011-02-21 10:03-0500\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-02-05 05:36+0000\n" -"X-Generator: Launchpad (build 12177)\n" +"X-Launchpad-Export-Date: 2011-03-19 06:19+0000\n" +"X-Generator: Launchpad (build 12559)\n" -#: nova/crypto.py:46 +#: ../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 "" + +#: ../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/api/openstack/servers.py:72 +msgid "Failed to read private ip" +msgstr "" + +#: ../nova/api/openstack/servers.py:79 +msgid "Failed to read public ip(s)" +msgstr "" + +#: ../nova/api/openstack/servers.py:152 +#, python-format +msgid "%(param)s property not found for image %(_image_id)s" +msgstr "" + +#: ../nova/api/openstack/servers.py:168 +msgid "No keypairs defined" +msgstr "" + +#: ../nova/api/openstack/servers.py:238 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:253 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:267 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:281 +#, python-format +msgid "Compute.api::reset_network %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:292 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:303 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:314 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:325 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: ../nova/twistd.py:157 +msgid "Wrong number of arguments." +msgstr "" + +#: ../nova/twistd.py:209 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "" + +#: ../nova/twistd.py:221 +msgid "No such process" +msgstr "" + +#: ../nova/twistd.py:230 ../nova/service.py:224 +#, python-format +msgid "Serving %s" +msgstr "Обслуговування %s" + +#: ../nova/twistd.py:262 ../nova/service.py:225 +msgid "Full set of FLAGS:" +msgstr "" + +#: ../nova/twistd.py:266 +#, python-format +msgid "Starting %s" +msgstr "Запускається %s" + +#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101 +#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741 +#: ../nova/api/ec2/__init__.py:317 +#, 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 +#: ../nova/crypto.py:49 msgid "Filename of private key" msgstr "Ім'я файлу секретного ключа" -#: nova/crypto.py:51 +#: ../nova/crypto.py:51 msgid "Filename of root Certificate Revokation List" msgstr "" -#: nova/crypto.py:53 +#: ../nova/crypto.py:53 msgid "Where we keep our keys" msgstr "Шлях до збережених ключів" -#: nova/crypto.py:55 +#: ../nova/crypto.py:55 msgid "Where we keep our root CA" msgstr "" -#: nova/crypto.py:57 +#: ../nova/crypto.py:57 msgid "Should we use a CA for each project?" msgstr "" -#: nova/crypto.py:61 +#: ../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:78 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:80 +#, python-format +msgid "" +"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|" +msgstr "" + +#: ../nova/compute/manager.py:84 +#, python-format +msgid "check_instance_lock: locked: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:86 +#, python-format +msgid "check_instance_lock: admin: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:91 +#, python-format +msgid "check_instance_lock: executing: |%s|" +msgstr "" + +#: ../nova/compute/manager.py:95 +#, python-format +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: ../nova/compute/manager.py:179 +msgid "Instance has already been created" +msgstr "" + +#: ../nova/compute/manager.py:180 +#, python-format +msgid "instance %s: starting..." +msgstr "" + +#. pylint: disable=W0702 +#: ../nova/compute/manager.py:219 +#, python-format +msgid "instance %s: Failed to spawn" +msgstr "" + +#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286 +#, python-format +msgid "Terminating instance %s" +msgstr "" + +#: ../nova/compute/manager.py:255 +#, python-format +msgid "Deallocating address %s" +msgstr "" + +#: ../nova/compute/manager.py:268 +#, python-format +msgid "trying to destroy already destroyed instance: %s" +msgstr "" + +#: ../nova/compute/manager.py:282 +#, python-format +msgid "Rebooting instance %s" +msgstr "" + +#: ../nova/compute/manager.py:287 +#, python-format +msgid "" +"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:311 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: ../nova/compute/manager.py:316 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:332 +#, python-format +msgid "" +"trying to reset the password on a non-running instance: %(instance_id)s " +"(state: %(instance_state)s expected: %(expected_state)s)" +msgstr "" + +#: ../nova/compute/manager.py:335 +#, python-format +msgid "instance %s: setting admin password" +msgstr "" + +#: ../nova/compute/manager.py:353 +#, python-format +msgid "" +"trying to inject a file into a non-running instance: %(instance_id)s (state: " +"%(instance_state)s expected: %(expected_state)s)" +msgstr "" + +#: ../nova/compute/manager.py:362 +#, python-format +msgid "instance %(nm)s: injecting file to %(plain_path)s" +msgstr "" + +#: ../nova/compute/manager.py:372 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: ../nova/compute/manager.py:387 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: ../nova/compute/manager.py:406 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: ../nova/compute/manager.py:423 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: ../nova/compute/manager.py:440 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: ../nova/compute/manager.py:453 +#, python-format +msgid "instance %s: suspending" +msgstr "" + +#: ../nova/compute/manager.py:472 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: ../nova/compute/manager.py:491 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: ../nova/compute/manager.py:503 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: ../nova/compute/manager.py:513 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: ../nova/compute/manager.py:526 +#, python-format +msgid "instance %s: reset network" +msgstr "" + +#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515 +#, python-format +msgid "Get console output for instance %s" +msgstr "" + +#: ../nova/compute/manager.py:543 +#, python-format +msgid "instance %s: getting ajax console" +msgstr "" + +#: ../nova/compute/manager.py:553 +#, python-format +msgid "" +"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s" +msgstr "" + +#. pylint: disable=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:569 +#, python-format +msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing" +msgstr "" + +#: ../nova/compute/manager.py:585 +#, python-format +msgid "" +"Detach volume %(volume_id)s from mountpoint %(mp)s on instance " +"%(instance_id)s" +msgstr "" + +#: ../nova/compute/manager.py:588 +#, 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:304 ../nova/virt/xenapi/fake.py:404 +#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478 +msgid "Raising NotImplemented" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:306 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:341 +#, python-format +msgid "Calling %(localname)s %(impl)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:346 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:406 +#, 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:187 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: ../nova/network/linux_net.py:208 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:314 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:316 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:358 +#, python-format +msgid "killing radvd threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:360 +#, python-format +msgid "Pid %d is stale, relaunching radvd" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:449 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: ../nova/utils.py:58 +#, python-format +msgid "Inner Exception: %s" +msgstr "" + +#: ../nova/utils.py:59 +#, python-format +msgid "Class %s cannot be found" +msgstr "" + +#: ../nova/utils.py:118 +#, python-format +msgid "Fetching %s" +msgstr "" + +#: ../nova/utils.py:130 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "" + +#: ../nova/utils.py:143 ../nova/utils.py:183 +#, python-format +msgid "Result was %s" +msgstr "" + +#: ../nova/utils.py:159 +#, python-format +msgid "Running cmd (SSH): %s" +msgstr "" + +#: ../nova/utils.py:217 +#, python-format +msgid "debug in callback: %s" +msgstr "" + +#: ../nova/utils.py:222 +#, python-format +msgid "Running %s" +msgstr "Запускається %s" + +#: ../nova/utils.py:262 +#, python-format +msgid "Link Local address is not found.:%s" +msgstr "" + +#: ../nova/utils.py:265 +#, python-format +msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s" +msgstr "" + +#: ../nova/utils.py:363 +#, python-format +msgid "Invalid backend: %s" +msgstr "" + +#: ../nova/utils.py:374 +#, 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 "Оголошення черги %s" + +#: ../nova/fakerabbit.py:90 +#, python-format +msgid "Declaring exchange %s" +msgstr "Оголошення точки обміну %s" + +#: ../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:168 +#, python-format +msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:171 +#, python-format +msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "VBD not found in instance %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:197 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:209 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:224 #, python-format -msgid "Subject for certificate for users, %s for project, user, timestamp" +msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s." msgstr "" -#: nova/crypto.py:66 +#: ../nova/virt/xenapi/vm_utils.py:227 #, python-format -msgid "Subject for certificate for projects, %s for project, timestamp" +msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s." msgstr "" -#: nova/crypto.py:71 +#: ../nova/virt/xenapi/vm_utils.py:246 #, python-format -msgid "Subject for certificate for vpns, %s for project, timestamp" +msgid "" +"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on " +"%(sr_ref)s." msgstr "" -#: nova/crypto.py:258 +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vm_utils.py:258 #, python-format -msgid "Flags path: %s" +msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..." msgstr "" -#: nova/exception.py:33 -msgid "Unexpected error while running command." -msgstr "Неочікувана помилка при виконанні команди." +#: ../nova/virt/xenapi/vm_utils.py:272 +#, python-format +msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s." +msgstr "" -#: nova/exception.py:36 +#: ../nova/virt/xenapi/vm_utils.py:286 #, 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 "Необроблене виключення" +msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s" +msgstr "" -#: nova/fakerabbit.py:48 +#: ../nova/virt/xenapi/vm_utils.py:327 #, python-format -msgid "(%s) publish (key: %s) %s" +msgid "Size for image %(image)s:%(virtual_size)d" msgstr "" -#: nova/fakerabbit.py:53 +#: ../nova/virt/xenapi/vm_utils.py:332 #, python-format -msgid "Publishing to route %s" +msgid "Glance image %s" msgstr "" -#: nova/fakerabbit.py:83 +#. we need to invoke a plugin for copying VDI's +#. content into proper path +#: ../nova/virt/xenapi/vm_utils.py:342 #, python-format -msgid "Declaring queue %s" -msgstr "Оголошення черги %s" +msgid "Copying VDI %s to /boot/guest on dom0" +msgstr "" -#: nova/fakerabbit.py:89 +#: ../nova/virt/xenapi/vm_utils.py:352 #, python-format -msgid "Declaring exchange %s" -msgstr "Оголошення точки обміну %s" +msgid "Kernel/Ramdisk VDI %s destroyed" +msgstr "" -#: nova/fakerabbit.py:95 +#: ../nova/virt/xenapi/vm_utils.py:361 #, python-format -msgid "Binding %s to %s with key %s" +msgid "Asking xapi to fetch %(url)s as %(access)s" msgstr "" -#: nova/fakerabbit.py:120 +#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402 #, python-format -msgid "Getting from %s: %s" -msgstr "Отримання з %s: %s" +msgid "Looking up vdi %s for PV kernel" +msgstr "" -#: nova/rpc.py:92 +#: ../nova/virt/xenapi/vm_utils.py:397 #, python-format -msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." -msgstr "AMQP сервер %s:%d недоступний. Спроба під'єднання через %d секунд." +msgid "PV Kernel in VDI:%s" +msgstr "" -#: nova/rpc.py:99 +#: ../nova/virt/xenapi/vm_utils.py:405 #, python-format -msgid "Unable to connect to AMQP server after %d tries. Shutting down." -msgstr "Не вдалось під'єднатися до серверу AMQP після %d спроб. Вимкнення." +msgid "Running pygrub against %s" +msgstr "" -#: nova/rpc.py:118 -msgid "Reconnected to queue" -msgstr "Оновлено з'єднання до черги" +#: ../nova/virt/xenapi/vm_utils.py:411 +#, python-format +msgid "Found Xen kernel %s" +msgstr "" -#: nova/rpc.py:125 -msgid "Failed to fetch message from queue" +#: ../nova/virt/xenapi/vm_utils.py:413 +msgid "No Xen kernel found. Booting HVM." msgstr "" -#: nova/rpc.py:155 +#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431 #, python-format -msgid "Initing the Adapter Consumer for %s" +msgid "duplicate name found: %s" msgstr "" -#: nova/rpc.py:170 +#: ../nova/virt/xenapi/vm_utils.py:442 #, python-format -msgid "received %s" -msgstr "отримано %s" +msgid "VDI %s is still available" +msgstr "" -#: nova/rpc.py:183 +#: ../nova/virt/xenapi/vm_utils.py:463 #, python-format -msgid "no method for message: %s" -msgstr "без порядку для повідомлень: %s" +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "" -#: nova/rpc.py:184 +#: ../nova/virt/xenapi/vm_utils.py:465 #, python-format -msgid "No method for message: %s" -msgstr "Без порядку для повідомлень: %s" +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "" -#: nova/rpc.py:245 +#: ../nova/virt/xenapi/vm_utils.py:525 #, python-format -msgid "Returning exception %s to caller" +msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s" msgstr "" -#: nova/rpc.py:286 +#: ../nova/virt/xenapi/vm_utils.py:542 #, python-format -msgid "unpacked context: %s" +msgid "Re-scanning SR %s" msgstr "" -#: nova/rpc.py:305 -msgid "Making asynchronous call..." -msgstr "Створення асинхронного виклику..." +#: ../nova/virt/xenapi/vm_utils.py:567 +#, python-format +msgid "" +"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..." +msgstr "" -#: nova/rpc.py:308 +#: ../nova/virt/xenapi/vm_utils.py:574 #, python-format -msgid "MSG_ID is %s" -msgstr "MSG_ID %s" +msgid "" +"Parent %(parent_uuid)s doesn't match original parent " +"%(original_parent_uuid)s, waiting for coalesce..." +msgstr "" -#: nova/rpc.py:356 +#: ../nova/virt/xenapi/vm_utils.py:590 #, python-format -msgid "response %s" -msgstr "відповідь %s" +msgid "No VDIs found for VM %s" +msgstr "" -#: nova/rpc.py:365 +#: ../nova/virt/xenapi/vm_utils.py:594 #, python-format -msgid "topic is %s" -msgstr "заголовок %s" +msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s" +msgstr "" -#: nova/rpc.py:366 +#: ../nova/virt/xenapi/vm_utils.py:653 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188 #, python-format -msgid "message %s" -msgstr "повідомлення %s" +msgid "Creating VBD for VDI %s ... " +msgstr "" -#: nova/service.py:157 +#: ../nova/virt/xenapi/vm_utils.py:655 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190 #, python-format -msgid "Starting %s node" +msgid "Creating VBD for VDI %s done." msgstr "" -#: nova/service.py:169 -msgid "Service killed that has no database entry" +#: ../nova/virt/xenapi/vm_utils.py:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192 +#, python-format +msgid "Plugging VBD %s ... " msgstr "" -#: nova/service.py:190 -msgid "The service database object disappeared, Recreating it." +#: ../nova/virt/xenapi/vm_utils.py:659 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:194 +#, python-format +msgid "Plugging VBD %s done." msgstr "" -#: nova/service.py:202 -msgid "Recovered model server connection!" +#: ../nova/virt/xenapi/vm_utils.py:661 +#, python-format +msgid "VBD %(vbd)s plugged as %(orig_dev)s" msgstr "" -#: nova/service.py:208 -msgid "model server went away" +#: ../nova/virt/xenapi/vm_utils.py:664 +#, python-format +msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s" msgstr "" -#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#: ../nova/virt/xenapi/vm_utils.py:668 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:197 #, python-format -msgid "Data store %s is unreachable. Trying again in %d seconds." +msgid "Destroying VBD for VDI %s ... " msgstr "" -#: nova/service.py:232 nova/twistd.py:232 +#: ../nova/virt/xenapi/vm_utils.py:671 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:200 #, python-format -msgid "Serving %s" -msgstr "Обслуговування %s" +msgid "Destroying VBD for VDI %s done." +msgstr "" -#: nova/service.py:234 nova/twistd.py:264 -msgid "Full set of FLAGS:" +#: ../nova/virt/xenapi/vm_utils.py:683 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211 +msgid "VBD.unplug successful first time." msgstr "" -#: nova/twistd.py:211 -#, python-format -msgid "pidfile %s does not exist. Daemon not running?\n" +#: ../nova/virt/xenapi/vm_utils.py:688 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216 +msgid "VBD.unplug rejected: retrying..." msgstr "" -#: nova/twistd.py:268 -#, python-format -msgid "Starting %s" -msgstr "Запускається %s" +#: ../nova/virt/xenapi/vm_utils.py:692 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220 +msgid "VBD.unplug successful eventually." +msgstr "" -#: nova/utils.py:53 +#: ../nova/virt/xenapi/vm_utils.py:695 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:223 #, python-format -msgid "Inner Exception: %s" +msgid "Ignoring XenAPI.Failure in VBD.unplug: %s" msgstr "" -#: nova/utils.py:54 +#: ../nova/virt/xenapi/vm_utils.py:704 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:66 #, python-format -msgid "Class %s cannot be found" +msgid "Ignoring XenAPI.Failure %s" msgstr "" -#: nova/utils.py:113 +#: ../nova/virt/xenapi/vm_utils.py:735 #, python-format -msgid "Fetching %s" +msgid "" +"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..." msgstr "" -#: nova/utils.py:125 +#: ../nova/virt/xenapi/vm_utils.py:747 #, python-format -msgid "Running cmd (subprocess): %s" +msgid "Writing partition table %s done." msgstr "" -#: nova/utils.py:138 +#: ../nova/tests/test_rpc.py:89 #, python-format -msgid "Result was %s" +msgid "Nested received %(queue)s, %(value)s" msgstr "" -#: nova/utils.py:171 +#: ../nova/tests/test_rpc.py:95 #, python-format -msgid "debug in callback: %s" +msgid "Nested return %s" msgstr "" -#: nova/utils.py:176 +#: ../nova/tests/test_rpc.py:120 ../nova/tests/test_rpc.py:126 #, python-format -msgid "Running %s" -msgstr "Запускається %s" +msgid "Received %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/db/sqlalchemy/api.py:44 +msgid "Use of empty request context is deprecated" +msgstr "" -#: nova/utils.py:289 +#: ../nova/db/sqlalchemy/api.py:133 #, python-format -msgid "Invalid backend: %s" +msgid "No service for id %s" msgstr "" -#: nova/utils.py:300 +#: ../nova/db/sqlalchemy/api.py:251 #, python-format -msgid "backend %s" +msgid "No service for %(host)s, %(binary)s" msgstr "" -#: nova/api/ec2/__init__.py:133 -msgid "Too many failed authentications." -msgstr "Занадто багато невдалих аутентифікацій." +#: ../nova/db/sqlalchemy/api.py:592 +msgid "No fixed ips defined" +msgstr "" -#: nova/api/ec2/__init__.py:142 +#: ../nova/db/sqlalchemy/api.py:608 #, python-format -msgid "" -"Access key %s has had %d failed authentications and will be locked out for " -"%d minutes." +msgid "No floating ip for address %s" msgstr "" -#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#: ../nova/db/sqlalchemy/api.py:629 #, python-format -msgid "Authentication Failure: %s" +msgid "No address for instance %s" msgstr "" -#: nova/api/ec2/__init__.py:190 +#: ../nova/db/sqlalchemy/api.py:961 #, python-format -msgid "Authenticated Request For %s:%s)" +msgid "no keypair for user %(user_id)s, name %(name)s" msgstr "" -#: nova/api/ec2/__init__.py:227 +#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156 #, python-format -msgid "action: %s" +msgid "No network for id %s" msgstr "" -#: nova/api/ec2/__init__.py:229 -#, python-format -msgid "arg: %s\t\tval: %s" +#: ../nova/db/sqlalchemy/api.py:1086 +msgid "No networks defined" msgstr "" -#: nova/api/ec2/__init__.py:301 +#: ../nova/db/sqlalchemy/api.py:1115 #, python-format -msgid "Unauthorized request for controller=%s and action=%s" +msgid "No network for bridge %s" msgstr "" -#: nova/api/ec2/__init__.py:339 +#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142 #, python-format -msgid "NotFound raised: %s" +msgid "No network for instance %s" msgstr "" -#: nova/api/ec2/__init__.py:342 +#: ../nova/db/sqlalchemy/api.py:1277 #, python-format -msgid "ApiError raised: %s" +msgid "Token %s does not exist" msgstr "" -#: nova/api/ec2/__init__.py:349 +#: ../nova/db/sqlalchemy/api.py:1302 #, python-format -msgid "Unexpected error raised: %s" +msgid "No quota for project_id %s" msgstr "" -#: nova/api/ec2/__init__.py:354 -msgid "An unknown error has occurred. Please try your request again." +#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501 +#: ../nova/api/ec2/__init__.py:323 +#, python-format +msgid "Volume %s not found" msgstr "" -#: nova/api/ec2/admin.py:84 +#: ../nova/db/sqlalchemy/api.py:1514 #, python-format -msgid "Creating new user: %s" +msgid "No export device found for volume %s" msgstr "" -#: nova/api/ec2/admin.py:92 +#: ../nova/db/sqlalchemy/api.py:1527 #, python-format -msgid "Deleting user: %s" +msgid "No target id found for volume %s" msgstr "" -#: nova/api/ec2/admin.py:114 +#: ../nova/db/sqlalchemy/api.py:1572 #, python-format -msgid "Adding role %s to user %s for project %s" +msgid "No security group with id %s" msgstr "" -#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#: ../nova/db/sqlalchemy/api.py:1589 #, python-format -msgid "Adding sitewide role %s to user %s" +msgid "No security group named %(group_name)s for project: %(project_id)s" msgstr "" -#: nova/api/ec2/admin.py:122 +#: ../nova/db/sqlalchemy/api.py:1682 #, python-format -msgid "Removing role %s from user %s for project %s" +msgid "No secuity group rule with id %s" msgstr "" -#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#: ../nova/db/sqlalchemy/api.py:1756 #, python-format -msgid "Removing sitewide role %s from user %s" +msgid "No user for id %s" msgstr "" -#: nova/api/ec2/admin.py:129 nova/api/ec2/admin.py:192 -msgid "operation must be add or remove" +#: ../nova/db/sqlalchemy/api.py:1772 +#, python-format +msgid "No user for access key %s" msgstr "" -#: nova/api/ec2/admin.py:142 +#: ../nova/db/sqlalchemy/api.py:1834 #, python-format -msgid "Getting x509 for user: %s on project: %s" +msgid "No project with id %s" msgstr "" -#: nova/api/ec2/admin.py:159 +#: ../nova/db/sqlalchemy/api.py:1979 #, python-format -msgid "Create project %s managed by %s" +msgid "No console pool with id %(pool_id)s" msgstr "" -#: nova/api/ec2/admin.py:170 +#: ../nova/db/sqlalchemy/api.py:1996 #, python-format -msgid "Delete project: %s" -msgstr "Вилучити проект: %s" +msgid "" +"No console pool of type %(console_type)s for compute host %(compute_host)s " +"on proxy host %(host)s" +msgstr "" -#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#: ../nova/db/sqlalchemy/api.py:2035 #, python-format -msgid "Adding user %s to project %s" -msgstr "Долучення користувача %s до проекту %s" +msgid "No console for instance %(instance_id)s in pool %(pool_id)s" +msgstr "" -#: nova/api/ec2/admin.py:188 +#: ../nova/db/sqlalchemy/api.py:2057 #, python-format -msgid "Removing user %s from project %s" -msgstr "Вилучення користувача %s з проекту %s" +msgid "on instance %s" +msgstr "" -#: nova/api/ec2/apirequest.py:95 +#: ../nova/db/sqlalchemy/api.py:2058 #, python-format -msgid "Unsupported API request: controller = %s,action = %s" +msgid "No console with id %(console_id)s %(idesc)s" msgstr "" -#: nova/api/ec2/cloud.py:117 +#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097 #, python-format -msgid "Generating root CA: %s" +msgid "No zone with id %(zone_id)s" msgstr "" -#: nova/api/ec2/cloud.py:277 +#: ../nova/virt/libvirt_conn.py:160 #, python-format -msgid "Create key pair %s" +msgid "Checking state of %s" msgstr "" -#: nova/api/ec2/cloud.py:285 +#: ../nova/virt/libvirt_conn.py:165 #, python-format -msgid "Delete key pair %s" +msgid "Current state of %(name)s was %(state)s." msgstr "" -#: nova/api/ec2/cloud.py:357 +#: ../nova/virt/libvirt_conn.py:183 #, python-format -msgid "%s is not a valid ipProtocol" -msgstr "%s не допустимий ipProtocol" +msgid "Connecting to libvirt: %s" +msgstr "" -#: nova/api/ec2/cloud.py:361 -msgid "Invalid port range" -msgstr "Невірний діапазон портів" +#: ../nova/virt/libvirt_conn.py:196 +msgid "Connection to libvirt broke" +msgstr "" -#: nova/api/ec2/cloud.py:392 +#: ../nova/virt/libvirt_conn.py:258 #, python-format -msgid "Revoke security group ingress %s" +msgid "instance %(instance_name)s: deleting instance files %(target)s" msgstr "" -#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 -msgid "No rule for the specified parameters." +#: ../nova/virt/libvirt_conn.py:283 +#, python-format +msgid "Invalid device path %s" msgstr "" -#: nova/api/ec2/cloud.py:421 +#: ../nova/virt/libvirt_conn.py:313 #, python-format -msgid "Authorize security group ingress %s" +msgid "No disk at %s" msgstr "" -#: nova/api/ec2/cloud.py:432 -#, python-format -msgid "This rule already exists in group %s" -msgstr "Це правило вже існує в групі %s" +#: ../nova/virt/libvirt_conn.py:320 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "" -#: nova/api/ec2/cloud.py:460 +#: ../nova/virt/libvirt_conn.py:336 #, python-format -msgid "Create Security Group %s" +msgid "instance %s: rebooted" msgstr "" -#: nova/api/ec2/cloud.py:463 +#: ../nova/virt/libvirt_conn.py:339 #, python-format -msgid "group %s already exists" +msgid "_wait_for_reboot failed: %s" msgstr "" -#: nova/api/ec2/cloud.py:475 +#: ../nova/virt/libvirt_conn.py:382 #, python-format -msgid "Delete security group %s" -msgstr "Вилучити групу безпеки %s" +msgid "instance %s: rescued" +msgstr "" -#: nova/api/ec2/cloud.py:483 nova/compute/manager.py:452 +#: ../nova/virt/libvirt_conn.py:385 #, python-format -msgid "Get console output for instance %s" +msgid "_wait_for_rescue failed: %s" msgstr "" -#: nova/api/ec2/cloud.py:543 +#: ../nova/virt/libvirt_conn.py:411 #, python-format -msgid "Create volume of %s GB" -msgstr "Створити розділ на %s ГБ" +msgid "instance %s: is running" +msgstr "" -#: nova/api/ec2/cloud.py:567 +#: ../nova/virt/libvirt_conn.py:422 #, python-format -msgid "Attach volume %s to instacne %s at %s" +msgid "instance %s: booted" msgstr "" -#: nova/api/ec2/cloud.py:579 +#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186 #, python-format -msgid "Detach volume %s" -msgstr "Від'єднати том %s" - -#: nova/api/ec2/cloud.py:686 -msgid "Allocate address" +msgid "instance %s: failed to boot" msgstr "" -#: nova/api/ec2/cloud.py:691 +#: ../nova/virt/libvirt_conn.py:436 #, python-format -msgid "Release address %s" +msgid "virsh said: %r" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:440 +msgid "cool, it's a device" msgstr "" -#: nova/api/ec2/cloud.py:696 +#: ../nova/virt/libvirt_conn.py:448 #, python-format -msgid "Associate address %s to instance %s" +msgid "data: %(data)r, fpath: %(fpath)r" msgstr "" -#: nova/api/ec2/cloud.py:703 +#: ../nova/virt/libvirt_conn.py:456 #, python-format -msgid "Disassociate address %s" +msgid "Contents of file %(fpath)s: %(contents)r" msgstr "" -#: nova/api/ec2/cloud.py:730 -msgid "Going to start terminating instances" +#: ../nova/virt/libvirt_conn.py:489 +msgid "Unable to find an open port" msgstr "" -#: nova/api/ec2/cloud.py:738 +#: ../nova/virt/libvirt_conn.py:563 #, python-format -msgid "Reboot instance %r" +msgid "instance %s: Creating image" msgstr "" -#: nova/api/ec2/cloud.py:775 +#: ../nova/virt/libvirt_conn.py:646 #, python-format -msgid "De-registering image %s" +msgid "instance %(inst_name)s: injecting key into image %(img_id)s" msgstr "" -#: nova/api/ec2/cloud.py:783 +#: ../nova/virt/libvirt_conn.py:649 #, python-format -msgid "Registered image %s with id %s" +msgid "instance %(inst_name)s: injecting net into image %(img_id)s" msgstr "" -#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#. This could be a windows image, or a vmdk format disk +#: ../nova/virt/libvirt_conn.py:657 #, python-format -msgid "attribute not supported: %s" +msgid "" +"instance %(inst_name)s: ignoring error injecting data into image %(img_id)s " +"(%(e)s)" msgstr "" -#: nova/api/ec2/cloud.py:794 +#. TODO(termie): cache? +#: ../nova/virt/libvirt_conn.py:665 #, python-format -msgid "invalid id: %s" +msgid "instance %s: starting toXML method" msgstr "" -#: nova/api/ec2/cloud.py:807 -msgid "user or group not specified" +#: ../nova/virt/libvirt_conn.py:732 +#, python-format +msgid "instance %s: finished toXML method" 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" +#: ../nova/virt/libvirt_conn.py:751 +msgid "diagnostics are not supported for libvirt" msgstr "" -#: nova/api/ec2/cloud.py:812 +#: ../nova/virt/libvirt_conn.py:1225 #, python-format -msgid "Updating image %s publicity" +msgid "Attempted to unfilter instance %s which is not filtered" msgstr "" -#: nova/api/ec2/metadatarequesthandler.py:75 +#: ../nova/api/ec2/metadatarequesthandler.py:76 #, 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." +#: ../nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" msgstr "" -#: nova/api/openstack/servers.py:184 +#: ../nova/network/api.py:39 #, python-format -msgid "Compute.api::lock %s" +msgid "Quota exceeeded for %s, tried to allocate address" msgstr "" -#: nova/api/openstack/servers.py:199 -#, python-format -msgid "Compute.api::unlock %s" +#: ../nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" msgstr "" -#: nova/api/openstack/servers.py:213 +#: ../nova/tests/test_volume.py:162 #, python-format -msgid "Compute.api::get_lock %s" +msgid "Target %s allocated" msgstr "" -#: nova/api/openstack/servers.py:224 +#: ../nova/virt/images.py:70 #, python-format -msgid "Compute.api::pause %s" +msgid "Finished retreving %(url)s -- placed in %(path)s" msgstr "" -#: nova/api/openstack/servers.py:235 -#, python-format -msgid "Compute.api::unpause %s" +#: ../nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" msgstr "" -#: nova/api/openstack/servers.py:246 -#, python-format -msgid "compute.api::suspend %s" +#: ../nova/console/manager.py:70 +msgid "Adding console" msgstr "" -#: nova/api/openstack/servers.py:257 +#: ../nova/console/manager.py:90 #, python-format -msgid "compute.api::resume %s" +msgid "Tried to remove non-existant console %(console_id)s." msgstr "" -#: nova/auth/dbdriver.py:84 -#, python-format -msgid "User %s already exists" -msgstr "Користувач %s вже існує" +#: ../nova/api/direct.py:149 +msgid "not available" +msgstr "" -#: nova/auth/dbdriver.py:106 nova/auth/ldapdriver.py:207 +#: ../nova/api/ec2/cloud.py:62 #, python-format -msgid "Project can't be created because manager %s doesn't exist" +msgid "The key_pair %s already exists" msgstr "" -#: nova/auth/dbdriver.py:135 nova/auth/ldapdriver.py:204 +#. TODO(vish): Do this with M2Crypto instead +#: ../nova/api/ec2/cloud.py:118 #, python-format -msgid "Project can't be created because project %s already exists" +msgid "Generating root CA: %s" msgstr "" -#: nova/auth/dbdriver.py:157 nova/auth/ldapdriver.py:241 +#: ../nova/api/ec2/cloud.py:303 #, python-format -msgid "Project can't be modified because manager %s doesn't exist" +msgid "Create key pair %s" msgstr "" -#: nova/auth/dbdriver.py:245 +#: ../nova/api/ec2/cloud.py:311 #, python-format -msgid "User \"%s\" not found" -msgstr "Користувач \"%s\" не знайдено" +msgid "Delete key pair %s" +msgstr "" -#: nova/auth/dbdriver.py:248 +#: ../nova/api/ec2/cloud.py:386 #, python-format -msgid "Project \"%s\" not found" -msgstr "Проект \"%s\" не знайдено" +msgid "%s is not a valid ipProtocol" +msgstr "%s не допустимий ipProtocol" -#: nova/auth/fakeldap.py:33 -msgid "Attempted to instantiate singleton" -msgstr "" +#: ../nova/api/ec2/cloud.py:390 +msgid "Invalid port range" +msgstr "Невірний діапазон портів" -#: nova/auth/ldapdriver.py:181 +#: ../nova/api/ec2/cloud.py:421 #, python-format -msgid "LDAP object for %s doesn't exist" +msgid "Revoke security group ingress %s" msgstr "" -#: nova/auth/ldapdriver.py:218 -#, python-format -msgid "Project can't be created because user %s doesn't exist" +#: ../nova/api/ec2/cloud.py:430 ../nova/api/ec2/cloud.py:459 +msgid "Not enough parameters to build a valid rule." msgstr "" -#: nova/auth/ldapdriver.py:478 -#, python-format -msgid "User %s is already a member of the group %s" +#: ../nova/api/ec2/cloud.py:443 +msgid "No rule for the specified parameters." msgstr "" -#: nova/auth/ldapdriver.py:507 +#: ../nova/api/ec2/cloud.py:450 #, python-format -msgid "" -"Attempted to remove the last member of a group. Deleting the group at %s " -"instead." +msgid "Authorize security group ingress %s" msgstr "" -#: nova/auth/ldapdriver.py:528 +#: ../nova/api/ec2/cloud.py:464 #, python-format -msgid "Group at dn %s doesn't exist" -msgstr "" +msgid "This rule already exists in group %s" +msgstr "Це правило вже існує в групі %s" -#: nova/auth/manager.py:259 +#: ../nova/api/ec2/cloud.py:492 #, python-format -msgid "Looking up user: %r" +msgid "Create Security Group %s" msgstr "" -#: nova/auth/manager.py:263 +#: ../nova/api/ec2/cloud.py:495 #, python-format -msgid "Failed authorization for access key %s" +msgid "group %s already exists" msgstr "" -#: nova/auth/manager.py:264 +#: ../nova/api/ec2/cloud.py:507 #, python-format -msgid "No user found for access key %s" -msgstr "" +msgid "Delete security group %s" +msgstr "Вилучити групу безпеки %s" -#: nova/auth/manager.py:270 +#: ../nova/api/ec2/cloud.py:584 #, python-format -msgid "Using project name = user name (%s)" -msgstr "" +msgid "Create volume of %s GB" +msgstr "Створити розділ на %s ГБ" -#: nova/auth/manager.py:275 +#: ../nova/api/ec2/cloud.py:612 #, python-format -msgid "failed authorization: no project named %s (user=%s)" +msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s" msgstr "" -#: nova/auth/manager.py:277 +#: ../nova/api/ec2/cloud.py:629 #, python-format -msgid "No project called %s could be found" -msgstr "" +msgid "Detach volume %s" +msgstr "Від'єднати том %s" -#: nova/auth/manager.py:281 -#, python-format -msgid "Failed authorization: user %s not admin and not member of project %s" +#: ../nova/api/ec2/cloud.py:761 +msgid "Allocate address" msgstr "" -#: nova/auth/manager.py:283 +#: ../nova/api/ec2/cloud.py:766 #, python-format -msgid "User %s is not a member of project %s" +msgid "Release address %s" msgstr "" -#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#: ../nova/api/ec2/cloud.py:771 #, python-format -msgid "Invalid signature for user %s" +msgid "Associate address %(public_ip)s to instance %(instance_id)s" msgstr "" -#: nova/auth/manager.py:293 nova/auth/manager.py:304 -msgid "Signature does not match" +#: ../nova/api/ec2/cloud.py:780 +#, python-format +msgid "Disassociate address %s" msgstr "" -#: nova/auth/manager.py:374 -msgid "Must specify project" +#: ../nova/api/ec2/cloud.py:807 +msgid "Going to start terminating instances" msgstr "" -#: nova/auth/manager.py:408 +#: ../nova/api/ec2/cloud.py:815 #, python-format -msgid "The %s role can not be found" +msgid "Reboot instance %r" msgstr "" -#: nova/auth/manager.py:410 +#: ../nova/api/ec2/cloud.py:867 #, python-format -msgid "The %s role is global only" +msgid "De-registering image %s" msgstr "" -#: nova/auth/manager.py:412 +#: ../nova/api/ec2/cloud.py:875 #, python-format -msgid "Adding role %s to user %s in project %s" +msgid "Registered image %(image_location)s with id %(image_id)s" msgstr "" -#: nova/auth/manager.py:438 +#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900 #, python-format -msgid "Removing role %s from user %s on project %s" +msgid "attribute not supported: %s" msgstr "" -#: nova/auth/manager.py:505 +#: ../nova/api/ec2/cloud.py:890 #, python-format -msgid "Created project %s with manager %s" +msgid "invalid id: %s" msgstr "" -#: nova/auth/manager.py:523 -#, python-format -msgid "modifying project %s" +#: ../nova/api/ec2/cloud.py:903 +msgid "user or group not specified" msgstr "" -#: nova/auth/manager.py:553 -#, python-format -msgid "Remove user %s from project %s" -msgstr "" +#: ../nova/api/ec2/cloud.py:905 +msgid "only group \"all\" is supported" +msgstr "лише група \"всі\" підтримується" -#: nova/auth/manager.py:581 -#, python-format -msgid "Deleting project %s" +#: ../nova/api/ec2/cloud.py:907 +msgid "operation_type must be add or remove" msgstr "" -#: nova/auth/manager.py:637 +#: ../nova/api/ec2/cloud.py:908 #, python-format -msgid "Created user %s (admin: %r)" +msgid "Updating image %s publicity" msgstr "" -#: nova/auth/manager.py:645 +#: ../bin/nova-api.py:52 #, python-format -msgid "Deleting user %s" +msgid "Using paste.deploy config at: %s" msgstr "" -#: nova/auth/manager.py:655 +#: ../bin/nova-api.py:57 #, python-format -msgid "Access Key change for user %s" +msgid "No paste configuration for app: %s" msgstr "" -#: nova/auth/manager.py:657 +#: ../bin/nova-api.py:59 #, python-format -msgid "Secret Key change for user %s" +msgid "" +"App Config: %(api)s\n" +"%(config)r" msgstr "" -#: nova/auth/manager.py:659 +#: ../bin/nova-api.py:64 #, python-format -msgid "Admin status set to %r for user %s" +msgid "Running %s API" msgstr "" -#: nova/auth/manager.py:708 +#: ../bin/nova-api.py:69 #, python-format -msgid "No vpn data for project %s" +msgid "No known API applications configured in %s." msgstr "" -#: nova/cloudpipe/pipelib.py:45 -msgid "Template for script to run on cloudpipe instance boot" +#: ../bin/nova-api.py:83 +#, python-format +msgid "Starting nova-api node (version %s)" msgstr "" -#: nova/cloudpipe/pipelib.py:48 -msgid "Network to push into openvpn config" +#: ../bin/nova-api.py:89 +#, python-format +msgid "No paste configuration found for: %s" msgstr "" -#: nova/cloudpipe/pipelib.py:51 -msgid "Netmask to push into openvpn config" +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84 +#, python-format +msgid "Argument %(key)s value %(value)s is too short." msgstr "" -#: nova/cloudpipe/pipelib.py:97 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89 #, python-format -msgid "Launching VPN for %s" +msgid "Argument %(key)s value %(value)s contains invalid characters." msgstr "" -#: nova/compute/api.py:67 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94 #, python-format -msgid "Instance %d was not found in get_network_topic" +msgid "Argument %(key)s value %(value)s starts with a hyphen." msgstr "" -#: nova/compute/api.py:73 +#: ../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 "Instance %d has no host" +msgid "Argument %s is required." msgstr "" -#: nova/compute/api.py:92 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117 #, python-format -msgid "Quota exceeeded for %s, tried to run %s instances" +msgid "" +"Argument %(key)s may not take value %(value)s. Valid values are ['true', " +"'false']." msgstr "" -#: nova/compute/api.py:94 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:163 #, python-format msgid "" -"Instance quota exceeded. You can only run %s more instances of this type." +"Created VDI %(vdi_ref)s (%(label)s, %(size)s, %(read_only)s) on %(sr_ref)s." msgstr "" -#: nova/compute/api.py:109 -msgid "Creating a raw instance" +#: ../nova/virt/xenapi/vmops.py:67 +#, python-format +msgid "Attempted to create non-unique name %s" msgstr "" -#: nova/compute/api.py:156 +#: ../nova/virt/xenapi/vmops.py:73 #, python-format -msgid "Going to run %s instances..." +msgid "instance %(name)s: not enough free memory" msgstr "" -#: nova/compute/api.py:180 +#: ../nova/virt/xenapi/vmops.py:148 #, python-format -msgid "Casting to scheduler for %s/%s's instance %s" +msgid "Starting VM %s..." msgstr "" -#: nova/compute/api.py:279 +#: ../nova/virt/xenapi/vmops.py:151 #, python-format -msgid "Going to try and terminate %s" +msgid "Spawning VM %(instance_name)s created %(vm_ref)s." msgstr "" -#: nova/compute/api.py:283 +#: ../nova/virt/xenapi/vmops.py:162 #, python-format -msgid "Instance %d was not found during terminate" +msgid "Invalid value for onset_files: '%s'" msgstr "" -#: nova/compute/api.py:288 +#: ../nova/virt/xenapi/vmops.py:167 #, python-format -msgid "Instance %d is already being terminated" +msgid "Injecting file path: '%s'" msgstr "" -#: nova/compute/api.py:450 +#: ../nova/virt/xenapi/vmops.py:180 #, python-format -msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgid "Instance %s: booted" msgstr "" -#: nova/compute/api.py:465 -msgid "Volume isn't attached to anything!" +#: ../nova/virt/xenapi/vmops.py:232 +#, python-format +msgid "Instance not present %s" msgstr "" -#: nova/compute/disk.py:71 +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vmops.py:261 #, python-format -msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgid "Starting snapshot for VM %s" msgstr "" -#: nova/compute/disk.py:75 +#: ../nova/virt/xenapi/vmops.py:269 #, python-format -msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" +msgid "Unable to Snapshot %(vm_ref)s: %(exc)s" msgstr "" -#: nova/compute/disk.py:128 +#: ../nova/virt/xenapi/vmops.py:280 #, python-format -msgid "Could not attach image to loopback: %s" +msgid "Finished snapshot and upload for VM %s" msgstr "" -#: nova/compute/disk.py:136 +#: ../nova/virt/xenapi/vmops.py:356 #, python-format -msgid "Failed to load partition: %s" +msgid "VM %(vm)s already halted, skipping shutdown..." msgstr "" -#: nova/compute/disk.py:158 -#, python-format -msgid "Failed to mount filesystem: %s" +#: ../nova/virt/xenapi/vmops.py:389 +msgid "Removing kernel/ramdisk files" msgstr "" -#: nova/compute/instance_types.py:41 -#, python-format -msgid "Unknown instance type: %s" +#: ../nova/virt/xenapi/vmops.py:399 +msgid "kernel/ramdisk files removed" msgstr "" -#: nova/compute/manager.py:69 +#: ../nova/virt/xenapi/vmops.py:561 #, python-format -msgid "check_instance_lock: decorating: |%s|" +msgid "" +"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/manager.py:71 +#: ../nova/virt/xenapi/vmops.py:564 #, python-format -msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgid "" +"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM " +"id=%(instance_id)s; args=%(strargs)s" msgstr "" -#: nova/compute/manager.py:75 +#: ../nova/virt/xenapi/vmops.py:569 #, python-format -msgid "check_instance_lock: locked: |%s|" +msgid "" +"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/manager.py:77 +#: ../nova/virt/xenapi/vmops.py:760 #, python-format -msgid "check_instance_lock: admin: |%s|" +msgid "OpenSSL error: %s" msgstr "" -#: nova/compute/manager.py:82 +#: ../nova/tests/test_compute.py:148 #, python-format -msgid "check_instance_lock: executing: |%s|" +msgid "Running instances: %s" msgstr "" -#: nova/compute/manager.py:86 +#: ../nova/tests/test_compute.py:154 #, python-format -msgid "check_instance_lock: not executing |%s|" +msgid "After terminating instances: %s" msgstr "" -#: nova/compute/manager.py:157 -msgid "Instance has already been created" +#: ../nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" msgstr "" -#: nova/compute/manager.py:158 -#, python-format -msgid "instance %s: starting..." +#: ../nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" msgstr "" -#: nova/compute/manager.py:197 -#, python-format -msgid "instance %s: Failed to spawn" +#: ../nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" msgstr "" -#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#: ../nova/cloudpipe/pipelib.py:97 #, python-format -msgid "Terminating instance %s" +msgid "Launching VPN for %s" +msgstr "" + +#: ../nova/db/sqlalchemy/migration.py:35 +msgid "python-migrate is not installed. Exiting." msgstr "" -#: nova/compute/manager.py:217 +#: ../nova/image/s3.py:99 #, python-format -msgid "Disassociating address %s" +msgid "Image %s could not be found" msgstr "" -#: nova/compute/manager.py:230 +#: ../nova/api/ec2/__init__.py:121 +msgid "Too many failed authentications." +msgstr "Занадто багато невдалих аутентифікацій." + +#: ../nova/api/ec2/__init__.py:131 #, python-format -msgid "Deallocating address %s" +msgid "" +"Access key %(access_key)s has had %(failures)d failed authentications and " +"will be locked out for %(lock_mins)d minutes." msgstr "" -#: nova/compute/manager.py:243 +#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140 #, python-format -msgid "trying to destroy already destroyed instance: %s" +msgid "Authentication Failure: %s" msgstr "" -#: nova/compute/manager.py:257 +#: ../nova/api/ec2/__init__.py:182 #, python-format -msgid "Rebooting instance %s" +msgid "Authenticated Request For %(uname)s:%(pname)s)" msgstr "" -#: nova/compute/manager.py:260 +#: ../nova/api/ec2/__init__.py:207 #, python-format -msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgid "action: %s" msgstr "" -#: nova/compute/manager.py:286 +#: ../nova/api/ec2/__init__.py:209 #, python-format -msgid "instance %s: snapshotting" +msgid "arg: %(key)s\t\tval: %(value)s" msgstr "" -#: nova/compute/manager.py:289 +#: ../nova/api/ec2/__init__.py:281 #, python-format msgid "" -"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +"Unauthorized request for controller=%(controller)s and action=%(action)s" msgstr "" -#: nova/compute/manager.py:301 +#: ../nova/api/ec2/__init__.py:314 #, python-format -msgid "instance %s: rescuing" +msgid "InstanceNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:316 +#: ../nova/api/ec2/__init__.py:320 #, python-format -msgid "instance %s: unrescuing" +msgid "VolumeNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:335 +#: ../nova/api/ec2/__init__.py:326 #, python-format -msgid "instance %s: pausing" +msgid "NotFound raised: %s" msgstr "" -#: nova/compute/manager.py:352 +#: ../nova/api/ec2/__init__.py:329 #, python-format -msgid "instance %s: unpausing" +msgid "ApiError raised: %s" msgstr "" -#: nova/compute/manager.py:369 +#: ../nova/api/ec2/__init__.py:338 #, python-format -msgid "instance %s: retrieving diagnostics" +msgid "Unexpected error raised: %s" msgstr "" -#: nova/compute/manager.py:382 -#, python-format -msgid "instance %s: suspending" +#: ../nova/api/ec2/__init__.py:343 +msgid "An unknown error has occurred. Please try your request again." msgstr "" -#: nova/compute/manager.py:401 +#: ../nova/auth/dbdriver.py:84 #, python-format -msgid "instance %s: resuming" +msgid "User %s already exists" +msgstr "Користувач %s вже існує" + +#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232 +#, python-format +msgid "Project can't be created because manager %s doesn't exist" msgstr "" -#: nova/compute/manager.py:420 +#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243 #, python-format -msgid "instance %s: locking" +msgid "Project can't be created because user %s doesn't exist" msgstr "" -#: nova/compute/manager.py:432 +#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229 #, python-format -msgid "instance %s: unlocking" +msgid "Project can't be created because project %s already exists" msgstr "" -#: nova/compute/manager.py:442 +#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268 #, python-format -msgid "instance %s: getting locked state" +msgid "Project can't be modified because manager %s doesn't exist" msgstr "" -#: nova/compute/manager.py:462 +#: ../nova/auth/dbdriver.py:245 +#, python-format +msgid "User \"%s\" not found" +msgstr "Користувач \"%s\" не знайдено" + +#: ../nova/auth/dbdriver.py:248 #, python-format -msgid "instance %s: attaching volume %s to %s" +msgid "Project \"%s\" not found" +msgstr "Проект \"%s\" не знайдено" + +#: ../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/compute/manager.py:478 +#: ../nova/virt/xenapi_conn.py:311 #, python-format -msgid "instance %s: attach failed %s, removing" +msgid "Task [%(name)s] %(task)s status: success %(result)s" msgstr "" -#: nova/compute/manager.py:493 +#: ../nova/virt/xenapi_conn.py:317 #, python-format -msgid "Detach volume %s from mountpoint %s on instance %s" +msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s" msgstr "" -#: nova/compute/manager.py:497 +#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344 #, python-format -msgid "Detaching volume from unknown instance %s" +msgid "Got exception: %s" msgstr "" -#: nova/compute/monitor.py:259 +#: ../nova/compute/monitor.py:259 #, python-format msgid "updating %s..." msgstr "" -#: nova/compute/monitor.py:289 +#: ../nova/compute/monitor.py:289 msgid "unexpected error during update" msgstr "" -#: nova/compute/monitor.py:355 +#: ../nova/compute/monitor.py:356 #, python-format -msgid "Cannot get blockstats for \"%s\" on \"%s\"" +msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/monitor.py:377 +#: ../nova/compute/monitor.py:379 #, python-format -msgid "Cannot get ifstats for \"%s\" on \"%s\"" +msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/monitor.py:412 +#: ../nova/compute/monitor.py:414 msgid "unexpected exception getting connection" msgstr "" -#: nova/compute/monitor.py:427 +#: ../nova/compute/monitor.py:429 #, 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 +#: ../nova/volume/san.py:67 #, python-format -msgid "No service for id %s" +msgid "Could not find iSCSI export for volume %s" msgstr "" -#: nova/db/sqlalchemy/api.py:229 +#: ../nova/api/ec2/apirequest.py:100 #, python-format -msgid "No service for %s, %s" +msgid "" +"Unsupported API request: controller = %(controller)s, action = %(action)s" msgstr "" -#: nova/db/sqlalchemy/api.py:574 +#: ../nova/api/openstack/__init__.py:55 #, python-format -msgid "No floating ip for address %s" +msgid "Caught error: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:668 -#, python-format -msgid "No instance for id %s" +#: ../nova/api/openstack/__init__.py:76 +msgid "Including admin operations in API." 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" +#: ../nova/console/xvp.py:99 +msgid "Rebuilding xvp conf" msgstr "" -#: nova/db/sqlalchemy/api.py:891 +#: ../nova/console/xvp.py:116 #, python-format -msgid "no keypair for user %s, name %s" +msgid "Re-wrote %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 -#, python-format -msgid "No network for id %s" +#: ../nova/console/xvp.py:121 +msgid "Stopping xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1036 -#, python-format -msgid "No network for bridge %s" +#: ../nova/console/xvp.py:134 +msgid "Starting xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1050 +#: ../nova/console/xvp.py:141 #, python-format -msgid "No network for instance %s" +msgid "Error starting xvp: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1180 -#, python-format -msgid "Token %s does not exist" +#: ../nova/console/xvp.py:144 +msgid "Restarting xvp" msgstr "" -#: nova/db/sqlalchemy/api.py:1205 -#, python-format -msgid "No quota for project_id %s" +#: ../nova/console/xvp.py:146 +msgid "xvp not running..." msgstr "" -#: nova/db/sqlalchemy/api.py:1356 -#, python-format -msgid "No volume for id %s" +#: ../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 "" -#: nova/db/sqlalchemy/api.py:1401 -#, python-format -msgid "Volume %s not found" +#: ../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 "" -#: nova/db/sqlalchemy/api.py:1413 -#, python-format -msgid "No export device found for volume %s" +#: ../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/db/sqlalchemy/api.py:1426 -#, python-format -msgid "No target id found for volume %s" +#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536 +msgid "network" msgstr "" -#: nova/db/sqlalchemy/api.py:1471 -#, python-format -msgid "No security group with id %s" +#: ../bin/nova-manage.py:448 +msgid "IP address" msgstr "" -#: nova/db/sqlalchemy/api.py:1488 -#, python-format -msgid "No security group named %s for project: %s" +#: ../bin/nova-manage.py:449 +msgid "MAC address" msgstr "" -#: nova/db/sqlalchemy/api.py:1576 -#, python-format -msgid "No secuity group rule with id %s" +#: ../bin/nova-manage.py:450 +msgid "hostname" msgstr "" -#: nova/db/sqlalchemy/api.py:1650 -#, python-format -msgid "No user for id %s" +#: ../bin/nova-manage.py:451 +msgid "host" msgstr "" -#: nova/db/sqlalchemy/api.py:1666 -#, python-format -msgid "No user for access key %s" +#: ../bin/nova-manage.py:537 +msgid "netmask" msgstr "" -#: nova/db/sqlalchemy/api.py:1728 -#, python-format -msgid "No project with id %s" +#: ../bin/nova-manage.py:538 +msgid "start address" msgstr "" -#: nova/image/glance.py:78 +#: ../nova/virt/disk.py:69 #, python-format -msgid "Parallax returned HTTP error %d from request for /images" +msgid "Failed to load partition: %s" msgstr "" -#: nova/image/glance.py:97 +#: ../nova/virt/disk.py:91 #, python-format -msgid "Parallax returned HTTP error %d from request for /images/detail" +msgid "Failed to mount filesystem: %s" msgstr "" -#: nova/image/s3.py:82 +#: ../nova/virt/disk.py:124 #, python-format -msgid "Image %s could not be found" +msgid "nbd device %s did not show up" msgstr "" -#: nova/network/api.py:39 +#: ../nova/virt/disk.py:128 #, python-format -msgid "Quota exceeeded for %s, tried to allocate address" +msgid "Could not attach image to loopback: %s" msgstr "" -#: nova/network/api.py:42 -msgid "Address quota exceeded. You cannot allocate any more addresses" +#: ../nova/virt/disk.py:151 +msgid "No free nbd devices" msgstr "" -#: nova/network/linux_net.py:176 +#: ../doc/ext/nova_todo.py:46 #, python-format -msgid "Starting VLAN inteface %s" +msgid "%(filename)s, line %(line_info)d" msgstr "" -#: nova/network/linux_net.py:186 -#, python-format -msgid "Starting Bridge interface for %s" +#. FIXME(chiradeep): implement this +#: ../nova/virt/hyperv.py:118 +msgid "In init host" msgstr "" -#: nova/network/linux_net.py:254 +#: ../nova/virt/hyperv.py:131 #, python-format -msgid "Hupping dnsmasq threw %s" +msgid "Attempt to create duplicate vm %s" msgstr "" -#: nova/network/linux_net.py:256 +#: ../nova/virt/hyperv.py:148 #, python-format -msgid "Pid %d is stale, relaunching dnsmasq" +msgid "Starting VM %s " msgstr "" -#: nova/network/linux_net.py:334 +#: ../nova/virt/hyperv.py:150 #, python-format -msgid "Killing dnsmasq threw %s" -msgstr "" - -#: nova/network/manager.py:135 -msgid "setting network host" +msgid "Started VM %s " msgstr "" -#: nova/network/manager.py:190 +#: ../nova/virt/hyperv.py:152 #, python-format -msgid "Leasing IP %s" +msgid "spawn vm failed: %s" msgstr "" -#: nova/network/manager.py:194 +#: ../nova/virt/hyperv.py:169 #, python-format -msgid "IP %s leased that isn't associated" +msgid "Failed to create VM %s" msgstr "" -#: nova/network/manager.py:197 +#: ../nova/virt/hyperv.py:188 #, python-format -msgid "IP %s leased to bad mac %s vs %s" +msgid "Set memory for vm %s..." msgstr "" -#: nova/network/manager.py:205 +#: ../nova/virt/hyperv.py:198 #, python-format -msgid "IP %s leased that was already deallocated" +msgid "Set vcpus for vm %s..." msgstr "" -#: nova/network/manager.py:214 +#: ../nova/virt/hyperv.py:202 #, python-format -msgid "IP %s released that isn't associated" +msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s" msgstr "" -#: nova/network/manager.py:217 +#: ../nova/virt/hyperv.py:227 #, python-format -msgid "IP %s released from bad mac %s vs %s" +msgid "Failed to add diskdrive to VM %s" msgstr "" -#: nova/network/manager.py:220 +#: ../nova/virt/hyperv.py:230 #, python-format -msgid "IP %s released that was not leased" +msgid "New disk drive path is %s" msgstr "" -#: nova/network/manager.py:442 +#: ../nova/virt/hyperv.py:247 #, python-format -msgid "Dissassociated %s stale fixed ip(s)" +msgid "Failed to add vhd file to VM %s" msgstr "" -#: nova/objectstore/handler.py:106 +#: ../nova/virt/hyperv.py:249 #, python-format -msgid "Unknown S3 value type %r" +msgid "Created disk for %s" msgstr "" -#: nova/objectstore/handler.py:137 -msgid "Authenticated request" +#: ../nova/virt/hyperv.py:253 +#, python-format +msgid "Creating nic for %s " msgstr "" -#: nova/objectstore/handler.py:182 -msgid "List of buckets requested" +#: ../nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" msgstr "" -#: nova/objectstore/handler.py:209 +#: ../nova/virt/hyperv.py:273 #, python-format -msgid "List keys for bucket %s" +msgid "Failed creating port for %s" msgstr "" -#: nova/objectstore/handler.py:217 +#: ../nova/virt/hyperv.py:276 #, python-format -msgid "Unauthorized attempt to access bucket %s" +msgid "Created switch port %(vm_name)s on switch %(ext_path)s" msgstr "" -#: nova/objectstore/handler.py:235 +#: ../nova/virt/hyperv.py:286 #, python-format -msgid "Creating bucket %s" +msgid "Failed to add nic to VM %s" msgstr "" -#: nova/objectstore/handler.py:245 +#: ../nova/virt/hyperv.py:288 #, python-format -msgid "Deleting bucket %s" +msgid "Created nic for %s " msgstr "" -#: nova/objectstore/handler.py:249 +#: ../nova/virt/hyperv.py:321 #, python-format -msgid "Unauthorized attempt to delete bucket %s" +msgid "WMI job failed: %s" msgstr "" -#: nova/objectstore/handler.py:271 +#: ../nova/virt/hyperv.py:325 #, python-format -msgid "Getting object: %s / %s" +msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s " msgstr "" -#: nova/objectstore/handler.py:274 +#: ../nova/virt/hyperv.py:361 #, python-format -msgid "Unauthorized attempt to get object %s from bucket %s" +msgid "Got request to destroy vm %s" msgstr "" -#: nova/objectstore/handler.py:292 +#: ../nova/virt/hyperv.py:386 #, python-format -msgid "Putting object: %s / %s" +msgid "Failed to destroy vm %s" msgstr "" -#: nova/objectstore/handler.py:295 +#: ../nova/virt/hyperv.py:393 #, python-format -msgid "Unauthorized attempt to upload object %s to bucket %s" +msgid "Del: disk %(vhdfile)s vm %(instance_name)s" msgstr "" -#: nova/objectstore/handler.py:314 +#: ../nova/virt/hyperv.py:415 #, python-format -msgid "Deleting object: %s / %s" +msgid "" +"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, " +"num_cpu=%(numprocs)s, cpu_time=%(uptime)s" msgstr "" -#: nova/objectstore/handler.py:393 +#: ../nova/virt/hyperv.py:451 #, python-format -msgid "Not authorized to upload image: invalid directory %s" +msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/objectstore/handler.py:401 +#: ../nova/virt/hyperv.py:454 #, python-format -msgid "Not authorized to upload image: unauthorized bucket %s" +msgid "Failed to change vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/objectstore/handler.py:406 +#: ../nova/compute/api.py:71 #, python-format -msgid "Starting image upload: %s" +msgid "Instance %d was not found in get_network_topic" msgstr "" -#: nova/objectstore/handler.py:420 +#: ../nova/compute/api.py:77 #, python-format -msgid "Not authorized to update attributes of image %s" +msgid "Instance %d has no host" msgstr "" -#: nova/objectstore/handler.py:428 +#: ../nova/compute/api.py:97 #, python-format -msgid "Toggling publicity flag of image %s %r" +msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances" msgstr "" -#: nova/objectstore/handler.py:433 +#: ../nova/compute/api.py:99 #, python-format -msgid "Updating user fields on image %s" +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." msgstr "" -#: nova/objectstore/handler.py:447 -#, python-format -msgid "Unauthorized attempt to delete image %s" +#: ../nova/compute/api.py:112 +msgid "Creating a raw instance" msgstr "" -#: nova/objectstore/handler.py:452 +#: ../nova/compute/api.py:160 #, 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" +msgid "Going to run %s instances..." msgstr "" -#: nova/scheduler/driver.py:66 -msgid "Must implement a fallback schedule" +#: ../nova/compute/api.py:187 +#, python-format +msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s" msgstr "" -#: nova/scheduler/manager.py:69 +#: ../nova/compute/api.py:292 #, python-format -msgid "Casting to %s %s for %s" +msgid "Going to try to terminate %s" msgstr "" -#: nova/scheduler/simple.py:63 -msgid "All hosts have too many cores" +#: ../nova/compute/api.py:296 +#, python-format +msgid "Instance %d was not found during terminate" msgstr "" -#: nova/scheduler/simple.py:95 -msgid "All hosts have too many gigabytes" +#: ../nova/compute/api.py:301 +#, python-format +msgid "Instance %d is already being terminated" msgstr "" -#: nova/scheduler/simple.py:115 -msgid "All hosts have too many networks" +#: ../nova/compute/api.py:481 +#, python-format +msgid "Invalid device specified: %s. Example device: /dev/vdb" msgstr "" -#: nova/tests/test_cloud.py:198 -msgid "Can't test instances without a real virtual env." +#: ../nova/compute/api.py:496 +msgid "Volume isn't attached to anything!" msgstr "" -#: nova/tests/test_cloud.py:210 +#: ../nova/rpc.py:98 #, python-format -msgid "Need to watch instance %s until it's running..." +msgid "" +"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in " +"%(fl_intv)d seconds." msgstr "" -#: nova/tests/test_compute.py:104 +#: ../nova/rpc.py:103 #, python-format -msgid "Running instances: %s" +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "Не вдалось під'єднатися до серверу AMQP після %d спроб. Вимкнення." + +#: ../nova/rpc.py:122 +msgid "Reconnected to queue" +msgstr "Оновлено з'єднання до черги" + +#: ../nova/rpc.py:129 +msgid "Failed to fetch message from queue" msgstr "" -#: nova/tests/test_compute.py:110 +#: ../nova/rpc.py:159 #, python-format -msgid "After terminating instances: %s" +msgid "Initing the Adapter Consumer for %s" msgstr "" -#: nova/tests/test_rpc.py:89 +#: ../nova/rpc.py:178 #, python-format -msgid "Nested received %s, %s" -msgstr "" +msgid "received %s" +msgstr "отримано %s" -#: nova/tests/test_rpc.py:94 +#. 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:191 #, python-format -msgid "Nested return %s" -msgstr "" +msgid "no method for message: %s" +msgstr "без порядку для повідомлень: %s" -#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#: ../nova/rpc.py:192 #, python-format -msgid "Received %s" -msgstr "" +msgid "No method for message: %s" +msgstr "Без порядку для повідомлень: %s" -#: nova/tests/test_volume.py:162 +#: ../nova/rpc.py:253 #, python-format -msgid "Target %s allocated" +msgid "Returning exception %s to caller" msgstr "" -#: nova/virt/connection.py:73 -msgid "Failed to open connection to the hypervisor" +#: ../nova/rpc.py:294 +#, python-format +msgid "unpacked context: %s" msgstr "" -#: nova/virt/fake.py:210 +#: ../nova/rpc.py:313 +msgid "Making asynchronous call..." +msgstr "Створення асинхронного виклику..." + +#: ../nova/rpc.py:316 #, python-format -msgid "Instance %s Not Found" -msgstr "" +msgid "MSG_ID is %s" +msgstr "MSG_ID %s" -#: nova/virt/hyperv.py:118 -msgid "In init host" +#: ../nova/rpc.py:354 +msgid "Making asynchronous cast..." msgstr "" -#: nova/virt/hyperv.py:131 +#: ../nova/rpc.py:364 #, python-format -msgid "Attempt to create duplicate vm %s" -msgstr "" +msgid "response %s" +msgstr "відповідь %s" -#: nova/virt/hyperv.py:148 +#: ../nova/rpc.py:373 #, python-format -msgid "Starting VM %s " -msgstr "" +msgid "topic is %s" +msgstr "заголовок %s" -#: nova/virt/hyperv.py:150 +#: ../nova/rpc.py:374 #, python-format -msgid "Started VM %s " -msgstr "" +msgid "message %s" +msgstr "повідомлення %s" -#: nova/virt/hyperv.py:152 +#: ../nova/volume/driver.py:78 #, python-format -msgid "spawn vm failed: %s" +msgid "Recovering from a failed execute. Try number %s" msgstr "" -#: nova/virt/hyperv.py:169 +#: ../nova/volume/driver.py:87 #, python-format -msgid "Failed to create VM %s" +msgid "volume group %s doesn't exist" msgstr "" -#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 +#: ../nova/volume/driver.py:220 #, python-format -msgid "Created VM %s..." +msgid "FAKE AOE: %s" msgstr "" -#: nova/virt/hyperv.py:188 -#, python-format -msgid "Set memory for vm %s..." +#: ../nova/volume/driver.py:233 +msgid "Skipping ensure_export. No iscsi_target " msgstr "" -#: nova/virt/hyperv.py:198 -#, python-format -msgid "Set vcpus for vm %s..." +#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288 +msgid "Skipping remove_export. No iscsi_target " msgstr "" -#: nova/virt/hyperv.py:202 +#: ../nova/volume/driver.py:347 #, python-format -msgid "Creating disk for %s by attaching disk file %s" +msgid "FAKE ISCSI: %s" msgstr "" -#: nova/virt/hyperv.py:227 +#: ../nova/volume/driver.py:359 #, python-format -msgid "Failed to add diskdrive to VM %s" +msgid "rbd has no pool %s" msgstr "" -#: nova/virt/hyperv.py:230 +#: ../nova/volume/driver.py:414 #, python-format -msgid "New disk drive path is %s" +msgid "Sheepdog is not working: %s" msgstr "" -#: nova/virt/hyperv.py:247 -#, python-format -msgid "Failed to add vhd file to VM %s" +#: ../nova/volume/driver.py:416 +msgid "Sheepdog is not working" msgstr "" -#: nova/virt/hyperv.py:249 +#: ../nova/wsgi.py:68 #, python-format -msgid "Created disk for %s" +msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: nova/virt/hyperv.py:253 -#, python-format -msgid "Creating nic for %s " +#: ../nova/wsgi.py:147 +msgid "You must implement __call__" msgstr "" -#: nova/virt/hyperv.py:272 -msgid "Failed creating a port on the external vswitch" +#: ../bin/nova-instancemonitor.py:55 +msgid "Starting instance monitor" msgstr "" -#: nova/virt/hyperv.py:273 -#, python-format -msgid "Failed creating port for %s" +#: ../bin/nova-dhcpbridge.py:58 +msgid "leasing ip" msgstr "" -#: nova/virt/hyperv.py:275 -#, python-format -msgid "Created switch port %s on switch %s" +#: ../bin/nova-dhcpbridge.py:73 +msgid "Adopted old lease or got a change of mac/hostname" msgstr "" -#: nova/virt/hyperv.py:285 -#, python-format -msgid "Failed to add nic to VM %s" +#: ../bin/nova-dhcpbridge.py:80 +msgid "releasing ip" msgstr "" -#: nova/virt/hyperv.py:287 +#: ../bin/nova-dhcpbridge.py:123 #, python-format -msgid "Created nic for %s " +msgid "" +"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s " +"on interface %(interface)s" msgstr "" -#: nova/virt/hyperv.py:320 +#: ../nova/virt/fake.py:239 #, python-format -msgid "WMI job failed: %s" +msgid "Instance %s Not Found" msgstr "" -#: nova/virt/hyperv.py:322 +#: ../nova/network/manager.py:153 #, python-format -msgid "WMI job succeeded: %s, Elapsed=%s " +msgid "Dissassociated %s stale fixed ip(s)" msgstr "" -#: nova/virt/hyperv.py:358 -#, python-format -msgid "Got request to destroy vm %s" +#: ../nova/network/manager.py:157 +msgid "setting network host" msgstr "" -#: nova/virt/hyperv.py:383 +#: ../nova/network/manager.py:212 #, python-format -msgid "Failed to destroy vm %s" +msgid "Leasing IP %s" msgstr "" -#: nova/virt/hyperv.py:389 +#: ../nova/network/manager.py:216 #, python-format -msgid "Del: disk %s vm %s" +msgid "IP %s leased that isn't associated" msgstr "" -#: nova/virt/hyperv.py:405 +#: ../nova/network/manager.py:220 #, python-format -msgid "" -"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " -"cpu_time=%s" +msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#: ../nova/network/manager.py:228 #, python-format -msgid "duplicate name found: %s" +msgid "IP %s leased that was already deallocated" msgstr "" -#: nova/virt/hyperv.py:444 +#: ../nova/network/manager.py:233 #, python-format -msgid "Successfully changed vm state of %s to %s" +msgid "Releasing IP %s" msgstr "" -#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#: ../nova/network/manager.py:237 #, python-format -msgid "Failed to change vm state of %s to %s" +msgid "IP %s released that isn't associated" msgstr "" -#: nova/virt/images.py:70 +#: ../nova/network/manager.py:241 #, python-format -msgid "Finished retreving %s -- placed in %s" +msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/libvirt_conn.py:144 +#: ../nova/network/manager.py:244 #, python-format -msgid "Connecting to libvirt: %s" +msgid "IP %s released that was not leased" msgstr "" -#: nova/virt/libvirt_conn.py:157 -msgid "Connection to libvirt broke" +#: ../nova/network/manager.py:519 +msgid "" +"The sum between the number of networks and the vlan start cannot be greater " +"than 4094" msgstr "" -#: nova/virt/libvirt_conn.py:229 +#: ../nova/virt/xenapi/volume_utils.py:57 #, python-format -msgid "instance %s: deleting instance files %s" +msgid "Introducing %s..." msgstr "" -#: nova/virt/libvirt_conn.py:271 +#: ../nova/virt/xenapi/volume_utils.py:74 #, python-format -msgid "No disk at %s" +msgid "Introduced %(label)s as %(sr_ref)s." msgstr "" -#: nova/virt/libvirt_conn.py:278 -msgid "Instance snapshotting is not supported for libvirtat this time" +#: ../nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" msgstr "" -#: nova/virt/libvirt_conn.py:294 +#: ../nova/virt/xenapi/volume_utils.py:90 #, python-format -msgid "instance %s: rebooted" +msgid "Unable to find SR from VBD %s" msgstr "" -#: nova/virt/libvirt_conn.py:297 +#: ../nova/virt/xenapi/volume_utils.py:96 #, python-format -msgid "_wait_for_reboot failed: %s" +msgid "Forgetting SR %s ... " msgstr "" -#: nova/virt/libvirt_conn.py:340 +#: ../nova/virt/xenapi/volume_utils.py:101 #, python-format -msgid "instance %s: rescued" +msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s" msgstr "" -#: nova/virt/libvirt_conn.py:343 +#: ../nova/virt/xenapi/volume_utils.py:107 #, python-format -msgid "_wait_for_rescue failed: %s" +msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s" msgstr "" -#: nova/virt/libvirt_conn.py:370 +#: ../nova/virt/xenapi/volume_utils.py:111 #, python-format -msgid "instance %s: is running" +msgid "Forgetting SR %s done." msgstr "" -#: nova/virt/libvirt_conn.py:381 +#: ../nova/virt/xenapi/volume_utils.py:113 #, python-format -msgid "instance %s: booted" +msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s" msgstr "" -#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#: ../nova/virt/xenapi/volume_utils.py:123 #, python-format -msgid "instance %s: failed to boot" +msgid "Unable to introduce VDI on SR %s" msgstr "" -#: nova/virt/libvirt_conn.py:395 +#: ../nova/virt/xenapi/volume_utils.py:128 #, python-format -msgid "virsh said: %r" -msgstr "" - -#: nova/virt/libvirt_conn.py:399 -msgid "cool, it's a device" +msgid "Unable to get record of VDI %s on" msgstr "" -#: nova/virt/libvirt_conn.py:407 +#: ../nova/virt/xenapi/volume_utils.py:146 #, python-format -msgid "data: %r, fpath: %r" +msgid "Unable to introduce VDI for SR %s" msgstr "" -#: nova/virt/libvirt_conn.py:415 +#: ../nova/virt/xenapi/volume_utils.py:175 #, python-format -msgid "Contents of file %s: %r" +msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s" msgstr "" -#: nova/virt/libvirt_conn.py:449 +#: ../nova/virt/xenapi/volume_utils.py:197 #, python-format -msgid "instance %s: Creating image" +msgid "Mountpoint cannot be translated: %s" msgstr "" -#: nova/virt/libvirt_conn.py:505 +#: ../nova/objectstore/image.py:262 #, python-format -msgid "instance %s: injecting key into image %s" +msgid "Failed to decrypt private key: %s" msgstr "" -#: nova/virt/libvirt_conn.py:508 +#: ../nova/objectstore/image.py:269 #, python-format -msgid "instance %s: injecting net into image %s" +msgid "Failed to decrypt initialization vector: %s" msgstr "" -#: nova/virt/libvirt_conn.py:516 +#: ../nova/objectstore/image.py:277 #, python-format -msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgid "Failed to decrypt image file %(image_file)s: %(err)s" msgstr "" -#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#: ../nova/objectstore/handler.py:106 #, python-format -msgid "instance %s: starting toXML method" +msgid "Unknown S3 value type %r" msgstr "" -#: nova/virt/libvirt_conn.py:589 -#, python-format -msgid "instance %s: finished toXML method" +#: ../nova/objectstore/handler.py:137 +msgid "Authenticated request" 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" +#: ../nova/objectstore/handler.py:182 +msgid "List of buckets requested" msgstr "" -#: nova/virt/xenapi_conn.py:263 +#: ../nova/objectstore/handler.py:209 #, python-format -msgid "Task [%s] %s status: success %s" +msgid "List keys for bucket %s" msgstr "" -#: nova/virt/xenapi_conn.py:271 +#: ../nova/objectstore/handler.py:217 #, python-format -msgid "Task [%s] %s status: %s %s" +msgid "Unauthorized attempt to access bucket %s" msgstr "" -#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#: ../nova/objectstore/handler.py:235 #, python-format -msgid "Got exception: %s" +msgid "Creating bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:72 +#: ../nova/objectstore/handler.py:245 #, python-format -msgid "%s: _db_content => %s" +msgid "Deleting bucket %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" +#: ../nova/objectstore/handler.py:249 +#, python-format +msgid "Unauthorized attempt to delete bucket %s" msgstr "" -#: nova/virt/xenapi/fake.py:249 +#: ../nova/objectstore/handler.py:273 #, python-format -msgid "xenapi.fake does not have an implementation for %s" +msgid "Getting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/fake.py:283 +#: ../nova/objectstore/handler.py:276 #, python-format -msgid "Calling %s %s" +msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/fake.py:288 +#: ../nova/objectstore/handler.py:296 #, python-format -msgid "Calling getter %s" +msgid "Putting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/fake.py:340 +#: ../nova/objectstore/handler.py:299 #, python-format -msgid "" -"xenapi.fake does not have an implementation for %s or it has been called " -"with the wrong number of arguments" +msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/network_utils.py:40 +#: ../nova/objectstore/handler.py:318 #, python-format -msgid "Found non-unique network for bridge %s" +msgid "Deleting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/xenapi/network_utils.py:43 +#: ../nova/objectstore/handler.py:322 #, python-format -msgid "Found no network for bridge %s" +msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:127 +#: ../nova/objectstore/handler.py:396 #, python-format -msgid "Created VM %s as %s." +msgid "Not authorized to upload image: invalid directory %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:147 +#: ../nova/objectstore/handler.py:404 #, python-format -msgid "Creating VBD for VM %s, VDI %s ... " +msgid "Not authorized to upload image: unauthorized bucket %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:149 +#: ../nova/objectstore/handler.py:409 #, python-format -msgid "Created VBD %s for VM %s, VDI %s." +msgid "Starting image upload: %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:165 +#: ../nova/objectstore/handler.py:423 #, python-format -msgid "VBD not found in instance %s" +msgid "Not authorized to update attributes of image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:175 +#: ../nova/objectstore/handler.py:431 #, python-format -msgid "Unable to unplug VBD %s" +msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r" msgstr "" -#: nova/virt/xenapi/vm_utils.py:187 +#. other attributes imply update +#: ../nova/objectstore/handler.py:436 #, python-format -msgid "Unable to destroy VBD %s" +msgid "Updating user fields on image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:202 +#: ../nova/objectstore/handler.py:450 #, python-format -msgid "Creating VIF for VM %s, network %s." +msgid "Unauthorized attempt to delete image %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:205 +#: ../nova/objectstore/handler.py:455 #, python-format -msgid "Created VIF %s for VM %s, network %s." +msgid "Deleted image: %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:216 +#: ../nova/auth/manager.py:259 #, python-format -msgid "Snapshotting VM %s with label '%s'..." +msgid "Looking up user: %r" msgstr "" -#: nova/virt/xenapi/vm_utils.py:229 +#: ../nova/auth/manager.py:263 #, python-format -msgid "Created snapshot %s from VM %s." +msgid "Failed authorization for access key %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:243 +#: ../nova/auth/manager.py:264 #, python-format -msgid "Asking xapi to upload %s as '%s'" +msgid "No user found for access key %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:261 +#: ../nova/auth/manager.py:270 #, python-format -msgid "Asking xapi to fetch %s as %s" +msgid "Using project name = user name (%s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:279 +#: ../nova/auth/manager.py:277 #, python-format -msgid "Looking up vdi %s for PV kernel" +msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:290 +#: ../nova/auth/manager.py:279 #, python-format -msgid "PV Kernel in VDI:%d" +msgid "No project called %s could be found" msgstr "" -#: nova/virt/xenapi/vm_utils.py:318 +#: ../nova/auth/manager.py:287 #, python-format -msgid "VDI %s is still available" +msgid "" +"Failed authorization: user %(uname)s not admin and not member of project " +"%(pjname)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:331 +#: ../nova/auth/manager.py:289 #, python-format -msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgid "User %(uid)s is not a member of project %(pjid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:333 +#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309 #, python-format -msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgid "Invalid signature for user %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:390 -#, python-format -msgid "VHD %s has parent %s" +#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310 +msgid "Signature does not match" msgstr "" -#: nova/virt/xenapi/vm_utils.py:407 -#, python-format -msgid "Re-scanning SR %s" +#: ../nova/auth/manager.py:380 +msgid "Must specify project" msgstr "" -#: nova/virt/xenapi/vm_utils.py:431 +#: ../nova/auth/manager.py:414 #, python-format -msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgid "The %s role can not be found" msgstr "" -#: nova/virt/xenapi/vm_utils.py:448 +#: ../nova/auth/manager.py:416 #, python-format -msgid "No VDIs found for VM %s" +msgid "The %s role is global only" msgstr "" -#: nova/virt/xenapi/vm_utils.py:452 +#: ../nova/auth/manager.py:420 #, python-format -msgid "Unexpected number of VDIs (%s) found for VM %s" +msgid "Adding role %(role)s to user %(uid)s in project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:62 +#: ../nova/auth/manager.py:423 #, python-format -msgid "Attempted to create non-unique name %s" +msgid "Adding sitewide role %(role)s to user %(uid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:99 +#: ../nova/auth/manager.py:448 #, python-format -msgid "Starting VM %s..." +msgid "Removing role %(role)s from user %(uid)s on project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:101 +#: ../nova/auth/manager.py:451 #, python-format -msgid "Spawning VM %s created %s." +msgid "Removing sitewide role %(role)s from user %(uid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:112 +#: ../nova/auth/manager.py:515 #, python-format -msgid "Instance %s: booted" +msgid "Created project %(name)s with manager %(manager_user)s" msgstr "" -#: nova/virt/xenapi/vmops.py:137 +#: ../nova/auth/manager.py:533 #, python-format -msgid "Instance not present %s" +msgid "modifying project %s" msgstr "" -#: nova/virt/xenapi/vmops.py:166 +#: ../nova/auth/manager.py:545 #, python-format -msgid "Starting snapshot for VM %s" +msgid "Adding user %(uid)s to project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:174 +#: ../nova/auth/manager.py:566 #, python-format -msgid "Unable to Snapshot %s: %s" +msgid "Remove user %(uid)s from project %(pid)s" msgstr "" -#: nova/virt/xenapi/vmops.py:184 +#: ../nova/auth/manager.py:592 #, python-format -msgid "Finished snapshot and upload for VM %s" +msgid "Deleting project %s" msgstr "" -#: nova/virt/xenapi/vmops.py:252 +#: ../nova/auth/manager.py:650 #, python-format -msgid "suspend: instance not present %s" +msgid "Created user %(rvname)s (admin: %(rvadmin)r)" msgstr "" -#: nova/virt/xenapi/vmops.py:262 +#: ../nova/auth/manager.py:659 #, python-format -msgid "resume: instance not present %s" +msgid "Deleting user %s" msgstr "" -#: nova/virt/xenapi/vmops.py:271 +#: ../nova/auth/manager.py:669 #, python-format -msgid "Instance not found %s" +msgid "Access Key change for user %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:57 +#: ../nova/auth/manager.py:671 #, python-format -msgid "Introducing %s..." +msgid "Secret Key change for user %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:74 +#: ../nova/auth/manager.py:673 #, python-format -msgid "Introduced %s as %s." +msgid "Admin status set to %(admin)r for user %(uid)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:78 -msgid "Unable to create Storage Repository" +#: ../nova/auth/manager.py:722 +#, python-format +msgid "No vpn data for project %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:90 +#: ../nova/service.py:161 #, python-format -msgid "Unable to find SR from VBD %s" +msgid "Starting %(topic)s node (version %(vcs_string)s)" msgstr "" -#: nova/virt/xenapi/volume_utils.py:96 -#, python-format -msgid "Forgetting SR %s ... " +#: ../nova/service.py:174 +msgid "Service killed that has no database entry" msgstr "" -#: nova/virt/xenapi/volume_utils.py:101 -#, python-format -msgid "Ignoring exception %s when getting PBDs for %s" +#: ../nova/service.py:195 +msgid "The service database object disappeared, Recreating it." msgstr "" -#: nova/virt/xenapi/volume_utils.py:107 -#, python-format -msgid "Ignoring exception %s when unplugging PBD %s" +#: ../nova/service.py:207 +msgid "Recovered model server connection!" msgstr "" -#: nova/virt/xenapi/volume_utils.py:111 -#, python-format -msgid "Forgetting SR %s done." +#: ../nova/service.py:213 +msgid "model server went away" msgstr "" -#: nova/virt/xenapi/volume_utils.py:113 +#: ../nova/auth/ldapdriver.py:174 #, python-format -msgid "Ignoring exception %s when forgetting SR %s" +msgid "LDAP user %s already exists" msgstr "" -#: nova/virt/xenapi/volume_utils.py:123 +#: ../nova/auth/ldapdriver.py:205 #, python-format -msgid "Unable to introduce VDI on SR %s" +msgid "LDAP object for %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:128 +#: ../nova/auth/ldapdriver.py:348 #, python-format -msgid "Unable to get record of VDI %s on" +msgid "User %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:146 +#: ../nova/auth/ldapdriver.py:472 #, python-format -msgid "Unable to introduce VDI for SR %s" +msgid "Group can't be created because group %s already exists" msgstr "" -#: nova/virt/xenapi/volume_utils.py:175 +#: ../nova/auth/ldapdriver.py:478 #, python-format -msgid "Unable to obtain target information %s, %s" +msgid "Group can't be created because user %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:197 +#: ../nova/auth/ldapdriver.py:495 #, python-format -msgid "Mountpoint cannot be translated: %s" +msgid "User %s can't be searched in group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:51 +#: ../nova/auth/ldapdriver.py:507 #, python-format -msgid "Attach_volume: %s, %s, %s" +msgid "User %s can't be added to the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:69 +#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521 #, python-format -msgid "Unable to create VDI on SR %s for instance %s" +msgid "The group at dn %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:81 +#: ../nova/auth/ldapdriver.py:513 #, python-format -msgid "Unable to use SR %s for instance %s" +msgid "User %(uid)s is already a member of the group %(group_dn)s" msgstr "" -#: nova/virt/xenapi/volumeops.py:93 +#: ../nova/auth/ldapdriver.py:524 #, python-format -msgid "Unable to attach volume to instance %s" +msgid "" +"User %s can't be removed from the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:95 +#: ../nova/auth/ldapdriver.py:528 #, python-format -msgid "Mountpoint %s attached to instance %s" +msgid "User %s is not a member of the group" msgstr "" -#: nova/virt/xenapi/volumeops.py:106 +#: ../nova/auth/ldapdriver.py:542 #, python-format -msgid "Detach_volume: %s, %s" +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." msgstr "" -#: nova/virt/xenapi/volumeops.py:113 +#: ../nova/auth/ldapdriver.py:549 #, python-format -msgid "Unable to locate volume %s" +msgid "User %s can't be removed from all because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:121 +#: ../nova/auth/ldapdriver.py:564 #, python-format -msgid "Unable to detach volume %s" +msgid "Group at dn %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volumeops.py:128 +#: ../nova/virt/xenapi/network_utils.py:40 #, python-format -msgid "Mountpoint %s detached from instance %s" +msgid "Found non-unique network for bridge %s" msgstr "" -#: nova/volume/api.py:44 +#: ../nova/virt/xenapi/network_utils.py:43 #, python-format -msgid "Quota exceeeded for %s, tried to create %sG volume" +msgid "Found no network for bridge %s" msgstr "" -#: nova/volume/api.py:46 +#: ../nova/api/ec2/admin.py:97 #, python-format -msgid "Volume quota exceeded. You cannot create a volume of size %s" +msgid "Creating new user: %s" msgstr "" -#: nova/volume/api.py:70 nova/volume/api.py:95 -msgid "Volume status must be available" +#: ../nova/api/ec2/admin.py:105 +#, python-format +msgid "Deleting user: %s" msgstr "" -#: nova/volume/api.py:97 -msgid "Volume is already attached" +#: ../nova/api/ec2/admin.py:127 +#, python-format +msgid "Adding role %(role)s to user %(user)s for project %(project)s" msgstr "" -#: nova/volume/api.py:103 -msgid "Volume is already detached" +#: ../nova/api/ec2/admin.py:131 +#, python-format +msgid "Adding sitewide role %(role)s to user %(user)s" msgstr "" -#: nova/volume/driver.py:76 +#: ../nova/api/ec2/admin.py:137 #, python-format -msgid "Recovering from a failed execute. Try number %s" +msgid "Removing role %(role)s from user %(user)s for project %(project)s" msgstr "" -#: nova/volume/driver.py:85 +#: ../nova/api/ec2/admin.py:141 #, python-format -msgid "volume group %s doesn't exist" +msgid "Removing sitewide role %(role)s from user %(user)s" msgstr "" -#: nova/volume/driver.py:210 -#, python-format -msgid "FAKE AOE: %s" +#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223 +msgid "operation must be add or remove" msgstr "" -#: nova/volume/driver.py:315 +#: ../nova/api/ec2/admin.py:159 #, python-format -msgid "FAKE ISCSI: %s" +msgid "Getting x509 for user: %(name)s on project: %(project)s" msgstr "" -#: nova/volume/manager.py:85 +#: ../nova/api/ec2/admin.py:177 #, python-format -msgid "Re-exporting %s volumes" +msgid "Create project %(name)s managed by %(manager_user)s" msgstr "" -#: nova/volume/manager.py:93 +#: ../nova/api/ec2/admin.py:190 #, python-format -msgid "volume %s: creating" +msgid "Modify project: %(name)s managed by %(manager_user)s" msgstr "" -#: nova/volume/manager.py:102 +#: ../nova/api/ec2/admin.py:200 #, python-format -msgid "volume %s: creating lv of size %sG" -msgstr "" +msgid "Delete project: %s" +msgstr "Вилучити проект: %s" -#: nova/volume/manager.py:106 +#: ../nova/api/ec2/admin.py:214 #, python-format -msgid "volume %s: creating export" +msgid "Adding user %(user)s to project %(project)s" msgstr "" -#: nova/volume/manager.py:113 +#: ../nova/api/ec2/admin.py:218 #, python-format -msgid "volume %s: created successfully" +msgid "Removing user %(user)s from project %(project)s" msgstr "" -#: nova/volume/manager.py:121 -msgid "Volume is still attached" -msgstr "" +#, python-format +#~ msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +#~ msgstr "AMQP сервер %s:%d недоступний. Спроба під'єднання через %d секунд." -#: nova/volume/manager.py:123 -msgid "Volume is not local to this node" -msgstr "" +#, python-format +#~ msgid "Couldn't get IP, using 127.0.0.1 %s" +#~ msgstr "Не вдалось отримати IP, використовуючи 127.0.0.1 %s" -#: nova/volume/manager.py:124 #, python-format -msgid "volume %s: removing export" -msgstr "" +#~ msgid "Removing user %s from project %s" +#~ msgstr "Вилучення користувача %s з проекту %s" -#: nova/volume/manager.py:126 #, python-format -msgid "volume %s: deleting" -msgstr "" +#~ msgid "Adding user %s to project %s" +#~ msgstr "Долучення користувача %s до проекту %s" -#: nova/volume/manager.py:129 #, python-format -msgid "volume %s: deleted successfully" -msgstr "" +#~ 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" + +#, python-format +#~ msgid "Getting from %s: %s" +#~ msgstr "Отримання з %s: %s" diff --git a/po/zh_CN.po b/po/zh_CN.po index a39383497..9690356f5 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,2129 +7,2934 @@ 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-14 02:26+0000\n" -"Last-Translator: Winston Dillon \n" +"POT-Creation-Date: 2011-02-21 10:03-0500\n" +"PO-Revision-Date: 2011-04-07 05:01+0000\n" +"Last-Translator: ben \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-15 05:12+0000\n" -"X-Generator: Launchpad (build 12351)\n" +"X-Launchpad-Export-Date: 2011-04-08 05:28+0000\n" +"X-Generator: Launchpad (build 12735)\n" -#: nova/twistd.py:268 +#: ../nova/twistd.py:266 #, python-format msgid "Starting %s" -msgstr "正在启动 %s" +msgstr "启动 %s 中" -#: nova/crypto.py:46 +#: ../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 "未找到主机" + +#: ../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 "卷磁盘配额已耗尽,不能创建 %sG 大小的卷" + +#: ../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/api/openstack/servers.py:72 +msgid "Failed to read private ip" +msgstr "获取内网IP失败" + +#: ../nova/api/openstack/servers.py:79 +msgid "Failed to read public ip(s)" +msgstr "获取外网IP失败" + +#: ../nova/api/openstack/servers.py:152 +#, python-format +msgid "%(param)s property not found for image %(_image_id)s" +msgstr "" + +#: ../nova/api/openstack/servers.py:168 +msgid "No keypairs defined" +msgstr "未定义密钥对" + +#: ../nova/api/openstack/servers.py:238 +#, python-format +msgid "Compute.api::lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:253 +#, python-format +msgid "Compute.api::unlock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:267 +#, python-format +msgid "Compute.api::get_lock %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:281 +#, python-format +msgid "Compute.api::reset_network %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:292 +#, python-format +msgid "Compute.api::pause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:303 +#, python-format +msgid "Compute.api::unpause %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:314 +#, python-format +msgid "compute.api::suspend %s" +msgstr "" + +#: ../nova/api/openstack/servers.py:325 +#, python-format +msgid "compute.api::resume %s" +msgstr "" + +#: ../nova/twistd.py:157 +msgid "Wrong number of arguments." +msgstr "错误参数个数。" + +#: ../nova/twistd.py:209 +#, python-format +msgid "pidfile %s does not exist. Daemon not running?\n" +msgstr "pidfile %s 不存在,守护进程是否运行?\n" + +#: ../nova/twistd.py:221 +msgid "No such process" +msgstr "没有该进程" + +#: ../nova/twistd.py:230 ../nova/service.py:224 +#, python-format +msgid "Serving %s" +msgstr "正在为 %s 服务" + +#: ../nova/twistd.py:262 ../nova/service.py:225 +msgid "Full set of FLAGS:" +msgstr "FLAGS全集:" + +#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101 +#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741 +#: ../nova/api/ec2/__init__.py:317 +#, 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 "无法挂载卷到虚拟机 %s" + +#: ../nova/virt/xenapi/volumeops.py:93 +#, python-format +msgid "Mountpoint %(mountpoint)s attached to instance %(instance_name)s" +msgstr "挂载点 %(mountpoint)s 挂载到虚拟机 %(instance_name)s" + +#. Detach VBD from VM +#: ../nova/virt/xenapi/volumeops.py:104 +#, python-format +msgid "Detach_volume: %(instance_name)s, %(mountpoint)s" +msgstr "卸载_volume: %(instance_name)s, %(mountpoint)s" + +#: ../nova/virt/xenapi/volumeops.py:112 +#, python-format +msgid "Unable to locate volume %s" +msgstr "无法找到 %s 卷" + +#: ../nova/virt/xenapi/volumeops.py:120 +#, python-format +msgid "Unable to detach volume %s" +msgstr "无法卸载 %s 卷" + +#: ../nova/virt/xenapi/volumeops.py:127 +#, python-format +msgid "Mountpoint %(mountpoint)s detached from instance %(instance_name)s" +msgstr "挂载点 %(mountpoint)s 从虚拟机 %(instance_name)s 卸载" + +#: ../nova/compute/instance_types.py:41 +#, python-format +msgid "Unknown instance type: %s" +msgstr "未知的虚拟机类型:%s" + +#: ../nova/crypto.py:46 msgid "Filename of root CA" msgstr "根证书文件名" -#: nova/crypto.py:49 +#: ../nova/crypto.py:49 msgid "Filename of private key" msgstr "私钥文件名" -#: nova/crypto.py:51 +#: ../nova/crypto.py:51 msgid "Filename of root Certificate Revokation List" msgstr "" -#: nova/crypto.py:53 +#: ../nova/crypto.py:53 msgid "Where we keep our keys" msgstr "保存密钥的位置" -#: nova/crypto.py:55 +#: ../nova/crypto.py:55 msgid "Where we keep our root CA" msgstr "保存根证书的位置" -#: nova/crypto.py:57 +#: ../nova/crypto.py:57 msgid "Should we use a CA for each project?" msgstr "是否所有项目都是用证书授权(CA)?" -#: nova/crypto.py:61 +#: ../nova/crypto.py:61 #, python-format msgid "Subject for certificate for users, %s for project, user, timestamp" msgstr "用户证书的标题,%s依次分别为项目,用户,时间戳" -#: nova/crypto.py:66 +#: ../nova/crypto.py:66 #, python-format msgid "Subject for certificate for projects, %s for project, timestamp" msgstr "项目证书的标题,%s依次分别为项目,时间戳" -#: nova/crypto.py:71 +#: ../nova/crypto.py:71 #, python-format msgid "Subject for certificate for vpns, %s for project, timestamp" msgstr "VPN证书的标题,%s依次分别为项目,时间戳" -#: nova/crypto.py:258 +#: ../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/scheduler/manager.py:69 +#, python-format +msgid "Casting to %(topic)s %(host)s for %(method)s" +msgstr "" + +#: ../nova/compute/manager.py:78 +#, python-format +msgid "check_instance_lock: decorating: |%s|" +msgstr "" -#: nova/exception.py:36 +#: ../nova/compute/manager.py:80 #, 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 "未捕获异常" +"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|" +msgstr "" -#: nova/fakerabbit.py:48 +#: ../nova/compute/manager.py:84 #, python-format -msgid "(%s) publish (key: %s) %s" -msgstr "(%s)发布(键值:%s)%s" +msgid "check_instance_lock: locked: |%s|" +msgstr "" -#: nova/fakerabbit.py:53 +#: ../nova/compute/manager.py:86 #, python-format -msgid "Publishing to route %s" -msgstr "发布并路由到 %s" +msgid "check_instance_lock: admin: |%s|" +msgstr "" -#: nova/fakerabbit.py:83 +#: ../nova/compute/manager.py:91 #, python-format -msgid "Declaring queue %s" -msgstr "正在声明队列%s" +msgid "check_instance_lock: executing: |%s|" +msgstr "" -#: nova/fakerabbit.py:89 +#: ../nova/compute/manager.py:95 #, python-format -msgid "Declaring exchange %s" -msgstr "正在声明交换(exchange)%s" +msgid "check_instance_lock: not executing |%s|" +msgstr "" + +#: ../nova/compute/manager.py:179 +msgid "Instance has already been created" +msgstr "虚拟机已经创建" + +#: ../nova/compute/manager.py:180 +#, python-format +msgid "instance %s: starting..." +msgstr "虚拟机 %s :启动" -#: nova/fakerabbit.py:95 +#. pylint: disable=W0702 +#: ../nova/compute/manager.py:219 #, python-format -msgid "Binding %s to %s with key %s" -msgstr "将%s绑定到%s(以%s键值)" +msgid "instance %s: Failed to spawn" +msgstr "" -#: nova/fakerabbit.py:120 +#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286 #, python-format -msgid "Getting from %s: %s" -msgstr "从%s获得如下内容:%s" +msgid "Terminating instance %s" +msgstr "" -#: nova/rpc.py:92 +#: ../nova/compute/manager.py:255 #, python-format -msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." -msgstr "位于%s:%d的AMQP服务器不可用。%d秒后重试。" +msgid "Deallocating address %s" +msgstr "" -#: nova/rpc.py:99 +#: ../nova/compute/manager.py:268 #, python-format -msgid "Unable to connect to AMQP server after %d tries. Shutting down." -msgstr "已尝试%d次,均无法连接到AMQP服务器。关闭中。" +msgid "trying to destroy already destroyed instance: %s" +msgstr "" -#: nova/rpc.py:118 -msgid "Reconnected to queue" -msgstr "重新与队列建立连接" +#: ../nova/compute/manager.py:282 +#, python-format +msgid "Rebooting instance %s" +msgstr "重启虚拟机 %s" -#: nova/rpc.py:125 -msgid "Failed to fetch message from queue" -msgstr "从队列获取数据失败" +#: ../nova/compute/manager.py:287 +#, python-format +msgid "" +"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:311 +#, python-format +msgid "instance %s: snapshotting" +msgstr "" + +#: ../nova/compute/manager.py:316 +#, python-format +msgid "" +"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s " +"expected: %(running)s)" +msgstr "" + +#: ../nova/compute/manager.py:332 +#, python-format +msgid "" +"trying to reset the password on a non-running instance: %(instance_id)s " +"(state: %(instance_state)s expected: %(expected_state)s)" +msgstr "" + +#: ../nova/compute/manager.py:335 +#, python-format +msgid "instance %s: setting admin password" +msgstr "虚拟机 %s:设置管理员密码" + +#: ../nova/compute/manager.py:353 +#, python-format +msgid "" +"trying to inject a file into a non-running instance: %(instance_id)s (state: " +"%(instance_state)s expected: %(expected_state)s)" +msgstr "" + +#: ../nova/compute/manager.py:362 +#, python-format +msgid "instance %(nm)s: injecting file to %(plain_path)s" +msgstr "" + +#: ../nova/compute/manager.py:372 +#, python-format +msgid "instance %s: rescuing" +msgstr "" + +#: ../nova/compute/manager.py:387 +#, python-format +msgid "instance %s: unrescuing" +msgstr "" + +#: ../nova/compute/manager.py:406 +#, python-format +msgid "instance %s: pausing" +msgstr "" + +#: ../nova/compute/manager.py:423 +#, python-format +msgid "instance %s: unpausing" +msgstr "" + +#: ../nova/compute/manager.py:440 +#, python-format +msgid "instance %s: retrieving diagnostics" +msgstr "" + +#: ../nova/compute/manager.py:453 +#, python-format +msgid "instance %s: suspending" +msgstr "虚拟机 %s:挂起" + +#: ../nova/compute/manager.py:472 +#, python-format +msgid "instance %s: resuming" +msgstr "" + +#: ../nova/compute/manager.py:491 +#, python-format +msgid "instance %s: locking" +msgstr "" + +#: ../nova/compute/manager.py:503 +#, python-format +msgid "instance %s: unlocking" +msgstr "" + +#: ../nova/compute/manager.py:513 +#, python-format +msgid "instance %s: getting locked state" +msgstr "" + +#: ../nova/compute/manager.py:526 +#, python-format +msgid "instance %s: reset network" +msgstr "" + +#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515 +#, python-format +msgid "Get console output for instance %s" +msgstr "获取虚拟机 %s 控制台输出" + +#: ../nova/compute/manager.py:543 +#, python-format +msgid "instance %s: getting ajax console" +msgstr "虚拟机 %s :获取ajax控制台" + +#: ../nova/compute/manager.py:553 +#, python-format +msgid "" +"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s" +msgstr "" + +#. pylint: disable=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:569 +#, python-format +msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing" +msgstr "" + +#: ../nova/compute/manager.py:585 +#, python-format +msgid "" +"Detach volume %(volume_id)s from mountpoint %(mp)s on instance " +"%(instance_id)s" +msgstr "" + +#: ../nova/compute/manager.py:588 +#, 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:304 ../nova/virt/xenapi/fake.py:404 +#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478 +msgid "Raising NotImplemented" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:306 +#, python-format +msgid "xenapi.fake does not have an implementation for %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:341 +#, python-format +msgid "Calling %(localname)s %(impl)s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:346 +#, python-format +msgid "Calling getter %s" +msgstr "" + +#: ../nova/virt/xenapi/fake.py:406 +#, 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:187 +#, python-format +msgid "Starting VLAN inteface %s" +msgstr "" + +#: ../nova/network/linux_net.py:208 +#, python-format +msgid "Starting Bridge interface for %s" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:314 +#, python-format +msgid "Hupping dnsmasq threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:316 +#, python-format +msgid "Pid %d is stale, relaunching dnsmasq" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:358 +#, python-format +msgid "killing radvd threw %s" +msgstr "" + +#: ../nova/network/linux_net.py:360 +#, python-format +msgid "Pid %d is stale, relaunching radvd" +msgstr "" + +#. pylint: disable=W0703 +#: ../nova/network/linux_net.py:449 +#, python-format +msgid "Killing dnsmasq threw %s" +msgstr "" + +#: ../nova/utils.py:58 +#, python-format +msgid "Inner Exception: %s" +msgstr "内层异常:%s" + +#: ../nova/utils.py:59 +#, python-format +msgid "Class %s cannot be found" +msgstr "无法找到 %s 类" + +#: ../nova/utils.py:118 +#, python-format +msgid "Fetching %s" +msgstr "正在抓取 %s" + +#: ../nova/utils.py:130 +#, python-format +msgid "Running cmd (subprocess): %s" +msgstr "正在运行(在子进程中)运行命令:%s" + +#: ../nova/utils.py:143 ../nova/utils.py:183 +#, python-format +msgid "Result was %s" +msgstr "运行结果为 %s" + +#: ../nova/utils.py:159 +#, python-format +msgid "Running cmd (SSH): %s" +msgstr "" + +#: ../nova/utils.py:217 +#, python-format +msgid "debug in callback: %s" +msgstr "回调中debug:%s" + +#: ../nova/utils.py:222 +#, python-format +msgid "Running %s" +msgstr "正在运行 %s" + +#: ../nova/utils.py:262 +#, python-format +msgid "Link Local address is not found.:%s" +msgstr "" + +#: ../nova/utils.py:265 +#, python-format +msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s" +msgstr "" + +#: ../nova/utils.py:363 +#, python-format +msgid "Invalid backend: %s" +msgstr "无效的后台:%s" + +#: ../nova/utils.py:374 +#, python-format +msgid "backend %s" +msgstr "后台 %s" + +#: ../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 "发布并路由到 %s" + +#: ../nova/fakerabbit.py:84 +#, python-format +msgid "Declaring queue %s" +msgstr "正在声明队列 %s" + +#: ../nova/fakerabbit.py:90 +#, python-format +msgid "Declaring exchange %s" +msgstr "正在声明交换(exchange) %s" + +#: ../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:168 +#, python-format +msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:171 +#, python-format +msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:187 +#, python-format +msgid "VBD not found in instance %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:197 +#, python-format +msgid "Unable to unplug VBD %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:209 +#, python-format +msgid "Unable to destroy VBD %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:224 +#, python-format +msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:227 +#, python-format +msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:246 +#, 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:258 +#, python-format +msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:272 +#, python-format +msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:286 +#, python-format +msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:327 +#, python-format +msgid "Size for image %(image)s:%(virtual_size)d" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:332 +#, 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:342 +#, python-format +msgid "Copying VDI %s to /boot/guest on dom0" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:352 +#, python-format +msgid "Kernel/Ramdisk VDI %s destroyed" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:361 +#, python-format +msgid "Asking xapi to fetch %(url)s as %(access)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402 +#, python-format +msgid "Looking up vdi %s for PV kernel" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:397 +#, python-format +msgid "PV Kernel in VDI:%s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:405 +#, python-format +msgid "Running pygrub against %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:411 +#, python-format +msgid "Found Xen kernel %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:413 +msgid "No Xen kernel found. Booting HVM." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431 +#, python-format +msgid "duplicate name found: %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:442 +#, python-format +msgid "VDI %s is still available" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:463 +#, python-format +msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:465 +#, python-format +msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:525 +#, python-format +msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:542 +#, python-format +msgid "Re-scanning SR %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:567 +#, python-format +msgid "" +"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:574 +#, 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:590 +#, python-format +msgid "No VDIs found for VM %s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:594 +#, python-format +msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:653 +#: ../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:655 +#: ../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:657 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192 +#, python-format +msgid "Plugging VBD %s ... " +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:659 +#: ../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:661 +#, python-format +msgid "VBD %(vbd)s plugged as %(orig_dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:664 +#, python-format +msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s" +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:668 +#: ../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:671 +#: ../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:683 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211 +msgid "VBD.unplug successful first time." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:688 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216 +msgid "VBD.unplug rejected: retrying..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:692 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220 +msgid "VBD.unplug successful eventually." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:695 +#: ../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:704 +#: ../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:735 +#, python-format +msgid "" +"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..." +msgstr "" + +#: ../nova/virt/xenapi/vm_utils.py:747 +#, 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:592 +msgid "No fixed ips defined" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:608 +#, python-format +msgid "No floating ip for address %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:629 +#, python-format +msgid "No address for instance %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:961 +#, python-format +msgid "no keypair for user %(user_id)s, name %(name)s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156 +#, python-format +msgid "No network for id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1086 +msgid "No networks defined" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1115 +#, python-format +msgid "No network for bridge %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142 +#, python-format +msgid "No network for instance %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1277 +#, python-format +msgid "Token %s does not exist" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1302 +#, python-format +msgid "No quota for project_id %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501 +#: ../nova/api/ec2/__init__.py:323 +#, python-format +msgid "Volume %s not found" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1514 +#, python-format +msgid "No export device found for volume %s" +msgstr "" + +#: ../nova/db/sqlalchemy/api.py:1527 +#, python-format +msgid "No target id found for volume %s" +msgstr "" -#: nova/rpc.py:155 +#: ../nova/db/sqlalchemy/api.py:1572 #, python-format -msgid "Initing the Adapter Consumer for %s" +msgid "No security group with id %s" msgstr "" -#: nova/rpc.py:170 +#: ../nova/db/sqlalchemy/api.py:1589 #, python-format -msgid "received %s" -msgstr "已接收 %s" +msgid "No security group named %(group_name)s for project: %(project_id)s" +msgstr "" -#: nova/rpc.py:183 +#: ../nova/db/sqlalchemy/api.py:1682 #, python-format -msgid "no method for message: %s" -msgstr "没有适用于消息%s的方法" +msgid "No secuity group rule with id %s" +msgstr "" -#: nova/rpc.py:184 +#: ../nova/db/sqlalchemy/api.py:1756 #, python-format -msgid "No method for message: %s" -msgstr "没有适用于消息%s的方法" +msgid "No user for id %s" +msgstr "" -#: nova/rpc.py:245 +#: ../nova/db/sqlalchemy/api.py:1772 #, python-format -msgid "Returning exception %s to caller" -msgstr "返回%s异常给调用者" +msgid "No user for access key %s" +msgstr "" -#: nova/rpc.py:286 +#: ../nova/db/sqlalchemy/api.py:1834 #, python-format -msgid "unpacked context: %s" +msgid "No project with id %s" msgstr "" -#: nova/rpc.py:305 -msgid "Making asynchronous call..." -msgstr "产生异步调用中……" - -#: nova/rpc.py:308 +#: ../nova/db/sqlalchemy/api.py:1979 #, python-format -msgid "MSG_ID is %s" -msgstr "消息ID(MSG_ID)是 %s" +msgid "No console pool with id %(pool_id)s" +msgstr "" -#: nova/rpc.py:356 +#: ../nova/db/sqlalchemy/api.py:1996 #, python-format -msgid "response %s" -msgstr "回复 %s" +msgid "" +"No console pool of type %(console_type)s for compute host %(compute_host)s " +"on proxy host %(host)s" +msgstr "" -#: nova/rpc.py:365 +#: ../nova/db/sqlalchemy/api.py:2035 #, python-format -msgid "topic is %s" -msgstr "话题是 %s" +msgid "No console for instance %(instance_id)s in pool %(pool_id)s" +msgstr "" -#: nova/rpc.py:366 +#: ../nova/db/sqlalchemy/api.py:2057 #, python-format -msgid "message %s" -msgstr "消息 %s" +msgid "on instance %s" +msgstr "" -#: nova/service.py:157 +#: ../nova/db/sqlalchemy/api.py:2058 #, 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." +msgid "No console with id %(console_id)s %(idesc)s" msgstr "" -#: nova/service.py:202 -msgid "Recovered model server connection!" -msgstr "与模型服务器(model server)的连接已恢复!" +#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097 +#, python-format +msgid "No zone with id %(zone_id)s" +msgstr "" -#: nova/service.py:208 -msgid "model server went away" -msgstr "失去与模型服务器的连接" +#: ../nova/virt/libvirt_conn.py:160 +#, python-format +msgid "Checking state of %s" +msgstr "" -#: nova/service.py:217 nova/db/sqlalchemy/__init__.py:43 +#: ../nova/virt/libvirt_conn.py:165 #, python-format -msgid "Data store %s is unreachable. Trying again in %d seconds." -msgstr "数据储存服务%s不可用。%d秒之后继续尝试。" +msgid "Current state of %(name)s was %(state)s." +msgstr "" -#: nova/service.py:232 nova/twistd.py:232 +#: ../nova/virt/libvirt_conn.py:183 #, python-format -msgid "Serving %s" -msgstr "正在为%s服务" +msgid "Connecting to libvirt: %s" +msgstr "" -#: nova/service.py:234 nova/twistd.py:264 -msgid "Full set of FLAGS:" -msgstr "FLAGS全集:" +#: ../nova/virt/libvirt_conn.py:196 +msgid "Connection to libvirt broke" +msgstr "" -#: nova/twistd.py:211 +#: ../nova/virt/libvirt_conn.py:258 #, python-format -msgid "pidfile %s does not exist. Daemon not running?\n" -msgstr "pidfile %s不存在。后台服务没有运行?\n" +msgid "instance %(instance_name)s: deleting instance files %(target)s" +msgstr "" -#: nova/utils.py:53 +#: ../nova/virt/libvirt_conn.py:283 #, python-format -msgid "Inner Exception: %s" -msgstr "内层异常:%s" +msgid "Invalid device path %s" +msgstr "" -#: nova/utils.py:54 +#: ../nova/virt/libvirt_conn.py:313 #, python-format -msgid "Class %s cannot be found" -msgstr "无法找到%s类" +msgid "No disk at %s" +msgstr "" + +#: ../nova/virt/libvirt_conn.py:320 +msgid "Instance snapshotting is not supported for libvirtat this time" +msgstr "" -#: nova/utils.py:113 +#: ../nova/virt/libvirt_conn.py:336 #, python-format -msgid "Fetching %s" -msgstr "正在抓取%s" +msgid "instance %s: rebooted" +msgstr "" -#: nova/utils.py:125 +#: ../nova/virt/libvirt_conn.py:339 #, python-format -msgid "Running cmd (subprocess): %s" -msgstr "正在运行(在子进程中)运行命令:%s" +msgid "_wait_for_reboot failed: %s" +msgstr "" -#: nova/utils.py:138 +#: ../nova/virt/libvirt_conn.py:382 #, python-format -msgid "Result was %s" -msgstr "运行结果为 %s" +msgid "instance %s: rescued" +msgstr "" -#: nova/utils.py:171 +#: ../nova/virt/libvirt_conn.py:385 #, python-format -msgid "debug in callback: %s" -msgstr "回调中debug:%s" +msgid "_wait_for_rescue failed: %s" +msgstr "" -#: nova/utils.py:176 +#: ../nova/virt/libvirt_conn.py:411 #, python-format -msgid "Running %s" -msgstr "正在运行 %s" +msgid "instance %s: is running" +msgstr "" -#: nova/utils.py:207 +#: ../nova/virt/libvirt_conn.py:422 #, python-format -msgid "Couldn't get IP, using 127.0.0.1 %s" -msgstr "不能获取IP,将使用 127.0.0.1 %s" +msgid "instance %s: booted" +msgstr "" -#: nova/utils.py:289 +#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186 #, python-format -msgid "Invalid backend: %s" -msgstr "无效的后台:%s" +msgid "instance %s: failed to boot" +msgstr "" -#: nova/utils.py:300 +#: ../nova/virt/libvirt_conn.py:436 #, python-format -msgid "backend %s" -msgstr "后台 %s" +msgid "virsh said: %r" +msgstr "" -#: nova/api/ec2/__init__.py:133 -msgid "Too many failed authentications." -msgstr "较多失败的认证" +#: ../nova/virt/libvirt_conn.py:440 +msgid "cool, it's a device" +msgstr "" -#: nova/api/ec2/__init__.py:142 +#: ../nova/virt/libvirt_conn.py:448 #, python-format -msgid "" -"Access key %s has had %d failed authentications and will be locked out for " -"%d minutes." -msgstr "访问键 %s时,存在%d个失败的认证,将于%d分钟后解锁" +msgid "data: %(data)r, fpath: %(fpath)r" +msgstr "" -#: nova/api/ec2/__init__.py:179 nova/objectstore/handler.py:140 +#: ../nova/virt/libvirt_conn.py:456 #, python-format -msgid "Authentication Failure: %s" -msgstr "认证失败:%s" +msgid "Contents of file %(fpath)s: %(contents)r" +msgstr "" -#: nova/api/ec2/__init__.py:190 -#, python-format -msgid "Authenticated Request For %s:%s)" -msgstr "为%s:%s申请认证" +#: ../nova/virt/libvirt_conn.py:489 +msgid "Unable to find an open port" +msgstr "" -#: nova/api/ec2/__init__.py:227 +#: ../nova/virt/libvirt_conn.py:563 #, python-format -msgid "action: %s" -msgstr "执行: %s" +msgid "instance %s: Creating image" +msgstr "" -#: nova/api/ec2/__init__.py:229 +#: ../nova/virt/libvirt_conn.py:646 #, python-format -msgid "arg: %s\t\tval: %s" -msgstr "键为: %s\t\t值为: %s" +msgid "instance %(inst_name)s: injecting key into image %(img_id)s" +msgstr "" -#: nova/api/ec2/__init__.py:301 +#: ../nova/virt/libvirt_conn.py:649 #, python-format -msgid "Unauthorized request for controller=%s and action=%s" -msgstr "对控制器=%s及动作=%s未经授权" +msgid "instance %(inst_name)s: injecting net into image %(img_id)s" +msgstr "" -#: nova/api/ec2/__init__.py:339 +#. This could be a windows image, or a vmdk format disk +#: ../nova/virt/libvirt_conn.py:657 #, python-format -msgid "NotFound raised: %s" -msgstr "引起没有找到的错误: %s" +msgid "" +"instance %(inst_name)s: ignoring error injecting data into image %(img_id)s " +"(%(e)s)" +msgstr "" -#: nova/api/ec2/__init__.py:342 +#. TODO(termie): cache? +#: ../nova/virt/libvirt_conn.py:665 #, python-format -msgid "ApiError raised: %s" -msgstr "引发了Api错误: %s" +msgid "instance %s: starting toXML method" +msgstr "" -#: nova/api/ec2/__init__.py:349 +#: ../nova/virt/libvirt_conn.py:732 #, python-format -msgid "Unexpected error raised: %s" -msgstr "引发了意外的错误:%s" +msgid "instance %s: finished toXML method" +msgstr "" -#: nova/api/ec2/__init__.py:354 -msgid "An unknown error has occurred. Please try your request again." -msgstr "发生了一个未知的错误. 请重试你的请求." +#: ../nova/virt/libvirt_conn.py:751 +msgid "diagnostics are not supported for libvirt" +msgstr "" -#: nova/api/ec2/admin.py:84 +#: ../nova/virt/libvirt_conn.py:1225 #, python-format -msgid "Creating new user: %s" -msgstr "创建新用户: %s" +msgid "Attempted to unfilter instance %s which is not filtered" +msgstr "" -#: nova/api/ec2/admin.py:92 +#: ../nova/api/ec2/metadatarequesthandler.py:76 #, python-format -msgid "Deleting user: %s" -msgstr "删除用户: %s" +msgid "Failed to get metadata for ip: %s" +msgstr "" -#: nova/api/ec2/admin.py:114 -#, python-format -msgid "Adding role %s to user %s for project %s" -msgstr "正将%s角色赋予用户%s(在工程%s中)" +#: ../nova/auth/fakeldap.py:33 +msgid "Attempted to instantiate singleton" +msgstr "" -#: nova/api/ec2/admin.py:117 nova/auth/manager.py:415 +#: ../nova/network/api.py:39 #, python-format -msgid "Adding sitewide role %s to user %s" -msgstr "增加站点范围的 %s角色给用户 %s" +msgid "Quota exceeeded for %s, tried to allocate address" +msgstr "" -#: nova/api/ec2/admin.py:122 -#, python-format -msgid "Removing role %s from user %s for project %s" -msgstr "正将角色%s从用户%s在工程%s中移除" +#: ../nova/network/api.py:42 +msgid "Address quota exceeded. You cannot allocate any more addresses" +msgstr "" -#: nova/api/ec2/admin.py:125 nova/auth/manager.py:441 +#: ../nova/tests/test_volume.py:162 #, python-format -msgid "Removing sitewide role %s from user %s" +msgid "Target %s allocated" 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 +#: ../nova/virt/images.py:70 #, python-format -msgid "Getting x509 for user: %s on project: %s" -msgstr "为用户 %s从工程%s中获取 x509" +msgid "Finished retreving %(url)s -- placed in %(path)s" +msgstr "" -#: nova/api/ec2/admin.py:159 -#, python-format -msgid "Create project %s managed by %s" -msgstr "创建工程%s,此工程由%s管理" +#: ../nova/scheduler/driver.py:66 +msgid "Must implement a fallback schedule" +msgstr "" -#: nova/api/ec2/admin.py:170 -#, python-format -msgid "Delete project: %s" -msgstr "删除工程%s" +#: ../nova/console/manager.py:70 +msgid "Adding console" +msgstr "" -#: nova/api/ec2/admin.py:184 nova/auth/manager.py:533 +#: ../nova/console/manager.py:90 #, python-format -msgid "Adding user %s to project %s" -msgstr "增加用户%s到%s工程" +msgid "Tried to remove non-existant console %(console_id)s." +msgstr "" -#: nova/api/ec2/admin.py:188 -#, python-format -msgid "Removing user %s from project %s" -msgstr "正将用户%s从工程%s中移除" +#: ../nova/api/direct.py:149 +msgid "not available" +msgstr "" -#: nova/api/ec2/apirequest.py:95 +#: ../nova/api/ec2/cloud.py:62 #, python-format -msgid "Unsupported API request: controller = %s,action = %s" -msgstr "不支持的API请求: 控制器 = %s,执行 = %s" +msgid "The key_pair %s already exists" +msgstr "" -#: nova/api/ec2/cloud.py:117 +#. TODO(vish): Do this with M2Crypto instead +#: ../nova/api/ec2/cloud.py:118 #, python-format msgid "Generating root CA: %s" msgstr "生成根证书: %s" -#: nova/api/ec2/cloud.py:277 +#: ../nova/api/ec2/cloud.py:303 #, python-format msgid "Create key pair %s" msgstr "创建键值对 %s" -#: nova/api/ec2/cloud.py:285 +#: ../nova/api/ec2/cloud.py:311 #, python-format msgid "Delete key pair %s" msgstr "删除键值对 %s" -#: nova/api/ec2/cloud.py:357 +#: ../nova/api/ec2/cloud.py:386 #, python-format msgid "%s is not a valid ipProtocol" -msgstr "%s是无效的IP协议" +msgstr "%s 是无效的IP协议" -#: nova/api/ec2/cloud.py:361 +#: ../nova/api/ec2/cloud.py:390 msgid "Invalid port range" msgstr "端口范围无效" -#: nova/api/ec2/cloud.py:392 +#: ../nova/api/ec2/cloud.py:421 #, python-format msgid "Revoke security group ingress %s" msgstr "撤销输入安全组 %s" -#: nova/api/ec2/cloud.py:401 nova/api/ec2/cloud.py:414 +#: ../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:443 msgid "No rule for the specified parameters." msgstr "对给定的参数无特定规则。" -#: nova/api/ec2/cloud.py:421 +#: ../nova/api/ec2/cloud.py:450 #, python-format msgid "Authorize security group ingress %s" msgstr "验证输入安全组 %s" -#: nova/api/ec2/cloud.py:432 +#: ../nova/api/ec2/cloud.py:464 #, python-format msgid "This rule already exists in group %s" -msgstr "这条规则已经存在安全组%s中。" +msgstr "这条规则已经存在安全组 %s 中。" -#: nova/api/ec2/cloud.py:460 +#: ../nova/api/ec2/cloud.py:492 #, python-format msgid "Create Security Group %s" -msgstr "创建安全组%s" +msgstr "创建安全组 %s" -#: nova/api/ec2/cloud.py:463 +#: ../nova/api/ec2/cloud.py:495 #, python-format msgid "group %s already exists" -msgstr "安全组%s已经存在" +msgstr "安全组 %s 已经存在" -#: nova/api/ec2/cloud.py:475 +#: ../nova/api/ec2/cloud.py:507 #, 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 +#: ../nova/api/ec2/cloud.py:584 #, python-format msgid "Create volume of %s GB" msgstr "" -#: nova/api/ec2/cloud.py:567 +#: ../nova/api/ec2/cloud.py:612 #, python-format -msgid "Attach volume %s to instacne %s at %s" +msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s" msgstr "" -#: nova/api/ec2/cloud.py:579 +#: ../nova/api/ec2/cloud.py:629 #, python-format msgid "Detach volume %s" msgstr "" -#: nova/api/ec2/cloud.py:686 +#: ../nova/api/ec2/cloud.py:761 msgid "Allocate address" msgstr "" -#: nova/api/ec2/cloud.py:691 +#: ../nova/api/ec2/cloud.py:766 #, python-format msgid "Release address %s" msgstr "" -#: nova/api/ec2/cloud.py:696 +#: ../nova/api/ec2/cloud.py:771 #, python-format -msgid "Associate address %s to instance %s" +msgid "Associate address %(public_ip)s to instance %(instance_id)s" msgstr "" -#: nova/api/ec2/cloud.py:703 +#: ../nova/api/ec2/cloud.py:780 #, python-format msgid "Disassociate address %s" msgstr "" -#: nova/api/ec2/cloud.py:730 +#: ../nova/api/ec2/cloud.py:807 msgid "Going to start terminating instances" msgstr "" -#: nova/api/ec2/cloud.py:738 +#: ../nova/api/ec2/cloud.py:815 #, python-format msgid "Reboot instance %r" msgstr "" -#: nova/api/ec2/cloud.py:775 +#: ../nova/api/ec2/cloud.py:867 #, python-format msgid "De-registering image %s" msgstr "" -#: nova/api/ec2/cloud.py:783 +#: ../nova/api/ec2/cloud.py:875 #, python-format -msgid "Registered image %s with id %s" +msgid "Registered image %(image_location)s with id %(image_id)s" msgstr "" -#: nova/api/ec2/cloud.py:789 nova/api/ec2/cloud.py:804 +#: ../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:794 +#: ../nova/api/ec2/cloud.py:890 #, python-format msgid "invalid id: %s" msgstr "" -#: nova/api/ec2/cloud.py:807 +#: ../nova/api/ec2/cloud.py:903 msgid "user or group not specified" msgstr "" -#: nova/api/ec2/cloud.py:809 +#: ../nova/api/ec2/cloud.py:905 msgid "only group \"all\" is supported" msgstr "" -#: nova/api/ec2/cloud.py:811 +#: ../nova/api/ec2/cloud.py:907 msgid "operation_type must be add or remove" msgstr "" -#: nova/api/ec2/cloud.py:812 +#: ../nova/api/ec2/cloud.py:908 #, 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 +#: ../bin/nova-api.py:52 #, python-format -msgid "Project can't be created because user %s doesn't exist" +msgid "Using paste.deploy config at: %s" msgstr "" -#: nova/auth/ldapdriver.py:478 +#: ../bin/nova-api.py:57 #, python-format -msgid "User %s is already a member of the group %s" +msgid "No paste configuration for app: %s" msgstr "" -#: nova/auth/ldapdriver.py:507 +#: ../bin/nova-api.py:59 #, 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" +"App Config: %(api)s\n" +"%(config)r" msgstr "" -#: nova/auth/manager.py:264 +#: ../bin/nova-api.py:64 #, python-format -msgid "No user found for access key %s" +msgid "Running %s API" msgstr "" -#: nova/auth/manager.py:270 +#: ../bin/nova-api.py:69 #, python-format -msgid "Using project name = user name (%s)" +msgid "No known API applications configured in %s." msgstr "" -#: nova/auth/manager.py:275 +#: ../bin/nova-api.py:83 #, python-format -msgid "failed authorization: no project named %s (user=%s)" +msgid "Starting nova-api node (version %s)" msgstr "" -#: nova/auth/manager.py:277 +#: ../bin/nova-api.py:89 #, python-format -msgid "No project called %s could be found" +msgid "No paste configuration found for: %s" msgstr "" -#: nova/auth/manager.py:281 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84 #, python-format -msgid "Failed authorization: user %s not admin and not member of project %s" +msgid "Argument %(key)s value %(value)s is too short." msgstr "" -#: nova/auth/manager.py:283 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89 #, python-format -msgid "User %s is not a member of project %s" +msgid "Argument %(key)s value %(value)s contains invalid characters." msgstr "" -#: nova/auth/manager.py:292 nova/auth/manager.py:303 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94 #, python-format -msgid "Invalid signature for user %s" -msgstr "" - -#: nova/auth/manager.py:293 nova/auth/manager.py:304 -msgid "Signature does not match" +msgid "Argument %(key)s value %(value)s starts with a hyphen." msgstr "" -#: nova/auth/manager.py:374 -msgid "Must specify project" -msgstr "" - -#: nova/auth/manager.py:408 +#: ../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 "The %s role can not be found" +msgid "Argument %s is required." msgstr "" -#: nova/auth/manager.py:410 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117 #, python-format -msgid "The %s role is global only" +msgid "" +"Argument %(key)s may not take value %(value)s. Valid values are ['true', " +"'false']." msgstr "" -#: nova/auth/manager.py:412 +#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:163 #, python-format -msgid "Adding role %s to user %s in project %s" +msgid "" +"Created VDI %(vdi_ref)s (%(label)s, %(size)s, %(read_only)s) on %(sr_ref)s." msgstr "" -#: nova/auth/manager.py:438 +#: ../nova/virt/xenapi/vmops.py:67 #, python-format -msgid "Removing role %s from user %s on project %s" +msgid "Attempted to create non-unique name %s" msgstr "" -#: nova/auth/manager.py:505 +#: ../nova/virt/xenapi/vmops.py:73 #, python-format -msgid "Created project %s with manager %s" +msgid "instance %(name)s: not enough free memory" msgstr "" -#: nova/auth/manager.py:523 +#: ../nova/virt/xenapi/vmops.py:148 #, python-format -msgid "modifying project %s" +msgid "Starting VM %s..." msgstr "" -#: nova/auth/manager.py:553 +#: ../nova/virt/xenapi/vmops.py:151 #, python-format -msgid "Remove user %s from project %s" +msgid "Spawning VM %(instance_name)s created %(vm_ref)s." msgstr "" -#: nova/auth/manager.py:581 +#: ../nova/virt/xenapi/vmops.py:162 #, python-format -msgid "Deleting project %s" +msgid "Invalid value for onset_files: '%s'" msgstr "" -#: nova/auth/manager.py:637 +#: ../nova/virt/xenapi/vmops.py:167 #, python-format -msgid "Created user %s (admin: %r)" +msgid "Injecting file path: '%s'" msgstr "" -#: nova/auth/manager.py:645 +#: ../nova/virt/xenapi/vmops.py:180 #, python-format -msgid "Deleting user %s" +msgid "Instance %s: booted" msgstr "" -#: nova/auth/manager.py:655 +#: ../nova/virt/xenapi/vmops.py:232 #, python-format -msgid "Access Key change for user %s" +msgid "Instance not present %s" msgstr "" -#: nova/auth/manager.py:657 +#. TODO(sirp): Add quiesce and VSS locking support when Windows support +#. is added +#: ../nova/virt/xenapi/vmops.py:261 #, python-format -msgid "Secret Key change for user %s" +msgid "Starting snapshot for VM %s" msgstr "" -#: nova/auth/manager.py:659 +#: ../nova/virt/xenapi/vmops.py:269 #, python-format -msgid "Admin status set to %r for user %s" +msgid "Unable to Snapshot %(vm_ref)s: %(exc)s" msgstr "" -#: nova/auth/manager.py:708 +#: ../nova/virt/xenapi/vmops.py:280 #, python-format -msgid "No vpn data for project %s" +msgid "Finished snapshot and upload for VM %s" msgstr "" -#: nova/cloudpipe/pipelib.py:45 -msgid "Template for script to run on cloudpipe instance boot" +#: ../nova/virt/xenapi/vmops.py:356 +#, python-format +msgid "VM %(vm)s already halted, skipping shutdown..." msgstr "" -#: nova/cloudpipe/pipelib.py:48 -msgid "Network to push into openvpn config" +#: ../nova/virt/xenapi/vmops.py:389 +msgid "Removing kernel/ramdisk files" msgstr "" -#: nova/cloudpipe/pipelib.py:51 -msgid "Netmask to push into openvpn config" +#: ../nova/virt/xenapi/vmops.py:399 +msgid "kernel/ramdisk files removed" msgstr "" -#: nova/cloudpipe/pipelib.py:97 +#: ../nova/virt/xenapi/vmops.py:561 #, python-format -msgid "Launching VPN for %s" +msgid "" +"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/api.py:67 +#: ../nova/virt/xenapi/vmops.py:564 #, python-format -msgid "Instance %d was not found in get_network_topic" +msgid "" +"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM " +"id=%(instance_id)s; args=%(strargs)s" msgstr "" -#: nova/compute/api.py:73 +#: ../nova/virt/xenapi/vmops.py:569 #, python-format -msgid "Instance %d has no host" +msgid "" +"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; " +"args=%(strargs)s" msgstr "" -#: nova/compute/api.py:92 +#: ../nova/virt/xenapi/vmops.py:760 #, python-format -msgid "Quota exceeeded for %s, tried to run %s instances" +msgid "OpenSSL error: %s" msgstr "" -#: nova/compute/api.py:94 +#: ../nova/tests/test_compute.py:148 #, python-format -msgid "" -"Instance quota exceeded. You can only run %s more instances of this type." +msgid "Running instances: %s" msgstr "" -#: nova/compute/api.py:109 -msgid "Creating a raw instance" +#: ../nova/tests/test_compute.py:154 +#, python-format +msgid "After terminating instances: %s" msgstr "" -#: nova/compute/api.py:156 -#, python-format -msgid "Going to run %s instances..." +#: ../nova/cloudpipe/pipelib.py:45 +msgid "Template for script to run on cloudpipe instance boot" msgstr "" -#: nova/compute/api.py:180 -#, python-format -msgid "Casting to scheduler for %s/%s's instance %s" +#: ../nova/cloudpipe/pipelib.py:48 +msgid "Network to push into openvpn config" msgstr "" -#: nova/compute/api.py:279 -#, python-format -msgid "Going to try and terminate %s" +#: ../nova/cloudpipe/pipelib.py:51 +msgid "Netmask to push into openvpn config" msgstr "" -#: nova/compute/api.py:283 +#: ../nova/cloudpipe/pipelib.py:97 #, python-format -msgid "Instance %d was not found during terminate" +msgid "Launching VPN for %s" msgstr "" -#: nova/compute/api.py:288 -#, python-format -msgid "Instance %d is already being terminated" +#: ../nova/db/sqlalchemy/migration.py:35 +msgid "python-migrate is not installed. Exiting." msgstr "" -#: nova/compute/api.py:450 +#: ../nova/image/s3.py:99 #, python-format -msgid "Invalid device specified: %s. Example device: /dev/vdb" +msgid "Image %s could not be found" msgstr "" -#: nova/compute/api.py:465 -msgid "Volume isn't attached to anything!" -msgstr "" +#: ../nova/api/ec2/__init__.py:121 +msgid "Too many failed authentications." +msgstr "认证失败过多" -#: nova/compute/disk.py:71 +#: ../nova/api/ec2/__init__.py:131 #, python-format -msgid "Input partition size not evenly divisible by sector size: %d / %d" +msgid "" +"Access key %(access_key)s has had %(failures)d failed authentications and " +"will be locked out for %(lock_mins)d minutes." msgstr "" -#: nova/compute/disk.py:75 +#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140 #, python-format -msgid "Bytes for local storage not evenly divisible by sector size: %d / %d" -msgstr "" +msgid "Authentication Failure: %s" +msgstr "认证失败:%s" -#: nova/compute/disk.py:128 +#: ../nova/api/ec2/__init__.py:182 #, python-format -msgid "Could not attach image to loopback: %s" +msgid "Authenticated Request For %(uname)s:%(pname)s)" msgstr "" -#: nova/compute/disk.py:136 +#: ../nova/api/ec2/__init__.py:207 #, python-format -msgid "Failed to load partition: %s" -msgstr "" +msgid "action: %s" +msgstr "执行: %s" -#: nova/compute/disk.py:158 +#: ../nova/api/ec2/__init__.py:209 #, python-format -msgid "Failed to mount filesystem: %s" +msgid "arg: %(key)s\t\tval: %(value)s" msgstr "" -#: nova/compute/instance_types.py:41 +#: ../nova/api/ec2/__init__.py:281 #, python-format -msgid "Unknown instance type: %s" +msgid "" +"Unauthorized request for controller=%(controller)s and action=%(action)s" msgstr "" -#: nova/compute/manager.py:69 +#: ../nova/api/ec2/__init__.py:314 #, python-format -msgid "check_instance_lock: decorating: |%s|" +msgid "InstanceNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:71 +#: ../nova/api/ec2/__init__.py:320 #, python-format -msgid "check_instance_lock: arguments: |%s| |%s| |%s|" +msgid "VolumeNotFound raised: %s" msgstr "" -#: nova/compute/manager.py:75 +#: ../nova/api/ec2/__init__.py:326 #, python-format -msgid "check_instance_lock: locked: |%s|" -msgstr "" +msgid "NotFound raised: %s" +msgstr "引起没有找到的错误: %s" -#: nova/compute/manager.py:77 +#: ../nova/api/ec2/__init__.py:329 #, python-format -msgid "check_instance_lock: admin: |%s|" -msgstr "" +msgid "ApiError raised: %s" +msgstr "引发了Api错误: %s" -#: nova/compute/manager.py:82 +#: ../nova/api/ec2/__init__.py:338 #, python-format -msgid "check_instance_lock: executing: |%s|" -msgstr "" +msgid "Unexpected error raised: %s" +msgstr "引发了意外的错误:%s" -#: nova/compute/manager.py:86 +#: ../nova/api/ec2/__init__.py:343 +msgid "An unknown error has occurred. Please try your request again." +msgstr "发生了一个未知的错误. 请重试你的请求." + +#: ../nova/auth/dbdriver.py:84 #, python-format -msgid "check_instance_lock: not executing |%s|" +msgid "User %s already exists" msgstr "" -#: nova/compute/manager.py:157 -msgid "Instance has already been created" +#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232 +#, python-format +msgid "Project can't be created because manager %s doesn't exist" msgstr "" -#: nova/compute/manager.py:158 +#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243 #, python-format -msgid "instance %s: starting..." +msgid "Project can't be created because user %s doesn't exist" msgstr "" -#: nova/compute/manager.py:197 +#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229 #, python-format -msgid "instance %s: Failed to spawn" +msgid "Project can't be created because project %s already exists" msgstr "" -#: nova/compute/manager.py:211 nova/tests/test_cloud.py:228 +#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268 #, python-format -msgid "Terminating instance %s" +msgid "Project can't be modified because manager %s doesn't exist" msgstr "" -#: nova/compute/manager.py:217 +#: ../nova/auth/dbdriver.py:245 #, python-format -msgid "Disassociating address %s" +msgid "User \"%s\" not found" msgstr "" -#: nova/compute/manager.py:230 +#: ../nova/auth/dbdriver.py:248 #, python-format -msgid "Deallocating address %s" +msgid "Project \"%s\" not found" msgstr "" -#: nova/compute/manager.py:243 -#, python-format -msgid "trying to destroy already destroyed instance: %s" +#: ../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/compute/manager.py:257 +#: ../nova/virt/xenapi_conn.py:311 #, python-format -msgid "Rebooting instance %s" +msgid "Task [%(name)s] %(task)s status: success %(result)s" msgstr "" -#: nova/compute/manager.py:260 +#: ../nova/virt/xenapi_conn.py:317 #, python-format -msgid "trying to reboot a non-running instance: %s (state: %s excepted: %s)" +msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s" msgstr "" -#: nova/compute/manager.py:286 +#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344 #, python-format -msgid "instance %s: snapshotting" +msgid "Got exception: %s" msgstr "" -#: nova/compute/manager.py:289 +#: ../nova/compute/monitor.py:259 #, python-format -msgid "" -"trying to snapshot a non-running instance: %s (state: %s excepted: %s)" +msgid "updating %s..." msgstr "" -#: nova/compute/manager.py:301 -#, python-format -msgid "instance %s: rescuing" +#: ../nova/compute/monitor.py:289 +msgid "unexpected error during update" msgstr "" -#: nova/compute/manager.py:316 +#: ../nova/compute/monitor.py:356 #, python-format -msgid "instance %s: unrescuing" +msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/manager.py:335 +#: ../nova/compute/monitor.py:379 #, python-format -msgid "instance %s: pausing" +msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\"" msgstr "" -#: nova/compute/manager.py:352 -#, python-format -msgid "instance %s: unpausing" +#: ../nova/compute/monitor.py:414 +msgid "unexpected exception getting connection" msgstr "" -#: nova/compute/manager.py:369 +#: ../nova/compute/monitor.py:429 #, python-format -msgid "instance %s: retrieving diagnostics" +msgid "Found instance: %s" msgstr "" -#: nova/compute/manager.py:382 +#: ../nova/volume/san.py:67 #, python-format -msgid "instance %s: suspending" +msgid "Could not find iSCSI export for volume %s" msgstr "" -#: nova/compute/manager.py:401 +#: ../nova/api/ec2/apirequest.py:100 #, python-format -msgid "instance %s: resuming" +msgid "" +"Unsupported API request: controller = %(controller)s, action = %(action)s" msgstr "" -#: nova/compute/manager.py:420 +#: ../nova/api/openstack/__init__.py:55 #, python-format -msgid "instance %s: locking" +msgid "Caught error: %s" msgstr "" -#: nova/compute/manager.py:432 -#, python-format -msgid "instance %s: unlocking" +#: ../nova/api/openstack/__init__.py:76 +msgid "Including admin operations in API." msgstr "" -#: nova/compute/manager.py:442 -#, python-format -msgid "instance %s: getting locked state" +#: ../nova/console/xvp.py:99 +msgid "Rebuilding xvp conf" msgstr "" -#: nova/compute/manager.py:462 +#: ../nova/console/xvp.py:116 #, python-format -msgid "instance %s: attaching volume %s to %s" +msgid "Re-wrote %s" msgstr "" -#: nova/compute/manager.py:478 -#, python-format -msgid "instance %s: attach failed %s, removing" +#: ../nova/console/xvp.py:121 +msgid "Stopping xvp" msgstr "" -#: nova/compute/manager.py:493 -#, python-format -msgid "Detach volume %s from mountpoint %s on instance %s" +#: ../nova/console/xvp.py:134 +msgid "Starting xvp" msgstr "" -#: nova/compute/manager.py:497 +#: ../nova/console/xvp.py:141 #, python-format -msgid "Detaching volume from unknown instance %s" +msgid "Error starting xvp: %s" msgstr "" -#: nova/compute/monitor.py:259 -#, python-format -msgid "updating %s..." +#: ../nova/console/xvp.py:144 +msgid "Restarting xvp" msgstr "" -#: nova/compute/monitor.py:289 -msgid "unexpected error during update" +#: ../nova/console/xvp.py:146 +msgid "xvp not running..." msgstr "" -#: nova/compute/monitor.py:355 -#, python-format -msgid "Cannot get blockstats for \"%s\" on \"%s\"" +#: ../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 "" -#: nova/compute/monitor.py:377 -#, python-format -msgid "Cannot get ifstats for \"%s\" on \"%s\"" +#: ../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 "" -#: nova/compute/monitor.py:412 -msgid "unexpected exception getting connection" +#: ../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/compute/monitor.py:427 -#, python-format -msgid "Found instance: %s" +#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536 +msgid "network" msgstr "" -#: nova/db/sqlalchemy/api.py:43 -msgid "Use of empty request context is deprecated" +#: ../bin/nova-manage.py:448 +msgid "IP address" msgstr "" -#: nova/db/sqlalchemy/api.py:132 -#, python-format -msgid "No service for id %s" +#: ../bin/nova-manage.py:449 +msgid "MAC address" msgstr "" -#: nova/db/sqlalchemy/api.py:229 -#, python-format -msgid "No service for %s, %s" +#: ../bin/nova-manage.py:450 +msgid "hostname" msgstr "" -#: nova/db/sqlalchemy/api.py:574 -#, python-format -msgid "No floating ip for address %s" +#: ../bin/nova-manage.py:451 +msgid "host" msgstr "" -#: nova/db/sqlalchemy/api.py:668 -#, python-format -msgid "No instance for id %s" +#: ../bin/nova-manage.py:537 +msgid "netmask" 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" +#: ../bin/nova-manage.py:538 +msgid "start address" msgstr "" -#: nova/db/sqlalchemy/api.py:891 +#: ../nova/virt/disk.py:69 #, python-format -msgid "no keypair for user %s, name %s" +msgid "Failed to load partition: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1006 nova/db/sqlalchemy/api.py:1064 +#: ../nova/virt/disk.py:91 #, python-format -msgid "No network for id %s" +msgid "Failed to mount filesystem: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1036 +#: ../nova/virt/disk.py:124 #, python-format -msgid "No network for bridge %s" +msgid "nbd device %s did not show up" msgstr "" -#: nova/db/sqlalchemy/api.py:1050 +#: ../nova/virt/disk.py:128 #, python-format -msgid "No network for instance %s" +msgid "Could not attach image to loopback: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1180 -#, python-format -msgid "Token %s does not exist" +#: ../nova/virt/disk.py:151 +msgid "No free nbd devices" msgstr "" -#: nova/db/sqlalchemy/api.py:1205 +#: ../doc/ext/nova_todo.py:46 #, python-format -msgid "No quota for project_id %s" +msgid "%(filename)s, line %(line_info)d" msgstr "" -#: nova/db/sqlalchemy/api.py:1356 -#, python-format -msgid "No volume for id %s" +#. FIXME(chiradeep): implement this +#: ../nova/virt/hyperv.py:118 +msgid "In init host" msgstr "" -#: nova/db/sqlalchemy/api.py:1401 +#: ../nova/virt/hyperv.py:131 #, python-format -msgid "Volume %s not found" +msgid "Attempt to create duplicate vm %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1413 +#: ../nova/virt/hyperv.py:148 #, python-format -msgid "No export device found for volume %s" +msgid "Starting VM %s " msgstr "" -#: nova/db/sqlalchemy/api.py:1426 +#: ../nova/virt/hyperv.py:150 #, python-format -msgid "No target id found for volume %s" +msgid "Started VM %s " msgstr "" -#: nova/db/sqlalchemy/api.py:1471 +#: ../nova/virt/hyperv.py:152 #, python-format -msgid "No security group with id %s" +msgid "spawn vm failed: %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1488 +#: ../nova/virt/hyperv.py:169 #, python-format -msgid "No security group named %s for project: %s" +msgid "Failed to create VM %s" msgstr "" -#: nova/db/sqlalchemy/api.py:1576 +#: ../nova/virt/hyperv.py:188 #, python-format -msgid "No secuity group rule with id %s" +msgid "Set memory for vm %s..." msgstr "" -#: nova/db/sqlalchemy/api.py:1650 +#: ../nova/virt/hyperv.py:198 #, python-format -msgid "No user for id %s" +msgid "Set vcpus for vm %s..." msgstr "" -#: nova/db/sqlalchemy/api.py:1666 +#: ../nova/virt/hyperv.py:202 #, python-format -msgid "No user for access key %s" +msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s" msgstr "" -#: nova/db/sqlalchemy/api.py:1728 +#: ../nova/virt/hyperv.py:227 #, python-format -msgid "No project with id %s" +msgid "Failed to add diskdrive to VM %s" msgstr "" -#: nova/image/glance.py:78 +#: ../nova/virt/hyperv.py:230 #, python-format -msgid "Parallax returned HTTP error %d from request for /images" +msgid "New disk drive path is %s" msgstr "" -#: nova/image/glance.py:97 +#: ../nova/virt/hyperv.py:247 #, python-format -msgid "Parallax returned HTTP error %d from request for /images/detail" +msgid "Failed to add vhd file to VM %s" msgstr "" -#: nova/image/s3.py:82 +#: ../nova/virt/hyperv.py:249 #, python-format -msgid "Image %s could not be found" +msgid "Created disk for %s" msgstr "" -#: nova/network/api.py:39 +#: ../nova/virt/hyperv.py:253 #, python-format -msgid "Quota exceeeded for %s, tried to allocate address" +msgid "Creating nic for %s " msgstr "" -#: nova/network/api.py:42 -msgid "Address quota exceeded. You cannot allocate any more addresses" +#: ../nova/virt/hyperv.py:272 +msgid "Failed creating a port on the external vswitch" msgstr "" -#: nova/network/linux_net.py:176 +#: ../nova/virt/hyperv.py:273 #, python-format -msgid "Starting VLAN inteface %s" +msgid "Failed creating port for %s" msgstr "" -#: nova/network/linux_net.py:186 +#: ../nova/virt/hyperv.py:276 #, python-format -msgid "Starting Bridge interface for %s" +msgid "Created switch port %(vm_name)s on switch %(ext_path)s" msgstr "" -#: nova/network/linux_net.py:254 +#: ../nova/virt/hyperv.py:286 #, python-format -msgid "Hupping dnsmasq threw %s" +msgid "Failed to add nic to VM %s" msgstr "" -#: nova/network/linux_net.py:256 +#: ../nova/virt/hyperv.py:288 #, python-format -msgid "Pid %d is stale, relaunching dnsmasq" +msgid "Created nic for %s " msgstr "" -#: nova/network/linux_net.py:334 +#: ../nova/virt/hyperv.py:321 #, python-format -msgid "Killing dnsmasq threw %s" +msgid "WMI job failed: %s" msgstr "" -#: nova/network/manager.py:135 -msgid "setting network host" +#: ../nova/virt/hyperv.py:325 +#, python-format +msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s " msgstr "" -#: nova/network/manager.py:190 +#: ../nova/virt/hyperv.py:361 #, python-format -msgid "Leasing IP %s" +msgid "Got request to destroy vm %s" msgstr "" -#: nova/network/manager.py:194 +#: ../nova/virt/hyperv.py:386 #, python-format -msgid "IP %s leased that isn't associated" +msgid "Failed to destroy vm %s" msgstr "" -#: nova/network/manager.py:197 +#: ../nova/virt/hyperv.py:393 #, python-format -msgid "IP %s leased to bad mac %s vs %s" +msgid "Del: disk %(vhdfile)s vm %(instance_name)s" msgstr "" -#: nova/network/manager.py:205 +#: ../nova/virt/hyperv.py:415 #, python-format -msgid "IP %s leased that was already deallocated" +msgid "" +"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, " +"num_cpu=%(numprocs)s, cpu_time=%(uptime)s" msgstr "" -#: nova/network/manager.py:214 +#: ../nova/virt/hyperv.py:451 #, python-format -msgid "IP %s released that isn't associated" +msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/network/manager.py:217 +#: ../nova/virt/hyperv.py:454 #, python-format -msgid "IP %s released from bad mac %s vs %s" +msgid "Failed to change vm state of %(vm_name)s to %(req_state)s" msgstr "" -#: nova/network/manager.py:220 +#: ../nova/compute/api.py:71 #, python-format -msgid "IP %s released that was not leased" +msgid "Instance %d was not found in get_network_topic" msgstr "" -#: nova/network/manager.py:442 +#: ../nova/compute/api.py:77 #, python-format -msgid "Dissassociated %s stale fixed ip(s)" +msgid "Instance %d has no host" msgstr "" -#: nova/objectstore/handler.py:106 +#: ../nova/compute/api.py:97 #, python-format -msgid "Unknown S3 value type %r" +msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances" msgstr "" -#: nova/objectstore/handler.py:137 -msgid "Authenticated request" +#: ../nova/compute/api.py:99 +#, python-format +msgid "" +"Instance quota exceeded. You can only run %s more instances of this type." msgstr "" -#: nova/objectstore/handler.py:182 -msgid "List of buckets requested" +#: ../nova/compute/api.py:112 +msgid "Creating a raw instance" msgstr "" -#: nova/objectstore/handler.py:209 +#: ../nova/compute/api.py:160 #, python-format -msgid "List keys for bucket %s" +msgid "Going to run %s instances..." msgstr "" -#: nova/objectstore/handler.py:217 +#: ../nova/compute/api.py:187 #, python-format -msgid "Unauthorized attempt to access bucket %s" +msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s" msgstr "" -#: nova/objectstore/handler.py:235 +#: ../nova/compute/api.py:292 #, python-format -msgid "Creating bucket %s" +msgid "Going to try to terminate %s" msgstr "" -#: nova/objectstore/handler.py:245 +#: ../nova/compute/api.py:296 #, python-format -msgid "Deleting bucket %s" +msgid "Instance %d was not found during terminate" msgstr "" -#: nova/objectstore/handler.py:249 +#: ../nova/compute/api.py:301 #, python-format -msgid "Unauthorized attempt to delete bucket %s" +msgid "Instance %d is already being terminated" msgstr "" -#: nova/objectstore/handler.py:271 +#: ../nova/compute/api.py:481 #, python-format -msgid "Getting object: %s / %s" +msgid "Invalid device specified: %s. Example device: /dev/vdb" msgstr "" -#: nova/objectstore/handler.py:274 -#, python-format -msgid "Unauthorized attempt to get object %s from bucket %s" +#: ../nova/compute/api.py:496 +msgid "Volume isn't attached to anything!" msgstr "" -#: nova/objectstore/handler.py:292 +#: ../nova/rpc.py:98 #, python-format -msgid "Putting object: %s / %s" +msgid "" +"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in " +"%(fl_intv)d seconds." msgstr "" -#: nova/objectstore/handler.py:295 +#: ../nova/rpc.py:103 #, python-format -msgid "Unauthorized attempt to upload object %s to bucket %s" -msgstr "" +msgid "Unable to connect to AMQP server after %d tries. Shutting down." +msgstr "已尝试 %d 次,均无法连接到AMQP服务器。关闭中。" -#: nova/objectstore/handler.py:314 -#, python-format -msgid "Deleting object: %s / %s" -msgstr "" +#: ../nova/rpc.py:122 +msgid "Reconnected to queue" +msgstr "重新与队列建立连接" -#: nova/objectstore/handler.py:393 -#, python-format -msgid "Not authorized to upload image: invalid directory %s" -msgstr "" +#: ../nova/rpc.py:129 +msgid "Failed to fetch message from queue" +msgstr "从队列获取数据失败" -#: nova/objectstore/handler.py:401 +#: ../nova/rpc.py:159 #, python-format -msgid "Not authorized to upload image: unauthorized bucket %s" +msgid "Initing the Adapter Consumer for %s" msgstr "" -#: nova/objectstore/handler.py:406 +#: ../nova/rpc.py:178 #, python-format -msgid "Starting image upload: %s" -msgstr "" +msgid "received %s" +msgstr "已接收 %s" -#: nova/objectstore/handler.py:420 +#. 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:191 #, python-format -msgid "Not authorized to update attributes of image %s" -msgstr "" +msgid "no method for message: %s" +msgstr "没有适用于消息 %s 的方法" -#: nova/objectstore/handler.py:428 +#: ../nova/rpc.py:192 #, python-format -msgid "Toggling publicity flag of image %s %r" -msgstr "" +msgid "No method for message: %s" +msgstr "没有适用于消息 %s 的方法" -#: nova/objectstore/handler.py:433 +#: ../nova/rpc.py:253 #, python-format -msgid "Updating user fields on image %s" -msgstr "" +msgid "Returning exception %s to caller" +msgstr "返回 %s 异常给调用者" -#: nova/objectstore/handler.py:447 +#: ../nova/rpc.py:294 #, python-format -msgid "Unauthorized attempt to delete image %s" +msgid "unpacked context: %s" msgstr "" -#: nova/objectstore/handler.py:452 -#, python-format -msgid "Deleted image: %s" -msgstr "" +#: ../nova/rpc.py:313 +msgid "Making asynchronous call..." +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/rpc.py:316 +#, python-format +msgid "MSG_ID is %s" +msgstr "消息ID(MSG_ID)是 %s" -#: nova/scheduler/driver.py:66 -msgid "Must implement a fallback schedule" +#: ../nova/rpc.py:354 +msgid "Making asynchronous cast..." msgstr "" -#: nova/scheduler/manager.py:69 +#: ../nova/rpc.py:364 #, python-format -msgid "Casting to %s %s for %s" -msgstr "" +msgid "response %s" +msgstr "回复 %s" -#: nova/scheduler/simple.py:63 -msgid "All hosts have too many cores" -msgstr "" +#: ../nova/rpc.py:373 +#, python-format +msgid "topic is %s" +msgstr "话题是 %s" -#: nova/scheduler/simple.py:95 -msgid "All hosts have too many gigabytes" -msgstr "" +#: ../nova/rpc.py:374 +#, python-format +msgid "message %s" +msgstr "消息 %s" -#: nova/scheduler/simple.py:115 -msgid "All hosts have too many networks" +#: ../nova/volume/driver.py:78 +#, python-format +msgid "Recovering from a failed execute. Try number %s" msgstr "" -#: nova/tests/test_cloud.py:198 -msgid "Can't test instances without a real virtual env." +#: ../nova/volume/driver.py:87 +#, python-format +msgid "volume group %s doesn't exist" msgstr "" -#: nova/tests/test_cloud.py:210 +#: ../nova/volume/driver.py:220 #, python-format -msgid "Need to watch instance %s until it's running..." +msgid "FAKE AOE: %s" msgstr "" -#: nova/tests/test_compute.py:104 -#, python-format -msgid "Running instances: %s" +#: ../nova/volume/driver.py:233 +msgid "Skipping ensure_export. No iscsi_target " msgstr "" -#: nova/tests/test_compute.py:110 -#, python-format -msgid "After terminating instances: %s" +#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288 +msgid "Skipping remove_export. No iscsi_target " msgstr "" -#: nova/tests/test_rpc.py:89 +#: ../nova/volume/driver.py:347 #, python-format -msgid "Nested received %s, %s" +msgid "FAKE ISCSI: %s" msgstr "" -#: nova/tests/test_rpc.py:94 +#: ../nova/volume/driver.py:359 #, python-format -msgid "Nested return %s" +msgid "rbd has no pool %s" msgstr "" -#: nova/tests/test_rpc.py:119 nova/tests/test_rpc.py:125 +#: ../nova/volume/driver.py:414 #, python-format -msgid "Received %s" +msgid "Sheepdog is not working: %s" msgstr "" -#: nova/tests/test_volume.py:162 +#: ../nova/volume/driver.py:416 +msgid "Sheepdog is not working" +msgstr "" + +#: ../nova/wsgi.py:68 #, python-format -msgid "Target %s allocated" +msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: nova/virt/connection.py:73 -msgid "Failed to open connection to the hypervisor" +#: ../nova/wsgi.py:147 +msgid "You must implement __call__" msgstr "" -#: nova/virt/fake.py:210 -#, python-format -msgid "Instance %s Not Found" +#: ../bin/nova-instancemonitor.py:55 +msgid "Starting instance monitor" msgstr "" -#: nova/virt/hyperv.py:118 -msgid "In init host" +#: ../bin/nova-dhcpbridge.py:58 +msgid "leasing ip" msgstr "" -#: nova/virt/hyperv.py:131 -#, python-format -msgid "Attempt to create duplicate vm %s" +#: ../bin/nova-dhcpbridge.py:73 +msgid "Adopted old lease or got a change of mac/hostname" msgstr "" -#: nova/virt/hyperv.py:148 -#, python-format -msgid "Starting VM %s " +#: ../bin/nova-dhcpbridge.py:80 +msgid "releasing ip" msgstr "" -#: nova/virt/hyperv.py:150 +#: ../bin/nova-dhcpbridge.py:123 #, python-format -msgid "Started VM %s " +msgid "" +"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s " +"on interface %(interface)s" msgstr "" -#: nova/virt/hyperv.py:152 +#: ../nova/virt/fake.py:239 #, python-format -msgid "spawn vm failed: %s" +msgid "Instance %s Not Found" msgstr "" -#: nova/virt/hyperv.py:169 +#: ../nova/network/manager.py:153 #, python-format -msgid "Failed to create VM %s" +msgid "Dissassociated %s stale fixed ip(s)" msgstr "" -#: nova/virt/hyperv.py:171 nova/virt/xenapi/vm_utils.py:125 -#, python-format -msgid "Created VM %s..." +#: ../nova/network/manager.py:157 +msgid "setting network host" msgstr "" -#: nova/virt/hyperv.py:188 +#: ../nova/network/manager.py:212 #, python-format -msgid "Set memory for vm %s..." +msgid "Leasing IP %s" msgstr "" -#: nova/virt/hyperv.py:198 +#: ../nova/network/manager.py:216 #, python-format -msgid "Set vcpus for vm %s..." +msgid "IP %s leased that isn't associated" msgstr "" -#: nova/virt/hyperv.py:202 +#: ../nova/network/manager.py:220 #, python-format -msgid "Creating disk for %s by attaching disk file %s" +msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/hyperv.py:227 +#: ../nova/network/manager.py:228 #, python-format -msgid "Failed to add diskdrive to VM %s" +msgid "IP %s leased that was already deallocated" msgstr "" -#: nova/virt/hyperv.py:230 +#: ../nova/network/manager.py:233 #, python-format -msgid "New disk drive path is %s" +msgid "Releasing IP %s" msgstr "" -#: nova/virt/hyperv.py:247 +#: ../nova/network/manager.py:237 #, python-format -msgid "Failed to add vhd file to VM %s" +msgid "IP %s released that isn't associated" msgstr "" -#: nova/virt/hyperv.py:249 +#: ../nova/network/manager.py:241 #, python-format -msgid "Created disk for %s" +msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s" msgstr "" -#: nova/virt/hyperv.py:253 +#: ../nova/network/manager.py:244 #, python-format -msgid "Creating nic for %s " +msgid "IP %s released that was not leased" msgstr "" -#: nova/virt/hyperv.py:272 -msgid "Failed creating a port on the external vswitch" +#: ../nova/network/manager.py:519 +msgid "" +"The sum between the number of networks and the vlan start cannot be greater " +"than 4094" msgstr "" -#: nova/virt/hyperv.py:273 +#: ../nova/virt/xenapi/volume_utils.py:57 #, python-format -msgid "Failed creating port for %s" +msgid "Introducing %s..." msgstr "" -#: nova/virt/hyperv.py:275 +#: ../nova/virt/xenapi/volume_utils.py:74 #, python-format -msgid "Created switch port %s on switch %s" +msgid "Introduced %(label)s as %(sr_ref)s." msgstr "" -#: nova/virt/hyperv.py:285 -#, python-format -msgid "Failed to add nic to VM %s" +#: ../nova/virt/xenapi/volume_utils.py:78 +msgid "Unable to create Storage Repository" msgstr "" -#: nova/virt/hyperv.py:287 +#: ../nova/virt/xenapi/volume_utils.py:90 #, python-format -msgid "Created nic for %s " +msgid "Unable to find SR from VBD %s" msgstr "" -#: nova/virt/hyperv.py:320 +#: ../nova/virt/xenapi/volume_utils.py:96 #, python-format -msgid "WMI job failed: %s" +msgid "Forgetting SR %s ... " msgstr "" -#: nova/virt/hyperv.py:322 +#: ../nova/virt/xenapi/volume_utils.py:101 #, python-format -msgid "WMI job succeeded: %s, Elapsed=%s " +msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s" msgstr "" -#: nova/virt/hyperv.py:358 +#: ../nova/virt/xenapi/volume_utils.py:107 #, python-format -msgid "Got request to destroy vm %s" +msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s" msgstr "" -#: nova/virt/hyperv.py:383 +#: ../nova/virt/xenapi/volume_utils.py:111 #, python-format -msgid "Failed to destroy vm %s" +msgid "Forgetting SR %s done." msgstr "" -#: nova/virt/hyperv.py:389 +#: ../nova/virt/xenapi/volume_utils.py:113 #, python-format -msgid "Del: disk %s vm %s" +msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s" msgstr "" -#: nova/virt/hyperv.py:405 +#: ../nova/virt/xenapi/volume_utils.py:123 #, python-format -msgid "" -"Got Info for vm %s: state=%s, mem=%s, num_cpu=%s, " -"cpu_time=%s" +msgid "Unable to introduce VDI on SR %s" msgstr "" -#: nova/virt/hyperv.py:424 nova/virt/xenapi/vm_utils.py:301 +#: ../nova/virt/xenapi/volume_utils.py:128 #, python-format -msgid "duplicate name found: %s" +msgid "Unable to get record of VDI %s on" msgstr "" -#: nova/virt/hyperv.py:444 +#: ../nova/virt/xenapi/volume_utils.py:146 #, python-format -msgid "Successfully changed vm state of %s to %s" +msgid "Unable to introduce VDI for SR %s" msgstr "" -#: nova/virt/hyperv.py:447 nova/virt/hyperv.py:449 +#: ../nova/virt/xenapi/volume_utils.py:175 #, python-format -msgid "Failed to change vm state of %s to %s" +msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s" msgstr "" -#: nova/virt/images.py:70 +#: ../nova/virt/xenapi/volume_utils.py:197 #, python-format -msgid "Finished retreving %s -- placed in %s" +msgid "Mountpoint cannot be translated: %s" msgstr "" -#: nova/virt/libvirt_conn.py:144 +#: ../nova/objectstore/image.py:262 #, python-format -msgid "Connecting to libvirt: %s" +msgid "Failed to decrypt private key: %s" msgstr "" -#: nova/virt/libvirt_conn.py:157 -msgid "Connection to libvirt broke" +#: ../nova/objectstore/image.py:269 +#, python-format +msgid "Failed to decrypt initialization vector: %s" msgstr "" -#: nova/virt/libvirt_conn.py:229 +#: ../nova/objectstore/image.py:277 #, python-format -msgid "instance %s: deleting instance files %s" +msgid "Failed to decrypt image file %(image_file)s: %(err)s" msgstr "" -#: nova/virt/libvirt_conn.py:271 +#: ../nova/objectstore/handler.py:106 #, python-format -msgid "No disk at %s" +msgid "Unknown S3 value type %r" msgstr "" -#: nova/virt/libvirt_conn.py:278 -msgid "Instance snapshotting is not supported for libvirtat this time" +#: ../nova/objectstore/handler.py:137 +msgid "Authenticated request" msgstr "" -#: nova/virt/libvirt_conn.py:294 -#, python-format -msgid "instance %s: rebooted" +#: ../nova/objectstore/handler.py:182 +msgid "List of buckets requested" msgstr "" -#: nova/virt/libvirt_conn.py:297 +#: ../nova/objectstore/handler.py:209 #, python-format -msgid "_wait_for_reboot failed: %s" +msgid "List keys for bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:340 +#: ../nova/objectstore/handler.py:217 #, python-format -msgid "instance %s: rescued" +msgid "Unauthorized attempt to access bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:343 +#: ../nova/objectstore/handler.py:235 #, python-format -msgid "_wait_for_rescue failed: %s" +msgid "Creating bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:370 +#: ../nova/objectstore/handler.py:245 #, python-format -msgid "instance %s: is running" +msgid "Deleting bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:381 +#: ../nova/objectstore/handler.py:249 #, python-format -msgid "instance %s: booted" +msgid "Unauthorized attempt to delete bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:384 nova/virt/xenapi/vmops.py:116 +#: ../nova/objectstore/handler.py:273 #, python-format -msgid "instance %s: failed to boot" +msgid "Getting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/libvirt_conn.py:395 +#: ../nova/objectstore/handler.py:276 #, python-format -msgid "virsh said: %r" +msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/libvirt_conn.py:399 -msgid "cool, it's a device" +#: ../nova/objectstore/handler.py:296 +#, python-format +msgid "Putting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/libvirt_conn.py:407 +#: ../nova/objectstore/handler.py:299 #, python-format -msgid "data: %r, fpath: %r" +msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s" msgstr "" -#: nova/virt/libvirt_conn.py:415 +#: ../nova/objectstore/handler.py:318 #, python-format -msgid "Contents of file %s: %r" +msgid "Deleting object: %(bname)s / %(nm)s" msgstr "" -#: nova/virt/libvirt_conn.py:449 +#: ../nova/objectstore/handler.py:322 #, python-format -msgid "instance %s: Creating image" +msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s" msgstr "" -#: nova/virt/libvirt_conn.py:505 +#: ../nova/objectstore/handler.py:396 #, python-format -msgid "instance %s: injecting key into image %s" +msgid "Not authorized to upload image: invalid directory %s" msgstr "" -#: nova/virt/libvirt_conn.py:508 +#: ../nova/objectstore/handler.py:404 #, python-format -msgid "instance %s: injecting net into image %s" +msgid "Not authorized to upload image: unauthorized bucket %s" msgstr "" -#: nova/virt/libvirt_conn.py:516 +#: ../nova/objectstore/handler.py:409 #, python-format -msgid "instance %s: ignoring error injecting data into image %s (%s)" +msgid "Starting image upload: %s" msgstr "" -#: nova/virt/libvirt_conn.py:544 nova/virt/libvirt_conn.py:547 +#: ../nova/objectstore/handler.py:423 #, python-format -msgid "instance %s: starting toXML method" +msgid "Not authorized to update attributes of image %s" msgstr "" -#: nova/virt/libvirt_conn.py:589 +#: ../nova/objectstore/handler.py:431 #, python-format -msgid "instance %s: finished toXML method" +msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r" 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" +#. other attributes imply update +#: ../nova/objectstore/handler.py:436 +#, python-format +msgid "Updating user fields on image %s" msgstr "" -#: nova/virt/xenapi_conn.py:263 +#: ../nova/objectstore/handler.py:450 #, python-format -msgid "Task [%s] %s status: success %s" +msgid "Unauthorized attempt to delete image %s" msgstr "" -#: nova/virt/xenapi_conn.py:271 +#: ../nova/objectstore/handler.py:455 #, python-format -msgid "Task [%s] %s status: %s %s" +msgid "Deleted image: %s" msgstr "" -#: nova/virt/xenapi_conn.py:287 nova/virt/xenapi_conn.py:300 +#: ../nova/auth/manager.py:259 #, python-format -msgid "Got exception: %s" +msgid "Looking up user: %r" msgstr "" -#: nova/virt/xenapi/fake.py:72 +#: ../nova/auth/manager.py:263 #, python-format -msgid "%s: _db_content => %s" +msgid "Failed authorization for access key %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" +#: ../nova/auth/manager.py:264 +#, python-format +msgid "No user found for access key %s" msgstr "" -#: nova/virt/xenapi/fake.py:249 +#: ../nova/auth/manager.py:270 #, python-format -msgid "xenapi.fake does not have an implementation for %s" +msgid "Using project name = user name (%s)" msgstr "" -#: nova/virt/xenapi/fake.py:283 +#: ../nova/auth/manager.py:277 #, python-format -msgid "Calling %s %s" +msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)" msgstr "" -#: nova/virt/xenapi/fake.py:288 +#: ../nova/auth/manager.py:279 #, python-format -msgid "Calling getter %s" +msgid "No project called %s could be found" msgstr "" -#: nova/virt/xenapi/fake.py:340 +#: ../nova/auth/manager.py:287 #, python-format msgid "" -"xenapi.fake does not have an implementation for %s or it has been called " -"with the wrong number of arguments" +"Failed authorization: user %(uname)s not admin and not member of project " +"%(pjname)s" msgstr "" -#: nova/virt/xenapi/network_utils.py:40 +#: ../nova/auth/manager.py:289 #, python-format -msgid "Found non-unique network for bridge %s" +msgid "User %(uid)s is not a member of project %(pjid)s" msgstr "" -#: nova/virt/xenapi/network_utils.py:43 +#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309 #, python-format -msgid "Found no network for bridge %s" +msgid "Invalid signature for user %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:127 -#, python-format -msgid "Created VM %s as %s." +#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310 +msgid "Signature does not match" msgstr "" -#: nova/virt/xenapi/vm_utils.py:147 -#, python-format -msgid "Creating VBD for VM %s, VDI %s ... " +#: ../nova/auth/manager.py:380 +msgid "Must specify project" msgstr "" -#: nova/virt/xenapi/vm_utils.py:149 +#: ../nova/auth/manager.py:414 #, python-format -msgid "Created VBD %s for VM %s, VDI %s." +msgid "The %s role can not be found" msgstr "" -#: nova/virt/xenapi/vm_utils.py:165 +#: ../nova/auth/manager.py:416 #, python-format -msgid "VBD not found in instance %s" +msgid "The %s role is global only" msgstr "" -#: nova/virt/xenapi/vm_utils.py:175 +#: ../nova/auth/manager.py:420 #, python-format -msgid "Unable to unplug VBD %s" +msgid "Adding role %(role)s to user %(uid)s in project %(pid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:187 +#: ../nova/auth/manager.py:423 #, python-format -msgid "Unable to destroy VBD %s" +msgid "Adding sitewide role %(role)s to user %(uid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:202 +#: ../nova/auth/manager.py:448 #, python-format -msgid "Creating VIF for VM %s, network %s." +msgid "Removing role %(role)s from user %(uid)s on project %(pid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:205 +#: ../nova/auth/manager.py:451 #, python-format -msgid "Created VIF %s for VM %s, network %s." +msgid "Removing sitewide role %(role)s from user %(uid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:216 +#: ../nova/auth/manager.py:515 #, python-format -msgid "Snapshotting VM %s with label '%s'..." +msgid "Created project %(name)s with manager %(manager_user)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:229 +#: ../nova/auth/manager.py:533 #, python-format -msgid "Created snapshot %s from VM %s." +msgid "modifying project %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:243 +#: ../nova/auth/manager.py:545 #, python-format -msgid "Asking xapi to upload %s as '%s'" +msgid "Adding user %(uid)s to project %(pid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:261 +#: ../nova/auth/manager.py:566 #, python-format -msgid "Asking xapi to fetch %s as %s" +msgid "Remove user %(uid)s from project %(pid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:279 +#: ../nova/auth/manager.py:592 #, python-format -msgid "Looking up vdi %s for PV kernel" -msgstr "" +msgid "Deleting project %s" +msgstr "删除项目 %s" -#: nova/virt/xenapi/vm_utils.py:290 +#: ../nova/auth/manager.py:650 #, python-format -msgid "PV Kernel in VDI:%d" +msgid "Created user %(rvname)s (admin: %(rvadmin)r)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:318 +#: ../nova/auth/manager.py:659 #, python-format -msgid "VDI %s is still available" -msgstr "" +msgid "Deleting user %s" +msgstr "删除用户 %s" -#: nova/virt/xenapi/vm_utils.py:331 +#: ../nova/auth/manager.py:669 #, python-format -msgid "(VM_UTILS) xenserver vm state -> |%s|" +msgid "Access Key change for user %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:333 +#: ../nova/auth/manager.py:671 #, python-format -msgid "(VM_UTILS) xenapi power_state -> |%s|" +msgid "Secret Key change for user %s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:390 +#: ../nova/auth/manager.py:673 #, python-format -msgid "VHD %s has parent %s" +msgid "Admin status set to %(admin)r for user %(uid)s" msgstr "" -#: nova/virt/xenapi/vm_utils.py:407 +#: ../nova/auth/manager.py:722 #, python-format -msgid "Re-scanning SR %s" -msgstr "" +msgid "No vpn data for project %s" +msgstr "没有 %s 项目的vpn数据" -#: nova/virt/xenapi/vm_utils.py:431 +#: ../nova/service.py:161 #, python-format -msgid "Parent %s doesn't match original parent %s, waiting for coalesce..." +msgid "Starting %(topic)s node (version %(vcs_string)s)" msgstr "" -#: nova/virt/xenapi/vm_utils.py:448 -#, python-format -msgid "No VDIs found for VM %s" -msgstr "" +#: ../nova/service.py:174 +msgid "Service killed that has no database entry" +msgstr "因无数据库记录,服务已被中止" -#: nova/virt/xenapi/vm_utils.py:452 -#, python-format -msgid "Unexpected number of VDIs (%s) found for VM %s" +#: ../nova/service.py:195 +msgid "The service database object disappeared, Recreating it." msgstr "" -#: nova/virt/xenapi/vmops.py:62 -#, python-format -msgid "Attempted to create non-unique name %s" -msgstr "" +#: ../nova/service.py:207 +msgid "Recovered model server connection!" +msgstr "与模型服务器(model server)的连接已恢复!" -#: nova/virt/xenapi/vmops.py:99 -#, python-format -msgid "Starting VM %s..." -msgstr "" +#: ../nova/service.py:213 +msgid "model server went away" +msgstr "失去与模型服务器的连接" -#: nova/virt/xenapi/vmops.py:101 +#: ../nova/auth/ldapdriver.py:174 #, python-format -msgid "Spawning VM %s created %s." -msgstr "" +msgid "LDAP user %s already exists" +msgstr "LDAP 用户 %s 已存在" -#: nova/virt/xenapi/vmops.py:112 +#: ../nova/auth/ldapdriver.py:205 #, python-format -msgid "Instance %s: booted" +msgid "LDAP object for %s doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:137 +#: ../nova/auth/ldapdriver.py:348 #, python-format -msgid "Instance not present %s" -msgstr "" +msgid "User %s doesn't exist" +msgstr "用户 %s 不存在" -#: nova/virt/xenapi/vmops.py:166 +#: ../nova/auth/ldapdriver.py:472 #, python-format -msgid "Starting snapshot for VM %s" +msgid "Group can't be created because group %s already exists" msgstr "" -#: nova/virt/xenapi/vmops.py:174 +#: ../nova/auth/ldapdriver.py:478 #, python-format -msgid "Unable to Snapshot %s: %s" +msgid "Group can't be created because user %s doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:184 +#: ../nova/auth/ldapdriver.py:495 #, python-format -msgid "Finished snapshot and upload for VM %s" +msgid "User %s can't be searched in group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:252 +#: ../nova/auth/ldapdriver.py:507 #, python-format -msgid "suspend: instance not present %s" +msgid "User %s can't be added to the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:262 +#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521 #, python-format -msgid "resume: instance not present %s" +msgid "The group at dn %s doesn't exist" msgstr "" -#: nova/virt/xenapi/vmops.py:271 +#: ../nova/auth/ldapdriver.py:513 #, python-format -msgid "Instance not found %s" +msgid "User %(uid)s is already a member of the group %(group_dn)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:57 +#: ../nova/auth/ldapdriver.py:524 #, python-format -msgid "Introducing %s..." +msgid "" +"User %s can't be removed from the group because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:74 +#: ../nova/auth/ldapdriver.py:528 #, python-format -msgid "Introduced %s as %s." -msgstr "" - -#: nova/virt/xenapi/volume_utils.py:78 -msgid "Unable to create Storage Repository" +msgid "User %s is not a member of the group" msgstr "" -#: nova/virt/xenapi/volume_utils.py:90 +#: ../nova/auth/ldapdriver.py:542 #, python-format -msgid "Unable to find SR from VBD %s" +msgid "" +"Attempted to remove the last member of a group. Deleting the group at %s " +"instead." msgstr "" -#: nova/virt/xenapi/volume_utils.py:96 +#: ../nova/auth/ldapdriver.py:549 #, python-format -msgid "Forgetting SR %s ... " +msgid "User %s can't be removed from all because the user doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:101 +#: ../nova/auth/ldapdriver.py:564 #, python-format -msgid "Ignoring exception %s when getting PBDs for %s" +msgid "Group at dn %s doesn't exist" msgstr "" -#: nova/virt/xenapi/volume_utils.py:107 +#: ../nova/virt/xenapi/network_utils.py:40 #, python-format -msgid "Ignoring exception %s when unplugging PBD %s" +msgid "Found non-unique network for bridge %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:111 +#: ../nova/virt/xenapi/network_utils.py:43 #, python-format -msgid "Forgetting SR %s done." +msgid "Found no network for bridge %s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:113 +#: ../nova/api/ec2/admin.py:97 #, python-format -msgid "Ignoring exception %s when forgetting SR %s" -msgstr "" +msgid "Creating new user: %s" +msgstr "创建新用户: %s" -#: nova/virt/xenapi/volume_utils.py:123 +#: ../nova/api/ec2/admin.py:105 #, python-format -msgid "Unable to introduce VDI on SR %s" -msgstr "" +msgid "Deleting user: %s" +msgstr "删除用户: %s" -#: nova/virt/xenapi/volume_utils.py:128 +#: ../nova/api/ec2/admin.py:127 #, python-format -msgid "Unable to get record of VDI %s on" +msgid "Adding role %(role)s to user %(user)s for project %(project)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:146 +#: ../nova/api/ec2/admin.py:131 #, python-format -msgid "Unable to introduce VDI for SR %s" +msgid "Adding sitewide role %(role)s to user %(user)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:175 +#: ../nova/api/ec2/admin.py:137 #, python-format -msgid "Unable to obtain target information %s, %s" +msgid "Removing role %(role)s from user %(user)s for project %(project)s" msgstr "" -#: nova/virt/xenapi/volume_utils.py:197 +#: ../nova/api/ec2/admin.py:141 #, python-format -msgid "Mountpoint cannot be translated: %s" +msgid "Removing sitewide role %(role)s from user %(user)s" msgstr "" -#: nova/virt/xenapi/volumeops.py:51 -#, python-format -msgid "Attach_volume: %s, %s, %s" -msgstr "" +#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223 +msgid "operation must be add or remove" +msgstr "操作必须为添加或删除" -#: nova/virt/xenapi/volumeops.py:69 +#: ../nova/api/ec2/admin.py:159 #, python-format -msgid "Unable to create VDI on SR %s for instance %s" +msgid "Getting x509 for user: %(name)s on project: %(project)s" msgstr "" -#: nova/virt/xenapi/volumeops.py:81 +#: ../nova/api/ec2/admin.py:177 #, python-format -msgid "Unable to use SR %s for instance %s" +msgid "Create project %(name)s managed by %(manager_user)s" msgstr "" -#: nova/virt/xenapi/volumeops.py:93 +#: ../nova/api/ec2/admin.py:190 #, python-format -msgid "Unable to attach volume to instance %s" +msgid "Modify project: %(name)s managed by %(manager_user)s" msgstr "" -#: nova/virt/xenapi/volumeops.py:95 +#: ../nova/api/ec2/admin.py:200 #, python-format -msgid "Mountpoint %s attached to instance %s" -msgstr "" +msgid "Delete project: %s" +msgstr "删除工程 %s" -#: nova/virt/xenapi/volumeops.py:106 +#: ../nova/api/ec2/admin.py:214 #, python-format -msgid "Detach_volume: %s, %s" -msgstr "" +msgid "Adding user %(user)s to project %(project)s" +msgstr "添加用户 %(user)s 到项目 %(project)s 中" -#: nova/virt/xenapi/volumeops.py:113 +#: ../nova/api/ec2/admin.py:218 #, python-format -msgid "Unable to locate volume %s" -msgstr "" +msgid "Removing user %(user)s from project %(project)s" +msgstr "从项目 %(project)s 中移除用户 %(user)s" -#: nova/virt/xenapi/volumeops.py:121 #, python-format -msgid "Unable to detach volume %s" -msgstr "" +#~ 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/virt/xenapi/volumeops.py:128 #, python-format -msgid "Mountpoint %s detached from instance %s" -msgstr "" +#~ msgid "Binding %s to %s with key %s" +#~ msgstr "将%s绑定到%s(以%s键值)" -#: nova/volume/api.py:44 #, python-format -msgid "Quota exceeeded for %s, tried to create %sG volume" -msgstr "" +#~ msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds." +#~ msgstr "位于%s:%d的AMQP服务器不可用。%d秒后重试。" -#: 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 "" +#~ msgid "Getting from %s: %s" +#~ msgstr "从%s获得如下内容:%s" -#: nova/volume/api.py:97 -msgid "Volume is already attached" -msgstr "" +#, python-format +#~ msgid "Starting %s node" +#~ msgstr "启动%s节点" -#: nova/volume/api.py:103 -msgid "Volume is already detached" -msgstr "" +#, python-format +#~ msgid "Data store %s is unreachable. Trying again in %d seconds." +#~ msgstr "数据储存服务%s不可用。%d秒之后继续尝试。" -#: nova/volume/driver.py:76 #, python-format -msgid "Recovering from a failed execute. Try number %s" -msgstr "" +#~ msgid "(%s) publish (key: %s) %s" +#~ msgstr "(%s)发布(键值:%s)%s" -#: nova/volume/driver.py:85 #, python-format -msgid "volume group %s doesn't exist" -msgstr "" +#~ msgid "Couldn't get IP, using 127.0.0.1 %s" +#~ msgstr "不能获取IP,将使用 127.0.0.1 %s" -#: nova/volume/driver.py:210 #, python-format -msgid "FAKE AOE: %s" -msgstr "" +#~ msgid "" +#~ "Access key %s has had %d failed authentications and will be locked out for " +#~ "%d minutes." +#~ msgstr "访问键 %s时,存在%d个失败的认证,将于%d分钟后解锁" -#: nova/volume/driver.py:315 #, python-format -msgid "FAKE ISCSI: %s" -msgstr "" +#~ msgid "Authenticated Request For %s:%s)" +#~ msgstr "为%s:%s申请认证" -#: nova/volume/manager.py:85 #, python-format -msgid "Re-exporting %s volumes" -msgstr "" +#~ msgid "arg: %s\t\tval: %s" +#~ msgstr "键为: %s\t\t值为: %s" -#: nova/volume/manager.py:93 #, python-format -msgid "volume %s: creating" -msgstr "" +#~ msgid "Getting x509 for user: %s on project: %s" +#~ msgstr "为用户 %s从工程%s中获取 x509" -#: nova/volume/manager.py:102 #, python-format -msgid "volume %s: creating lv of size %sG" -msgstr "" +#~ msgid "Create project %s managed by %s" +#~ msgstr "创建工程%s,此工程由%s管理" -#: nova/volume/manager.py:106 #, python-format -msgid "volume %s: creating export" -msgstr "" +#~ msgid "Unsupported API request: controller = %s,action = %s" +#~ msgstr "不支持的API请求: 控制器 = %s,执行 = %s" -#: nova/volume/manager.py:113 #, python-format -msgid "volume %s: created successfully" -msgstr "" +#~ msgid "Adding sitewide role %s to user %s" +#~ msgstr "增加站点范围的 %s角色给用户 %s" -#: nova/volume/manager.py:121 -msgid "Volume is still attached" -msgstr "" +#, python-format +#~ msgid "Adding user %s to project %s" +#~ msgstr "增加用户%s到%s工程" -#: nova/volume/manager.py:123 -msgid "Volume is not local to this node" -msgstr "" +#, python-format +#~ msgid "Unauthorized request for controller=%s and action=%s" +#~ msgstr "对控制器=%s及动作=%s未经授权" -#: nova/volume/manager.py:124 #, python-format -msgid "volume %s: removing export" -msgstr "" +#~ msgid "Removing user %s from project %s" +#~ msgstr "正将用户%s从工程%s中移除" -#: nova/volume/manager.py:126 #, python-format -msgid "volume %s: deleting" -msgstr "" +#~ msgid "Adding role %s to user %s for project %s" +#~ msgstr "正将%s角色赋予用户%s(在工程%s中)" -#: nova/volume/manager.py:129 #, python-format -msgid "volume %s: deleted successfully" -msgstr "" +#~ msgid "Removing role %s from user %s for project %s" +#~ msgstr "正将角色%s从用户%s在工程%s中移除" -- cgit From d7f0c23b0a398b35442be7e053539d7d7e230122 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Fri, 8 Apr 2011 08:50:45 -0300 Subject: added Zones doc --- doc/source/devref/zone.rst | 128 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 doc/source/devref/zone.rst diff --git a/doc/source/devref/zone.rst b/doc/source/devref/zone.rst new file mode 100644 index 000000000..c3d04a405 --- /dev/null +++ b/doc/source/devref/zone.rst @@ -0,0 +1,128 @@ +.. + Copyright 2010-2011 OpenStack LLC + All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); you may + not use this file except in compliance with the License. You may obtain + a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + License for the specific language governing permissions and limitations + under the License. + +Zones +===== + +A Nova deployment is called a Zone. At the very least a Zone requires an API node, a Scheduler node, a database and RabbitMQ. Pushed further a Zone may contain many API nodes, many Scheduler, Volume, Network and Compute nodes as well as a cluster of databases and RabbitMQ servers. A Zone allows you partition your deployments into logical groups for load balancing and instance distribution. + +The idea behind Zones is, if a particular deployment is not capable of servicing a particular request, the request may be forwarded to (child) Zones for possible processing. Zones may be nested in a tree fashion. + +Zones only know about their immediate children, they do not know about their parent Zones and may in fact have more than one parent. Likewise, a Zone's children may themselves have child Zones. + +Zones share nothing. They communicate via the public OpenStack API only. No database, queue, user or project definition is shared between Zones. + + +Capabilities +------------ +Routing between Zones is based on the Capabilities of that Zone. Capabilities are nothing more than key/value pairs. When expressed as a string they take the form: + +:: + + key=value;value;value, key=value;value;value + +Zones have Capabilities which are general to the Zone and are set via `--zone-capabilities` flag. Zones also have dynamic per-service Capabilities. Services derived from `nova.manager.SchedulerDependentManager` (such as Compute, Volume and Network) can set these capabilities by calling the `update_service_capabilities()` method on their `Manager` base class. These capabilities will be periodically sent to the Scheduler service automatically. The rate at which these updates are sent is controlled by the `--periodic_interval` flag. + +Flow within a Zone +------------------ +The brunt of the work within a Zone is done in the Scheduler Service. The Scheduler is responsible for: +- collecting capability messages from the Compute, Volume and Network nodes, +- polling the child Zones for their status and +- providing data to the Distributed Scheduler for performing load balancing calculations + +Inter-service communication within a Zone is done with RabbitMQ. Each class of Service (Compute, Volume and Network) has both a named message exchange (particular to that host) and a general message exchange (particular to that class of service). Messages sent to these exchanges are picked off in round-robin fashion. Zones introduce a new fan-out exchange per service. Messages sent to the fan-out exchange are picked up by all services of a particular class. This fan-out exchange is used by the Scheduler services to receive capability messages from the Compute, Volume and Network nodes. + +These capability messages are received by the Scheduler services and stored in the `ZoneManager` object. The SchedulerManager object has a reference to the `ZoneManager` it can use for load balancing. + +The `ZoneManager` also polls the child Zones periodically to gather their capabilities to aid in decision making. This is done via the OpenStack API `/v1.0/zones/info` REST call. This also captures the name of each child Zone. The Zone name is set via the `--zone-name` flag (and defaults to "nova"). + +Zone administrative functions +----------------------------- +Zone administrative operations are usually done using python-novaclient_ + +.. _python-novaclient: https://github.com/rackspace/python-novaclient + +In order to use the Zone operations, be sure to enable administrator operations in OpenStack API by setting the `--allow_admin_api=true` flag. + + +Find out about this Zone +------------------------ +In any Zone you can find the Zone's name and capabilities with the ``nova zone-info`` command. + +:: + + alice@novadev:~$ nova zone-info + +-----------------+---------------+ + | Property | Value | + +-----------------+---------------+ + | compute_cpu | 0.7,0.7 | + | compute_disk | 123000,123000 | + | compute_network | 800,800 | + | hypervisor | xenserver | + | name | nova | + | network_cpu | 0.7,0.7 | + | network_disk | 123000,123000 | + | network_network | 800,800 | + | os | linux | + +-----------------+---------------+ + +This equates to a GET operation on `.../zones/info`. If you have no child Zones defined you'll usually only get back the default `name`, `hypervisor` and `os` capabilities. Otherwise you'll get back a tuple of min, max values for each capabilities of all the hosts of all the services running in the child zone. These take the `_ = ,` format. + +Adding a child Zone +------------------- +From a parent zone you can add a child zone with the following command: + +:: + + nova zone-add + +You can get the `child zone api url`, `nova api key` and `username` from the `novarc` file in the child zone. For example: + +:: + + export NOVA_API_KEY="3bd1af06-6435-4e23-a827-413b2eb86934" + export NOVA_USERNAME="alice" + export NOVA_URL="http://192.168.2.120:8774/v1.0/" + + +This equates to a POST operation to `.../zones/` to add a new zone. No connection attempt to the child zone is done when this command. It only puts an entry in the db at this point. After about 30 seconds the `ZoneManager` in the Scheduler services will attempt to talk to the child zone and get its information. + +Getting a list of child Zones +----------------------------- + +:: + + nova zone-list + + alice@novadev:~$ nova zone-list + +----+-------+-----------+--------------------------------------------+---------------------------------+ + | ID | Name | Is Active | Capabilities | API URL | + +----+-------+-----------+--------------------------------------------+---------------------------------+ + | 2 | zone1 | True | hypervisor=xenserver;kvm, os=linux;windows | http://192.168.2.108:8774/v1.0/ | + | 3 | zone2 | True | hypervisor=xenserver;kvm, os=linux;windows | http://192.168.2.115:8774/v1.0/ | + +----+-------+-----------+--------------------------------------------+---------------------------------+ + +This equates to a GET operation to `.../zones`. + +Removing a child Zone +--------------------- +:: + + nova zone-delete + +This equates to a DELETE call to `.../zones/N`. The Zone with ID=N will be removed. + + -- cgit From 845d32660eb18b8a402519d382392232f79f2990 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Fri, 8 Apr 2011 10:04:38 -0300 Subject: merge prop tweaks --- doc/source/devref/zone.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/source/devref/zone.rst b/doc/source/devref/zone.rst index c3d04a405..acc7398bf 100644 --- a/doc/source/devref/zone.rst +++ b/doc/source/devref/zone.rst @@ -28,7 +28,7 @@ Zones share nothing. They communicate via the public OpenStack API only. No data Capabilities ------------ -Routing between Zones is based on the Capabilities of that Zone. Capabilities are nothing more than key/value pairs. When expressed as a string they take the form: +Routing between Zones is based on the Capabilities of that Zone. Capabilities are nothing more than key/value pairs. Values are multi-value, with each value separated with a semicolon (`;`). When expressed as a string they take the form: :: @@ -123,6 +123,4 @@ Removing a child Zone nova zone-delete -This equates to a DELETE call to `.../zones/N`. The Zone with ID=N will be removed. - - +This equates to a DELETE call to `.../zones/N`. The Zone with ID=N will be removed. This will only remove the zone entry from the current (parent) Zone, no child Zones are affected. -- cgit From 0d4fe0ddf20b36042cb73bdd8f1f40fa9832bd28 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Fri, 8 Apr 2011 09:50:16 -0400 Subject: bzr ignore the CA dir. --- .bzrignore | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.bzrignore b/.bzrignore index b751ad825..14d8028f7 100644 --- a/.bzrignore +++ b/.bzrignore @@ -5,13 +5,7 @@ _trial_temp keys networks nova.sqlite -CA/cacert.pem -CA/crl.pem -CA/index.txt* -CA/openssl.cnf -CA/serial* -CA/newcerts/*.pem -CA/private/cakey.pem +CA nova/vcsversion.py *.DS_Store .project -- cgit From decdaa30acb15e088eb6a0ca3ebc8ea6f377cbfe Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Fri, 8 Apr 2011 12:22:09 -0400 Subject: Set default stateOrProvice to 'supplied' in openssl.cnf.tmpl. This resolves a stateOrProvince printable string UTF8 mismatch on RHEL 6 and Fedora 14 (using openssl-1.0.0-4.el6.x86_64 or openssl-1.0.0d-1.fc14.x86_64). Fixes x509 certificate generation on Fedora 14 and Redhat 6. --- nova/CA/openssl.cnf.tmpl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nova/CA/openssl.cnf.tmpl b/nova/CA/openssl.cnf.tmpl index dd81f1c2b..b80fadf40 100644 --- a/nova/CA/openssl.cnf.tmpl +++ b/nova/CA/openssl.cnf.tmpl @@ -41,9 +41,13 @@ nameopt = default_ca certopt = default_ca policy = policy_match +# NOTE(dprince): stateOrProvinceName must be 'supplied' or 'optional' to +# work around a stateOrProvince printable string UTF8 mismatch on +# RHEL 6 and Fedora 14 (using openssl-1.0.0-4.el6.x86_64 or +# openssl-1.0.0d-1.fc14.x86_64) [ policy_match ] countryName = match -stateOrProvinceName = match +stateOrProvinceName = supplied organizationName = optional organizationalUnitName = optional commonName = supplied -- cgit From 9da9d9c8d5f763ec18c1286bf10f33ae67c84ced Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Fri, 8 Apr 2011 13:45:19 -0300 Subject: merge prop tweaks 2 --- doc/source/devref/zone.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/source/devref/zone.rst b/doc/source/devref/zone.rst index acc7398bf..234a96916 100644 --- a/doc/source/devref/zone.rst +++ b/doc/source/devref/zone.rst @@ -57,6 +57,7 @@ Zone administrative operations are usually done using python-novaclient_ In order to use the Zone operations, be sure to enable administrator operations in OpenStack API by setting the `--allow_admin_api=true` flag. +Finally you need to enable Zone Forwarding. This will be used by the Distributed Scheduler initiative currently underway. Set `--enable_zone_routing=true` to enable this feature. Find out about this Zone ------------------------ @@ -83,7 +84,7 @@ This equates to a GET operation on `.../zones/info`. If you have no child Zones Adding a child Zone ------------------- -From a parent zone you can add a child zone with the following command: +Any Zone can be a parent Zone. Children are associated to a Zone. The Zone where this command originates from is known as the Parent Zone. Routing is only ever conducted from a Zone to its children, never the other direction. From a parent zone you can add a child zone with the following command: :: @@ -123,4 +124,4 @@ Removing a child Zone nova zone-delete -This equates to a DELETE call to `.../zones/N`. The Zone with ID=N will be removed. This will only remove the zone entry from the current (parent) Zone, no child Zones are affected. +This equates to a DELETE call to `.../zones/N`. The Zone with ID=N will be removed. This will only remove the zone entry from the current (parent) Zone, no child Zones are affected. Removing a Child Zone doesn't affect any other part of the hierarchy. -- cgit From 0cf2a52218fbb801a35e5dd73e146c6c37e218e2 Mon Sep 17 00:00:00 2001 From: Kei Masumoto Date: Sat, 9 Apr 2011 02:39:18 +0900 Subject: fixed LOG level and log message phrase --- nova/compute/manager.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 847c3655a..c7d86e27b 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1094,9 +1094,8 @@ class ComputeManager(manager.SchedulerDependentManager): # A situation which db record exists, but no instance" # sometimes occurs while live-migration at src compute, # this case should be ignored. - LOG.info(_("the instance '%(name)s' is not found in hypervisor" - ", while db record is found. But not synchronize " - "since it is migrating.") % locals()) + LOG.debug(_("Ignoring %(name)s, as it's currently being " + "migrated.") % locals()) continue if vm_state != db_state: -- cgit From 5deb4796bc26d98eeea94065c5098f7ce30ac2af Mon Sep 17 00:00:00 2001 From: Johannes Erdfelt Date: Fri, 8 Apr 2011 11:21:36 -0700 Subject: Short circuit non-existant device during unit tests. It won't ever be created because of the stubs used during the unit tests --- nova/virt/xenapi/vm_utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 73a1e2a3a..d2045a557 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -936,7 +936,11 @@ def with_vdi_attached_here(session, vdi_ref, read_only, f): if dev != orig_dev: LOG.debug(_('VBD %(vbd_ref)s plugged into wrong dev, ' 'remapping to %(dev)s') % locals()) - _wait_for_device(dev) + if dev != 'autodetect': + # NOTE(johannes): Unit tests will end up with a device called + # 'autodetect' which obviously won't exist. It's not ideal, + # but the alternatives were much messier + _wait_for_device(dev) return f(dev) finally: LOG.debug(_('Destroying VBD for VDI %s ... '), vdi_ref) -- cgit From dd212c8d1c2155582e819d00055c297e00291bd0 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Fri, 8 Apr 2011 15:45:42 -0300 Subject: missing 'to' --- doc/source/devref/zone.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/devref/zone.rst b/doc/source/devref/zone.rst index 234a96916..3dd9d37d3 100644 --- a/doc/source/devref/zone.rst +++ b/doc/source/devref/zone.rst @@ -17,7 +17,7 @@ Zones ===== -A Nova deployment is called a Zone. At the very least a Zone requires an API node, a Scheduler node, a database and RabbitMQ. Pushed further a Zone may contain many API nodes, many Scheduler, Volume, Network and Compute nodes as well as a cluster of databases and RabbitMQ servers. A Zone allows you partition your deployments into logical groups for load balancing and instance distribution. +A Nova deployment is called a Zone. At the very least a Zone requires an API node, a Scheduler node, a database and RabbitMQ. Pushed further a Zone may contain many API nodes, many Scheduler, Volume, Network and Compute nodes as well as a cluster of databases and RabbitMQ servers. A Zone allows you to partition your deployments into logical groups for load balancing and instance distribution. The idea behind Zones is, if a particular deployment is not capable of servicing a particular request, the request may be forwarded to (child) Zones for possible processing. Zones may be nested in a tree fashion. -- cgit From 5ea0991db9526969f100f3361661731aaf4d24d5 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Fri, 8 Apr 2011 15:22:15 -0400 Subject: Fixes bug which hangs nova-compute when terminating an instance when using libvirt backend. --- nova/virt/libvirt_conn.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index b949e6c92..51a0a3380 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -325,12 +325,13 @@ class LibvirtConnection(driver.ComputeDriver): state = self.get_info(instance['name'])['state'] db.instance_set_state(context.get_admin_context(), instance['id'], state) - if state == power_state.SHUTDOWN: + if state == power_state.SHUTOFF: break - except Exception: + except Exception as ex: + LOG.debug(ex) db.instance_set_state(context.get_admin_context(), instance['id'], - power_state.SHUTDOWN) + power_state.SHUTOFF) break self.firewall_driver.unfilter_instance(instance) -- cgit From a1c40feb0cd592829b63df1cf19109bc322f81a7 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Fri, 8 Apr 2011 15:54:17 -0400 Subject: Added error message to exception logging. --- nova/virt/libvirt_conn.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 51a0a3380..bfa9ff688 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -328,7 +328,9 @@ class LibvirtConnection(driver.ComputeDriver): if state == power_state.SHUTOFF: break except Exception as ex: - LOG.debug(ex) + msg = _("Error encountered when destroying instance '%(id)s': " + "%(ex)s") % locals().update({"id": instance["id"]}) + LOG.debug(msg) db.instance_set_state(context.get_admin_context(), instance['id'], power_state.SHUTOFF) -- cgit From 5632baa79da2164457f75a240c5c497027c49fca Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Fri, 8 Apr 2011 14:36:27 -0700 Subject: pep8 --- bin/nova-manage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nova-manage b/bin/nova-manage index ab35e2c74..adc631318 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -572,7 +572,7 @@ class VmCommands(object): def list(self, host=None): """Show a list of all instances - + :param host: show all instance on specified host. :param instance: show specificed instance. """ -- cgit From 2800f931e134e7d6b316bb4d7f7118162c301ca9 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Fri, 8 Apr 2011 14:53:54 -0700 Subject: zero out volumes on delete using dd --- nova/volume/driver.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nova/volume/driver.py b/nova/volume/driver.py index 850893914..906a9654b 100644 --- a/nova/volume/driver.py +++ b/nova/volume/driver.py @@ -112,6 +112,11 @@ class VolumeDriver(object): # If the volume isn't present, then don't attempt to delete return True + # zero out old volumes to prevent data leaking between users + # TODO(ja): reclaiming space should be done lazy and low priority + self._try_execute('sudo', 'dd', 'if=/dev/zero', + 'of=%s' % self.local_path(volume), + 'bs=1M') self._try_execute('sudo', 'lvremove', '-f', "%s/%s" % (FLAGS.volume_group, volume['name'])) -- cgit From df4c269a338a9b983488ce4d5b86c829a92d471b Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Fri, 8 Apr 2011 15:17:52 -0700 Subject: dd needs a count to succeed, and remove unused/non-working special case for size 0 --- nova/volume/driver.py | 11 +++-------- nova/volume/san.py | 10 ++-------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/nova/volume/driver.py b/nova/volume/driver.py index 906a9654b..43792b791 100644 --- a/nova/volume/driver.py +++ b/nova/volume/driver.py @@ -93,10 +93,7 @@ class VolumeDriver(object): def create_volume(self, volume): """Creates a logical volume. Can optionally return a Dictionary of changes to the volume object to be persisted.""" - if int(volume['size']) == 0: - sizestr = '100M' - else: - sizestr = '%sG' % volume['size'] + sizestr = '%sG' % volume['size'] self._try_execute('sudo', 'lvcreate', '-L', sizestr, '-n', volume['name'], FLAGS.volume_group) @@ -116,6 +113,7 @@ class VolumeDriver(object): # TODO(ja): reclaiming space should be done lazy and low priority self._try_execute('sudo', 'dd', 'if=/dev/zero', 'of=%s' % self.local_path(volume), + 'count=%d' % volume['size'] * 1024, 'bs=1M') self._try_execute('sudo', 'lvremove', '-f', "%s/%s" % (FLAGS.volume_group, @@ -601,10 +599,7 @@ class SheepdogDriver(VolumeDriver): def create_volume(self, volume): """Creates a sheepdog volume""" - if int(volume['size']) == 0: - sizestr = '100M' - else: - sizestr = '%sG' % volume['size'] + sizestr = '%sG' % volume['size'] self._try_execute('qemu-img', 'create', "sheepdog:%s" % volume['name'], sizestr) diff --git a/nova/volume/san.py b/nova/volume/san.py index 9532c8116..dd332de1a 100644 --- a/nova/volume/san.py +++ b/nova/volume/san.py @@ -219,10 +219,7 @@ class SolarisISCSIDriver(SanISCSIDriver): def create_volume(self, volume): """Creates a volume.""" - if int(volume['size']) == 0: - sizestr = '100M' - else: - sizestr = '%sG' % volume['size'] + sizestr = '%sG' % volume['size'] zfs_poolname = self._build_zfs_poolname(volume) @@ -489,10 +486,7 @@ class HpSanISCSIDriver(SanISCSIDriver): #TODO(justinsb): Should we default to inheriting thinProvision? cliq_args['thinProvision'] = '1' if FLAGS.san_thin_provision else '0' cliq_args['volumeName'] = volume['name'] - if int(volume['size']) == 0: - cliq_args['size'] = '100MB' - else: - cliq_args['size'] = '%sGB' % volume['size'] + cliq_args['size'] = '%sGB' % volume['size'] self._cliq_run_xml("createVolume", cliq_args) -- cgit From 7f04c6f5165ea96f22ec17bdbe7a3f2a7595edb1 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Fri, 8 Apr 2011 15:23:17 -0700 Subject: typo - need to get nova-volumes working on this machine :-/ --- nova/volume/driver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/volume/driver.py b/nova/volume/driver.py index 43792b791..f9c268191 100644 --- a/nova/volume/driver.py +++ b/nova/volume/driver.py @@ -113,7 +113,7 @@ class VolumeDriver(object): # TODO(ja): reclaiming space should be done lazy and low priority self._try_execute('sudo', 'dd', 'if=/dev/zero', 'of=%s' % self.local_path(volume), - 'count=%d' % volume['size'] * 1024, + 'count=%d' % (volume['size'] * 1024), 'bs=1M') self._try_execute('sudo', 'lvremove', '-f', "%s/%s" % (FLAGS.volume_group, -- cgit From 5aab609b24140622b87db970243641ec382b214e Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Fri, 8 Apr 2011 15:24:09 -0700 Subject: pylintage --- nova/volume/driver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/volume/driver.py b/nova/volume/driver.py index f9c268191..0c4086039 100644 --- a/nova/volume/driver.py +++ b/nova/volume/driver.py @@ -111,7 +111,7 @@ class VolumeDriver(object): # zero out old volumes to prevent data leaking between users # TODO(ja): reclaiming space should be done lazy and low priority - self._try_execute('sudo', 'dd', 'if=/dev/zero', + self._try_execute('sudo', 'dd', 'if=/dev/zero', 'of=%s' % self.local_path(volume), 'count=%d' % (volume['size'] * 1024), 'bs=1M') -- cgit From 79ebe165f255037b0d5eaad7afe81b51cf85ed63 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Sat, 9 Apr 2011 11:08:47 -0400 Subject: Fixed log message gaffe. --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index bfa9ff688..9c665ab15 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -329,7 +329,7 @@ class LibvirtConnection(driver.ComputeDriver): break except Exception as ex: msg = _("Error encountered when destroying instance '%(id)s': " - "%(ex)s") % locals().update({"id": instance["id"]}) + "%(ex)s") % {"id": instance["id"], "ex": ex} LOG.debug(msg) db.instance_set_state(context.get_admin_context(), instance['id'], -- cgit From a572b49e376cd6da4265c2807eaed8f0a2daf954 Mon Sep 17 00:00:00 2001 From: Justin SB Date: Sat, 9 Apr 2011 11:57:14 -0700 Subject: Remove the XML definition when we destroy a machine --- nova/virt/libvirt_conn.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index b949e6c92..1ad6f8b32 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -309,10 +309,18 @@ class LibvirtConnection(driver.ComputeDriver): return infos def destroy(self, instance, cleanup=True): + name = instance['name'] try: - virt_dom = self._conn.lookupByName(instance['name']) + virt_dom = self._conn.lookupByName(name) virt_dom.destroy() - except Exception as _err: + # NOTE(justinsb): We remove the domain definition. We probably + # would do better to keep it if cleanup=False (e.g. volumes?) + # (e.g. #2 - not losing machines on failure) + virt_dom.undefine() + except Exception as e: + # TODO(justinsb): We really should check the error is 'not found' + LOG.warn(_("Ignoring error destroying domain %(name)s: %(e)s") % + locals()) pass # If the instance is already terminated, we're still happy -- cgit From be386ee614777212da2a14ebd8211f4b3d90ce66 Mon Sep 17 00:00:00 2001 From: Justin SB Date: Sat, 9 Apr 2011 12:33:24 -0700 Subject: Split logic on shutdown and undefine, so that even if the machine is already shutdown we will be able to proceed --- nova/virt/libvirt_conn.py | 53 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 1ad6f8b32..47eb17abb 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -309,20 +309,47 @@ class LibvirtConnection(driver.ComputeDriver): return infos def destroy(self, instance, cleanup=True): - name = instance['name'] + instance_name = instance['name'] + + # TODO(justinsb): Refactor all lookupByName calls for error-handling try: - virt_dom = self._conn.lookupByName(name) - virt_dom.destroy() - # NOTE(justinsb): We remove the domain definition. We probably - # would do better to keep it if cleanup=False (e.g. volumes?) - # (e.g. #2 - not losing machines on failure) - virt_dom.undefine() - except Exception as e: - # TODO(justinsb): We really should check the error is 'not found' - LOG.warn(_("Ignoring error destroying domain %(name)s: %(e)s") % - locals()) - pass - # If the instance is already terminated, we're still happy + virt_dom = self._conn.lookupByName(instance_name) + except libvirt.libvirtError as e: + errcode = e.get_error_code() + if errcode == libvirt.VIR_ERR_NO_DOMAIN: + virt_dom = None + else: + LOG.warning(_("Error from libvirt during lookup of " + "%(instance_name)s. Code=%(errcode)s " + "Error=%(e)s") % + locals()) + raise + + # If the instance is already terminated, we're still happy + # Otherwise, destroy it + if virt_dom is not None: + try: + virt_dom.destroy() + except libvirt.libvirtError as e: + errcode = e.get_error_code() + LOG.warning(_("Error from libvirt during destroy of " + "%(instance_name)s. Code=%(errcode)s " + "Error=%(e)s") % + locals()) + raise + + try: + # NOTE(justinsb): We remove the domain definition. We probably + # would do better to keep it if cleanup=False (e.g. volumes?) + # (e.g. #2 - not losing machines on failure) + virt_dom.undefine() + except libvirt.libvirtError as e: + errcode = e.get_error_code() + LOG.warning(_("Error from libvirt during undefine of " + "%(instance_name)s. Code=%(errcode)s " + "Error=%(e)s") % + locals()) + raise # We'll save this for when we do shutdown, # instead of destroy - but destroy returns immediately -- cgit From c6923ec603288e1d46fdb80e874c8e71361442f5 Mon Sep 17 00:00:00 2001 From: Justin SB Date: Sat, 9 Apr 2011 12:41:30 -0700 Subject: Handle the case when the machine is already SHUTOFF --- nova/virt/libvirt_conn.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 47eb17abb..7771aad7a 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -331,12 +331,22 @@ class LibvirtConnection(driver.ComputeDriver): try: virt_dom.destroy() except libvirt.libvirtError as e: + is_okay = False errcode = e.get_error_code() - LOG.warning(_("Error from libvirt during destroy of " - "%(instance_name)s. Code=%(errcode)s " - "Error=%(e)s") % - locals()) - raise + if errcode == libvirt.VIR_ERR_OPERATION_INVALID: + # If the instance if already shut off, we get this: + # Code=55 Error=Requested operation is not valid: + # domain is not running + (state, _, _, _, _) = virt_dom.info() + if state == power_state.SHUTOFF: + is_okay = True + + if not is_okay: + LOG.warning(_("Error from libvirt during destroy of " + "%(instance_name)s. Code=%(errcode)s " + "Error=%(e)s") % + locals()) + raise try: # NOTE(justinsb): We remove the domain definition. We probably -- cgit From f59f8e8fcbde6f0d8d4c19b00bfc5f4141287772 Mon Sep 17 00:00:00 2001 From: Justin SB Date: Sat, 9 Apr 2011 12:57:32 -0700 Subject: Ooops - redefining the _ variable seems like a _really_ bad idea --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 7771aad7a..22b0e1103 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -337,7 +337,7 @@ class LibvirtConnection(driver.ComputeDriver): # If the instance if already shut off, we get this: # Code=55 Error=Requested operation is not valid: # domain is not running - (state, _, _, _, _) = virt_dom.info() + (state, _max_mem, _mem, _cpus, _t) = virt_dom.info() if state == power_state.SHUTOFF: is_okay = True -- cgit From 5752838917237e7b86a64117f46c71d1c2a356f3 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 11 Apr 2011 16:18:18 +0200 Subject: Replace instance ref from compute.api.get_all with one from instance_get. This should ensure it gets fully populated with all the relevant attributes. --- nova/api/ec2/cloud.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 651ec47f9..83c894bea 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -142,6 +142,11 @@ class CloudController(object): instance_ref = self.compute_api.get_all(ctxt, fixed_ip=address) if instance_ref is None: return None + + # This ensures that all attributes of the instance + # are populated. + instance_ref = db.instance_get(ctxt, instance_ref['id']) + mpi = self._get_mpi_data(ctxt, instance_ref['project_id']) if instance_ref['key_name']: keys = {'0': {'_name': instance_ref['key_name'], -- cgit From 21fd04c34487b97f7d1ed199773cf80e9ab60839 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 11 Apr 2011 15:56:36 +0000 Subject: fix reference to genvpn to point to the right shell script --- nova/crypto.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/crypto.py b/nova/crypto.py index 9b1897926..605be2a32 100644 --- a/nova/crypto.py +++ b/nova/crypto.py @@ -232,7 +232,7 @@ def generate_vpn_files(project_id): genvpn_sh_path = os.path.join(os.path.dirname(__file__), 'CA', - 'geninter.sh') + 'genvpn.sh') if os.path.exists(crt_fn): return _ensure_project_folder(project_id) -- cgit From 6ac2b25d77ea71be0f9232b5502a75f255a6b2ec Mon Sep 17 00:00:00 2001 From: termie Date: Mon, 11 Apr 2011 11:34:19 -0500 Subject: docstring cleanup, direct api, part of compute --- nova/api/__init__.py | 2 - nova/api/direct.py | 90 +++++++++++++++++++++++++++++++- nova/compute/api.py | 115 ++++++++++++++++++++++------------------- nova/compute/instance_types.py | 35 ++++++------- 4 files changed, 165 insertions(+), 77 deletions(-) diff --git a/nova/api/__init__.py b/nova/api/__init__.py index 0fedbbfad..747015af5 100644 --- a/nova/api/__init__.py +++ b/nova/api/__init__.py @@ -15,5 +15,3 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. - -"""No-op __init__ for directory full of api goodies.""" diff --git a/nova/api/direct.py b/nova/api/direct.py index f487df7c7..8ceae299c 100644 --- a/nova/api/direct.py +++ b/nova/api/direct.py @@ -44,14 +44,33 @@ from nova import utils from nova import wsgi +# Global storage for registering modules. ROUTES = {} def register_service(path, handle): + """Register a service handle at a given path. + + Services registered in this way will be made available to any instances of + nova.api.direct.Router. + + :param path: `routes` path, can be a basic string like "/path" + :param handle: an object whose methods will be made available via the api + + """ ROUTES[path] = handle class Router(wsgi.Router): + """A simple WSGI router configured via `register_service`. + + This is a quick way to attach multiple services to a given endpoint. + It will automatically load the routes registered in the `ROUTES` global. + + TODO(termie): provide a paste-deploy version of this. + + """ + def __init__(self, mapper=None): if mapper is None: mapper = routes.Mapper() @@ -66,6 +85,24 @@ class Router(wsgi.Router): class DelegatedAuthMiddleware(wsgi.Middleware): + """A simple and naive authentication middleware. + + Designed mostly to provide basic support for alternative authentication + schemes, this middleware only desires the identity of the user and will + generate the appropriate nova.context.RequestContext for the rest of the + application. This allows any middleware above it in the stack to + authenticate however it would like while only needing to conform to a + minimal interface. + + Expects two headers to determine identity: + - X-OpenStack-User + - X-OpenStack-Project + + This middleware is tied to identity management and will need to be kept + in sync with any changes to the way identity is dealt with internally. + + """ + def process_request(self, request): os_user = request.headers['X-OpenStack-User'] os_project = request.headers['X-OpenStack-Project'] @@ -74,6 +111,20 @@ class DelegatedAuthMiddleware(wsgi.Middleware): class JsonParamsMiddleware(wsgi.Middleware): + """Middleware to allow method arguments to be passed as serialized JSON. + + Accepting arguments as JSON is useful for accepting data that may be more + complex than simple primitives. + + In this case we accept it as urlencoded data under the key 'json' as in + json= but this could be extended to accept raw JSON + in the POST body. + + Filters out the parameters `self`, `context` and anything beginning with + an underscore. + + """ + def process_request(self, request): if 'json' not in request.params: return @@ -92,6 +143,13 @@ class JsonParamsMiddleware(wsgi.Middleware): class PostParamsMiddleware(wsgi.Middleware): + """Middleware to allow method arguments to be passed as POST parameters. + + Filters out the parameters `self`, `context` and anything beginning with + an underscore. + + """ + def process_request(self, request): params_parsed = request.params params = {} @@ -106,12 +164,21 @@ class PostParamsMiddleware(wsgi.Middleware): class Reflection(object): - """Reflection methods to list available methods.""" + """Reflection methods to list available methods. + + This is an object that expects to be registered via register_service. + These methods allow the endpoint to be self-describing. They introspect + the exposed methods and provide call signatures and documentation for + them allowing quick experimentation. + + """ + def __init__(self): self._methods = {} self._controllers = {} def _gather_methods(self): + """Introspect available methods and generate documentation for them.""" methods = {} controllers = {} for route, handler in ROUTES.iteritems(): @@ -185,6 +252,16 @@ class Reflection(object): class ServiceWrapper(wsgi.Controller): + """Wrapper to dynamically povide a WSGI controller for arbitrary objects. + + With lightweight introspection allows public methods on the object to + be accesed via simple WSGI routing and parameters and serializes the + return values. + + Automatically used be nova.api.direct.Router to wrap registered instances. + + """ + def __init__(self, service_handle): self.service_handle = service_handle @@ -260,7 +337,16 @@ class Limited(object): class Proxy(object): - """Pretend a Direct API endpoint is an object.""" + """Pretend a Direct API endpoint is an object. + + This is mostly useful in testing at the moment though it should be easily + extendable to provide a basic API library functionality. + + In testing we use this to stub out internal objects to verify that results + from the API are serializable. + + """ + def __init__(self, app, prefix=None): self.app = app self.prefix = prefix diff --git a/nova/compute/api.py b/nova/compute/api.py index 041e0e74a..e6146231c 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -16,9 +16,7 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Handles all requests relating to instances (guest vms). -""" +"""Handles all requests relating to instances (guest vms).""" import datetime import re @@ -86,10 +84,10 @@ class API(base.Base): {"method": "get_network_topic", "args": {'fake': 1}}) def _check_injected_file_quota(self, context, injected_files): - """ - Enforce quota limits on injected files + """Enforce quota limits on injected files. + + Raises a QuotaError if any limit is exceeded. - Raises a QuotaError if any limit is exceeded """ if injected_files is None: return @@ -111,8 +109,11 @@ class API(base.Base): key_name=None, key_data=None, security_group='default', availability_zone=None, user_data=None, metadata=[], injected_files=None): - """Create the number of instances requested if quota and - other arguments check out ok.""" + """Create the number and type of instances requested. + + Verifies that quota and other arguments are valid. + + """ if not instance_type: instance_type = instance_types.get_default_instance_type() @@ -262,8 +263,7 @@ class API(base.Base): return [dict(x.iteritems()) for x in instances] def has_finished_migration(self, context, instance_id): - """Retrieves whether or not a finished migration exists for - an instance""" + """Returns true if an instance has a finished migration.""" try: db.migration_get_by_instance_and_status(context, instance_id, 'finished') @@ -272,8 +272,10 @@ class API(base.Base): return False def ensure_default_security_group(self, context): - """ Create security group for the security context if it - does not already exist + """Ensure that a context has a security group. + + Creates a security group for the security context if it does not + already exist. :param context: the security context @@ -289,7 +291,7 @@ class API(base.Base): db.security_group_create(context, values) def trigger_security_group_rules_refresh(self, context, security_group_id): - """Called when a rule is added to or removed from a security_group""" + """Called when a rule is added to or removed from a security_group.""" security_group = self.db.security_group_get(context, security_group_id) @@ -305,11 +307,12 @@ class API(base.Base): "args": {"security_group_id": security_group.id}}) def trigger_security_group_members_refresh(self, context, group_id): - """Called when a security group gains a new or loses a member + """Called when a security group gains a new or loses a member. Sends an update request to each compute node for whom this is - relevant.""" + relevant. + """ # First, we get the security group rules that reference this group as # the grantee.. security_group_rules = \ @@ -354,7 +357,7 @@ class API(base.Base): as data fields of the instance to be updated - :retval None + :returns: None """ rv = self.db.instance_update(context, instance_id, kwargs) @@ -362,6 +365,7 @@ class API(base.Base): @scheduler_api.reroute_compute("delete") def delete(self, context, instance_id): + """Terminate an instance.""" LOG.debug(_("Going to try to terminate %s"), instance_id) try: instance = self.get(context, instance_id) @@ -393,22 +397,28 @@ class API(base.Base): self.db.instance_destroy(context, instance_id) def get(self, context, instance_id): - """Get a single instance with the given ID.""" + """Get a single instance with the given instance_id.""" rv = self.db.instance_get(context, instance_id) return dict(rv.iteritems()) @scheduler_api.reroute_compute("get") def routing_get(self, context, instance_id): - """Use this method instead of get() if this is the only - operation you intend to to. It will route to novaclient.get - if the instance is not found.""" + """A version of get with special routing characteristics. + + Use this method instead of get() if this is the only operation you + intend to to. It will route to novaclient.get if the instance is not + found. + + """ return self.get(context, instance_id) def get_all(self, context, project_id=None, reservation_id=None, fixed_ip=None): - """Get all instances, possibly filtered by one of the - given parameters. If there is no filter and the context is - an admin, it will retreive all instances in the system. + """Get all instances filtered by one of the given parameters. + + If there is no filter and the context is an admin, it will retreive + all instances in the system. + """ if reservation_id is not None: return self.db.instance_get_all_by_reservation( @@ -437,7 +447,8 @@ class API(base.Base): :param params: Optional dictionary of arguments to be passed to the compute worker - :retval None + :returns: None + """ if not params: params = {} @@ -456,7 +467,7 @@ class API(base.Base): :param params: Optional dictionary of arguments to be passed to the compute worker - :retval: Result returned by compute worker + :returns: Result returned by compute worker """ if not params: params = {} @@ -469,13 +480,14 @@ class API(base.Base): return rpc.call(context, queue, kwargs) def _cast_scheduler_message(self, context, args): - """Generic handler for RPC calls to the scheduler""" + """Generic handler for RPC calls to the scheduler.""" rpc.cast(context, FLAGS.scheduler_topic, args) def snapshot(self, context, instance_id, name): """Snapshot the given instance. - :retval: A dict containing image metadata + :returns: A dict containing image metadata + """ properties = {'instance_id': str(instance_id), 'user_id': str(context.user_id)} @@ -492,7 +504,7 @@ class API(base.Base): self._cast_compute_message('reboot_instance', context, instance_id) def revert_resize(self, context, instance_id): - """Reverts a resize, deleting the 'new' instance in the process""" + """Reverts a resize, deleting the 'new' instance in the process.""" context = context.elevated() migration_ref = self.db.migration_get_by_instance_and_status(context, instance_id, 'finished') @@ -507,8 +519,7 @@ class API(base.Base): {'status': 'reverted'}) def confirm_resize(self, context, instance_id): - """Confirms a migration/resize, deleting the 'old' instance in the - process.""" + """Confirms a migration/resize and deletes the 'old' instance.""" context = context.elevated() migration_ref = self.db.migration_get_by_instance_and_status(context, instance_id, 'finished') @@ -568,10 +579,9 @@ class API(base.Base): @scheduler_api.reroute_compute("diagnostics") def get_diagnostics(self, context, instance_id): """Retrieve diagnostics for the given instance.""" - return self._call_compute_message( - "get_diagnostics", - context, - instance_id) + return self._call_compute_message("get_diagnostics", + context, + instance_id) def get_actions(self, context, instance_id): """Retrieve actions for the given instance.""" @@ -579,12 +589,12 @@ class API(base.Base): @scheduler_api.reroute_compute("suspend") def suspend(self, context, instance_id): - """suspend the instance with instance_id""" + """Suspend the given instance.""" self._cast_compute_message('suspend_instance', context, instance_id) @scheduler_api.reroute_compute("resume") def resume(self, context, instance_id): - """resume the instance with instance_id""" + """Resume the given instance.""" self._cast_compute_message('resume_instance', context, instance_id) @scheduler_api.reroute_compute("rescue") @@ -599,15 +609,15 @@ class API(base.Base): def set_admin_password(self, context, instance_id, password=None): """Set the root/admin password for the given instance.""" - self._cast_compute_message('set_admin_password', context, instance_id, - password) + self._cast_compute_message( + 'set_admin_password', context, instance_id, password) def inject_file(self, context, instance_id): """Write a file to the given instance.""" self._cast_compute_message('inject_file', context, instance_id) def get_ajax_console(self, context, instance_id): - """Get a url to an AJAX Console""" + """Get a url to an AJAX Console.""" output = self._call_compute_message('get_ajax_console', context, instance_id) @@ -616,7 +626,7 @@ class API(base.Base): 'args': {'token': output['token'], 'host': output['host'], 'port': output['port']}}) return {'url': '%s/?token=%s' % (FLAGS.ajax_console_proxy_url, - output['token'])} + output['token'])} def get_vnc_console(self, context, instance_id): """Get a url to a VNC Console.""" @@ -638,39 +648,34 @@ class API(base.Base): 'portignore')} def get_console_output(self, context, instance_id): - """Get console output for an an instance""" + """Get console output for an an instance.""" return self._call_compute_message('get_console_output', context, instance_id) def lock(self, context, instance_id): - """lock the instance with instance_id""" + """Lock the given instance.""" self._cast_compute_message('lock_instance', context, instance_id) def unlock(self, context, instance_id): - """unlock the instance with instance_id""" + """Unlock the given instance.""" self._cast_compute_message('unlock_instance', context, instance_id) def get_lock(self, context, instance_id): - """return the boolean state of (instance with instance_id)'s lock""" + """Return the boolean state of given instance's lock.""" instance = self.get(context, instance_id) return instance['locked'] def reset_network(self, context, instance_id): - """ - Reset networking on the instance. - - """ + """Reset networking on the instance.""" self._cast_compute_message('reset_network', context, instance_id) def inject_network_info(self, context, instance_id): - """ - Inject network info for the instance. - - """ + """Inject network info for the instance.""" self._cast_compute_message('inject_network_info', context, instance_id) def attach_volume(self, context, instance_id, volume_id, device): + """Attach an existing volume to an existing instance.""" if not re.match("^/dev/[a-z]d[a-z]+$", device): raise exception.ApiError(_("Invalid device specified: %s. " "Example device: /dev/vdb") % device) @@ -685,6 +690,7 @@ class API(base.Base): "mountpoint": device}}) def detach_volume(self, context, volume_id): + """Detach a volume from an instance.""" instance = self.db.volume_get_instance(context.elevated(), volume_id) if not instance: raise exception.ApiError(_("Volume isn't attached to anything!")) @@ -698,6 +704,7 @@ class API(base.Base): return instance def associate_floating_ip(self, context, instance_id, address): + """Associate a floating ip with an instance.""" instance = self.get(context, instance_id) self.network_api.associate_floating_ip(context, floating_ip=address, @@ -709,11 +716,11 @@ class API(base.Base): return dict(rv.iteritems()) def delete_instance_metadata(self, context, instance_id, key): - """Delete the given metadata item""" + """Delete the given metadata item from an instance.""" self.db.instance_metadata_delete(context, instance_id, key) def update_or_create_instance_metadata(self, context, instance_id, metadata): - """Updates or creates instance metadata""" + """Updates or creates instance metadata.""" self.db.instance_metadata_update_or_create(context, instance_id, metadata) diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index b3a5ab0ac..f893f8478 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -18,9 +18,7 @@ # License for the specific language governing permissions and limitations # under the License. -""" -The built-in instance properties. -""" +"""Built-in instance properties.""" from nova import context from nova import db @@ -34,9 +32,7 @@ LOG = logging.getLogger('nova.instance_types') def create(name, memory, vcpus, local_gb, flavorid, swap=0, rxtx_quota=0, rxtx_cap=0): - """Creates instance types / flavors - arguments: name memory vcpus local_gb flavorid swap rxtx_quota rxtx_cap - """ + """Creates instance types.""" for option in [memory, vcpus, local_gb, flavorid]: try: int(option) @@ -64,8 +60,7 @@ def create(name, memory, vcpus, local_gb, flavorid, swap=0, def destroy(name): - """Marks instance types / flavors as deleted - arguments: name""" + """Marks instance types as deleted.""" if name == None: raise exception.InvalidInputException(_("No instance type specified")) else: @@ -77,8 +72,7 @@ def destroy(name): def purge(name): - """Removes instance types / flavors from database - arguments: name""" + """Removes instance types from database.""" if name == None: raise exception.InvalidInputException(_("No instance type specified")) else: @@ -90,18 +84,19 @@ def purge(name): def get_all_types(inactive=0): - """Retrieves non-deleted instance_types. - Pass true as argument if you want deleted instance types returned also.""" + """Get all non-deleted instance_types. + + Pass true as argument if you want deleted instance types returned also. + + """ return db.instance_type_get_all(context.get_admin_context(), inactive) -def get_all_flavors(): - """retrieves non-deleted flavors. alias for instance_types.get_all_types(). - Pass true as argument if you want deleted instance types returned also.""" - return get_all_types(context.get_admin_context()) +get_all_flavors = get_all_types def get_default_instance_type(): + """Get the default instance type.""" name = FLAGS.default_instance_type try: return get_instance_type_by_name(name) @@ -110,7 +105,7 @@ def get_default_instance_type(): def get_instance_type(id): - """Retrieves single instance type by id""" + """Retrieves single instance type by id.""" if id is None: return get_default_instance_type() try: @@ -121,7 +116,7 @@ def get_instance_type(id): def get_instance_type_by_name(name): - """Retrieves single instance type by name""" + """Retrieves single instance type by name.""" if name is None: return get_default_instance_type() try: @@ -131,8 +126,10 @@ def get_instance_type_by_name(name): raise exception.ApiError(_("Unknown instance type: %s") % name) +# TODO(termie): flavor-specific code should probably be in the API that uses +# flavors. def get_instance_type_by_flavor_id(flavor_id): - """retrieve instance type by flavor_id""" + """Retrieve instance type by flavor_id.""" if flavor_id is None: return get_default_instance_type() try: -- cgit From b342b1b63a860b9f4abdc28224ab7a6a0f3b00dd Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Mon, 11 Apr 2011 12:15:22 -0500 Subject: Remove unused self.interfaces_xml --- nova/virt/libvirt_conn.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 6ec15fbb8..4b6cfa6a4 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -211,7 +211,6 @@ class LibvirtConnection(driver.ComputeDriver): self.libvirt_uri = self.get_uri() self.libvirt_xml = open(FLAGS.libvirt_xml_template).read() - self.interfaces_xml = open(FLAGS.injected_network_template).read() self.cpuinfo_xml = open(FLAGS.cpuinfo_xml_template).read() self._wrapped_conn = None self.read_only = read_only -- cgit From 9ce66a4a09094d2b0403deea77416149aa789f3c Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Mon, 11 Apr 2011 22:35:09 +0400 Subject: Floating ips auto assignment --- nova/compute/manager.py | 21 +++++++++++++++++++++ nova/db/api.py | 3 +++ nova/db/sqlalchemy/api.py | 12 ++++++++++++ 3 files changed, 36 insertions(+) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 68b163355..86273b6b4 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -73,6 +73,8 @@ flags.DEFINE_integer('live_migration_retry_count', 30, flags.DEFINE_integer("rescue_timeout", 0, "Automatically unrescue an instance after N seconds." " Set to 0 to disable.") +flags.DEFINE_bool('auto_assign_floating_ip',False, 'Autoassigning floating' + ' ip to VM') LOG = logging.getLogger('nova.compute.manager') @@ -224,6 +226,16 @@ class ComputeManager(manager.SchedulerDependentManager): self.network_manager.setup_compute_network(context, instance_id) + if FLAGS.auto_assign_floating_ip: + public_ip = rpc.call(context, + FLAGS.network_topic, + {"method": "allocate_floating_ip", + "args": {"project_id": context.project_id}}) + self.network_manager.associate_floating_ip(context, + instance_id=instance_id, + address=public_ip) + + # TODO(vish) check to make sure the availability zone matches self.db.instance_set_state(context, instance_id, @@ -271,6 +283,15 @@ class ComputeManager(manager.SchedulerDependentManager): network_topic, {"method": "disassociate_floating_ip", "args": {"floating_address": address}}) + + if FLAGS.auto_assign_floating_ip: + LOG.debug(_("Deallocating floating ip %s"), + floating_ip['address'], context=context) + rpc.cast(context, + FLAGS.network_topic, + {"method": "deallocate_floating_ip", + "args": {"floating_address": + floating_ip['address']}}) address = fixed_ip['address'] if address: diff --git a/nova/db/api.py b/nova/db/api.py index 63901e94d..859acc146 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -290,6 +290,9 @@ def floating_ip_update(context, address, values): """Update a floating ip by address or raise if it doesn't exist.""" return IMPL.floating_ip_update(context, address, values) +def floating_ip_set_auto_assigned(context, address): + """Set auto_assigned flag to floating ip""" + return IMPL.floating_ip_set_auto_assigned(context, address) #################### diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index e675022e9..28126a517 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -489,6 +489,7 @@ def floating_ip_deallocate(context, address): address, session=session) floating_ip_ref['project_id'] = None + floating_ip_ref['auto_assigned'] = False floating_ip_ref.save(session=session) @@ -522,6 +523,17 @@ def floating_ip_disassociate(context, address): return fixed_ip_address +@require_context +def floating_ip_set_auto_assigned(context, address): + session = get_session() + with session.begin(): + floating_ip_ref = floating_ip_get_by_address(context, + address, + session=session) + floating_ip_ref.auto_assigned = True + floating_ip_ref.save(session=session) + + @require_admin_context def floating_ip_get_all(context): session = get_session() -- cgit From 0d40279353be6932a05e614f78e7b23d28177b94 Mon Sep 17 00:00:00 2001 From: Anne Gentle Date: Mon, 11 Apr 2011 15:04:00 -0500 Subject: Updating the runnova information and fixing bug 753352 --- doc/source/runnova/flags.rst | 172 +------------------------ doc/source/runnova/index.rst | 4 +- doc/source/runnova/managing.images.rst | 7 +- doc/source/runnova/managing.instance.types.rst | 2 + doc/source/runnova/managingsecurity.rst | 2 - doc/source/runnova/network.vlan.rst | 5 +- doc/source/runnova/nova.manage.rst | 14 +- 7 files changed, 19 insertions(+), 187 deletions(-) diff --git a/doc/source/runnova/flags.rst b/doc/source/runnova/flags.rst index 1bfa022d9..3d16e1303 100644 --- a/doc/source/runnova/flags.rst +++ b/doc/source/runnova/flags.rst @@ -20,174 +20,4 @@ Flags and Flagfiles Nova uses a configuration file containing flags located in /etc/nova/nova.conf. You can get the most recent listing of avaialble flags by running nova-(servicename) --help, for example, nova-api --help. -Here's a list of available flags and their default settings. - - --ajax_console_proxy_port: port that ajax_console_proxy binds - (default: '8000') - --ajax_console_proxy_topic: the topic ajax proxy nodes listen on - (default: 'ajax_proxy') - --ajax_console_proxy_url: location of ajax console proxy, in the form - "http://127.0.0.1:8000" - (default: 'http://127.0.0.1:8000') - --auth_token_ttl: Seconds for auth tokens to linger - (default: '3600') - (an integer) - --aws_access_key_id: AWS Access ID - (default: 'admin') - --aws_secret_access_key: AWS Access Key - (default: 'admin') - --compute_manager: Manager for compute - (default: 'nova.compute.manager.ComputeManager') - --compute_topic: the topic compute nodes listen on - (default: 'compute') - --connection_type: libvirt, xenapi or fake - (default: 'libvirt') - --console_manager: Manager for console proxy - (default: 'nova.console.manager.ConsoleProxyManager') - --console_topic: the topic console proxy nodes listen on - (default: 'console') - --control_exchange: the main exchange to connect to - (default: 'nova') - --db_backend: The backend to use for db - (default: 'sqlalchemy') - --default_image: default image to use, testing only - (default: 'ami-11111') - --default_instance_type: default instance type to use, testing only - (default: 'm1.small') - --default_log_levels: list of logger=LEVEL pairs - (default: 'amqplib=WARN,sqlalchemy=WARN,eventlet.wsgi.server=WARN') - (a comma separated list) - --default_project: default project for openstack - (default: 'openstack') - --ec2_dmz_host: internal ip of api server - (default: '$my_ip') - --ec2_host: ip of api server - (default: '$my_ip') - --ec2_path: suffix for ec2 - (default: '/services/Cloud') - --ec2_port: cloud controller port - (default: '8773') - (an integer) - --ec2_scheme: prefix for ec2 - (default: 'http') - --[no]enable_new_services: Services to be added to the available pool on - create - (default: 'true') - --[no]fake_network: should we use fake network devices and addresses - (default: 'false') - --[no]fake_rabbit: use a fake rabbit - (default: 'false') - --glance_host: glance host - (default: '$my_ip') - --glance_port: glance port - (default: '9292') - (an integer) - -?,--[no]help: show this help - --[no]helpshort: show usage only for this module - --[no]helpxml: like --help, but generates XML output - --host: name of this node - (default: 'osdemo03') - --image_service: The service to use for retrieving and searching for images. - (default: 'nova.image.s3.S3ImageService') - --instance_name_template: Template string to be used to generate instance - names - (default: 'instance-%08x') - --logfile: output to named file - --logging_context_format_string: format string to use for log messages with - context - (default: '%(asctime)s %(levelname)s %(name)s [%(request_id)s %(user)s - %(project)s] %(message)s') - --logging_debug_format_suffix: data to append to log format when level is - DEBUG - (default: 'from %(processName)s (pid=%(process)d) %(funcName)s - %(pathname)s:%(lineno)d') - --logging_default_format_string: format string to use for log messages without - context - (default: '%(asctime)s %(levelname)s %(name)s [-] %(message)s') - --logging_exception_prefix: prefix each line of exception output with this - format - (default: '(%(name)s): TRACE: ') - --my_ip: host ip address - (default: '184.106.73.68') - --network_manager: Manager for network - (default: 'nova.network.manager.VlanManager') - --network_topic: the topic network nodes listen on - (default: 'network') - --node_availability_zone: availability zone of this node - (default: 'nova') - --null_kernel: kernel image that indicates not to use a kernel, but to use a - raw disk image instead - (default: 'nokernel') - --osapi_host: ip of api server - (default: '$my_ip') - --osapi_path: suffix for openstack - (default: '/v1.0/') - --osapi_port: OpenStack API port - (default: '8774') - (an integer) - --osapi_scheme: prefix for openstack - (default: 'http') - --periodic_interval: seconds between running periodic tasks - (default: '60') - (a positive integer) - --pidfile: pidfile to use for this service - --rabbit_host: rabbit host - (default: 'localhost') - --rabbit_max_retries: rabbit connection attempts - (default: '12') - (an integer) - --rabbit_password: rabbit password - (default: 'guest') - --rabbit_port: rabbit port - (default: '5672') - (an integer) - --rabbit_retry_interval: rabbit connection retry interval - (default: '10') - (an integer) - --rabbit_userid: rabbit userid - (default: 'guest') - --rabbit_virtual_host: rabbit virtual host - (default: '/') - --region_list: list of region=fqdn pairs separated by commas - (default: '') - (a comma separated list) - --report_interval: seconds between nodes reporting state to datastore - (default: '10') - (a positive integer) - --s3_dmz: s3 dmz ip (for instances) - (default: '$my_ip') - --s3_host: s3 host (for infrastructure) - (default: '$my_ip') - --s3_port: s3 port - (default: '3333') - (an integer) - --scheduler_manager: Manager for scheduler - (default: 'nova.scheduler.manager.SchedulerManager') - --scheduler_topic: the topic scheduler nodes listen on - (default: 'scheduler') - --sql_connection: connection string for sql database - (default: 'sqlite:///$state_path/nova.sqlite') - --sql_idle_timeout: timeout for idle sql database connections - (default: '3600') - --sql_max_retries: sql connection attempts - (default: '12') - (an integer) - --sql_retry_interval: sql connection retry interval - (default: '10') - (an integer) - --state_path: Top-level directory for maintaining nova's state - (default: '/usr/lib/pymodules/python2.6/nova/../') - --[no]use_syslog: output to syslog - (default: 'false') - --[no]verbose: show debug output - (default: 'false') - --volume_manager: Manager for volume - (default: 'nova.volume.manager.VolumeManager') - --volume_name_template: Template string to be used to generate instance names - (default: 'volume-%08x') - --volume_topic: the topic volume nodes listen on - (default: 'volume') - --vpn_image_id: AMI for cloudpipe vpn server - (default: 'ami-cloudpipe') - --vpn_key_suffix: Suffix to add to project name for vpn key and secgroups - (default: '-vpn') \ No newline at end of file +The OpenStack wiki has a page with the flags listed by their purpose and use at http://wiki.openstack.org/FlagsGrouping. \ No newline at end of file diff --git a/doc/source/runnova/index.rst b/doc/source/runnova/index.rst index 283d268ce..769bbec84 100644 --- a/doc/source/runnova/index.rst +++ b/doc/source/runnova/index.rst @@ -18,7 +18,7 @@ Running Nova ============ -This guide describes the basics of running and managing Nova. For more administrator's documentation, refer to `docs.openstack.org `_. +This guide describes the basics of running and managing Nova. This site is intended to provide developer documentation. For more administrator's documentation, refer to `docs.openstack.org `_. Running the Cloud ----------------- @@ -60,7 +60,7 @@ For background on the core objects referenced in this section, see :doc:`../obje Deployment ---------- -For a starting multi-node architecture, you would start with two nodes - a cloud controller node and a compute node. The cloud controller node contains the nova- services plus the Nova database. The compute node installs all the nova-services but then refers to the database installation, which is hosted by the cloud controller node. Ensure that the nova.conf file is identical on each node. If you find performance issues not related to database reads or writes, but due to the messaging queue backing up, you could add additional messaging services (rabbitmq). For instructions on multi-server installations, refer to `Installing and Configuring OpenStack Compute `_. +For a starting multi-node architecture, you would start with two nodes - a cloud controller node and a compute node. The cloud controller node contains the nova- services plus the Nova database. The compute node installs all the nova-services but then refers to the database installation, which is hosted by the cloud controller node. Ensure that the nova.conf file is identical on each node. If you find performance issues not related to database reads or writes, but due to the messaging queue backing up, you could add additional messaging services (rabbitmq). For instructions on multi-server installations, refer to `Installing and Configuring OpenStack Compute `_. .. toctree:: diff --git a/doc/source/runnova/managing.images.rst b/doc/source/runnova/managing.images.rst index c5d93a6e8..a2e618602 100644 --- a/doc/source/runnova/managing.images.rst +++ b/doc/source/runnova/managing.images.rst @@ -18,4 +18,9 @@ Managing Images =============== -.. todo:: Put info on managing images here! +With Nova, you can manage images either using the built-in object store or using Glance, a related OpenStack project. Glance is a server that provides the following services: + + * Ability to store and retrieve virtual machine images + * Ability to store and retrieve metadata about these virtual machine images + +Refer to http://glance.openstack.org for additional details. \ No newline at end of file diff --git a/doc/source/runnova/managing.instance.types.rst b/doc/source/runnova/managing.instance.types.rst index 746077716..a575e16b7 100644 --- a/doc/source/runnova/managing.instance.types.rst +++ b/doc/source/runnova/managing.instance.types.rst @@ -16,6 +16,8 @@ Managing Instance Types and Flavors =================================== +You can manage instance types and instance flavors using the nova-manage command-line interface coupled with the instance_type subcommand for nova-manage. + What are Instance Types or Flavors ? ------------------------------------ diff --git a/doc/source/runnova/managingsecurity.rst b/doc/source/runnova/managingsecurity.rst index 7893925e7..85329ed4a 100644 --- a/doc/source/runnova/managingsecurity.rst +++ b/doc/source/runnova/managingsecurity.rst @@ -18,8 +18,6 @@ Security Considerations ======================= -.. todo:: This doc is vague and just high-level right now. Describe architecture that enables security. - The goal of securing a cloud computing system involves both protecting the instances, data on the instances, and ensuring users are authenticated for actions and that borders are understood by the users and the system. Protecting the system from intrusion or attack involves authentication, network protections, and diff --git a/doc/source/runnova/network.vlan.rst b/doc/source/runnova/network.vlan.rst index c06ce8e8b..df19c7a80 100644 --- a/doc/source/runnova/network.vlan.rst +++ b/doc/source/runnova/network.vlan.rst @@ -36,9 +36,7 @@ In this mode, each project gets its own VLAN, Linux networking bridge, and subne While network traffic between VM instances belonging to the same VLAN is always open, Nova can enforce isolation of network traffic between different projects by enforcing one VLAN per project. -In addition, the network administrator can specify a pool of public IP addresses that users may allocate and then assign to VMs, either at boot or dynamically at run-time. This capability is similar to Amazon's 'elastic IPs'. A public IP address may be associated with a running instances, allowing the VM instance to be accessed from the public network. The public IP addresses are accessible from the network host and NATed to the private IP address of the project. - -.. todo:: Describe how a public IP address could be associated with a project (a VLAN) +In addition, the network administrator can specify a pool of public IP addresses that users may allocate and then assign to VMs, either at boot or dynamically at run-time. This capability is similar to Amazon's 'elastic IPs'. A public IP address may be associated with a running instances, allowing the VM instance to be accessed from the public network. The public IP addresses are accessible from the network host and NATed to the private IP address of the project. A public IP address could be associated with a project using the euca-allocate-address commands. This is the default networking mode and supports the most features. For multiple machine installation, it requires a switch that supports host-managed vlan tagging. In this mode, nova will create a vlan and bridge for each project. The project gets a range of private ips that are only accessible from inside the vlan. In order for a user to access the instances in their project, a special vpn instance (code named :ref:`cloudpipe `) needs to be created. Nova generates a certificate and key for the user to access the vpn and starts the vpn automatically. More information on cloudpipe can be found :ref:`here `. @@ -176,4 +174,3 @@ Setup * project network size * DMZ network -.. todo:: need specific Nova configuration added diff --git a/doc/source/runnova/nova.manage.rst b/doc/source/runnova/nova.manage.rst index 0636e5752..af82b6a4f 100644 --- a/doc/source/runnova/nova.manage.rst +++ b/doc/source/runnova/nova.manage.rst @@ -83,13 +83,13 @@ Nova User Nova Project ~~~~~~~~~~~~ -``nova-manage project add `` +``nova-manage project add `` - Add a nova project with the name to the database. + Add a nova project with the name to the database that will be administered by the named user. -``nova-manage project create `` +``nova-manage project create `` - Create a new nova project with the name (you still need to do nova-manage project add to add it to the database). + Create a new nova project with the name (you still need to do nova-manage project add to add it to the database). The username is the administrator of the project. ``nova-manage project delete `` @@ -111,9 +111,9 @@ Nova Project Deletes the project with the name . -``nova-manage project zipfile`` +``nova-manage project zipfile `` - Compresses all related files for a created project into a zip file nova.zip. + Compresses all related files for a created project into a named zip file such as nova.zip. Nova Role ~~~~~~~~~ @@ -226,7 +226,7 @@ Concept: Plugins Concept: IPC/RPC ---------------- -Rabbit! +Rabbit is the main messaging queue, used for all communication between Nova components and it also does the remote procedure calls and inter-process communication. Concept: Fakes -- cgit From 3aae677e5a87858f2195028bd78571c9d10f1615 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 11 Apr 2011 21:43:12 +0000 Subject: update documentation on cloudpipe --- doc/source/devref/cloudpipe.rst | 53 ++++++++++++++++++++++++++++++++++ doc/source/devref/rc.local | 36 +++++++++++++++++++++++ doc/source/devref/server.conf.template | 34 ++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 doc/source/devref/rc.local create mode 100644 doc/source/devref/server.conf.template diff --git a/doc/source/devref/cloudpipe.rst b/doc/source/devref/cloudpipe.rst index 4f5d91e28..e12d47dd7 100644 --- a/doc/source/devref/cloudpipe.rst +++ b/doc/source/devref/cloudpipe.rst @@ -38,6 +38,34 @@ The cloudpipe image is basically just a linux instance with openvpn installed. It is also useful to have a cron script that will periodically redownload the metadata and copy the new crl. This will keep revoked users from connecting and will disconnect any users that are connected with revoked certificates when their connection is renegotiated (every hour). +Creating a Cloudpipe Image +-------------------------- + +Making a cloudpipe image is relatively easy. + +# install openvpn on a base ubuntu image. +# set up a server.conf.template in /etc/openvpn/ + +.. literalinclude:: server.conf.template + :language: bash + :linenos: + +# download and run the payload on boot from /etc/rc.local. + +.. literalinclude:: rc.local + :language: bash + :linenos: + +# register the image and set the image id in your flagfile:: + + --vpn_image_id=ami-xxxxxxxx + +# you should set a few other flags to make vpns work properly:: + + --use_project_ca + --cnt_vpn_clients=5 + + Cloudpipe Launch ---------------- @@ -63,6 +91,31 @@ Certificates and Revocation If the use_project_ca flag is set (required to for cloudpipes to work securely), then each project has its own ca. This ca is used to sign the certificate for the vpn, and is also passed to the user for bundling images. When a certificate is revoked using nova-manage, a new Certificate Revocation List (crl) is generated. As long as cloudpipe has an updated crl, it will block revoked users from connecting to the vpn. +The userdata for cloudpipe isn't currently updated when certs are revoked, so it is necessary to restart the cloudpipe instance if a user's credentials are revoked. + + +Restarting Cloudpipe VPN +------------------------ + +You can reboot a cloudpipe vpn through the api if something goes wrong (using euca-reboot-instances for example), but if you generate a new crl, you will have to terminate it and start it again using nova-manage vpn run. The cloudpipe instance always gets the first ip in the subnet and it can take up to 10 minutes for the ip to be recovered. If you try to start the new vpn instance too soon, the instance will fail to start because of a NoMoreAddresses error. If you can't wait 10 minutes, you can manually update the ip with something like the following (use the right ip for the project):: + + euca-terminate-instances + mysql nova -e "update fixed_ips set allocated=0, leased=0, instance_id=NULL where fixed_ip='10.0.0.2'" + +You also will need to terminate the dnsmasq running for the user (make sure you use the right pid file):: + + sudo kill `cat /var/lib/nova/br100.pid` + +Now you should be able to re-run the vpn:: + + nova-manage vpn run + + +Logging into Cloudpipe VPN +-------------------------- + +The keypair that was used to launch the cloudpipe instance should be in the keys/ folder. You can use this key to log into the cloudpipe instance for debugging purposes. + The :mod:`nova.cloudpipe.pipelib` Module ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/source/devref/rc.local b/doc/source/devref/rc.local new file mode 100644 index 000000000..d1ccf0cbc --- /dev/null +++ b/doc/source/devref/rc.local @@ -0,0 +1,36 @@ +#!/bin/sh -e +# +# rc.local +# +# This script is executed at the end of each multiuser runlevel. +# Make sure that the script will "exit 0" on success or any other +# value on error. +# +# In order to enable or disable this script just change the execution +# bits. +# +# By default this script does nothing. +####### These lines go at the end of /etc/rc.local ####### +. /lib/lsb/init-functions + +echo Downloading payload from userdata +wget http://169.254.169.254/latest/user-data -O /tmp/payload.b64 +echo Decrypting base64 payload +openssl enc -d -base64 -in /tmp/payload.b64 -out /tmp/payload.zip + +mkdir -p /tmp/payload +echo Unzipping payload file +unzip -o /tmp/payload.zip -d /tmp/payload/ + +# if the autorun.sh script exists, run it +if [ -e /tmp/payload/autorun.sh ]; then + echo Running autorun.sh + cd /tmp/payload + sh /tmp/payload/autorun.sh + +else + echo rc.local : No autorun script to run +fi + + +exit 0 diff --git a/doc/source/devref/server.conf.template b/doc/source/devref/server.conf.template new file mode 100644 index 000000000..feee3185b --- /dev/null +++ b/doc/source/devref/server.conf.template @@ -0,0 +1,34 @@ +port 1194 +proto udp +dev tap0 +up "/etc/openvpn/up.sh br0" +down "/etc/openvpn/down.sh br0" + +persist-key +persist-tun + +ca ca.crt +cert server.crt +key server.key # This file should be kept secret + +dh dh1024.pem +ifconfig-pool-persist ipp.txt + +server-bridge VPN_IP DHCP_SUBNET DHCP_LOWER DHCP_UPPER + +client-to-client +keepalive 10 120 +comp-lzo + +max-clients 1 + +user nobody +group nogroup + +persist-key +persist-tun + +status openvpn-status.log + +verb 3 +mute 20 \ No newline at end of file -- cgit From 4a2c973fe5c7cf68ff7f45a4927dc6d2e0a3986b Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Tue, 12 Apr 2011 02:44:44 +0400 Subject: migaration and pep8 fixes --- nova/api/openstack/contrib/volumes.py | 3 +- nova/compute/manager.py | 4 +-- nova/db/api.py | 2 ++ .../015_add_auto_assign_to_floating_ips.py | 38 ++++++++++++++++++++++ 4 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py diff --git a/nova/api/openstack/contrib/volumes.py b/nova/api/openstack/contrib/volumes.py index 6efacce52..18de2ec71 100644 --- a/nova/api/openstack/contrib/volumes.py +++ b/nova/api/openstack/contrib/volumes.py @@ -322,8 +322,7 @@ class Volumes(extensions.ExtensionDescriptor): # Does this matter? res = extensions.ResourceExtension('volumes', VolumeController(), - collection_actions={'detail': 'GET'} - ) + collection_actions={'detail': 'GET'}) resources.append(res) res = extensions.ResourceExtension('volume_attachments', diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 86273b6b4..af3551708 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -73,7 +73,7 @@ flags.DEFINE_integer('live_migration_retry_count', 30, flags.DEFINE_integer("rescue_timeout", 0, "Automatically unrescue an instance after N seconds." " Set to 0 to disable.") -flags.DEFINE_bool('auto_assign_floating_ip',False, 'Autoassigning floating' +flags.DEFINE_bool('auto_assign_floating_ip', False, 'Autoassigning floating' ' ip to VM') LOG = logging.getLogger('nova.compute.manager') @@ -235,7 +235,6 @@ class ComputeManager(manager.SchedulerDependentManager): instance_id=instance_id, address=public_ip) - # TODO(vish) check to make sure the availability zone matches self.db.instance_set_state(context, instance_id, @@ -283,7 +282,6 @@ class ComputeManager(manager.SchedulerDependentManager): network_topic, {"method": "disassociate_floating_ip", "args": {"floating_address": address}}) - if FLAGS.auto_assign_floating_ip: LOG.debug(_("Deallocating floating ip %s"), floating_ip['address'], context=context) diff --git a/nova/db/api.py b/nova/db/api.py index 859acc146..6b465c021 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -290,12 +290,14 @@ def floating_ip_update(context, address, values): """Update a floating ip by address or raise if it doesn't exist.""" return IMPL.floating_ip_update(context, address, values) + def floating_ip_set_auto_assigned(context, address): """Set auto_assigned flag to floating ip""" return IMPL.floating_ip_set_auto_assigned(context, address) #################### + def migration_update(context, id, values): """Update a migration instance""" return IMPL.migration_update(context, id, values) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py b/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py new file mode 100644 index 000000000..b7e480e67 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py @@ -0,0 +1,38 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# Copyright 2011 Grid Dynamics +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import * +from sqlalchemy.sql import text +from migrate import * + + +meta = MetaData() + +c_auto_assigned = Column('auto_assigned',Boolean, default=False) + + +def upgrade(migrate_engine): + # Upgrade operations go here. Don't create your own engine; + # bind migrate_engine to your metadata + meta.bind = migrate_engine + + floating_ips = Table('floating_ips', meta, autoload=True, + autoload_with=migrate_engine) + + floating_ips.create_column(c_auto_assigned) + + \ No newline at end of file -- cgit From fa4aeb9af8d00ecff6620646c142e5ff68e1cd5e Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Tue, 12 Apr 2011 03:07:22 +0400 Subject: pep8 fixes --- .../migrate_repo/versions/015_add_auto_assign_to_floating_ips.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py b/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py index b7e480e67..6829b5d6e 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py @@ -22,7 +22,7 @@ from migrate import * meta = MetaData() -c_auto_assigned = Column('auto_assigned',Boolean, default=False) +c_auto_assigned = Column('auto_assigned', Boolean, default=False) def upgrade(migrate_engine): @@ -33,6 +33,4 @@ def upgrade(migrate_engine): floating_ips = Table('floating_ips', meta, autoload=True, autoload_with=migrate_engine) - floating_ips.create_column(c_auto_assigned) - - \ No newline at end of file + floating_ips.create_column(c_auto_assigned) \ No newline at end of file -- cgit From 87d758b18836085d73c8b4230cd4812e0aa876aa Mon Sep 17 00:00:00 2001 From: Yoshiaki Tamura Date: Tue, 12 Apr 2011 11:37:51 +0900 Subject: Fix RBDDriver in volume manager. discover_volume was raising exception. Modified local_path as well. --- Authors | 1 + nova/volume/driver.py | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Authors b/Authors index 2de4fb955..f4b40a853 100644 --- a/Authors +++ b/Authors @@ -74,5 +74,6 @@ Trey Morris Tushar Patil Vasiliy Shlykov Vishvananda Ishaya +Yoshiaki Tamura Youcef Laribi Zhixue Wu diff --git a/nova/volume/driver.py b/nova/volume/driver.py index 850893914..85ff17708 100644 --- a/nova/volume/driver.py +++ b/nova/volume/driver.py @@ -557,7 +557,7 @@ class RBDDriver(VolumeDriver): """Returns the path of the rbd volume.""" # This is the same as the remote path # since qemu accesses it directly. - return self.discover_volume(volume) + return "rbd:%s/%s" % (FLAGS.rbd_pool, volume['name']) def ensure_export(self, context, volume): """Synchronously recreates an export for a logical volume.""" @@ -571,10 +571,8 @@ class RBDDriver(VolumeDriver): """Removes an export for a logical volume""" pass - def discover_volume(self, volume): + def discover_volume(self, context, volume): """Discover volume on a remote host""" - # NOTE(justinsb): This is messed up... discover_volume takes 3 args - # but then that would break local_path return "rbd:%s/%s" % (FLAGS.rbd_pool, volume['name']) def undiscover_volume(self, volume): -- cgit From 07c1f30225fb27cbc8e7cfeebc6a73ec67a7f2e5 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 12 Apr 2011 09:41:42 +0200 Subject: pep8 --- nova/api/ec2/cloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 83c894bea..5e81878c4 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -144,7 +144,7 @@ class CloudController(object): return None # This ensures that all attributes of the instance - # are populated. + # are populated. instance_ref = db.instance_get(ctxt, instance_ref['id']) mpi = self._get_mpi_data(ctxt, instance_ref['project_id']) -- cgit From 70c7558b54b693872af09772ae310d893b334dff Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 12 Apr 2011 11:21:29 -0500 Subject: Only warn about rouge instances that compute should know about. --- nova/compute/manager.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 68b163355..39d7af9c1 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1111,6 +1111,9 @@ class ComputeManager(manager.SchedulerDependentManager): # Are there VMs not in the DB? for vm_not_found_in_db in vms_not_found_in_db: name = vm_not_found_in_db - # TODO(justinsb): What to do here? Adopt it? Shut it down? - LOG.warning(_("Found VM not in DB: '%(name)s'. Ignoring") - % locals()) + + # We only care about instances that compute *should* know about + if name.startswith("instance-"): + # TODO(justinsb): What to do here? Adopt it? Shut it down? + LOG.warning(_("Found VM not in DB: '%(name)s'. Ignoring") + % locals()) -- cgit From baa129773c41f143237db992d90e1c681b3d33f8 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Tue, 12 Apr 2011 13:47:45 -0400 Subject: dots. --- nova/api/openstack/server_metadata.py | 2 +- nova/compute/api.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/api/openstack/server_metadata.py b/nova/api/openstack/server_metadata.py index 01ca79eec..fd64ee4fb 100644 --- a/nova/api/openstack/server_metadata.py +++ b/nova/api/openstack/server_metadata.py @@ -88,7 +88,7 @@ class Controller(common.OpenstackController): self.compute_api.delete_instance_metadata(context, server_id, id) def _handle_quota_error(self, error): - """Reraise quota errors as api-specific http exceptions""" + """Reraise quota errors as api-specific http exceptions.""" if error.code == "MetadataLimitExceeded": raise exc.HTTPBadRequest(explanation=error.message) raise error diff --git a/nova/compute/api.py b/nova/compute/api.py index f237f994c..0c7e8f84e 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -105,7 +105,7 @@ class API(base.Base): raise quota.QuotaError(code="OnsetFileContentLimitExceeded") def _check_metadata_properties_quota(self, context, metadata={}): - """Enforce quota limits on metadata properties""" + """Enforce quota limits on metadata properties.""" num_metadata = len(metadata) quota_metadata = quota.allowed_metadata_items(context, num_metadata) if quota_metadata < num_metadata: -- cgit From e288c8aab3092f8691e190d2a3b9405518dab858 Mon Sep 17 00:00:00 2001 From: termie Date: Tue, 12 Apr 2011 13:08:48 -0500 Subject: remove extra newline --- nova/compute/api.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index e6146231c..c29523033 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -114,7 +114,6 @@ class API(base.Base): Verifies that quota and other arguments are valid. """ - if not instance_type: instance_type = instance_types.get_default_instance_type() -- cgit From 76bb9f42c6cc39218824332e396dca4a5e6ec351 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 12 Apr 2011 18:43:49 +0000 Subject: fix show_by_name in s3.py and give a helpful error message if image lookup fails --- nova/api/ec2/cloud.py | 5 ++++- nova/image/s3.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 5e81878c4..10b1d0ac5 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -908,7 +908,10 @@ class CloudController(object): internal_id = ec2utils.ec2_id_to_id(ec2_id) return self.image_service.show(context, internal_id) except exception.NotFound: - return self.image_service.show_by_name(context, ec2_id) + try: + return self.image_service.show_by_name(context, ec2_id) + except exception.NotFound: + raise exception.NotFound(_('Image %s not found') % ec2_id) def _format_image(self, image): """Convert from format defined by BaseImageService to S3 format.""" diff --git a/nova/image/s3.py b/nova/image/s3.py index 554760d53..b1034d151 100644 --- a/nova/image/s3.py +++ b/nova/image/s3.py @@ -75,7 +75,7 @@ class S3ImageService(service.BaseImageService): return self.service.show(context, image_id) def show_by_name(self, context, name): - return self.service.show(context, name) + return self.service.show_by_name(context, name) @staticmethod def _conn(context): -- cgit From 0c7b62428b50ca1264c271f5db2b1c80be7a1696 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 12 Apr 2011 20:33:33 +0000 Subject: add up and down .sh --- doc/source/devref/cloudpipe.rst | 12 ++++++++++++ doc/source/down.sh | 7 +++++++ doc/source/up.sh | 7 +++++++ 3 files changed, 26 insertions(+) create mode 100644 doc/source/down.sh create mode 100644 doc/source/up.sh diff --git a/doc/source/devref/cloudpipe.rst b/doc/source/devref/cloudpipe.rst index e12d47dd7..95570aa1b 100644 --- a/doc/source/devref/cloudpipe.rst +++ b/doc/source/devref/cloudpipe.rst @@ -50,6 +50,18 @@ Making a cloudpipe image is relatively easy. :language: bash :linenos: +# set up.sh in /etc/openvpn/ + +.. literalinclude:: up.sh + :language: bash + :linenos: + +# set down.sh in /etc/openvpn/ + +.. literalinclude:: down.sh + :language: bash + :linenos: + # download and run the payload on boot from /etc/rc.local. .. literalinclude:: rc.local diff --git a/doc/source/down.sh b/doc/source/down.sh new file mode 100644 index 000000000..5c1888870 --- /dev/null +++ b/doc/source/down.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +BR=$1 +DEV=$2 + +/usr/sbin/brctl delif $BR $DEV +/sbin/ifconfig $DEV down diff --git a/doc/source/up.sh b/doc/source/up.sh new file mode 100644 index 000000000..073a58e15 --- /dev/null +++ b/doc/source/up.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +BR=$1 +DEV=$2 +MTU=$3 +/sbin/ifconfig $DEV mtu $MTU promisc up +/usr/sbin/brctl addif $BR $DEV -- cgit From acfa9d4e3ae2185a0d6d9afdddf3e8a2e7f6f398 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 12 Apr 2011 14:43:07 -0700 Subject: Make VMWare Connection inherit from ComputeDriver --- nova/virt/vmwareapi_conn.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py index 20c1b2b45..1c6d2572d 100644 --- a/nova/virt/vmwareapi_conn.py +++ b/nova/virt/vmwareapi_conn.py @@ -42,6 +42,7 @@ from nova import exception from nova import flags from nova import log as logging from nova import utils +from nova.virt import driver from nova.virt.vmwareapi import error_util from nova.virt.vmwareapi import vim from nova.virt.vmwareapi import vim_util @@ -104,11 +105,12 @@ def get_connection(_): api_retry_count) -class VMWareESXConnection(object): +class VMWareESXConnection(driver.ComputeDriver): """The ESX host connection object.""" def __init__(self, host_ip, host_username, host_password, api_retry_count, scheme="https"): + super(VMWareESXConnection, self).__init__() session = VMWareAPISession(host_ip, host_username, host_password, api_retry_count, scheme=scheme) self._vmops = VMWareVMOps(session) -- cgit From 822ec6fe3075bed4479c8e48a984bd4c9622ffe1 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Tue, 12 Apr 2011 16:46:18 -0500 Subject: move from try_execute to _execute --- nova/volume/driver.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nova/volume/driver.py b/nova/volume/driver.py index 0c4086039..6d86f193f 100644 --- a/nova/volume/driver.py +++ b/nova/volume/driver.py @@ -111,10 +111,10 @@ class VolumeDriver(object): # zero out old volumes to prevent data leaking between users # TODO(ja): reclaiming space should be done lazy and low priority - self._try_execute('sudo', 'dd', 'if=/dev/zero', - 'of=%s' % self.local_path(volume), - 'count=%d' % (volume['size'] * 1024), - 'bs=1M') + self._execute('sudo', 'dd', 'if=/dev/zero', + 'of=%s' % self.local_path(volume), + 'count=%d' % (volume['size'] * 1024), + 'bs=1M') self._try_execute('sudo', 'lvremove', '-f', "%s/%s" % (FLAGS.volume_group, volume['name'])) -- cgit From b64af9a52d9093c01d9e5df52e7ced877f6ad9a3 Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Wed, 13 Apr 2011 10:33:56 +0200 Subject: Final versioning --- nova/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/version.py b/nova/version.py index c3ecc2245..75d4d69c9 100644 --- a/nova/version.py +++ b/nova/version.py @@ -24,7 +24,7 @@ except ImportError: NOVA_VERSION = ['2011', '2'] YEAR, COUNT = NOVA_VERSION -FINAL = False # This becomes true at Release Candidate time +FINAL = True # This becomes true at Release Candidate time def canonical_version_string(): -- cgit From 899e6607086f6df9442f588aae4f3c37367e696d Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Wed, 13 Apr 2011 11:31:28 -0500 Subject: re-add broken code --- nova/volume/driver.py | 10 ++++++++-- nova/volume/san.py | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/nova/volume/driver.py b/nova/volume/driver.py index 6d86f193f..15b6b550b 100644 --- a/nova/volume/driver.py +++ b/nova/volume/driver.py @@ -93,7 +93,10 @@ class VolumeDriver(object): def create_volume(self, volume): """Creates a logical volume. Can optionally return a Dictionary of changes to the volume object to be persisted.""" - sizestr = '%sG' % volume['size'] + if int(volume['size']) == 0: + sizestr = '100M' + else: + sizestr = '%sG' % volume['size'] self._try_execute('sudo', 'lvcreate', '-L', sizestr, '-n', volume['name'], FLAGS.volume_group) @@ -599,7 +602,10 @@ class SheepdogDriver(VolumeDriver): def create_volume(self, volume): """Creates a sheepdog volume""" - sizestr = '%sG' % volume['size'] + if int(volume['size']) == 0: + sizestr = '100M' + else: + sizestr = '%sG' % volume['size'] self._try_execute('qemu-img', 'create', "sheepdog:%s" % volume['name'], sizestr) diff --git a/nova/volume/san.py b/nova/volume/san.py index dd332de1a..9532c8116 100644 --- a/nova/volume/san.py +++ b/nova/volume/san.py @@ -219,7 +219,10 @@ class SolarisISCSIDriver(SanISCSIDriver): def create_volume(self, volume): """Creates a volume.""" - sizestr = '%sG' % volume['size'] + if int(volume['size']) == 0: + sizestr = '100M' + else: + sizestr = '%sG' % volume['size'] zfs_poolname = self._build_zfs_poolname(volume) @@ -486,7 +489,10 @@ class HpSanISCSIDriver(SanISCSIDriver): #TODO(justinsb): Should we default to inheriting thinProvision? cliq_args['thinProvision'] = '1' if FLAGS.san_thin_provision else '0' cliq_args['volumeName'] = volume['name'] - cliq_args['size'] = '%sGB' % volume['size'] + if int(volume['size']) == 0: + cliq_args['size'] = '100MB' + else: + cliq_args['size'] = '%sGB' % volume['size'] self._cliq_run_xml("createVolume", cliq_args) -- cgit From 33ca304f4cd7156c6a183293521ba29bb9e2833e Mon Sep 17 00:00:00 2001 From: Naveed Massjouni Date: Wed, 13 Apr 2011 12:46:51 -0400 Subject: Changed pep8 command line option from --just-pep8 to --pep8. --- run_tests.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run_tests.sh b/run_tests.sh index 9773071c7..4f85dfe6d 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -7,7 +7,7 @@ function usage { echo " -V, --virtual-env Always use virtualenv. Install automatically if not present" echo " -N, --no-virtual-env Don't use virtualenv. Run tests in local environment" echo " -f, --force Force a clean re-build of the virtual environment. Useful when dependencies have been added." - echo " -p, --just-pep8 Just run pep8" + echo " -p, --pep8 Just run pep8" echo " -h, --help Print this usage message" echo "" echo "Note: with no options specified, the script will try to run the tests in a virtual environment," @@ -22,7 +22,7 @@ function process_option { -V|--virtual-env) let always_venv=1; let never_venv=0;; -N|--no-virtual-env) let always_venv=0; let never_venv=1;; -f|--force) let force=1;; - -p|--just-pep8) let just_pep8=1;; + -p|--pep8) let just_pep8=1;; *) noseargs="$noseargs $1" esac } -- cgit From 7206aa7af5f7d945ce9dfeff8de786bfd416ab21 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Wed, 13 Apr 2011 12:03:55 -0500 Subject: jesse@aire.local to mailmap --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index ccf2109a7..7e031fc7c 100644 --- a/.mailmap +++ b/.mailmap @@ -4,6 +4,7 @@ + -- cgit From eda350a605b5711b8373849f389e3fe472670ca0 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Wed, 13 Apr 2011 13:35:32 -0500 Subject: Don't hammer on the DB --- nova/virt/libvirt_conn.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 6ec15fbb8..94410003e 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -372,6 +372,9 @@ class LibvirtConnection(driver.ComputeDriver): instance['id'], state) if state == power_state.SHUTOFF: break + + # Let's not hammer on the DB + time.sleep(1) except Exception as ex: msg = _("Error encountered when destroying instance '%(id)s': " "%(ex)s") % {"id": instance["id"], "ex": ex} -- cgit From 3d72f59530b1c974dca498fbca44e5720547fc61 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 13 Apr 2011 11:51:03 -0700 Subject: fixed error message i18n-ization. added test. --- nova/compute/instance_types.py | 8 ++++---- nova/tests/test_instance_types.py | 10 ++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index 70b43540f..158cf1e9d 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -59,10 +59,10 @@ def create(name, memory, vcpus, local_gb, flavorid, swap=0, rxtx_quota=rxtx_quota, rxtx_cap=rxtx_cap)) except exception.DBError, e: - LOG.exception(_('DB error: %s' % e)) - raise exception.ApiError( - _("Cannot create instance_type with name %s and flavorid %s"\ - % (name, flavorid))) + LOG.exception(_('DB error: %s') % e) + raise exception.ApiError(_("Cannot create instance_type with\ + name %(name)s and flavorid %(flavorid)s") % + locals()) def destroy(name): diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index 5d6d5e1f4..ec3bc5bbf 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -88,3 +88,13 @@ class InstanceTypeTestCase(test.TestCase): """Ensures that instance type creation fails with invalid args""" self.assertRaises(exception.ApiError, instance_types.destroy, "sfsfsdfdfs") + + def test_repeated_inst_types_should_raise_api_error(self): + """Ensures that instance duplicates raises ApiError""" + new_name = self.name + "dup" + instance_types.create(new_name, 256, 1, 120, self.flavorid + 1) + instance_types.destroy(new_name) + self.assertRaises( + exception.ApiError, + instance_types.create, new_name, 256, 1, 120, self.flavorid) + \ No newline at end of file -- cgit From 6a20cba0ea3c1e9945897ec27646d74d597492d7 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 13 Apr 2011 12:01:59 -0700 Subject: pep8 --- bin/nova-manage | 3 ++- nova/tests/test_instance_types.py | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 750cd2596..8ec3a1e64 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -832,7 +832,8 @@ class InstanceTypeCommands(object): print e sys.exit(1) except exception.ApiError, e: - print "\n\nPlease ensure instance_type name and flavor id are unique." + print "\n\n" + print "Please ensure instance_type name and flavorid are unique." print "To complete remove a instance_type, use the --purge flag:" print "\n # nova-manage instance_type delete --purge\n" print "Currently defined instance_type names and flavorids:" diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index ec3bc5bbf..dd7d0737e 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -97,4 +97,3 @@ class InstanceTypeTestCase(test.TestCase): self.assertRaises( exception.ApiError, instance_types.create, new_name, 256, 1, 120, self.flavorid) - \ No newline at end of file -- cgit From db755b38609f5c94b70f88057d0b2f0f4964744e Mon Sep 17 00:00:00 2001 From: "jaypipes@gmail.com" <> Date: Wed, 13 Apr 2011 18:32:43 -0400 Subject: Rework GlanceImageService._translate_base() to not call BaseImageService._translate_base() otherwise the wrong class attributes are used in properties construction... --- nova/image/glance.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/image/glance.py b/nova/image/glance.py index bf49ca96c..1a80bb2af 100644 --- a/nova/image/glance.py +++ b/nova/image/glance.py @@ -186,7 +186,8 @@ class GlanceImageService(service.BaseImageService): """Overriding the base translation to handle conversion to datetime objects """ - image_meta = service.BaseImageService._translate_to_base(image_meta) + image_meta = service.BaseImageService._propertify_metadata( + image_meta, cls.SERVICE_IMAGE_ATTRS) image_meta = _convert_timestamps_to_datetimes(image_meta) return image_meta -- cgit From ba69d58d21a6164626835e5dd7f45f75dfca07bd Mon Sep 17 00:00:00 2001 From: Yoshiaki Tamura Date: Thu, 14 Apr 2011 21:38:55 +0900 Subject: Fix parameter mismatch calling to_xml() from spawn() in libvirt_conn.py Insert 'False' between instance and network_info. --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 94410003e..72896bb20 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -606,7 +606,7 @@ class LibvirtConnection(driver.ComputeDriver): # for xenapi(tr3buchet) @exception.wrap_exception def spawn(self, instance, network_info=None): - xml = self.to_xml(instance, network_info) + xml = self.to_xml(instance, False, network_info) db.instance_set_state(context.get_admin_context(), instance['id'], power_state.NOSTATE, -- cgit From 1b460de2f881d3cda0fd58bacedc3886020e4ca7 Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Thu, 14 Apr 2011 17:12:54 +0400 Subject: bugfix --- nova/compute/manager.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index af3551708..63d374326 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -226,15 +226,6 @@ class ComputeManager(manager.SchedulerDependentManager): self.network_manager.setup_compute_network(context, instance_id) - if FLAGS.auto_assign_floating_ip: - public_ip = rpc.call(context, - FLAGS.network_topic, - {"method": "allocate_floating_ip", - "args": {"project_id": context.project_id}}) - self.network_manager.associate_floating_ip(context, - instance_id=instance_id, - address=public_ip) - # TODO(vish) check to make sure the availability zone matches self.db.instance_set_state(context, instance_id, @@ -255,6 +246,16 @@ class ComputeManager(manager.SchedulerDependentManager): instance_id, power_state.SHUTDOWN) + if not FLAGS.stub_network: + if FLAGS.auto_assign_floating_ip: + public_ip = rpc.call(context, + FLAGS.network_topic, + {"method": "allocate_floating_ip", + "args": {"project_id": context.project_id}}) + self.network_manager.associate_floating_ip(context, + floating_address=public_ip, + fixed_address=address) + self._update_state(context, instance_id) @exception.wrap_exception -- cgit From 76e643dc0b6b8b6e2ad499034f4d4491380e91ba Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Thu, 14 Apr 2011 21:23:40 +0400 Subject: bugfix --- nova/compute/manager.py | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 63d374326..94fee36a5 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -252,9 +252,34 @@ class ComputeManager(manager.SchedulerDependentManager): FLAGS.network_topic, {"method": "allocate_floating_ip", "args": {"project_id": context.project_id}}) - self.network_manager.associate_floating_ip(context, - floating_address=public_ip, - fixed_address=address) + + fixed_ip = self.db.fixed_ip_get_by_address(context, address) + floating_ip = self.db.floating_ip_get_by_address(context, + public_ip) + # Check if the floating ip address is allocated + if floating_ip['project_id'] is None: + raise exception.Error(_("Address (%s) is not allocated") % + floating_ip['address']) + # Check if the floating ip address is allocated + # to the same project + if floating_ip['project_id'] != context.project_id: + LOG.warn(_("Address (%(address)s) is not allocated to your" + " project (%(project)s)"), + {'address': floating_ip['address'], + 'project': context.project_id}) + raise exception.Error(_("Address (%(address)s) is not " + "allocated to your project" + "(%(project)s)") % + {'address': floating_ip['address'], + 'project': context.project_id}) + + host = fixed_ip['network']['host'] + rpc.cast(context, + self.db.queue_get_for(context, + FLAGS.network_topic, host), + {"method": "associate_floating_ip", + "args": {"floating_address": floating_ip['address'], + "fixed_address": fixed_ip['address']}}) self._update_state(context, instance_id) -- cgit From e152c5d06a2ba4004b6d2a3c6517c43069d3713f Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Fri, 15 Apr 2011 11:39:08 +0200 Subject: Diablo versioning --- nova/version.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/version.py b/nova/version.py index 75d4d69c9..c43d12cf8 100644 --- a/nova/version.py +++ b/nova/version.py @@ -21,10 +21,10 @@ except ImportError: 'revision_id': 'LOCALREVISION', 'revno': 0} -NOVA_VERSION = ['2011', '2'] +NOVA_VERSION = ['2011', '3'] YEAR, COUNT = NOVA_VERSION -FINAL = True # This becomes true at Release Candidate time +FINAL = False # This becomes true at Release Candidate time def canonical_version_string(): -- cgit From b571bf6bb329e3bb085987554461c411ef56b330 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Fri, 15 Apr 2011 15:01:17 -0400 Subject: Explicitly tell a user that they need to authenticate against a version root. --- nova/api/openstack/auth.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py index 42c23785a..311e6bde9 100644 --- a/nova/api/openstack/auth.py +++ b/nova/api/openstack/auth.py @@ -87,9 +87,10 @@ class AuthMiddleware(wsgi.Middleware): # honor it path_info = req.path_info if len(path_info) > 1: - msg = _("Authentication requests must be made against /") + msg = _("Authentication requests must be made against a version " + "root (e.g. /v1.0 or /v1.1).") LOG.warn(msg) - return faults.Fault(webob.exc.HTTPUnauthorized()) + return faults.Fault(webob.exc.HTTPUnauthorized(explanation=msg)) try: username = req.headers['X-Auth-User'] -- cgit -- cgit From 7080cbe4d5d3e963dac21a51cb7e9819ec03a27b Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Fri, 15 Apr 2011 15:36:52 -0400 Subject: Added period to docstring for metadata test. --- nova/tests/integrated/test_servers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/tests/integrated/test_servers.py b/nova/tests/integrated/test_servers.py index 8175659a3..e89d0100a 100644 --- a/nova/tests/integrated/test_servers.py +++ b/nova/tests/integrated/test_servers.py @@ -135,7 +135,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): self.assertFalse(found_server) def test_create_server_with_metadata(self): - """Creates a server with metadata""" + """Creates a server with metadata.""" # Build the server data gradually, checking errors along the way server = self._build_minimal_create_server_request() -- cgit From 25d95c9f9ba0000773902186a5838fbe57a25a8c Mon Sep 17 00:00:00 2001 From: termie Date: Sat, 16 Apr 2011 20:23:06 -0700 Subject: change libvirt snapshot to new style execute --- nova/virt/libvirt_conn.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index ccfce39e4..7f25a8503 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -58,7 +58,6 @@ from nova import db from nova import exception from nova import flags from nova import log as logging -#from nova import test from nova import utils from nova import vnc from nova.auth import manager @@ -499,12 +498,17 @@ class LibvirtConnection(driver.ComputeDriver): # Export the snapshot to a raw image temp_dir = tempfile.mkdtemp() out_path = os.path.join(temp_dir, snapshot_name) - qemu_img_cmd = '%s convert -f qcow2 -O raw -s %s %s %s' % ( - FLAGS.qemu_img, - snapshot_name, - disk_path, - out_path) - utils.execute(qemu_img_cmd) + qemu_img_cmd = (FLAGS.qemu_img, + 'convert', + '-f', + 'qcow2', + '-O', + 'raw', + '-s', + snapshot_name, + disk_path, + out_path) + utils.execute(*qemu_img_cmd) # Upload that image to the image service with open(out_path) as image_file: -- cgit From dbb0ff6b7720d4715d26b470f0ee39f27b1e187c Mon Sep 17 00:00:00 2001 From: termie Date: Sat, 16 Apr 2011 20:23:06 -0700 Subject: move name into main metadata instead of properties --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 7f25a8503..d62cb5224 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -470,8 +470,8 @@ class LibvirtConnection(driver.ComputeDriver): metadata = {'disk_format': base['disk_format'], 'container_format': base['container_format'], 'is_public': False, + 'name': '%s.%s' % (base['name'], image_id), 'properties': {'architecture': base['architecture'], - 'name': '%s.%s' % (base['name'], image_id), 'kernel_id': instance['kernel_id'], 'image_location': 'snapshot', 'image_state': 'available', -- cgit From c49c372ec3e94331eb8a16a0af7c9c9c5e46bba0 Mon Sep 17 00:00:00 2001 From: Eldar Nugaev Date: Mon, 18 Apr 2011 17:06:18 +0400 Subject: Fix logging in openstack api --- nova/api/openstack/common.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py index 234f921ab..2ace9b3de 100644 --- a/nova/api/openstack/common.py +++ b/nova/api/openstack/common.py @@ -25,7 +25,7 @@ from nova import log as logging from nova import wsgi -LOG = logging.getLogger('common') +LOG = logging.getLogger('nova.api.openstack.common') FLAGS = flags.FLAGS @@ -116,8 +116,14 @@ def get_image_id_from_image_hash(image_service, context, image_hash): items = image_service.index(context) for image in items: image_id = image['id'] - if abs(hash(image_id)) == int(image_hash): - return image_id + try: + if abs(hash(image_id)) == int(image_hash): + return image_id + except ValueError: + msg = _("Requested image_id has wrong format: %s," + "should have numerical format" % image_id) + LOG.error(msg) + raise msg raise exception.NotFound(image_hash) -- cgit From a582afce13286160411a65d4b1b91e69f67ab430 Mon Sep 17 00:00:00 2001 From: Eldar Nugaev Date: Mon, 18 Apr 2011 17:31:29 +0400 Subject: Fix logging in openstack api --- nova/api/openstack/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py index 2ace9b3de..f3f7f6d9b 100644 --- a/nova/api/openstack/common.py +++ b/nova/api/openstack/common.py @@ -121,7 +121,7 @@ def get_image_id_from_image_hash(image_service, context, image_hash): return image_id except ValueError: msg = _("Requested image_id has wrong format: %s," - "should have numerical format" % image_id) + "should have numerical format") % image_id LOG.error(msg) raise msg raise exception.NotFound(image_hash) -- cgit From d1a7cf94f368e0c115bd7680512c582163f5e49e Mon Sep 17 00:00:00 2001 From: Eldar Nugaev Date: Mon, 18 Apr 2011 17:32:48 +0400 Subject: Fix logging in openstack api --- nova/api/openstack/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py index f3f7f6d9b..0b6dc944a 100644 --- a/nova/api/openstack/common.py +++ b/nova/api/openstack/common.py @@ -123,7 +123,7 @@ def get_image_id_from_image_hash(image_service, context, image_hash): msg = _("Requested image_id has wrong format: %s," "should have numerical format") % image_id LOG.error(msg) - raise msg + raise Exception(msg) raise exception.NotFound(image_hash) -- cgit From fe2d43472548f7c32a621ab4f245e078d0f46f0b Mon Sep 17 00:00:00 2001 From: Eldar Nugaev Date: Mon, 18 Apr 2011 18:13:56 +0400 Subject: add fault as response --- nova/api/openstack/servers.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 43e0c7963..4fb0f078b 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -127,8 +127,13 @@ class Controller(common.OpenstackController): key_data = key_pair['public_key'] requested_image_id = self._image_id_from_req_data(env) - image_id = common.get_image_id_from_image_hash(self._image_service, - context, requested_image_id) + try: + image_id = common.get_image_id_from_image_hash(self._image_service, + context, requested_image_id) + except: + msg = _("Can not find requested image") + return faults.Fault(exc.HTTPBadRequest(msg)) + kernel_id, ramdisk_id = self._get_kernel_ramdisk_from_image( req, image_id) -- cgit From c8ca373cfc71cf62d79ff90957961e9b0aa2ed36 Mon Sep 17 00:00:00 2001 From: Eldar Nugaev Date: Mon, 18 Apr 2011 19:36:19 +0400 Subject: pep8 fix --- nova/api/openstack/servers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 4fb0f078b..d3f51df0d 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -133,7 +133,7 @@ class Controller(common.OpenstackController): except: msg = _("Can not find requested image") return faults.Fault(exc.HTTPBadRequest(msg)) - + kernel_id, ramdisk_id = self._get_kernel_ramdisk_from_image( req, image_id) -- cgit From 73215aa7fd31e54c84220bb852f98559a63bb17d Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 18 Apr 2011 09:10:07 -0700 Subject: it is rename not move --- bin/nova-manage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nova-manage b/bin/nova-manage index adc631318..297fd8667 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -1009,7 +1009,7 @@ class ImageCommands(object): if (FLAGS.image_service == 'nova.image.local.LocalImageService' and directory == os.path.abspath(FLAGS.images_path)): new_dir = "%s_bak" % directory - os.move(directory, new_dir) + os.rename(directory, new_dir) os.mkdir(directory) directory = new_dir for fn in glob.glob("%s/*/info.json" % directory): -- cgit From 9a0d079cfe28d6d8d4e909f68541efda5ad3a3c5 Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Mon, 18 Apr 2011 21:06:29 +0400 Subject: not performing floating ip operation with auto allocated ips --- nova/compute/manager.py | 3 ++- nova/db/sqlalchemy/api.py | 2 ++ nova/db/sqlalchemy/models.py | 1 + nova/network/api.py | 6 ++++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 94fee36a5..829d59170 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -308,7 +308,8 @@ class ComputeManager(manager.SchedulerDependentManager): network_topic, {"method": "disassociate_floating_ip", "args": {"floating_address": address}}) - if FLAGS.auto_assign_floating_ip: + if FLAGS.auto_assign_floating_ip \ + and floating_ip.get('auto_assigned'): LOG.debug(_("Deallocating floating ip %s"), floating_ip['address'], context=context) rpc.cast(context, diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 28126a517..6b2caf46c 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -461,6 +461,7 @@ def floating_ip_count_by_project(context, project_id): session = get_session() return session.query(models.FloatingIp).\ filter_by(project_id=project_id).\ + filter_by(auto_assigned=False).\ filter_by(deleted=False).\ count() @@ -560,6 +561,7 @@ def floating_ip_get_all_by_project(context, project_id): return session.query(models.FloatingIp).\ options(joinedload_all('fixed_ip.instance')).\ filter_by(project_id=project_id).\ + filter_by(auto_assigned=False).\ filter_by(deleted=False).\ all() diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index f79d0f16c..36a084a1d 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -592,6 +592,7 @@ class FloatingIp(BASE, NovaBase): 'FloatingIp.deleted == False)') project_id = Column(String(255)) host = Column(String(255)) # , ForeignKey('hosts.id')) + auto_assigned = Column(Boolean, default=False, nullable=False) class ConsolePool(BASE, NovaBase): diff --git a/nova/network/api.py b/nova/network/api.py index c56e3062b..c5f76a14e 100644 --- a/nova/network/api.py +++ b/nova/network/api.py @@ -53,6 +53,8 @@ class API(base.Base): def release_floating_ip(self, context, address): floating_ip = self.db.floating_ip_get_by_address(context, address) + if floating_ip.get('auto_assigned'): + return # NOTE(vish): We don't know which network host should get the ip # when we deallocate, so just send it to any one. This # will probably need to move into a network supervisor @@ -66,6 +68,8 @@ class API(base.Base): if isinstance(fixed_ip, str) or isinstance(fixed_ip, unicode): fixed_ip = self.db.fixed_ip_get_by_address(context, fixed_ip) floating_ip = self.db.floating_ip_get_by_address(context, floating_ip) + if floating_ip.get('auto_assigned'): + return # Check if the floating ip address is allocated if floating_ip['project_id'] is None: raise exception.ApiError(_("Address (%s) is not allocated") % @@ -92,6 +96,8 @@ class API(base.Base): def disassociate_floating_ip(self, context, address): floating_ip = self.db.floating_ip_get_by_address(context, address) + if floating_ip.get('auto_assigned'): + return if not floating_ip.get('fixed_ip'): raise exception.ApiError('Address is not associated.') # NOTE(vish): Get the topic from the host name of the network of -- cgit From 841d25c1c9ab840ed39261a3bb234b981d9c337a Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Mon, 18 Apr 2011 22:02:12 +0400 Subject: pep8 fixed --- .../migrate_repo/versions/015_add_auto_assign_to_floating_ips.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py b/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py index 6829b5d6e..f3767b29f 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py @@ -33,4 +33,4 @@ def upgrade(migrate_engine): floating_ips = Table('floating_ips', meta, autoload=True, autoload_with=migrate_engine) - floating_ips.create_column(c_auto_assigned) \ No newline at end of file + floating_ips.create_column(c_auto_assigned) -- cgit From eb20dd53832577f94f5f251bd97e866435f6aeb9 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Mon, 18 Apr 2011 15:40:16 -0500 Subject: Change '== None' to 'is None' --- Authors | 1 + bin/nova-manage | 8 ++++---- nova/api/ec2/cloud.py | 4 ++-- nova/auth/manager.py | 8 ++++---- nova/compute/api.py | 2 +- nova/compute/instance_types.py | 4 ++-- nova/compute/monitor.py | 2 +- nova/image/local.py | 2 +- nova/image/s3.py | 2 +- nova/log.py | 2 +- nova/network/xenapi_net.py | 2 +- nova/tests/api/openstack/test_servers.py | 2 +- nova/tests/test_scheduler.py | 4 ++-- nova/virt/libvirt_conn.py | 4 ++-- 14 files changed, 24 insertions(+), 23 deletions(-) diff --git a/Authors b/Authors index f4b40a853..ce280749d 100644 --- a/Authors +++ b/Authors @@ -27,6 +27,7 @@ Gabe Westmaas Hisaharu Ishii Hisaki Ohara Ilya Alekseyev +Jason Koelker Jay Pipes Jesse Andrews Joe Heck diff --git a/bin/nova-manage b/bin/nova-manage index adc631318..74346cc13 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -449,7 +449,7 @@ class FixedIpCommands(object): ctxt = context.get_admin_context() try: - if host == None: + if host is None: fixed_ips = db.fixed_ip_get_all(ctxt) else: fixed_ips = db.fixed_ip_get_all_by_host(ctxt, host) @@ -499,7 +499,7 @@ class FloatingIpCommands(object): """Lists all floating ips (optionally by host) arguments: [host]""" ctxt = context.get_admin_context() - if host == None: + if host is None: floating_ips = db.floating_ip_get_all(ctxt) else: floating_ips = db.floating_ip_get_all_by_host(ctxt, host) @@ -591,7 +591,7 @@ class VmCommands(object): _('zone'), _('index')) - if host == None: + if host is None: instances = db.instance_get_all(context.get_admin_context()) else: instances = db.instance_get_all_by_host( @@ -864,7 +864,7 @@ class InstanceTypeCommands(object): """Lists all active or specific instance types / flavors arguments: [name]""" try: - if name == None: + if name is None: inst_types = instance_types.get_all_types() elif name == "--all": inst_types = instance_types.get_all_types(True) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 10b1d0ac5..bd4c9dcd4 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -442,7 +442,7 @@ class CloudController(object): group_name) criteria = self._revoke_rule_args_to_dict(context, **kwargs) - if criteria == None: + if criteria is None: raise exception.ApiError(_("Not enough parameters to build a " "valid rule.")) @@ -664,7 +664,7 @@ class CloudController(object): 'volumeId': ec2utils.id_to_ec2_id(volume_id, 'vol-%08x')} def _convert_to_set(self, lst, label): - if lst == None or lst == []: + if lst is None or lst == []: return None if not isinstance(lst, list): lst = [lst] diff --git a/nova/auth/manager.py b/nova/auth/manager.py index 486845399..8479c95a4 100644 --- a/nova/auth/manager.py +++ b/nova/auth/manager.py @@ -268,7 +268,7 @@ class AuthManager(object): LOG.debug(_('Looking up user: %r'), access_key) user = self.get_user_from_access_key(access_key) LOG.debug('user: %r', user) - if user == None: + if user is None: LOG.audit(_("Failed authorization for access key %s"), access_key) raise exception.NotFound(_('No user found for access key %s') % access_key) @@ -280,7 +280,7 @@ class AuthManager(object): project_id = user.name project = self.get_project(project_id) - if project == None: + if project is None: pjid = project_id uname = user.name LOG.audit(_("failed authorization: no project named %(pjid)s" @@ -646,9 +646,9 @@ class AuthManager(object): @rtype: User @return: The new user. """ - if access == None: + if access is None: access = str(uuid.uuid4()) - if secret == None: + if secret is None: secret = str(uuid.uuid4()) with self.driver() as drv: user_dict = drv.create_user(name, access, secret, admin) diff --git a/nova/compute/api.py b/nova/compute/api.py index e6146231c..48f8b7b0e 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -239,7 +239,7 @@ class API(base.Base): # Set sane defaults if not specified updates = dict(hostname=self.hostname_factory(instance_id)) if (not hasattr(instance, 'display_name') or - instance.display_name == None): + instance.display_name is None): updates['display_name'] = "Server %s" % instance_id instance = self.update(context, instance_id, **updates) diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index f893f8478..98b4425c8 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -61,7 +61,7 @@ def create(name, memory, vcpus, local_gb, flavorid, swap=0, def destroy(name): """Marks instance types as deleted.""" - if name == None: + if name is None: raise exception.InvalidInputException(_("No instance type specified")) else: try: @@ -73,7 +73,7 @@ def destroy(name): def purge(name): """Removes instance types from database.""" - if name == None: + if name is None: raise exception.InvalidInputException(_("No instance type specified")) else: try: diff --git a/nova/compute/monitor.py b/nova/compute/monitor.py index 04e08a235..afe5ddb1e 100644 --- a/nova/compute/monitor.py +++ b/nova/compute/monitor.py @@ -313,7 +313,7 @@ class Instance(object): LOG.debug('CPU: %d', self.cputime) # Skip calculation on first pass. Need delta to get a meaningful value. - if cputime_last_updated == None: + if cputime_last_updated is None: return None # Calculate the number of seconds between samples. diff --git a/nova/image/local.py b/nova/image/local.py index d4fd62156..fa5e93346 100644 --- a/nova/image/local.py +++ b/nova/image/local.py @@ -101,7 +101,7 @@ class LocalImageService(service.BaseImageService): if name == cantidate.get('name'): image = cantidate break - if image == None: + if image is None: raise exception.NotFound return image diff --git a/nova/image/s3.py b/nova/image/s3.py index b1034d151..2a02d4674 100644 --- a/nova/image/s3.py +++ b/nova/image/s3.py @@ -48,7 +48,7 @@ flags.DEFINE_string('image_decryption_dir', '/tmp', class S3ImageService(service.BaseImageService): """Wraps an existing image service to support s3 based register""" def __init__(self, service=None, *args, **kwargs): - if service == None: + if service is None: service = utils.import_object(FLAGS.image_service) self.service = service self.service.__init__(*args, **kwargs) diff --git a/nova/log.py b/nova/log.py index d194ab8f0..ea94be194 100644 --- a/nova/log.py +++ b/nova/log.py @@ -106,7 +106,7 @@ logging.addLevelName(AUDIT, 'AUDIT') def _dictify_context(context): - if context == None: + if context is None: return None if not isinstance(context, dict) \ and getattr(context, 'to_dict', None): diff --git a/nova/network/xenapi_net.py b/nova/network/xenapi_net.py index 9a99602d9..8c22a7d4b 100644 --- a/nova/network/xenapi_net.py +++ b/nova/network/xenapi_net.py @@ -47,7 +47,7 @@ def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None): network_ref = network_utils.NetworkHelper.find_network_with_name_label( session, bridge) - if network_ref == None: + if network_ref is None: # If bridge does not exists # 1 - create network description = "network for nova bridge %s" % bridge diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 34513734b..9d3352a1c 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -79,7 +79,7 @@ def stub_instance(id, user_id=1, private_address=None, public_addresses=None, inst_type = instance_types.get_instance_type_by_flavor_id(1) - if public_addresses == None: + if public_addresses is None: public_addresses = list() if host != None: diff --git a/nova/tests/test_scheduler.py b/nova/tests/test_scheduler.py index ae56a1a16..51d987288 100644 --- a/nova/tests/test_scheduler.py +++ b/nova/tests/test_scheduler.py @@ -737,7 +737,7 @@ class SimpleDriverTestCase(test.TestCase): ret = self.scheduler.driver._live_migration_src_check(self.context, i_ref) - self.assertTrue(ret == None) + self.assertTrue(ret is None) db.instance_destroy(self.context, instance_id) db.service_destroy(self.context, s_ref['id']) @@ -805,7 +805,7 @@ class SimpleDriverTestCase(test.TestCase): ret = self.scheduler.driver._live_migration_dest_check(self.context, i_ref, 'somewhere') - self.assertTrue(ret == None) + self.assertTrue(ret is None) db.instance_destroy(self.context, instance_id) db.service_destroy(self.context, s_ref['id']) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index ccfce39e4..a405b43fe 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1116,7 +1116,7 @@ class LibvirtConnection(driver.ComputeDriver): if child.name == 'target': devdst = child.prop('dev') - if devdst == None: + if devdst is None: continue disks.append(devdst) @@ -1158,7 +1158,7 @@ class LibvirtConnection(driver.ComputeDriver): if child.name == 'target': devdst = child.prop('dev') - if devdst == None: + if devdst is None: continue interfaces.append(devdst) -- cgit From 65ca5ba31f2c5ecea05290390ad66e65543aa83d Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Mon, 18 Apr 2011 15:49:06 -0500 Subject: pep8 fixes --- nova/api/openstack/contrib/volumes.py | 3 +-- nova/image/fake.py | 3 +-- nova/tests/api/openstack/test_image_metadata.py | 6 ++---- nova/tests/api/openstack/test_server_metadata.py | 3 +-- nova/tests/api/openstack/test_versions.py | 6 ++---- nova/virt/vmwareapi/vim.py | 1 + 6 files changed, 8 insertions(+), 14 deletions(-) diff --git a/nova/api/openstack/contrib/volumes.py b/nova/api/openstack/contrib/volumes.py index 6efacce52..18de2ec71 100644 --- a/nova/api/openstack/contrib/volumes.py +++ b/nova/api/openstack/contrib/volumes.py @@ -322,8 +322,7 @@ class Volumes(extensions.ExtensionDescriptor): # Does this matter? res = extensions.ResourceExtension('volumes', VolumeController(), - collection_actions={'detail': 'GET'} - ) + collection_actions={'detail': 'GET'}) resources.append(res) res = extensions.ResourceExtension('volume_attachments', diff --git a/nova/image/fake.py b/nova/image/fake.py index d1c62757f..e02b4127e 100644 --- a/nova/image/fake.py +++ b/nova/image/fake.py @@ -47,8 +47,7 @@ class FakeImageService(service.BaseImageService): 'container_format': 'ami', 'disk_format': 'raw', 'properties': {'kernel_id': FLAGS.null_kernel, - 'ramdisk_id': FLAGS.null_kernel} - } + 'ramdisk_id': FLAGS.null_kernel}} self.create(None, image) super(FakeImageService, self).__init__() diff --git a/nova/tests/api/openstack/test_image_metadata.py b/nova/tests/api/openstack/test_image_metadata.py index 543c59629..56be0f1cc 100644 --- a/nova/tests/api/openstack/test_image_metadata.py +++ b/nova/tests/api/openstack/test_image_metadata.py @@ -46,8 +46,7 @@ class ImageMetaDataTest(unittest.TestCase): 'deleted_at': None, 'properties': { 'key1': 'value1', - 'key2': 'value2' - }, + 'key2': 'value2'}, 'size': 5882349}, {'status': 'active', 'name': 'image2', @@ -62,8 +61,7 @@ class ImageMetaDataTest(unittest.TestCase): 'deleted_at': None, 'properties': { 'key1': 'value1', - 'key2': 'value2' - }, + 'key2': 'value2'}, 'size': 5882349}, {'status': 'active', 'name': 'image3', diff --git a/nova/tests/api/openstack/test_server_metadata.py b/nova/tests/api/openstack/test_server_metadata.py index c8d456472..680ff3e2c 100644 --- a/nova/tests/api/openstack/test_server_metadata.py +++ b/nova/tests/api/openstack/test_server_metadata.py @@ -48,8 +48,7 @@ def stub_server_metadata(): "key2": "value2", "key3": "value3", "key4": "value4", - "key5": "value5" - } + "key5": "value5"} return metadata diff --git a/nova/tests/api/openstack/test_versions.py b/nova/tests/api/openstack/test_versions.py index 2640a4ddb..fd8d50904 100644 --- a/nova/tests/api/openstack/test_versions.py +++ b/nova/tests/api/openstack/test_versions.py @@ -47,8 +47,7 @@ class VersionsTest(test.TestCase): { "rel": "self", "href": "http://localhost/v1.1", - } - ], + }], }, { "id": "v1.0", @@ -57,8 +56,7 @@ class VersionsTest(test.TestCase): { "rel": "self", "href": "http://localhost/v1.0", - } - ], + }], }, ] self.assertEqual(versions, expected) diff --git a/nova/virt/vmwareapi/vim.py b/nova/virt/vmwareapi/vim.py index 159e16a80..0cbdba363 100644 --- a/nova/virt/vmwareapi/vim.py +++ b/nova/virt/vmwareapi/vim.py @@ -43,6 +43,7 @@ flags.DEFINE_string('vmwareapi_wsdl_loc', if suds: + class VIMMessagePlugin(suds.plugin.MessagePlugin): def addAttributeForValue(self, node): -- cgit From f59f792c83c7f18e48903165df8d3dd78f45dd4c Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Mon, 18 Apr 2011 15:53:09 -0500 Subject: use 'is not None' instead of '!= None' --- nova/api/ec2/apirequest.py | 2 +- nova/auth/dbdriver.py | 2 +- nova/compute/monitor.py | 2 +- nova/db/sqlalchemy/api.py | 2 +- nova/tests/api/openstack/test_servers.py | 2 +- nova/utils.py | 2 +- nova/virt/libvirt_conn.py | 12 ++++++------ tools/esx/guest_tool.py | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/nova/api/ec2/apirequest.py b/nova/api/ec2/apirequest.py index d7ad08d2f..6672e60bb 100644 --- a/nova/api/ec2/apirequest.py +++ b/nova/api/ec2/apirequest.py @@ -196,7 +196,7 @@ class APIRequest(object): elif isinstance(data, datetime.datetime): data_el.appendChild( xml.createTextNode(_database_to_isoformat(data))) - elif data != None: + elif data is not None: data_el.appendChild(xml.createTextNode(str(data))) return data_el diff --git a/nova/auth/dbdriver.py b/nova/auth/dbdriver.py index d1e3f2ed5..b2c580d83 100644 --- a/nova/auth/dbdriver.py +++ b/nova/auth/dbdriver.py @@ -115,7 +115,7 @@ class DbDriver(object): # on to create the project. This way we won't have to destroy # the project again because a user turns out to be invalid. members = set([manager]) - if member_uids != None: + if member_uids is not None: for member_uid in member_uids: member = db.user_get(context.get_admin_context(), member_uid) if not member: diff --git a/nova/compute/monitor.py b/nova/compute/monitor.py index 04e08a235..0b1a4c13f 100644 --- a/nova/compute/monitor.py +++ b/nova/compute/monitor.py @@ -260,7 +260,7 @@ class Instance(object): try: data = self.fetch_cpu_stats() - if data != None: + if data is not None: LOG.debug('CPU: %s', data) update_rrd(self, 'cpu', data) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index e675022e9..646675a45 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1835,7 +1835,7 @@ def security_group_get_by_instance(context, instance_id): def security_group_exists(context, project_id, group_name): try: group = security_group_get_by_name(context, project_id, group_name) - return group != None + return group is not None except exception.NotFound: return False diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 34513734b..d7525fca0 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -82,7 +82,7 @@ def stub_instance(id, user_id=1, private_address=None, public_addresses=None, if public_addresses == None: public_addresses = list() - if host != None: + if host is not None: host = str(host) instance = { diff --git a/nova/utils.py b/nova/utils.py index 3f6f9fc8a..76cba1a08 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -157,7 +157,7 @@ def execute(*cmd, **kwargs): stderr=subprocess.PIPE, env=env) result = None - if process_input != None: + if process_input is not None: result = obj.communicate(process_input) else: result = obj.communicate() diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 6ec15fbb8..bf5d0c00a 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -437,9 +437,9 @@ class LibvirtConnection(driver.ComputeDriver): if child.prop('dev') == device: return str(node) finally: - if ctx != None: + if ctx is not None: ctx.xpathFreeContext() - if doc != None: + if doc is not None: doc.freeDoc() @exception.wrap_exception @@ -1119,9 +1119,9 @@ class LibvirtConnection(driver.ComputeDriver): disks.append(devdst) finally: - if ctx != None: + if ctx is not None: ctx.xpathFreeContext() - if doc != None: + if doc is not None: doc.freeDoc() return disks @@ -1161,9 +1161,9 @@ class LibvirtConnection(driver.ComputeDriver): interfaces.append(devdst) finally: - if ctx != None: + if ctx is not None: ctx.xpathFreeContext() - if doc != None: + if doc is not None: doc.freeDoc() return interfaces diff --git a/tools/esx/guest_tool.py b/tools/esx/guest_tool.py index bbf3ea908..13b0f8d33 100644 --- a/tools/esx/guest_tool.py +++ b/tools/esx/guest_tool.py @@ -209,7 +209,7 @@ def _execute(cmd_list, process_input=None, check_exit_code=True): obj = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) result = None - if process_input != None: + if process_input is not None: result = obj.communicate(process_input) else: result = obj.communicate() -- cgit From 9874e9d8ca6e81000619cefe1a408102dbf257d1 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Mon, 18 Apr 2011 15:55:48 -0500 Subject: remove zope.interface requires --- tools/pip-requires | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/pip-requires b/tools/pip-requires index 6ea446493..2f4136732 100644 --- a/tools/pip-requires +++ b/tools/pip-requires @@ -17,7 +17,6 @@ redis==2.0.0 routes==1.12.3 WebOb==0.9.8 wsgiref==0.1.2 -zope.interface==3.6.1 mox==0.5.0 -f http://pymox.googlecode.com/files/mox-0.5.0.tar.gz greenlet==0.3.1 -- cgit From d9628e8ba927074b6e80433de80d745b34acaa28 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Mon, 18 Apr 2011 17:00:39 -0500 Subject: First round of pylint cleanup. --- nova/compute/manager.py | 5 ----- nova/virt/xenapi/fake.py | 2 +- nova/virt/xenapi/vm_utils.py | 9 ++------- nova/virt/xenapi/vmops.py | 10 ++++------ 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 39d7af9c1..67d1eab5d 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -434,7 +434,6 @@ class ComputeManager(manager.SchedulerDependentManager): """Destroys the source instance""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) - migration_ref = self.db.migration_get(context, migration_id) self.driver.destroy(instance_ref) @exception.wrap_exception @@ -525,8 +524,6 @@ class ComputeManager(manager.SchedulerDependentManager): self.db.migration_update(context, migration_id, {'status': 'post-migrating', }) - service = self.db.service_get_by_host_and_topic(context, - migration_ref['dest_compute'], FLAGS.compute_topic) topic = self.db.queue_get_for(context, FLAGS.compute_topic, migration_ref['dest_compute']) rpc.cast(context, topic, @@ -652,7 +649,6 @@ class ComputeManager(manager.SchedulerDependentManager): """ context = context.elevated() - instance_ref = self.db.instance_get(context, instance_id) LOG.debug(_('instance %s: locking'), instance_id, context=context) self.db.instance_update(context, instance_id, {'locked': True}) @@ -664,7 +660,6 @@ class ComputeManager(manager.SchedulerDependentManager): """ context = context.elevated() - instance_ref = self.db.instance_get(context, instance_id) LOG.debug(_('instance %s: unlocking'), instance_id, context=context) self.db.instance_update(context, instance_id, {'locked': False}) diff --git a/nova/virt/xenapi/fake.py b/nova/virt/xenapi/fake.py index 4434dbf0b..e36ef3288 100644 --- a/nova/virt/xenapi/fake.py +++ b/nova/virt/xenapi/fake.py @@ -294,7 +294,7 @@ class Failure(Exception): def __str__(self): try: return str(self.details) - except Exception, exc: + except Exception: return "XenAPI Fake Failure: %s" % str(self.details) def _details_map(self): diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index d2045a557..1927500ad 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -28,10 +28,7 @@ import urllib import uuid from xml.dom import minidom -from eventlet import event import glance.client -from nova import context -from nova import db from nova import exception from nova import flags from nova import log as logging @@ -306,7 +303,6 @@ class VMHelper(HelperBase): % locals()) vm_vdi_ref, vm_vdi_rec = cls.get_vdi_for_vm_safely(session, vm_ref) - vm_vdi_uuid = vm_vdi_rec["uuid"] sr_ref = vm_vdi_rec["SR"] original_parent_uuid = get_vhd_parent_uuid(session, vm_vdi_ref) @@ -755,14 +751,14 @@ class VMHelper(HelperBase): session.call_xenapi('SR.scan', sr_ref) -def get_rrd(host, uuid): +def get_rrd(host, vm_uuid): """Return the VM RRD XML as a string""" try: xml = urllib.urlopen("http://%s:%s@%s/vm_rrd?uuid=%s" % ( FLAGS.xenapi_connection_username, FLAGS.xenapi_connection_password, host, - uuid)) + vm_uuid)) return xml.read() except IOError: return None @@ -1020,7 +1016,6 @@ def _stream_disk(dev, image_type, virtual_size, image_file): def _write_partition(virtual_size, dev): dest = '/dev/%s' % dev - mbr_last = MBR_SIZE_SECTORS - 1 primary_first = MBR_SIZE_SECTORS primary_last = MBR_SIZE_SECTORS + (virtual_size / SECTOR_SIZE) - 1 diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 7c7aa8e98..8b6a35f74 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -387,7 +387,6 @@ class VMOps(object): def link_disks(self, instance, base_copy_uuid, cow_uuid): """Links the base copy VHD to the COW via the XAPI plugin.""" - vm_ref = VMHelper.lookup(self._session, instance.name) new_base_copy_uuid = str(uuid.uuid4()) new_cow_uuid = str(uuid.uuid4()) params = {'instance_id': instance.id, @@ -760,7 +759,6 @@ class VMOps(object): instance))) for vm in rescue_vms: - rescue_name = vm["name"] rescue_vm_ref = vm["vm_ref"] self._destroy_rescue_instance(rescue_vm_ref) @@ -798,7 +796,7 @@ class VMOps(object): def _get_network_info(self, instance): """Creates network info list for instance.""" admin_context = context.get_admin_context() - IPs = db.fixed_ip_get_all_by_instance(admin_context, + ips = db.fixed_ip_get_all_by_instance(admin_context, instance['id']) networks = db.network_get_all_by_instance(admin_context, instance['id']) @@ -808,7 +806,7 @@ class VMOps(object): network_info = [] for network in networks: - network_IPs = [ip for ip in IPs if ip.network_id == network.id] + network_ips = [ip for ip in ips if ip.network_id == network.id] def ip_dict(ip): return { @@ -830,7 +828,7 @@ class VMOps(object): 'mac': instance.mac_address, 'rxtx_cap': inst_type['rxtx_cap'], 'dns': [network['dns']], - 'ips': [ip_dict(ip) for ip in network_IPs]} + 'ips': [ip_dict(ip) for ip in network_ips]} if network['cidr_v6']: info['ip6s'] = [ip6_dict()] if network['gateway_v6']: @@ -923,7 +921,7 @@ class VMOps(object): try: ret = self._make_xenstore_call('read_record', vm, path, {'ignore_missing_path': 'True'}) - except self.XenAPI.Failure, e: + except self.XenAPI.Failure: return None ret = json.loads(ret) if ret == "None": -- cgit From 50bd39e0413c2231ebdf9f4c9fb7e58d27624250 Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Tue, 19 Apr 2011 16:57:17 +0400 Subject: refractoring --- nova/compute/manager.py | 50 ++++++++++--------------------------------------- nova/network/api.py | 15 +++++++++------ 2 files changed, 19 insertions(+), 46 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index db97ae690..313b9e0e1 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -54,6 +54,7 @@ from nova import rpc from nova import utils from nova.compute import power_state from nova.virt import driver +from nova.network import api as network_api FLAGS = flags.FLAGS flags.DEFINE_string('instances_path', '$state_path/instances', @@ -134,6 +135,7 @@ class ComputeManager(manager.SchedulerDependentManager): self.network_manager = utils.import_object(FLAGS.network_manager) self.volume_manager = utils.import_object(FLAGS.volume_manager) + self.network_api = network_api.API() super(ComputeManager, self).__init__(service_name="compute", *args, **kwargs) @@ -248,39 +250,15 @@ class ComputeManager(manager.SchedulerDependentManager): if not FLAGS.stub_network: if FLAGS.auto_assign_floating_ip: - public_ip = rpc.call(context, - FLAGS.network_topic, - {"method": "allocate_floating_ip", - "args": {"project_id": context.project_id}}) + public_ip = self.network_api.allocate_floating_ip(context) fixed_ip = self.db.fixed_ip_get_by_address(context, address) floating_ip = self.db.floating_ip_get_by_address(context, public_ip) - # Check if the floating ip address is allocated - if floating_ip['project_id'] is None: - raise exception.Error(_("Address (%s) is not allocated") % - floating_ip['address']) - # Check if the floating ip address is allocated - # to the same project - if floating_ip['project_id'] != context.project_id: - LOG.warn(_("Address (%(address)s) is not allocated to your" - " project (%(project)s)"), - {'address': floating_ip['address'], - 'project': context.project_id}) - raise exception.Error(_("Address (%(address)s) is not " - "allocated to your project" - "(%(project)s)") % - {'address': floating_ip['address'], - 'project': context.project_id}) - - host = fixed_ip['network']['host'] - rpc.cast(context, - self.db.queue_get_for(context, - FLAGS.network_topic, host), - {"method": "associate_floating_ip", - "args": {"floating_address": floating_ip['address'], - "fixed_address": fixed_ip['address']}}) + self.network_api.associate_floating_ip(context, floating_ip, + fixed_ip, + affect_auto_assigned=True) self._update_state(context, instance_id) @exception.wrap_exception @@ -301,22 +279,14 @@ class ComputeManager(manager.SchedulerDependentManager): # NOTE(vish): Right now we don't really care if the ip is # disassociated. We may need to worry about # checking this later. - network_topic = self.db.queue_get_for(context, - FLAGS.network_topic, - floating_ip['host']) - rpc.cast(context, - network_topic, - {"method": "disassociate_floating_ip", - "args": {"floating_address": address}}) + self.network_api.disassociate_floating_ip(context, address, + affect_auto_assigned=True) if FLAGS.auto_assign_floating_ip \ and floating_ip.get('auto_assigned'): LOG.debug(_("Deallocating floating ip %s"), floating_ip['address'], context=context) - rpc.cast(context, - FLAGS.network_topic, - {"method": "deallocate_floating_ip", - "args": {"floating_address": - floating_ip['address']}}) + self.network_api.release_floating_ip(context, address, + affect_auto_assigned=True) address = fixed_ip['address'] if address: diff --git a/nova/network/api.py b/nova/network/api.py index c5f76a14e..61db646ae 100644 --- a/nova/network/api.py +++ b/nova/network/api.py @@ -51,9 +51,10 @@ class API(base.Base): {"method": "allocate_floating_ip", "args": {"project_id": context.project_id}}) - def release_floating_ip(self, context, address): + def release_floating_ip(self, context, address, + affect_auto_assigned = False): floating_ip = self.db.floating_ip_get_by_address(context, address) - if floating_ip.get('auto_assigned'): + if not affect_auto_assigned and floating_ip.get('auto_assigned'): return # NOTE(vish): We don't know which network host should get the ip # when we deallocate, so just send it to any one. This @@ -64,11 +65,12 @@ class API(base.Base): {"method": "deallocate_floating_ip", "args": {"floating_address": floating_ip['address']}}) - def associate_floating_ip(self, context, floating_ip, fixed_ip): + def associate_floating_ip(self, context, floating_ip, fixed_ip, + affect_auto_assigned = False): if isinstance(fixed_ip, str) or isinstance(fixed_ip, unicode): fixed_ip = self.db.fixed_ip_get_by_address(context, fixed_ip) floating_ip = self.db.floating_ip_get_by_address(context, floating_ip) - if floating_ip.get('auto_assigned'): + if not affect_auto_assigned and floating_ip.get('auto_assigned'): return # Check if the floating ip address is allocated if floating_ip['project_id'] is None: @@ -94,9 +96,10 @@ class API(base.Base): "args": {"floating_address": floating_ip['address'], "fixed_address": fixed_ip['address']}}) - def disassociate_floating_ip(self, context, address): + def disassociate_floating_ip(self, context, address, + affect_auto_assigned = False): floating_ip = self.db.floating_ip_get_by_address(context, address) - if floating_ip.get('auto_assigned'): + if not affect_auto_assigned and floating_ip.get('auto_assigned'): return if not floating_ip.get('fixed_ip'): raise exception.ApiError('Address is not associated.') -- cgit From 9812ae8d3c113475f8ef5d609874317d0b330425 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Tue, 19 Apr 2011 11:05:37 -0400 Subject: Removed extra calls in exception handling and standardized the way LoopingCalls are done. --- nova/virt/libvirt_conn.py | 186 ++++++++++++++++++++++++---------------------- 1 file changed, 98 insertions(+), 88 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index d212be3c9..4e96b4e97 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -154,8 +154,8 @@ def _get_net_and_prefixlen(cidr): def _get_ip_version(cidr): - net = IPy.IP(cidr) - return int(net.version()) + net = IPy.IP(cidr) + return int(net.version()) def _get_network_info(instance): @@ -359,28 +359,24 @@ class LibvirtConnection(driver.ComputeDriver): locals()) raise - # We'll save this for when we do shutdown, - # instead of destroy - but destroy returns immediately - timer = utils.LoopingCall(f=None) + def _wait_for_destroy(): + """Called at an interval until the VM is running again.""" + instance_name = insatnce['name'] - while True: try: - state = self.get_info(instance['name'])['state'] - db.instance_set_state(context.get_admin_context(), - instance['id'], state) - if state == power_state.SHUTOFF: - break - - # Let's not hammer on the DB - time.sleep(1) - except Exception as ex: - msg = _("Error encountered when destroying instance '%(id)s': " - "%(ex)s") % {"id": instance["id"], "ex": ex} - LOG.debug(msg) - db.instance_set_state(context.get_admin_context(), - instance['id'], - power_state.SHUTOFF) - break + state = self.get_info(instance_name)['state'] + except exception.NotFound: + msg = _("During destroy, %s disappeared.") % instance_name + LOG.error(msg) + raise utils.LoopingCallDone + + if state == power_state.SHUTOFF: + msg = _("Instance %s destroyed successfully.") % instance_name + LOG.debug(instance_name) + raise utils.LoopingCallDone + + timer = utils.LoopingCall(_wait_for_destroy) + timer.start(interval=0.5, now=True) self.firewall_driver.unfilter_instance(instance) @@ -522,6 +518,12 @@ class LibvirtConnection(driver.ComputeDriver): @exception.wrap_exception def reboot(self, instance): + """Reboot a virtual machine, given an instance reference. + + This method actually destroys and re-creates the domain to ensure the + reboot happens, as the guest OS cannot ignore this action. + + """ self.destroy(instance, False) xml = self.to_xml(instance) self.firewall_driver.setup_basic_filtering(instance) @@ -529,24 +531,23 @@ class LibvirtConnection(driver.ComputeDriver): self._create_new_domain(xml) self.firewall_driver.apply_instance_filter(instance) - timer = utils.LoopingCall(f=None) - def _wait_for_reboot(): + """Called at an interval until the VM is running again.""" + instance_name = insatnce['name'] + try: - state = self.get_info(instance['name'])['state'] - db.instance_set_state(context.get_admin_context(), - instance['id'], state) - if state == power_state.RUNNING: - LOG.debug(_('instance %s: rebooted'), instance['name']) - timer.stop() - except Exception, exn: - LOG.exception(_('_wait_for_reboot failed: %s'), exn) - db.instance_set_state(context.get_admin_context(), - instance['id'], - power_state.SHUTDOWN) - timer.stop() + state = self.get_info(instance_name)['state'] + except exception.NotFound: + msg = _("During reboot, %s disappeared.") % instance_name + LOG.error(msg) + raise utils.LoopingCallDone + + if state == power_state.RUNNING: + msg = _("Instance %s rebooted successfully.") % instance_name + LOG.debug(instance_name) + raise utils.LoopingCallDone - timer.f = _wait_for_reboot + timer = utils.LoopingCall(_wait_for_reboot) return timer.start(interval=0.5, now=True) @exception.wrap_exception @@ -566,7 +567,15 @@ class LibvirtConnection(driver.ComputeDriver): raise exception.ApiError("resume not supported for libvirt") @exception.wrap_exception - def rescue(self, instance, callback=None): + def rescue(self, instance): + """Loads a VM using rescue images. + + A rescue is normally performed when something goes wrong with the + primary images and data needs to be corrected/recovered. Rescuing + should not edit or over-ride the original image, only allow for + data recovery. + + """ self.destroy(instance, False) xml = self.to_xml(instance, rescue=True) @@ -576,29 +585,33 @@ class LibvirtConnection(driver.ComputeDriver): self._create_image(instance, xml, '.rescue', rescue_images) self._create_new_domain(xml) - timer = utils.LoopingCall(f=None) - def _wait_for_rescue(): + """Called at an interval until the VM is running again.""" + instance_name = instance['name'] + try: - state = self.get_info(instance['name'])['state'] - db.instance_set_state(None, instance['id'], state) - if state == power_state.RUNNING: - LOG.debug(_('instance %s: rescued'), instance['name']) - timer.stop() - except Exception, exn: - LOG.exception(_('_wait_for_rescue failed: %s'), exn) - db.instance_set_state(None, - instance['id'], - power_state.SHUTDOWN) - timer.stop() + state = self.get_info(instance_name)['state'] + except exception.NotFound: + msg = _("During reboot, %s disappeared.") % instance_name + LOG.error(msg) + raise utils.LoopingCallDone + + if state == power_state.RUNNING: + msg = _("Instance %s rescued successfully.") % instance_name + LOG.debug(instance_name) + raise utils.LoopingCallDone - timer.f = _wait_for_rescue + timer = utils.LoopingCall(_wait_for_rescue) return timer.start(interval=0.5, now=True) @exception.wrap_exception - def unrescue(self, instance, callback=None): - # NOTE(vish): Because reboot destroys and recreates an instance using - # the normal xml file, we can just call reboot here + def unrescue(self, instance): + """Reboot the VM which is being rescued back into primary images. + + Because reboot destroys and re-creates instances, unresue should + simply call reboot. + + """ self.reboot(instance) @exception.wrap_exception @@ -610,10 +623,6 @@ class LibvirtConnection(driver.ComputeDriver): @exception.wrap_exception def spawn(self, instance, network_info=None): xml = self.to_xml(instance, False, network_info) - db.instance_set_state(context.get_admin_context(), - instance['id'], - power_state.NOSTATE, - 'launching') self.firewall_driver.setup_basic_filtering(instance, network_info) self.firewall_driver.prepare_instance_filter(instance, network_info) self._create_image(instance, xml, network_info) @@ -626,25 +635,23 @@ class LibvirtConnection(driver.ComputeDriver): instance['name']) domain.setAutostart(1) - timer = utils.LoopingCall(f=None) - def _wait_for_boot(): + """Called at an interval until the VM is running.""" + instance_name = insatnce['name'] + try: - state = self.get_info(instance['name'])['state'] - db.instance_set_state(context.get_admin_context(), - instance['id'], state) - if state == power_state.RUNNING: - LOG.debug(_('instance %s: booted'), instance['name']) - timer.stop() - except: - LOG.exception(_('instance %s: failed to boot'), - instance['name']) - db.instance_set_state(context.get_admin_context(), - instance['id'], - power_state.SHUTDOWN) - timer.stop() + state = self.get_info(instance_name)['state'] + except exception.NotFound: + msg = _("During reboot, %s disappeared.") % instance_name + LOG.error(msg) + raise utils.LoopingCallDone - timer.f = _wait_for_boot + if state == power_state.RUNNING: + msg = _("Instance %s spawned successfully.") % instance_name + LOG.debug(instance_name) + raise utils.LoopingCallDone + + timer = utils.LoopingCall(_wait_for_boot) return timer.start(interval=0.5, now=True) def _flush_xen_console(self, virsh_output): @@ -1045,21 +1052,24 @@ class LibvirtConnection(driver.ComputeDriver): return xml def get_info(self, instance_name): - # NOTE(justinsb): When libvirt isn't running / can't connect, we get: - # libvir: Remote error : unable to connect to - # '/var/run/libvirt/libvirt-sock', libvirtd may need to be started: - # No such file or directory + """Retrieve information from libvirt for a specific instance name. + + If a libvirt error is encountered during lookup, we might raise a + NotFound exception or Error exception depending on how severe the + libvirt error is. + + """ try: virt_dom = self._conn.lookupByName(instance_name) - except libvirt.libvirtError as e: - errcode = e.get_error_code() - if errcode == libvirt.VIR_ERR_NO_DOMAIN: - raise exception.NotFound(_("Instance %s not found") - % instance_name) - LOG.warning(_("Error from libvirt during lookup. " - "Code=%(errcode)s Error=%(e)s") % - locals()) - raise + except libvirt.libvirtError as ex: + error_code = ex.get_error_code() + if error_code == libvirt.VIR_ERR_NO_DOMAIN: + msg = _("Instance %s not found") % instance_name + raise exception.NotFound(msg) + + msg = _("Error from libvirt while looking up %(instance_name)s: " + "[Error Code %(error_code)s] %(ex)s") % locals() + raise exception.Error(msg) (state, max_mem, mem, num_cpu, cpu_time) = virt_dom.info() return {'state': state, -- cgit From 8e98888323d4308640ab5061cdae5ccd4e3ebabf Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Tue, 19 Apr 2011 11:09:07 -0400 Subject: Pretty critical spelling error. --- nova/virt/libvirt_conn.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 4e96b4e97..fad8dd52a 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -361,7 +361,7 @@ class LibvirtConnection(driver.ComputeDriver): def _wait_for_destroy(): """Called at an interval until the VM is running again.""" - instance_name = insatnce['name'] + instance_name = instance['name'] try: state = self.get_info(instance_name)['state'] @@ -533,7 +533,7 @@ class LibvirtConnection(driver.ComputeDriver): def _wait_for_reboot(): """Called at an interval until the VM is running again.""" - instance_name = insatnce['name'] + instance_name = instance['name'] try: state = self.get_info(instance_name)['state'] @@ -637,7 +637,7 @@ class LibvirtConnection(driver.ComputeDriver): def _wait_for_boot(): """Called at an interval until the VM is running.""" - instance_name = insatnce['name'] + instance_name = instance['name'] try: state = self.get_info(instance_name)['state'] -- cgit From 3e31785d86c59dbda62e3a3ba3a1e23452e52562 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Tue, 19 Apr 2011 11:16:46 -0400 Subject: Tweak to destroy loop logic. --- nova/virt/libvirt_conn.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index fad8dd52a..53137395e 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -366,11 +366,6 @@ class LibvirtConnection(driver.ComputeDriver): try: state = self.get_info(instance_name)['state'] except exception.NotFound: - msg = _("During destroy, %s disappeared.") % instance_name - LOG.error(msg) - raise utils.LoopingCallDone - - if state == power_state.SHUTOFF: msg = _("Instance %s destroyed successfully.") % instance_name LOG.debug(instance_name) raise utils.LoopingCallDone -- cgit From ad2d97972d63f50500ec8215c7f8f04d87468060 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Tue, 19 Apr 2011 11:29:26 -0400 Subject: Fixed info messages. --- nova/virt/libvirt_conn.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 53137395e..13378bbd2 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -367,7 +367,7 @@ class LibvirtConnection(driver.ComputeDriver): state = self.get_info(instance_name)['state'] except exception.NotFound: msg = _("Instance %s destroyed successfully.") % instance_name - LOG.debug(instance_name) + LOG.info(msg) raise utils.LoopingCallDone timer = utils.LoopingCall(_wait_for_destroy) @@ -539,7 +539,7 @@ class LibvirtConnection(driver.ComputeDriver): if state == power_state.RUNNING: msg = _("Instance %s rebooted successfully.") % instance_name - LOG.debug(instance_name) + LOG.info(msg) raise utils.LoopingCallDone timer = utils.LoopingCall(_wait_for_reboot) @@ -593,7 +593,7 @@ class LibvirtConnection(driver.ComputeDriver): if state == power_state.RUNNING: msg = _("Instance %s rescued successfully.") % instance_name - LOG.debug(instance_name) + LOG.info(msg) raise utils.LoopingCallDone timer = utils.LoopingCall(_wait_for_rescue) @@ -643,7 +643,7 @@ class LibvirtConnection(driver.ComputeDriver): if state == power_state.RUNNING: msg = _("Instance %s spawned successfully.") % instance_name - LOG.debug(instance_name) + LOG.info(msg) raise utils.LoopingCallDone timer = utils.LoopingCall(_wait_for_boot) -- cgit From 25e1e2d64ad43638ad4231e6e6edd84d96e14bdb Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Tue, 19 Apr 2011 11:33:51 -0400 Subject: Merged trunk and fixed small comment. --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 13378bbd2..2582b9730 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -360,7 +360,7 @@ class LibvirtConnection(driver.ComputeDriver): raise def _wait_for_destroy(): - """Called at an interval until the VM is running again.""" + """Called at an interval until the VM is gone.""" instance_name = instance['name'] try: -- cgit From da99e8e6b143cd2051c23f14d4d46602f16f7ba3 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 19 Apr 2011 09:16:25 -0700 Subject: add instructions for setting up interfaces --- doc/source/devref/cloudpipe.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/source/devref/cloudpipe.rst b/doc/source/devref/cloudpipe.rst index 95570aa1b..a1f6c6450 100644 --- a/doc/source/devref/cloudpipe.rst +++ b/doc/source/devref/cloudpipe.rst @@ -68,6 +68,12 @@ Making a cloudpipe image is relatively easy. :language: bash :linenos: +# setup network interfaces. + +.. literalinclude:: interfaces + :language: bash + :linenos: + # register the image and set the image id in your flagfile:: --vpn_image_id=ami-xxxxxxxx -- cgit From 8b21dd6634cc32c43d0bebf3dede40b4b28c0a78 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 19 Apr 2011 09:16:45 -0700 Subject: add include file for doc interfaces --- doc/source/devref/interfaces | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 doc/source/devref/interfaces diff --git a/doc/source/devref/interfaces b/doc/source/devref/interfaces new file mode 100644 index 000000000..2aae39558 --- /dev/null +++ b/doc/source/devref/interfaces @@ -0,0 +1,18 @@ +# The loopback network interface +auto lo +iface lo inet loopback + +# The primary network interface +auto br0 +iface br0 inet dhcp + bridge_ports eth0 + bridge_fd 9 ## from the libvirt docs (forward delay time) + bridge_hello 2 ## from the libvirt docs (hello time) + bridge_maxage 12 ## from the libvirt docs (maximum message age) + bridge_stp off ## from the libvirt docs (spanning tree protocol) + +iface eth0 inet manual + up ifconfig $IFACE 0.0.0.0 up + up ip link set $IFACE promisc on + down ip link set $IFACE promisc off + down ifconfig $IFACE down -- cgit From 745351d1e2a98a98de0a5f955385a92c01110684 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 19 Apr 2011 09:19:52 -0700 Subject: Fixes cloudpipe to get the proper ip address. * Changes FLAGS.vpn_image_id to integer * Converts to str when comparing because instance['image_id'] is a str * Removes unused method from db * Converts integer_id to ami when launching * Adds docs for setting up interface in cloudpipe image --- nova/api/ec2/admin.py | 2 +- nova/api/ec2/cloud.py | 4 ++-- nova/cloudpipe/pipelib.py | 2 ++ nova/compute/manager.py | 2 +- nova/db/api.py | 5 ----- nova/db/sqlalchemy/api.py | 9 +-------- nova/flags.py | 2 +- nova/virt/libvirt_conn.py | 2 +- 8 files changed, 9 insertions(+), 19 deletions(-) diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py index 6a5609d4a..ea94d9c1f 100644 --- a/nova/api/ec2/admin.py +++ b/nova/api/ec2/admin.py @@ -266,7 +266,7 @@ class AdminController(object): def _vpn_for(self, context, project_id): """Get the VPN instance for a project ID.""" for instance in db.instance_get_all_by_project(context, project_id): - if (instance['image_id'] == FLAGS.vpn_image_id + if (instance['image_id'] == str(FLAGS.vpn_image_id) and not instance['state_description'] in ['shutting_down', 'shutdown']): return instance diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 10b1d0ac5..d9c1af072 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -703,7 +703,7 @@ class CloudController(object): instances = self.compute_api.get_all(context, **kwargs) for instance in instances: if not context.is_admin: - if instance['image_id'] == FLAGS.vpn_image_id: + if instance['image_id'] == str(FLAGS.vpn_image_id): continue i = {} instance_id = instance['id'] @@ -898,7 +898,7 @@ class CloudController(object): return image_type @staticmethod - def _image_ec2_id(image_id, image_type='ami'): + def image_ec2_id(image_id, image_type='ami'): """Returns image ec2_id using id and three letter type.""" template = image_type + '-%08x' return ec2utils.id_to_ec2_id(int(image_id), template=template) diff --git a/nova/cloudpipe/pipelib.py b/nova/cloudpipe/pipelib.py index dc6f55af2..2c8912422 100644 --- a/nova/cloudpipe/pipelib.py +++ b/nova/cloudpipe/pipelib.py @@ -37,6 +37,7 @@ from nova import utils from nova.auth import manager # TODO(eday): Eventually changes these to something not ec2-specific from nova.api.ec2 import cloud +from nova.api FLAGS = flags.FLAGS @@ -101,6 +102,7 @@ class CloudPipe(object): key_name = self.setup_key_pair(ctxt) group_name = self.setup_security_group(ctxt) + ec2_id = self.controller.image_ec2_id(FLAGS.vpn_image_id) reservation = self.controller.run_instances(ctxt, user_data=self.get_encoded_zip(project_id), max_count=1, diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 39d7af9c1..05b168e13 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -209,7 +209,7 @@ class ComputeManager(manager.SchedulerDependentManager): power_state.NOSTATE, 'networking') - is_vpn = instance_ref['image_id'] == FLAGS.vpn_image_id + is_vpn = instance_ref['image_id'] == str(FLAGS.vpn_image_id) # NOTE(vish): This could be a cast because we don't do anything # with the address currently, but I'm leaving it as # a call to ensure that network setup completes. We diff --git a/nova/db/api.py b/nova/db/api.py index 63901e94d..030d2f434 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -455,11 +455,6 @@ def instance_get_project_vpn(context, project_id): return IMPL.instance_get_project_vpn(context, project_id) -def instance_is_vpn(context, instance_id): - """True if instance is a vpn.""" - return IMPL.instance_is_vpn(context, instance_id) - - def instance_set_state(context, instance_id, state, description=None): """Set the state of an instance.""" return IMPL.instance_set_state(context, instance_id, state, description) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index e675022e9..e9450e392 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -940,7 +940,7 @@ def instance_get_project_vpn(context, project_id): options(joinedload('security_groups')).\ options(joinedload('instance_type')).\ filter_by(project_id=project_id).\ - filter_by(image_id=FLAGS.vpn_image_id).\ + filter_by(image_id=str(FLAGS.vpn_image_id)).\ filter_by(deleted=can_read_deleted(context)).\ first() @@ -979,13 +979,6 @@ def instance_get_floating_address(context, instance_id): return instance_ref.fixed_ip.floating_ips[0]['address'] -@require_admin_context -def instance_is_vpn(context, instance_id): - # TODO(vish): Move this into image code somewhere - instance_ref = instance_get(context, instance_id) - return instance_ref['image_id'] == FLAGS.vpn_image_id - - @require_admin_context def instance_set_state(context, instance_id, state, description=None): # TODO(devcamcar): Move this out of models and into driver diff --git a/nova/flags.py b/nova/flags.py index f011ab383..760bcc37d 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -316,7 +316,7 @@ DEFINE_string('null_kernel', 'nokernel', 'kernel image that indicates not to use a kernel,' ' but to use a raw disk image instead') -DEFINE_string('vpn_image_id', 'ami-cloudpipe', 'AMI for cloudpipe vpn server') +DEFINE_integer('vpn_image_id', 0, 'integer id for cloudpipe vpn server') DEFINE_string('vpn_key_suffix', '-vpn', 'Suffix to add to project name for vpn key and secgroups') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 5da091920..9c8d64446 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1837,7 +1837,7 @@ class NWFilterFirewall(FirewallDriver): """ if not network_info: network_info = _get_network_info(instance) - if instance['image_id'] == FLAGS.vpn_image_id: + if instance['image_id'] == str(FLAGS.vpn_image_id): base_filter = 'nova-vpn' else: base_filter = 'nova-base' -- cgit From 7554ab7da290565ee457b2d42730a2bff2fd7861 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 19 Apr 2011 09:31:18 -0700 Subject: remove typo --- nova/cloudpipe/pipelib.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nova/cloudpipe/pipelib.py b/nova/cloudpipe/pipelib.py index 2c8912422..f4cb53da0 100644 --- a/nova/cloudpipe/pipelib.py +++ b/nova/cloudpipe/pipelib.py @@ -37,7 +37,6 @@ from nova import utils from nova.auth import manager # TODO(eday): Eventually changes these to something not ec2-specific from nova.api.ec2 import cloud -from nova.api FLAGS = flags.FLAGS -- cgit From 2d649fa8928e9682064613f2c984f53f492efbec Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 19 Apr 2011 09:32:33 -0700 Subject: actually use the ec2_id --- nova/cloudpipe/pipelib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/cloudpipe/pipelib.py b/nova/cloudpipe/pipelib.py index f4cb53da0..7844d31e1 100644 --- a/nova/cloudpipe/pipelib.py +++ b/nova/cloudpipe/pipelib.py @@ -107,7 +107,7 @@ class CloudPipe(object): max_count=1, min_count=1, instance_type='m1.tiny', - image_id=FLAGS.vpn_image_id, + image_id=ec2_id, key_name=key_name, security_group=[group_name]) -- cgit From 3e3f8e1f09d0615e66cc1be0b656d0d8e1d69671 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Tue, 19 Apr 2011 12:36:07 -0400 Subject: Abstracted lookupByName calls to _lookup_by_name for centralized error handling. --- nova/virt/libvirt_conn.py | 53 +++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 2582b9730..c1f62c391 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -309,19 +309,10 @@ class LibvirtConnection(driver.ComputeDriver): def destroy(self, instance, cleanup=True): instance_name = instance['name'] - # TODO(justinsb): Refactor all lookupByName calls for error-handling try: - virt_dom = self._conn.lookupByName(instance_name) - except libvirt.libvirtError as e: - errcode = e.get_error_code() - if errcode == libvirt.VIR_ERR_NO_DOMAIN: - virt_dom = None - else: - LOG.warning(_("Error from libvirt during lookup of " - "%(instance_name)s. Code=%(errcode)s " - "Error=%(e)s") % - locals()) - raise + virt_dom = self._lookup_by_name(instance_name) + except exception.NotFound: + virt_dom = None # If the instance is already terminated, we're still happy # Otherwise, destroy it @@ -392,7 +383,7 @@ class LibvirtConnection(driver.ComputeDriver): @exception.wrap_exception def attach_volume(self, instance_name, device_path, mountpoint): - virt_dom = self._conn.lookupByName(instance_name) + virt_dom = self._lookup_by_name(instance_name) mount_device = mountpoint.rpartition("/")[2] if device_path.startswith('/dev/'): xml = """ @@ -436,7 +427,7 @@ class LibvirtConnection(driver.ComputeDriver): @exception.wrap_exception def detach_volume(self, instance_name, mountpoint): - virt_dom = self._conn.lookupByName(instance_name) + virt_dom = self._lookup_by_name(instance_name) mount_device = mountpoint.rpartition("/")[2] xml = self._get_disk_xml(virt_dom.XMLDesc(0), mount_device) if not xml: @@ -453,7 +444,7 @@ class LibvirtConnection(driver.ComputeDriver): """ image_service = utils.import_object(FLAGS.image_service) - virt_dom = self._conn.lookupByName(instance['name']) + virt_dom = self._lookup_by_name(instance['name']) elevated = context.get_admin_context() base = image_service.show(elevated, instance['image_id']) @@ -712,7 +703,7 @@ class LibvirtConnection(driver.ComputeDriver): raise Exception(_('Unable to find an open port')) def get_pty_for_instance(instance_name): - virt_dom = self._conn.lookupByName(instance_name) + virt_dom = self._lookup_by_name(instance_name) xml = virt_dom.XMLDesc(0) dom = minidom.parseString(xml) @@ -737,7 +728,7 @@ class LibvirtConnection(driver.ComputeDriver): @exception.wrap_exception def get_vnc_console(self, instance): def get_vnc_port_for_instance(instance_name): - virt_dom = self._conn.lookupByName(instance_name) + virt_dom = self._lookup_by_name(instance_name) xml = virt_dom.XMLDesc(0) # TODO: use etree instead of minidom dom = minidom.parseString(xml) @@ -1046,16 +1037,15 @@ class LibvirtConnection(driver.ComputeDriver): instance['name']) return xml - def get_info(self, instance_name): - """Retrieve information from libvirt for a specific instance name. + def _lookup_by_name(self, instance_name): + """Retrieve libvirt domain object given an instance name. - If a libvirt error is encountered during lookup, we might raise a - NotFound exception or Error exception depending on how severe the - libvirt error is. + All libvirt error handling should be handled in this method and + relevant nova exceptions should be raised in response. """ try: - virt_dom = self._conn.lookupByName(instance_name) + return self._conn.lookupByName(instance_name) except libvirt.libvirtError as ex: error_code = ex.get_error_code() if error_code == libvirt.VIR_ERR_NO_DOMAIN: @@ -1066,6 +1056,15 @@ class LibvirtConnection(driver.ComputeDriver): "[Error Code %(error_code)s] %(ex)s") % locals() raise exception.Error(msg) + def get_info(self, instance_name): + """Retrieve information from libvirt for a specific instance name. + + If a libvirt error is encountered during lookup, we might raise a + NotFound exception or Error exception depending on how severe the + libvirt error is. + + """ + virt_dom = self._lookup_by_name(instance_name) (state, max_mem, mem, num_cpu, cpu_time) = virt_dom.info() return {'state': state, 'max_mem': max_mem, @@ -1102,7 +1101,7 @@ class LibvirtConnection(driver.ComputeDriver): Returns a list of all block devices for this domain. """ - domain = self._conn.lookupByName(instance_name) + domain = self._lookup_by_name(instance_name) # TODO(devcamcar): Replace libxml2 with etree. xml = domain.XMLDesc(0) doc = None @@ -1144,7 +1143,7 @@ class LibvirtConnection(driver.ComputeDriver): Returns a list of all network interfaces for this instance. """ - domain = self._conn.lookupByName(instance_name) + domain = self._lookup_by_name(instance_name) # TODO(devcamcar): Replace libxml2 with etree. xml = domain.XMLDesc(0) doc = None @@ -1359,7 +1358,7 @@ class LibvirtConnection(driver.ComputeDriver): Note that this function takes an instance name, not an Instance, so that it can be called by monitor. """ - domain = self._conn.lookupByName(instance_name) + domain = self._lookup_by_name(instance_name) return domain.blockStats(disk) def interface_stats(self, instance_name, interface): @@ -1367,7 +1366,7 @@ class LibvirtConnection(driver.ComputeDriver): Note that this function takes an instance name, not an Instance, so that it can be called by monitor. """ - domain = self._conn.lookupByName(instance_name) + domain = self._lookup_by_name(instance_name) return domain.interfaceStats(interface) def get_console_pool_info(self, console_type): -- cgit From c3a45962a322086e4d7339f980bcf61ee8bd3167 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 19 Apr 2011 09:38:01 -0700 Subject: rename all versions of image_ec2_id --- nova/api/ec2/cloud.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index d9c1af072..c48ec9004 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -159,7 +159,7 @@ class CloudController(object): floating_ip = db.instance_get_floating_address(ctxt, instance_ref['id']) ec2_id = ec2utils.id_to_ec2_id(instance_ref['id']) - image_ec2_id = self._image_ec2_id(instance_ref['image_id'], 'ami') + image_ec2_id = self.image_ec2_id(instance_ref['image_id']) data = { 'user-data': base64.b64decode(instance_ref['user_data']), 'meta-data': { @@ -188,8 +188,8 @@ class CloudController(object): for image_type in ['kernel', 'ramdisk']: if '%s_id' % image_type in instance_ref: - ec2_id = self._image_ec2_id(instance_ref['%s_id' % image_type], - self._image_type(image_type)) + ec2_id = self.image_ec2_id(instance_ref['%s_id' % image_type], + self._image_type(image_type)) data['meta-data']['%s-id' % image_type] = ec2_id if False: # TODO(vish): store ancestor ids @@ -709,7 +709,7 @@ class CloudController(object): instance_id = instance['id'] ec2_id = ec2utils.id_to_ec2_id(instance_id) i['instanceId'] = ec2_id - i['imageId'] = self._image_ec2_id(instance['image_id']) + i['imageId'] = self.image_ec2_id(instance['image_id']) i['instanceState'] = { 'code': instance['state'], 'name': instance['state_description']} @@ -917,15 +917,15 @@ class CloudController(object): """Convert from format defined by BaseImageService to S3 format.""" i = {} image_type = self._image_type(image.get('container_format')) - ec2_id = self._image_ec2_id(image.get('id'), image_type) + ec2_id = self.image_ec2_id(image.get('id'), image_type) name = image.get('name') i['imageId'] = ec2_id kernel_id = image['properties'].get('kernel_id') if kernel_id: - i['kernelId'] = self._image_ec2_id(kernel_id, 'aki') + i['kernelId'] = self.image_ec2_id(kernel_id, 'aki') ramdisk_id = image['properties'].get('ramdisk_id') if ramdisk_id: - i['ramdiskId'] = self._image_ec2_id(ramdisk_id, 'ari') + i['ramdiskId'] = self.image_ec2_id(ramdisk_id, 'ari') i['imageOwnerId'] = image['properties'].get('owner_id') if name: i['imageLocation'] = "%s (%s)" % (image['properties']. @@ -976,8 +976,8 @@ class CloudController(object): metadata = {'properties': {'image_location': image_location}} image = self.image_service.create(context, metadata) image_type = self._image_type(image.get('container_format')) - image_id = self._image_ec2_id(image['id'], - image_type) + image_id = self.image_ec2_id(image['id'], + image_type) msg = _("Registered image %(image_location)s with" " id %(image_id)s") % locals() LOG.audit(msg, context=context) -- cgit From 4442d8f7017868f64eacc6d8ad94620263b9a9c9 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 19 Apr 2011 10:20:56 -0700 Subject: make geninter.sh use the right tmpl file --- nova/CA/geninter.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/CA/geninter.sh b/nova/CA/geninter.sh index 4b7f5a55c..9b3ea3b76 100755 --- a/nova/CA/geninter.sh +++ b/nova/CA/geninter.sh @@ -21,7 +21,7 @@ NAME=$1 SUBJ=$2 mkdir -p projects/$NAME cd projects/$NAME -cp ../../openssl.cnf.tmpl openssl.cnf +cp "$(dirname $0)/openssl.cnf.tmpl" openssl.cnf sed -i -e s/%USERNAME%/$NAME/g openssl.cnf mkdir -p certs crl newcerts private openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 365 -config ./openssl.cnf -batch -nodes -- cgit From ccf9b2ccb41b1e7f946f2b2c21e6f8fbc9bd04e8 Mon Sep 17 00:00:00 2001 From: Eldar Nugaev Date: Tue, 19 Apr 2011 21:25:53 +0400 Subject: fix logging in reboot OpenStack API --- nova/api/openstack/servers.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index f221229f0..e9f570213 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -40,7 +40,7 @@ import nova.api.openstack from nova.scheduler import api as scheduler_api -LOG = logging.getLogger('server') +LOG = logging.getLogger('nova.api.openstack.servers') FLAGS = flags.FLAGS @@ -331,6 +331,7 @@ class Controller(common.OpenstackController): return exc.HTTPAccepted() def _action_rebuild(self, input_dict, req, id): + LOG.debug(_("Rebuild server action is not implemented")) return faults.Fault(exc.HTTPNotImplemented()) def _action_resize(self, input_dict, req, id): @@ -346,18 +347,20 @@ class Controller(common.OpenstackController): except Exception, e: LOG.exception(_("Error in resize %s"), e) return faults.Fault(exc.HTTPBadRequest()) - return faults.Fault(exc.HTTPAccepted()) + return exc.HTTPAccepted() def _action_reboot(self, input_dict, req, id): - try: + if 'reboot' in input_dict and 'type' in input_dict['reboot']: reboot_type = input_dict['reboot']['type'] - except Exception: - raise faults.Fault(exc.HTTPNotImplemented()) + else: + LOG.exception(_("Missing argument 'type' for reboot")) + return faults.Fault(exc.HTTPUnprocessableEntity()) try: # TODO(gundlach): pass reboot_type, support soft reboot in # virt driver self.compute_api.reboot(req.environ['nova.context'], id) - except: + except Exception, e: + LOG.exception(_("Error in reboot %s"), e) return faults.Fault(exc.HTTPUnprocessableEntity()) return exc.HTTPAccepted() -- cgit From 66a15373a14e9acc30808d2cf21bd800c64cc012 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 19 Apr 2011 10:31:35 -0700 Subject: fix doc typo --- doc/source/devref/cloudpipe.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/devref/cloudpipe.rst b/doc/source/devref/cloudpipe.rst index a1f6c6450..15d3160b7 100644 --- a/doc/source/devref/cloudpipe.rst +++ b/doc/source/devref/cloudpipe.rst @@ -62,13 +62,13 @@ Making a cloudpipe image is relatively easy. :language: bash :linenos: -# download and run the payload on boot from /etc/rc.local. +# download and run the payload on boot from /etc/rc.local .. literalinclude:: rc.local :language: bash :linenos: -# setup network interfaces. +# setup /etc/network/interfaces .. literalinclude:: interfaces :language: bash -- cgit From 0465f9249c0bcca27ad04bf8326bada2449e96c9 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 19 Apr 2011 13:29:16 -0500 Subject: Review feedback. --- nova/compute/manager.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 67d1eab5d..c795d72ad 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -524,6 +524,9 @@ class ComputeManager(manager.SchedulerDependentManager): self.db.migration_update(context, migration_id, {'status': 'post-migrating', }) + # Make sure the service exists before sending a message. + _service = self.db.service_get_by_host_and_topic(context, + migration_ref['dest_compute'], FLAGS.compute_topic) topic = self.db.queue_get_for(context, FLAGS.compute_topic, migration_ref['dest_compute']) rpc.cast(context, topic, -- cgit From a474310be8ed4d7a9840412779567abef71406f1 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Tue, 19 Apr 2011 17:24:01 -0400 Subject: Create a dictionary of instance_types before executing SQL updates in the instance_type_id migration (014). This should resolve a "cannot commit transaction - SQL statements in progress" error with some versions of sqlite. --- .../migrate_repo/versions/014_add_instance_type_id_to_instances.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/014_add_instance_type_id_to_instances.py b/nova/db/sqlalchemy/migrate_repo/versions/014_add_instance_type_id_to_instances.py index b12a0a801..334d1f255 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/014_add_instance_type_id_to_instances.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/014_add_instance_type_id_to_instances.py @@ -54,10 +54,12 @@ def upgrade(migrate_engine): instances.create_column(c_instance_type_id) + type_names = {} recs = migrate_engine.execute(instance_types.select()) for row in recs: - type_id = row[0] - type_name = row[1] + type_names[row[0]] = row[1] + + for type_id, type_name in type_names.iteritems(): migrate_engine.execute(instances.update()\ .where(instances.c.instance_type == type_name)\ .values(instance_type_id=type_id)) -- cgit From 63f5aa5484aa9d61f2ed79caae1c665230a56f35 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Tue, 19 Apr 2011 15:25:39 -0700 Subject: revamped spacing per Rick Harris suggestion. Added exact error to nova-manage output. --- bin/nova-manage | 1 + nova/compute/instance_types.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 8ec3a1e64..6b47cc4f5 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -833,6 +833,7 @@ class InstanceTypeCommands(object): sys.exit(1) except exception.ApiError, e: print "\n\n" + print "\n%s" % e print "Please ensure instance_type name and flavorid are unique." print "To complete remove a instance_type, use the --purge flag:" print "\n # nova-manage instance_type delete --purge\n" diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index a92e5d3bc..6accf82bb 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -56,8 +56,8 @@ def create(name, memory, vcpus, local_gb, flavorid, swap=0, rxtx_cap=rxtx_cap)) except exception.DBError, e: LOG.exception(_('DB error: %s') % e) - raise exception.ApiError(_("Cannot create instance_type with\ - name %(name)s and flavorid %(flavorid)s") % + raise exception.ApiError(_("Cannot create instance_type with " + "name %(name)s and flavorid %(flavorid)s") % locals()) -- cgit From d992fbbde7c8e5274d80e2fce9c840e7209c78c6 Mon Sep 17 00:00:00 2001 From: Jimmy Bergman Date: Wed, 20 Apr 2011 14:06:23 +0200 Subject: Change response format of CreateVolume to match EC2 --- nova/api/ec2/cloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index bd4c9dcd4..2bbe4c368 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -613,7 +613,7 @@ class CloudController(object): # TODO(vish): Instance should be None at db layer instead of # trying to lazy load, but for now we turn it into # a dict to avoid an error. - return {'volumeSet': [self._format_volume(context, dict(volume))]} + return self._format_volume(context, dict(volume)) def delete_volume(self, context, volume_id, **kwargs): volume_id = ec2utils.ec2_id_to_id(volume_id) -- cgit From 19aaf2523b1f157b5f9cad0d625857e98c19002b Mon Sep 17 00:00:00 2001 From: Jimmy Bergman Date: Wed, 20 Apr 2011 14:12:47 +0200 Subject: Add to Authors --- Authors | 1 + 1 file changed, 1 insertion(+) diff --git a/Authors b/Authors index ce280749d..c440d3c11 100644 --- a/Authors +++ b/Authors @@ -30,6 +30,7 @@ Ilya Alekseyev Jason Koelker Jay Pipes Jesse Andrews +Jimmy Bergman Joe Heck Joel Moore Johannes Erdfelt -- cgit From 45178fd6da58ff37617e35b5cddaf416ae5cee65 Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Wed, 20 Apr 2011 17:44:25 +0400 Subject: fix: mark floating ip as auto assigned --- nova/compute/manager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 313b9e0e1..c1dc06557 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -252,6 +252,7 @@ class ComputeManager(manager.SchedulerDependentManager): if FLAGS.auto_assign_floating_ip: public_ip = self.network_api.allocate_floating_ip(context) + self.db.floating_ip_set_auto_assigned(context, public_ip) fixed_ip = self.db.fixed_ip_get_by_address(context, address) floating_ip = self.db.floating_ip_get_by_address(context, public_ip) -- cgit From 803d246c35256e0578837226b1a91003e451ab6f Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Wed, 20 Apr 2011 18:35:07 +0400 Subject: instance type get approach changed. tests fixed --- nova/tests/test_virt.py | 4 ++-- nova/virt/libvirt_conn.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 5c8705a1c..0a0c7a958 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -619,7 +619,7 @@ class IptablesFirewallTestCase(test.TestCase): {'user_id': 'fake', 'project_id': 'fake', 'mac_address': '56:12:12:12:12:12', - 'instance_type': 'm1.small'}) + 'instance_type_id': 1}) ip = '10.11.12.13' network_ref = db.project_get_network(self.context, @@ -843,7 +843,7 @@ class NWFilterTestCase(test.TestCase): {'user_id': 'fake', 'project_id': 'fake', 'mac_address': '00:A0:C9:14:C8:29', - 'instance_type': 'm1.small'}) + 'instance_type_id': 1}) inst_id = instance_ref['id'] ip = '10.11.12.13' diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index c12b6e91e..d5a88ebed 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -167,8 +167,8 @@ def _get_network_info(instance): instance['id']) networks = db.network_get_all_by_instance(admin_context, instance['id']) - flavor = db.instance_type_get_by_name(admin_context, - instance['instance_type']) + flavor = db.instance_type_get_by_id(admin_context, + instance['instance_type_id']) network_info = [] for network in networks: -- cgit From 48936f6b8f063cf71fa42b4586d8ba524ed39cc4 Mon Sep 17 00:00:00 2001 From: Eldar Nugaev Date: Wed, 20 Apr 2011 20:37:51 +0400 Subject: fix Request.get_content_type --- nova/api/openstack/servers.py | 67 +++++++++++------------------ nova/tests/api/openstack/test_extensions.py | 1 + nova/tests/api/openstack/test_servers.py | 4 ++ nova/tests/api/test_wsgi.py | 7 +++ nova/wsgi.py | 20 ++++++--- 5 files changed, 52 insertions(+), 47 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 22a9c632c..e0681e597 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -294,61 +294,47 @@ class Controller(common.OpenstackController): 'revertResize': self._action_revert_resize, 'rebuild': self._action_rebuild, } - input_dict = self._deserialize(req.body, req.get_content_type()) for key in actions.keys(): if key in input_dict: - return actions[key](input_dict, req, id) + try: + context = req.environ['nova.context'] + return actions[key](context, input_dict, id) + except Exception, e: + LOG.exception(_("Error in action %(key)s: %(e)s") % + locals()) + return faults.Fault(exc.HTTPBadRequest()) return faults.Fault(exc.HTTPNotImplemented()) - def _action_change_password(self, input_dict, req, id): + def _action_change_password(self, context, input_dict, id): return exc.HTTPNotImplemented() - def _action_confirm_resize(self, input_dict, req, id): - try: - self.compute_api.confirm_resize(req.environ['nova.context'], id) - except Exception, e: - LOG.exception(_("Error in confirm-resize %s"), e) - return faults.Fault(exc.HTTPBadRequest()) + def _action_confirm_resize(self, context, input_dict, id): + self.compute_api.confirm_resize(context, id) return exc.HTTPNoContent() - def _action_revert_resize(self, input_dict, req, id): - try: - self.compute_api.revert_resize(req.environ['nova.context'], id) - except Exception, e: - LOG.exception(_("Error in revert-resize %s"), e) - return faults.Fault(exc.HTTPBadRequest()) + def _action_revert_resize(self, context, input_dict, id): + self.compute_api.revert_resize(context, id) return exc.HTTPAccepted() - def _action_rebuild(self, input_dict, req, id): + def _action_rebuild(self, context, input_dict, id): return faults.Fault(exc.HTTPNotImplemented()) - def _action_resize(self, input_dict, req, id): + def _action_resize(self, context, input_dict, id): """ Resizes a given instance to the flavor size requested """ - try: - if 'resize' in input_dict and 'flavorId' in input_dict['resize']: - flavor_id = input_dict['resize']['flavorId'] - self.compute_api.resize(req.environ['nova.context'], id, - flavor_id) - else: - LOG.exception(_("Missing arguments for resize")) - return faults.Fault(exc.HTTPUnprocessableEntity()) - except Exception, e: - LOG.exception(_("Error in resize %s"), e) - return faults.Fault(exc.HTTPBadRequest()) + if 'resize' in input_dict and 'flavorId' in input_dict['resize']: + flavor_id = input_dict['resize']['flavorId'] + self.compute_api.resize(context, id, flavor_id) + else: + LOG.exception(_("Missing arguments for resize")) + return faults.Fault(exc.HTTPUnprocessableEntity()) return faults.Fault(exc.HTTPAccepted()) - def _action_reboot(self, input_dict, req, id): - try: - reboot_type = input_dict['reboot']['type'] - except Exception: - raise faults.Fault(exc.HTTPNotImplemented()) - try: - # TODO(gundlach): pass reboot_type, support soft reboot in - # virt driver - self.compute_api.reboot(req.environ['nova.context'], id) - except: - return faults.Fault(exc.HTTPUnprocessableEntity()) + def _action_reboot(self, context, input_dict, id): + reboot_type = input_dict['reboot']['type'] + # TODO(gundlach): pass reboot_type, support soft reboot in + # virt driver + self.compute_api.reboot(context, id) return exc.HTTPAccepted() @scheduler_api.redirect_handler @@ -632,8 +618,7 @@ class ControllerV11(Controller): def _get_addresses_view_builder(self, req): return nova.api.openstack.views.addresses.ViewBuilderV11(req) - def _action_change_password(self, input_dict, req, id): - context = req.environ['nova.context'] + def _action_change_password(self, context, input_dict, id): if (not 'changePassword' in input_dict or not 'adminPass' in input_dict['changePassword']): msg = _("No adminPass was specified") diff --git a/nova/tests/api/openstack/test_extensions.py b/nova/tests/api/openstack/test_extensions.py index 481d34ed1..6453e96c9 100644 --- a/nova/tests/api/openstack/test_extensions.py +++ b/nova/tests/api/openstack/test_extensions.py @@ -158,6 +158,7 @@ class ActionExtensionTest(unittest.TestCase): request.method = 'POST' request.content_type = 'application/json' request.body = json.dumps(body) + request.environ = {'nova.context': 'context'} response = request.get_response(ext_midware) return response diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 556046e9d..a92da52b1 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -952,6 +952,7 @@ class ServersTest(test.TestCase): req.method = 'POST' req.content_type = 'application/json' req.body = json.dumps(body) + req.environ = {"nova.context": "context"} res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 501) @@ -973,6 +974,7 @@ class ServersTest(test.TestCase): req.method = 'POST' req.content_type = 'application/json' req.body = json.dumps(body) + req.environ = {"nova.context": "context"} res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 202) self.assertEqual(mock_method.instance_id, '1') @@ -993,6 +995,7 @@ class ServersTest(test.TestCase): req.method = 'POST' req.content_type = 'application/json' req.body = json.dumps(body) + req.environ = {"nova.context": "context"} res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 400) @@ -1002,6 +1005,7 @@ class ServersTest(test.TestCase): req.method = 'POST' req.content_type = 'application/json' req.body = json.dumps(body) + req.environ = {"nova.context": "context"} res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 400) diff --git a/nova/tests/api/test_wsgi.py b/nova/tests/api/test_wsgi.py index 1ecdd1cfb..ed96aac5e 100644 --- a/nova/tests/api/test_wsgi.py +++ b/nova/tests/api/test_wsgi.py @@ -136,6 +136,13 @@ class RequestTest(test.TestCase): request.body = "asdf
" self.assertRaises(webob.exc.HTTPBadRequest, request.get_content_type) + def test_request_content_type_with_charset(self): + request = wsgi.Request.blank('/tests/123') + request.headers["Content-Type"] = "application/json; charset=UTF-8" + request.body = "" + result = request.get_content_type() + self.assertEqual(result, "application/json") + def test_content_type_from_accept_xml(self): request = wsgi.Request.blank('/tests/123') request.headers["Accept"] = "application/xml" diff --git a/nova/wsgi.py b/nova/wsgi.py index de2e0749f..617830c22 100644 --- a/nova/wsgi.py +++ b/nova/wsgi.py @@ -28,6 +28,7 @@ from xml.dom import minidom import eventlet import eventlet.wsgi eventlet.patcher.monkey_patch(all=False, socket=True, time=True) +import re import routes import routes.middleware import webob @@ -105,12 +106,19 @@ class Request(webob.Request): return bm or "application/json" def get_content_type(self): - try: - ct = self.headers["Content-Type"] - assert ct in ("application/xml", "application/json") - return ct - except Exception: - raise webob.exc.HTTPBadRequest("Invalid content type") + allowed_types = ("application/xml", "application/json") + if not "Content-Type" in self.headers: + msg = _("Missing Content-Type") + LOG.debug(msg) + raise webob.exc.HTTPBadRequest(msg) + content_type = self.headers["Content-Type"] + match = re.search("([\w/]+)", content_type) + if match: + type = match.group(0) + if type in allowed_types: + return type + LOG.debug(_("Wrong Content-Type: %s") % content_type) + raise webob.exc.HTTPBadRequest("Invalid content type") class Application(object): -- cgit From 155635faf20d4a1996639baf5d2c10b05734c3df Mon Sep 17 00:00:00 2001 From: Eldar Nugaev Date: Wed, 20 Apr 2011 21:50:03 +0400 Subject: replaced regex to webob.Request.content_type --- nova/wsgi.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/nova/wsgi.py b/nova/wsgi.py index 617830c22..9e0f80565 100644 --- a/nova/wsgi.py +++ b/nova/wsgi.py @@ -28,7 +28,6 @@ from xml.dom import minidom import eventlet import eventlet.wsgi eventlet.patcher.monkey_patch(all=False, socket=True, time=True) -import re import routes import routes.middleware import webob @@ -111,13 +110,10 @@ class Request(webob.Request): msg = _("Missing Content-Type") LOG.debug(msg) raise webob.exc.HTTPBadRequest(msg) - content_type = self.headers["Content-Type"] - match = re.search("([\w/]+)", content_type) - if match: - type = match.group(0) - if type in allowed_types: - return type - LOG.debug(_("Wrong Content-Type: %s") % content_type) + type = self.content_type + if type in allowed_types: + return type + LOG.debug(_("Wrong Content-Type: %s") % type) raise webob.exc.HTTPBadRequest("Invalid content type") -- cgit From 584cde68aa36c35c03c29eb4bb09ede5f8c4074e Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Wed, 20 Apr 2011 12:50:23 -0500 Subject: Pylinted nova-manage --- bin/nova-manage | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index b2308bc03..2c06767f1 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -58,7 +58,6 @@ import gettext import glob import json import os -import re import sys import time @@ -66,11 +65,11 @@ import IPy # 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]), +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) +if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'nova', '__init__.py')): + sys.path.insert(0, POSSIBLE_TOPDIR) gettext.install('nova', unicode=1) @@ -809,11 +808,11 @@ class VolumeCommands(object): class InstanceTypeCommands(object): """Class for managing instance types / flavors.""" - def _print_instance_types(self, n, val): + def _print_instance_types(self, name, val): deleted = ('', ', inactive')[val["deleted"] == 1] print ("%s: Memory: %sMB, VCPUS: %s, Storage: %sGB, FlavorID: %s, " "Swap: %sGB, RXTX Quota: %sGB, RXTX Cap: %sMB%s") % ( - n, val["memory_mb"], val["vcpus"], val["local_gb"], + name, val["memory_mb"], val["vcpus"], val["local_gb"], val["flavorid"], val["swap"], val["rxtx_quota"], val["rxtx_cap"], deleted) @@ -1021,7 +1020,7 @@ class ImageCommands(object): machine_images[image_path] = image_metadata else: other_images[image_path] = image_metadata - except Exception as exc: + except Exception: print _("Failed to load %(fn)s.") % locals() # NOTE(vish): do kernels and ramdisks first so images self._convert_images(other_images) -- cgit From 8b2ac745211a567b7c05e31343ada3ef4be85eb4 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Wed, 20 Apr 2011 12:56:44 -0500 Subject: Pylinted nova-compute. --- bin/nova-compute | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/nova-compute b/bin/nova-compute index 95fa393b1..cd7c78def 100755 --- a/bin/nova-compute +++ b/bin/nova-compute @@ -28,11 +28,11 @@ 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]), +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) +if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'nova', '__init__.py')): + sys.path.insert(0, POSSIBLE_TOPDIR) gettext.install('nova', unicode=1) -- cgit From fe23f71687e09248feb7542ea97001a496697742 Mon Sep 17 00:00:00 2001 From: Eldar Nugaev Date: Wed, 20 Apr 2011 22:01:14 +0400 Subject: remove ambiguity in test --- nova/tests/api/test_wsgi.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nova/tests/api/test_wsgi.py b/nova/tests/api/test_wsgi.py index ed96aac5e..5820ecdc2 100644 --- a/nova/tests/api/test_wsgi.py +++ b/nova/tests/api/test_wsgi.py @@ -139,7 +139,6 @@ class RequestTest(test.TestCase): def test_request_content_type_with_charset(self): request = wsgi.Request.blank('/tests/123') request.headers["Content-Type"] = "application/json; charset=UTF-8" - request.body = "" result = request.get_content_type() self.assertEqual(result, "application/json") -- cgit From f4cfb9f0e654f26664345a041a62fd93613ef83b Mon Sep 17 00:00:00 2001 From: termie Date: Wed, 20 Apr 2011 11:52:17 -0700 Subject: docstring cleanup compute manager --- nova/compute/manager.py | 236 +++++++++++++++++++++--------------------------- 1 file changed, 105 insertions(+), 131 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index c795d72ad..8103ed61e 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -17,8 +17,7 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Handles all processes relating to instances (guest vms). +"""Handles all processes relating to instances (guest vms). The :py:class:`ComputeManager` class is a :py:class:`nova.manager.Manager` that handles RPC calls relating to creating instances. It is responsible for @@ -33,6 +32,7 @@ terminating it. by :func:`nova.utils.import_object` :volume_manager: Name of class that handles persistent storage, loaded by :func:`nova.utils.import_object` + """ import datetime @@ -55,6 +55,7 @@ from nova import utils from nova.compute import power_state from nova.virt import driver + FLAGS = flags.FLAGS flags.DEFINE_string('instances_path', '$state_path/instances', 'where instances are stored on disk') @@ -74,19 +75,14 @@ flags.DEFINE_integer("rescue_timeout", 0, "Automatically unrescue an instance after N seconds." " Set to 0 to disable.") + LOG = logging.getLogger('nova.compute.manager') def checks_instance_lock(function): - """ - decorator used for preventing action against locked instances - unless, of course, you happen to be admin - - """ - + """Decorator to prevent action against locked instances for non-admins.""" @functools.wraps(function) def decorated_function(self, context, instance_id, *args, **kwargs): - LOG.info(_("check_instance_lock: decorating: |%s|"), function, context=context) LOG.info(_("check_instance_lock: arguments: |%(self)s| |%(context)s|" @@ -112,7 +108,6 @@ def checks_instance_lock(function): class ComputeManager(manager.SchedulerDependentManager): - """Manages the running instances from creation to destruction.""" def __init__(self, compute_driver=None, *args, **kwargs): @@ -136,9 +131,7 @@ class ComputeManager(manager.SchedulerDependentManager): *args, **kwargs) def init_host(self): - """Do any initialization that needs to be run if this is a - standalone service. - """ + """Initialization for a standalone compute service.""" self.driver.init_host(host=self.host) def _update_state(self, context, instance_id): @@ -153,16 +146,18 @@ class ComputeManager(manager.SchedulerDependentManager): self.db.instance_set_state(context, instance_id, state) def get_console_topic(self, context, **kwargs): - """Retrieves the console host for a project on this host - Currently this is just set in the flags for each compute - host.""" + """Retrieves the console host for a project on this host. + + Currently this is just set in the flags for each compute host. + + """ #TODO(mdragon): perhaps make this variable by console_type? return self.db.queue_get_for(context, FLAGS.console_topic, FLAGS.console_host) def get_network_topic(self, context, **kwargs): - """Retrieves the network host for a project on this host""" + """Retrieves the network host for a project on this host.""" # TODO(vish): This method should be memoized. This will make # the call to get_network_host cheaper, so that # it can pas messages instead of checking the db @@ -179,15 +174,23 @@ class ComputeManager(manager.SchedulerDependentManager): return self.driver.get_console_pool_info(console_type) @exception.wrap_exception - def refresh_security_group_rules(self, context, - security_group_id, **kwargs): - """This call passes straight through to the virtualization driver.""" + def refresh_security_group_rules(self, context, security_group_id, + **kwargs): + """Tell the virtualization driver to refresh security group rules. + + Passes straight through to the virtualization driver. + + """ return self.driver.refresh_security_group_rules(security_group_id) @exception.wrap_exception def refresh_security_group_members(self, context, security_group_id, **kwargs): - """This call passes straight through to the virtualization driver.""" + """Tell the virtualization driver to refresh security group members. + + Passes straight through to the virtualization driver. + + """ return self.driver.refresh_security_group_members(security_group_id) @exception.wrap_exception @@ -249,7 +252,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock def terminate_instance(self, context, instance_id): - """Terminate an instance on this machine.""" + """Terminate an instance on this host.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) LOG.audit(_("Terminating instance %s"), instance_id, context=context) @@ -297,7 +300,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock def reboot_instance(self, context, instance_id): - """Reboot an instance on this server.""" + """Reboot an instance on this host.""" context = context.elevated() self._update_state(context, instance_id) instance_ref = self.db.instance_get(context, instance_id) @@ -321,7 +324,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception def snapshot_instance(self, context, instance_id, image_id): - """Snapshot an instance on this server.""" + """Snapshot an instance on this host.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) @@ -344,7 +347,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock def set_admin_password(self, context, instance_id, new_pass=None): - """Set the root/admin password for an instance on this server.""" + """Set the root/admin password for an instance on this host.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) instance_id = instance_ref['id'] @@ -365,7 +368,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock def inject_file(self, context, instance_id, path, file_contents): - """Write a file to the specified path on an instance on this server""" + """Write a file to the specified path in an instance on this host.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) instance_id = instance_ref['id'] @@ -383,44 +386,34 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock def rescue_instance(self, context, instance_id): - """Rescue an instance on this server.""" + """Rescue an instance on this host.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) LOG.audit(_('instance %s: rescuing'), instance_id, context=context) - self.db.instance_set_state( - context, - instance_id, - power_state.NOSTATE, - 'rescuing') + self.db.instance_set_state(context, + instance_id, + power_state.NOSTATE, + 'rescuing') self.network_manager.setup_compute_network(context, instance_id) - self.driver.rescue( - instance_ref, - lambda result: self._update_state_callback( - self, - context, - instance_id, - result)) + _update_state = lambda result: self._update_state_callback( + self, context, instance_id, result)) + self.driver.rescue(instance_ref, _update_state) self._update_state(context, instance_id) @exception.wrap_exception @checks_instance_lock def unrescue_instance(self, context, instance_id): - """Rescue an instance on this server.""" + """Rescue an instance on this host.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) LOG.audit(_('instance %s: unrescuing'), instance_id, context=context) - self.db.instance_set_state( - context, - instance_id, - power_state.NOSTATE, - 'unrescuing') - self.driver.unrescue( - instance_ref, - lambda result: self._update_state_callback( - self, - context, - instance_id, - result)) + self.db.instance_set_state(context, + instance_id, + power_state.NOSTATE, + 'unrescuing') + _update_state = lambda result: self._update_state_callback( + self, context, instance_id, result)) + self.driver.unrescue(instance_ref, _update_state) self._update_state(context, instance_id) @staticmethod @@ -431,7 +424,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock def confirm_resize(self, context, instance_id, migration_id): - """Destroys the source instance""" + """Destroys the source instance.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) self.driver.destroy(instance_ref) @@ -439,9 +432,12 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock def revert_resize(self, context, instance_id, migration_id): - """Destroys the new instance on the destination machine, - reverts the model changes, and powers on the old - instance on the source machine""" + """Destroys the new instance on the destination machine. + + Reverts the model changes, and powers on the old instance on the + source machine. + + """ instance_ref = self.db.instance_get(context, instance_id) migration_ref = self.db.migration_get(context, migration_id) @@ -458,9 +454,12 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock def finish_revert_resize(self, context, instance_id, migration_id): - """Finishes the second half of reverting a resize, powering back on - the source instance and reverting the resized attributes in the - database""" + """Finishes the second half of reverting a resize. + + Power back on the source instance and revert the resized attributes + in the database. + + """ instance_ref = self.db.instance_get(context, instance_id) migration_ref = self.db.migration_get(context, migration_id) instance_type = self.db.instance_type_get_by_flavor_id(context, @@ -480,8 +479,11 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock def prep_resize(self, context, instance_id, flavor_id): - """Initiates the process of moving a running instance to another - host, possibly changing the RAM and disk size in the process""" + """Initiates the process of moving a running instance to another host. + + Possibly changes the RAM and disk size in the process. + + """ context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) if instance_ref['host'] == FLAGS.host: @@ -513,35 +515,38 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock def resize_instance(self, context, instance_id, migration_id): - """Starts the migration of a running instance to another host""" + """Starts the migration of a running instance to another host.""" migration_ref = self.db.migration_get(context, migration_id) instance_ref = self.db.instance_get(context, instance_id) - self.db.migration_update(context, migration_id, - {'status': 'migrating', }) - - disk_info = self.driver.migrate_disk_and_power_off(instance_ref, - migration_ref['dest_host']) - self.db.migration_update(context, migration_id, - {'status': 'post-migrating', }) - - # Make sure the service exists before sending a message. - _service = self.db.service_get_by_host_and_topic(context, - migration_ref['dest_compute'], FLAGS.compute_topic) - topic = self.db.queue_get_for(context, FLAGS.compute_topic, - migration_ref['dest_compute']) - rpc.cast(context, topic, - {'method': 'finish_resize', - 'args': { - 'migration_id': migration_id, - 'instance_id': instance_id, - 'disk_info': disk_info, }, - }) + self.db.migration_update(context, + migration_id, + {'status': 'migrating'}) + + disk_info = self.driver.migrate_disk_and_power_off( + instance_ref, migration_ref['dest_host']) + self.db.migration_update(context, + migration_id, + {'status': 'post-migrating'}) + + service = self.db.service_get_by_host_and_topic( + context, migration_ref['dest_compute'], FLAGS.compute_topic) + topic = self.db.queue_get_for(context, + FLAGS.compute_topic, + migration_ref['dest_compute']) + rpc.cast(context, topic, {'method': 'finish_resize', + 'args': {'migration_id': migration_id, + 'instance_id': instance_id, + 'disk_info': disk_info}}) @exception.wrap_exception @checks_instance_lock def finish_resize(self, context, instance_id, migration_id, disk_info): - """Completes the migration process by setting up the newly transferred - disk and turning on the instance on its new host machine""" + """Completes the migration process. + + Sets up the newly transferred disk and turns on the instance at its + new host machine. + + """ migration_ref = self.db.migration_get(context, migration_id) instance_ref = self.db.instance_get(context, migration_ref['instance_id']) @@ -566,7 +571,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock def pause_instance(self, context, instance_id): - """Pause an instance on this server.""" + """Pause an instance on this host.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) LOG.audit(_('instance %s: pausing'), instance_id, context=context) @@ -583,7 +588,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock def unpause_instance(self, context, instance_id): - """Unpause a paused instance on this server.""" + """Unpause a paused instance on this host.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) LOG.audit(_('instance %s: unpausing'), instance_id, context=context) @@ -599,7 +604,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception def get_diagnostics(self, context, instance_id): - """Retrieve diagnostics for an instance on this server.""" + """Retrieve diagnostics for an instance on this host.""" instance_ref = self.db.instance_get(context, instance_id) if instance_ref["state"] == power_state.RUNNING: @@ -610,10 +615,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock def suspend_instance(self, context, instance_id): - """ - suspend the instance with instance_id - - """ + """Suspend the given instance.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) LOG.audit(_('instance %s: suspending'), instance_id, context=context) @@ -629,10 +631,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock def resume_instance(self, context, instance_id): - """ - resume the suspended instance with instance_id - - """ + """Resume the given suspended instance.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) LOG.audit(_('instance %s: resuming'), instance_id, context=context) @@ -647,10 +646,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception def lock_instance(self, context, instance_id): - """ - lock the instance with instance_id - - """ + """Lock the given instance.""" context = context.elevated() LOG.debug(_('instance %s: locking'), instance_id, context=context) @@ -658,10 +654,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception def unlock_instance(self, context, instance_id): - """ - unlock the instance with instance_id - - """ + """Unlock the given instance.""" context = context.elevated() LOG.debug(_('instance %s: unlocking'), instance_id, context=context) @@ -669,10 +662,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception def get_lock(self, context, instance_id): - """ - return the boolean state of (instance with instance_id)'s lock - - """ + """Return the boolean state of the given instance's lock.""" context = context.elevated() LOG.debug(_('instance %s: getting locked state'), instance_id, context=context) @@ -681,10 +671,7 @@ class ComputeManager(manager.SchedulerDependentManager): @checks_instance_lock def reset_network(self, context, instance_id): - """ - Reset networking on the instance. - - """ + """Reset networking on the given instance.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) LOG.debug(_('instance %s: reset network'), instance_id, @@ -693,10 +680,7 @@ class ComputeManager(manager.SchedulerDependentManager): @checks_instance_lock def inject_network_info(self, context, instance_id): - """ - Inject network info for the instance. - - """ + """Inject network info for the given instance.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) LOG.debug(_('instance %s: inject network info'), instance_id, @@ -705,7 +689,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception def get_console_output(self, context, instance_id): - """Send the console output for an instance.""" + """Send the console output for the given instance.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) LOG.audit(_("Get console output for instance %s"), instance_id, @@ -714,20 +698,18 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception def get_ajax_console(self, context, instance_id): - """Return connection information for an ajax console""" + """Return connection information for an ajax console.""" context = context.elevated() LOG.debug(_("instance %s: getting ajax console"), instance_id) instance_ref = self.db.instance_get(context, instance_id) - return self.driver.get_ajax_console(instance_ref) @exception.wrap_exception def get_vnc_console(self, context, instance_id): - """Return connection information for an vnc console.""" + """Return connection information for a vnc console.""" context = context.elevated() LOG.debug(_("instance %s: getting vnc console"), instance_id) instance_ref = self.db.instance_get(context, instance_id) - return self.driver.get_vnc_console(instance_ref) @checks_instance_lock @@ -781,7 +763,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception def compare_cpu(self, context, cpu_info): - """Checks the host cpu is compatible to a cpu given by xml. + """Checks that the host cpu is compatible with a cpu given by xml. :param context: security context :param cpu_info: json string obtained from virConnect.getCapabilities @@ -802,7 +784,6 @@ class ComputeManager(manager.SchedulerDependentManager): :returns: tmpfile name(basename) """ - dirpath = FLAGS.instances_path fd, tmp_file = tempfile.mkstemp(dir=dirpath) LOG.debug(_("Creating tmpfile %s to notify to other " @@ -819,7 +800,6 @@ class ComputeManager(manager.SchedulerDependentManager): :param filename: confirm existence of FLAGS.instances_path/thisfile """ - tmp_file = os.path.join(FLAGS.instances_path, filename) if not os.path.exists(tmp_file): raise exception.NotFound(_('%s not found') % tmp_file) @@ -832,7 +812,6 @@ class ComputeManager(manager.SchedulerDependentManager): :param filename: remove existence of FLAGS.instances_path/thisfile """ - tmp_file = os.path.join(FLAGS.instances_path, filename) os.remove(tmp_file) @@ -844,7 +823,6 @@ class ComputeManager(manager.SchedulerDependentManager): :returns: See driver.update_available_resource() """ - return self.driver.update_available_resource(context, self.host) def pre_live_migration(self, context, instance_id, time=None): @@ -854,7 +832,6 @@ class ComputeManager(manager.SchedulerDependentManager): :param instance_id: nova.db.sqlalchemy.models.Instance.Id """ - if not time: time = greenthread @@ -913,7 +890,6 @@ class ComputeManager(manager.SchedulerDependentManager): :param dest: destination host """ - # Get instance for error handling. instance_ref = self.db.instance_get(context, instance_id) i_name = instance_ref.name @@ -1009,12 +985,10 @@ class ComputeManager(manager.SchedulerDependentManager): :param ctxt: security context :param instance_id: nova.db.sqlalchemy.models.Instance.Id - :param host: - DB column value is updated by this hostname. - if none, the host instance currently running is selected. + :param host: DB column value is updated by this hostname. + If none, the host instance currently running is selected. """ - if not host: host = instance_ref['host'] -- cgit From b26f3166554cf5de29fcedee7463bc523786cf72 Mon Sep 17 00:00:00 2001 From: termie Date: Wed, 20 Apr 2011 11:52:19 -0700 Subject: fix typo --- nova/compute/manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 8103ed61e..fac00e45e 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -396,7 +396,7 @@ class ComputeManager(manager.SchedulerDependentManager): 'rescuing') self.network_manager.setup_compute_network(context, instance_id) _update_state = lambda result: self._update_state_callback( - self, context, instance_id, result)) + self, context, instance_id, result) self.driver.rescue(instance_ref, _update_state) self._update_state(context, instance_id) @@ -412,7 +412,7 @@ class ComputeManager(manager.SchedulerDependentManager): power_state.NOSTATE, 'unrescuing') _update_state = lambda result: self._update_state_callback( - self, context, instance_id, result)) + self, context, instance_id, result) self.driver.unrescue(instance_ref, _update_state) self._update_state(context, instance_id) -- cgit From 98b8a800b16a1e6699b1d4c7ce0e4ab61319be6e Mon Sep 17 00:00:00 2001 From: termie Date: Wed, 20 Apr 2011 12:00:21 -0700 Subject: docstring cleanup, nova/db dir --- nova/db/api.py | 61 +++++++++++++++++++++++++++------------------------- nova/db/base.py | 8 +++---- nova/db/migration.py | 2 ++ 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/nova/db/api.py b/nova/db/api.py index 63901e94d..1b33d8932 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -15,8 +15,8 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -""" -Defines interface for DB access. + +"""Defines interface for DB access. The underlying driver is loaded as a :class:`LazyPluggable`. @@ -30,6 +30,7 @@ The underlying driver is loaded as a :class:`LazyPluggable`. :enable_new_services: when adding a new service to the database, is it in the pool of available hardware (Default: True) + """ from nova import exception @@ -86,7 +87,7 @@ def service_get(context, service_id): def service_get_by_host_and_topic(context, host, topic): - """Get a service by host it's on and topic it listens to""" + """Get a service by host it's on and topic it listens to.""" return IMPL.service_get_by_host_and_topic(context, host, topic) @@ -113,7 +114,7 @@ def service_get_all_compute_by_host(context, host): def service_get_all_compute_sorted(context): """Get all compute services sorted by instance count. - Returns a list of (Service, instance_count) tuples. + :returns: a list of (Service, instance_count) tuples. """ return IMPL.service_get_all_compute_sorted(context) @@ -122,7 +123,7 @@ def service_get_all_compute_sorted(context): def service_get_all_network_sorted(context): """Get all network services sorted by network count. - Returns a list of (Service, network_count) tuples. + :returns: a list of (Service, network_count) tuples. """ return IMPL.service_get_all_network_sorted(context) @@ -131,7 +132,7 @@ def service_get_all_network_sorted(context): def service_get_all_volume_sorted(context): """Get all volume services sorted by volume count. - Returns a list of (Service, volume_count) tuples. + :returns: a list of (Service, volume_count) tuples. """ return IMPL.service_get_all_volume_sorted(context) @@ -241,7 +242,7 @@ def floating_ip_count_by_project(context, project_id): def floating_ip_deallocate(context, address): - """Deallocate an floating ip by address""" + """Deallocate an floating ip by address.""" return IMPL.floating_ip_deallocate(context, address) @@ -253,7 +254,7 @@ def floating_ip_destroy(context, address): def floating_ip_disassociate(context, address): """Disassociate an floating ip from a fixed ip by address. - Returns the address of the existing fixed ip. + :returns: the address of the existing fixed ip. """ return IMPL.floating_ip_disassociate(context, address) @@ -294,22 +295,22 @@ def floating_ip_update(context, address, values): #################### def migration_update(context, id, values): - """Update a migration instance""" + """Update a migration instance.""" return IMPL.migration_update(context, id, values) def migration_create(context, values): - """Create a migration record""" + """Create a migration record.""" return IMPL.migration_create(context, values) def migration_get(context, migration_id): - """Finds a migration by the id""" + """Finds a migration by the id.""" return IMPL.migration_get(context, migration_id) def migration_get_by_instance_and_status(context, instance_id, status): - """Finds a migration by the instance id its migrating""" + """Finds a migration by the instance id its migrating.""" return IMPL.migration_get_by_instance_and_status(context, instance_id, status) @@ -579,7 +580,9 @@ def network_create_safe(context, values): def network_delete_safe(context, network_id): """Delete network with key network_id. + This method assumes that the network is not associated with any project + """ return IMPL.network_delete_safe(context, network_id) @@ -674,7 +677,6 @@ def project_get_network(context, project_id, associate=True): network if one is not found, otherwise it returns None. """ - return IMPL.project_get_network(context, project_id, associate) @@ -722,7 +724,9 @@ def iscsi_target_create_safe(context, values): The device is not returned. If the create violates the unique constraints because the iscsi_target and host already exist, - no exception is raised.""" + no exception is raised. + + """ return IMPL.iscsi_target_create_safe(context, values) @@ -1050,10 +1054,7 @@ def project_delete(context, project_id): def host_get_networks(context, host): - """Return all networks for which the given host is the designated - network host. - - """ + """All networks for which the given host is the network host.""" return IMPL.host_get_networks(context, host) @@ -1115,38 +1116,40 @@ def console_get(context, console_id, instance_id=None): def instance_type_create(context, values): - """Create a new instance type""" + """Create a new instance type.""" return IMPL.instance_type_create(context, values) def instance_type_get_all(context, inactive=False): - """Get all instance types""" + """Get all instance types.""" return IMPL.instance_type_get_all(context, inactive) def instance_type_get_by_id(context, id): - """Get instance type by id""" + """Get instance type by id.""" return IMPL.instance_type_get_by_id(context, id) def instance_type_get_by_name(context, name): - """Get instance type by name""" + """Get instance type by name.""" return IMPL.instance_type_get_by_name(context, name) def instance_type_get_by_flavor_id(context, id): - """Get instance type by name""" + """Get instance type by name.""" return IMPL.instance_type_get_by_flavor_id(context, id) def instance_type_destroy(context, name): - """Delete a instance type""" + """Delete a instance type.""" return IMPL.instance_type_destroy(context, name) def instance_type_purge(context, name): - """Purges (removes) an instance type from DB - Use instance_type_destroy for most cases + """Purges (removes) an instance type from DB. + + Use instance_type_destroy for most cases + """ return IMPL.instance_type_purge(context, name) @@ -1183,15 +1186,15 @@ def zone_get_all(context): def instance_metadata_get(context, instance_id): - """Get all metadata for an instance""" + """Get all metadata for an instance.""" return IMPL.instance_metadata_get(context, instance_id) def instance_metadata_delete(context, instance_id, key): - """Delete the given metadata item""" + """Delete the given metadata item.""" IMPL.instance_metadata_delete(context, instance_id, key) def instance_metadata_update_or_create(context, instance_id, metadata): - """Create or update instance metadata""" + """Create or update instance metadata.""" IMPL.instance_metadata_update_or_create(context, instance_id, metadata) diff --git a/nova/db/base.py b/nova/db/base.py index a0f2180c6..a0d055d5b 100644 --- a/nova/db/base.py +++ b/nova/db/base.py @@ -16,20 +16,20 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Base class for classes that need modular database access. -""" +"""Base class for classes that need modular database access.""" from nova import utils from nova import flags + FLAGS = flags.FLAGS flags.DEFINE_string('db_driver', 'nova.db.api', 'driver to use for database access') class Base(object): - """DB driver is injected in the init method""" + """DB driver is injected in the init method.""" + def __init__(self, db_driver=None): if not db_driver: db_driver = FLAGS.db_driver diff --git a/nova/db/migration.py b/nova/db/migration.py index e54b90cd8..ccd06cffe 100644 --- a/nova/db/migration.py +++ b/nova/db/migration.py @@ -15,11 +15,13 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. + """Database setup and migration commands.""" from nova import flags from nova import utils + FLAGS = flags.FLAGS flags.DECLARE('db_backend', 'nova.db.api') -- cgit From 04fd29085c6ed5fe72378b061b1d7659f110c924 Mon Sep 17 00:00:00 2001 From: termie Date: Wed, 20 Apr 2011 12:06:10 -0700 Subject: docstring cleanup, console --- nova/console/api.py | 23 ++++++-------- nova/console/fake.py | 22 ++++++-------- nova/console/manager.py | 17 ++++++----- nova/console/vmrc.py | 48 ++++++++++++++--------------- nova/console/vmrc_manager.py | 72 ++++++++++++++++++++------------------------ nova/console/xvp.py | 48 +++++++++++++++-------------- 6 files changed, 108 insertions(+), 122 deletions(-) diff --git a/nova/console/api.py b/nova/console/api.py index 3850d2c44..137ddcaac 100644 --- a/nova/console/api.py +++ b/nova/console/api.py @@ -15,23 +15,19 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Handles ConsoleProxy API requests -""" +"""Handles ConsoleProxy API requests.""" from nova import exception -from nova.db import base - - from nova import flags from nova import rpc +from nova.db import base FLAGS = flags.FLAGS class API(base.Base): - """API for spining up or down console proxy connections""" + """API for spinning up or down console proxy connections.""" def __init__(self, **kwargs): super(API, self).__init__(**kwargs) @@ -51,8 +47,8 @@ class API(base.Base): self.db.queue_get_for(context, FLAGS.console_topic, pool['host']), - {"method": "remove_console", - "args": {"console_id": console['id']}}) + {'method': 'remove_console', + 'args': {'console_id': console['id']}}) def create_console(self, context, instance_id): instance = self.db.instance_get(context, instance_id) @@ -63,13 +59,12 @@ class API(base.Base): # here. rpc.cast(context, self._get_console_topic(context, instance['host']), - {"method": "add_console", - "args": {"instance_id": instance_id}}) + {'method': 'add_console', + 'args': {'instance_id': instance_id}}) def _get_console_topic(self, context, instance_host): topic = self.db.queue_get_for(context, FLAGS.compute_topic, instance_host) - return rpc.call(context, - topic, - {"method": "get_console_topic", "args": {'fake': 1}}) + return rpc.call(context, topic, {'method': 'get_console_topic', + 'args': {'fake': 1}}) diff --git a/nova/console/fake.py b/nova/console/fake.py index 7a90d5221..e2eb886f8 100644 --- a/nova/console/fake.py +++ b/nova/console/fake.py @@ -15,9 +15,7 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Fake ConsoleProxy driver for tests. -""" +"""Fake ConsoleProxy driver for tests.""" from nova import exception @@ -27,32 +25,32 @@ class FakeConsoleProxy(object): @property def console_type(self): - return "fake" + return 'fake' def setup_console(self, context, console): - """Sets up actual proxies""" + """Sets up actual proxies.""" pass def teardown_console(self, context, console): - """Tears down actual proxies""" + """Tears down actual proxies.""" pass def init_host(self): - """Start up any config'ed consoles on start""" + """Start up any config'ed consoles on start.""" pass def generate_password(self, length=8): - """Returns random console password""" - return "fakepass" + """Returns random console password.""" + return 'fakepass' def get_port(self, context): - """get available port for consoles that need one""" + """Get available port for consoles that need one.""" return 5999 def fix_pool_password(self, password): - """Trim password to length, and any other massaging""" + """Trim password to length, and any other massaging.""" return password def fix_console_password(self, password): - """Trim password to length, and any other massaging""" + """Trim password to length, and any other massaging.""" return password diff --git a/nova/console/manager.py b/nova/console/manager.py index bfa571ea9..e0db21666 100644 --- a/nova/console/manager.py +++ b/nova/console/manager.py @@ -15,9 +15,7 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Console Proxy Service -""" +"""Console Proxy Service.""" import functools import socket @@ -29,6 +27,7 @@ from nova import manager from nova import rpc from nova import utils + FLAGS = flags.FLAGS flags.DEFINE_string('console_driver', 'nova.console.xvp.XVPConsoleProxy', @@ -41,9 +40,11 @@ flags.DEFINE_string('console_public_hostname', class ConsoleProxyManager(manager.Manager): + """Sets up and tears down any console proxy connections. + + Needed for accessing instance consoles securely. - """ Sets up and tears down any proxy connections needed for accessing - instance consoles securely""" + """ def __init__(self, console_driver=None, *args, **kwargs): if not console_driver: @@ -67,7 +68,7 @@ class ConsoleProxyManager(manager.Manager): pool['id'], instance_id) except exception.NotFound: - logging.debug(_("Adding console")) + logging.debug(_('Adding console')) if not password: password = utils.generate_password(8) if not port: @@ -115,8 +116,8 @@ class ConsoleProxyManager(manager.Manager): self.db.queue_get_for(context, FLAGS.compute_topic, instance_host), - {"method": "get_console_pool_info", - "args": {"console_type": console_type}}) + {'method': 'get_console_pool_info', + 'args': {'console_type': console_type}}) pool_info['password'] = self.driver.fix_pool_password( pool_info['password']) pool_info['host'] = self.host diff --git a/nova/console/vmrc.py b/nova/console/vmrc.py index 521da289f..127d31121 100644 --- a/nova/console/vmrc.py +++ b/nova/console/vmrc.py @@ -15,9 +15,7 @@ # License for the specific language governing permissions and limitations # under the License. -""" -VMRC console drivers. -""" +"""VMRC console drivers.""" import base64 import json @@ -27,6 +25,8 @@ from nova import flags from nova import log as logging from nova.virt.vmwareapi import vim_util + +FLAGS = flags.FLAGS flags.DEFINE_integer('console_vmrc_port', 443, "port for VMware VMRC connections") @@ -34,8 +34,6 @@ flags.DEFINE_integer('console_vmrc_error_retries', 10, "number of retries for retrieving VMRC information") -FLAGS = flags.FLAGS - class VMRCConsole(object): """VMRC console driver with ESX credentials.""" @@ -69,34 +67,34 @@ class VMRCConsole(object): return password def generate_password(self, vim_session, pool, instance_name): - """ - Returns VMRC Connection credentials. + """Returns VMRC Connection credentials. Return string is of the form ':@'. + """ username, password = pool['username'], pool['password'] - vms = vim_session._call_method(vim_util, "get_objects", - "VirtualMachine", ["name", "config.files.vmPathName"]) + vms = vim_session._call_method(vim_util, 'get_objects', + 'VirtualMachine', ['name', 'config.files.vmPathName']) vm_ds_path_name = None vm_ref = None for vm in vms: vm_name = None ds_path_name = None for prop in vm.propSet: - if prop.name == "name": + if prop.name == 'name': vm_name = prop.val - elif prop.name == "config.files.vmPathName": + elif prop.name == 'config.files.vmPathName': ds_path_name = prop.val if vm_name == instance_name: vm_ref = vm.obj vm_ds_path_name = ds_path_name break if vm_ref is None: - raise exception.NotFound(_("instance - %s not present") % + raise exception.NotFound(_('instance - %s not present') % instance_name) - json_data = json.dumps({"vm_id": vm_ds_path_name, - "username": username, - "password": password}) + json_data = json.dumps({'vm_id': vm_ds_path_name, + 'username': username, + 'password': password}) return base64.b64encode(json_data) def is_otp(self): @@ -115,28 +113,28 @@ class VMRCSessionConsole(VMRCConsole): return 'vmrc+session' def generate_password(self, vim_session, pool, instance_name): - """ - Returns a VMRC Session. + """Returns a VMRC Session. Return string is of the form ':'. + """ - vms = vim_session._call_method(vim_util, "get_objects", - "VirtualMachine", ["name"]) - vm_ref = None + vms = vim_session._call_method(vim_util, 'get_objects', + 'VirtualMachine', ['name']) + vm_ref = NoneV for vm in vms: if vm.propSet[0].val == instance_name: vm_ref = vm.obj if vm_ref is None: - raise exception.NotFound(_("instance - %s not present") % + raise exception.NotFound(_('instance - %s not present') % instance_name) virtual_machine_ticket = \ vim_session._call_method( vim_session._get_vim(), - "AcquireCloneTicket", + 'AcquireCloneTicket', vim_session._get_vim().get_service_content().sessionManager) - json_data = json.dumps({"vm_id": str(vm_ref.value), - "username": virtual_machine_ticket, - "password": virtual_machine_ticket}) + json_data = json.dumps({'vm_id': str(vm_ref.value), + 'username': virtual_machine_ticket, + 'password': virtual_machine_ticket}) return base64.b64encode(json_data) def is_otp(self): diff --git a/nova/console/vmrc_manager.py b/nova/console/vmrc_manager.py index 09beac7a0..3c6b77782 100644 --- a/nova/console/vmrc_manager.py +++ b/nova/console/vmrc_manager.py @@ -15,9 +15,7 @@ # License for the specific language governing permissions and limitations # under the License. -""" -VMRC Console Manager. -""" +"""VMRC Console Manager.""" from nova import exception from nova import flags @@ -25,24 +23,21 @@ from nova import log as logging from nova import manager from nova import rpc from nova import utils -from nova.virt.vmwareapi_conn import VMWareAPISession +from nova.virt import vmwareapi_conn + LOG = logging.getLogger("nova.console.vmrc_manager") + FLAGS = flags.FLAGS -flags.DEFINE_string('console_public_hostname', - '', +flags.DEFINE_string('console_public_hostname', '', 'Publicly visible name for this console host') -flags.DEFINE_string('console_driver', - 'nova.console.vmrc.VMRCConsole', +flags.DEFINE_string('console_driver', 'nova.console.vmrc.VMRCConsole', 'Driver to use for the console') class ConsoleVMRCManager(manager.Manager): - - """ - Manager to handle VMRC connections needed for accessing instance consoles. - """ + """Manager to handle VMRC connections for accessing instance consoles.""" def __init__(self, console_driver=None, *args, **kwargs): self.driver = utils.import_object(FLAGS.console_driver) @@ -56,7 +51,7 @@ class ConsoleVMRCManager(manager.Manager): """Get VIM session for the pool specified.""" vim_session = None if pool['id'] not in self.sessions.keys(): - vim_session = VMWareAPISession(pool['address'], + vim_session = vmwareapi_conn.VMWareAPISession(pool['address'], pool['username'], pool['password'], FLAGS.console_vmrc_error_retries) @@ -65,7 +60,7 @@ class ConsoleVMRCManager(manager.Manager): def _generate_console(self, context, pool, name, instance_id, instance): """Sets up console for the instance.""" - LOG.debug(_("Adding console")) + LOG.debug(_('Adding console')) password = self.driver.generate_password( self._get_vim_session(pool), @@ -84,9 +79,10 @@ class ConsoleVMRCManager(manager.Manager): @exception.wrap_exception def add_console(self, context, instance_id, password=None, port=None, **kwargs): - """ - Adds a console for the instance. If it is one time password, then we - generate new console credentials. + """Adds a console for the instance. + + If it is one time password, then we generate new console credentials. + """ instance = self.db.instance_get(context, instance_id) host = instance['host'] @@ -97,19 +93,17 @@ class ConsoleVMRCManager(manager.Manager): pool['id'], instance_id) if self.driver.is_otp(): - console = self._generate_console( - context, - pool, - name, - instance_id, - instance) + console = self._generate_console(context, + pool, + name, + instance_id, + instance) except exception.NotFound: - console = self._generate_console( - context, - pool, - name, - instance_id, - instance) + console = self._generate_console(context, + pool, + name, + instance_id, + instance) return console['id'] @exception.wrap_exception @@ -118,13 +112,11 @@ class ConsoleVMRCManager(manager.Manager): try: console = self.db.console_get(context, console_id) except exception.NotFound: - LOG.debug(_("Tried to remove non-existent console " - "%(console_id)s.") % - {'console_id': console_id}) + LOG.debug(_('Tried to remove non-existent console ' + '%(console_id)s.') % {'console_id': console_id}) return - LOG.debug(_("Removing console " - "%(console_id)s.") % - {'console_id': console_id}) + LOG.debug(_('Removing console ' + '%(console_id)s.') % {'console_id': console_id}) self.db.console_delete(context, console_id) self.driver.teardown_console(context, console) @@ -139,11 +131,11 @@ class ConsoleVMRCManager(manager.Manager): console_type) except exception.NotFound: pool_info = rpc.call(context, - self.db.queue_get_for(context, - FLAGS.compute_topic, - instance_host), - {"method": "get_console_pool_info", - "args": {"console_type": console_type}}) + self.db.queue_get_for(context, + FLAGS.compute_topic, + instance_host), + {'method': 'get_console_pool_info', + 'args': {'console_type': console_type}}) pool_info['password'] = self.driver.fix_pool_password( pool_info['password']) pool_info['host'] = self.host diff --git a/nova/console/xvp.py b/nova/console/xvp.py index 0cedfbb13..3cd287183 100644 --- a/nova/console/xvp.py +++ b/nova/console/xvp.py @@ -15,16 +15,14 @@ # License for the specific language governing permissions and limitations # under the License. -""" -XVP (Xenserver VNC Proxy) driver. -""" +"""XVP (Xenserver VNC Proxy) driver.""" import fcntl import os import signal import subprocess -from Cheetah.Template import Template +from Cheetah import Template from nova import context from nova import db @@ -33,6 +31,8 @@ from nova import flags from nova import log as logging from nova import utils + +FLAGS = flags.FLAGS flags.DEFINE_string('console_xvp_conf_template', utils.abspath('console/xvp.conf.template'), 'XVP conf template') @@ -47,12 +47,11 @@ flags.DEFINE_string('console_xvp_log', 'XVP log file') flags.DEFINE_integer('console_xvp_multiplex_port', 5900, - "port for XVP to multiplex VNC connections on") -FLAGS = flags.FLAGS + 'port for XVP to multiplex VNC connections on') class XVPConsoleProxy(object): - """Sets up XVP config, and manages xvp daemon""" + """Sets up XVP config, and manages XVP daemon.""" def __init__(self): self.xvpconf_template = open(FLAGS.console_xvp_conf_template).read() @@ -61,50 +60,51 @@ class XVPConsoleProxy(object): @property def console_type(self): - return "vnc+xvp" + return 'vnc+xvp' def get_port(self, context): - """get available port for consoles that need one""" + """Get available port for consoles that need one.""" #TODO(mdragon): implement port selection for non multiplex ports, # we are not using that, but someone else may want # it. return FLAGS.console_xvp_multiplex_port def setup_console(self, context, console): - """Sets up actual proxies""" + """Sets up actual proxies.""" self._rebuild_xvp_conf(context.elevated()) def teardown_console(self, context, console): - """Tears down actual proxies""" + """Tears down actual proxies.""" self._rebuild_xvp_conf(context.elevated()) def init_host(self): - """Start up any config'ed consoles on start""" + """Start up any config'ed consoles on start.""" ctxt = context.get_admin_context() self._rebuild_xvp_conf(ctxt) def fix_pool_password(self, password): - """Trim password to length, and encode""" + """Trim password to length, and encode.""" return self._xvp_encrypt(password, is_pool_password=True) def fix_console_password(self, password): - """Trim password to length, and encode""" + """Trim password to length, and encode.""" return self._xvp_encrypt(password) def _rebuild_xvp_conf(self, context): - logging.debug(_("Rebuilding xvp conf")) + logging.debug(_('Rebuilding xvp conf')) pools = [pool for pool in db.console_pool_get_all_by_host_type(context, self.host, self.console_type) if pool['consoles']] if not pools: - logging.debug("No console pools!") + logging.debug('No console pools!') self._xvp_stop() return conf_data = {'multiplex_port': FLAGS.console_xvp_multiplex_port, 'pools': pools, 'pass_encode': self.fix_console_password} - config = str(Template(self.xvpconf_template, searchList=[conf_data])) + config = str(Template.Template(self.xvpconf_template, + searchList=[conf_data])) self._write_conf(config) self._xvp_restart() @@ -114,7 +114,7 @@ class XVPConsoleProxy(object): cfile.write(config) def _xvp_stop(self): - logging.debug(_("Stopping xvp")) + logging.debug(_('Stopping xvp')) pid = self._xvp_pid() if not pid: return @@ -127,19 +127,19 @@ class XVPConsoleProxy(object): def _xvp_start(self): if self._xvp_check_running(): return - logging.debug(_("Starting xvp")) + logging.debug(_('Starting xvp')) try: utils.execute('xvp', '-p', FLAGS.console_xvp_pid, '-c', FLAGS.console_xvp_conf, '-l', FLAGS.console_xvp_log) except exception.ProcessExecutionError, err: - logging.error(_("Error starting xvp: %s") % err) + logging.error(_('Error starting xvp: %s') % err) def _xvp_restart(self): - logging.debug(_("Restarting xvp")) + logging.debug(_('Restarting xvp')) if not self._xvp_check_running(): - logging.debug(_("xvp not running...")) + logging.debug(_('xvp not running...')) self._xvp_start() else: pid = self._xvp_pid() @@ -178,7 +178,9 @@ class XVPConsoleProxy(object): Note that xvp's obfuscation should not be considered 'real' encryption. It simply DES encrypts the passwords with static keys plainly viewable - in the xvp source code.""" + in the xvp source code. + + """ maxlen = 8 flag = '-e' if is_pool_password: -- cgit From 740547fcb1aa02c31a362d1be2d4a27b3799e36a Mon Sep 17 00:00:00 2001 From: termie Date: Wed, 20 Apr 2011 12:06:10 -0700 Subject: fixed indentation --- nova/console/vmrc_manager.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/nova/console/vmrc_manager.py b/nova/console/vmrc_manager.py index 3c6b77782..acecc1075 100644 --- a/nova/console/vmrc_manager.py +++ b/nova/console/vmrc_manager.py @@ -51,10 +51,11 @@ class ConsoleVMRCManager(manager.Manager): """Get VIM session for the pool specified.""" vim_session = None if pool['id'] not in self.sessions.keys(): - vim_session = vmwareapi_conn.VMWareAPISession(pool['address'], - pool['username'], - pool['password'], - FLAGS.console_vmrc_error_retries) + vim_session = vmwareapi_conn.VMWareAPISession( + pool['address'], + pool['username'], + pool['password'], + FLAGS.console_vmrc_error_retries) self.sessions[pool['id']] = vim_session return self.sessions[pool['id']] -- cgit From f69600e1844898bd48dc8f615c6684044d9aebe0 Mon Sep 17 00:00:00 2001 From: termie Date: Wed, 20 Apr 2011 12:08:22 -0700 Subject: docstring cleanup, nova dir --- nova/context.py | 10 +++- nova/crypto.py | 61 +++++++++++---------- nova/exception.py | 25 +++++---- nova/fakememcache.py | 4 +- nova/flags.py | 16 ++++-- nova/log.py | 49 ++++++++--------- nova/manager.py | 34 ++++++++---- nova/quota.py | 23 ++++---- nova/rpc.py | 152 +++++++++++++++++++++++++++++---------------------- nova/service.py | 83 +++++++++++++--------------- nova/test.py | 50 +++++++++-------- nova/utils.py | 147 ++++++++++++++++++++++++------------------------- nova/version.py | 6 +- nova/wsgi.py | 144 ++++++++++++++++++++++++------------------------ 14 files changed, 422 insertions(+), 382 deletions(-) diff --git a/nova/context.py b/nova/context.py index 0256bf448..c113f7ea7 100644 --- a/nova/context.py +++ b/nova/context.py @@ -16,9 +16,7 @@ # License for the specific language governing permissions and limitations # under the License. -""" -RequestContext: context for requests that persist through all of nova. -""" +"""RequestContext: context for requests that persist through all of nova.""" import datetime import random @@ -28,6 +26,12 @@ from nova import utils class RequestContext(object): + """Security context and request information. + + Represents the user taking a given action within the system. + + """ + def __init__(self, user, project, is_admin=None, read_deleted=False, remote_address=None, timestamp=None, request_id=None): if hasattr(user, 'id'): diff --git a/nova/crypto.py b/nova/crypto.py index 605be2a32..14b9cbef6 100644 --- a/nova/crypto.py +++ b/nova/crypto.py @@ -15,10 +15,11 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -""" -Wrappers around standard crypto data elements. + +"""Wrappers around standard crypto data elements. Includes root and intermediate CAs, SSH key_pairs and x509 certificates. + """ import base64 @@ -43,6 +44,8 @@ from nova import log as logging LOG = logging.getLogger("nova.crypto") + + FLAGS = flags.FLAGS flags.DEFINE_string('ca_file', 'cacert.pem', _('Filename of root CA')) flags.DEFINE_string('key_file', @@ -90,13 +93,13 @@ def key_path(project_id=None): def fetch_ca(project_id=None, chain=True): if not FLAGS.use_project_ca: project_id = None - buffer = "" + buffer = '' if project_id: - with open(ca_path(project_id), "r") as cafile: + with open(ca_path(project_id), 'r') as cafile: buffer += cafile.read() if not chain: return buffer - with open(ca_path(None), "r") as cafile: + with open(ca_path(None), 'r') as cafile: buffer += cafile.read() return buffer @@ -143,7 +146,7 @@ def ssl_pub_to_ssh_pub(ssl_public_key, name='root', suffix='nova'): def revoke_cert(project_id, file_name): - """Revoke a cert by file name""" + """Revoke a cert by file name.""" start = os.getcwd() os.chdir(ca_folder(project_id)) # NOTE(vish): potential race condition here @@ -155,14 +158,14 @@ def revoke_cert(project_id, file_name): def revoke_certs_by_user(user_id): - """Revoke all user certs""" + """Revoke all user certs.""" admin = context.get_admin_context() for cert in db.certificate_get_all_by_user(admin, user_id): revoke_cert(cert['project_id'], cert['file_name']) def revoke_certs_by_project(project_id): - """Revoke all project certs""" + """Revoke all project certs.""" # NOTE(vish): This is somewhat useless because we can just shut down # the vpn. admin = context.get_admin_context() @@ -171,29 +174,29 @@ def revoke_certs_by_project(project_id): def revoke_certs_by_user_and_project(user_id, project_id): - """Revoke certs for user in project""" + """Revoke certs for user in project.""" admin = context.get_admin_context() for cert in db.certificate_get_all_by_user(admin, user_id, project_id): revoke_cert(cert['project_id'], cert['file_name']) def _project_cert_subject(project_id): - """Helper to generate user cert subject""" + """Helper to generate user cert subject.""" return FLAGS.project_cert_subject % (project_id, utils.isotime()) def _vpn_cert_subject(project_id): - """Helper to generate user cert subject""" + """Helper to generate user cert subject.""" return FLAGS.vpn_cert_subject % (project_id, utils.isotime()) def _user_cert_subject(user_id, project_id): - """Helper to generate user cert subject""" + """Helper to generate user cert subject.""" return FLAGS.user_cert_subject % (project_id, user_id, utils.isotime()) def generate_x509_cert(user_id, project_id, bits=1024): - """Generate and sign a cert for user in project""" + """Generate and sign a cert for user in project.""" subject = _user_cert_subject(user_id, project_id) tmpdir = tempfile.mkdtemp() keyfile = os.path.abspath(os.path.join(tmpdir, 'temp.key')) @@ -205,7 +208,7 @@ def generate_x509_cert(user_id, project_id, bits=1024): csr = open(csrfile).read() shutil.rmtree(tmpdir) (serial, signed_csr) = sign_csr(csr, project_id) - fname = os.path.join(ca_folder(project_id), "newcerts/%s.pem" % serial) + fname = os.path.join(ca_folder(project_id), 'newcerts/%s.pem' % serial) cert = {'user_id': user_id, 'project_id': project_id, 'file_name': fname} @@ -227,8 +230,8 @@ def _ensure_project_folder(project_id): def generate_vpn_files(project_id): project_folder = ca_folder(project_id) - csr_fn = os.path.join(project_folder, "server.csr") - crt_fn = os.path.join(project_folder, "server.crt") + csr_fn = os.path.join(project_folder, 'server.csr') + crt_fn = os.path.join(project_folder, 'server.crt') genvpn_sh_path = os.path.join(os.path.dirname(__file__), 'CA', @@ -241,10 +244,10 @@ def generate_vpn_files(project_id): # TODO(vish): the shell scripts could all be done in python utils.execute('sh', genvpn_sh_path, project_id, _vpn_cert_subject(project_id)) - with open(csr_fn, "r") as csrfile: + with open(csr_fn, 'r') as csrfile: csr_text = csrfile.read() (serial, signed_csr) = sign_csr(csr_text, project_id) - with open(crt_fn, "w") as crtfile: + with open(crt_fn, 'w') as crtfile: crtfile.write(signed_csr) os.chdir(start) @@ -261,12 +264,12 @@ def sign_csr(csr_text, project_id=None): def _sign_csr(csr_text, ca_folder): tmpfolder = tempfile.mkdtemp() - inbound = os.path.join(tmpfolder, "inbound.csr") - outbound = os.path.join(tmpfolder, "outbound.csr") - csrfile = open(inbound, "w") + inbound = os.path.join(tmpfolder, 'inbound.csr') + outbound = os.path.join(tmpfolder, 'outbound.csr') + csrfile = open(inbound, 'w') csrfile.write(csr_text) csrfile.close() - LOG.debug(_("Flags path: %s"), ca_folder) + LOG.debug(_('Flags path: %s'), ca_folder) start = os.getcwd() # Change working dir to CA if not os.path.exists(ca_folder): @@ -276,13 +279,13 @@ def _sign_csr(csr_text, ca_folder): './openssl.cnf', '-infiles', inbound) out, _err = utils.execute('openssl', 'x509', '-in', outbound, '-serial', '-noout') - serial = string.strip(out.rpartition("=")[2]) + serial = string.strip(out.rpartition('=')[2]) os.chdir(start) - with open(outbound, "r") as crtfile: + with open(outbound, 'r') as crtfile: return (serial, crtfile.read()) -def mkreq(bits, subject="foo", ca=0): +def mkreq(bits, subject='foo', ca=0): pk = M2Crypto.EVP.PKey() req = M2Crypto.X509.Request() rsa = M2Crypto.RSA.gen_key(bits, 65537, callback=lambda: None) @@ -314,7 +317,7 @@ def mkcacert(subject='nova', years=1): cert.set_not_before(now) cert.set_not_after(nowPlusYear) issuer = M2Crypto.X509.X509_Name() - issuer.C = "US" + issuer.C = 'US' issuer.CN = subject cert.set_issuer(issuer) cert.set_pubkey(pkey) @@ -352,13 +355,15 @@ def mkcacert(subject='nova', years=1): # http://code.google.com/p/boto def compute_md5(fp): - """ + """Compute an md5 hash. + :type fp: file :param fp: File pointer to the file to MD5 hash. The file pointer will be reset to the beginning of the file before the method returns. :rtype: tuple - :return: the hex digest version of the MD5 hash + :returns: the hex digest version of the MD5 hash + """ m = hashlib.md5() fp.seek(0) diff --git a/nova/exception.py b/nova/exception.py index 4e2bbdbaf..3123b2f1f 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -16,31 +16,34 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Nova base exception handling, including decorator for re-raising -Nova-type exceptions. SHOULD include dedicated exception logging. +"""Nova base exception handling. + +Includes decorator for re-raising Nova-type exceptions. + +SHOULD include dedicated exception logging. + """ from nova import log as logging + + LOG = logging.getLogger('nova.exception') class ProcessExecutionError(IOError): - def __init__(self, stdout=None, stderr=None, exit_code=None, cmd=None, description=None): if description is None: - description = _("Unexpected error while running command.") + description = _('Unexpected error while running command.') if exit_code is None: exit_code = '-' - message = _("%(description)s\nCommand: %(cmd)s\n" - "Exit code: %(exit_code)s\nStdout: %(stdout)r\n" - "Stderr: %(stderr)r") % locals() + message = _('%(description)s\nCommand: %(cmd)s\n' + 'Exit code: %(exit_code)s\nStdout: %(stdout)r\n' + 'Stderr: %(stderr)r') % locals() IOError.__init__(self, message) class Error(Exception): - def __init__(self, message=None): super(Error, self).__init__(message) @@ -97,7 +100,7 @@ class TimeoutException(Error): class DBError(Error): - """Wraps an implementation specific exception""" + """Wraps an implementation specific exception.""" def __init__(self, inner_exception): self.inner_exception = inner_exception super(DBError, self).__init__(str(inner_exception)) @@ -108,7 +111,7 @@ def wrap_db_error(f): try: return f(*args, **kwargs) except Exception, e: - LOG.exception(_('DB exception wrapped')) + LOG.exception(_('DB exception wrapped.')) raise DBError(e) return _wrap _wrap.func_name = f.func_name diff --git a/nova/fakememcache.py b/nova/fakememcache.py index 67f46dbdc..e4f238aa9 100644 --- a/nova/fakememcache.py +++ b/nova/fakememcache.py @@ -18,14 +18,14 @@ """Super simple fake memcache client.""" -import utils +from nova import utils class Client(object): """Replicates a tiny subset of memcached client interface.""" def __init__(self, *args, **kwargs): - """Ignores the passed in args""" + """Ignores the passed in args.""" self.cache = {} def get(self, key): diff --git a/nova/flags.py b/nova/flags.py index f011ab383..d1b93f0a8 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -16,9 +16,13 @@ # License for the specific language governing permissions and limitations # under the License. -""" +"""Command-line flag library. + +Wraps gflags. + Package-level global flags are defined here, the rest are defined where they're used. + """ import getopt @@ -145,10 +149,12 @@ class FlagValues(gflags.FlagValues): class StrWrapper(object): - """Wrapper around FlagValues objects + """Wrapper around FlagValues objects. Wraps FlagValues objects for string.Template so that we're - sure to return strings.""" + sure to return strings. + + """ def __init__(self, context_objs): self.context_objs = context_objs @@ -169,6 +175,7 @@ def _GetCallingModule(): 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()): @@ -192,6 +199,7 @@ def __GetModuleName(globals_dict): 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: @@ -326,7 +334,7 @@ DEFINE_integer('auth_token_ttl', 3600, 'Seconds for auth tokens to linger') DEFINE_string('state_path', os.path.join(os.path.dirname(__file__), '../'), "Top-level directory for maintaining nova's state") DEFINE_string('lock_path', os.path.join(os.path.dirname(__file__), '../'), - "Directory for lock files") + 'Directory for lock files') DEFINE_string('logdir', None, 'output to a per-service log file in named ' 'directory') diff --git a/nova/log.py b/nova/log.py index ea94be194..096279f7c 100644 --- a/nova/log.py +++ b/nova/log.py @@ -16,16 +16,15 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Nova logging handler. +"""Nova logging handler. This module adds to logging functionality by adding the option to specify a context object when calling the various log methods. If the context object is not specified, default formatting is used. It also allows setting of formatting information through flags. -""" +""" import cStringIO import inspect @@ -41,34 +40,28 @@ from nova import version FLAGS = flags.FLAGS - flags.DEFINE_string('logging_context_format_string', '%(asctime)s %(levelname)s %(name)s ' '[%(request_id)s %(user)s ' '%(project)s] %(message)s', 'format string to use for log messages with context') - flags.DEFINE_string('logging_default_format_string', '%(asctime)s %(levelname)s %(name)s [-] ' '%(message)s', 'format string to use for log messages without context') - flags.DEFINE_string('logging_debug_format_suffix', 'from (pid=%(process)d) %(funcName)s' ' %(pathname)s:%(lineno)d', 'data to append to log format when level is DEBUG') - flags.DEFINE_string('logging_exception_prefix', '(%(name)s): TRACE: ', 'prefix each line of exception output with this format') - flags.DEFINE_list('default_log_levels', ['amqplib=WARN', 'sqlalchemy=WARN', 'boto=WARN', 'eventlet.wsgi.server=WARN'], 'list of logger=LEVEL pairs') - flags.DEFINE_bool('use_syslog', False, 'output to syslog') flags.DEFINE_string('logfile', None, 'output to named file') @@ -83,6 +76,8 @@ WARN = logging.WARN INFO = logging.INFO DEBUG = logging.DEBUG NOTSET = logging.NOTSET + + # methods getLogger = logging.getLogger debug = logging.debug @@ -93,6 +88,8 @@ error = logging.error exception = logging.exception critical = logging.critical log = logging.log + + # handlers StreamHandler = logging.StreamHandler WatchedFileHandler = logging.handlers.WatchedFileHandler @@ -127,17 +124,18 @@ def _get_log_file_path(binary=None): class NovaLogger(logging.Logger): - """ - NovaLogger manages request context and formatting. + """NovaLogger manages request context and formatting. This becomes the class that is instanciated by logging.getLogger. + """ + def __init__(self, name, level=NOTSET): logging.Logger.__init__(self, name, level) self.setup_from_flags() def setup_from_flags(self): - """Setup logger from flags""" + """Setup logger from flags.""" level = NOTSET for pair in FLAGS.default_log_levels: logger, _sep, level_name = pair.partition('=') @@ -148,7 +146,7 @@ class NovaLogger(logging.Logger): self.setLevel(level) def _log(self, level, msg, args, exc_info=None, extra=None, context=None): - """Extract context from any log call""" + """Extract context from any log call.""" if not extra: extra = {} if context: @@ -157,17 +155,17 @@ class NovaLogger(logging.Logger): return logging.Logger._log(self, level, msg, args, exc_info, extra) def addHandler(self, handler): - """Each handler gets our custom formatter""" + """Each handler gets our custom formatter.""" handler.setFormatter(_formatter) return logging.Logger.addHandler(self, handler) def audit(self, msg, *args, **kwargs): - """Shortcut for our AUDIT level""" + """Shortcut for our AUDIT level.""" if self.isEnabledFor(AUDIT): self._log(AUDIT, msg, args, **kwargs) def exception(self, msg, *args, **kwargs): - """Logging.exception doesn't handle kwargs, so breaks context""" + """Logging.exception doesn't handle kwargs, so breaks context.""" if not kwargs.get('exc_info'): kwargs['exc_info'] = 1 self.error(msg, *args, **kwargs) @@ -181,14 +179,13 @@ class NovaLogger(logging.Logger): for k in env.keys(): if not isinstance(env[k], str): env.pop(k) - message = "Environment: %s" % json.dumps(env) + message = 'Environment: %s' % json.dumps(env) kwargs.pop('exc_info') self.error(message, **kwargs) class NovaFormatter(logging.Formatter): - """ - A nova.context.RequestContext aware formatter configured through flags. + """A nova.context.RequestContext aware formatter configured through flags. The flags used to set format strings are: logging_context_foramt_string and logging_default_format_string. You can also specify @@ -197,10 +194,11 @@ class NovaFormatter(logging.Formatter): For information about what variables are available for the formatter see: http://docs.python.org/library/logging.html#formatter + """ def format(self, record): - """Uses contextstring if request_id is set, otherwise default""" + """Uses contextstring if request_id is set, otherwise default.""" if record.__dict__.get('request_id', None): self._fmt = FLAGS.logging_context_format_string else: @@ -214,20 +212,21 @@ class NovaFormatter(logging.Formatter): return logging.Formatter.format(self, record) def formatException(self, exc_info, record=None): - """Format exception output with FLAGS.logging_exception_prefix""" + """Format exception output with FLAGS.logging_exception_prefix.""" if not record: return logging.Formatter.formatException(self, exc_info) stringbuffer = cStringIO.StringIO() traceback.print_exception(exc_info[0], exc_info[1], exc_info[2], None, stringbuffer) - lines = stringbuffer.getvalue().split("\n") + lines = stringbuffer.getvalue().split('\n') stringbuffer.close() formatted_lines = [] for line in lines: pl = FLAGS.logging_exception_prefix % record.__dict__ - fl = "%s%s" % (pl, line) + fl = '%s%s' % (pl, line) formatted_lines.append(fl) - return "\n".join(formatted_lines) + return '\n'.join(formatted_lines) + _formatter = NovaFormatter() @@ -241,7 +240,7 @@ class NovaRootLogger(NovaLogger): NovaLogger.__init__(self, name, level) def setup_from_flags(self): - """Setup logger from flags""" + """Setup logger from flags.""" global _filelog if FLAGS.use_syslog: self.syslog = SysLogHandler(address='/dev/log') diff --git a/nova/manager.py b/nova/manager.py index 804a50479..34338ac04 100644 --- a/nova/manager.py +++ b/nova/manager.py @@ -16,7 +16,8 @@ # License for the specific language governing permissions and limitations # under the License. -""" +"""Base Manager class. + Managers are responsible for a certain aspect of the sytem. It is a logical grouping of code relating to a portion of the system. In general other components should be using the manager to make changes to the components that @@ -49,16 +50,19 @@ Managers will often provide methods for initial setup of a host or periodic tasksto a wrapping service. This module provides Manager, a base class for managers. + """ -from nova import utils from nova import flags from nova import log as logging +from nova import utils from nova.db import base from nova.scheduler import api + FLAGS = flags.FLAGS + LOG = logging.getLogger('nova.manager') @@ -70,23 +74,29 @@ class Manager(base.Base): super(Manager, self).__init__(db_driver) def periodic_tasks(self, context=None): - """Tasks to be run at a periodic interval""" + """Tasks to be run at a periodic interval.""" pass def init_host(self): - """Do any initialization that needs to be run if this is a standalone - service. Child classes should override this method.""" + """Handle initialization if this is a standalone service. + + Child classes should override this method. + + """ pass class SchedulerDependentManager(Manager): """Periodically send capability updates to the Scheduler services. - Services that need to update the Scheduler of their capabilities - should derive from this class. Otherwise they can derive from - manager.Manager directly. Updates are only sent after - update_service_capabilities is called with non-None values.""" - def __init__(self, host=None, db_driver=None, service_name="undefined"): + Services that need to update the Scheduler of their capabilities + should derive from this class. Otherwise they can derive from + manager.Manager directly. Updates are only sent after + update_service_capabilities is called with non-None values. + + """ + + def __init__(self, host=None, db_driver=None, service_name='undefined'): self.last_capabilities = None self.service_name = service_name super(SchedulerDependentManager, self).__init__(host, db_driver) @@ -96,9 +106,9 @@ class SchedulerDependentManager(Manager): self.last_capabilities = capabilities def periodic_tasks(self, context=None): - """Pass data back to the scheduler at a periodic interval""" + """Pass data back to the scheduler at a periodic interval.""" if self.last_capabilities: - LOG.debug(_("Notifying Schedulers of capabilities ...")) + LOG.debug(_('Notifying Schedulers of capabilities ...')) api.update_service_capabilities(context, self.service_name, self.host, self.last_capabilities) diff --git a/nova/quota.py b/nova/quota.py index 2b24c0b5b..d8b5d9a93 100644 --- a/nova/quota.py +++ b/nova/quota.py @@ -15,16 +15,15 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -""" -Quotas for instances, volumes, and floating ips -""" + +"""Quotas for instances, volumes, and floating ips.""" from nova import db from nova import exception from nova import flags -FLAGS = flags.FLAGS +FLAGS = flags.FLAGS flags.DEFINE_integer('quota_instances', 10, 'number of instances allowed per project') flags.DEFINE_integer('quota_cores', 20, @@ -64,7 +63,7 @@ def get_quota(context, project_id): def allowed_instances(context, num_instances, instance_type): - """Check quota and return min(num_instances, allowed_instances)""" + """Check quota and return min(num_instances, allowed_instances).""" project_id = context.project_id context = context.elevated() used_instances, used_cores = db.instance_data_get_for_project(context, @@ -79,7 +78,7 @@ def allowed_instances(context, num_instances, instance_type): def allowed_volumes(context, num_volumes, size): - """Check quota and return min(num_volumes, allowed_volumes)""" + """Check quota and return min(num_volumes, allowed_volumes).""" project_id = context.project_id context = context.elevated() used_volumes, used_gigabytes = db.volume_data_get_for_project(context, @@ -95,7 +94,7 @@ def allowed_volumes(context, num_volumes, size): def allowed_floating_ips(context, num_floating_ips): - """Check quota and return min(num_floating_ips, allowed_floating_ips)""" + """Check quota and return min(num_floating_ips, allowed_floating_ips).""" project_id = context.project_id context = context.elevated() used_floating_ips = db.floating_ip_count_by_project(context, project_id) @@ -105,7 +104,7 @@ def allowed_floating_ips(context, num_floating_ips): def allowed_metadata_items(context, num_metadata_items): - """Check quota; return min(num_metadata_items,allowed_metadata_items)""" + """Check quota; return min(num_metadata_items,allowed_metadata_items).""" project_id = context.project_id context = context.elevated() quota = get_quota(context, project_id) @@ -114,20 +113,20 @@ def allowed_metadata_items(context, num_metadata_items): def allowed_injected_files(context): - """Return the number of injected files allowed""" + """Return the number of injected files allowed.""" return FLAGS.quota_max_injected_files def allowed_injected_file_content_bytes(context): - """Return the number of bytes allowed per injected file content""" + """Return the number of bytes allowed per injected file content.""" return FLAGS.quota_max_injected_file_content_bytes def allowed_injected_file_path_bytes(context): - """Return the number of bytes allowed in an injected file path""" + """Return the number of bytes allowed in an injected file path.""" return FLAGS.quota_max_injected_file_path_bytes class QuotaError(exception.ApiError): - """Quota Exceeeded""" + """Quota Exceeeded.""" pass diff --git a/nova/rpc.py b/nova/rpc.py index b610cdf9b..2116f22c3 100644 --- a/nova/rpc.py +++ b/nova/rpc.py @@ -16,9 +16,12 @@ # License for the specific language governing permissions and limitations # under the License. -""" -AMQP-based RPC. Queues have consumers and publishers. +"""AMQP-based RPC. + +Queues have consumers and publishers. + No fan-out support yet. + """ import json @@ -40,17 +43,19 @@ from nova import log as logging from nova import utils -FLAGS = flags.FLAGS LOG = logging.getLogger('nova.rpc') + +FLAGS = flags.FLAGS flags.DEFINE_integer('rpc_thread_pool_size', 1024, 'Size of RPC thread pool') class Connection(carrot_connection.BrokerConnection): - """Connection instance object""" + """Connection instance object.""" + @classmethod def instance(cls, new=True): - """Returns the instance""" + """Returns the instance.""" if new or not hasattr(cls, '_instance'): params = dict(hostname=FLAGS.rabbit_host, port=FLAGS.rabbit_port, @@ -71,9 +76,11 @@ class Connection(carrot_connection.BrokerConnection): @classmethod def recreate(cls): - """Recreates the connection instance + """Recreates the connection instance. + + This is necessary to recover from some network errors/disconnects. - This is necessary to recover from some network errors/disconnects""" + """ try: del cls._instance except AttributeError, e: @@ -84,10 +91,12 @@ class Connection(carrot_connection.BrokerConnection): class Consumer(messaging.Consumer): - """Consumer base class + """Consumer base class. + + Contains methods for connecting the fetch method to async loops. - Contains methods for connecting the fetch method to async loops """ + def __init__(self, *args, **kwargs): for i in xrange(FLAGS.rabbit_max_retries): if i > 0: @@ -100,19 +109,18 @@ class Consumer(messaging.Consumer): 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: %(e)s. Trying again in %(fl_intv)d" - " seconds.") - % locals()) + LOG.error(_('AMQP server on %(fl_host)s:%(fl_port)d is' + ' unreachable: %(e)s. Trying again in %(fl_intv)d' + ' seconds.') % locals()) self.failed_connection = True if self.failed_connection: - LOG.error(_("Unable to connect to AMQP server " - "after %d tries. Shutting down."), + 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): - """Wraps the parent fetch with some logic for failed connections""" + """Wraps the parent fetch with some logic for failed connection.""" # TODO(vish): the logic for failed connections and logging should be # refactored into some sort of connection manager object try: @@ -125,14 +133,14 @@ class Consumer(messaging.Consumer): self.declare() super(Consumer, self).fetch(no_ack, auto_ack, enable_callbacks) if self.failed_connection: - LOG.error(_("Reconnected to queue")) + LOG.error(_('Reconnected to queue')) self.failed_connection = False # NOTE(vish): This is catching all errors because we really don't # want exceptions to be logged 10 times a second if some # persistent failure occurs. except Exception, e: # pylint: disable=W0703 if not self.failed_connection: - LOG.exception(_("Failed to fetch message from queue: %s" % e)) + LOG.exception(_('Failed to fetch message from queue: %s' % e)) self.failed_connection = True def attach_to_eventlet(self): @@ -143,8 +151,9 @@ class Consumer(messaging.Consumer): class AdapterConsumer(Consumer): - """Calls methods on a proxy object based on method and args""" - def __init__(self, connection=None, topic="broadcast", proxy=None): + """Calls methods on a proxy object based on method and args.""" + + def __init__(self, connection=None, topic='broadcast', proxy=None): LOG.debug(_('Initing the Adapter Consumer for %s') % topic) self.proxy = proxy self.pool = greenpool.GreenPool(FLAGS.rpc_thread_pool_size) @@ -156,13 +165,14 @@ class AdapterConsumer(Consumer): @exception.wrap_exception def _receive(self, message_data, message): - """Magically looks for a method on the proxy object and calls it + """Magically looks for a method on the proxy object and calls it. Message data should be a dictionary with two keys: method: string representing the method to call args: dictionary of arg: value Example: {'method': 'echo', 'args': {'value': 42}} + """ LOG.debug(_('received %s') % message_data) msg_id = message_data.pop('_msg_id', None) @@ -189,22 +199,23 @@ class AdapterConsumer(Consumer): if msg_id: msg_reply(msg_id, rval, None) except Exception as e: - logging.exception("Exception during message handling") + logging.exception('Exception during message handling') if msg_id: msg_reply(msg_id, None, sys.exc_info()) return class Publisher(messaging.Publisher): - """Publisher base class""" + """Publisher base class.""" pass class TopicAdapterConsumer(AdapterConsumer): - """Consumes messages on a specific topic""" - exchange_type = "topic" + """Consumes messages on a specific topic.""" + + exchange_type = 'topic' - def __init__(self, connection=None, topic="broadcast", proxy=None): + def __init__(self, connection=None, topic='broadcast', proxy=None): self.queue = topic self.routing_key = topic self.exchange = FLAGS.control_exchange @@ -214,27 +225,29 @@ class TopicAdapterConsumer(AdapterConsumer): class FanoutAdapterConsumer(AdapterConsumer): - """Consumes messages from a fanout exchange""" - exchange_type = "fanout" + """Consumes messages from a fanout exchange.""" - def __init__(self, connection=None, topic="broadcast", proxy=None): - self.exchange = "%s_fanout" % topic + exchange_type = 'fanout' + + def __init__(self, connection=None, topic='broadcast', proxy=None): + self.exchange = '%s_fanout' % topic self.routing_key = topic unique = uuid.uuid4().hex - self.queue = "%s_fanout_%s" % (topic, unique) + self.queue = '%s_fanout_%s' % (topic, unique) self.durable = False - LOG.info(_("Created '%(exchange)s' fanout exchange " - "with '%(key)s' routing key"), - dict(exchange=self.exchange, key=self.routing_key)) + LOG.info(_('Created "%(exchange)s" fanout exchange ' + 'with "%(key)s" routing key'), + dict(exchange=self.exchange, key=self.routing_key)) super(FanoutAdapterConsumer, self).__init__(connection=connection, topic=topic, proxy=proxy) class TopicPublisher(Publisher): - """Publishes messages on a specific topic""" - exchange_type = "topic" + """Publishes messages on a specific topic.""" + + exchange_type = 'topic' - def __init__(self, connection=None, topic="broadcast"): + def __init__(self, connection=None, topic='broadcast'): self.routing_key = topic self.exchange = FLAGS.control_exchange self.durable = False @@ -243,20 +256,22 @@ class TopicPublisher(Publisher): class FanoutPublisher(Publisher): """Publishes messages to a fanout exchange.""" - exchange_type = "fanout" + + exchange_type = 'fanout' def __init__(self, topic, connection=None): - self.exchange = "%s_fanout" % topic - self.queue = "%s_fanout" % topic + self.exchange = '%s_fanout' % topic + self.queue = '%s_fanout' % topic self.durable = False - LOG.info(_("Creating '%(exchange)s' fanout exchange"), - dict(exchange=self.exchange)) + LOG.info(_('Creating "%(exchange)s" fanout exchange'), + dict(exchange=self.exchange)) super(FanoutPublisher, self).__init__(connection=connection) class DirectConsumer(Consumer): - """Consumes messages directly on a channel specified by msg_id""" - exchange_type = "direct" + """Consumes messages directly on a channel specified by msg_id.""" + + exchange_type = 'direct' def __init__(self, connection=None, msg_id=None): self.queue = msg_id @@ -268,8 +283,9 @@ class DirectConsumer(Consumer): class DirectPublisher(Publisher): - """Publishes messages directly on a channel specified by msg_id""" - exchange_type = "direct" + """Publishes messages directly on a channel specified by msg_id.""" + + exchange_type = 'direct' def __init__(self, connection=None, msg_id=None): self.routing_key = msg_id @@ -279,9 +295,9 @@ class DirectPublisher(Publisher): def msg_reply(msg_id, reply=None, failure=None): - """Sends a reply or an error on the channel signified by msg_id + """Sends a reply or an error on the channel signified by msg_id. - failure should be a sys.exc_info() tuple. + Failure should be a sys.exc_info() tuple. """ if failure: @@ -303,17 +319,20 @@ def msg_reply(msg_id, reply=None, failure=None): class RemoteError(exception.Error): - """Signifies that a remote class has raised an exception + """Signifies that a remote class has raised an exception. Containes a string representation of the type of the original exception, the value of the original exception, and the traceback. These are sent to the parent as a joined string so printing the exception - contains all of the relevent info.""" + contains all of the relevent info. + + """ + def __init__(self, exc_type, value, traceback): self.exc_type = exc_type self.value = value self.traceback = traceback - super(RemoteError, self).__init__("%s %s\n%s" % (exc_type, + super(RemoteError, self).__init__('%s %s\n%s' % (exc_type, value, traceback)) @@ -339,6 +358,7 @@ def _pack_context(msg, context): context out into a bunch of separate keys. If we want to support more arguments in rabbit messages, we may want to do the same for args at some point. + """ context = dict([('_context_%s' % key, value) for (key, value) in context.to_dict().iteritems()]) @@ -346,11 +366,11 @@ def _pack_context(msg, context): def call(context, topic, msg): - """Sends a message on a topic and wait for a response""" - LOG.debug(_("Making asynchronous call on %s ..."), topic) + """Sends a message on a topic and wait for a response.""" + LOG.debug(_('Making asynchronous call on %s ...'), topic) msg_id = uuid.uuid4().hex msg.update({'_msg_id': msg_id}) - LOG.debug(_("MSG_ID is %s") % (msg_id)) + LOG.debug(_('MSG_ID is %s') % (msg_id)) _pack_context(msg, context) class WaitMessage(object): @@ -387,8 +407,8 @@ def call(context, topic, msg): def cast(context, topic, msg): - """Sends a message on a topic without waiting for a response""" - LOG.debug(_("Making asynchronous cast on %s..."), topic) + """Sends a message on a topic without waiting for a response.""" + LOG.debug(_('Making asynchronous cast on %s...'), topic) _pack_context(msg, context) conn = Connection.instance() publisher = TopicPublisher(connection=conn, topic=topic) @@ -397,8 +417,8 @@ def cast(context, topic, msg): def fanout_cast(context, topic, msg): - """Sends a message on a fanout exchange without waiting for a response""" - LOG.debug(_("Making asynchronous fanout cast...")) + """Sends a message on a fanout exchange without waiting for a response.""" + LOG.debug(_('Making asynchronous fanout cast...')) _pack_context(msg, context) conn = Connection.instance() publisher = FanoutPublisher(topic, connection=conn) @@ -407,14 +427,14 @@ def fanout_cast(context, topic, msg): def generic_response(message_data, message): - """Logs a result and exits""" + """Logs a result and exits.""" LOG.debug(_('response %s'), message_data) message.ack() sys.exit(0) def send_message(topic, message, wait=True): - """Sends a message for testing""" + """Sends a message for testing.""" msg_id = uuid.uuid4().hex message.update({'_msg_id': msg_id}) LOG.debug(_('topic is %s'), topic) @@ -425,14 +445,14 @@ def send_message(topic, message, wait=True): queue=msg_id, exchange=msg_id, auto_delete=True, - exchange_type="direct", + exchange_type='direct', routing_key=msg_id) consumer.register_callback(generic_response) publisher = messaging.Publisher(connection=Connection.instance(), exchange=FLAGS.control_exchange, durable=False, - exchange_type="topic", + exchange_type='topic', routing_key=topic) publisher.send(message) publisher.close() @@ -441,8 +461,8 @@ def send_message(topic, message, wait=True): consumer.wait() -if __name__ == "__main__": - # NOTE(vish): you can send messages from the command line using - # topic and a json sting representing a dictionary - # for the method +if __name__ == '__main__': + # You can send messages from the command line using + # topic and a json string representing a dictionary + # for the method send_message(sys.argv[1], json.loads(sys.argv[2])) diff --git a/nova/service.py b/nova/service.py index 47c0b96c0..2532b9df2 100644 --- a/nova/service.py +++ b/nova/service.py @@ -17,9 +17,7 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Generic Node baseclass for all workers that run on hosts -""" +"""Generic Node baseclass for all workers that run on hosts.""" import inspect import os @@ -30,13 +28,11 @@ from eventlet import event from eventlet import greenthread from eventlet import greenpool -from sqlalchemy.exc import OperationalError - from nova import context from nova import db from nova import exception -from nova import log as logging from nova import flags +from nova import log as logging from nova import rpc from nova import utils from nova import version @@ -79,7 +75,7 @@ class Service(object): def start(self): vcs_string = version.version_string_with_vcs() - logging.audit(_("Starting %(topic)s node (version %(vcs_string)s)"), + logging.audit(_('Starting %(topic)s node (version %(vcs_string)s)'), {'topic': self.topic, 'vcs_string': vcs_string}) self.manager.init_host() self.model_disconnected = False @@ -140,29 +136,24 @@ class Service(object): return getattr(manager, key) @classmethod - def create(cls, - host=None, - binary=None, - topic=None, - manager=None, - report_interval=None, - periodic_interval=None): + def create(cls, host=None, binary=None, topic=None, manager=None, + report_interval=None, periodic_interval=None): """Instantiates class and passes back application object. - Args: - host, defaults to FLAGS.host - binary, defaults to basename of executable - topic, defaults to bin_name - "nova-" part - manager, defaults to FLAGS._manager - report_interval, defaults to FLAGS.report_interval - periodic_interval, defaults to FLAGS.periodic_interval + :param host: defaults to FLAGS.host + :param binary: defaults to basename of executable + :param topic: defaults to bin_name - 'nova-' part + :param manager: defaults to FLAGS._manager + :param report_interval: defaults to FLAGS.report_interval + :param periodic_interval: defaults to FLAGS.periodic_interval + """ if not host: host = FLAGS.host if not binary: binary = os.path.basename(inspect.stack()[-1][1]) if not topic: - topic = binary.rpartition("nova-")[2] + topic = binary.rpartition('nova-')[2] if not manager: manager = FLAGS.get('%s_manager' % topic, None) if not report_interval: @@ -175,12 +166,12 @@ class Service(object): return service_obj def kill(self): - """Destroy the service object in the datastore""" + """Destroy the service object in the datastore.""" self.stop() try: db.service_destroy(context.get_admin_context(), self.service_id) except exception.NotFound: - logging.warn(_("Service killed that has no database entry")) + logging.warn(_('Service killed that has no database entry')) def stop(self): for x in self.timers: @@ -198,7 +189,7 @@ class Service(object): pass def periodic_tasks(self): - """Tasks to be run at a periodic interval""" + """Tasks to be run at a periodic interval.""" self.manager.periodic_tasks(context.get_admin_context()) def report_state(self): @@ -208,8 +199,8 @@ class Service(object): try: service_ref = db.service_get(ctxt, self.service_id) except exception.NotFound: - logging.debug(_("The service database object disappeared, " - "Recreating it.")) + logging.debug(_('The service database object disappeared, ' + 'Recreating it.')) self._create_service_ref(ctxt) service_ref = db.service_get(ctxt, self.service_id) @@ -218,23 +209,24 @@ class Service(object): {'report_count': service_ref['report_count'] + 1}) # TODO(termie): make this pattern be more elegant. - if getattr(self, "model_disconnected", False): + if getattr(self, 'model_disconnected', False): self.model_disconnected = False - logging.error(_("Recovered model server connection!")) + logging.error(_('Recovered model server connection!')) # TODO(vish): this should probably only catch connection errors except Exception: # pylint: disable=W0702 - if not getattr(self, "model_disconnected", False): + if not getattr(self, 'model_disconnected', False): self.model_disconnected = True - logging.exception(_("model server went away")) + logging.exception(_('model server went away')) class WsgiService(object): """Base class for WSGI based services. For each api you define, you must also define these flags: - :_listen: The address on which to listen - :_listen_port: The port on which to listen + :_listen: The address on which to listen + :_listen_port: The port on which to listen + """ def __init__(self, conf, apis): @@ -250,13 +242,14 @@ class WsgiService(object): class ApiService(WsgiService): - """Class for our nova-api service""" + """Class for our nova-api service.""" + @classmethod def create(cls, conf=None): if not conf: conf = wsgi.paste_config_file(FLAGS.api_paste_config) if not conf: - message = (_("No paste configuration found for: %s"), + message = (_('No paste configuration found for: %s'), FLAGS.api_paste_config) raise exception.Error(message) api_endpoints = ['ec2', 'osapi'] @@ -280,11 +273,11 @@ def serve(*services): FLAGS.ParseNewFlags() name = '_'.join(x.binary for x in services) - logging.debug(_("Serving %s"), name) - logging.debug(_("Full set of FLAGS:")) + logging.debug(_('Serving %s'), name) + logging.debug(_('Full set of FLAGS:')) for flag in FLAGS: flag_get = FLAGS.get(flag, None) - logging.debug("%(flag)s : %(flag_get)s" % locals()) + logging.debug('%(flag)s : %(flag_get)s' % locals()) for x in services: x.start() @@ -315,20 +308,20 @@ def serve_wsgi(cls, conf=None): def _run_wsgi(paste_config_file, apis): - logging.debug(_("Using paste.deploy config at: %s"), paste_config_file) + logging.debug(_('Using paste.deploy config at: %s'), paste_config_file) apps = [] for api in apis: config = wsgi.load_paste_configuration(paste_config_file, api) if config is None: - logging.debug(_("No paste configuration for app: %s"), api) + logging.debug(_('No paste configuration for app: %s'), api) continue - logging.debug(_("App Config: %(api)s\n%(config)r") % locals()) - logging.info(_("Running %s API"), api) + logging.debug(_('App Config: %(api)s\n%(config)r') % locals()) + logging.info(_('Running %s API'), api) app = wsgi.load_paste_app(paste_config_file, api) - apps.append((app, getattr(FLAGS, "%s_listen_port" % api), - getattr(FLAGS, "%s_listen" % api))) + apps.append((app, getattr(FLAGS, '%s_listen_port' % api), + getattr(FLAGS, '%s_listen' % api))) if len(apps) == 0: - logging.error(_("No known API applications configured in %s."), + logging.error(_('No known API applications configured in %s.'), paste_config_file) return diff --git a/nova/test.py b/nova/test.py index 3b608520a..4deb2a175 100644 --- a/nova/test.py +++ b/nova/test.py @@ -16,12 +16,12 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Base classes for our unit tests. -Allows overriding of flags for use of fakes, -and some black magic for inline callbacks. -""" +"""Base classes for our unit tests. +Allows overriding of flags for use of fakes, and some black magic for +inline callbacks. + +""" import datetime import functools @@ -52,9 +52,9 @@ flags.DEFINE_bool('fake_tests', True, def skip_if_fake(func): - """Decorator that skips a test if running in fake mode""" + """Decorator that skips a test if running in fake mode.""" def _skipper(*args, **kw): - """Wrapped skipper function""" + """Wrapped skipper function.""" if FLAGS.fake_tests: raise unittest.SkipTest('Test cannot be run in fake mode') else: @@ -63,9 +63,10 @@ def skip_if_fake(func): class TestCase(unittest.TestCase): - """Test case base class for all unit tests""" + """Test case base class for all unit tests.""" + def setUp(self): - """Run before each test method to initialize test environment""" + """Run before each test method to initialize test environment.""" super(TestCase, self).setUp() # NOTE(vish): We need a better method for creating fixtures for tests # now that we have some required db setup for the system @@ -86,8 +87,7 @@ class TestCase(unittest.TestCase): self._original_flags = FLAGS.FlagValuesDict() def tearDown(self): - """Runs after each test method to finalize/tear down test - environment.""" + """Runs after each test method to tear down test environment.""" try: self.mox.UnsetStubs() self.stubs.UnsetAll() @@ -121,7 +121,7 @@ class TestCase(unittest.TestCase): pass def flags(self, **kw): - """Override flag variables for a test""" + """Override flag variables for a test.""" for k, v in kw.iteritems(): if k in self.flag_overrides: self.reset_flags() @@ -131,7 +131,11 @@ class TestCase(unittest.TestCase): setattr(FLAGS, k, v) def reset_flags(self): - """Resets all flag variables for the test. Runs after each test""" + """Resets all flag variables for the test. + + Runs after each test. + + """ FLAGS.Reset() for k, v in self._original_flags.iteritems(): setattr(FLAGS, k, v) @@ -158,7 +162,6 @@ class TestCase(unittest.TestCase): def _monkey_patch_wsgi(self): """Allow us to kill servers spawned by wsgi.Server.""" - # TODO(termie): change these patterns to use functools self.original_start = wsgi.Server.start @functools.wraps(self.original_start) @@ -189,12 +192,13 @@ class TestCase(unittest.TestCase): If you don't care (or don't know) a given value, you can specify the string DONTCARE as the value. This will cause that dict-item to be skipped. + """ def raise_assertion(msg): d1str = str(d1) d2str = str(d2) - base_msg = ("Dictionaries do not match. %(msg)s d1: %(d1str)s " - "d2: %(d2str)s" % locals()) + base_msg = ('Dictionaries do not match. %(msg)s d1: %(d1str)s ' + 'd2: %(d2str)s' % locals()) raise AssertionError(base_msg) d1keys = set(d1.keys()) @@ -202,8 +206,8 @@ class TestCase(unittest.TestCase): if d1keys != d2keys: d1only = d1keys - d2keys d2only = d2keys - d1keys - raise_assertion("Keys in d1 and not d2: %(d1only)s. " - "Keys in d2 and not d1: %(d2only)s" % locals()) + raise_assertion('Keys in d1 and not d2: %(d1only)s. ' + 'Keys in d2 and not d1: %(d2only)s' % locals()) for key in d1keys: d1value = d1[key] @@ -217,19 +221,19 @@ class TestCase(unittest.TestCase): "d2['%(key)s']=%(d2value)s" % locals()) def assertDictListMatch(self, L1, L2): - """Assert a list of dicts are equivalent""" + """Assert a list of dicts are equivalent.""" def raise_assertion(msg): L1str = str(L1) L2str = str(L2) - base_msg = ("List of dictionaries do not match: %(msg)s " - "L1: %(L1str)s L2: %(L2str)s" % locals()) + base_msg = ('List of dictionaries do not match: %(msg)s ' + 'L1: %(L1str)s L2: %(L2str)s' % locals()) raise AssertionError(base_msg) L1count = len(L1) L2count = len(L2) if L1count != L2count: - raise_assertion("Length mismatch: len(L1)=%(L1count)d != " - "len(L2)=%(L2count)d" % locals()) + raise_assertion('Length mismatch: len(L1)=%(L1count)d != ' + 'len(L2)=%(L2count)d' % locals()) for d1, d2 in zip(L1, L2): self.assertDictMatch(d1, d2) diff --git a/nova/utils.py b/nova/utils.py index 76cba1a08..59f694196 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -17,9 +17,7 @@ # License for the specific language governing permissions and limitations # under the License. -""" -System-level utilities and helper functions. -""" +"""Utilities and helper functions.""" import base64 import datetime @@ -43,9 +41,8 @@ from eventlet import event from eventlet import greenthread from eventlet import semaphore from eventlet.green import subprocess -None + from nova import exception -from nova.exception import ProcessExecutionError from nova import flags from nova import log as logging @@ -56,7 +53,7 @@ FLAGS = flags.FLAGS def import_class(import_str): - """Returns a class from a string including module and class""" + """Returns a class from a string including module and class.""" mod_str, _sep, class_str = import_str.rpartition('.') try: __import__(mod_str) @@ -67,7 +64,7 @@ def import_class(import_str): def import_object(import_str): - """Returns an object including a module or module and class""" + """Returns an object including a module or module and class.""" try: __import__(import_str) return sys.modules[import_str] @@ -99,11 +96,12 @@ def vpn_ping(address, port, timeout=0.05, session_id=None): cli_id = 64 bit identifier ? = unknown, probably flags/padding bit 9 was 1 and the rest were 0 in testing + """ if session_id is None: session_id = random.randint(0, 0xffffffffffffffff) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - data = struct.pack("!BQxxxxxx", 0x38, session_id) + data = struct.pack('!BQxxxxxx', 0x38, session_id) sock.sendto(data, (address, port)) sock.settimeout(timeout) try: @@ -112,7 +110,7 @@ def vpn_ping(address, port, timeout=0.05, session_id=None): return False finally: sock.close() - fmt = "!BQxxxxxQxxxx" + fmt = '!BQxxxxxQxxxx' if len(received) != struct.calcsize(fmt): print struct.calcsize(fmt) return False @@ -122,15 +120,8 @@ def vpn_ping(address, port, timeout=0.05, session_id=None): def fetchfile(url, target): - LOG.debug(_("Fetching %s") % url) -# c = pycurl.Curl() -# fp = open(target, "wb") -# c.setopt(c.URL, url) -# c.setopt(c.WRITEDATA, fp) -# c.perform() -# c.close() -# fp.close() - execute("curl", "--fail", url, "-o", target) + LOG.debug(_('Fetching %s') % url) + execute('curl', '--fail', url, '-o', target) def execute(*cmd, **kwargs): @@ -147,7 +138,7 @@ def execute(*cmd, **kwargs): while attempts > 0: attempts -= 1 try: - LOG.debug(_("Running cmd (subprocess): %s"), ' '.join(cmd)) + LOG.debug(_('Running cmd (subprocess): %s'), ' '.join(cmd)) env = os.environ.copy() if addl_env: env.update(addl_env) @@ -163,20 +154,21 @@ def execute(*cmd, **kwargs): result = obj.communicate() obj.stdin.close() if obj.returncode: - LOG.debug(_("Result was %s") % obj.returncode) + LOG.debug(_('Result was %s') % obj.returncode) if type(check_exit_code) == types.IntType \ and obj.returncode != check_exit_code: (stdout, stderr) = result - raise ProcessExecutionError(exit_code=obj.returncode, - stdout=stdout, - stderr=stderr, - cmd=' '.join(cmd)) + raise exception.ProcessExecutionError( + exit_code=obj.returncode, + stdout=stdout, + stderr=stderr, + cmd=' '.join(cmd)) return result - except ProcessExecutionError: + except exception.ProcessExecutionError: if not attempts: raise else: - LOG.debug(_("%r failed. Retrying."), cmd) + LOG.debug(_('%r failed. Retrying.'), cmd) if delay_on_retry: greenthread.sleep(random.randint(20, 200) / 100.0) finally: @@ -188,13 +180,13 @@ def execute(*cmd, **kwargs): def ssh_execute(ssh, cmd, process_input=None, addl_env=None, check_exit_code=True): - LOG.debug(_("Running cmd (SSH): %s"), ' '.join(cmd)) + LOG.debug(_('Running cmd (SSH): %s'), ' '.join(cmd)) if addl_env: - raise exception.Error("Environment not supported over SSH") + raise exception.Error('Environment not supported over SSH') if process_input: # This is (probably) fixable if we need it... - raise exception.Error("process_input not supported over SSH") + raise exception.Error('process_input not supported over SSH') stdin_stream, stdout_stream, stderr_stream = ssh.exec_command(cmd) channel = stdout_stream.channel @@ -212,7 +204,7 @@ def ssh_execute(ssh, cmd, process_input=None, # exit_status == -1 if no exit code was returned if exit_status != -1: - LOG.debug(_("Result was %s") % exit_status) + LOG.debug(_('Result was %s') % exit_status) if check_exit_code and exit_status != 0: raise exception.ProcessExecutionError(exit_code=exit_status, stdout=stdout, @@ -251,7 +243,7 @@ def debug(arg): def runthis(prompt, *cmd, **kwargs): - LOG.debug(_("Running %s"), (" ".join(cmd))) + LOG.debug(_('Running %s'), (' '.join(cmd))) rv, err = execute(*cmd, **kwargs) @@ -266,48 +258,49 @@ def generate_mac(): random.randint(0x00, 0x7f), random.randint(0x00, 0xff), random.randint(0x00, 0xff)] - return ':'.join(map(lambda x: "%02x" % x, mac)) + return ':'.join(map(lambda x: '%02x' % x, mac)) # Default symbols to use for passwords. Avoids visually confusing characters. # ~6 bits per symbol -DEFAULT_PASSWORD_SYMBOLS = ("23456789" # Removed: 0,1 - "ABCDEFGHJKLMNPQRSTUVWXYZ" # Removed: I, O - "abcdefghijkmnopqrstuvwxyz") # Removed: l +DEFAULT_PASSWORD_SYMBOLS = ('23456789' # Removed: 0,1 + 'ABCDEFGHJKLMNPQRSTUVWXYZ' # Removed: I, O + 'abcdefghijkmnopqrstuvwxyz') # Removed: l # ~5 bits per symbol -EASIER_PASSWORD_SYMBOLS = ("23456789" # Removed: 0, 1 - "ABCDEFGHJKLMNPQRSTUVWXYZ") # Removed: I, O +EASIER_PASSWORD_SYMBOLS = ('23456789' # Removed: 0, 1 + 'ABCDEFGHJKLMNPQRSTUVWXYZ') # Removed: I, O def generate_password(length=20, symbols=DEFAULT_PASSWORD_SYMBOLS): """Generate a random password from the supplied symbols. Believed to be reasonably secure (with a reasonable password length!) + """ r = random.SystemRandom() - return "".join([r.choice(symbols) for _i in xrange(length)]) + return ''.join([r.choice(symbols) for _i in xrange(length)]) def last_octet(address): - return int(address.split(".")[-1]) + return int(address.split('.')[-1]) def get_my_linklocal(interface): try: - if_str = execute("ip", "-f", "inet6", "-o", "addr", "show", interface) - condition = "\s+inet6\s+([0-9a-f:]+)/\d+\s+scope\s+link" + if_str = execute('ip', '-f', 'inet6', '-o', 'addr', 'show', interface) + condition = '\s+inet6\s+([0-9a-f:]+)/\d+\s+scope\s+link' links = [re.search(condition, x) for x in if_str[0].split('\n')] address = [w.group(1) for w in links if w is not None] if address[0] is not None: return address[0] else: - raise exception.Error(_("Link Local address is not found.:%s") + raise exception.Error(_('Link Local address is not found.:%s') % if_str) except Exception as ex: raise exception.Error(_("Couldn't get Link Local IP of %(interface)s" - " :%(ex)s") % locals()) + " :%(ex)s") % locals()) def to_global_ipv6(prefix, mac): @@ -319,15 +312,15 @@ def to_global_ipv6(prefix, mac): return (mac64_addr ^ netaddr.IPAddress('::0200:0:0:0') | maskIP).\ format() except TypeError: - raise TypeError(_("Bad mac for to_global_ipv6: %s") % mac) + raise TypeError(_('Bad mac for to_global_ipv6: %s') % mac) def to_mac(ipv6_address): address = netaddr.IPAddress(ipv6_address) - mask1 = netaddr.IPAddress("::ffff:ffff:ffff:ffff") - mask2 = netaddr.IPAddress("::0200:0:0:0") + mask1 = netaddr.IPAddress('::ffff:ffff:ffff:ffff') + mask2 = netaddr.IPAddress('::0200:0:0:0') mac64 = netaddr.EUI(int(address & mask1 ^ mask2)).words - return ":".join(["%02x" % i for i in mac64[0:3] + mac64[5:8]]) + return ':'.join(['%02x' % i for i in mac64[0:3] + mac64[5:8]]) def utcnow(): @@ -341,7 +334,7 @@ utcnow.override_time = None def is_older_than(before, seconds): - """Return True if before is older than seconds""" + """Return True if before is older than seconds.""" return utcnow() - before > datetime.timedelta(seconds=seconds) @@ -379,7 +372,7 @@ def isotime(at=None): def parse_isotime(timestr): - """Turn an iso formatted time back into a datetime""" + """Turn an iso formatted time back into a datetime.""" return datetime.datetime.strptime(timestr, TIME_FORMAT) @@ -433,16 +426,19 @@ class LazyPluggable(object): class LoopingCallDone(Exception): - """The poll-function passed to LoopingCall can raise this exception to + """Exception to break out and stop a LoopingCall. + + The poll-function passed to LoopingCall can raise this exception to break out of the loop normally. This is somewhat analogous to StopIteration. An optional return-value can be included as the argument to the exception; this return-value will be returned by LoopingCall.wait() + """ def __init__(self, retvalue=True): - """:param retvalue: Value that LoopingCall.wait() should return""" + """:param retvalue: Value that LoopingCall.wait() should return.""" self.retvalue = retvalue @@ -493,7 +489,7 @@ def xhtml_escape(value): http://github.com/facebook/tornado/blob/master/tornado/escape.py """ - return saxutils.escape(value, {'"': """}) + return saxutils.escape(value, {'"': '"'}) def utf8(value): @@ -504,7 +500,7 @@ def utf8(value): """ if isinstance(value, unicode): - return value.encode("utf-8") + return value.encode('utf-8') assert isinstance(value, str) return value @@ -554,7 +550,7 @@ class _NoopContextManager(object): def synchronized(name, external=False): - """Synchronization decorator + """Synchronization decorator. Decorating a method like so: @synchronized('mylock') @@ -578,6 +574,7 @@ def synchronized(name, external=False): multiple processes. This means that if two different workers both run a a method decorated with @synchronized('mylock', external=True), only one of them will execute at a time. + """ def wrap(f): @@ -590,13 +587,13 @@ def synchronized(name, external=False): _semaphores[name] = semaphore.Semaphore() sem = _semaphores[name] LOG.debug(_('Attempting to grab semaphore "%(lock)s" for method ' - '"%(method)s"...' % {"lock": name, - "method": f.__name__})) + '"%(method)s"...' % {'lock': name, + 'method': f.__name__})) with sem: if external: LOG.debug(_('Attempting to grab file lock "%(lock)s" for ' 'method "%(method)s"...' % - {"lock": name, "method": f.__name__})) + {'lock': name, 'method': f.__name__})) lock_file_path = os.path.join(FLAGS.lock_path, 'nova-%s.lock' % name) lock = lockfile.FileLock(lock_file_path) @@ -617,21 +614,23 @@ def synchronized(name, external=False): def get_from_path(items, path): - """ Returns a list of items matching the specified path. Takes an - XPath-like expression e.g. prop1/prop2/prop3, and for each item in items, - looks up items[prop1][prop2][prop3]. Like XPath, if any of the + """Returns a list of items matching the specified path. + + Takes an XPath-like expression e.g. prop1/prop2/prop3, and for each item + in items, looks up items[prop1][prop2][prop3]. Like XPath, if any of the intermediate results are lists it will treat each list item individually. A 'None' in items or any child expressions will be ignored, this function will not throw because of None (anywhere) in items. The returned list - will contain no None values.""" + will contain no None values. + """ if path is None: - raise exception.Error("Invalid mini_xpath") + raise exception.Error('Invalid mini_xpath') - (first_token, sep, remainder) = path.partition("/") + (first_token, sep, remainder) = path.partition('/') - if first_token == "": - raise exception.Error("Invalid mini_xpath") + if first_token == '': + raise exception.Error('Invalid mini_xpath') results = [] @@ -645,7 +644,7 @@ def get_from_path(items, path): for item in items: if item is None: continue - get_method = getattr(item, "get", None) + get_method = getattr(item, 'get', None) if get_method is None: continue child = get_method(first_token) @@ -666,7 +665,7 @@ def get_from_path(items, path): def flatten_dict(dict_, flattened=None): - """Recursively flatten a nested dictionary""" + """Recursively flatten a nested dictionary.""" flattened = flattened or {} for key, value in dict_.iteritems(): if hasattr(value, 'iteritems'): @@ -677,9 +676,7 @@ def flatten_dict(dict_, flattened=None): def partition_dict(dict_, keys): - """Return two dicts, one containing only `keys` the other containing - everything but `keys` - """ + """Return two dicts, one with `keys` the other with everything else.""" intersection = {} difference = {} for key, value in dict_.iteritems(): @@ -691,9 +688,7 @@ def partition_dict(dict_, keys): def map_dict_keys(dict_, key_map): - """Return a dictionary in which the dictionaries keys are mapped to - new keys. - """ + """Return a dict in which the dictionaries keys are mapped to new keys.""" mapped = {} for key, value in dict_.iteritems(): mapped_key = key_map[key] if key in key_map else key @@ -702,15 +697,15 @@ def map_dict_keys(dict_, key_map): def subset_dict(dict_, keys): - """Return a dict that only contains a subset of keys""" + """Return a dict that only contains a subset of keys.""" subset = partition_dict(dict_, keys)[0] return subset def check_isinstance(obj, cls): - """Checks that obj is of type cls, and lets PyLint infer types""" + """Checks that obj is of type cls, and lets PyLint infer types.""" if isinstance(obj, cls): return obj - raise Exception(_("Expected object of type: %s") % (str(cls))) + raise Exception(_('Expected object of type: %s') % (str(cls))) # TODO(justinsb): Can we make this better?? return cls() # Ugly PyLint hack diff --git a/nova/version.py b/nova/version.py index c43d12cf8..1f8d08e8c 100644 --- a/nova/version.py +++ b/nova/version.py @@ -21,9 +21,9 @@ except ImportError: 'revision_id': 'LOCALREVISION', 'revno': 0} + NOVA_VERSION = ['2011', '3'] YEAR, COUNT = NOVA_VERSION - FINAL = False # This becomes true at Release Candidate time @@ -39,8 +39,8 @@ def version_string(): def vcs_version_string(): - return "%s:%s" % (version_info['branch_nick'], version_info['revision_id']) + return '%s:%s' % (version_info['branch_nick'], version_info['revision_id']) def version_string_with_vcs(): - return "%s-%s" % (canonical_version_string(), vcs_version_string()) + return '%s-%s' % (canonical_version_string(), vcs_version_string()) diff --git a/nova/wsgi.py b/nova/wsgi.py index de2e0749f..119fcbe4c 100644 --- a/nova/wsgi.py +++ b/nova/wsgi.py @@ -17,9 +17,7 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Utility methods for working with WSGI servers -""" +"""Utility methods for working with WSGI servers.""" import os import sys @@ -33,7 +31,6 @@ import routes.middleware import webob import webob.dec import webob.exc - from paste import deploy from nova import exception @@ -66,7 +63,7 @@ class Server(object): def start(self, application, port, host='0.0.0.0', backlog=128): """Run a WSGI server with the given application.""" arg0 = sys.argv[0] - logging.audit(_("Starting %(arg0)s on %(host)s:%(port)s") % locals()) + logging.audit(_('Starting %(arg0)s on %(host)s:%(port)s') % locals()) socket = eventlet.listen((host, port), backlog=backlog) self.pool.spawn_n(self._run, application, socket) @@ -87,30 +84,31 @@ class Server(object): class Request(webob.Request): def best_match_content_type(self): - """ - Determine the most acceptable content-type based on the - query extension then the Accept header + """Determine the most acceptable content-type. + + Based on the query extension then the Accept header. + """ - parts = self.path.rsplit(".", 1) + parts = self.path.rsplit('.', 1) if len(parts) > 1: format = parts[1] - if format in ["json", "xml"]: - return "application/{0}".format(parts[1]) + if format in ['json', 'xml']: + return 'application/{0}'.format(parts[1]) - ctypes = ["application/json", "application/xml"] + ctypes = ['application/json', 'application/xml'] bm = self.accept.best_match(ctypes) - return bm or "application/json" + return bm or 'application/json' def get_content_type(self): try: - ct = self.headers["Content-Type"] - assert ct in ("application/xml", "application/json") + ct = self.headers['Content-Type'] + assert ct in ('application/xml', 'application/json') return ct except Exception: - raise webob.exc.HTTPBadRequest("Invalid content type") + raise webob.exc.HTTPBadRequest('Invalid content type') class Application(object): @@ -118,7 +116,7 @@ class Application(object): @classmethod def factory(cls, global_config, **local_config): - """Used for paste app factories in paste.deploy config fles. + """Used for paste app factories in paste.deploy config files. Any local configuration (that is, values under the [app:APPNAME] section of the paste config) will be passed into the `__init__` method @@ -173,8 +171,9 @@ class Application(object): See the end of http://pythonpaste.org/webob/modules/dec.html for more info. + """ - raise NotImplementedError(_("You must implement __call__")) + raise NotImplementedError(_('You must implement __call__')) class Middleware(Application): @@ -184,11 +183,12 @@ class Middleware(Application): initialized that will be called next. By default the middleware will simply call its wrapped app, or you can override __call__ to customize its behavior. + """ @classmethod def factory(cls, global_config, **local_config): - """Used for paste app factories in paste.deploy config fles. + """Used for paste app factories in paste.deploy config files. Any local configuration (that is, values under the [filter:APPNAME] section of the paste config) will be passed into the `__init__` method @@ -240,20 +240,24 @@ class Middleware(Application): class Debug(Middleware): - """Helper class that can be inserted into any WSGI application chain - to get information about the request and response.""" + """Helper class for debugging a WSGI application. + + Can be inserted into any WSGI application chain to get information + about the request and response. + + """ @webob.dec.wsgify(RequestClass=Request) def __call__(self, req): - print ("*" * 40) + " REQUEST ENVIRON" + print ('*' * 40) + ' REQUEST ENVIRON' for key, value in req.environ.items(): - print key, "=", value + print key, '=', value print resp = req.get_response(self.application) - print ("*" * 40) + " RESPONSE HEADERS" + print ('*' * 40) + ' RESPONSE HEADERS' for (key, value) in resp.headers.iteritems(): - print key, "=", value + print key, '=', value print resp.app_iter = self.print_generator(resp.app_iter) @@ -262,11 +266,8 @@ class Debug(Middleware): @staticmethod def print_generator(app_iter): - """ - Iterator that prints the contents of a wrapper string iterator - when iterated. - """ - print ("*" * 40) + " BODY" + """Iterator that prints the contents of a wrapper string.""" + print ('*' * 40) + ' BODY' for part in app_iter: sys.stdout.write(part) sys.stdout.flush() @@ -275,13 +276,10 @@ class Debug(Middleware): class Router(object): - """ - WSGI middleware that maps incoming requests to WSGI apps. - """ + """WSGI middleware that maps incoming requests to WSGI apps.""" def __init__(self, mapper): - """ - Create a router for the given routes.Mapper. + """Create a router for the given routes.Mapper. Each route in `mapper` must specify a 'controller', which is a WSGI app to call. You'll probably want to specify an 'action' as @@ -293,15 +291,16 @@ class Router(object): sc = ServerController() # Explicit mapping of one route to a controller+action - mapper.connect(None, "/svrlist", controller=sc, action="list") + mapper.connect(None, '/svrlist', controller=sc, action='list') # Actions are all implicitly defined - mapper.resource("server", "servers", controller=sc) + mapper.resource('server', 'servers', controller=sc) # Pointing to an arbitrary WSGI app. You can specify the # {path_info:.*} parameter so the target app can be handed just that # section of the URL. - mapper.connect(None, "/v1.0/{path_info:.*}", controller=BlogApp()) + mapper.connect(None, '/v1.0/{path_info:.*}', controller=BlogApp()) + """ self.map = mapper self._router = routes.middleware.RoutesMiddleware(self._dispatch, @@ -309,19 +308,22 @@ class Router(object): @webob.dec.wsgify(RequestClass=Request) def __call__(self, req): - """ - Route the incoming request to a controller based on self.map. + """Route the incoming request to a controller based on self.map. + If no match, return a 404. + """ return self._router @staticmethod @webob.dec.wsgify(RequestClass=Request) def _dispatch(req): - """ + """Dispatch the request to the appropriate controller. + Called by self._router after matching the incoming request to a route and putting the information into req.environ. Either returns 404 or the routed WSGI app's response. + """ match = req.environ['wsgiorg.routing_args'][1] if not match: @@ -331,19 +333,19 @@ class Router(object): class Controller(object): - """ + """WSGI app that dispatched to methods. + WSGI app that reads routing information supplied by RoutesMiddleware and calls the requested action method upon itself. All action methods must, in addition to their normal parameters, accept a 'req' argument which is the incoming wsgi.Request. They raise a webob.exc exception, or return a dict which will be serialized by requested content type. + """ @webob.dec.wsgify(RequestClass=Request) def __call__(self, req): - """ - Call the method specified in req.environ by RoutesMiddleware. - """ + """Call the method specified in req.environ by RoutesMiddleware.""" arg_dict = req.environ['wsgiorg.routing_args'][1] action = arg_dict['action'] method = getattr(self, action) @@ -361,7 +363,7 @@ class Controller(object): body = self._serialize(result, content_type, default_xmlns) response = webob.Response() - response.headers["Content-Type"] = content_type + response.headers['Content-Type'] = content_type response.body = body msg_dict = dict(url=req.url, status=response.status_int) msg = _("%(url)s returned with HTTP %(status)d") % msg_dict @@ -371,12 +373,13 @@ class Controller(object): return result def _serialize(self, data, content_type, default_xmlns): - """ - Serialize the given dict to the provided content_type. + """Serialize the given dict to the provided content_type. + Uses self._serialization_metadata if it exists, which is a dict mapping MIME types to information needed to serialize to that type. + """ - _metadata = getattr(type(self), "_serialization_metadata", {}) + _metadata = getattr(type(self), '_serialization_metadata', {}) serializer = Serializer(_metadata, default_xmlns) try: @@ -385,12 +388,13 @@ class Controller(object): raise webob.exc.HTTPNotAcceptable() def _deserialize(self, data, content_type): - """ - Deserialize the request body to the specefied content type. + """Deserialize the request body to the specefied content type. + Uses self._serialization_metadata if it exists, which is a dict mapping MIME types to information needed to serialize to that type. + """ - _metadata = getattr(type(self), "_serialization_metadata", {}) + _metadata = getattr(type(self), '_serialization_metadata', {}) serializer = Serializer(_metadata) return serializer.deserialize(data, content_type) @@ -400,23 +404,22 @@ class Controller(object): class Serializer(object): - """ - Serializes and deserializes dictionaries to certain MIME types. - """ + """Serializes and deserializes dictionaries to certain MIME types.""" def __init__(self, metadata=None, default_xmlns=None): - """ - Create a serializer based on the given WSGI environment. + """Create a serializer based on the given WSGI environment. + 'metadata' is an optional dict mapping MIME types to information needed to serialize a dictionary to that type. + """ self.metadata = metadata or {} self.default_xmlns = default_xmlns def _get_serialize_handler(self, content_type): handlers = { - "application/json": self._to_json, - "application/xml": self._to_xml, + 'application/json': self._to_json, + 'application/xml': self._to_xml, } try: @@ -425,29 +428,27 @@ class Serializer(object): raise exception.InvalidContentType() def serialize(self, data, content_type): - """ - Serialize a dictionary into a string of the specified content type. - """ + """Serialize a dictionary into the specified content type.""" return self._get_serialize_handler(content_type)(data) def deserialize(self, datastring, content_type): - """ - Deserialize a string to a dictionary. + """Deserialize a string to a dictionary. The string must be in the format of a supported MIME type. + """ return self.get_deserialize_handler(content_type)(datastring) def get_deserialize_handler(self, content_type): handlers = { - "application/json": self._from_json, - "application/xml": self._from_xml, + 'application/json': self._from_json, + 'application/xml': self._from_xml, } try: return handlers[content_type] except Exception: - raise exception.InvalidContentType(_("Invalid content type %s" + raise exception.InvalidContentType(_('Invalid content type %s' % content_type)) def _from_json(self, datastring): @@ -460,11 +461,11 @@ class Serializer(object): return {node.nodeName: self._from_xml_node(node, plurals)} def _from_xml_node(self, node, listnames): - """ - Convert a minidom node to a simple Python type. + """Convert a minidom node to a simple Python type. listnames is a collection of names of XML nodes whose subnodes should be considered list items. + """ if len(node.childNodes) == 1 and node.childNodes[0].nodeType == 3: return node.childNodes[0].nodeValue @@ -571,7 +572,6 @@ def paste_config_file(basename): * /etc/nova, which may not be diffrerent from state_path on your distro """ - configfiles = [basename, os.path.join(FLAGS.state_path, 'etc', 'nova', basename), os.path.join(FLAGS.state_path, 'etc', basename), @@ -587,7 +587,7 @@ def load_paste_configuration(filename, appname): filename = os.path.abspath(filename) config = None try: - config = deploy.appconfig("config:%s" % filename, name=appname) + config = deploy.appconfig('config:%s' % filename, name=appname) except LookupError: pass return config @@ -598,7 +598,7 @@ def load_paste_app(filename, appname): filename = os.path.abspath(filename) app = None try: - app = deploy.loadapp("config:%s" % filename, name=appname) + app = deploy.loadapp('config:%s' % filename, name=appname) except LookupError: pass return app -- cgit From 6eacc130af49ced7a1e5ce511c7096dd7563b4b2 Mon Sep 17 00:00:00 2001 From: termie Date: Wed, 20 Apr 2011 12:08:24 -0700 Subject: cleanups per code review --- nova/utils.py | 4 ++-- nova/wsgi.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/nova/utils.py b/nova/utils.py index 59f694196..b783f6c14 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -182,11 +182,11 @@ def ssh_execute(ssh, cmd, process_input=None, addl_env=None, check_exit_code=True): LOG.debug(_('Running cmd (SSH): %s'), ' '.join(cmd)) if addl_env: - raise exception.Error('Environment not supported over SSH') + raise exception.Error(_('Environment not supported over SSH')) if process_input: # This is (probably) fixable if we need it... - raise exception.Error('process_input not supported over SSH') + raise exception.Error(_('process_input not supported over SSH')) stdin_stream, stdout_stream, stderr_stream = ssh.exec_command(cmd) channel = stdout_stream.channel diff --git a/nova/wsgi.py b/nova/wsgi.py index 119fcbe4c..418087641 100644 --- a/nova/wsgi.py +++ b/nova/wsgi.py @@ -89,7 +89,6 @@ class Request(webob.Request): Based on the query extension then the Accept header. """ - parts = self.path.rsplit('.', 1) if len(parts) > 1: -- cgit From 8bf11973b0de6a57f18ac48452e3f8b36adac565 Mon Sep 17 00:00:00 2001 From: termie Date: Wed, 20 Apr 2011 12:26:15 -0700 Subject: docstring cleanup, nova/image dir --- nova/image/fake.py | 9 ++++--- nova/image/glance.py | 70 +++++++++++++++++++++------------------------------ nova/image/local.py | 8 +++--- nova/image/s3.py | 43 +++++++++++++++---------------- nova/image/service.py | 63 +++++++++++++++++++++++----------------------- 5 files changed, 92 insertions(+), 101 deletions(-) diff --git a/nova/image/fake.py b/nova/image/fake.py index e02b4127e..3bc2a8287 100644 --- a/nova/image/fake.py +++ b/nova/image/fake.py @@ -14,6 +14,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. + """Implementation of an fake image service""" import copy @@ -69,14 +70,14 @@ class FakeImageService(service.BaseImageService): image = self.images.get(image_id) if image: return copy.deepcopy(image) - LOG.warn("Unable to find image id %s. Have images: %s", + LOG.warn('Unable to find image id %s. Have images: %s', image_id, self.images) raise exception.NotFound def create(self, context, data): """Store the image data and return the new image id. - :raises Duplicate if the image already exist. + :raises: Duplicate if the image already exist. """ image_id = int(data['id']) @@ -88,7 +89,7 @@ class FakeImageService(service.BaseImageService): def update(self, context, image_id, data): """Replace the contents of the given image with the new data. - :raises NotFound if the image does not exist. + :raises: NotFound if the image does not exist. """ image_id = int(image_id) @@ -99,7 +100,7 @@ class FakeImageService(service.BaseImageService): def delete(self, context, image_id): """Delete the given image. - :raises NotFound if the image does not exist. + :raises: NotFound if the image does not exist. """ image_id = int(image_id) diff --git a/nova/image/glance.py b/nova/image/glance.py index 1a80bb2af..81661b3b0 100644 --- a/nova/image/glance.py +++ b/nova/image/glance.py @@ -14,6 +14,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. + """Implementation of an image service that uses Glance as the backend""" from __future__ import absolute_import @@ -31,16 +32,18 @@ from nova.image import service LOG = logging.getLogger('nova.image.glance') + FLAGS = flags.FLAGS + GlanceClient = utils.import_class('glance.client.Client') class GlanceImageService(service.BaseImageService): """Provides storage and retrieval of disk image objects within Glance.""" - GLANCE_ONLY_ATTRS = ["size", "location", "disk_format", - "container_format"] + GLANCE_ONLY_ATTRS = ['size', 'location', 'disk_format', + 'container_format'] # NOTE(sirp): Overriding to use _translate_to_service provided by # BaseImageService @@ -56,9 +59,7 @@ class GlanceImageService(service.BaseImageService): self.client = client def index(self, context): - """ - Calls out to Glance for a list of images available - """ + """Calls out to Glance for a list of images available.""" # NOTE(sirp): We need to use `get_images_detailed` and not # `get_images` here because we need `is_public` and `properties` # included so we can filter by user @@ -71,9 +72,7 @@ class GlanceImageService(service.BaseImageService): return filtered def detail(self, context): - """ - Calls out to Glance for a list of detailed image information - """ + """Calls out to Glance for a list of detailed image information.""" filtered = [] image_metas = self.client.get_images_detailed() for image_meta in image_metas: @@ -83,9 +82,7 @@ class GlanceImageService(service.BaseImageService): return filtered def show(self, context, image_id): - """ - Returns a dict containing image data for the given opaque image id. - """ + """Returns a dict with image data for the given opaque image id.""" try: image_meta = self.client.get_image_meta(image_id) except glance_exception.NotFound: @@ -98,9 +95,7 @@ class GlanceImageService(service.BaseImageService): return base_image_meta def show_by_name(self, context, name): - """ - Returns a dict containing image data for the given name. - """ + """Returns a dict containing image data for the given name.""" # TODO(vish): replace this with more efficient call when glance # supports it. image_metas = self.detail(context) @@ -110,9 +105,7 @@ class GlanceImageService(service.BaseImageService): raise exception.NotFound def get(self, context, image_id, data): - """ - Calls out to Glance for metadata and data and writes data. - """ + """Calls out to Glance for metadata and data and writes data.""" try: image_meta, image_chunks = self.client.get_image(image_id) except glance_exception.NotFound: @@ -125,16 +118,16 @@ class GlanceImageService(service.BaseImageService): return base_image_meta def create(self, context, image_meta, data=None): - """ - Store the image data and return the new image id. + """Store the image data and return the new image id. + + :raises: AlreadyExists if the image already exist. - :raises AlreadyExists if the image already exist. """ # Translate Base -> Service - LOG.debug(_("Creating image in Glance. Metadata passed in %s"), + LOG.debug(_('Creating image in Glance. Metadata passed in %s'), image_meta) sent_service_image_meta = self._translate_to_service(image_meta) - LOG.debug(_("Metadata after formatting for Glance %s"), + LOG.debug(_('Metadata after formatting for Glance %s'), sent_service_image_meta) recv_service_image_meta = self.client.add_image( @@ -142,14 +135,15 @@ class GlanceImageService(service.BaseImageService): # Translate Service -> Base base_image_meta = self._translate_to_base(recv_service_image_meta) - LOG.debug(_("Metadata returned from Glance formatted for Base %s"), + LOG.debug(_('Metadata returned from Glance formatted for Base %s'), base_image_meta) return base_image_meta def update(self, context, image_id, image_meta, data=None): """Replace the contents of the given image with the new data. - :raises NotFound if the image does not exist. + :raises: NotFound if the image does not exist. + """ # NOTE(vish): show is to check if image is available self.show(context, image_id) @@ -162,10 +156,10 @@ class GlanceImageService(service.BaseImageService): return base_image_meta def delete(self, context, image_id): - """ - Delete the given image. + """Delete the given image. + + :raises: NotFound if the image does not exist. - :raises NotFound if the image does not exist. """ # NOTE(vish): show is to check if image is available self.show(context, image_id) @@ -176,16 +170,12 @@ class GlanceImageService(service.BaseImageService): return result def delete_all(self): - """ - Clears out all images - """ + """Clears out all images.""" pass @classmethod def _translate_to_base(cls, image_meta): - """Overriding the base translation to handle conversion to datetime - objects - """ + """Override translation to handle conversion to datetime objects.""" image_meta = service.BaseImageService._propertify_metadata( image_meta, cls.SERVICE_IMAGE_ATTRS) image_meta = _convert_timestamps_to_datetimes(image_meta) @@ -194,9 +184,7 @@ class GlanceImageService(service.BaseImageService): # utility functions def _convert_timestamps_to_datetimes(image_meta): - """ - Returns image with known timestamp fields converted to datetime objects - """ + """Returns image with timestamp fields converted to datetime objects.""" for attr in ['created_at', 'updated_at', 'deleted_at']: if image_meta.get(attr): image_meta[attr] = _parse_glance_iso8601_timestamp( @@ -205,10 +193,8 @@ def _convert_timestamps_to_datetimes(image_meta): def _parse_glance_iso8601_timestamp(timestamp): - """ - Parse a subset of iso8601 timestamps into datetime objects - """ - iso_formats = ["%Y-%m-%dT%H:%M:%S.%f", "%Y-%m-%dT%H:%M:%S"] + """Parse a subset of iso8601 timestamps into datetime objects.""" + iso_formats = ['%Y-%m-%dT%H:%M:%S.%f', '%Y-%m-%dT%H:%M:%S'] for iso_format in iso_formats: try: @@ -216,5 +202,5 @@ def _parse_glance_iso8601_timestamp(timestamp): except ValueError: pass - raise ValueError(_("%(timestamp)s does not follow any of the " - "signatures: %(ISO_FORMATS)s") % locals()) + raise ValueError(_('%(timestamp)s does not follow any of the ' + 'signatures: %(ISO_FORMATS)s') % locals()) diff --git a/nova/image/local.py b/nova/image/local.py index fa5e93346..d59c3970f 100644 --- a/nova/image/local.py +++ b/nova/image/local.py @@ -23,14 +23,15 @@ import shutil from nova import exception from nova import flags from nova import log as logging -from nova.image import service from nova import utils +from nova.image import service FLAGS = flags.FLAGS flags.DEFINE_string('images_path', '$state_path/images', 'path to decrypted images') + LOG = logging.getLogger('nova.image.local') @@ -57,7 +58,7 @@ class LocalImageService(service.BaseImageService): unhexed_image_id = int(image_dir, 16) except ValueError: LOG.error( - _("%s is not in correct directory naming format"\ + _('%s is not in correct directory naming format'\ % image_dir)) else: images.append(unhexed_image_id) @@ -148,7 +149,8 @@ class LocalImageService(service.BaseImageService): def delete(self, context, image_id): """Delete the given image. - Raises NotFound if the image does not exist. + + :raises: NotFound if the image does not exist. """ # NOTE(vish): show is to check if image is available diff --git a/nova/image/s3.py b/nova/image/s3.py index 2a02d4674..4a4ee44d8 100644 --- a/nova/image/s3.py +++ b/nova/image/s3.py @@ -16,19 +16,16 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Proxy AMI-related calls from the cloud controller, to the running -objectstore service. -""" +"""Proxy AMI-related calls from cloud controller to objectstore service.""" import binascii -import eventlet import os import shutil import tarfile import tempfile from xml.etree import ElementTree +import eventlet import boto.s3.connection from nova import crypto @@ -46,7 +43,7 @@ flags.DEFINE_string('image_decryption_dir', '/tmp', class S3ImageService(service.BaseImageService): - """Wraps an existing image service to support s3 based register""" + """Wraps an existing image service to support s3 based register.""" def __init__(self, service=None, *args, **kwargs): if service is None: service = utils.import_object(FLAGS.image_service) @@ -54,7 +51,11 @@ class S3ImageService(service.BaseImageService): self.service.__init__(*args, **kwargs) def create(self, context, metadata, data=None): - """metadata['properties'] should contain image_location""" + """Create an image. + + metadata['properties'] should contain image_location. + + """ image = self._s3_create(context, metadata) return image @@ -100,12 +101,12 @@ class S3ImageService(service.BaseImageService): return local_filename def _s3_create(self, context, metadata): - """Gets a manifext from s3 and makes an image""" + """Gets a manifext from s3 and makes an image.""" image_path = tempfile.mkdtemp(dir=FLAGS.image_decryption_dir) image_location = metadata['properties']['image_location'] - bucket_name = image_location.split("/")[0] + bucket_name = image_location.split('/')[0] manifest_path = image_location[len(bucket_name) + 1:] bucket = self._conn(context).get_bucket(bucket_name) key = bucket.get_key(manifest_path) @@ -116,7 +117,7 @@ class S3ImageService(service.BaseImageService): image_type = 'machine' try: - kernel_id = manifest.find("machine_configuration/kernel_id").text + kernel_id = manifest.find('machine_configuration/kernel_id').text if kernel_id == 'true': image_format = 'aki' image_type = 'kernel' @@ -125,7 +126,7 @@ class S3ImageService(service.BaseImageService): kernel_id = None try: - ramdisk_id = manifest.find("machine_configuration/ramdisk_id").text + ramdisk_id = manifest.find('machine_configuration/ramdisk_id').text if ramdisk_id == 'true': image_format = 'ari' image_type = 'ramdisk' @@ -134,7 +135,7 @@ class S3ImageService(service.BaseImageService): ramdisk_id = None try: - arch = manifest.find("machine_configuration/architecture").text + arch = manifest.find('machine_configuration/architecture').text except Exception: arch = 'x86_64' @@ -160,7 +161,7 @@ class S3ImageService(service.BaseImageService): def delayed_create(): """This handles the fetching and decrypting of the part files.""" parts = [] - for fn_element in manifest.find("image").getiterator("filename"): + for fn_element in manifest.find('image').getiterator('filename'): part = self._download_file(bucket, fn_element.text, image_path) parts.append(part) @@ -174,9 +175,9 @@ class S3ImageService(service.BaseImageService): metadata['properties']['image_state'] = 'decrypting' self.service.update(context, image_id, metadata) - hex_key = manifest.find("image/ec2_encrypted_key").text + hex_key = manifest.find('image/ec2_encrypted_key').text encrypted_key = binascii.a2b_hex(hex_key) - hex_iv = manifest.find("image/ec2_encrypted_iv").text + hex_iv = manifest.find('image/ec2_encrypted_iv').text encrypted_iv = binascii.a2b_hex(hex_iv) # FIXME(vish): grab key from common service so this can run on @@ -214,7 +215,7 @@ class S3ImageService(service.BaseImageService): process_input=encrypted_key, check_exit_code=False) if err: - raise exception.Error(_("Failed to decrypt private key: %s") + raise exception.Error(_('Failed to decrypt private key: %s') % err) iv, err = utils.execute('openssl', 'rsautl', @@ -223,8 +224,8 @@ class S3ImageService(service.BaseImageService): process_input=encrypted_iv, check_exit_code=False) if err: - raise exception.Error(_("Failed to decrypt initialization " - "vector: %s") % err) + raise exception.Error(_('Failed to decrypt initialization ' + 'vector: %s') % err) _out, err = utils.execute('openssl', 'enc', '-d', '-aes-128-cbc', @@ -234,14 +235,14 @@ class S3ImageService(service.BaseImageService): '-out', '%s' % (decrypted_filename,), check_exit_code=False) if err: - raise exception.Error(_("Failed to decrypt image file " - "%(image_file)s: %(err)s") % + raise exception.Error(_('Failed to decrypt image file ' + '%(image_file)s: %(err)s') % {'image_file': encrypted_filename, 'err': err}) @staticmethod def _untarzip_image(path, filename): - tar_file = tarfile.open(filename, "r|gz") + tar_file = tarfile.open(filename, 'r|gz') tar_file.extractall(path) image_file = tar_file.getnames()[0] tar_file.close() diff --git a/nova/image/service.py b/nova/image/service.py index fddc72409..3e2357df8 100644 --- a/nova/image/service.py +++ b/nova/image/service.py @@ -20,7 +20,7 @@ from nova import utils class BaseImageService(object): - """Base class for providing image search and retrieval services + """Base class for providing image search and retrieval services. ImageService exposes two concepts of metadata: @@ -35,7 +35,9 @@ class BaseImageService(object): This means that ImageServices will return BASE_IMAGE_ATTRS as keys in the metadata dict, all other attributes will be returned as keys in the nested 'properties' dict. + """ + BASE_IMAGE_ATTRS = ['id', 'name', 'created_at', 'updated_at', 'deleted_at', 'deleted', 'status', 'is_public'] @@ -45,23 +47,18 @@ class BaseImageService(object): SERVICE_IMAGE_ATTRS = [] def index(self, context): - """ - Returns a sequence of mappings of id and name information about - images. + """List images. - :rtype: array - :retval: a sequence of mappings with the following signature + :returnsl: a sequence of mappings with the following signature {'id': opaque id of image, 'name': name of image} """ raise NotImplementedError def detail(self, context): - """ - Returns a sequence of mappings of detailed information about images. + """Detailed information about an images. - :rtype: array - :retval: a sequence of mappings with the following signature + :returns: a sequence of mappings with the following signature {'id': opaque id of image, 'name': name of image, 'created_at': creation datetime object, @@ -77,15 +74,14 @@ class BaseImageService(object): NotImplementedError, in which case Nova will emulate this method with repeated calls to show() for each image received from the index() method. + """ raise NotImplementedError def show(self, context, image_id): - """ - Returns a dict containing image metadata for the given opaque image id. - - :retval a mapping with the following signature: + """Detailed information about an image. + :returns: a mapping with the following signature: {'id': opaque id of image, 'name': name of image, 'created_at': creation datetime object, @@ -96,31 +92,32 @@ class BaseImageService(object): 'is_public': boolean indicating if image is public }, ... - :raises NotFound if the image does not exist + :raises: NotFound if the image does not exist + """ raise NotImplementedError def get(self, context, data): - """ - Returns a dict containing image metadata and writes image data to data. + """Get an image. :param data: a file-like object to hold binary image data - + :returns: a dict containing image metadata, writes image data to data. :raises NotFound if the image does not exist + """ raise NotImplementedError def create(self, context, metadata, data=None): - """ - Store the image metadata and data and return the new image metadata. + """Store the image metadata and data. - :raises AlreadyExists if the image already exist. + :returns: the new image metadata. + :raises: AlreadyExists if the image already exist. """ raise NotImplementedError def update(self, context, image_id, metadata, data=None): - """Update the given image metadata and data and return the metadata + """Update the given image metadata and data and return the metadata. :raises NotFound if the image does not exist. @@ -128,8 +125,7 @@ class BaseImageService(object): raise NotImplementedError def delete(self, context, image_id): - """ - Delete the given image. + """Delete the given image. :raises NotFound if the image does not exist. @@ -138,12 +134,14 @@ class BaseImageService(object): @staticmethod def _is_image_available(context, image_meta): - """ + """Check image availability. + Images are always available if they are public or if the user is an admin. Otherwise, we filter by project_id (if present) and then fall-back to images owned by user. + """ # FIXME(sirp): We should be filtering by user_id on the Glance side # for security; however, we can't do that until we get authn/authz @@ -169,29 +167,32 @@ class BaseImageService(object): This is used by subclasses to expose only a metadata dictionary that is the same across ImageService implementations. + """ return cls._propertify_metadata(metadata, cls.BASE_IMAGE_ATTRS) @classmethod def _translate_to_service(cls, metadata): - """Return a metadata dictionary that is usable by the ImageService - subclass. + """Return a metadata dict that is usable by the ImageService subclass. As an example, Glance has additional attributes (like 'location'); the BaseImageService considers these properties, but we need to translate these back to first-class attrs for sending to Glance. This method handles this by allowing you to specify the attributes an ImageService considers first-class. + """ if not cls.SERVICE_IMAGE_ATTRS: - raise NotImplementedError(_("Cannot use this without specifying " - "SERVICE_IMAGE_ATTRS for subclass")) + raise NotImplementedError(_('Cannot use this without specifying ' + 'SERVICE_IMAGE_ATTRS for subclass')) return cls._propertify_metadata(metadata, cls.SERVICE_IMAGE_ATTRS) @staticmethod def _propertify_metadata(metadata, keys): - """Return a dict with any unrecognized keys placed in the nested - 'properties' dict. + """Move unknown keys to a nested 'properties' dict. + + :returns: a new dict with the keys moved. + """ flattened = utils.flatten_dict(metadata) attributes, properties = utils.partition_dict(flattened, keys) -- cgit From 42b139f740c08cce04d898c4ce7c85030733927f Mon Sep 17 00:00:00 2001 From: termie Date: Wed, 20 Apr 2011 12:26:17 -0700 Subject: fixes per review --- nova/image/s3.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/image/s3.py b/nova/image/s3.py index 4a4ee44d8..c38c58d95 100644 --- a/nova/image/s3.py +++ b/nova/image/s3.py @@ -25,8 +25,8 @@ import tarfile import tempfile from xml.etree import ElementTree -import eventlet import boto.s3.connection +import eventlet from nova import crypto from nova import exception @@ -44,6 +44,7 @@ flags.DEFINE_string('image_decryption_dir', '/tmp', class S3ImageService(service.BaseImageService): """Wraps an existing image service to support s3 based register.""" + def __init__(self, service=None, *args, **kwargs): if service is None: service = utils.import_object(FLAGS.image_service) -- cgit From ce8fd6b5e3ef0c757c76bbe9db37c696a1d2c11c Mon Sep 17 00:00:00 2001 From: termie Date: Wed, 20 Apr 2011 12:26:17 -0700 Subject: more changes per review --- nova/image/local.py | 5 ++--- nova/image/service.py | 10 +++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/nova/image/local.py b/nova/image/local.py index d59c3970f..50f00bee1 100644 --- a/nova/image/local.py +++ b/nova/image/local.py @@ -57,9 +57,8 @@ class LocalImageService(service.BaseImageService): try: unhexed_image_id = int(image_dir, 16) except ValueError: - LOG.error( - _('%s is not in correct directory naming format'\ - % image_dir)) + LOG.error(_('%s is not in correct directory naming format') + % image_dir) else: images.append(unhexed_image_id) return images diff --git a/nova/image/service.py b/nova/image/service.py index 3e2357df8..ab6749049 100644 --- a/nova/image/service.py +++ b/nova/image/service.py @@ -49,8 +49,8 @@ class BaseImageService(object): def index(self, context): """List images. - :returnsl: a sequence of mappings with the following signature - {'id': opaque id of image, 'name': name of image} + :returns: a sequence of mappings with the following signature + {'id': opaque id of image, 'name': name of image} """ raise NotImplementedError @@ -102,7 +102,7 @@ class BaseImageService(object): :param data: a file-like object to hold binary image data :returns: a dict containing image metadata, writes image data to data. - :raises NotFound if the image does not exist + :raises: NotFound if the image does not exist """ raise NotImplementedError @@ -119,7 +119,7 @@ class BaseImageService(object): def update(self, context, image_id, metadata, data=None): """Update the given image metadata and data and return the metadata. - :raises NotFound if the image does not exist. + :raises: NotFound if the image does not exist. """ raise NotImplementedError @@ -127,7 +127,7 @@ class BaseImageService(object): def delete(self, context, image_id): """Delete the given image. - :raises NotFound if the image does not exist. + :raises: NotFound if the image does not exist. """ raise NotImplementedError -- cgit From 2ea651dad0265807119716046767b85cf769ca05 Mon Sep 17 00:00:00 2001 From: Naveed Massjouni Date: Wed, 20 Apr 2011 16:27:33 -0400 Subject: Exit early if tests fail, before pep8 is run. --- run_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run_tests.sh b/run_tests.sh index 4f85dfe6d..610cf1f27 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -96,7 +96,7 @@ then fi fi -run_tests +run_tests || exit # Also run pep8 if no options were provided. if [ -z "$noseargs" ]; then -- cgit From 7d8698ad551b756a9dfc7058e6d836de65a64945 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 20 Apr 2011 16:21:37 -0700 Subject: in doesn't work properly on instance_ref --- nova/api/ec2/cloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index bd4c9dcd4..4785d812a 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -187,7 +187,7 @@ class CloudController(object): 'mpi': mpi}} for image_type in ['kernel', 'ramdisk']: - if '%s_id' % image_type in instance_ref: + if instance_ref.get('%s_id' % image_type): ec2_id = self._image_ec2_id(instance_ref['%s_id' % image_type], self._image_type(image_type)) data['meta-data']['%s-id' % image_type] = ec2_id -- cgit From 783cea4dc4497176b57b7a718a29bde102fb92bc Mon Sep 17 00:00:00 2001 From: Eldar Nugaev Date: Thu, 21 Apr 2011 04:31:17 +0400 Subject: style fix --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index d5a88ebed..a42433fed 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -168,7 +168,7 @@ def _get_network_info(instance): networks = db.network_get_all_by_instance(admin_context, instance['id']) flavor = db.instance_type_get_by_id(admin_context, - instance['instance_type_id']) + instance['instance_type_id']) network_info = [] for network in networks: -- cgit From 2217872ff5e8e5b53af0b38064a3cdbc2c783ebb Mon Sep 17 00:00:00 2001 From: Eldar Nugaev Date: Thu, 21 Apr 2011 05:22:09 +0400 Subject: pep8 cleaning --- nova/compute/manager.py | 47 +++++++++++----------- .../015_add_auto_assign_to_floating_ips.py | 1 + nova/network/api.py | 6 +-- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index c1dc06557..13a082b44 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -37,8 +37,6 @@ terminating it. import datetime import os -import random -import string import socket import sys import tempfile @@ -54,7 +52,7 @@ from nova import rpc from nova import utils from nova.compute import power_state from nova.virt import driver -from nova.network import api as network_api +from nova import network FLAGS = flags.FLAGS flags.DEFINE_string('instances_path', '$state_path/instances', @@ -74,8 +72,8 @@ flags.DEFINE_integer('live_migration_retry_count', 30, flags.DEFINE_integer("rescue_timeout", 0, "Automatically unrescue an instance after N seconds." " Set to 0 to disable.") -flags.DEFINE_bool('auto_assign_floating_ip', False, 'Autoassigning floating' - ' ip to VM') +flags.DEFINE_bool('auto_assign_floating_ip', False, + 'Autoassigning floating ip to VM') LOG = logging.getLogger('nova.compute.manager') @@ -135,7 +133,7 @@ class ComputeManager(manager.SchedulerDependentManager): self.network_manager = utils.import_object(FLAGS.network_manager) self.volume_manager = utils.import_object(FLAGS.volume_manager) - self.network_api = network_api.API() + self.network_api = network.API() super(ComputeManager, self).__init__(service_name="compute", *args, **kwargs) @@ -248,18 +246,18 @@ class ComputeManager(manager.SchedulerDependentManager): instance_id, power_state.SHUTDOWN) - if not FLAGS.stub_network: - if FLAGS.auto_assign_floating_ip: - public_ip = self.network_api.allocate_floating_ip(context) + if not FLAGS.stub_network and FLAGS.auto_assign_floating_ip: + public_ip = self.network_api.allocate_floating_ip(context) - self.db.floating_ip_set_auto_assigned(context, public_ip) - fixed_ip = self.db.fixed_ip_get_by_address(context, address) - floating_ip = self.db.floating_ip_get_by_address(context, - public_ip) + self.db.floating_ip_set_auto_assigned(context, public_ip) + fixed_ip = self.db.fixed_ip_get_by_address(context, address) + floating_ip = self.db.floating_ip_get_by_address(context, + public_ip) - self.network_api.associate_floating_ip(context, floating_ip, - fixed_ip, - affect_auto_assigned=True) + self.network_api.associate_floating_ip(context, + floating_ip, + fixed_ip, + affect_auto_assigned=True) self._update_state(context, instance_id) @exception.wrap_exception @@ -280,14 +278,17 @@ class ComputeManager(manager.SchedulerDependentManager): # NOTE(vish): Right now we don't really care if the ip is # disassociated. We may need to worry about # checking this later. - self.network_api.disassociate_floating_ip(context, address, - affect_auto_assigned=True) - if FLAGS.auto_assign_floating_ip \ - and floating_ip.get('auto_assigned'): + self.network_api.disassociate_floating_ip(context, + address, + True) + if (FLAGS.auto_assign_floating_ip + and floating_ip.get('auto_assigned')): LOG.debug(_("Deallocating floating ip %s"), - floating_ip['address'], context=context) - self.network_api.release_floating_ip(context, address, - affect_auto_assigned=True) + floating_ip['address'], + context=context) + self.network_api.release_floating_ip(context, + address, + True) address = fixed_ip['address'] if address: diff --git a/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py b/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py index f3767b29f..64d6df77f 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py @@ -22,6 +22,7 @@ from migrate import * meta = MetaData() + c_auto_assigned = Column('auto_assigned', Boolean, default=False) diff --git a/nova/network/api.py b/nova/network/api.py index 61db646ae..1d8193b28 100644 --- a/nova/network/api.py +++ b/nova/network/api.py @@ -52,7 +52,7 @@ class API(base.Base): "args": {"project_id": context.project_id}}) def release_floating_ip(self, context, address, - affect_auto_assigned = False): + affect_auto_assigned=False): floating_ip = self.db.floating_ip_get_by_address(context, address) if not affect_auto_assigned and floating_ip.get('auto_assigned'): return @@ -66,7 +66,7 @@ class API(base.Base): "args": {"floating_address": floating_ip['address']}}) def associate_floating_ip(self, context, floating_ip, fixed_ip, - affect_auto_assigned = False): + affect_auto_assigned=False): if isinstance(fixed_ip, str) or isinstance(fixed_ip, unicode): fixed_ip = self.db.fixed_ip_get_by_address(context, fixed_ip) floating_ip = self.db.floating_ip_get_by_address(context, floating_ip) @@ -97,7 +97,7 @@ class API(base.Base): "fixed_address": fixed_ip['address']}}) def disassociate_floating_ip(self, context, address, - affect_auto_assigned = False): + affect_auto_assigned=False): floating_ip = self.db.floating_ip_get_by_address(context, address) if not affect_auto_assigned and floating_ip.get('auto_assigned'): return -- cgit From ba9edf8d6d93290d1f1e85bb3a51e3a69e3f0822 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 20 Apr 2011 21:06:56 -0700 Subject: put up and down in the right dir --- doc/source/devref/down.sh | 7 +++++++ doc/source/devref/up.sh | 7 +++++++ doc/source/down.sh | 7 ------- doc/source/up.sh | 7 ------- 4 files changed, 14 insertions(+), 14 deletions(-) create mode 100644 doc/source/devref/down.sh create mode 100644 doc/source/devref/up.sh delete mode 100644 doc/source/down.sh delete mode 100644 doc/source/up.sh diff --git a/doc/source/devref/down.sh b/doc/source/devref/down.sh new file mode 100644 index 000000000..5c1888870 --- /dev/null +++ b/doc/source/devref/down.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +BR=$1 +DEV=$2 + +/usr/sbin/brctl delif $BR $DEV +/sbin/ifconfig $DEV down diff --git a/doc/source/devref/up.sh b/doc/source/devref/up.sh new file mode 100644 index 000000000..073a58e15 --- /dev/null +++ b/doc/source/devref/up.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +BR=$1 +DEV=$2 +MTU=$3 +/sbin/ifconfig $DEV mtu $MTU promisc up +/usr/sbin/brctl addif $BR $DEV diff --git a/doc/source/down.sh b/doc/source/down.sh deleted file mode 100644 index 5c1888870..000000000 --- a/doc/source/down.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -BR=$1 -DEV=$2 - -/usr/sbin/brctl delif $BR $DEV -/sbin/ifconfig $DEV down diff --git a/doc/source/up.sh b/doc/source/up.sh deleted file mode 100644 index 073a58e15..000000000 --- a/doc/source/up.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -BR=$1 -DEV=$2 -MTU=$3 -/sbin/ifconfig $DEV mtu $MTU promisc up -/usr/sbin/brctl addif $BR $DEV -- cgit From e1f37b81e805c087947c87a9bc341dd60e7e481c Mon Sep 17 00:00:00 2001 From: Eldar Nugaev Date: Thu, 21 Apr 2011 15:49:47 +0400 Subject: style fixing --- nova/compute/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 13a082b44..864b3a816 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -48,11 +48,11 @@ from nova import exception from nova import flags from nova import log as logging from nova import manager +from nova import network from nova import rpc from nova import utils from nova.compute import power_state from nova.virt import driver -from nova import network FLAGS = flags.FLAGS flags.DEFINE_string('instances_path', '$state_path/instances', -- cgit From ea11033935192ee26ea6d0d0dad47a0a624b17a0 Mon Sep 17 00:00:00 2001 From: Jimmy Bergman Date: Thu, 21 Apr 2011 15:23:36 +0200 Subject: Add privateIpAddress and ipAddress to EC2 API DescribeInstances response. --- nova/api/ec2/cloud.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 4785d812a..4aa973290 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -726,7 +726,9 @@ class CloudController(object): instance['mac_address']) i['privateDnsName'] = fixed_addr + i['privateIpAddress'] = fixed_addr i['publicDnsName'] = floating_addr + i['ipAddress'] = floating_addr or fixed_addr i['dnsName'] = i['publicDnsName'] or i['privateDnsName'] i['keyName'] = instance['key_name'] -- cgit From e6b76ce6886a1404739a972d106248a67df4f02a Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 21 Apr 2011 07:35:30 -0700 Subject: use simpler interfaces --- doc/source/devref/interfaces | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/doc/source/devref/interfaces b/doc/source/devref/interfaces index 2aae39558..b7116aeb7 100644 --- a/doc/source/devref/interfaces +++ b/doc/source/devref/interfaces @@ -1,18 +1,17 @@ +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + # The loopback network interface auto lo iface lo inet loopback # The primary network interface +auto eth0 +iface eth0 inet manual + up ifconfig $IFACE 0.0.0.0 up + down ifconfig $IFACE down + auto br0 iface br0 inet dhcp bridge_ports eth0 - bridge_fd 9 ## from the libvirt docs (forward delay time) - bridge_hello 2 ## from the libvirt docs (hello time) - bridge_maxage 12 ## from the libvirt docs (maximum message age) - bridge_stp off ## from the libvirt docs (spanning tree protocol) -iface eth0 inet manual - up ifconfig $IFACE 0.0.0.0 up - up ip link set $IFACE promisc on - down ip link set $IFACE promisc off - down ifconfig $IFACE down -- cgit From 2d82195d59240ea53d4726879d2a28a5872e58f7 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 21 Apr 2011 07:39:49 -0700 Subject: use vpn filter in basic filtering so cloudpipe works with iptables driver --- nova/virt/libvirt_conn.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 9c8d64446..3dcb8ae42 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1734,11 +1734,16 @@ class NWFilterFirewall(FirewallDriver): logging.info('ensuring static filters') self._ensure_static_filters() + if instance['image_id'] == str(FLAGS.vpn_image_id): + base_filter = 'nova-vpn' + else: + base_filter = 'nova-base' + for (network, mapping) in network_info: nic_id = mapping['mac'].replace(':', '') instance_filter_name = self._instance_filter_name(instance, nic_id) self._define_filter(self._filter_container(instance_filter_name, - ['nova-base'])) + [base_filter])) def _ensure_static_filters(self): if self.static_filters_configured: @@ -1749,11 +1754,12 @@ class NWFilterFirewall(FirewallDriver): 'no-ip-spoofing', 'no-arp-spoofing', 'allow-dhcp-server'])) + self._define_filter(self._filter_container('nova-vpn', + ['allow-dhcp-server'])) self._define_filter(self.nova_base_ipv4_filter) self._define_filter(self.nova_base_ipv6_filter) self._define_filter(self.nova_dhcp_filter) self._define_filter(self.nova_ra_filter) - self._define_filter(self.nova_vpn_filter) if FLAGS.allow_project_net_traffic: self._define_filter(self.nova_project_filter) if FLAGS.use_ipv6: @@ -1767,14 +1773,6 @@ class NWFilterFirewall(FirewallDriver): ''.join(["" % (f,) for f in filters])) return xml - nova_vpn_filter = ''' - 2086015e-cf03-11df-8c5d-080027c27973 - - - - - ''' - def nova_base_ipv4_filter(self): retval = "" for protocol in ['tcp', 'udp', 'icmp']: -- cgit From 5904cba617038600f3d8e7f65c71485abb163927 Mon Sep 17 00:00:00 2001 From: Eldar Nugaev Date: Thu, 21 Apr 2011 22:23:40 +0400 Subject: style cleaning --- .../migrate_repo/versions/015_add_auto_assign_to_floating_ips.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py b/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py index 64d6df77f..29b26b3dd 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py @@ -31,7 +31,9 @@ def upgrade(migrate_engine): # bind migrate_engine to your metadata meta.bind = migrate_engine - floating_ips = Table('floating_ips', meta, autoload=True, - autoload_with=migrate_engine) + floating_ips = Table('floating_ips', + meta, + autoload=True, + autoload_with=migrate_engine) floating_ips.create_column(c_auto_assigned) -- cgit From f710ad1e3fff16de696f608986f24bdc8ffc3f6b Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Fri, 22 Apr 2011 00:22:23 -0700 Subject: pep8 --- nova/compute/instance_types.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py index 4e250bb83..7e7198b96 100644 --- a/nova/compute/instance_types.py +++ b/nova/compute/instance_types.py @@ -57,8 +57,8 @@ def create(name, memory, vcpus, local_gb, flavorid, swap=0, except exception.DBError, e: LOG.exception(_('DB error: %s') % e) raise exception.ApiError(_("Cannot create instance_type with " - "name %(name)s and flavorid %(flavorid)s") % - locals()) + "name %(name)s and flavorid %(flavorid)s") + % locals()) def destroy(name): -- cgit