diff options
41 files changed, 909 insertions, 491 deletions
diff --git a/nova/api/openstack/compute/schemas/block_device_mapping.py b/nova/api/openstack/compute/schemas/block_device_mapping.py index ec20c944fc..6c32199180 100644 --- a/nova/api/openstack/compute/schemas/block_device_mapping.py +++ b/nova/api/openstack/compute/schemas/block_device_mapping.py @@ -16,6 +16,7 @@ import copy from nova.api.openstack.compute.schemas import block_device_mapping_v1 from nova.api.validation import parameter_types +from nova.objects import fields block_device_mapping_new_item = { @@ -35,7 +36,8 @@ block_device_mapping_new_item = { # Defined as varchar(255) in column "destination_type" in table # "block_device_mapping" 'destination_type': { - 'type': 'string', 'maxLength': 255, + 'type': 'string', + 'enum': fields.BlockDeviceDestinationType.ALL, }, # Defined as varchar(255) in column "guest_format" in table # "block_device_mapping" diff --git a/nova/api/openstack/compute/schemas/block_device_mapping_v1.py b/nova/api/openstack/compute/schemas/block_device_mapping_v1.py index d4e6e9f836..5528e3d137 100644 --- a/nova/api/openstack/compute/schemas/block_device_mapping_v1.py +++ b/nova/api/openstack/compute/schemas/block_device_mapping_v1.py @@ -22,7 +22,7 @@ legacy_block_device_mapping = { }, 'volume_id': parameter_types.volume_id, 'snapshot_id': parameter_types.image_id, - 'volume_size': parameter_types.non_negative_integer, + 'volume_size': parameter_types.volume_size, # Do not allow empty device names and number values and # containing spaces(defined in nova/block_device.py:from_api()) 'device_name': { diff --git a/nova/api/openstack/compute/schemas/user_data.py b/nova/api/openstack/compute/schemas/user_data.py index dd4f9ad244..6ffc4aaab3 100644 --- a/nova/api/openstack/compute/schemas/user_data.py +++ b/nova/api/openstack/compute/schemas/user_data.py @@ -18,3 +18,13 @@ server_create = { 'format': 'base64' }, } + + +server_create_v20 = { + 'user_data': { + 'oneOf': [ + {'type': 'string', 'format': 'base64'}, + {'type': 'null'}, + ], + }, +} diff --git a/nova/api/openstack/compute/user_data.py b/nova/api/openstack/compute/user_data.py index fdcb1c0f7a..7e46ee78ee 100644 --- a/nova/api/openstack/compute/user_data.py +++ b/nova/api/openstack/compute/user_data.py @@ -39,4 +39,6 @@ class UserData(extensions.V21APIExtensionBase): create_kwargs['user_data'] = server_dict.get(ATTRIBUTE_NAME) def get_server_create_schema(self, version): + if version == '2.0': + return schema_user_data.server_create_v20 return schema_user_data.server_create diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py index 1a530162f0..146c937f98 100644 --- a/nova/api/openstack/wsgi.py +++ b/nova/api/openstack/wsgi.py @@ -661,7 +661,7 @@ class Resource(wsgi.Application): accept = request.best_match_content_type() except exception.InvalidContentType: msg = _("Unsupported Content-Type") - return Fault(webob.exc.HTTPBadRequest(explanation=msg)) + return Fault(webob.exc.HTTPUnsupportedMediaType(explanation=msg)) # NOTE(Vek): Splitting the function up this way allows for # auditing by external tools that wrap the existing diff --git a/nova/api/validation/parameter_types.py b/nova/api/validation/parameter_types.py index e17443fd2f..45c6b7f412 100644 --- a/nova/api/validation/parameter_types.py +++ b/nova/api/validation/parameter_types.py @@ -21,6 +21,7 @@ import unicodedata import six +from nova import db from nova.i18n import _ @@ -347,3 +348,11 @@ ipv6 = { cidr = { 'type': 'string', 'format': 'cidr' } + + +volume_size = { + 'type': ['integer', 'string'], + 'pattern': '^[0-9]+$', + 'minimum': 1, + 'maximum': db.MAX_INT +} diff --git a/nova/api/validation/validators.py b/nova/api/validation/validators.py index 392689d114..72a3095d18 100644 --- a/nova/api/validation/validators.py +++ b/nova/api/validation/validators.py @@ -48,6 +48,10 @@ def _validate_base64_format(instance): base64.decodestring(instance) except base64.binascii.Error: return False + except TypeError: + # The name must be string type. If instance isn't string type, the + # TypeError will be raised at here. + return False return True diff --git a/nova/cells/state.py b/nova/cells/state.py index a61989fed9..a26c2417a7 100644 --- a/nova/cells/state.py +++ b/nova/cells/state.py @@ -275,12 +275,12 @@ class CellStateManager(base.Base): continue chost = compute_hosts[host] - chost['free_ram_mb'] += compute['free_ram_mb'] - free_disk = compute['free_disk_gb'] * 1024 - chost['free_disk_mb'] += free_disk - chost['total_ram_mb'] += compute['memory_mb'] - total_disk = compute['local_gb'] * 1024 - chost['total_disk_mb'] += total_disk + chost['free_ram_mb'] += max(0, compute.free_ram_mb) + free_disk = compute.free_disk_gb * 1024 + chost['free_disk_mb'] += max(0, free_disk) + chost['total_ram_mb'] += max(0, compute.memory_mb) + total_disk = compute.local_gb * 1024 + chost['total_disk_mb'] += max(0, total_disk) _get_compute_hosts() if not compute_hosts: diff --git a/nova/cmd/api.py b/nova/cmd/api.py index a63871b565..6964d77d24 100644 --- a/nova/cmd/api.py +++ b/nova/cmd/api.py @@ -25,8 +25,11 @@ import sys from oslo_config import cfg from oslo_log import log as logging from oslo_reports import guru_meditation_report as gmr +import six from nova import config +from nova import exception +from nova.i18n import _LE, _LW from nova import objects from nova import service from nova import utils @@ -42,12 +45,26 @@ def main(): logging.setup(CONF, "nova") utils.monkey_patch() objects.register_all() + log = logging.getLogger(__name__) gmr.TextGuruMeditation.setup_autorun(version) launcher = service.process_launcher() + started = 0 for api in CONF.enabled_apis: should_use_ssl = api in CONF.enabled_ssl_apis - server = service.WSGIService(api, use_ssl=should_use_ssl) - launcher.launch_service(server, workers=server.workers or 1) + try: + server = service.WSGIService(api, use_ssl=should_use_ssl) + launcher.launch_service(server, workers=server.workers or 1) + started += 1 + except exception.PasteAppNotFound as ex: + log.warning( + _LW("%s. ``enabled_apis`` includes bad values. " + "Fix to remove this warning."), six.text_type(ex)) + + if started == 0: + log.error(_LE('No APIs were started. ' + 'Check the enabled_apis config option.')) + sys.exit(1) + launcher.wait() diff --git a/nova/compute/api.py b/nova/compute/api.py index 0cd37b14a5..972405214e 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -2270,6 +2270,13 @@ class API(base.Base): image_meta = self._initialize_instance_snapshot_metadata( instance, name, properties) + # if we're making a snapshot, omit the disk and container formats, + # since the image may have been converted to another format, and the + # original values won't be accurate. The driver will populate these + # with the correct values later, on image upload. + if image_type == 'snapshot': + image_meta.pop('disk_format', None) + image_meta.pop('container_format', None) return self.image_api.create(context, image_meta) def _initialize_instance_snapshot_metadata(self, instance, name, diff --git a/nova/compute/manager.py b/nova/compute/manager.py index c01dfcf81d..79562577f4 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -2897,7 +2897,7 @@ class ComputeManager(manager.Manager): image_meta = objects.ImageMeta.from_image_ref( context, self.image_api, image_ref) else: - image_meta = objects.ImageMeta.from_dict({}) + image_meta = instance.image_meta # This instance.exists message should contain the original # image_ref, not the new one. Since the DB has been updated @@ -6793,28 +6793,29 @@ class ComputeManager(manager.Manager): in migrations]) inst_filters = {'deleted': True, 'soft_deleted': False, - 'uuid': inst_uuid_from_migrations, 'host': CONF.host} + 'uuid': inst_uuid_from_migrations} attrs = ['info_cache', 'security_groups', 'system_metadata'] with utils.temporary_mutation(context, read_deleted='yes'): instances = objects.InstanceList.get_by_filters( context, inst_filters, expected_attrs=attrs, use_slave=True) for instance in instances: - for migration in migrations: - if instance.uuid == migration.instance_uuid: - # Delete instance files if not cleanup properly either - # from the source or destination compute nodes when - # the instance is deleted during resizing. - self.driver.delete_instance_files(instance) - try: - migration.status = 'failed' - with migration.obj_as_admin(): - migration.save() - except exception.MigrationNotFound: - LOG.warning(_LW("Migration %s is not found."), - migration.id, context=context, - instance=instance) - break + if instance.host != CONF.host: + for migration in migrations: + if instance.uuid == migration.instance_uuid: + # Delete instance files if not cleanup properly either + # from the source or destination compute nodes when + # the instance is deleted during resizing. + self.driver.delete_instance_files(instance) + try: + migration.status = 'failed' + with migration.obj_as_admin(): + migration.save() + except exception.MigrationNotFound: + LOG.warning(_LW("Migration %s is not found."), + migration.id, context=context, + instance=instance) + break @messaging.expected_exceptions(exception.InstanceQuiesceNotSupported, exception.QemuGuestAgentNotEnabled, diff --git a/nova/compute/resource_tracker.py b/nova/compute/resource_tracker.py index 42ecd5fa37..8dcf7f5434 100644 --- a/nova/compute/resource_tracker.py +++ b/nova/compute/resource_tracker.py @@ -925,6 +925,8 @@ class ResourceTracker(object): for instance in instances: if instance.vm_state not in vm_states.ALLOW_RESOURCE_REMOVAL: self._update_usage_from_instance(context, instance) + self.compute_node.free_ram_mb = max(0, self.compute_node.free_ram_mb) + self.compute_node.free_disk_gb = max(0, self.compute_node.free_disk_gb) def _find_orphaned_instances(self): """Given the set of instances and migrations already account for diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py index ac3cc643d5..46e041e629 100644 --- a/nova/compute/rpcapi.py +++ b/nova/compute/rpcapi.py @@ -645,6 +645,7 @@ class ComputeAPI(object): pre_migration_result=True) if not self.client.can_send_version(version): version = '4.0' + args.pop('migration') cctxt = self.client.prepare(server=host, version=version) cctxt.cast(ctxt, 'live_migration', instance=instance, dest=dest, block_migration=block_migration, diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 346ab360e7..a163ead674 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1949,6 +1949,9 @@ def instance_destroy(context, instance_uuid, constraint=None): model_query(context, models.InstanceSystemMetadata).\ filter_by(instance_uuid=instance_uuid).\ soft_delete() + model_query(context, models.InstanceGroupMember).\ + filter_by(instance_id=instance_uuid).\ + soft_delete() # NOTE(snikitin): We can't use model_query here, because there is no # column 'deleted' in 'tags' table. context.session.query(models.Tag).filter_by( @@ -4765,7 +4768,7 @@ def migration_get_in_progress_by_host_and_node(context, host, node): models.Migration.dest_node == node))).\ filter(~models.Migration.status.in_(['accepted', 'confirmed', 'reverted', 'error', - 'failed'])).\ + 'failed', 'completed'])).\ options(joinedload_all('instance.system_metadata')).\ all() @@ -6320,6 +6323,35 @@ def _archive_deleted_rows_for_table(tablename, max_rows): # database's limit of maximum parameter in one SQL statement. deleted_column = table.c.deleted columns = [c.name for c in table.c] + + # NOTE(clecomte): Tables instance_actions and instances_actions_events + # have to be manage differently so we soft-delete them here to let + # the archive work the same for all tables + if tablename == "instance_actions": + instances = models.BASE.metadata.tables["instances"] + deleted_instances = sql.select([instances.c.uuid]).\ + where(instances.c.deleted != instances.c.deleted.default.arg) + update_statement = table.update().values(deleted=table.c.id).\ + where(table.c.instance_uuid.in_(deleted_instances)) + + conn.execute(update_statement) + + elif tablename == "instance_actions_events": + # NOTE(clecomte): we have to grab all the relation from + # instances because instance_actions_events rely on + # action_id and not uuid + instances = models.BASE.metadata.tables["instances"] + instance_actions = models.BASE.metadata.tables["instance_actions"] + deleted_instances = sql.select([instances.c.uuid]).\ + where(instances.c.deleted != instances.c.deleted.default.arg) + deleted_actions = sql.select([instance_actions.c.id]).\ + where(instance_actions.c.instance_uuid.in_(deleted_instances)) + + update_statement = table.update().values(deleted=table.c.id).\ + where(table.c.action_id.in_(deleted_actions)) + + conn.execute(update_statement) + insert = shadow_table.insert(inline=True).\ from_select(columns, sql.select([table], diff --git a/nova/locale/de/LC_MESSAGES/nova.po b/nova/locale/de/LC_MESSAGES/nova.po index 59373175ae..d1b13e3bff 100644 --- a/nova/locale/de/LC_MESSAGES/nova.po +++ b/nova/locale/de/LC_MESSAGES/nova.po @@ -14,13 +14,13 @@ # Monika Wolf <vcomas3@de.ibm.com>, 2016. #zanata msgid "" msgstr "" -"Project-Id-Version: nova 13.0.1.dev12\n" +"Project-Id-Version: nova 13.0.1.dev33\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-04-19 04:49+0000\n" +"POT-Creation-Date: 2016-04-22 16:50+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2016-04-12 10:40+0000\n" +"PO-Revision-Date: 2016-04-25 02:00+0000\n" "Last-Translator: Monika Wolf <vcomas3@de.ibm.com>\n" "Language: de\n" "Language-Team: German\n" @@ -3352,6 +3352,10 @@ msgstr "" "Nur %(value)s %(verb)s-Anforderung(en) an %(uri)s alle %(unit_string)s " "möglich" +#, python-format +msgid "Only %d SCSI controllers are allowed to be created on this instance." +msgstr "Nur %d SCSI-Controller dürfen in dieser Instanz erstellt werden." + msgid "Only 'updated_since', 'project_id' and 'deleted' are understood." msgstr "Nur 'updated_since', 'project_id' und 'deleted' werden verstanden." @@ -4623,7 +4627,7 @@ msgid "Unable to find host for Instance %s" msgstr "Host für Instanz %s kann nicht gefunden werden" msgid "Unable to find iSCSI Target" -msgstr "iSCSI-Ziel konnte nicht gefunden worden" +msgstr "iSCSI-Ziel konnte nicht gefunden werden." #, python-format msgid "Unable to find key_file : %s" diff --git a/nova/locale/es/LC_MESSAGES/nova.po b/nova/locale/es/LC_MESSAGES/nova.po index f421935155..f92310bb3e 100644 --- a/nova/locale/es/LC_MESSAGES/nova.po +++ b/nova/locale/es/LC_MESSAGES/nova.po @@ -19,13 +19,13 @@ # Tom Cocozzello <tjcocozz@us.ibm.com>, 2016. #zanata msgid "" msgstr "" -"Project-Id-Version: nova 13.0.1.dev12\n" +"Project-Id-Version: nova 13.0.1.dev33\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-04-19 04:49+0000\n" +"POT-Creation-Date: 2016-04-22 16:50+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2016-03-23 08:57+0000\n" +"PO-Revision-Date: 2016-04-25 09:07+0000\n" "Last-Translator: Eugènia Torrella <tester03@es.ibm.com>\n" "Language: es\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" @@ -560,7 +560,7 @@ msgstr "" "No se puede utilizar la migración de bloque con almacenamiento compartido. " msgid "Boot index is invalid." -msgstr "El índice de arranque es válido." +msgstr "El índice de arranque no es válido." #, python-format msgid "Build of instance %(instance_uuid)s aborted: %(reason)s" @@ -2300,7 +2300,7 @@ msgid "Invalid datetime string: %(reason)s" msgstr "Cadena date time invalida: %(reason)s" msgid "Invalid device UUID." -msgstr "Dispositivo UUID invalido." +msgstr "Dispositivo UUID no válido." #, python-format msgid "Invalid entry: '%s'" @@ -2495,7 +2495,7 @@ msgid "Invalid signature key type: %s" msgstr "Tipo de clave de firma no válido: %s" msgid "Invalid source_type field." -msgstr "Campo source_type inválido." +msgstr "Campo source_type no válido." msgid "Invalid start time. The start time cannot occur after the end time." msgstr "" @@ -4046,7 +4046,7 @@ msgid "Some fields are invalid." msgstr "Algunos campos no son válidos." msgid "Some required fields are missing" -msgstr "Algunos campos obligatorios no están rellenos." +msgstr "Faltan algunos campos obligatorios." #, python-format msgid "" diff --git a/nova/locale/pt_BR/LC_MESSAGES/nova.po b/nova/locale/pt_BR/LC_MESSAGES/nova.po index d3b712b2b7..1c9eb7abe9 100644 --- a/nova/locale/pt_BR/LC_MESSAGES/nova.po +++ b/nova/locale/pt_BR/LC_MESSAGES/nova.po @@ -14,7 +14,6 @@ # Volmar Oliveira Junior <volmar.oliveira.jr@gmail.com>, 2013 # Welkson Renny de Medeiros <welkson@gmail.com>, 2012 # Wiliam Souza <wiliamsouza83@gmail.com>, 2013 -# Fernando Pimenta <fernando.c.pimenta@gmail.com>, 2015. #zanata # Lucas Palm <lapalm@us.ibm.com>, 2015. #zanata # OpenStack Infra <zanata@openstack.org>, 2015. #zanata # Carlos Marques <marquesc@br.ibm.com>, 2016. #zanata @@ -22,13 +21,13 @@ # Lucas Palm <lapalm@us.ibm.com>, 2016. #zanata msgid "" msgstr "" -"Project-Id-Version: nova 13.0.1.dev30\n" +"Project-Id-Version: nova 13.0.1.dev33\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-04-21 15:11+0000\n" +"POT-Creation-Date: 2016-04-22 16:50+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2016-04-20 06:40+0000\n" +"PO-Revision-Date: 2016-04-25 07:57+0000\n" "Last-Translator: Carlos Marques <marquesc@br.ibm.com>\n" "Language: pt-BR\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" @@ -46,7 +45,7 @@ msgstr "%(address)s não é um endereço IPv4/6 válido." #, python-format msgid "%(address)s is not within %(cidr)s." -msgstr "%(address)s não está dentro do %(cidr)s." +msgstr "%(address)s não está dentro de %(cidr)s." #, python-format msgid "" @@ -91,7 +90,7 @@ msgstr "%(field)s não deve fazer parte das atualizações." #, python-format msgid "%(fieldname)s missing field type" -msgstr "%(fieldname)s faltando tipo do campo" +msgstr "Informação de tipo de campo ausente para %(fieldname)s" #, python-format msgid "%(host)s:%(port)s: Target closed" @@ -108,15 +107,16 @@ msgstr "%(key)s deve ser um número inteiro." #, python-format msgid "%(memsize)d MB of memory assigned, but expected %(memtotal)d MB" -msgstr "%(memsize)d MB de memória designada, mas esperada %(memtotal)d MB" +msgstr "" +"Memória designada de %(memsize)d MB, mas memória esperada de %(memtotal)d MB" #, python-format msgid "%(name)s has a minimum character requirement of %(min_length)s." -msgstr "%(name)s tem um requisito de caracteres mínimo de %(min_length)s." +msgstr "%(name)s tem um requisito mínimo de %(min_length)s caracteres." #, python-format msgid "%(name)s has more than %(max_length)s characters." -msgstr "%(name)s possui mais de %(max_length)s caracteres." +msgstr "%(name)s possui mais que %(max_length)s caracteres." #, python-format msgid "%(path)s is not on local storage: %(reason)s" @@ -128,7 +128,7 @@ msgstr "%(path)s não está no armazenamento compartilhado: %(reason)s" #, python-format msgid "%(req)s is required to create a network." -msgstr "%(req)s é necessário para criar a rede." +msgstr "%(req)s é necessário para a criação de uma rede." #, python-format msgid "%(total)i rows matched query %(meth)s, %(done)i migrated" @@ -160,15 +160,16 @@ msgstr "%(vendor)s %(product)s %(version)s" #, python-format msgid "%(worker_name)s value of %(workers)s is invalid, must be greater than 0" -msgstr "%(worker_name)s valor de %(workers)s é inválido, deve ser maior que 0" +msgstr "" +"O valor %(worker_name)s de %(workers)s é inválido, deve ser maior que 0" #, python-format msgid "%r failed. Not Retrying." -msgstr "%r falhou. Não tentando novamente." +msgstr "Falha em %r. Sem novas tentativas" #, python-format msgid "%r failed. Retrying." -msgstr "%r falhou. Tentando novamente." +msgstr "Falha em %r. Tentando novamente." #, python-format msgid "%s does not support disk hotplug." @@ -180,7 +181,7 @@ msgstr "O formato %s não é suportado" #, python-format msgid "%s is not a string or unicode" -msgstr "%s não é uma sequência ou unicode" +msgstr "%s não é uma cadeia de caracteres ou unicode" #, python-format msgid "%s is not a valid IP network" @@ -260,15 +261,15 @@ msgid "" "API Version String %(version)s is of invalid format. Must be of format " "MajorNum.MinorNum." msgstr "" -"String de Versão de API %(version)s é de formato inválido. Deve estar no " +"O formato da String de Versão de API %(version)s é inválido. Deve estar no " "formato MajorNum.MinorNum." #, python-format msgid "API version %(version)s is not supported on this method." -msgstr "Versão de API %(version)s não é suportada nesse método." +msgstr "A versão de API %(version)s não é suportada nesse método." msgid "Access list not available for public flavors." -msgstr "Lista de acesso não disponível para métodos públicos." +msgstr "Lista de acesso não disponível para espécies públicas." #, python-format msgid "Action %s not found" @@ -309,8 +310,8 @@ msgid "" "Agent-build with hypervisor %(hypervisor)s os %(os)s architecture " "%(architecture)s exists." msgstr "" -"A construção do agente com hypervisor %(hypervisor)s os %(os)s arquitetura " -"%(architecture)s existe." +"A construção do agente com hypervisor %(hypervisor)s SO %(os)s arquitetura " +"%(architecture)s já existe." #, python-format msgid "Aggregate %(aggregate_id)s already has host %(host)s." @@ -318,7 +319,7 @@ msgstr "O agregado %(aggregate_id)s já possui o host %(host)s." #, python-format msgid "Aggregate %(aggregate_id)s could not be found." -msgstr "O agregado %(aggregate_id)s não pôde ser localizado." +msgstr "Não foi possível localizar o agregado %(aggregate_id)s." #, python-format msgid "Aggregate %(aggregate_id)s has no host %(host)s." @@ -334,7 +335,7 @@ msgstr "" msgid "" "Aggregate %(aggregate_id)s: action '%(action)s' caused an error: %(reason)s." msgstr "" -"Agregado %(aggregate_id)s: ação '%(action)s' causou um erro: %(reason)s." +"Agregado %(aggregate_id)s: a ação '%(action)s' causou um erro: %(reason)s." #, python-format msgid "Aggregate %(aggregate_name)s already exists." @@ -363,8 +364,7 @@ msgid "An unexpected error has occurred." msgstr "Ocorreu um erro inesperado." msgid "An unknown error has occurred. Please try your request again." -msgstr "" -"Ocorreu um erro desconhecido. Por favor tente sua requisição novamente." +msgstr "Ocorreu um erro desconhecido. Tente sua solicitação novamente." msgid "An unknown exception occurred." msgstr "Ocorreu uma exceção desconhecida." @@ -374,7 +374,7 @@ msgstr "Política de grupo de instância Antiafinidade foi violada." #, python-format msgid "Architecture name '%(arch)s' is not recognised" -msgstr "Nome de arquitetura '%(arch)s' não é reconhecido" +msgstr "O nome de arquitetura '%(arch)s' não é reconhecido" #, python-format msgid "Architecture name '%s' is not valid" @@ -393,8 +393,8 @@ msgid "" "Asymmetric NUMA topologies require explicit assignment of CPUs and memory to " "nodes in image or flavor" msgstr "" -"Topologias NUMA assimétricas requer a designação explícita de CPUs e da " -"memória para nós na imagem ou tipo" +"Topologias NUMA assimétricas exigem a designação explícita de CPUs e memória " +"para nós na imagem ou espécie" #, python-format msgid "" @@ -470,8 +470,8 @@ msgid "" "Binding failed for port %(port_id)s, please check neutron logs for more " "information." msgstr "" -"A ligação falhou para a porta %(port_id)s, verifique os logs do neutron para " -"obter informações adicionais." +"Falha na vinculação para a porta %(port_id)s, verifique os logs do Neutron " +"para obter informações adicionais." msgid "Blank components" msgstr "Componentes em branco" @@ -492,7 +492,7 @@ msgid "" "for this operation." msgstr "" "O Mapeamento de Dispositivo de Bloco %(volume_id)s é um volume de diversas " -"conexões e não é válido para essa operação." +"conexões e não é válido para esta operação." msgid "Block Device Mapping cannot be converted to legacy format. " msgstr "" @@ -516,7 +516,7 @@ msgid "" "Block Device Mapping is Invalid: Boot sequence for the instance and image/" "block device mapping combination is not valid." msgstr "" -"Mapeamento de Dispositivo de Bloco inválido: A sequência de boot para a " +"Mapeamento de Dispositivo de Bloco inválido: a sequência de boot para a " "instância e a combinação de mapeamento de dispositivo de imagem/bloco é " "inválida." @@ -524,7 +524,7 @@ msgid "" "Block Device Mapping is Invalid: You specified more local devices than the " "limit allows" msgstr "" -"Mapeamento de Dispositivo de Bloco inválido: Você especificou mais " +"Mapeamento de Dispositivo de Bloco inválido: você especificou mais " "dispositivos locais que o limite permitido" #, python-format @@ -567,7 +567,7 @@ msgid "CIDR is malformed." msgstr "CIDR está malformado." msgid "CPU and memory allocation must be provided for all NUMA nodes" -msgstr "CPU e alocação de memória devem ser fornecidos para todos os nós NUMA" +msgstr "A alocação de CPU e memória deve ser fornecida para todos os nós NUMA" #, python-format msgid "" @@ -597,18 +597,18 @@ msgstr "Número de CPU %(cpuset)s não é designado a nenhum nó" #, python-format msgid "CPU pinning is not supported by the host: %(reason)s" -msgstr "A fixação de CPU não é suportada pelo host: %(reason)s" +msgstr "Pinning de CPU não é suportado pelo host: %(reason)s" #, python-format msgid "" "CPU set to pin/unpin %(requested)s must be a subset of known CPU set " "%(cpuset)s" msgstr "" -"A CPU configurada para fixar/desafixar %(requested)s deve ser um subconjunto " -"do conjunto de CPU conhecido %(cpuset)s" +"A CPU configurada para vincular/desvincular %(requested)s deve ser um " +"subconjunto de um conjunto de CPUs conhecido %(cpuset)s" msgid "Can not add access to a public flavor." -msgstr "Não é possível incluir acesso em um tipo público." +msgstr "Não é adicionar acesso a um tipo público." msgid "Can not find requested image" msgstr "Não é possível localizar a imagem solicitada" @@ -640,8 +640,8 @@ msgstr "" msgid "" "Cannot '%(action)s' instance %(server_id)s while it is in %(attr)s %(state)s" msgstr "" -"Não é possível '%(action)s' da instância %(server_id)s enquanto ele está em " -"%(attr)s %(state)s" +"Não é possível '%(action)s' a instância %(server_id)s enquanto ele está no " +"estado %(attr)s %(state)s" #, python-format msgid "" @@ -706,7 +706,7 @@ msgstr "" "possível determinar onde armazenar as imagens" msgid "Cannot disassociate auto assigned floating IP" -msgstr "Não é possível desassociar o IP flutuante designado automaticamente" +msgstr "Não é possível desassociar um IP flutuante designado automaticamente" msgid "Cannot execute /sbin/mount.sofs" msgstr "Não é possível executar /sbin/mount.sofs" @@ -741,8 +741,8 @@ msgstr "Não é possível montar Scality SOFS, verifique os erros no syslog" msgid "" "Cannot pin/unpin cpus %(requested)s from the following pinned set %(pinned)s" msgstr "" -"Não é possível fixar/desmarcar cpus %(requested)s a partir do seguinte " -"conjunto fixado %(pinned)s" +"Não é possível vincular/desvincular cpus %(requested)s nos seguintes " +"conjuntos de pinning %(pinned)s" #, python-format msgid "Cannot remove host %(host)s in aggregate %(id)s" @@ -781,7 +781,7 @@ msgid "" "Cannot set cpu thread pinning policy in a non dedicated cpu pinning policy" msgstr "" "Não é possível configurar a política de pinning de encadeamento de CPU em " -"uma política de pinning de CPU dedicada" +"uma política de pinning de cpu não dedicada" #, python-format msgid "Cannot set metadata %(metadata)s in aggregate %(id)s" @@ -789,8 +789,8 @@ msgstr "Não é possível configurar metadados %(metadata)s no agregado %(id)s" msgid "Cannot set realtime policy in a non dedicated cpu pinning policy" msgstr "" -"Não é possível configurar a política em tempo real em uma política de " -"pinning de CPU dedicada" +"Não é possível configurar a política de tempo real em uma política de " +"pinning de CPU não dedicada" #, python-format msgid "Cannot update aggregate %(aggregate_id)s. Reason: %(reason)s." @@ -804,7 +804,7 @@ msgstr "Não é possível atualizar o arquivo de configuração de células." msgid "" "Cannot update metadata of aggregate %(aggregate_id)s. Reason: %(reason)s." msgstr "" -"Não é possível atualizar o metadado do agregado %(aggregate_id)s. Motivo: " +"Não é possível atualizar os metadados do agregado %(aggregate_id)s. Motivo: " "%(reason)s." #, python-format @@ -817,7 +817,7 @@ msgstr "Célula %(id)s não localizada." #, python-format msgid "Cell %(uuid)s has no mapping." -msgstr "Célula %(uuid)s não possui mapeamento." +msgstr "A célula %(uuid)s não possui mapeamento." #, python-format msgid "Cell %s doesn't exist." @@ -825,7 +825,7 @@ msgstr "A célula %s não existe." #, python-format msgid "Cell is not known for instance %(instance_uuid)s" -msgstr "A célula não é conhecida da instância %(instance_uuid)s" +msgstr "A célula não é conhecida para a instância %(instance_uuid)s" #, python-format msgid "Cell message has reached maximum hop count: %(hop_count)s" @@ -842,7 +842,7 @@ msgstr "O tipo da célula deve ser 'pai' ou 'filho'" #, python-format msgid "Cell with name %(name)s already exists." -msgstr "Célula com nome %(name)s já existe." +msgstr "Já existe uma célula com nome %(name)s." #, python-format msgid "Certificate is not valid after: %s UTC" @@ -855,14 +855,15 @@ msgstr "O certificado não é válido antes de: %s UTC" #, python-format msgid "" "Change would make usage less than 0 for the following resources: %(unders)s" -msgstr "A mudança faria uso de menos de 0 dos recursos a seguir: %(unders)s" +msgstr "" +"A mudança tornaria inferior a zero o uso dos recursos a seguir: %(unders)s" msgid "Claim pci failed." msgstr "Solicitação pci falhou." #, python-format msgid "Class %(class_name)s could not be found: %(exception)s" -msgstr "A classe %(class_name)s não pôde ser localizada: %(exception)s" +msgstr "Não foi possível localizar a classe %(class_name)s: %(exception)s" #, python-format msgid "" @@ -879,15 +880,16 @@ msgstr "O host de cálculo %(host)s não pôde ser localizado." #, python-format msgid "Compute host %(name)s needs to be created first before updating." msgstr "" -"O host de cálculo %(name)s precisa ser criado primeiro antes de atualizar." +"O host de cálculo %(name)s precisa ser criado primeiro para que possa ser " +"atualizado." #, python-format msgid "Compute host %s not found." -msgstr "Compute host %s não pode ser encontrado." +msgstr "Host de cálculo %s não localizado." #, python-format msgid "Compute service of %(host)s is still in use." -msgstr "Serviço de cálculo de %(host)s ainda está em uso." +msgstr "O serviço de cálculo de %(host)s ainda está em uso." #, python-format msgid "Compute service of %(host)s is unavailable at this time." @@ -895,7 +897,7 @@ msgstr "O serviço de cálculo de %(host)s está indisponível no momento." #, python-format msgid "Config drive format '%(format)s' is not supported." -msgstr "O formato da unidade de configuração %(format)s não é suportado." +msgstr "O formato da unidade configurada %(format)s não é suportado." msgid "Config requested a custom CPU model, but no model name was provided" msgstr "" @@ -931,11 +933,11 @@ msgstr "Políticas conflitantes configuradas!" #, python-format msgid "Connection to cinder host failed: %(reason)s" -msgstr "A conexão com o host Cinder falhou: %(reason)s" +msgstr "Falha na conexão com o host Cinder: %(reason)s" #, python-format msgid "Connection to glance host %(server)s failed: %(reason)s" -msgstr "A conexão com o host Glance %(server)s falhou: %(reason)s" +msgstr "Falha na conexão com o host Glance %(server)s: %(reason)s" #, python-format msgid "Connection to libvirt lost: %s" @@ -943,7 +945,7 @@ msgstr "Conexão com libvirt perdida: %s" #, python-format msgid "Connection to the hypervisor is broken on host: %(host)s" -msgstr "A conexão com o hypervisor for interrompida no host: %(host)s" +msgstr "A conexão com o hypervisor foi interrompida no host: %(host)s" #, python-format msgid "Console %(console_id)s could not be found." @@ -958,15 +960,15 @@ msgid "" "Console for instance %(instance_uuid)s in pool %(pool_id)s could not be " "found." msgstr "" -"O console para a instância %(instance_uuid)s no conjunto %(pool_id)s não " -"pôde ser localizado." +"Não foi possível localizar o console da instância %(instance_uuid)s no " +"conjunto %(pool_id)s." #, python-format msgid "" "Console log output could not be retrieved for instance %(instance_id)s. " "Reason: %(reason)s" msgstr "" -"A saída de log do console não pôde ser recuperada para a instância " +"A saída do log do console não pôde ser recuperada para a instância " "%(instance_id)s. Motivo: %(reason)s" #, python-format @@ -979,14 +981,14 @@ msgid "" "proxy host %(host)s not found." msgstr "" "Conjunto de console do tipo %(console_type)s para o host de cálculo " -"%(compute_host)s no host do proxy %(host)s não localizado." +"%(compute_host)s no host de proxy %(host)s não localizado." #, python-format msgid "" "Console pool with host %(host)s, console_type %(console_type)s and " "compute_host %(compute_host)s already exists." msgstr "" -"Conjunto de console com host %(host)s, console_type %(console_type)s e " +"O conjunto de console com host %(host)s, console_type %(console_type)s e " "compute_host %(compute_host)s já existe." msgid "Constraint not met." @@ -1026,9 +1028,8 @@ msgstr "Não foi possível localizar a configuração em %(path)s" msgid "Could not find the datastore reference(s) which the VM uses." msgstr "" -"Não foi possível localizar a(s) referência(s) do armazenamento de dados que " -"a VM " -"usa." +"Não foi possível localizar a(s) referência(s) de armazenamento de dados " +"usada(s) pela VM." #, python-format msgid "Could not load line %(line)s, got error %(error)s" @@ -1044,8 +1045,8 @@ msgstr "" msgid "" "Could not mount vfat config drive. %(operation)s failed. Error: %(error)s" msgstr "" -"Não foi possível montar a unidade de configuração vfat. Falha de " -"%(operation)s. Erro: %(error)s" +"Não foi possível montar a unidade configurada vfat. Falha de %(operation)s. " +"Erro: %(error)s" msgid "Could not parse imageRef from request." msgstr "Não foi possível analisar imageRef a partir da solicitação." @@ -1061,13 +1062,13 @@ msgstr "Não foi possível fazer upload da imagem %(image_id)s" #, 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" +"Não foi possível obter um IP para o Link Local de %(interface)s :%(ex)s" msgid "Create networks failed" msgstr "Falha na criação de redes" msgid "Creation of virtual interface with unique mac address failed" -msgstr "Criação da interface virtual com endereço mac único falhou" +msgstr "Falha na criação da interface virtual com endereço mac exclusivo" msgid "DNS entries not found." msgstr "Entradas DNS não localizadas." @@ -1116,7 +1117,7 @@ msgstr "Remover anexo das portas SR-IOV com libvirt < %(ver)s não é permitido" #, python-format msgid "Detected existing vlan with id %(vlan)d" -msgstr "Detectado vlan existente com o ID %(vlan)d" +msgstr "Detectada vlan existente com ID %(vlan)d" #, python-format msgid "Device '%(device)s' not found." @@ -1124,7 +1125,7 @@ msgstr "Dispositivo '%(device)s' não localizado." #, python-format msgid "Device detach failed for %(device)s: %(reason)s)" -msgstr "A separação do dispositivo falhou para %(device)s: %(reason)s)" +msgstr "Falha na desconexão de dispositivo para %(device)s: %(reason)s)" #, python-format msgid "" @@ -1167,11 +1168,11 @@ msgstr "" #, python-format msgid "Disk format %(disk_format)s is not acceptable" -msgstr "Formato do disco %(disk_format)s não é aceito" +msgstr "O formato do disco %(disk_format)s não é aceito" #, python-format msgid "Disk info file is invalid: %(reason)s" -msgstr "Arquivo de informações de disco é inválido: %(reason)s" +msgstr "O arquivo de informações de disco é inválido: %(reason)s" msgid "Disk must have only one partition." msgstr "O disco deve ter apenas uma partição." @@ -1219,8 +1220,8 @@ msgstr "" msgid "Ephemeral disks requested are larger than the instance type allows." msgstr "" -"Os discos efêmeros requisitados são maiores do que o tipo de instância " -"permite." +"O número de discos efêmeros requisitado é maior que o permitido pelo tipo de " +"instância." #, python-format msgid "Error attempting to run %(method)s" @@ -1244,7 +1245,7 @@ msgstr "" #, python-format msgid "Error during following call to agent: %(method)s" -msgstr "Erro durante a seguinte chamada ao agente: %(method)s" +msgstr "Erro durante a seguinte chamada para o agente: %(method)s" #, python-format msgid "Error during unshelve instance %(instance_id)s: %(reason)s" @@ -1303,7 +1304,7 @@ msgid "Error mounting %(image)s with libguestfs (%(e)s)" msgstr "Erro ao montar %(image)s com libguestfs (%(e)s)" msgid "Error occurred while creating the verifier" -msgstr "Ocorreu um erro ao criar o verificador." +msgstr "Ocorreu um erro ao criar o verificador" #, python-format msgid "Error when creating resource monitor: %(monitor)s" @@ -1314,7 +1315,7 @@ msgstr "Erro: O agente está desativado" #, python-format msgid "Event %(event)s not found for action id %(action_id)s" -msgstr "Evento %(event)s não localizado para o ID da ação %(action_id)s" +msgstr "Evento %(event)s não localizado para o ID de ação %(action_id)s" msgid "Event must be an instance of nova.virt.event.Event" msgstr "O evento deve ser uma instância de nova.virt.event.Event" @@ -1337,11 +1338,11 @@ msgstr "" #, python-format msgid "Exceeded maximum number of retries. %(reason)s" -msgstr "Foi excedido o número máximo de tentativas. %(reason)s" +msgstr "O número máximo de tentativas foi excedido. %(reason)s" #, python-format msgid "Expected a uuid but received %(uuid)s." -msgstr "Esperado um uuid, mas recebido %(uuid)s." +msgstr "Um uuid era esperado, mas o recebido foi %(uuid)s." #, python-format msgid "Expected object of type: %s" @@ -1391,8 +1392,7 @@ msgstr "Falha ao anexar a interface" #, python-format msgid "Failed to attach network adapter device to %(instance_uuid)s" -msgstr "" -"Falha ao anexar o dispositivo de adaptador de rede para %(instance_uuid)s" +msgstr "Falha ao anexar o dispositivo adaptador de rede a %(instance_uuid)s" #, python-format msgid "Failed to create vif %s" @@ -1412,11 +1412,11 @@ msgstr "Falha ao decriptografar chave privada: %s" #, python-format msgid "Failed to decrypt text: %(reason)s" -msgstr "Falha ao decriptografar texto: %(reason)s" +msgstr "Falha ao descriptografar texto: %(reason)s" #, python-format msgid "Failed to deploy instance: %(reason)s" -msgstr "Falha ao provisionar a instância: %(reason)s" +msgstr "Falha ao implementar a instância: %(reason)s" #, python-format msgid "Failed to detach PCI device %(dev)s: %(reason)s" @@ -1424,8 +1424,7 @@ msgstr "Falha ao remover o dispositivo PCI %(dev)s: %(reason)s" #, python-format msgid "Failed to detach network adapter device from %(instance_uuid)s" -msgstr "" -"Falha ao remover o dispositivo de adaptador de rede de %(instance_uuid)s" +msgstr "Falha ao remover o dispositivo adaptador de rede de %(instance_uuid)s" #, python-format msgid "Failed to encrypt text: %(reason)s" @@ -1433,7 +1432,7 @@ msgstr "Falha ao criptografar texto: %(reason)s" #, python-format msgid "Failed to launch instances: %(reason)s" -msgstr "Falha ao ativar instâncias: %(reason)s" +msgstr "Falha ao inicializar instâncias: %(reason)s" #, python-format msgid "Failed to map partitions: %s" @@ -1489,7 +1488,7 @@ msgstr "" #, python-format msgid "Failed to resume instance: %(reason)s" -msgstr "Falha ao continuar a instância: %(reason)s" +msgstr "Falha ao retomar a instância: %(reason)s" #, python-format msgid "Failed to revoke certificate for %(project_id)s" @@ -1517,7 +1516,7 @@ msgstr "Falha ao suspender a instância: %(reason)s" #, python-format msgid "Failed to terminate instance: %(reason)s" -msgstr "Falha ao finalizar instância: %(reason)s" +msgstr "Falha ao finalizar a instância: %(reason)s" #, python-format msgid "Failed to unplug vif %s" @@ -1536,7 +1535,7 @@ msgstr "" #, python-format msgid "File %(file_path)s could not be found." -msgstr "O arquivo %(file_path)s não pôde ser localizado." +msgstr "Não foi possível localizar o arquivo %(file_path)s." #, python-format msgid "File path %s not valid" @@ -1574,7 +1573,7 @@ msgstr "IP fixo %s não localizado" #, python-format msgid "Fixed IP %s not valid" -msgstr "IP fixo %s não é válido" +msgstr "O IP fixo %s não é válido" #, python-format msgid "" @@ -1594,7 +1593,7 @@ msgstr "" #, python-format msgid "Fixed IP associate failed for network: %(net)s." -msgstr "A associação do IP fixo falhou para rede: %(net)s." +msgstr "Falha na associação do IP fixo para a rede: %(net)s." #, python-format msgid "Fixed IP not found for address %(address)s." @@ -1602,18 +1601,18 @@ msgstr "IP fixo não localizado para o endereço %(address)s." #, python-format msgid "Flavor %(flavor_id)s could not be found." -msgstr "O método %(flavor_id)s não pôde ser localizado." +msgstr "Não foi possível localizar o método %(flavor_id)s." #, python-format msgid "Flavor %(flavor_id)s has no extra specs with key %(extra_specs_key)s." msgstr "" -"Tipo %(flavor_id)s não possui especificações extras com a chave " +"O tipo %(flavor_id)s não possui especificações extras com a chave " "%(extra_specs_key)s." #, python-format msgid "Flavor %(flavor_id)s has no extra specs with key %(key)s." msgstr "" -"Tipo %(flavor_id)s não possui especificações extras com a chave %(key)s." +"A espécie %(flavor_id)s não possui especificações extras com a chave %(key)s." #, python-format msgid "" @@ -1628,7 +1627,7 @@ msgid "" "Flavor access already exists for flavor %(flavor_id)s and project " "%(project_id)s combination." msgstr "" -"Acesso flavor já existe para o flavor %(flavor_id)s e o projeto " +"Já existe acesso flavor para a combinação flavor %(flavor_id)s e projeto " "%(project_id)s." #, python-format @@ -1658,15 +1657,15 @@ msgstr "O método usado pela instância não pôde ser localizado." #, python-format msgid "Flavor with ID %(flavor_id)s already exists." -msgstr "Tipo com ID %(flavor_id)s já existe." +msgstr "O tipo com ID %(flavor_id)s já existe." #, python-format msgid "Flavor with name %(flavor_name)s could not be found." -msgstr "Tipo com nome %(flavor_name)s não pôde ser localizado." +msgstr "Não foi possível localizar o tipo com nome %(flavor_name)s." #, python-format msgid "Flavor with name %(name)s already exists." -msgstr "Tipo com nome %(name)s já existe." +msgstr "O tipo com nome %(name)s já existe." #, python-format msgid "" @@ -1674,8 +1673,8 @@ msgid "" "Flavor disk is %(flavor_size)i bytes, minimum size is %(image_min_disk)i " "bytes." msgstr "" -"O disco do tipo é menor que o tamanho mínimo especificado nos metadados de " -"imagem. O disco do tipo tem %(flavor_size)i bytes; o tamanho mínimo é " +"O disco da espécie é menor que o tamanho mínimo especificado nos metadados " +"da imagem. O disco da espécie tem %(flavor_size)i bytes; o tamanho mínimo é " "%(image_min_disk)i bytes." #, python-format @@ -1683,11 +1682,11 @@ msgid "" "Flavor's disk is too small for requested image. Flavor disk is " "%(flavor_size)i bytes, image is %(image_size)i bytes." msgstr "" -"O disco do tipo é muito pequeno para a imagem solicitada. O disco do tipo " -"tem %(flavor_size)i bytes; a imagem tem %(image_size)i bytes." +"O disco da espécie é muito pequeno para a imagem solicitada. O disco da " +"espécie tem %(flavor_size)i bytes; a imagem tem %(image_size)i bytes." msgid "Flavor's memory is too small for requested image." -msgstr "Memória do tipo é muito pequena para a imagem solicitada." +msgstr "A memória da espécie é muito pequena para a imagem solicitada." #, python-format msgid "Floating IP %(address)s already exists." @@ -1695,7 +1694,7 @@ msgstr "O IP flutuante %(address)s já existe." #, python-format msgid "Floating IP %(address)s association has failed." -msgstr "A associação de IP flutuante %(address)s falhou." +msgstr "Falha na associação de IP flutuante %(address)s." #, python-format msgid "Floating IP %(address)s is associated." @@ -1710,7 +1709,7 @@ msgid "Floating IP %(address)s is not associated." msgstr "O IP flutuante %(address)s não está associado." msgid "Floating IP allocate failed." -msgstr "A alocação de IP flutuante falhou." +msgstr "Falha na alocação de IP flutuante." msgid "Floating IP is not associated" msgstr "O IP flutuante não está associado" @@ -1738,7 +1737,7 @@ msgid "" "Forbidden to exceed flavor value of number of serial ports passed in image " "meta." msgstr "" -"Proibido exceder valor do tipo do número de portas seriais passadas nos " +"Proibido exceder valor da espécie do número de portas seriais passadas nos " "metadados de imagem." #, python-format @@ -1789,7 +1788,7 @@ msgstr "Host" #, python-format msgid "Host %(host)s could not be found." -msgstr "Host %(host)s não encontrado." +msgstr "Host %(host)s não localizado." #, python-format msgid "Host %(host)s is already mapped to cell %(uuid)s" @@ -1800,13 +1799,13 @@ msgid "" "Host %(server)s is running an old version of Nova, live migrations involving " "that version may cause data loss. Upgrade Nova on %(server)s and try again." msgstr "" -"O host %(server)s está executando uma versão antiga do Nova, migrações em " -"tempo real envolvendo essa versão pode causar a perda de dados. Faça upgrade " -"de Nova em %(server)s e tente novamente." +"O host %(server)s está executando uma versão antiga do Nova e migrações em " +"tempo real envolvendo essa versão podem causar a perda de dados. Faça " +"upgrade do Nova no %(server)s e tente novamente." #, python-format msgid "Host '%(name)s' is not mapped to any cell" -msgstr "Host '%(name)s' não mapeado para qualquer célula" +msgstr "O host '%(name)s' não está mapeado para nenhuma célula" msgid "Host PowerOn is not supported by the Hyper-V driver" msgstr "O host PowerOn não é suportado pelo driver Hyper-V" @@ -1840,7 +1839,7 @@ msgstr "O tipo hypervisor virt '%s' não é válido" #, python-format msgid "Hypervisor virtualization type '%(hv_type)s' is not recognised" -msgstr "Tipo de virtualização do hypervisor '%(hv_type)s' não é reconhecido" +msgstr "O tipo de virtualização do hypervisor '%(hv_type)s' não é reconhecido" #, python-format msgid "Hypervisor with ID '%s' could not be found." @@ -1874,7 +1873,7 @@ msgstr "" #, python-format msgid "Image %(image_id)s could not be found." -msgstr "Imagem %(image_id)s não foi encontrada." +msgstr "A imagem %(image_id)s não foi encontrada." #, python-format msgid "" @@ -1884,7 +1883,7 @@ msgid "" msgstr "" "A imagem %(image_id)s não pôde ser localizada. A API nova EC2 designa IDs de " "imagem dinamicamente quando eles são listados pela primeira vez. Você listou " -"IDs de imagem desde a inclusão dessa imagem?" +"IDs de imagem desde a inclusão desta imagem?" #, python-format msgid "Image %(image_id)s is not active." @@ -1907,7 +1906,7 @@ msgid "Image metadata key too long" msgstr "A chave de metadados da imagem é muito longa" msgid "Image metadata limit exceeded" -msgstr "Limite excedido de metadados da imagem" +msgstr "Limite excedido de metadados na imagem" #, python-format msgid "Image model '%(image)s' is not supported" @@ -1921,23 +1920,23 @@ msgid "" "Image property '%(name)s' is not permitted to override NUMA configuration " "set against the flavor" msgstr "" -"Propriedade de imagem '%(name)s' não é permitida para substituir a " -"configuração NUMA definida com relação ao tipo" +"Não é permitido que a propriedade de imagem '%(name)s' substitua a " +"configuração NUMA definida em relação à espécie" msgid "" "Image property 'hw_cpu_policy' is not permitted to override CPU pinning " "policy set against the flavor" msgstr "" -"Propriedade de imagem 'hw_cpu_policy' não é permitida para substituir o " -"pinning da CPU conjunto de política em relação ao tipo" +"Não é permitido que a propriedade de imagem 'hw_cpu_policy' substitua a " +"política de pinning de CPU definida para a espécie" msgid "" "Image property 'hw_cpu_thread_policy' is not permitted to override CPU " "thread pinning policy set against the flavor" msgstr "" -"A propriedade de imagem 'hw_cpu_thread_policy' não é permitida para " -"substituir o conjunto de política de pinning de encadeamento de CPU em " -"relação ao tipo" +"Não é permitido que a propriedade de imagem 'hw_cpu_thread_policy' " +"substitua a política de pinning de encadeamento de CPU definida para a " +"espécie" msgid "Image that the instance was started with could not be found." msgstr "A imagem que foi iniciada pela instância não pode ser localizada." @@ -1947,7 +1946,7 @@ msgid "" "Image vCPU limits %(sockets)d:%(cores)d:%(threads)d exceeds permitted " "%(maxsockets)d:%(maxcores)d:%(maxthreads)d" msgstr "" -"Limites de vCPU de imagem %(sockets)d:%(cores)d:%(threads)d excede o " +"Os limites de vCPU de imagem %(sockets)d:%(cores)d:%(threads)d excedem o " "permitido %(maxsockets)d:%(maxcores)d:%(maxthreads)d" #, python-format @@ -1955,12 +1954,12 @@ msgid "" "Image vCPU topology %(sockets)d:%(cores)d:%(threads)d exceeds permitted " "%(maxsockets)d:%(maxcores)d:%(maxthreads)d" msgstr "" -"Topologia de vCPU de imagem %(sockets)d:%(cores)d:%(threads)d excede o " +"A topologia de vCPU de imagem %(sockets)d:%(cores)d:%(threads)d excede o " "permitido %(maxsockets)d:%(maxcores)d:%(maxthreads)d" #, python-format msgid "Image's config drive option '%(config_drive)s' is invalid" -msgstr "Opção de unidade de configuração da imagem '%(config_drive)s' inválida" +msgstr "A opção de unidade configurada da imagem '%(config_drive)s' é inválida" msgid "" "Images with destination_type 'volume' need to have a non-zero size specified" @@ -2001,8 +2000,8 @@ msgstr "Formato do corpo da solicitação incorreta" #, python-format msgid "Info cache for instance %(instance_uuid)s could not be found." msgstr "" -"O cache de informações para a instância %(instance_uuid)s não pôde ser " -"localizado." +"Não foi possível localizar o cache de informações para a instância " +"%(instance_uuid)s" #, python-format msgid "" @@ -2023,11 +2022,11 @@ msgstr "A instância %(instance_id)s não pode ser resgatada: %(reason)s" #, python-format msgid "Instance %(instance_id)s could not be found." -msgstr "A instância %(instance_id)s não pôde ser localizada." +msgstr "Não foi possível localizar a instância %(instance_id)s." #, python-format msgid "Instance %(instance_id)s has no tag '%(tag)s'" -msgstr "Instância %(instance_id)s não possui identificação ‘%(tag)s‘" +msgstr "A instância %(instance_id)s não possui nenhuma identificação ‘%(tag)s‘" #, python-format msgid "Instance %(instance_id)s is not in rescue mode" @@ -2039,7 +2038,7 @@ msgstr "A instância %(instance_id)s não está pronta" #, python-format msgid "Instance %(instance_id)s is not running." -msgstr "A instância %(instance_id)s não está executando." +msgstr "A instância %(instance_id)s não está em execução." #, python-format msgid "Instance %(instance_id)s is unacceptable: %(reason)s" @@ -2059,7 +2058,7 @@ msgstr "A instância %(instance_uuid)s não possui IP fixo '%(ip)s'." #, python-format msgid "Instance %(instance_uuid)s has zero fixed IPs." -msgstr "A instância %(instance_uuid)s possui zero IPs fixos." +msgstr "A instância %(instance_uuid)s possui zero IP fixo." #, python-format msgid "" @@ -2077,7 +2076,7 @@ msgstr "A instância %(instance_uuid)s está bloqueada" msgid "" "Instance %(instance_uuid)s requires config drive, but it does not exist." msgstr "" -"A instância %(instance_uuid)s requer a unidade de configuração, mas ela não " +"A instância %(instance_uuid)s requer uma unidade configurada, mas ela não " "existe." #, python-format @@ -2119,7 +2118,7 @@ msgstr "O grupo de instância %(group_uuid)s já existe." #, python-format msgid "Instance group %(group_uuid)s could not be found." -msgstr "O grupo de instância %(group_uuid)s não pôde ser localizado." +msgstr "Não foi possível localizar o grupo de instância %(group_uuid)s" #, python-format msgid "Instance group %(group_uuid)s has no member with id %(instance_id)s." @@ -2154,7 +2153,7 @@ msgid "Instance not yet ready" msgstr "A instância ainda não está pronta" msgid "Instance recreate is not supported." -msgstr "Recriação da instância não é suportada." +msgstr "A recriação da instância não é suportada." #, python-format msgid "Instance rollback performed due to: %s" @@ -2177,12 +2176,11 @@ msgstr "Recursos de cálculo insuficientes: %(reason)s." #, python-format msgid "Insufficient free memory on compute node to start %(uuid)s." -msgstr "" -"Memória livre insuficiente no nodo de computação para iniciar %(uuid)s." +msgstr "Memória livre insuficiente no nó de cálculo para iniciar %(uuid)s." #, python-format msgid "Interface %(interface)s not found." -msgstr "Interface %(interface)s não encontrada." +msgstr "Interface %(interface)s não localizada." #, python-format msgid "Invalid Base 64 data for file %(path)s" @@ -2201,21 +2199,21 @@ msgstr "Formato de IP inválido %s" #, python-format msgid "Invalid IP protocol %(protocol)s." -msgstr "Protocolo IP %(protocol)s é inválido." +msgstr "Protocolo IP %(protocol)s inválido." #, python-format msgid "" "Invalid PCI Whitelist: The PCI address %(address)s has an invalid %(field)s." msgstr "" -"Lista de desbloqueio de PCI inválido: O endereço PCI %(address)s possui um " -"inválido %(field)s." +"Lista de desbloqueio de PCI inválida: o endereço PCI %(address)s tem um " +"%(field)s inválido." msgid "" "Invalid PCI Whitelist: The PCI whitelist can specify devname or address, but " "not both" msgstr "" -"Lista de desbloqueio de PCI inválida: A lista de desbloqueio de PCI pode " -"especificar o devname ou endereço , mas não ambos" +"Lista de desbloqueio de PCI inválida: a lista de desbloqueio de PCI pode " +"especificar o nome do dispositivo ou endereço , mas não ambos" #, python-format msgid "Invalid PCI alias definition: %(reason)s" @@ -2268,7 +2266,7 @@ msgstr "Tipo de console inválido %(console_type)s" #, python-format msgid "Invalid content type %(content_type)s." -msgstr "Tipo de conteúdo %(content_type)s é inválido." +msgstr "Tipo de conteúdo %(content_type)s inválido." #, python-format msgid "Invalid datetime string: %(reason)s" @@ -2425,7 +2423,7 @@ msgstr "políticas inválidas: %s" #, python-format msgid "Invalid port range %(from_port)s:%(to_port)s. %(msg)s" -msgstr "Sequencia de porta %(from_port)s:%(to_port)s é inválida. %(msg)s" +msgstr "Intervalo de portas inválido %(from_port)s:%(to_port)s. %(msg)s" #, python-format msgid "Invalid port value: %s. It should be an integer" @@ -2466,7 +2464,7 @@ msgstr "Catálogo de serviço json inválido." #, python-format msgid "Invalid signature hash method: %s" -msgstr "Método de hash de assinatura inválido: %s" +msgstr "Método hash de assinatura inválido: %s" #, python-format msgid "Invalid signature key type: %s" @@ -2517,7 +2515,7 @@ msgstr "Valor inválido '%s' para força." #, python-format msgid "Invalid value for Config Drive option: %(option)s" -msgstr "Valor inválido para a opção Configuração de Unidade: %(option)s" +msgstr "Valor inválido para a opção Configurar Unidade: %(option)s" #, python-format msgid "" @@ -2609,7 +2607,7 @@ msgstr "Par de chaves %(name)s não localizado para o usuário %(user_id)s" #, python-format msgid "Keypair data is invalid: %(reason)s" -msgstr "Dados do par de chaves é inválido: %(reason)s" +msgstr "Os dados do par de chaves são inválidos: %(reason)s" msgid "Keypair name contains unsafe characters" msgstr "O nome do par de chaves contém caracteres não seguros" @@ -2646,7 +2644,7 @@ msgstr "Linha %(linenum)d : %(line)s" #, python-format msgid "Link Local address is not found.:%s" -msgstr "Endereço para Link Local não encontrado: %s" +msgstr "Endereço para Link Local não localizado: %s" msgid "" "List of file systems that are configured in this file in the image_file_url:" @@ -2685,15 +2683,15 @@ msgid "" "unless libvirt instance path and drive data is shared across compute nodes." msgstr "" "A migração em tempo real de instâncias com unidades de configuração não é " -"suportada no libvirt, a menos que o caminho da instância e dados da unidade " -"sejam compartilhados entre nós de cálculo." +"suportada no libvirt, a menos que o caminho e os dados da unidade da " +"instância libvirt sejam compartilhados entre nós de cálculo." msgid "" "Live migration with API v2.25 requires all the Mitaka upgrade to be complete " "before it is available." msgstr "" -"A migração em tempo real com a API v2.25 requer que todo o upgrade Mitaka " -"seja concluído antes que esteja disponível. " +"Para ser disponibilizada, a migração em tempo real com a API v2.25 exige que " +"todo o upgrade Mitaka esteja concluído." msgid "Malformed createBackup entity" msgstr "Entidade createBackup malformada" @@ -2707,11 +2705,11 @@ msgid "" "Malformed request URL: URL's project_id '%(project_id)s' doesn't match " "Context's project_id '%(context_project_id)s'" msgstr "" -"URL de solicitação Malformada: project_id '%(project_id)s' da URL não " +"URL de solicitação malformada: project_id '%(project_id)s' da URL não " "corresponde ao project_id '%(context_project_id)s' do contexto" msgid "Malformed request body" -msgstr "Corpo do pedido está mal formado" +msgstr "O corpo do pedido está malformado" msgid "Malformed request body. meta item must be object" msgstr "" @@ -2728,7 +2726,7 @@ msgstr "Mapeamento de imagem para local não é suportado." #, python-format msgid "Marker %(marker)s could not be found." -msgstr "O marcador %(marker)s não pôde ser localizado." +msgstr "Não foi possível localizar o marcador %(marker)s." msgid "Maximum allowed length for 'label' is 255." msgstr "O comprimento máximo permitido para 'label' é 255." @@ -2769,8 +2767,8 @@ msgid "" "Metric %(name)s could not be found on the compute host node %(host)s." "%(node)s." msgstr "" -"Métrica %(name)s não pôde ser localizada no nó de host de cálculo %(host)s." -"%(node)s." +"Não foi possível localizar a métrica %(name)s no nó de host de cálculo " +"%(host)s.%(node)s." msgid "Migrate Receive failed" msgstr "Falha em Migrar Recebimento" @@ -2791,7 +2789,7 @@ msgstr "A migração %(migration_id)s não pôde ser localizada." #, python-format msgid "Migration %(migration_id)s not found for instance %(instance_id)s" msgstr "" -"Migração %(migration_id)s não localizada para a instância %(instance_id)s" +"Migração %(migration_id)s não localizada para a instância %(instance_id)s" #, python-format msgid "" @@ -2799,8 +2797,8 @@ msgid "" "Cannot %(method)s while the migration is in this state." msgstr "" "O estado da migração %(migration_id)s da instância %(instance_uuid)s é " -"%(state)s. O método %(method)s não é possível enquanto a migração estiver " -"nesse estado." +"%(state)s. Não será possível %(method)s enquanto a migração estiver nesse " +"estado." #, python-format msgid "Migration error: %(reason)s" @@ -2813,7 +2811,7 @@ msgstr "A migração não é suportada para instâncias do LVM de backup" msgid "" "Migration not found for instance %(instance_id)s with status %(status)s." msgstr "" -"Migração não localizada para a instância %(instance_id)s com o status " +"Migração não localizada para a instância %(instance_id)s com status " "%(status)s." #, python-format @@ -2883,8 +2881,8 @@ msgid "" "More than one possible network found. Specify network ID(s) to select which " "one(s) to connect to." msgstr "" -"Mais de uma rede possível localizada. Especifique ID(s) de rede para " -"selecionar qual(is) a se conectar." +"Mais de uma rede possível localizada. Especifique o(s) ID(s) da(s) rede(s) " +"que deseja conectar." msgid "More than one swap drive requested." msgstr "Mais de uma unidade de troca solicitada." @@ -2894,7 +2892,7 @@ msgid "Multi-boot operating system found in %s" msgstr "Sistema operacional de multi-inicialização localizado em %s" msgid "Multiple X-Instance-ID headers found within request." -msgstr "Vários cabeçalhos X-Instance-ID localizados dentro da solicitação." +msgstr "Vários cabeçalhos X-Instance-ID localizados na solicitação." msgid "Multiple X-Tenant-ID headers found within request." msgstr "Vários cabeçalhos X-Tenant-ID localizados dentro da solicitação." @@ -2932,10 +2930,10 @@ msgid "Must input network_id when request IP address" msgstr "network_id deve ser inserido quando o endereço IP for solicitado" msgid "Must not input both network_id and port_id" -msgstr "Ambos network_id e port_id não devem ser inseridos" +msgstr "network_id e port_id não podem ser inseridos juntos" msgid "Must specify an ExtensionManager class" -msgstr "Deve especificar uma classe ExtensionManager" +msgstr "É necessário especificar uma classe ExtensionManager" msgid "" "Must specify connection_url, connection_username (optionally), and " @@ -2966,7 +2964,7 @@ msgstr "A rede \"%(val)s\" não é válida no campo %(attr)s" #, python-format msgid "Network %(network_id)s could not be found." -msgstr "Rede %(network_id)s não foi encontrada." +msgstr "A rede %(network_id)s não foi localizada." #, python-format msgid "Network %(network_id)s is duplicated." @@ -2984,33 +2982,33 @@ msgstr "" #, python-format msgid "Network adapter %(adapter)s could not be found." -msgstr "O adaptador de rede %(adapter)s não pôde ser localizado." +msgstr "Não foi possível localizar o adaptador de rede %(adapter)s." msgid "Network cidr or cidr_v6 is required" msgstr "O cidr ou cidr_v6 da rede é necessário" #, python-format msgid "Network could not be found for bridge %(bridge)s" -msgstr "A rede não pôde ser localizada para a ponte %(bridge)s" +msgstr "Não foi possível localizar uma rede para a ponte %(bridge)s" #, python-format msgid "Network could not be found for instance %(instance_id)s." -msgstr "A rede não pôde ser localizada para a instância %(instance_id)s." +msgstr "Não foi possível localizar uma rede para a instância %(instance_id)s." #, python-format msgid "Network could not be found for uuid %(uuid)s" -msgstr "A rede não pôde ser localizada para uuid %(uuid)s" +msgstr "Não foi possível localizar uma rede para uuid %(uuid)s" #, python-format msgid "Network could not be found with cidr %(cidr)s." -msgstr "A rede não pôde ser localizada com cidr %(cidr)s." +msgstr "Não foi possível localizar uma rede com cidr %(cidr)s." msgid "Network driver does not support this function." msgstr "O driver de rede não suporta essa função." #, python-format msgid "Network host %(host)s has zero fixed IPs in network %(network_id)s." -msgstr "O host da rede %(host)s possui zero IPs fixos na rede %(network_id)s." +msgstr "O host da rede %(host)s possui zero IP fixo na rede %(network_id)s." msgid "Network label is required" msgstr "O rótulo da rede é necessário" @@ -3020,7 +3018,7 @@ msgid "" "Network must be disassociated from project %(project_id)s before it can be " "deleted." msgstr "" -"A rede deve ser desassociada do projeto %(project_id)s antes de poder ser " +"A rede deve ser desassociada do projeto %(project_id)s para que possa ser " "excluída." msgid "Network not found" @@ -3035,7 +3033,7 @@ msgstr "" #, python-format msgid "Network set host failed for network %(network_id)s." -msgstr "O host configurado de rede falhou para a rede %(network_id)s." +msgstr "Falha no host configurado em rede para a rede %(network_id)s." msgid "Network to push into openvpn config" msgstr "Rede para enviar por push na configuração de openvpn" @@ -3071,7 +3069,7 @@ msgstr "Nenhum adminPass foi especificado" #, python-format msgid "No agent-build associated with id %(id)s." -msgstr "Nenhuma criação de agente associada ao id %(id)s." +msgstr "Nenhuma construção de agente associada ao id %(id)s." msgid "No cell given in routing path." msgstr "Nenhuma célula especificada no caminho de roteamento." @@ -3083,7 +3081,8 @@ msgid "No cell name in request" msgstr "Nenhum nome da célula na solicitação" msgid "No cells available matching scheduling criteria." -msgstr "Nenhum célula disponível correspondente aos critérios de planejamento." +msgstr "" +"Nenhuma célula disponível correspondente aos critérios de planejamento." msgid "No compute host specified" msgstr "Nenhum host de cálculo especificado" @@ -3111,7 +3110,7 @@ msgstr "Sem erros nos arquivos de log!" #, python-format msgid "No fixed IP addresses available for network: %(net)s" -msgstr "Nenhum endereço IP fixo disponível para rede: %(net)s" +msgstr "Nenhum endereço IP fixo disponível para a rede: %(net)s" #, python-format msgid "No fixed IP associated with id %(id)s." @@ -3135,7 +3134,7 @@ msgstr "Nenhum dispositivo nbd livre" #, python-format msgid "No free port available for instance %(instance)s." -msgstr "Nenhuma porta disponível para a instância %(instance)s." +msgstr "Nenhuma porta livre disponível para a instância %(instance)s." msgid "No host available on cluster" msgstr "Nenhum host disponível no cluster" @@ -3159,7 +3158,7 @@ msgid "" "\" hypervisor virtualization type." msgstr "" "Nenhum URI de migração em tempo real configurado e nenhum padrão disponível " -"para o tipo de virtualização do hypervisor \"%(virt_type)s\"." +"para o tipo de virtualização \"%(virt_type)s\" do hypervisor." #, python-format msgid "No matching ID for the URL %s was found." @@ -3229,16 +3228,16 @@ msgstr "Nenhum host válido localizado. %(reason)s" #, python-format msgid "No volume Block Device Mapping at path: %(path)s" msgstr "" -"Nenhum Mapeamento do Dispositivo de Bloco do volume no caminho: %(path)s" +"Nenhum Mapeamento do Dispositivo de Bloco de volume no caminho: %(path)s" #, python-format msgid "No volume Block Device Mapping with id %(volume_id)s." msgstr "" -"Nenhum Mapeamento de Dispositivo de Bloco do volume com o ID %(volume_id)s." +"Nenhum Mapeamento de Dispositivo de Bloco de volume com ID %(volume_id)s." #, python-format msgid "Node %s could not be found." -msgstr "O nó %s não pôde ser localizado." +msgstr "Não foi possível localizar o nó %s." #, python-format msgid "Not able to acquire a free port for %(host)s" @@ -3246,13 +3245,13 @@ msgstr "Não é possível adquirir uma porta livre para %(host)s" #, python-format msgid "Not able to bind %(host)s:%(port)d, %(error)s" -msgstr "Não é possível ligar %(host)s:%(port)d, %(error)s" +msgstr "Não é possível vincular %(host)s:%(port)d, %(error)s" #, python-format msgid "" "Not all Virtual Functions of PF %(compute_node_id)s:%(address)s are free." msgstr "" -"Nem todas as Funções Virtuais do %(compute_node_id)s:%(address)s estão " +"Nem todas as Funções Virtuais da FF %(compute_node_id)s:%(address)s estão " "livres." msgid "Not an rbd snapshot" @@ -3303,11 +3302,11 @@ msgstr "" #, python-format msgid "OVS configuration failed with: %(inner_exception)s." -msgstr "A configuração do OVS falhou com: %(inner_exception)s." +msgstr "Falha na configuração do OVS com: %(inner_exception)s." #, python-format msgid "Object action %(action)s failed because: %(reason)s" -msgstr "A ação do objeto %(action)s falhou porque: %(reason)s" +msgstr "Falha na ação do objeto %(action)s porque: %(reason)s" msgid "Old volume is attached to a different instance." msgstr "Um volume antigo está anexado a uma instância diferente." @@ -3324,6 +3323,10 @@ msgstr "" "Apenas %(value)s %(verb)s solicitação(ões) pode(m) ser feita(s) para %(uri)s " "a cada %(unit_string)s." +#, python-format +msgid "Only %d SCSI controllers are allowed to be created on this instance." +msgstr "Somente controladoras SCSI %d podem ser criadas nesta instância." + msgid "Only 'updated_since', 'project_id' and 'deleted' are understood." msgstr "Apenas 'updated_since', 'project_id' e 'deleted' são compreendidos." @@ -3378,7 +3381,7 @@ msgid "" "PCI device %(compute_node_id)s:%(address)s is owned by %(owner)s instead of " "%(hopeowner)s" msgstr "" -"Dispositivo PCI %(compute_node_id)s:%(address)s pertence a %(owner)s ao " +"O dispositivo PCI %(compute_node_id)s:%(address)s pertence a %(owner)s ao " "invés de %(hopeowner)s" #, python-format @@ -3387,7 +3390,7 @@ msgstr "Dispositivo PCI %(id)s não localizado" #, python-format msgid "PCI device request %(requests)s failed" -msgstr "A solicitação de dispositivo PCI %(requests)s falhou" +msgstr "Falha na solicitação do dispositivo PCI %(requests)s" #, python-format msgid "" @@ -3415,11 +3418,11 @@ msgstr "PROJETO" #, python-format msgid "Page size %(pagesize)s forbidden against '%(against)s'" -msgstr "Tamanho da página %(pagesize)s proibido contra '%(against)s'" +msgstr "Tamanho de página %(pagesize)s proibido contra '%(against)s'" #, python-format msgid "Page size %(pagesize)s is not supported by the host." -msgstr "Tamanho da página %(pagesize)s não é suportado pelo host." +msgstr "O tamanho de página %(pagesize)s não é suportado pelo host." #, python-format msgid "" @@ -3427,9 +3430,9 @@ msgid "" "Check your Neutron configuration to validate that the macvtap parameters are " "correct." msgstr "" -"Parâmetros %(missing_params)s não presentes em vif_details para vif " -"%(vif_id)s. Verifique a configuração do Neutron para validar se os " -"parâmetros macvtap estão corretos." +"Parâmetros %(missing_params)s ausentes em vif_details para vif %(vif_id)s. " +"Verifique a configuração do Neutron para validar se os parâmetros macvtap " +"estão corretos." #, python-format msgid "Path %s must be LVM logical volume" @@ -3446,10 +3449,10 @@ msgid "Personality content for %s cannot be decoded" msgstr "O conteúdo do personalidade para %s não pode ser decodificado" msgid "Personality file content too long" -msgstr "Conteúdo de arquivo de personalidade muito longo" +msgstr "Conteúdo de arquivo de personalidade muito grande" msgid "Personality file limit exceeded" -msgstr "Limite excedido do arquivo de personalidade" +msgstr "Limite do arquivo de personalidade excedido" msgid "Personality file path too long" msgstr "Caminho de arquivo de personalidade muito longo" @@ -3459,7 +3462,7 @@ msgid "" "Physical Function %(compute_node_id)s:%(address)s, related to VF " "%(compute_node_id)s:%(vf_address)s is %(status)s instead of %(hopestatus)s" msgstr "" -"A Função Física %(compute_node_id)s:%(address)s relacionada ao VF " +"A Função Física %(compute_node_id)s:%(address)s relacionada à FV " "%(compute_node_id)s:%(vf_address)s é %(status)s em vez de %(hopestatus)s" #, python-format @@ -3483,7 +3486,7 @@ msgstr "" #, python-format msgid "Policy doesn't allow %(action)s to be performed." -msgstr "A política não permite que %(action)s sejam executadas." +msgstr "A política não permite a execução de %(action)s." #, python-format msgid "Port %(port_id)s is still in use." @@ -3505,7 +3508,7 @@ msgstr "" #, python-format msgid "Port %(port_id)s requires a FixedIP in order to be used." -msgstr "A porta %(port_id)s requer um FixedIP para ser usado." +msgstr "A porta %(port_id)s requer um FixedIP para ser usada." #, python-format msgid "Port %s is not attached" @@ -3513,33 +3516,33 @@ msgstr "Porta %s não está conectada" #, python-format msgid "Port id %(port_id)s could not be found." -msgstr "O ID da porta %(port_id)s não pôde ser localizado." +msgstr "O ID da porta %(port_id)s não foi localizado." #, python-format msgid "Project %(project_id)s could not be found." -msgstr "Projeto %(project_id)s não foi encontrado." +msgstr "O projeto %(project_id)s não foi encontrado." #, python-format msgid "Provided video model (%(model)s) is not supported." -msgstr "Modelo de vídeo fornecido (%(model)s) não é suportado." +msgstr "O modelo de vídeo fornecido (%(model)s) não é suportado." #, python-format msgid "Provided watchdog action (%(action)s) is not supported." -msgstr "Ação de watchdog fornecida (%(action)s) não é suportada." +msgstr "A ação de watchdog fornecida (%(action)s) não é suportada." msgid "QEMU guest agent is not enabled" msgstr "O agente convidado QEMU não está ativado" #, python-format msgid "Quiescing is not supported in instance %(instance_id)s" -msgstr "Quiesce não é suportado na instância %(instance_id)s" +msgstr "Quiescing não suportado na instância %(instance_id)s" msgid "Quota" msgstr "Quota" #, python-format msgid "Quota class %(class_name)s could not be found." -msgstr "A classe da cota %(class_name)s não pôde ser localizada." +msgstr "Não foi possível localizar a classe da cota %(class_name)s." msgid "Quota could not be found" msgstr "A cota não pôde ser localizada" @@ -3549,7 +3552,7 @@ msgid "" "Quota exceeded for %(overs)s: Requested %(req)s, but already used %(used)s " "of %(allowed)s %(overs)s" msgstr "" -"Cota excedida para %(overs)s: Solicitados %(req)s, mas já usados %(used)s " +"Cota excedida para %(overs)s: %(req)s solicitados, mas %(used)s já usados de " "%(allowed)s %(overs)s" #, python-format @@ -3576,7 +3579,7 @@ msgstr "Cota excedida, servidores em excesso no grupo" #, python-format msgid "Quota exceeded: code=%(code)s" -msgstr "Quota excedida: codigo=%(code)s" +msgstr "Cota excedida: código = %(code)s" #, python-format msgid "Quota exists for project %(project_id)s, resource %(resource)s" @@ -3584,14 +3587,14 @@ msgstr "Existe cota para o projeto %(project_id)s, recurso %(resource)s" #, python-format msgid "Quota for project %(project_id)s could not be found." -msgstr "A cota para o projeto %(project_id)s não pôde ser localizada." +msgstr "Não foi possível localizar a cota para o projeto %(project_id)s." #, python-format msgid "" "Quota for user %(user_id)s in project %(project_id)s could not be found." msgstr "" -"Cota para o usuário %(user_id)s no projeto %(project_id)s não pôde ser " -"encontrada." +"Não foi possível localizar a cota para o usuário %(user_id)s no projeto " +"%(project_id)s." #, python-format msgid "Quota limit %(limit)s for %(resource)s must be -1 or greater." @@ -3634,11 +3637,12 @@ msgstr "O limite de cota deve ser menor que %s." #, python-format msgid "Quota reservation %(uuid)s could not be found." -msgstr "A reserva da cota %(uuid)s não pôde ser localizada." +msgstr "Não foi possível localizar a reserva da cota %(uuid)s." #, python-format msgid "Quota usage for project %(project_id)s could not be found." -msgstr "O uso da cota para o projeto %(project_id)s não pôde ser localizado." +msgstr "" +"Não foi possível localizar o uso da cota para o projeto %(project_id)s." #, python-format msgid "Reached maximum number of retries trying to unplug VBD %s" @@ -3666,7 +3670,7 @@ msgstr "" "volume voltado para o armazenamento de arquivo/rede." msgid "Request body and URI mismatch" -msgstr "Corpo do pedido e incompatibilidade URI" +msgstr "Incompatibilidade entre o corpo do pedido e o URI" msgid "Request body contains too many items" msgstr "Corpo da solicitação contém muitos intens" @@ -3677,13 +3681,12 @@ msgstr "A solicitação é muito grande." msgid "" "Request must include either Timestamp or Expires, but cannot contain both" msgstr "" -"A solicitação deve incluir Registro de Data e Hora ou Expira, mas não pode " -"conter ambos" +"A solicitação deve incluir Timestamp ou Expires, mas não pode conter ambos" #, python-format msgid "Request of image %(image_id)s got BadRequest response: %(response)s" msgstr "" -"A solicitação da imagem %(image_id)s obteve a resposta BadRequest: " +"A solicitação da imagem %(image_id)s obteve uma resposta BadRequest: " "%(response)s" #, python-format @@ -3691,22 +3694,23 @@ msgid "RequestSpec not found for instance %(instance_uuid)s" msgstr "RequestSpec não localizado para a instância %(instance_uuid)s" msgid "Requested CPU control policy not supported by host" -msgstr "Política de controle de CPU solicitada não suportada pelo host. " +msgstr "A política de controle de CPU solicitada não suportada pelo host. " #, python-format msgid "Requested cidr (%(cidr)s) conflicts with existing cidr (%(other)s)" -msgstr "Conflitos cidr (%(cidr)s) solicitador com cidr existente. %(other)s)" +msgstr "Conflito do cidr (%(cidr)s) solicitado com cidr existente. %(other)s)" #, python-format msgid "" "Requested hardware '%(model)s' is not supported by the '%(virt)s' virt driver" msgstr "" -"O hardware solicitado '%(model)s' não é suportado pelo driver virt '%(virt)s'" +"O hardware solicitado '%(model)s' não é suportado pela unidade virt " +"'%(virt)s'" #, python-format msgid "Requested image %(image)s has automatic disk resize disabled." msgstr "" -"A imagem solicitada %(image)s possui o redimensionamento automático de disco " +"A imagem solicitada %(image)s possui redimensionamento automático de disco " "desativado." msgid "" @@ -3730,16 +3734,16 @@ msgid "" "Requested vCPU limits %(sockets)d:%(cores)d:%(threads)d are impossible to " "satisfy for vcpus count %(vcpus)d" msgstr "" -"Os limites de vCPU solicitados %(sockets)d:%(cores)d:%(threads)d são " -"impossíveis de satisfazer para contagens de vcpus %(vcpus)d" +"Não é possível satisfazer os limites de vCPU solicitados %(sockets)d:" +"%(cores)d:%(threads)d para a contagem de vcpus %(vcpus)d" #, python-format msgid "" "Required image properties for signature verification do not exist. Cannot " "verify signature. Missing property: %s" msgstr "" -"As propriedades de imagem necessárias para a verificação de assinatura não " -"existem. Não é possível verificar a assinatura. Propriedade ausente: %s" +"Não existem propriedades de imagem necessárias para verificação da " +"assinatura. Não é possível verificar a assinatura. Propriedade ausente: %s" #, python-format msgid "Rescue device does not exist for instance %s" @@ -3804,12 +3808,12 @@ msgstr "Executando lotes de %i até a conclusão" #, python-format msgid "Running cmd (subprocess): %s" -msgstr "Executando comando (subprocesso): %s" +msgstr "Executando cmd (subprocesso): %s" #, python-format msgid "Scheduler Host Filter %(filter_name)s could not be found." msgstr "" -"O Filtro do Host do Planejador %(filter_name)s não pôde ser localizado." +"Não foi possível localizar o Filtro do Host do Planejador %(filter_name)s." #, python-format msgid "" @@ -3923,7 +3927,7 @@ msgstr "Servidor não localizado" #, python-format msgid "ServerGroup policy is not supported: %(reason)s" -msgstr "Política do ServerGroup não é suportada: %(reason)s" +msgstr "A política de ServerGroup não é suportada: %(reason)s" msgid "ServerGroupAffinityFilter not configured" msgstr "ServerGroupAffinityFilter não configurado" @@ -3947,7 +3951,7 @@ msgstr "Serviço %(service)s no host %(host)s ativado." #, python-format msgid "Service %(service_id)s could not be found." -msgstr "Serviço %(service_id)s não encontrado." +msgstr "Serviço %(service_id)s não localizado." #, python-format msgid "Service %s not found." @@ -3955,21 +3959,21 @@ msgstr "Serviço %s não localizado." #, python-format msgid "Service API method not found: %(detail)s" -msgstr "Método de API do serviço não localizado: %(detail)s" +msgstr "Método de API de serviço não localizado: %(detail)s" msgid "Service is unavailable at this time." -msgstr "Serviço está indisponível neste momento" +msgstr "Serviço indisponível neste momento." #, python-format msgid "Service with host %(host)s binary %(binary)s exists." -msgstr "O serviço com host %(host)s binário %(binary)s existe." +msgstr "O serviço com host %(host)s binário %(binary)s já existe." #, python-format msgid "Service with host %(host)s topic %(topic)s exists." -msgstr "O serviço com host %(host)s tópico %(topic)s existe." +msgstr "O serviço com host %(host)s tópico %(topic)s já existe." msgid "Set admin password is not supported" -msgstr "Definir senha admin não é suportado" +msgstr "A definição de senha de administrador não é suportada" #, python-format msgid "Shadow table with name %(name)s already exists." @@ -3996,7 +4000,7 @@ msgstr "" #, python-format msgid "Signature verification for the image failed: %(reason)s." -msgstr "A verificação de assinatura falhou para a imagem: %(reason)s." +msgstr "Falha na verificação de assinatura para a imagem: %(reason)s." #, python-format msgid "Snapshot %(snapshot_id)s could not be found." @@ -4079,7 +4083,8 @@ msgid "Suspended" msgstr "Suspenso" msgid "Swap drive requested is larger than instance type allows." -msgstr "Drive de swap é maior do que o tipo de instância permite." +msgstr "" +"A unidade de swap requisitada é maior que o permitido pelo tipo de instância." msgid "Swap only supports host devices" msgstr "A troca suporta apenas dispositivos de host" @@ -4100,11 +4105,11 @@ msgstr "Modelo para o script de inicialização da instância cloudpipe" #, python-format msgid "The CA file for %(project)s could not be found" -msgstr "O arquivo CA de %(project)s não pôde ser localizado" +msgstr "Não foi possível localizar o arquivo CA de %(project)s" #, python-format msgid "The CRL file for %(project)s could not be found" -msgstr "O arquivo CRL para %(project)s não pôde ser localizado" +msgstr "Não foi possível localizar o arquivo CRL para %(project)s" #, python-format msgid "The DNS entry %(name)s already exists in domain %(domain)s." @@ -4128,7 +4133,7 @@ msgstr "" "executar este comando." msgid "The backlog must be more than 0" -msgstr "O backlog deve ser maior que 0" +msgstr "A lista não processada deve ser maior que 0" #, python-format msgid "The console port range %(min_port)d-%(max_port)d is exhausted." @@ -4139,7 +4144,7 @@ msgid "The created instance's disk would be too small." msgstr "O disco da instância criada seria muito pequeno." msgid "The current driver does not support preserving ephemeral partitions." -msgstr "O driver atual não suporta a preservação partições temporárias." +msgstr "A unidade atual não suporta a preservação de partições efêmeras." msgid "The default PBM policy doesn't exist on the backend." msgstr "A política de PBM padrão não existe no backend." @@ -4149,7 +4154,7 @@ msgid "The firewall filter for %s does not exist" msgstr "O filtro de firewall para %s não existe" msgid "The floating IP request failed with a BadRequest" -msgstr "A solicitação de IP flutuante falhou com um BadRequest" +msgstr "Falha na solicitação de IP flutuante com um BadRequest" #, python-format msgid "The group %(group_name)s must be configured with an id." @@ -4161,7 +4166,7 @@ msgstr "A entrada não é uma sequência ou unicode" msgid "" "The instance requires a newer hypervisor version than has been provided." msgstr "" -"A instância requer uma versão de hypervisor mais recente do que a fornecida." +"A instância requer uma versão de hypervisor mais recente que a fornecida." #, python-format msgid "" @@ -4230,7 +4235,7 @@ msgid "The request body can't be empty" msgstr "O corpo da solicitação não pode estar vazio" msgid "The request is invalid." -msgstr "A requisição é inválida." +msgstr "A solicitação é inválida." #, python-format msgid "" @@ -4238,7 +4243,7 @@ msgid "" "allowed by flavor %(max_vram)d." msgstr "" "A quantidade solicitada de memória de vídeo %(req_vram)d é maior que o " -"máximo permitido pelo tipo %(max_vram)d." +"máximo permitido pela espécie %(max_vram)d." msgid "The requested availability zone is not available" msgstr "A zona de disponibilidade solicitada não está disponível" @@ -4360,7 +4365,7 @@ msgstr "Essa ação não existe: %s" #, python-format msgid "There was an error with the download module %(module)s. %(reason)s" -msgstr "Houve um erro com o módulo de download %(module)s. %(reason)s" +msgstr "Houve um erro no módulo de download %(module)s. %(reason)s" msgid "There were no records found where instance_uuid was NULL." msgstr "Não houve registros localizados em que instance_uuid era NULO." @@ -4413,7 +4418,7 @@ msgid "Timeout waiting for device %s to be created" msgstr "Tempo limite de espera para que o dispositivo %s seja criado" msgid "Timeout waiting for response from cell" -msgstr "Aguardando tempo limite para a resposta da célula" +msgstr "Aguardando tempo limite para resposta da célula" #, python-format msgid "Timeout while checking if we can live migrate to host: %s" @@ -4435,13 +4440,13 @@ msgstr "" "Muitos endereços IP serão gerados. Aumente /%s para reduzir o número gerado." msgid "Triggering crash dump is not supported" -msgstr "O acionamento de dump de travamento não é suportado." +msgstr "O acionamento de dump de memória não é suportado." msgid "Type and Code must be integers for ICMP protocol type" msgstr "Tipo e Código devem ser números inteiros para o tipo de protocolo ICMP" msgid "UEFI is not supported" -msgstr "UEFI não é suportado" +msgstr "UEFI não suportado" msgid "UUID is required to delete Neutron Networks" msgstr "UUID é requerido para excluir Redes Neutron" @@ -4470,8 +4475,8 @@ msgid "" "Unable to claim IP for VPN instances, ensure it isn't running, and try again " "in a few minutes" msgstr "" -"Não é possível solicitar IP para instâncias VPN; assegure-se de que ele não " -"esteja em execução e tente novamente em alguns minutos" +"Não é possível solicitar IP para instâncias VPN; assegure ela não esteja em " +"execução e tente novamente em alguns minutos" #, python-format msgid "Unable to contact guest agent. The following call timed out: %(method)s" @@ -4497,7 +4502,7 @@ msgid "Unable to create dns entry" msgstr "Não é possível criar a entrada dns" msgid "Unable to create flavor" -msgstr "Não é possível criar tipo" +msgstr "Não é possível criar espécie" msgid "Unable to delete dns domain" msgstr "Não é possível excluir o domínio dns" @@ -4720,9 +4725,9 @@ msgid "" "Undefined Block Device Mapping root: BlockDeviceMappingList contains Block " "Device Mappings from multiple instances." msgstr "" -"Raiz do Mapeamento de Dispositivo de Bloco indefinido: " -"BlockDeviceMappingList contém os Mapeamentos de Dispositivo de Bloco a " -"partir de diversas instâncias." +"Raiz de Mapeamento de Dispositivo de Bloco indefinida: " +"BlockDeviceMappingList contém Mapeamentos de Dispositivo de Bloco de várias " +"instâncias." #, python-format msgid "" @@ -4730,8 +4735,8 @@ msgid "" "and attach the Nova API log if possible.\n" "%s" msgstr "" -"Erro inesperado da API. Relate isso em http://bugs.launchpad.net/nova/ e " -"anexe o log da API Nova se possível.\n" +"Erro inesperado na API. Relate esse erro em http://bugs.launchpad.net/nova/ " +"e anexe o log da API Nova, se possível.\n" "%s" #, python-format @@ -4776,8 +4781,8 @@ msgstr "Cadeia desconhecida: %r" #, python-format msgid "Unknown config drive format %(format)s. Select one of iso9660 or vfat." msgstr "" -"Formato da unidade de configuração %(format)s desconhecido. Selecione um de " -"iso9660 ou vfat." +"Formato da unidade configurada %(format)s desconhecido. Selecione iso9660 ou " +"vfat." #, python-format msgid "Unknown delete_info type %s" @@ -4801,7 +4806,7 @@ msgstr "" #, python-format msgid "Unknown quota resources %(unknown)s." -msgstr "Recursos da cota desconhecidos %(unknown)s." +msgstr "Recursos de cota desconhecidos %(unknown)s." msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "Direção de classificação desconhecida; deve ser 'desc' ou 'asc'" @@ -4847,19 +4852,19 @@ msgid "User %(username)s not found in shadow file." msgstr "Usuário %(username)s não localizado no arquivo de sombra." msgid "User data needs to be valid base 64." -msgstr "Os dados do usuário devem ser base 64 válidos." +msgstr "Os dados do usuário devem ser base64 válido." #, python-format msgid "" "User data too large. User data must be no larger than %(maxsize)s bytes once " "base64 encoded. Your data is %(length)d bytes" msgstr "" -"Dados do usuário muito grandes. Os dados do usuário não devem ser superiores " -"a %(maxsize)s bytes quando codificados por base64. Seus dados têm %(length)d " -"bytes" +"O volume de dados do usuário é muito grande. Os dados do usuário não devem " +"ser superiores a %(maxsize)s bytes quando codificados por base64. Seus dados " +"têm %(length)d bytes" msgid "User does not have admin privileges" -msgstr "Usuário não tem privilégios de administrador" +msgstr "O uUsuário não tem privilégios de administrador" msgid "User is not authorized to use key manager." msgstr "O usuário não está autorizado a usar o gerenciador de chaves." @@ -4911,7 +4916,7 @@ msgid "" "VLAN tag is not appropriate for the port group %(bridge)s. Expected VLAN tag " "is %(tag)s, but the one associated with the port group is %(pgroup)s." msgstr "" -"A tag de VLAN não é apropriada para o grupo da porta %(bridge)s. A tag de " +"A tag de VLAN não é apropriada para o grupo de portas %(bridge)s. A tag de " "VLAN esperada é %(tag)s, mas a associada ao grupo da porta é %(pgroup)s." #, python-format @@ -4934,7 +4939,7 @@ msgid "" "Version %(req_ver)s is not supported by the API. Minimum is %(min_ver)s and " "maximum is %(max_ver)s." msgstr "" -"Versão %(req_ver)s não é suportada pela API. Mínimo é %(min_ver)s e máximo " +"A versão %(req_ver)s não é suportada pela API. Mínimo é %(min_ver)s e máximo " "é %(max_ver)s." msgid "Virt driver does not implement host disabled status." @@ -4953,11 +4958,11 @@ msgid "Virtual Interface creation failed" msgstr "Falha na criação da Interface Virtual" msgid "Virtual interface plugin failed" -msgstr "Plugin da interface virtual falhou." +msgstr "Falha no plugin da interface virtual" #, python-format msgid "Virtual machine mode '%(vmmode)s' is not recognised" -msgstr "Modo da máquina virtual '%(vmmode)s' não reconhecido" +msgstr "O modo de máquina virtual '%(vmmode)s' não é reconhecido" #, python-format msgid "Virtual machine mode '%s' is not valid" @@ -4972,7 +4977,8 @@ msgstr "" #, python-format msgid "Virtualization type '%(virt)s' is not supported by this compute driver" msgstr "" -"O tipo de virtualização '%(virt)s' não é suportado por esse driver de cálculo" +"O tipo de virtualização '%(virt)s' não é suportado por essa unidade de " +"cálculo" msgid "VlanID" msgstr "VlanID" @@ -4983,7 +4989,7 @@ msgstr "O volume %(volume_id)s não pôde ser anexado. Motivo: %(reason)s" #, python-format msgid "Volume %(volume_id)s could not be found." -msgstr "Volume %(volume_id)s não pode ser encontrado." +msgstr "O volume %(volume_id)s não pôde ser encontrado." #, python-format msgid "" @@ -4991,13 +4997,12 @@ msgid "" "%(seconds)s seconds or %(attempts)s attempts. And its status is " "%(volume_status)s." msgstr "" -"Volume %(volume_id)s acabou não sendo criado mesmo depois de esperarmos " -"%(seconds)s segundos ou %(attempts)s tentativas. E seu estado é " -"%(volume_status)s." +"O volume %(volume_id)s não foi criado mesmo depois de %(seconds)s segundos " +"de espera ou %(attempts)s tentativas. Seu estado é %(volume_status)s." #, python-format msgid "Volume %(volume_id)s is not attached to anything" -msgstr "O volume %(volume_id)s não está conectado a nada" +msgstr "O volume %(volume_id)s não está conectado" msgid "Volume does not belong to the requested instance." msgstr "Volume não pertence à instância solicitada." @@ -5014,7 +5019,7 @@ msgid "" "Volume is smaller than the minimum size specified in image metadata. Volume " "size is %(volume_size)i bytes, minimum size is %(image_min_disk)i bytes." msgstr "" -"O volume é menor que o tamanho mínimo especificado nos metadados de imagem. " +"O volume é menor que o tamanho mínimo especificado nos metadados da imagem. " "O tamanho do volume é %(volume_size)i bytes; o tamanho mínimo é " "%(image_min_disk)i bytes." @@ -5022,7 +5027,7 @@ msgid "Volume must be attached in order to detach." msgstr "O volume deve estar conectado para que seja removido." msgid "Volume resource quota exceeded" -msgstr "Quota de recurso de volume excedida." +msgstr "Cota de recurso de volume excedida." #, python-format msgid "" @@ -5050,14 +5055,14 @@ msgid "" msgstr "Não suportamos esquema ‘%s' sob Python < 2.7.4, use http ou https" msgid "When resizing, instances must change flavor!" -msgstr "Ao redimensionar, as instâncias devem alterar o método!" +msgstr "Ao redimensionar, as instâncias devem alterar a espécie!" msgid "" "When running server in SSL mode, you must specify both a cert_file and " "key_file option value in your configuration file" msgstr "" -"Ao executar o servidor no modo SSL, você deve especificar os valores de " -"opção cert_file e key_file em seu arquivo de configuração" +"Ao executar o servidor no modo SSL, você deve especificar os valores das " +"opções cert_file e key_file em seu arquivo de configuração" msgid "Where we keep our keys" msgstr "Onde armazenamos nossas chaves" @@ -5067,26 +5072,27 @@ msgstr "Onde mantemos nosso CA raiz" #, python-format msgid "Wrong quota method %(method)s used on resource %(res)s" -msgstr "Método de cota errado %(method)s usado no recurso %(res)s" +msgstr "Método de cota incorreto %(method)s usado no recurso %(res)s" msgid "Wrong type of hook method. Only 'pre' and 'post' type allowed" msgstr "" -"Tipo errado de método de gancho. Somente o tipo 'pré' e ‘pós' permitido" +"Tipo incorreto de método de gancho. Somente os tipos 'pré' e ‘pós' são " +"permitidos" msgid "X-Forwarded-For is missing from request." -msgstr "X-Forwarded-For está ausente da solicitação." +msgstr "X-Forwarded-For está ausente na solicitação." msgid "X-Instance-ID header is missing from request." -msgstr "O cabeçalho X-Instance-ID está ausente da solicitação." +msgstr "O cabeçalho X-Instance-ID está ausente na solicitação." msgid "X-Instance-ID-Signature header is missing from request." -msgstr "Cabeçalho X-Instance-ID-Signature está ausente da solicitação." +msgstr "O cabeçalho X-Instance-ID-Signature está ausente na solicitação." msgid "X-Metadata-Provider is missing from request." -msgstr "X-Metadata-Provider está ausente da solicitação." +msgstr "X-Metadata-Provider está ausente na solicitação." msgid "X-Tenant-ID header is missing from request." -msgstr "Cabeçalho X-Tenant-ID está ausente da solicitação." +msgstr "O cabeçalho X-Tenant-ID está ausente na solicitação." msgid "XAPI supporting relax-xsm-sr-check=true required" msgstr "XAPI que suporte relax-xsm-sr-check=true necessário" @@ -5137,13 +5143,13 @@ msgstr "" "ou o endereço local (127.0.0.1 ou ::1)." msgid "Zero fixed IPs could be found." -msgstr "Zero IPs fixos não puderam ser localizados." +msgstr "Zero IP fixo não pôde ser localizado." msgid "Zero floating IPs available." -msgstr "Nenhum IPs flutuantes disponíveis." +msgstr "Nenhum IP flutuante disponível." msgid "Zero floating IPs exist." -msgstr "Existem zero IPs flutuantes." +msgstr "Existe zero IP flutuante." msgid "Zone" msgstr "Zona" @@ -5158,7 +5164,7 @@ msgid "accessIPv6 is not proper IPv6 format" msgstr "accessIPv6 não está no formato IPv6 adequado" msgid "admin password can't be changed on existing disk" -msgstr "senha do administrador não pode ser alterada no disco existente" +msgstr "A senha do administrador não pode ser alterada no disco existente" msgid "aggregate deleted" msgstr "agregação excluída" @@ -5578,7 +5584,7 @@ msgid "" "desired physical adapter. Expected vSwitch is %(expected)s, but the one " "associated is %(actual)s." msgstr "" -"O vSwitch que contém o grupo da porta %(bridge)s não está associado ao " +"O vSwitch que contém o grupo de portas %(bridge)s não está associado ao " "adaptador físico desejado. O vSwitch esperado é %(expected)s, mas o " "associado é %(actual)s." @@ -5594,7 +5600,7 @@ msgstr "vg %s deve estar no grupo de volumes LVM" #, python-format msgid "vhostuser_sock_path not present in vif_details for vif %(vif_id)s" -msgstr "vhostuser_sock_path ausente no vif_details para vif %(vif_id)s" +msgstr "vhostuser_sock_path ausente em vif_details para vif %(vif_id)s" #, python-format msgid "vif type %s not supported" diff --git a/nova/locale/zh_TW/LC_MESSAGES/nova.po b/nova/locale/zh_TW/LC_MESSAGES/nova.po index 693eab8d43..fc141b0430 100644 --- a/nova/locale/zh_TW/LC_MESSAGES/nova.po +++ b/nova/locale/zh_TW/LC_MESSAGES/nova.po @@ -7,19 +7,16 @@ # FIRST AUTHOR <EMAIL@ADDRESS>, 2011 # Pellaeon Lin <nfsmwlin@gmail.com>, 2013 # Pellaeon Lin <nfsmwlin@gmail.com>, 2013 -# Lucas Palm <lapalm@us.ibm.com>, 2015. #zanata -# OpenStack Infra <zanata@openstack.org>, 2015. #zanata # Jennifer <cristxu@tw.ibm.com>, 2016. #zanata -# Lucas Palm <lapalm@us.ibm.com>, 2016. #zanata msgid "" msgstr "" -"Project-Id-Version: nova 13.0.1.dev30\n" +"Project-Id-Version: nova 13.0.1.dev33\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-04-21 15:11+0000\n" +"POT-Creation-Date: 2016-04-22 16:50+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2016-04-22 03:46+0000\n" +"PO-Revision-Date: 2016-04-25 03:58+0000\n" "Last-Translator: Lucas Palm <lapalm@us.ibm.com>\n" "Language: zh-TW\n" "Plural-Forms: nplurals=1; plural=0;\n" @@ -224,7 +221,7 @@ msgid "" "agreed upon here so that the operator knowns they are dealing with the same " "file system." msgstr "" -"提供給每個檔案系統的唯一 ID。此值是在 Glance 中設定,而且在這裡達成了協定,因" +"提供給每個檔案系統的唯一 ID。此值是在 Glance 中設定,並且在這裡達成了協定,因" "此操作員知道他們正在處理同一個檔案系統。" msgid "A valid disk parameter is required" @@ -390,7 +387,7 @@ msgstr "quota_set 中的索引鍵 %s 錯誤" #, python-format msgid "Bad mac for to_global_ipv6: %s" -msgstr "to_global_ipv6 的 Mac 位址錯誤:%s" +msgstr "to_global_ipv6 的 MAC 錯誤:%s" #, python-format msgid "Bad network format: missing %s" @@ -493,7 +490,7 @@ msgid "Block Device Mapping is Invalid: failed to get volume %(id)s." msgstr "「區塊裝置對映」無效:無法取得磁區 %(id)s。" msgid "Block migration can not be used with shared storage." -msgstr "區塊移轉不能與共用儲存體配合使用。" +msgstr "區塊移轉不能與共用儲存體搭配使用。" msgid "Boot index is invalid." msgstr "啟動索引無效。" @@ -577,7 +574,7 @@ msgid "Can't resize down ephemeral disks." msgstr "無法將暫時磁碟調小。" msgid "Can't retrieve root device path from instance libvirt configuration" -msgstr "無法從實例 libVirt 配置擷取根裝置路徑" +msgstr "無法從實例 libvirt 配置擷取根裝置路徑" #, python-format msgid "" @@ -593,9 +590,8 @@ msgid "" "with the builtin SYSTEM account or other accounts unable to authenticate on " "a remote host." msgstr "" -"無法存取 \"%(instances_path)s\",請確保路徑存在,以及您具有適當的權限。特別" -"是,不得使用內建系統帳戶或其他無法在遠端主機上進行鑑別的帳戶來執行 Nova-" -"Compute。" +"無法存取 \"%(instances_path)s\",請確保路徑存在並且您具有適當的權限。特別是," +"不得使用內建系統帳戶或其他無法在遠端主機上進行鑑別的帳戶來執行 Nova-Compute。" #, python-format msgid "Cannot access 'scality_sofs_config': %s" @@ -648,7 +644,7 @@ msgid "Cannot execute /sbin/mount.sofs" msgstr "無法執行 /sbin/mount.sofs" msgid "Cannot find SR of content-type ISO" -msgstr "找不到內容類型為 ISO 的「儲存體儲存庫 (SR)」" +msgstr "找不到內容類型為 ISO 的 SR" msgid "Cannot find SR to read/write VDI." msgstr "找不到 SR 來讀/寫 VDI。" @@ -815,14 +811,14 @@ msgid "Config drive format '%(format)s' is not supported." msgstr "不支援配置磁碟機格式 '%(format)s'。" msgid "Config requested a custom CPU model, but no model name was provided" -msgstr "配置已要求自訂 CPU 型號,但沒有提供型號名稱" +msgstr "配置已要求自訂 CPU 型號,但卻未提供型號名稱" #, python-format msgid "" "Config requested an explicit CPU model, but the current libvirt hypervisor " "'%s' does not support selecting CPU models" msgstr "" -"配置已要求明確的 CPU 型號,但現行 libVirt Hypervisor '%s' 不支援選取 CPU 型號" +"配置已要求明確的 CPU 型號,但現行 libvirt Hypervisor '%s' 不支援選取 CPU 型號" #, python-format msgid "" @@ -850,7 +846,7 @@ msgstr "與 Glance 主機 %(server)s 的連線失敗:%(reason)s" #, python-format msgid "Connection to libvirt lost: %s" -msgstr "libVirt 連線已中斷:%s" +msgstr "與 libvirt 的連線已遺失:%s" #, python-format msgid "Connection to the hypervisor is broken on host: %(host)s" @@ -901,7 +897,7 @@ msgstr "不符合限制。" #, python-format msgid "Converted to raw, but format is now %s" -msgstr "已轉換為原始,但格式現在為 %s" +msgstr "已轉換為原始格式,但格式現在為 %s" #, python-format msgid "Core API extensions are missing: %(missing_apis)s" @@ -935,7 +931,7 @@ msgstr "找不到 VM 所使用的資料儲存庫參照。" #, python-format msgid "Could not load line %(line)s, got error %(error)s" -msgstr "無法載入行 %(line)s,取得錯誤 %(error)s" +msgstr "無法載入行 %(line)s,發生錯誤 %(error)s" #, python-format msgid "Could not load paste app '%(name)s' from %(path)s" @@ -999,15 +995,15 @@ msgstr "必須指定所需的狀態。有效狀態為:%s" #, python-format msgid "Destination host:%s must be in the same aggregate as the source server" -msgstr "目的地主機:%s 必須位於來源伺服器所在的聚集中" +msgstr "目的地主機 %s 必須位於來源伺服器所在的聚集中" #, python-format msgid "Detaching PCI devices with libvirt < %(ver)s is not permitted" -msgstr "不允許分離 PCI 裝置和 libVirt < %(ver)s" +msgstr "不允許分離 libvirt 版本低於 %(ver)s 的 PCI 裝置" #, python-format msgid "Detaching SR-IOV ports with libvirt < %(ver)s is not permitted" -msgstr "不允許分離 SR-IOV 埠和 libVirt < %(ver)s" +msgstr "不允許分離 libvirt 版本低於 %(ver)s 的 SR-IOV 埠" #, python-format msgid "Detected existing vlan with id %(vlan)d" @@ -1041,7 +1037,7 @@ msgid "" "Different types in %(table)s.%(column)s and shadow table: %(c_type)s " "%(shadow_c_type)s" msgstr "" -"%(table)s.%(column)s 與備份副本表格中的類型不同:%(c_type)s %(shadow_c_type)s" +"%(table)s.%(column)s 與陰影表格中的類型不同:%(c_type)s %(shadow_c_type)s" msgid "Disassociate host is not implemented by the configured Network API" msgstr "所配置的網路 API 未實作解除關聯主機" @@ -1115,14 +1111,14 @@ msgid "" "Error contacting Ironic server for '%(method)s'. Attempt %(attempt)d of " "%(total)d" msgstr "" -"與用於 '%(method)s' 的 Ironic 伺服器聯絡時發生錯誤。嘗試 %(attempt)d 次" -"(共%(total)d 次)" +"與用於 '%(method)s' 的 Ironic 伺服器聯絡時發生錯誤。嘗試 %(attempt)d 次(共 " +"%(total)d 次)" #, python-format msgid "" "Error destroying the instance on node %(node)s. Provision state still " "'%(state)s'." -msgstr "毀損節點 %(node)s 上的實例時發生錯誤。供應狀態仍為'%(state)s'。" +msgstr "毀損節點 %(node)s 上的實例時發生錯誤。供應狀態仍為 '%(state)s'。" #, python-format msgid "Error during following call to agent: %(method)s" @@ -1137,7 +1133,7 @@ msgid "" "Error from libvirt while getting domain info for %(instance_name)s: [Error " "Code %(error_code)s] %(ex)s" msgstr "" -"獲取 %(instance_name)s 的網域資訊時 libVirt 傳回錯誤:[錯誤碼 " +"獲取 %(instance_name)s 的網域資訊時 libvirt 傳回錯誤:[錯誤碼 " "%(error_code)s] %(ex)s" #, python-format @@ -1145,21 +1141,21 @@ msgid "" "Error from libvirt while looking up %(instance_id)s: [Error Code " "%(error_code)s] %(ex)s" msgstr "" -"查閱 %(instance_id)s 時 libVirt 傳回錯誤:[錯誤碼%(error_code)s] %(ex)s" +"查閱 %(instance_id)s 時 libvirt 傳回錯誤:[錯誤碼%(error_code)s] %(ex)s" #, python-format msgid "" "Error from libvirt while looking up %(instance_name)s: [Error Code " "%(error_code)s] %(ex)s" msgstr "" -"查閱 %(instance_name)s 時 libVirt 傳回錯誤:[錯誤碼 %(error_code)s] %(ex)s" +"查閱 %(instance_name)s 時 libvirt 傳回錯誤:[錯誤碼 %(error_code)s] %(ex)s" #, python-format msgid "" "Error from libvirt while quiescing %(instance_name)s: [Error Code " "%(error_code)s] %(ex)s" msgstr "" -"對 %(instance_name)s 執行靜止動作時,libVirt 中發生錯誤:[錯誤碼 " +"對 %(instance_name)s 執行靜止動作時,libvirt 中發生錯誤:[錯誤碼 " "%(error_code)s] %(ex)s" #, python-format @@ -1175,12 +1171,12 @@ msgid "" "Error mounting %(device)s to %(dir)s in image %(image)s with libguestfs " "(%(e)s)" msgstr "" -"使用 libguestfs 將 %(device)s 裝載到映像檔 %(image)s 中的 %(dir)s 時發生錯誤" +"使用 libguestfs 將 %(device)s 裝載到映像檔 %(image)s 中的 %(dir)s 時發生錯誤 " "(%(e)s)" #, python-format msgid "Error mounting %(image)s with libguestfs (%(e)s)" -msgstr "裝載具有 libguestfs (%(e)s) 的 %(image)s 時發生錯誤" +msgstr "使用 libguestfs (%(e)s) 來裝載 %(image)s 時發生錯誤" msgid "Error occurred while creating the verifier" msgstr "建立驗證器時發生錯誤" @@ -1229,7 +1225,7 @@ msgstr "預期類型為 %s 的物件" #, python-format msgid "Extra column %(table)s.%(column)s in shadow table" -msgstr "備份副本表格中存在額外直欄 %(table)s.%(column)s" +msgstr "陰影表格中存在額外直欄 %(table)s.%(column)s" msgid "Extracting vmdk from OVA failed." msgstr "從 OVA 擷取 VMDK 失敗。" @@ -1368,7 +1364,7 @@ msgstr "無法撤銷 %(project_id)s 的憑證" #, python-format msgid "Failed to run qemu-img info on %(path)s : %(error)s" -msgstr "無法在 %(path)s 上執行 qemu-img 資訊:%(error)s" +msgstr "無法在 %(path)s 上執行 qemu-img info:%(error)s" msgid "Failed to run xvp." msgstr "無法執行 xvp。" @@ -1399,7 +1395,7 @@ msgstr "準備區塊裝置時失敗。" msgid "" "Field labels list %(labels)s has different number of elements than fields " "list %(fields)s" -msgstr "欄位標籤清單 %(labels)s 中的元素數目與欄位清單 %(fields)s 中的不同" +msgstr "欄位標籤清單 %(labels)s 中的元素數目與欄位清單 %(fields)s 不同" #, python-format msgid "File %(file_path)s could not be found." @@ -1594,7 +1590,7 @@ msgid "Found no PIF for device %s" msgstr "找不到裝置 %s 的 PIF" msgid "Found no disk to snapshot." -msgstr "找不到磁碟來取得 Snapshot。" +msgstr "找不到要建立 Snapshot 的磁碟。" #, python-format msgid "Found no network for bridge %s" @@ -1965,7 +1961,7 @@ msgstr "實例主機名 %(hostname)s 不是有效的 DNS 名稱" #, python-format msgid "Instance is already in Rescue Mode: %s" -msgstr "實例已處於救援模式:%s" +msgstr "實例已處於「救援模式」:%s" msgid "Instance is not a member of specified network" msgstr "實例不是所指定網路的成員" @@ -2099,11 +2095,11 @@ msgstr "項目 '%s' 無效" #, python-format msgid "Invalid entry: '%s'; Expecting dict" -msgstr "項目 '%s' 無效;預期字典" +msgstr "項目 '%s' 無效;預期為字典" #, python-format msgid "Invalid entry: '%s'; Expecting list or dict" -msgstr "項目 '%s' 無效;預期清單或字典" +msgstr "項目 '%s' 無效;預期為清單或字典" #, python-format msgid "Invalid event name %s" @@ -2297,7 +2293,7 @@ msgid "Invalid status: '%s'" msgstr "無效的狀態:'%s'" msgid "Invalid target_lun" -msgstr "目標 LUN 無效" +msgstr "target_lun 無效" #, python-format msgid "Invalid timestamp for date %s" @@ -2317,7 +2313,7 @@ msgstr "無效的更新設定:'%s'" #, python-format msgid "Invalid usage_type: %s" -msgstr "usage_type %s 無效" +msgstr "usage_type 無效:%s" #, python-format msgid "Invalid value '%s' for force." @@ -2336,7 +2332,7 @@ msgstr "" "%(online)s,所要求的 CPU 集:%(req)s" msgid "Invalid vcpu_pin_set config, out of hypervisor cpu range." -msgstr "無效的 vcpu_pin_set 配置,因為超出 Hypervisor CPU 範圍。" +msgstr "vcpu_pin_set 配置無效,因為超出了 Hypervisor CPU 範圍。" #, python-format msgid "Invalid virtual interface address %s in request" @@ -2374,8 +2370,8 @@ msgid "" "Ironic node: %(id)s virtual to physical interface count missmatch (Vif " "count: %(vif_count)d, Pif count: %(pif_count)d)" msgstr "" -"Ironic 節點 %(id)s 虛擬至實體介面計數不符(Vif計數:%(vif_count)d,Pif 計數:" -"%(pif_count)d)" +"Ironic 節點 %(id)s 虛擬至實體介面計數不符(VIF 計數:%(vif_count)d,PIF 計" +"數:%(pif_count)d)" msgid "Is the appropriate service running?" msgstr "正在執行適當的服務嗎?" @@ -2434,7 +2430,7 @@ msgid "Limit" msgstr "限制" msgid "Limits only supported from vCenter 6.0 and above" -msgstr "只有 vCenter 6.0 及更高版本中的限制才受支援" +msgstr "只有 vCenter 6.0 及更高版本才支援限制" #, python-format msgid "Line %(linenum)d : %(line)s" @@ -2447,7 +2443,7 @@ msgstr "找不到鏈結本端位址:%s" msgid "" "List of file systems that are configured in this file in the image_file_url:" "<list entry name> sections" -msgstr "檔案系統清單,配置於此檔案的 image_file_url:<清單項目名稱> 區段中" +msgstr "在此檔案的 image_file_url:<list entry name> 區段中配置的檔案系統清單" msgid "Listing virtual interfaces is not supported by this cloud." msgstr "這個雲端不支援列出虛擬介面。" @@ -2460,7 +2456,8 @@ msgid "" "Live migration can not be used without shared storage except a booted from " "volume VM which does not have a local disk." msgstr "" -"在沒有共用儲存體的情況下,無法使用即時移轉,不含沒有本端磁碟的啟動磁區 VM。" +"在沒有共用儲存體的情況下,無法使用即時移轉,但沒有本端磁碟的啟動磁區 VM 除" +"外。" #, python-format msgid "Live migration of instance %(id)s to host %(host)s failed" @@ -2588,7 +2585,7 @@ msgid "Migration error: %(reason)s" msgstr "移轉錯誤:%(reason)s" msgid "Migration is not supported for LVM backed instances" -msgstr "不支援移轉以 LVM 為基礎的實例" +msgstr "支援 LVM 的實例不支援移轉作業" #, python-format msgid "" @@ -2618,7 +2615,7 @@ msgstr "遺漏引數:%s" #, python-format msgid "Missing column %(table)s.%(column)s in shadow table" -msgstr "備份副本表格中遺漏了直欄 %(table)s.%(column)s" +msgstr "陰影表格中遺漏了直欄 %(table)s.%(column)s" msgid "Missing device UUID." msgstr "遺漏裝置 UUID。" @@ -2687,7 +2684,7 @@ msgid "" "Multiple hosts may be managed by the VMWare vCenter driver; therefore we do " "not return uptime for just one host." msgstr "" -"多個主機可能由 VMWare vCenter 驅動程式進行管理;因此,將不會儘傳回一個主機執" +"多個主機可能由 VMWare vCenter 驅動程式進行管理;因此,將不會僅傳回一個主機執" "行時間。" msgid "Multiple possible networks found, use a Network ID to be more specific." @@ -2711,14 +2708,14 @@ msgid "" "Must specify connection_url, connection_username (optionally), and " "connection_password to use compute_driver=xenapi.XenAPIDriver" msgstr "" -"必須指定 connection_url、connection_username(選用項目)及" +"必須指定 connection_url、connection_username(選用項目)及 " "connection_password,才能使用 compute_driver=xenapi.XenAPIDriver" msgid "" "Must specify host_ip, host_username and host_password to use vmwareapi." "VMwareVCDriver" msgstr "" -"必須指定 host_ip、host_username 及 host_password,才能使用vmwareapi." +"必須指定 host_ip、host_username 及 host_password,才能使用 vmwareapi." "VMwareVCDriver" msgid "Must supply a positive value for max_number" @@ -2891,7 +2888,7 @@ msgstr "尚未定義浮動 IP 位址。" #, python-format msgid "No free disk device names for prefix '%s'" -msgstr "字首 '%s' 沒有可用磁碟裝置名稱" +msgstr "沒有用於字首 '%s' 的磁碟裝置名稱" msgid "No free nbd devices" msgstr "沒有可用的 NBD 裝置" @@ -3040,7 +3037,7 @@ msgstr "未保存任何內容。" #, python-format msgid "Nova requires libvirt version %s or greater." -msgstr "Nova 需要 libVirt %s 版或更高版本。" +msgstr "Nova 需要 libvirt %s 版或更高版本。" msgid "Number of Rows Archived" msgstr "已保存的列數" @@ -3086,9 +3083,7 @@ msgstr "只有管理者才能列出已刪除的實例" msgid "" "Only file-based SRs (ext/NFS) are supported by this feature. SR %(uuid)s is " "of type %(type)s" -msgstr "" -"此特性僅支援檔案型「儲存體儲存庫 (SR)」(ext/NFS)。「儲存體儲存庫 " -"(SR)」%(uuid)s 的類型是%(type)s" +msgstr "此特性僅支援檔案型 SR (ext/NFS)。SR %(uuid)s 的類型是 %(type)s" msgid "Only host parameter can be specified" msgstr "只能指定主機參數" @@ -3147,7 +3142,7 @@ msgid "" "force_raw_images=True in config or upload an image in ploop or raw format." msgstr "" "PCS 不支援 %s 格式的映像檔。您應在配置中設定 force_raw_images=True,或者以 " -"pLoop 或原始格式 上傳映像檔。" +"ploop 或原始格式 上傳映像檔。" #, python-format msgid "" @@ -3224,7 +3219,7 @@ msgstr "請指定 fixed_range 或 UUID" #, python-format msgid "Plug vif failed because of unexpected vif_type=%s" -msgstr "由於非預期的 vif_type %s,VIF 插拔失敗" +msgstr "由於非預期的 vif_type %s,VIF 插入失敗" #, python-format msgid "Plugin version mismatch (Expected %(exp)s, got %(got)s)" @@ -3401,8 +3396,8 @@ msgid "" "Relative blockcommit support was not detected. Libvirt '%s' or later is " "required for online deletion of file/network storage-backed volume snapshots." msgstr "" -"偵測不到相對的區塊確定支援。線上刪除以檔案/網路儲存體為基礎的磁區 Snapshot 需" -"要 Libvirt '%s' 或更新版本。" +"偵測不到相對的區塊確定支援。需要 Libvirt '%s' 或更新版本,才能線上刪除檔案型/" +"網路儲存體型磁區 Snapshot。" msgid "Request body and URI mismatch" msgstr "要求內文與 URI 不符" @@ -3513,7 +3508,7 @@ msgstr "規則已存在於群組中:%(rule)s" #, python-format msgid "Running Nova with parallels virt_type requires libvirt version %s" -msgstr "執行 virt_type 為 parallels 的 Nova 需要 libVirt %s 版" +msgstr "使用 parallels virt_type 執行 Nova 需要 libvirt %s 版" #, python-format msgid "" @@ -3582,7 +3577,7 @@ msgstr "專案 %(project_id)s 已存在安全群組 %(security_group_name)s。" msgid "" "Security group %(security_group_name)s not associated with the instance " "%(instance)s" -msgstr "安全群組 %(security_group_name)s 未與實例 %(instance)s 產生關聯" +msgstr "安全群組 %(security_group_name)s 未與實例 %(instance)s 建立關聯" #, python-format msgid "Security group %s already exists" @@ -3865,7 +3860,7 @@ msgstr "實例需要比所提供版本還新的 Hypervisor 版本。" #, python-format msgid "" "The key %(r)s is required in the location metadata to access the url %(url)s." -msgstr "位置 meta 資料中需要索引鍵 %(r)s,才能存取 URL%(url)s。" +msgstr "位置 meta 資料中需要索引鍵 %(r)s,才能存取 URL %(url)s。" #, python-format msgid "The key %s is required in all file system descriptions." @@ -3893,7 +3888,7 @@ msgstr "裝載 %(mount_path)s 不是有效的 Quobyte 磁區。錯誤:%(exc)s" msgid "" "The mount point advertised by glance: %(glance_mount)s, does not match the " "URL path: %(path)s" -msgstr "Glance 所通告的裝載點 %(glance_mount)s,與URL 路徑 %(path)s 不符" +msgstr "Glance 所通告的裝載點 %(glance_mount)s,與 URL 路徑 %(path)s 不符" #, python-format msgid "" @@ -3953,7 +3948,7 @@ msgstr "包含停用服務原因的字串含有無效字元,或者太長。" msgid "" "The sum between the number of networks and the vlan start cannot be greater " "than 4094" -msgstr "網路數目及 VLAN 起始號碼之和不能大於 4094" +msgstr "網路數目及 VLAN 起始號碼之和不得大於 4094" #, python-format msgid "The supplied device (%(device)s) is busy." @@ -4084,7 +4079,7 @@ msgstr "" #, python-format msgid "Timeout waiting for device %s to be created" -msgstr "等待建立裝置 %s 時發生逾時" +msgstr "等待建立裝置 %s 時逾時" msgid "Timeout waiting for response from cell" msgstr "等候 Cell 回應時發生逾時" @@ -4184,7 +4179,7 @@ msgid "Unable to destroy VDI %s" msgstr "無法毀損 VDI %s" msgid "Unable to detach from guest transient domain." -msgstr "無法從訪客暫時網域分離" +msgstr "無法從訪客暫時網域分離。" #, python-format msgid "Unable to determine disk bus for '%s'" @@ -4204,11 +4199,11 @@ msgstr "無法將 %s 從儲存區中退出;儲存區不是空的" #, python-format msgid "Unable to find SR from VBD %s" -msgstr "在 VBD %s 中找不到「儲存體儲存庫 (SR)」" +msgstr "在 VBD %s 中找不到 SR" #, python-format msgid "Unable to find SR from VDI %s" -msgstr "從 VDI %s 中找不到 SR" +msgstr "在 VDI %s 中找不到 SR" #, python-format msgid "Unable to find a mounted disk for target_iqn: %s" @@ -4219,7 +4214,7 @@ msgid "" "Unable to find a mounted disk for target_iqn: %s. Please ensure that the " "host's SAN policy is set to \"OfflineAll\" or \"OfflineShared\"" msgstr "" -"找不到 target_iqn %s 的已裝載磁碟。請確保主機的 SAN 原則設定為 \"OfflineAll" +"找不到 target_iqn 的已裝載磁碟:%s。請確保主機的 SAN 原則設定為 \"OfflineAll" "\" 或 \"OfflineShared\"" #, python-format @@ -4289,11 +4284,11 @@ msgstr "無法取得 vnc 主控台,功能未實作" #, python-format msgid "Unable to introduce VDI for SR %s" -msgstr "無法給「儲存體儲存庫 (SR)」%s 建立 VDI" +msgstr "無法為 SR %s 建立 VDI" #, python-format msgid "Unable to introduce VDI on SR %s" -msgstr "無法在「儲存體儲存庫 (SR)」%s 上建立 VDI" +msgstr "無法在 SR %s 上建立 VDI" #, python-format msgid "Unable to join %s in the pool" @@ -4324,7 +4319,7 @@ msgid "" "on destination host:%(available)s < need:%(necessary)s)" msgstr "" "無法移轉 %(instance_uuid)s:實例的磁碟太大(目的地主機上的可用空間:" -"%(available)s < 需要的空間:%(necessary)s)" +"%(available)s 小於需要的空間:%(necessary)s)" #, python-format msgid "" @@ -4339,7 +4334,7 @@ msgid "Unable to parse metadata key/value pairs." msgstr "無法剖析 meta 資料鍵值組。" msgid "Unable to resize disk down." -msgstr "無法將磁碟大小調小。" +msgstr "無法將磁碟調小。" #, python-format msgid "Unable to retrieve certificate with ID: %s" @@ -4406,7 +4401,7 @@ msgid "Unexpected vif_type=%s" msgstr "非預期的 vif_type = %s" msgid "Unknown" -msgstr "未知" +msgstr "不明" #, python-format msgid "Unknown %(cell_type)s when routing to %(target_cell)s" @@ -4493,7 +4488,7 @@ msgid "Updated_At" msgstr "Updated_At" msgid "Upgrade DB using Essex release first." -msgstr "請先使用 Essex 版本來升級 DB。" +msgstr "請先使用 Essex 版本來升級資料庫。" #, python-format msgid "User %(username)s not found in password file." @@ -4533,15 +4528,14 @@ msgid "" "VDI %(vdi_ref)s is %(virtual_size)d bytes which is larger than flavor size " "of %(new_disk_size)d bytes." msgstr "" -"VDI %(vdi_ref)s 為 %(virtual_size)d 位元組,這大於特性大小%(new_disk_size)d " +"VDI %(vdi_ref)s 為 %(virtual_size)d 位元組,這大於特性大小 %(new_disk_size)d " "位元組。" #, python-format msgid "" "VDI not found on SR %(sr)s (vdi_uuid %(vdi_uuid)s, target_lun %(target_lun)s)" msgstr "" -"在「儲存體儲存庫 (SR)」%(sr)s 上找不到 VDI(vdi_uuid %(vdi_uuid)s、" -"target_lun %(target_lun)s)" +"在 SR %(sr)s 上找不到 VDI(vdi_uuid %(vdi_uuid)s、target_lun %(target_lun)s)" #, python-format msgid "VHD coalesce attempts exceeded (%d), giving up..." @@ -4552,7 +4546,7 @@ msgid "VIF driver not found for network_api_class: %s" msgstr "找不到 network_api_class 的 VIF 驅動程式:%s" msgid "VIF plugging is not supported by the Hyper-V driver." -msgstr "Hyper-V 驅動程式不支援 VIF 插拔。" +msgstr "Hyper-V 驅動程式不支援 VIF 插入。" msgid "VIF unplugging is not supported by the Hyper-V driver." msgstr "Hyper-V 驅動程式不支援 VIF 拔除。" @@ -4673,14 +4667,14 @@ msgstr "已超出磁區資源配額" msgid "" "Volume sets block size, but the current libvirt hypervisor '%s' does not " "support custom block size" -msgstr "由磁區設定區塊大小,但現行 libVirt Hypervisor '%s' 不支援自訂區塊大小" +msgstr "磁區會設定區塊大小,但現行 libvirt Hypervisor '%s' 不支援自訂區塊大小" #, python-format msgid "" "Volume sets discard option, but libvirt %(libvirt)s or later is required, " "qemu %(qemu)s or later is required." msgstr "" -"磁區設定了捨棄選項,但卻需要 libVirt %(libvirt)s 或更新版本,需要 qemu " +"磁區會設定捨棄選項,但卻需要 libvirt %(libvirt)s 或更新版本,需要 qemu " "%(qemu)s 或更新版本。" #, python-format @@ -4766,8 +4760,8 @@ msgid "" "(0.0.0.0 or ::) or the local address (127.0.0.1 or ::1)." msgstr "" "您的 Libvirt 版本不支援 VIR_DOMAIN_XML_MIGRATABLE 旗標,或者,您的目的地節點" -"不支援擷取接聽位址。如果讓即時移轉正常運作,您必須將圖形(VNC 及/或 SPICE)接" -"聽位址配置成捕捉所有位址(0.0.0.0 或 ::)或者本端位址(127.0.0.1 或 ::1)。" +"不支援擷取接聽位址。如果要讓即時移轉正常工作,您必須將圖形(VNC 及/或 SPICE)" +"接聽位址配置成捕捉所有位址(0.0.0.0 或 ::)或者本端位址(127.0.0.1 或 ::1)。" msgid "Zero fixed IPs could be found." msgstr "可以找到 0 個固定 IP。" @@ -4883,7 +4877,7 @@ msgid "failed to generate fingerprint" msgstr "無法產生指紋" msgid "filename cannot be None" -msgstr "檔名不能為 None" +msgstr "檔名不能為「無」" msgid "floating IP is already associated" msgstr "已與浮動 IP 建立關聯" @@ -4948,7 +4942,7 @@ msgid "instance is a required argument to use @refresh_cache" msgstr "實例是使用 @refresh_cache 的必要引數" msgid "instance is not in a suspended state" -msgstr "實例不處於暫停狀態" +msgstr "實例未處於暫停狀態" msgid "instance is not powered on" msgstr "未開啟實例的電源" @@ -4991,7 +4985,7 @@ msgid "libguestfs is not installed (%s)" msgstr "未安裝 libguestfs (%s)" msgid "libvirt error while requesting blockjob info." -msgstr "要求 blockjob 資訊時發生 libVirt 錯誤。" +msgstr "要求 blockjob 資訊時發生 libvirt 錯誤。" #, python-format msgid "marker [%s] not found" @@ -5021,7 +5015,7 @@ msgid "nbd device %s did not show up" msgstr "NBD 裝置 %s 未顯示" msgid "nbd unavailable: module not loaded" -msgstr "NBD 無法使用:未載入模組" +msgstr "無法使用 NBD:未載入模組" msgid "network" msgstr "網路" @@ -5131,7 +5125,7 @@ msgid "serve() can only be called once" msgstr "只能呼叫 serve() 一次" msgid "service is a mandatory argument for DB based ServiceGroup driver" -msgstr "服務是 DB 型 ServiceGroup 驅動程式的必要引數" +msgstr "服務是資料庫型 ServiceGroup 驅動程式的必要引數" msgid "service is a mandatory argument for Memcached based ServiceGroup driver" msgstr "服務是 Memcached 型 ServiceGroup 驅動程式的必要引數" diff --git a/nova/network/neutronv2/api.py b/nova/network/neutronv2/api.py index adee8f59e0..efc1dc2678 100644 --- a/nova/network/neutronv2/api.py +++ b/nova/network/neutronv2/api.py @@ -331,6 +331,8 @@ class API(base_api.NetworkAPI): if port_binding: port_req_body['port']['binding:host_id'] = None port_req_body['port']['binding:profile'] = {} + if constants.DNS_INTEGRATION in self.extensions: + port_req_body['port']['dns_name'] = '' try: port_client.update_port(port_id, port_req_body) except Exception: diff --git a/nova/tests/functional/db/test_archive.py b/nova/tests/functional/db/test_archive.py index 8876676e86..8d482c42b7 100644 --- a/nova/tests/functional/db/test_archive.py +++ b/nova/tests/functional/db/test_archive.py @@ -96,9 +96,9 @@ class TestDatabaseArchive(test_servers.ServersTestBase): self.assertIn('instance_system_metadata', results) self.assertEqual(len(instance.system_metadata), results['instance_system_metadata']) - # FIXME(mriedem): we fail to archive instances because of a fkey - # referential constraint error with instance_actions not being deleted - self.assertNotIn('instances', results) - # FIXME(mriedem): instance_actions aren't soft deleted so they aren't - # archived, which we need to fix. - self.assertNotIn('instance_actions', results) + # Verify that instances rows are dropped + self.assertIn('instances', results) + # Verify that instance_actions and actions_event are dropped + # by the archive + self.assertIn('instance_actions', results) + self.assertIn('instance_actions_events', results) diff --git a/nova/tests/unit/api/openstack/compute/legacy_v2/test_servers.py b/nova/tests/unit/api/openstack/compute/legacy_v2/test_servers.py index 1684b46118..d570a35b10 100644 --- a/nova/tests/unit/api/openstack/compute/legacy_v2/test_servers.py +++ b/nova/tests/unit/api/openstack/compute/legacy_v2/test_servers.py @@ -1362,7 +1362,7 @@ class ServersControllerUpdateTest(ControllerTest): key="Label"></meta>""" req = self._get_request(body, content_type='xml') res = req.get_response(self.wsgi_app) - self.assertEqual(400, res.status_int) + self.assertEqual(415, res.status_int) def test_update_server_invalid_xml_raises_expat(self): body = """<?xml version="1.0" encoding="UTF-8"?> @@ -1371,7 +1371,7 @@ class ServersControllerUpdateTest(ControllerTest): key="Label"></meta>""" req = self._get_request(body, content_type='xml') res = req.get_response(self.wsgi_app) - self.assertEqual(400, res.status_int) + self.assertEqual(415, res.status_int) def test_update_server_name(self): body = {'server': {'name': 'server_test'}} diff --git a/nova/tests/unit/api/openstack/compute/test_api.py b/nova/tests/unit/api/openstack/compute/test_api.py index da98a18b29..de8bf79966 100644 --- a/nova/tests/unit/api/openstack/compute/test_api.py +++ b/nova/tests/unit/api/openstack/compute/test_api.py @@ -59,7 +59,7 @@ class APITest(test.NoDBTestCase): req.headers["content-type"] = "application/xml" res = req.get_response(self.wsgi_app) - self.assertEqual(res.status_int, 400) + self.assertEqual(res.status_int, 415) def test_vendor_content_type_json(self): ctype = 'application/vnd.openstack.compute+json' diff --git a/nova/tests/unit/api/openstack/compute/test_block_device_mapping.py b/nova/tests/unit/api/openstack/compute/test_block_device_mapping.py index ea0c28c21a..c342236f05 100644 --- a/nova/tests/unit/api/openstack/compute/test_block_device_mapping.py +++ b/nova/tests/unit/api/openstack/compute/test_block_device_mapping.py @@ -231,6 +231,20 @@ class BlockDeviceMappingTestV21(test.TestCase): self.assertRaises(self.validation_error, self._test_create, params, no_image=True) + def _test_create_instance_with_destination_type_error(self, + destination_type): + self.bdm[0]['destination_type'] = destination_type + + params = {block_device_mapping.ATTRIBUTE_NAME: self.bdm} + self.assertRaises(self.validation_error, + self._test_create, params, no_image=True) + + def test_create_instance_with_destination_type_empty_string(self): + self._test_create_instance_with_destination_type_error('') + + def test_create_instance_with_invalid_destination_type(self): + self._test_create_instance_with_destination_type_error('fake') + def test_create_instance_bdm(self): bdm = [{ 'source_type': 'volume', @@ -361,3 +375,13 @@ class BlockDeviceMappingTestV2(BlockDeviceMappingTestV21): params = {block_device_mapping.ATTRIBUTE_NAME: bdm} self._test_create(params, override_controller=self.no_bdm_v2_controller) + + def test_create_instance_with_destination_type_empty_string(self): + # Add a check whether the destination type is an empty string + # in V2.1 API only. So this test is skipped in V2.0 API + pass + + def test_create_instance_with_invalid_destination_type(self): + # Add a check whether the destination type is invalid + # in V2.1 API only. So this test is skipped in V2.0 API + pass diff --git a/nova/tests/unit/api/openstack/compute/test_block_device_mapping_v1.py b/nova/tests/unit/api/openstack/compute/test_block_device_mapping_v1.py index 9e2b129085..d851e8b5b5 100644 --- a/nova/tests/unit/api/openstack/compute/test_block_device_mapping_v1.py +++ b/nova/tests/unit/api/openstack/compute/test_block_device_mapping_v1.py @@ -26,6 +26,7 @@ from nova.api.openstack.compute.legacy_v2 import extensions from nova.api.openstack.compute.legacy_v2 import servers as servers_v2 from nova.api.openstack.compute import servers as servers_v21 from nova.compute import api as compute_api +from nova import db from nova import exception from nova import test from nova.tests.unit.api.openstack import fakes @@ -242,10 +243,10 @@ class BlockDeviceMappingTestV21(test.TestCase): self.assertRaises(self.validation_error, self._test_create, params) - def test_create_instance_with_invalid_size(self): + def _test_create_instance_with_size_error(self, size): bdm = [{'delete_on_termination': True, 'device_name': 'vda', - 'volume_size': "hello world", + 'volume_size': size, 'volume_id': '11111111-1111-1111-1111-111111111111'}] params = {'block_device_mapping': bdm} old_create = compute_api.API.create @@ -258,6 +259,18 @@ class BlockDeviceMappingTestV21(test.TestCase): self.assertRaises(self.validation_error, self._test_create, params) + def test_create_instance_with_invalid_size(self): + self._test_create_instance_with_size_error("hello world") + + def test_create_instance_with_size_empty_string(self): + self._test_create_instance_with_size_error('') + + def test_create_instance_with_size_zero(self): + self._test_create_instance_with_size_error("0") + + def test_create_instance_with_size_greater_than_limit(self): + self._test_create_instance_with_size_error(db.MAX_INT + 1) + def test_create_instance_with_bdm_delete_on_termination(self): bdm = [{'device_name': 'foo1', 'volume_id': fakes.FAKE_UUID, 'delete_on_termination': 'True'}, @@ -394,3 +407,18 @@ class BlockDeviceMappingTestV2(BlockDeviceMappingTestV21): params = {'block_device_mapping': bdm} self._test_create(params, override_controller=controller) + + def test_create_instance_with_size_empty_string(self): + # Add a check whether the size is an empty string + # in V2.1 API only. So this test is skipped in V2.0 API + pass + + def test_create_instance_with_size_zero(self): + # Add a check whether the size is zero in V2.1 API only. + # So this test is skipped in V2.0 API + pass + + def test_create_instance_with_size_greater_than_limit(self): + # Add a check whether size is greater than the limit + # in V2.1 API only. So this test is skipped in V2.0 API + pass diff --git a/nova/tests/unit/api/openstack/compute/test_user_data.py b/nova/tests/unit/api/openstack/compute/test_user_data.py index 48e9c9c6f9..970d91c139 100644 --- a/nova/tests/unit/api/openstack/compute/test_user_data.py +++ b/nova/tests/unit/api/openstack/compute/test_user_data.py @@ -16,6 +16,7 @@ import base64 import datetime +import mock import uuid from oslo_config import cfg @@ -135,7 +136,7 @@ class ServersControllerCreateTest(test.TestCase): fake_method) def _test_create_extra(self, params, no_image=False, - override_controller=None): + override_controller=None, legacy_v2=False): image_uuid = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77' server = dict(name='server_test', imageRef=image_uuid, flavorRef=2) if no_image: @@ -146,6 +147,8 @@ class ServersControllerCreateTest(test.TestCase): req.method = 'POST' req.body = jsonutils.dump_as_bytes(body) req.headers["content-type"] = "application/json" + if legacy_v2: + req.set_legacy_v2() if override_controller: server = override_controller.create(req, body=body).obj['server'] else: @@ -187,3 +190,15 @@ class ServersControllerCreateTest(test.TestCase): params = {user_data.ATTRIBUTE_NAME: value} self.assertRaises(exception.ValidationError, self._test_create_extra, params) + + @mock.patch('nova.compute.api.API.create') + def test_create_instance_with_none_allowd_for_v20_compat_mode(self, + mock_create): + + def create(context, *args, **kwargs): + self.assertIsNone(kwargs['user_data']) + return ([fakes.stub_instance_obj(context)], None) + + mock_create.side_effect = create + params = {user_data.ATTRIBUTE_NAME: None} + self._test_create_extra(params, legacy_v2=True) diff --git a/nova/tests/unit/api/openstack/test_wsgi.py b/nova/tests/unit/api/openstack/test_wsgi.py index b71f27549c..dc58444cd3 100644 --- a/nova/tests/unit/api/openstack/test_wsgi.py +++ b/nova/tests/unit/api/openstack/test_wsgi.py @@ -409,9 +409,9 @@ class ResourceTest(test.NoDBTestCase): req.content_type = 'application/xml' req.body = b'{"body": {"key": "value"}}' response = req.get_response(app) - expected_unsupported_type_body = {'badRequest': - {'message': 'Unsupported Content-Type', 'code': 400}} - self.assertEqual(response.status_int, 400) + expected_unsupported_type_body = {'badMediaType': + {'message': 'Unsupported Content-Type', 'code': 415}} + self.assertEqual(response.status_int, 415) self.assertEqual(expected_unsupported_type_body, jsonutils.loads(response.body)) diff --git a/nova/tests/unit/cells/test_cells_state_manager.py b/nova/tests/unit/cells/test_cells_state_manager.py index 62e55779ef..74dbd16396 100644 --- a/nova/tests/unit/cells/test_cells_state_manager.py +++ b/nova/tests/unit/cells/test_cells_state_manager.py @@ -163,10 +163,11 @@ class TestCellsStateManager(test.NoDBTestCase): # utilize entire cell cap = self._capacity(0.0) - cell_free_ram = sum(compute[3] for compute in FAKE_COMPUTES) + cell_free_ram = sum(max(0, compute[3]) for compute in FAKE_COMPUTES) self.assertEqual(cell_free_ram, cap['ram_free']['total_mb']) - cell_free_disk = 1024 * sum(compute[4] for compute in FAKE_COMPUTES) + cell_free_disk = 1024 * sum(max(0, compute[4]) + for compute in FAKE_COMPUTES) self.assertEqual(cell_free_disk, cap['disk_free']['total_mb']) self.assertEqual(0, cap['ram_free']['units_by_mb']['0']) @@ -183,10 +184,11 @@ class TestCellsStateManager(test.NoDBTestCase): # reserve the entire cell. (utilize zero percent) cap = self._capacity(100.0) - cell_free_ram = sum(compute[3] for compute in FAKE_COMPUTES) + cell_free_ram = sum(max(0, compute[3]) for compute in FAKE_COMPUTES) self.assertEqual(cell_free_ram, cap['ram_free']['total_mb']) - cell_free_disk = 1024 * sum(compute[4] for compute in FAKE_COMPUTES) + cell_free_disk = 1024 * sum(max(0, compute[4]) + for compute in FAKE_COMPUTES) self.assertEqual(cell_free_disk, cap['disk_free']['total_mb']) self.assertEqual(0, cap['ram_free']['units_by_mb']['0']) @@ -200,10 +202,11 @@ class TestCellsStateManager(test.NoDBTestCase): # utilize half the cell's free capacity cap = self._capacity(50.0) - cell_free_ram = sum(compute[3] for compute in FAKE_COMPUTES) + cell_free_ram = sum(max(0, compute[3]) for compute in FAKE_COMPUTES) self.assertEqual(cell_free_ram, cap['ram_free']['total_mb']) - cell_free_disk = 1024 * sum(compute[4] for compute in FAKE_COMPUTES) + cell_free_disk = 1024 * sum(max(0, compute[4]) + for compute in FAKE_COMPUTES) self.assertEqual(cell_free_disk, cap['disk_free']['total_mb']) self.assertEqual(0, cap['ram_free']['units_by_mb']['0']) @@ -237,11 +240,13 @@ class TestCellsStateManagerNToOne(TestCellsStateManager): # utilize half the cell's free capacity cap = self._capacity(50.0) - cell_free_ram = sum(compute[3] for compute in FAKE_COMPUTES_N_TO_ONE) + cell_free_ram = sum(max(0, compute[3]) + for compute in FAKE_COMPUTES_N_TO_ONE) self.assertEqual(cell_free_ram, cap['ram_free']['total_mb']) cell_free_disk = (1024 * - sum(compute[4] for compute in FAKE_COMPUTES_N_TO_ONE)) + sum(max(0, compute[4]) + for compute in FAKE_COMPUTES_N_TO_ONE)) self.assertEqual(cell_free_disk, cap['disk_free']['total_mb']) self.assertEqual(0, cap['ram_free']['units_by_mb']['0']) @@ -269,10 +274,12 @@ class TestCellsStateManagerNodeDown(test.NoDBTestCase): def test_capacity_no_reserve_nodedown(self): cap = self._capacity(0.0) - cell_free_ram = sum(compute[3] for compute in FAKE_COMPUTES[:-1]) + cell_free_ram = sum(max(0, compute[3]) + for compute in FAKE_COMPUTES[:-1]) self.assertEqual(cell_free_ram, cap['ram_free']['total_mb']) - free_disk = sum(compute[4] for compute in FAKE_COMPUTES[:-1]) + free_disk = sum(max(0, compute[4]) + for compute in FAKE_COMPUTES[:-1]) cell_free_disk = 1024 * free_disk self.assertEqual(cell_free_disk, cap['disk_free']['total_mb']) diff --git a/nova/tests/unit/cmd/test_nova_api.py b/nova/tests/unit/cmd/test_nova_api.py new file mode 100644 index 0000000000..d9477afbb8 --- /dev/null +++ b/nova/tests/unit/cmd/test_nova_api.py @@ -0,0 +1,89 @@ +# Copyright 2015 HPE, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import mock + +from nova.cmd import api +from nova import config +from nova import exception +from nova import test + + +# required because otherwise oslo early parse_args dies +@mock.patch.object(config, 'parse_args', new=lambda *args, **kwargs: None) +class TestNovaAPI(test.NoDBTestCase): + + @mock.patch('nova.service.process_launcher') + def test_with_ec2(self, launcher): + """Ensure that we don't explode if enabled_apis is wrong. + + If the end user hasn't updated their config, an ec2 entry + might accidentally kill them in starting up their server. This + tests that our new safety filter will prevent that. + + The metadata api is excluded because it loads a bunch of the + network stack, which requires other mocking. + """ + self.flags(enabled_apis=['ec2', 'osapi_compute']) + # required because of where the portbind happens, so that we + # collide on ports. + self.flags(osapi_compute_listen_port=0) + api.main() + + def test_continues_on_failure(self): + count = [1, 2] + + fake_server = mock.MagicMock() + fake_server.workers = 123 + + def fake_service(api, **kw): + while count: + count.pop() + raise exception.PasteAppNotFound(name=api, path='/') + return fake_server + + self.flags(enabled_apis=['foo', 'bar', 'baz']) + with mock.patch.object(api, 'service') as mock_service: + mock_service.WSGIService.side_effect = fake_service + api.main() + mock_service.WSGIService.assert_has_calls([ + mock.call('foo', use_ssl=False), + mock.call('bar', use_ssl=False), + mock.call('baz', use_ssl=False), + ]) + launcher = mock_service.process_launcher.return_value + launcher.launch_service.assert_called_once_with( + fake_server, workers=123) + + @mock.patch('sys.exit') + def test_fails_if_none_started(self, mock_exit): + mock_exit.side_effect = test.TestingException + self.flags(enabled_apis=[]) + with mock.patch.object(api, 'service') as mock_service: + self.assertRaises(test.TestingException, api.main) + mock_exit.assert_called_once_with(1) + launcher = mock_service.process_launcher.return_value + self.assertFalse(launcher.wait.called) + + @mock.patch('sys.exit') + def test_fails_if_all_failed(self, mock_exit): + mock_exit.side_effect = test.TestingException + self.flags(enabled_apis=['foo', 'bar']) + with mock.patch.object(api, 'service') as mock_service: + mock_service.WSGIService.side_effect = exception.PasteAppNotFound( + name='foo', path='/') + self.assertRaises(test.TestingException, api.main) + mock_exit.assert_called_once_with(1) + launcher = mock_service.process_launcher.return_value + self.assertFalse(launcher.wait.called) diff --git a/nova/tests/unit/compute/test_compute.py b/nova/tests/unit/compute/test_compute.py index 7d6d35d848..0358595153 100644 --- a/nova/tests/unit/compute/test_compute.py +++ b/nova/tests/unit/compute/test_compute.py @@ -11660,11 +11660,14 @@ class EvacuateHostTestCase(BaseTestCase): self.assertRaises(exception.InstanceRecreateNotSupported, lambda: self._rebuild(on_shared_storage=True)) - def test_on_shared_storage_not_provided_host_without_shared_storage(self): + @mock.patch('nova.objects.ImageMeta.from_image_ref') + def test_on_shared_storage_not_provided_host_without_shared_storage(self, + mock_image_meta): + # 'spawn' should be called with the image_meta from the image_ref self.mox.StubOutWithMock(self.compute.driver, 'spawn') self.compute.driver.spawn(mox.IsA(self.context), mox.IsA(objects.Instance), - mox.IsA(objects.ImageMeta), + mock_image_meta.return_value, mox.IgnoreArg(), mox.IsA('newpass'), network_info=mox.IgnoreArg(), block_device_info=mox.IgnoreArg()) @@ -11675,11 +11678,15 @@ class EvacuateHostTestCase(BaseTestCase): self._rebuild(on_shared_storage=None) - def test_on_shared_storage_not_provided_host_with_shared_storage(self): + @mock.patch('nova.objects.Instance.image_meta', + new_callable=mock.PropertyMock) + def test_on_shared_storage_not_provided_host_with_shared_storage(self, + mock_image_meta): + # 'spawn' should be called with the image_meta from the instance self.mox.StubOutWithMock(self.compute.driver, 'spawn') self.compute.driver.spawn(mox.IsA(self.context), mox.IsA(objects.Instance), - mox.IsA(objects.ImageMeta), + mock_image_meta.return_value, mox.IgnoreArg(), 'newpass', network_info=mox.IgnoreArg(), block_device_info=mox.IgnoreArg()) diff --git a/nova/tests/unit/compute/test_compute_api.py b/nova/tests/unit/compute/test_compute_api.py index c0ac0c6080..2735d30ebf 100644 --- a/nova/tests/unit/compute/test_compute_api.py +++ b/nova/tests/unit/compute/test_compute_api.py @@ -2034,6 +2034,8 @@ class _ComputeAPIUnitTestMixIn(object): fake_image_meta = { 'is_public': True, 'name': 'base-name', + 'disk_format': 'fake', + 'container_format': 'fake', 'properties': { 'user_id': 'meow', 'foo': 'bar', @@ -2045,6 +2047,8 @@ class _ComputeAPIUnitTestMixIn(object): sent_meta = { 'is_public': False, 'name': 'fake-name', + 'disk_format': 'fake', + 'container_format': 'fake', 'properties': { 'user_id': self.context.user_id, 'instance_uuid': instance.uuid, @@ -2063,6 +2067,8 @@ class _ComputeAPIUnitTestMixIn(object): if min_disk is not None: fake_image_meta['min_disk'] = min_disk sent_meta['min_disk'] = min_disk + sent_meta.pop('disk_format', None) + sent_meta.pop('container_format', None) else: sent_meta['properties']['backup_type'] = 'fake-backup-type' diff --git a/nova/tests/unit/compute/test_compute_mgr.py b/nova/tests/unit/compute/test_compute_mgr.py index c91e75e043..473a993d3e 100644 --- a/nova/tests/unit/compute/test_compute_mgr.py +++ b/nova/tests/unit/compute/test_compute_mgr.py @@ -1580,13 +1580,10 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase): # files deletion for those instances whose instance.host is not # same as compute host where periodic task is running. for inst in fake_instances: - for mig in fake_migrations: - if inst.uuid == mig.instance_uuid: - self.assertEqual('failed', mig.status) - - # Make sure we filtered the instances by host in the DB query. - self.assertEqual(CONF.host, - mock_inst_get_by_filters.call_args[0][1]['host']) + if inst.host != CONF.host: + for mig in fake_migrations: + if inst.uuid == mig.instance_uuid: + self.assertEqual('failed', mig.status) def test_cleanup_incomplete_migrations_dest_node(self): """Test to ensure instance files are deleted from destination node. diff --git a/nova/tests/unit/compute/test_rpcapi.py b/nova/tests/unit/compute/test_rpcapi.py index 58ec05c6e6..f35b151be2 100644 --- a/nova/tests/unit/compute/test_rpcapi.py +++ b/nova/tests/unit/compute/test_rpcapi.py @@ -620,7 +620,6 @@ class ComputeRpcAPITestCase(test.NoDBTestCase): callargs={'instance': 'foo', 'dest': 'foo', 'block_migration': False, - 'migration': None, 'migrate_data': { 'pre_live_migration_result': {}}}, callret=None, diff --git a/nova/tests/unit/db/test_db_api.py b/nova/tests/unit/db/test_db_api.py index 933905d2bc..a756bfa717 100644 --- a/nova/tests/unit/db/test_db_api.py +++ b/nova/tests/unit/db/test_db_api.py @@ -1335,6 +1335,7 @@ class MigrationTestCase(test.TestCase): self._create(status='error') self._create(status='failed') self._create(status='accepted') + self._create(status='completed') self._create(source_compute='host2', source_node='b', dest_compute='host1', dest_node='a') self._create(source_compute='host2', dest_compute='host3') @@ -2811,6 +2812,23 @@ class InstanceTestCase(test.TestCase, ModelsObjectComparatorMixin): # Make sure instance faults is deleted as well self.assertEqual(0, len(faults[uuid])) + def test_delete_instance_group_member_on_instance_destroy(self): + ctxt = context.get_admin_context() + uuid = str(stdlib_uuid.uuid4()) + db.instance_create(ctxt, {'uuid': uuid}) + values = {'name': 'fake_name', 'user_id': 'fake', + 'project_id': 'fake'} + group = db.instance_group_create(ctxt, values, + policies=None, members=[uuid]) + self.assertEqual([uuid], + db.instance_group_members_get(ctxt, + group['uuid'])) + + db.instance_destroy(ctxt, uuid) + self.assertEqual([], + db.instance_group_members_get(ctxt, + group['uuid'])) + def test_instance_update_and_get_original(self): instance = self.create_instance_with_args(vm_state='building') (old_ref, new_ref) = db.instance_update_and_get_original(self.ctxt, diff --git a/nova/tests/unit/network/test_network_info.py b/nova/tests/unit/network/test_network_info.py index d6f60eff28..ce7d37da74 100644 --- a/nova/tests/unit/network/test_network_info.py +++ b/nova/tests/unit/network/test_network_info.py @@ -865,7 +865,7 @@ class TestNetworkMetadata(test.NoDBTestCase): self.netinfo[0]['network']['subnets'][0] = ipv4_subnet self.netinfo[0]['network']['subnets'][1] = ipv6_subnet - self.netinfo[0]['network']['mtu'] = 1500 + self.netinfo[0]['network']['meta']['mtu'] = 1500 def test_get_network_metadata_json(self): @@ -1141,7 +1141,7 @@ class TestNetworkMetadata(test.NoDBTestCase): '11111111-1111-1111-1111-111111111111') self.netinfo[1]['network']['subnets'][0] = ipv4_subnet - self.netinfo[1]['network']['mtu'] = 1500 + self.netinfo[1]['network']['meta']['mtu'] = 1500 network_json = netutils.get_network_metadata(self.netinfo) self.assertEqual(expected_json, network_json) diff --git a/nova/tests/unit/network/test_neutronv2.py b/nova/tests/unit/network/test_neutronv2.py index 43b1aa9964..8c835ec68e 100644 --- a/nova/tests/unit/network/test_neutronv2.py +++ b/nova/tests/unit/network/test_neutronv2.py @@ -45,6 +45,7 @@ from nova.pci import whitelist as pci_whitelist from nova import policy from nova import test from nova.tests.unit import fake_instance +from nova.tests import uuidsentinel as uuids CONF = cfg.CONF @@ -1400,7 +1401,7 @@ class TestNeutronv2(TestNeutronv2Base): for net, fip, port, request_id in requested_networks: self.moxed_client.update_port(port) for port in ports: - self.moxed_client.delete_port(port) + self.moxed_client.delete_port(port).InAnyOrder("delete_port_group") self.mox.StubOutWithMock(api.db, 'instance_info_cache_update') api.db.instance_info_cache_update(self.context, @@ -3803,6 +3804,20 @@ class TestNeutronv2WithMock(test.TestCase): self.api.get_floating_ips_by_project, self.context) + def test_unbind_ports_reset_dns_name(self): + neutron = mock.Mock() + port_client = mock.Mock() + with mock.patch.object(self.api, '_has_port_binding_extension', + return_value=False): + self.api.extensions = [constants.DNS_INTEGRATION] + ports = [uuids.port_id] + self.api._unbind_ports(self.context, ports, neutron, port_client) + port_req_body = {'port': {'device_id': '', + 'device_owner': '', + 'dns_name': ''}} + port_client.update_port.assert_called_once_with( + uuids.port_id, port_req_body) + class TestNeutronv2ModuleMethods(test.NoDBTestCase): diff --git a/nova/tests/unit/virt/ironic/test_driver.py b/nova/tests/unit/virt/ironic/test_driver.py index e2a6902bb7..7e7da56e4f 100644 --- a/nova/tests/unit/virt/ironic/test_driver.py +++ b/nova/tests/unit/virt/ironic/test_driver.py @@ -278,11 +278,11 @@ class IronicDriverTestCase(test.NoDBTestCase): else: props_dict = props expected_cpus = props['cpus'] - self.assertEqual(expected_cpus, result['vcpus']) + self.assertEqual(0, result['vcpus']) self.assertEqual(expected_cpus, result['vcpus_used']) - self.assertEqual(props_dict['memory_mb'], result['memory_mb']) + self.assertEqual(0, result['memory_mb']) self.assertEqual(props_dict['memory_mb'], result['memory_mb_used']) - self.assertEqual(props_dict['local_gb'], result['local_gb']) + self.assertEqual(0, result['local_gb']) self.assertEqual(props_dict['local_gb'], result['local_gb_used']) self.assertEqual(node_uuid, result['hypervisor_hostname']) @@ -397,11 +397,11 @@ class IronicDriverTestCase(test.NoDBTestCase): instance_info=instance_info) result = self.driver._node_resource(node) - self.assertEqual(instance_info['vcpus'], result['vcpus']) + self.assertEqual(0, result['vcpus']) self.assertEqual(instance_info['vcpus'], result['vcpus_used']) - self.assertEqual(instance_info['memory_mb'], result['memory_mb']) + self.assertEqual(0, result['memory_mb']) self.assertEqual(instance_info['memory_mb'], result['memory_mb_used']) - self.assertEqual(instance_info['local_gb'], result['local_gb']) + self.assertEqual(0, result['local_gb']) self.assertEqual(instance_info['local_gb'], result['local_gb_used']) self.assertEqual(node_uuid, result['hypervisor_hostname']) self.assertEqual(stats, result['stats']) @@ -659,14 +659,20 @@ class IronicDriverTestCase(test.NoDBTestCase): # a node in deleted {'uuid': uuidutils.generate_uuid(), 'power_state': ironic_states.POWER_ON, - 'provision_state': ironic_states.DELETED} + 'provision_state': ironic_states.DELETED}, + # a node in AVAILABLE with an instance uuid + {'uuid': uuidutils.generate_uuid(), + 'instance_uuid': uuidutils.generate_uuid(), + 'power_state': ironic_states.POWER_OFF, + 'provision_state': ironic_states.AVAILABLE} ] for n in node_dicts: node = ironic_utils.get_test_node(**n) self.assertTrue(self.driver._node_resources_unavailable(node)) for ok_state in (ironic_states.AVAILABLE, ironic_states.NOSTATE): - # these are both ok and should present as available + # these are both ok and should present as available as they + # have no instance_uuid avail_node = ironic_utils.get_test_node( power_state=ironic_states.POWER_OFF, provision_state=ok_state) diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 90e1d153a3..37646a18be 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -6362,6 +6362,12 @@ class LibvirtConnTestCase(test.NoDBTestCase): ret = conn._compare_cpu(None, None) self.assertIsNone(ret) + def test_compare_cpu_virt_type_qemu(self): + self.flags(virt_type='qemu', group='libvirt') + conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + ret = conn._compare_cpu(None, None) + self.assertIsNone(ret) + @mock.patch.object(host.Host, 'compare_cpu') @mock.patch.object(nova.virt.libvirt, 'config') def test_compare_cpu_invalid_cpuinfo_raises(self, mock_vconfig, @@ -13642,6 +13648,36 @@ class LibvirtConnTestCase(test.NoDBTestCase): self._test_get_guest_config_parallels_volume(vm_mode.EXE, 4) self._test_get_guest_config_parallels_volume(vm_mode.HVM, 6) + def test_get_guest_disk_config_rbd_older_config_drive_fall_back(self): + # New config drives are stored in rbd but existing instances have + # config drives in the old location under the instances path. + # Test that the driver falls back to 'raw' for config drive if it + # doesn't exist in rbd. + self.flags(images_type='rbd', group='libvirt') + drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + drvr.image_backend = mock.Mock() + mock_rbd_image = mock.Mock() + mock_raw_image = mock.Mock() + mock_raw_image.libvirt_info.return_value = mock.sentinel.diskconfig + drvr.image_backend.image.side_effect = [mock_rbd_image, + mock_raw_image] + mock_rbd_image.check_image_exists.return_value = False + instance = objects.Instance() + disk_mapping = {'disk.config': {'bus': 'ide', + 'dev': 'hdd', + 'type': 'file'}} + flavor = objects.Flavor(extra_specs={}) + + diskconfig = drvr._get_guest_disk_config( + instance, 'disk.config', disk_mapping, flavor, + drvr._get_disk_config_image_type()) + + self.assertEqual(2, drvr.image_backend.image.call_count) + call1 = mock.call(instance, 'disk.config', 'rbd') + call2 = mock.call(instance, 'disk.config', 'raw') + drvr.image_backend.image.assert_has_calls([call1, call2]) + self.assertEqual(mock.sentinel.diskconfig, diskconfig) + def _test_prepare_domain_for_snapshot(self, live_snapshot, state): drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) instance_ref = objects.Instance(**self.test_instance) @@ -14585,6 +14621,9 @@ class LibvirtDriverTestCase(test.NoDBTestCase): imagebackend.Backend.image(mox.IgnoreArg(), 'disk').AndReturn( fake_imagebackend.Raw()) + self.mox.StubOutWithMock(fake_imagebackend.Raw, 'check_image_exists') + fake_imagebackend.Raw.check_image_exists().AndReturn(True) + self.mox.ReplayAll() self.drvr.finish_revert_migration(context, instance, []) @@ -14661,6 +14700,24 @@ class LibvirtDriverTestCase(test.NoDBTestCase): drvr.image_backend.remove_snap.assert_called_once_with( libvirt_utils.RESIZE_SNAPSHOT_NAME, ignore_errors=True) + def test_finish_revert_migration_snap_backend_image_does_not_exist(self): + drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + drvr.image_backend = mock.Mock() + drvr.image_backend.image.return_value = drvr.image_backend + drvr.image_backend.check_image_exists.return_value = False + ins_ref = self._create_instance() + + with test.nested( + mock.patch.object(rbd_utils, 'RBDDriver'), + mock.patch.object(utils, 'get_image_from_system_metadata'), + mock.patch.object(drvr, '_create_domain_and_network'), + mock.patch.object(drvr, '_get_guest_xml')) as ( + mock_rbd, mock_image, mock_cdn, mock_ggx): + mock_image.return_value = {'disk_format': 'raw'} + drvr.finish_revert_migration('', ins_ref, None, power_on=False) + self.assertFalse(drvr.image_backend.rollback_to_snap.called) + self.assertFalse(drvr.image_backend.remove_snap.called) + def test_cleanup_failed_migration(self): self.mox.StubOutWithMock(shutil, 'rmtree') shutil.rmtree('/fake/inst') @@ -14698,6 +14755,9 @@ class LibvirtDriverTestCase(test.NoDBTestCase): imagebackend.Backend.image(ins_ref, 'disk').AndReturn( fake_imagebackend.Raw()) + self.mox.StubOutWithMock(fake_imagebackend.Raw, 'check_image_exists') + fake_imagebackend.Raw.check_image_exists().AndReturn(True) + self.mox.ReplayAll() self.drvr._cleanup_resize(ins_ref, _fake_network_info(self, 1)) @@ -14738,6 +14798,9 @@ class LibvirtDriverTestCase(test.NoDBTestCase): imagebackend.Backend.image(ins_ref, 'disk').AndReturn( fake_imagebackend.Raw()) + self.mox.StubOutWithMock(fake_imagebackend.Raw, 'check_image_exists') + fake_imagebackend.Raw.check_image_exists().AndReturn(True) + self.mox.ReplayAll() self.drvr._cleanup_resize(ins_ref, _fake_network_info(self, 1)) @@ -14765,6 +14828,29 @@ class LibvirtDriverTestCase(test.NoDBTestCase): mock_remove.assert_called_once_with( libvirt_utils.RESIZE_SNAPSHOT_NAME, ignore_errors=True) + def test_cleanup_resize_snap_backend_image_does_not_exist(self): + CONF.set_override('policy_dirs', [], group='oslo_policy') + ins_ref = self._create_instance({'host': CONF.host}) + drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + drvr.image_backend = mock.Mock() + drvr.image_backend.image.return_value = drvr.image_backend + drvr.image_backend.check_image_exists.return_value = False + + with test.nested( + mock.patch.object(os.path, 'exists'), + mock.patch.object(libvirt_utils, 'get_instance_path'), + mock.patch.object(utils, 'execute'), + mock.patch.object(drvr.image_backend, 'remove_snap')) as ( + mock_exists, mock_get_path, mock_exec, mock_remove): + mock_exists.return_value = True + mock_get_path.return_value = '/fake/inst' + + drvr._cleanup_resize(ins_ref, _fake_network_info(self, 1)) + mock_get_path.assert_called_once_with(ins_ref, forceold=True) + mock_exec.assert_called_once_with('rm', '-rf', '/fake/inst_resize', + delay_on_retry=True, attempts=5) + self.assertFalse(mock_remove.called) + def test_get_instance_disk_info_exception(self): instance = self._create_instance() @@ -15132,10 +15218,12 @@ class LibvirtDriverTestCase(test.NoDBTestCase): mock_get_domain.return_value = fake_dom mock_load_file.return_value = "fake_unrescue_xml" unrescue_xml_path = os.path.join('/path', 'unrescue.xml') + xml_path = os.path.join('/path', 'libvirt.xml') rescue_file = os.path.join('/path', 'rescue.file') drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) with test.nested( + mock.patch.object(libvirt_utils, 'write_to_file'), mock.patch.object(drvr, '_destroy'), mock.patch.object(drvr, '_create_domain'), mock.patch.object(libvirt_utils, 'file_delete'), @@ -15143,9 +15231,10 @@ class LibvirtDriverTestCase(test.NoDBTestCase): return_value=['lvm.rescue']), mock.patch.object(lvm, 'remove_volumes'), mock.patch.object(glob, 'iglob', return_value=[rescue_file]) - ) as (mock_destroy, mock_create, mock_del, mock_lvm_disks, - mock_remove_volumes, mock_glob): + ) as (mock_write, mock_destroy, mock_create, mock_del, + mock_lvm_disks, mock_remove_volumes, mock_glob): drvr.unrescue(instance, None) + mock_write.assert_called_once_with(xml_path, "fake_unrescue_xml") mock_destroy.assert_called_once_with(instance) mock_create.assert_called_once_with("fake_unrescue_xml", fake_dom) diff --git a/nova/virt/ironic/driver.py b/nova/virt/ironic/driver.py index 9cbf4d7064..3764fa9204 100644 --- a/nova/virt/ironic/driver.py +++ b/nova/virt/ironic/driver.py @@ -184,7 +184,9 @@ class IronicDriver(virt_driver.ComputeDriver): ironic_states.AVAILABLE, ironic_states.NOSTATE] return (node_obj.maintenance or node_obj.power_state in bad_power_states or - node_obj.provision_state not in good_provision_states) + node_obj.provision_state not in good_provision_states or + (node_obj.provision_state in good_provision_states and + node_obj.instance_uuid is not None)) def _node_resources_used(self, node_obj): """Determine whether the node's resources are currently used. @@ -310,7 +312,11 @@ class IronicDriver(virt_driver.ComputeDriver): vcpus_used = vcpus = instance_info['vcpus'] memory_mb_used = memory_mb = instance_info['memory_mb'] local_gb_used = local_gb = instance_info['local_gb'] - elif self._node_resources_unavailable(node): + + # Always checking allows us to catch the case where Nova thinks there + # are available resources on the Node, but Ironic does not (because it + # is not in a usable state): https://launchpad.net/bugs/1503453 + if self._node_resources_unavailable(node): # The node's current state is such that it should not present any # of its resources to Nova vcpus = 0 diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 3a4a10796c..29aabc93fc 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -1254,8 +1254,9 @@ class LibvirtDriver(driver.ComputeDriver): # reasonably assumed that no such instances exist in the wild # anymore, it should be set back to False (the default) so it will # throw errors, like it should. - backend.remove_snap(libvirt_utils.RESIZE_SNAPSHOT_NAME, - ignore_errors=True) + if backend.check_image_exists(): + backend.remove_snap(libvirt_utils.RESIZE_SNAPSHOT_NAME, + ignore_errors=True) if instance.host != CONF.host: self._undefine_domain(instance) @@ -2734,7 +2735,9 @@ class LibvirtDriver(driver.ComputeDriver): """ instance_dir = libvirt_utils.get_instance_path(instance) unrescue_xml_path = os.path.join(instance_dir, 'unrescue.xml') + xml_path = os.path.join(instance_dir, 'libvirt.xml') xml = libvirt_utils.load_file(unrescue_xml_path) + libvirt_utils.write_to_file(xml_path, xml) guest = self._host.get_guest(instance) # TODO(sahid): We are converting all calls from a @@ -3559,6 +3562,15 @@ class LibvirtDriver(driver.ComputeDriver): image = self.image_backend.image(instance, name, image_type) + if (name == 'disk.config' and image_type == 'rbd' and + not image.check_image_exists()): + # This is likely an older config drive that has not been migrated + # to rbd yet. Try to fall back on 'raw' image type. + # TODO(melwitt): Add online migration of some sort so we can + # remove this fall back once we know all config drives are in rbd. + image = self.image_backend.image(instance, name, 'raw') + LOG.debug('Config drive not found in RBD, falling back to the ' + 'instance directory', instance=instance) disk_info = disk_mapping[name] return image.libvirt_info(disk_info['bus'], disk_info['dev'], @@ -5666,8 +5678,13 @@ class LibvirtDriver(driver.ComputeDriver): raise exception. """ - # NOTE(berendt): virConnectCompareCPU not working for Xen - if CONF.libvirt.virt_type not in ['qemu', 'kvm']: + # NOTE(kchamart): Comparing host to guest CPU model for emulated + # guests (<domain type='qemu'>) should not matter -- in this + # mode (QEMU "TCG") the CPU is fully emulated in software and no + # hardware acceleration, like KVM, is involved. So, skip the CPU + # compatibility check for the QEMU domain type, and retain it for + # KVM guests. + if CONF.libvirt.virt_type not in ['kvm']: return if guest_cpu is None: @@ -7457,14 +7474,15 @@ class LibvirtDriver(driver.ComputeDriver): # anymore, the try/except/finally should be removed, # and ignore_errors should be set back to False (the default) so # that problems throw errors, like they should. - try: - backend.rollback_to_snap(libvirt_utils.RESIZE_SNAPSHOT_NAME) - except exception.SnapshotNotFound: - LOG.warning(_LW("Failed to rollback snapshot (%s)"), - libvirt_utils.RESIZE_SNAPSHOT_NAME) - finally: - backend.remove_snap(libvirt_utils.RESIZE_SNAPSHOT_NAME, - ignore_errors=True) + if backend.check_image_exists(): + try: + backend.rollback_to_snap(libvirt_utils.RESIZE_SNAPSHOT_NAME) + except exception.SnapshotNotFound: + LOG.warning(_LW("Failed to rollback snapshot (%s)"), + libvirt_utils.RESIZE_SNAPSHOT_NAME) + finally: + backend.remove_snap(libvirt_utils.RESIZE_SNAPSHOT_NAME, + ignore_errors=True) disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type, instance, diff --git a/nova/virt/netutils.py b/nova/virt/netutils.py index 6b64a5b181..38ae90cf99 100644 --- a/nova/virt/netutils.py +++ b/nova/virt/netutils.py @@ -258,7 +258,7 @@ def _get_eth_link(vif, ifc_num): 'id': link_id, 'vif_id': vif['id'], 'type': nic_type, - 'mtu': vif['network'].get('mtu'), + 'mtu': vif['network']['meta'].get('mtu'), 'ethernet_mac_address': vif.get('address'), } return link diff --git a/requirements.txt b/requirements.txt index c03c8fecee..98c16af0fb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,9 +10,10 @@ eventlet!=0.18.3,>=0.18.2 # MIT Jinja2>=2.8 # BSD License (3 clause) keystonemiddleware!=4.1.0,>=4.0.0 # Apache-2.0 lxml>=2.3 # BSD -Routes!=2.0,!=2.1,>=1.12.3;python_version=='2.7' # MIT -Routes!=2.0,>=1.12.3;python_version!='2.7' # MIT -cryptography>=1.0 # BSD/Apache-2.0 +Routes!=2.0,!=2.1,!=2.3.0,>=1.12.3;python_version=='2.7' # MIT +Routes!=2.0,!=2.3.0,>=1.12.3;python_version!='2.7' # MIT +cryptography!=1.3.0,>=1.0 # BSD/Apache-2.0 +pycrypto>=2.6 # Public Domain WebOb>=1.2.3 # MIT greenlet>=0.3.2 # MIT PasteDeploy>=1.5.0 # MIT @@ -22,7 +23,7 @@ sqlalchemy-migrate>=0.9.6 # Apache-2.0 netaddr!=0.7.16,>=0.7.12 # BSD netifaces>=0.10.4 # MIT paramiko>=1.16.0 # LGPL -Babel>=1.3 # BSD +Babel!=2.3.0,!=2.3.1,!=2.3.2,!=2.3.3,>=1.3 # BSD iso8601>=0.1.9 # MIT jsonschema!=2.5.0,<3.0.0,>=2.0.0 # MIT python-cinderclient>=1.3.1 # Apache-2.0 |