Merge branch 'master' into feature/crypto

Conflicts:
	swift/obj/server.py
	test/probe/test_object_async_update.py
	test/unit/obj/test_server.py

Change-Id: Ifeba1cfe8c4244eff069ab10b2c77f8ea5e2a39b
This commit is contained in:
Alistair Coles 2016-06-06 15:51:52 +01:00
commit ce0e16bcc5
28 changed files with 401 additions and 2079 deletions

View File

@ -134,6 +134,7 @@ Usage: %%prog [options] [conf_file]
retries = int(conf.get('retries', 5))
concurrency = int(conf.get('concurrency', 25))
endpoint_type = str(conf.get('endpoint_type', 'publicURL'))
region_name = str(conf.get('region_name', ''))
user_domain_name = str(conf.get('user_domain_name', ''))
project_domain_name = str(conf.get('project_domain_name', ''))
project_name = str(conf.get('project_name', ''))
@ -157,6 +158,8 @@ Usage: %%prog [options] [conf_file]
os_options['project_domain_name'] = project_domain_name
if project_name:
os_options['project_name'] = project_name
if region_name:
os_options['region_name'] = region_name
url, token = get_auth(conf['auth_url'], conf['auth_user'],
conf['auth_key'],

View File

@ -353,6 +353,7 @@ Usage: %%prog [options] [conf_file]
retries = int(conf.get('retries', 5))
concurrency = int(conf.get('concurrency', 25))
endpoint_type = str(conf.get('endpoint_type', 'publicURL'))
region_name = str(conf.get('region_name', ''))
if options.dump_json or config_true_value(conf.get('dump_json', 'no')):
json_output = True
container_report = config_true_value(conf.get('container_report', 'yes')) \
@ -378,6 +379,8 @@ Usage: %%prog [options] [conf_file]
os_options['project_domain_name'] = project_domain_name
if project_name:
os_options['project_name'] = project_name
if region_name:
os_options['region_name'] = region_name
url, token = get_auth(conf['auth_url'], conf['auth_user'],
conf['auth_key'],

View File

@ -425,7 +425,7 @@ cluster: region 1 in San Francisco (SF), and region 2 in New York
read_affinity
~~~~~~~~~~~~~
This setting makes the proxy server prefer local backend servers for
This setting, combined with sorting_method setting, makes the proxy server prefer local backend servers for
GET and HEAD requests over non-local ones. For example, it is
preferable for an SF proxy server to service object GET requests
by talking to SF object servers, as the client will receive lower
@ -440,6 +440,7 @@ This is where the read_affinity setting comes in.
Example::
[app:proxy-server]
sorting_method = affinity
read_affinity = r1=100
This will make the proxy attempt to service GET and HEAD requests from
@ -451,6 +452,7 @@ fall back to backend servers in other regions.
Example::
[app:proxy-server]
sorting_method = affinity
read_affinity = r1z1=100, r1=200
This will make the proxy attempt to service GET and HEAD requests from

View File

@ -109,8 +109,8 @@ Other
* `Better Staticweb <https://github.com/CloudVPS/better-staticweb>`_ - Makes swift containers accessible by default.
* `Django Swiftbrowser <https://github.com/cschwede/django-swiftbrowser>`_ - Simple Django web app to access OpenStack Swift.
* `Swift-account-stats <https://github.com/enovance/swift-account-stats>`_ - Swift-account-stats is a tool to report statistics on Swift usage at tenant and global levels.
* `PyECLib <https://bitbucket.org/kmgreen2/pyeclib>`_ - High Level Erasure Code library used by Swift
* `liberasurecode <http://www.bytebucket.org/tsg-/liberasurecode>`_ - Low Level Erasure Code library used by PyECLib
* `PyECLib <https://github.com/openstack/pyeclib>`_ - High Level Erasure Code library used by Swift
* `liberasurecode <https://github.com/openstack/liberasurecode>`_ - Low Level Erasure Code library used by PyECLib
* `Swift Browser <https://github.com/zerovm/swift-browser>`_ - JavaScript interface for Swift
* `swift-ui <https://github.com/fanatic/swift-ui>`_ - OpenStack Swift web browser
* `Swift Durability Calculator <https://github.com/enovance/swift-durability-calculator>`_ - Data Durability Calculation Tool for Swift

View File

@ -96,7 +96,7 @@ advantage of many well-known C libraries such as:
PyECLib uses a C based library called liberasurecode to implement the plug in
infrastructure; liberasure code is available at:
* liberasurecode: https://bitbucket.org/tsg-/liberasurecode
* liberasurecode: https://github.com/openstack/liberasurecode
PyECLib itself therefore allows for not only choice but further extensibility as
well. PyECLib also comes with a handy utility to help determine the best
@ -105,7 +105,7 @@ configurations may vary in performance per algorithm). More on this will be
covered in the configuration section. PyECLib is included as a Swift
requirement.
For complete details see `PyECLib <https://bitbucket.org/kmgreen2/pyeclib>`_
For complete details see `PyECLib <https://github.com/openstack/pyeclib>`_
------------------------------
Storing and Retrieving Objects
@ -215,7 +215,7 @@ Let's take a closer look at each configuration parameter:
PyECLib back-end. This specifies the EC scheme that is to be used. For
example the option shown here selects Vandermonde Reed-Solomon encoding while
an option of ``flat_xor_hd_3`` would select Flat-XOR based HD combination
codes. See the `PyECLib <https://bitbucket.org/kmgreen2/pyeclib>`_ page for
codes. See the `PyECLib <https://github.com/openstack/pyeclib>`_ page for
full details.
* ``ec_num_data_fragments``: The total number of fragments that will be
comprised of data.
@ -270,7 +270,7 @@ Region Support
--------------
For at least the initial version of EC, it is not recommended that an EC scheme
span beyond a single region, neither performance nor functional validation has
span beyond a single region, neither performance nor functional validation has
be been done in such a configuration.
--------------

View File

@ -24,6 +24,10 @@ auth_key = testing
# user_domain_name = user_domain
#
# endpoint_type = publicURL
#
# NOTE: If you have only 1 region with a swift endpoint, no need to specify it
# region_name =
#
# keystone_api_insecure = no
#
# swift_dir = /etc/swift

View File

@ -163,7 +163,7 @@ __all__ = ['TempURL', 'filter_factory',
from os.path import basename
from time import time
from time import time, strftime, gmtime
from six.moves.urllib.parse import parse_qs
from six.moves.urllib.parse import urlencode
@ -425,6 +425,11 @@ class TempURL(object):
# newline into existing_disposition
value = disposition_value.replace('\n', '%0A')
out_headers.append(('Content-Disposition', value))
# include Expires header for better cache-control
out_headers.append(('Expires', strftime(
"%a, %d %b %Y %H:%M:%S GMT",
gmtime(temp_url_expires))))
headers = out_headers
return start_response(status, headers, exc_info)

View File

@ -9,14 +9,14 @@
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
msgid ""
msgstr ""
"Project-Id-Version: swift 2.7.1.dev50\n"
"Project-Id-Version: swift 2.7.1.dev175\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2016-04-17 21:20+0000\n"
"POT-Creation-Date: 2016-06-03 04:47+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-24 03:15+0000\n"
"Last-Translator: Monika Wolf <vcomas3@de.ibm.com>\n"
"PO-Revision-Date: 2016-06-02 07:02+0000\n"
"Last-Translator: Andreas Jaeger <jaegerandi@gmail.com>\n"
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Generated-By: Babel 2.0\n"
@ -71,6 +71,10 @@ msgstr ""
"%(replicated)d/%(total)d (%(percentage).2f%%) Partitionen repliziert in "
"%(time).2fs (%(rate).2f/s, %(remaining)s verbleibend)"
#, python-format
msgid "%(server)s (%(pid)s) appears to have stopped"
msgstr "%(server)s (%(pid)s) scheinbar gestoppt"
#, python-format
msgid "%(success)s successes, %(failure)s failures"
msgstr "%(success)s Erfolge, %(failure)s Fehlschläge"
@ -79,6 +83,10 @@ msgstr "%(success)s Erfolge, %(failure)s Fehlschläge"
msgid "%(type)s returning 503 for %(statuses)s"
msgstr "%(type)s gab 503 für %(statuses)s zurück"
#, python-format
msgid "%(type)s: %(value)s"
msgstr "%(type)s: %(value)s"
#, python-format
msgid "%s already started..."
msgstr "%s bereits gestartet..."
@ -133,6 +141,10 @@ msgstr ", Rückgabecodes: "
msgid "Account"
msgstr "Konto"
#, python-format
msgid "Account %(account)s has not been reaped since %(time)s"
msgstr "Konto %(account)s wurde nicht aufgeräumt seit %(time)s"
#, python-format
msgid "Account audit \"once\" mode completed: %.02fs"
msgstr "Kontoprüfungsmodus \"once\" abgeschlossen: %.02fs"
@ -148,6 +160,10 @@ msgstr ""
"Versuch, %(count)d Datenbanken in %(time).5f Sekunden zu replizieren "
"(%(rate).5f/s)"
#, python-format
msgid "Audit Failed for %(path)s: %(err)s"
msgstr "Prüfung fehlgeschlagen für %(path)s: %(err)s"
#, python-format
msgid "Bad rsync return code: %(ret)d <- %(args)s"
msgstr "Falscher rsync-Rückgabecode: %(ret)d <- %(args)s"
@ -199,6 +215,14 @@ msgstr "Kann nicht auf die Datei %s zugreifen."
msgid "Can not load profile data from %s."
msgstr "Die Profildaten von %s können nicht geladen werden."
#, python-format
msgid "Cannot read %(auditor_status)s (%(err)s)"
msgstr "%(auditor_status)s (%(err)s) kann nicht gelesen werden."
#, python-format
msgid "Cannot write %(auditor_status)s (%(err)s)"
msgstr "Schreiben von %(auditor_status)s (%(err)s) nicht möglich."
#, python-format
msgid "Client did not read from proxy within %ss"
msgstr "Client konnte nicht innerhalb von %ss vom Proxy lesen"
@ -273,12 +297,15 @@ msgstr ""
"Änderungen"
#, python-format
msgid "Could not bind to %s:%s after trying for %s seconds"
msgstr "Keine Bindung an %s:%s möglich nach Versuch über %s Sekunden"
msgid ""
"Could not bind to %(addr)s:%(port)s after trying for %(timeout)s seconds"
msgstr ""
"Keine Bindung an %(addr)s:%(port)s möglich nach Versuch über %(timeout)s "
"Sekunden"
#, python-format
msgid "Could not load %r: %s"
msgstr "Konnte %r nicht laden: %s"
msgid "Could not load %(conf)r: %(error)s"
msgstr "%(conf)r konnte nicht geladen werden: %(error)s"
#, python-format
msgid "Data download error: %s"
@ -289,9 +316,10 @@ msgid "Devices pass completed: %.02fs"
msgstr "Gerätedurchgang abgeschlossen: %.02fs"
#, python-format
msgid "Directory %r does not map to a valid policy (%s)"
msgid "Directory %(directory)r does not map to a valid policy (%(error)s)"
msgstr ""
"Das Verzeichnis %r kann keiner gültigen Richtlinie (%s) zugeordnet werden."
"Das Verzeichnis %(directory)r kann keiner gültigen Richtlinie (%(error)s) "
"zugeordnet werden."
#, python-format
msgid "ERROR %(db_file)s: %(validate_sync_to_err)s"
@ -325,10 +353,10 @@ msgstr ""
#, python-format
msgid ""
"ERROR Account update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
"request: \"%(hosts)s\" vs \"%(devices)s\""
msgstr ""
"FEHLER Kontoaktualisierung fehlgeschlagen: Unterschiedliche Anzahl von Hosts "
"und Einheiten in der Anforderung: \"%s\" contra \"%s\""
"und Einheiten in der Anforderung: \"%(hosts)s\" contra \"%(devices)s\""
#, python-format
msgid "ERROR Bad response %(status)s from %(host)s"
@ -347,14 +375,6 @@ msgstr ""
"Aktualisierung zu einem späteren Zeitpunkt gespeichert): %(status)d Antwort "
"von %(ip)s:%(port)s/%(dev)s"
#, python-format
msgid ""
"ERROR Container update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"FEHLER Containeraktualisierung fehlgeschlagen: Unterschiedliche Anzahl von "
"Hosts und Einheiten in der Anforderung: \"%s\" contra \"%s\""
#, python-format
msgid "ERROR Could not get account info %s"
msgstr "FEHLER Kontoinfo %s konnte nicht abgerufen werden"
@ -514,8 +534,8 @@ msgid "Error hashing suffix"
msgstr "Fehler beim Hashing des Suffix"
#, python-format
msgid "Error in %r with mtime_check_interval: %s"
msgstr "Fehler in %r mit mtime_check_interval: %s"
msgid "Error in %(conf)r with mtime_check_interval: %(error)s"
msgstr "Fehler in %(conf)r mit mtime_check_interval: %(error)s"
#, python-format
msgid "Error limiting server %s"
@ -656,6 +676,10 @@ msgstr ""
msgid "Killing long-running rsync: %s"
msgstr "Lange laufendes rsync wird gekillt: %s"
#, python-format
msgid "Loading JSON from %(auditor_status)s failed (%(err)s)"
msgstr "Laden von JSON aus %(auditor_status)s fehlgeschlagen: (%(err)s)"
msgid "Lockup detected.. killing live coros."
msgstr "Suche erkannt. Live-Coros werden gelöscht."
@ -668,8 +692,8 @@ msgid "No %s running"
msgstr "Kein %s läuft"
#, python-format
msgid "No cluster endpoint for %r %r"
msgstr "Kein Cluster-Endpunkt für %r %r"
msgid "No cluster endpoint for %(realm)r %(cluster)r"
msgstr "Kein Cluster-Endpunkt für %(realm)r %(cluster)r"
#, python-format
msgid "No permission to signal PID %d"
@ -683,6 +707,10 @@ msgstr "Keine Richtlinie mit Index %s"
msgid "No realm key for %r"
msgstr "Kein Bereichsschlüssel für %r"
#, python-format
msgid "No space left on device for %(file)s (%(err)s)"
msgstr "Kein freier Speicherplatz im Gerät für %(file)s (%(err)s) vorhanden."
#, python-format
msgid "Node error limited %(ip)s:%(port)s (%(device)s)"
msgstr "Knotenfehler begrenzt %(ip)s:%(port)s (%(device)s)"
@ -800,21 +828,13 @@ msgid "Partition times: max %(max).4fs, min %(min).4fs, med %(med).4fs"
msgstr ""
"Partitionszeiten: max. %(max).4fs, min. %(min).4fs, durchschnittl. %(med).4fs"
#, python-format
msgid "Pass beginning; %s possible containers; %s possible objects"
msgstr "Durchlauf wird gestartet; %s mögliche Container; %s mögliche Objekte"
#, python-format
msgid "Pass completed in %ds; %d objects expired"
msgstr "Durchgang abgeschlossen in %ds; %d Objekte abgelaufen"
#, python-format
msgid "Pass so far %ds; %d objects expired"
msgstr "Bisherige Durchgänge %ds; %d Objekte abgelaufen"
msgid "Path required in X-Container-Sync-To"
msgstr "Pfad in X-Container-Sync-To ist erforderlich"
#, python-format
msgid "Problem cleaning up %(datadir)s (%(err)s)"
msgstr "Problem bei der Bereinigung von %(datadir)s (%(err)s)"
#, python-format
msgid "Problem cleaning up %s"
msgstr "Problem bei der Bereinigung von %s"
@ -903,6 +923,10 @@ msgstr "Objektrekonstruktor läuft im Skriptmodus."
msgid "Running object replicator in script mode."
msgstr "Objektreplikator läuft im Skriptmodus."
#, python-format
msgid "Signal %(server)s pid: %(pid)s signal: %(signal)s"
msgstr "Signal %(server)s PID: %(pid)s Signal: %(signal)s"
#, python-format
msgid ""
"Since %(time)s: %(sync)s synced [%(delete)s deletes, %(put)s puts], %(skip)s "
@ -1007,9 +1031,15 @@ msgid "UNCAUGHT EXCEPTION"
msgstr "NICHT ABGEFANGENE AUSNAHME"
#, python-format
msgid "Unable to load internal client from config: %r (%s)"
msgid "Unable to find %(section)s config section in %(conf)s"
msgstr ""
"Interner Client konnte nicht aus der Konfiguration geladen werden: %r (%s)"
"%(section)s-Konfigurationsabschnitt in %(conf)s kann nicht gefunden werden"
#, python-format
msgid "Unable to load internal client from config: %(conf)r (%(error)s)"
msgstr ""
"Interner Client konnte nicht aus der Konfiguration geladen werden: %(conf)r "
"(%(error)s)"
#, python-format
msgid "Unable to locate %s in libc. Leaving as a no-op."
@ -1020,12 +1050,20 @@ msgstr ""
msgid "Unable to locate config for %s"
msgstr "Konfiguration für %s wurde nicht gefunden."
#, python-format
msgid "Unable to locate config number %(number)s for %(server)s"
msgstr "Konfigurationsnummer %(number)s für %(server)s wurde nicht gefunden."
msgid ""
"Unable to locate fallocate, posix_fallocate in libc. Leaving as a no-op."
msgstr ""
"fallocate, posix_fallocate konnte nicht in libc gefunden werden. Wird als "
"Nullbefehl verlassen."
#, python-format
msgid "Unable to perform fsync() on directory %(dir)s: %(err)s"
msgstr "fsync() kann für Verzeichnis %(dir)s nicht ausgeführt werden: %(err)s"
#, python-format
msgid "Unable to read config from %s"
msgstr "Konfiguration aus %s kann nicht gelesen werden"
@ -1076,6 +1114,17 @@ msgstr ""
"WARNUNG: Grenzwert für Speicher kann nicht geändert werden. Wird nicht als "
"Root ausgeführt?"
#, python-format
msgid "Waited %(kill_wait)s seconds for %(server)s to die; giving up"
msgstr ""
"Hat %(kill_wait)s Sekunden für %(server)s zum Erlöschen gewartet; Gibt auf"
#, python-format
msgid "Waited %(kill_wait)s seconds for %(server)s to die; killing"
msgstr ""
"Hat %(kill_wait)s Sekunden für %(server)s zum Erlöschen gewartet. Wird "
"abgebrochen."
msgid "Warning: Cannot ratelimit without a memcached client"
msgstr ""
"Warnung: Geschwindigkeitsbegrenzung kann nicht ohne memcached-Client "

View File

@ -6,9 +6,9 @@
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
msgid ""
msgstr ""
"Project-Id-Version: swift 2.7.1.dev50\n"
"Project-Id-Version: swift 2.7.1.dev169\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2016-04-17 21:20+0000\n"
"POT-Creation-Date: 2016-06-02 04:58+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -267,14 +267,6 @@ msgstr ""
"%(elapsed).02fs, %(success)s con éxito, %(fail)s fallos, %(no_change)s sin "
"cambios"
#, python-format
msgid "Could not bind to %s:%s after trying for %s seconds"
msgstr "No se puede enlazar a %s:%s después de intentar por %s segundos"
#, python-format
msgid "Could not load %r: %s"
msgstr "No se ha podido cargar %r: %s"
#, python-format
msgid "Data download error: %s"
msgstr "Error de descarga de datos: %s"
@ -283,10 +275,6 @@ msgstr "Error de descarga de datos: %s"
msgid "Devices pass completed: %.02fs"
msgstr "Paso de dispositivos finalizado: %.02fs"
#, python-format
msgid "Directory %r does not map to a valid policy (%s)"
msgstr "El directory %r no está correlacionado con una política válida (%s)"
#, python-format
msgid "ERROR %(db_file)s: %(validate_sync_to_err)s"
msgstr "ERROR %(db_file)s: %(validate_sync_to_err)s"
@ -317,14 +305,6 @@ msgstr ""
"ERROR La actualización de la cuenta ha fallado con %(ip)s:%(port)s/"
"%(device)s (se volverá a intentar más tarde): Respuesta %(status)s %(reason)s"
#, python-format
msgid ""
"ERROR Account update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"ERROR La actualización de la cuenta ha fallado: hay números distintos de "
"hosts y dispositivos en la solicitud: \"%s\" frente a \"%s\""
#, python-format
msgid "ERROR Bad response %(status)s from %(host)s"
msgstr "ERROR Respuesta errónea %(status)s desde %(host)s"
@ -342,14 +322,6 @@ msgstr ""
"actualización asíncrona posterior): %(status)d respuesta desde %(ip)s:"
"%(port)s/%(dev)s"
#, python-format
msgid ""
"ERROR Container update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"ERROR La actualización del contenedor ha fallado: hay números distintos de "
"hosts y dispositivos en la solicitud: \"%s\" frente a \"%s\""
#, python-format
msgid "ERROR Could not get account info %s"
msgstr "ERROR No se ha podido obtener la información de cuenta %s"
@ -508,10 +480,6 @@ msgstr "Error en la codificación a UTF-8: %s"
msgid "Error hashing suffix"
msgstr "Error en el hash del sufijo"
#, python-format
msgid "Error in %r with mtime_check_interval: %s"
msgstr "Error en %r con mtime_check_interval: %s"
#, python-format
msgid "Error limiting server %s"
msgstr "Error al limitar el servidor %s"
@ -662,10 +630,6 @@ msgstr "Se ha correlacionado %(given_domain)s con %(found_domain)s"
msgid "No %s running"
msgstr "Ningún %s en ejecución"
#, python-format
msgid "No cluster endpoint for %r %r"
msgstr "No hay punto final de clúster para %r %r"
#, python-format
msgid "No permission to signal PID %d"
msgstr "No hay permiso para señalar el PID %d"
@ -796,18 +760,6 @@ msgid "Partition times: max %(max).4fs, min %(min).4fs, med %(med).4fs"
msgstr ""
"Tiempos de partición: máximo %(max).4fs, mínimo %(min).4fs, medio %(med).4fs"
#, python-format
msgid "Pass beginning; %s possible containers; %s possible objects"
msgstr "Inicio del paso; %s posibles contenedores; %s posibles objetos"
#, python-format
msgid "Pass completed in %ds; %d objects expired"
msgstr "Paso completado en %ds; %d objetos caducados"
#, python-format
msgid "Pass so far %ds; %d objects expired"
msgstr "Paso hasta ahora %ds; %d objetos caducados"
msgid "Path required in X-Container-Sync-To"
msgstr "Vía de acceso necesaria en X-Container-Sync-To"
@ -1003,11 +955,6 @@ msgstr "Intentando escribir en %s"
msgid "UNCAUGHT EXCEPTION"
msgstr "UNCAUGHT EXCEPTION"
#, python-format
msgid "Unable to load internal client from config: %r (%s)"
msgstr ""
"No se puede cargar el cliente interno a partir de la configuración: %r (%s)"
#, python-format
msgid "Unable to locate %s in libc. Leaving as a no-op."
msgstr "No se ha podido localizar %s en libc. Se dejará como no operativo."

View File

@ -7,9 +7,9 @@
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
msgid ""
msgstr ""
"Project-Id-Version: swift 2.7.1.dev50\n"
"Project-Id-Version: swift 2.7.1.dev169\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2016-04-17 21:20+0000\n"
"POT-Creation-Date: 2016-06-02 04:58+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -270,14 +270,6 @@ msgstr ""
"%(elapsed).02fs, %(success)s succès, %(fail)s échec(s), %(no_change)s "
"inchangé(s)"
#, python-format
msgid "Could not bind to %s:%s after trying for %s seconds"
msgstr "Liaison impossible à %s:%s après une tentative de %s secondes"
#, python-format
msgid "Could not load %r: %s"
msgstr "Impossible de charger %r: %s"
#, python-format
msgid "Data download error: %s"
msgstr "Erreur de téléchargement des données: %s"
@ -286,10 +278,6 @@ msgstr "Erreur de téléchargement des données: %s"
msgid "Devices pass completed: %.02fs"
msgstr "Session d'audit d'unité terminée : %.02fs"
#, python-format
msgid "Directory %r does not map to a valid policy (%s)"
msgstr "Le répertoire %r n'est pas mappé à une stratégie valide (%s)"
#, python-format
msgid "ERROR %(db_file)s: %(validate_sync_to_err)s"
msgstr "ERREUR %(db_file)s : %(validate_sync_to_err)s"
@ -322,14 +310,6 @@ msgstr ""
"(une nouvelle tentative sera effectuée ultérieurement). Réponse %(status)s "
"%(reason)s"
#, python-format
msgid ""
"ERROR Account update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"ERREUR Echec de la mise à jour du compte. Le nombre d'hôtes et le nombre "
"d'unités diffèrent dans la demande : \"%s\" / \"%s\""
#, python-format
msgid "ERROR Bad response %(status)s from %(host)s"
msgstr "ERREUR Réponse incorrecte %(status)s de %(host)s"
@ -347,14 +327,6 @@ msgstr ""
"asynchrone ultérieure) : réponse %(status)d renvoyée par %(ip)s:%(port)s/"
"%(dev)s"
#, python-format
msgid ""
"ERROR Container update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"ERREUR Echec de la mise à jour du conteneur. Le nombre d'hôtes et le nombre "
"d'unités diffèrent dans la demande : \"%s\" / \"%s\""
#, python-format
msgid "ERROR Could not get account info %s"
msgstr "ERREUR Impossible d'obtenir les infos de compte %s"
@ -515,10 +487,6 @@ msgstr "Erreur encodage UTF-8: %s"
msgid "Error hashing suffix"
msgstr "Erreur suffixe hashing"
#, python-format
msgid "Error in %r with mtime_check_interval: %s"
msgstr "Erreur dans %r liée à mtime_check_interval : %s"
#, python-format
msgid "Error limiting server %s"
msgstr "Erreur limitation du serveur %s"
@ -671,10 +639,6 @@ msgstr "%(given_domain)s mappé avec %(found_domain)s"
msgid "No %s running"
msgstr "Non démarré %s"
#, python-format
msgid "No cluster endpoint for %r %r"
msgstr "Aucun noeud final de cluster pour %r %r"
#, python-format
msgid "No permission to signal PID %d"
msgstr "Aucun droit pour signaler le PID %d"
@ -812,18 +776,6 @@ msgstr ""
"Temps de partition : maximum %(max).4fs, minimum %(min).4fs, moyenne "
"%(med).4fs"
#, python-format
msgid "Pass beginning; %s possible containers; %s possible objects"
msgstr "Début de session. %s conteneur(s) possible(s). %s objet(s) possible(s)"
#, python-format
msgid "Pass completed in %ds; %d objects expired"
msgstr "Session terminée dans %ds. %d objet(s) arrivé(s) à expiration"
#, python-format
msgid "Pass so far %ds; %d objects expired"
msgstr "Session jusqu'à %ds. %d objet(s) arrivé(s) à expiration"
msgid "Path required in X-Container-Sync-To"
msgstr "Chemin requis dans X-Container-Sync-To"
@ -1020,11 +972,6 @@ msgstr "Tentative d'écriture sur %s"
msgid "UNCAUGHT EXCEPTION"
msgstr "EXCEPTION NON INTERCEPTEE"
#, python-format
msgid "Unable to load internal client from config: %r (%s)"
msgstr ""
"Impossible de charger le client interne depuis la configuration : %r (%s)"
#, python-format
msgid "Unable to locate %s in libc. Leaving as a no-op."
msgstr ""

View File

@ -6,9 +6,9 @@
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
msgid ""
msgstr ""
"Project-Id-Version: swift 2.7.1.dev50\n"
"Project-Id-Version: swift 2.7.1.dev169\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2016-04-17 21:20+0000\n"
"POT-Creation-Date: 2016-06-02 04:58+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -272,15 +272,6 @@ msgstr ""
"%(success)s operazioni con esito positivo, %(fail)s errori, %(no_change)s "
"senza modifiche"
#, python-format
msgid "Could not bind to %s:%s after trying for %s seconds"
msgstr ""
"Impossibile effettuare il bind a %s:%s dopo aver provato per %s secondi"
#, python-format
msgid "Could not load %r: %s"
msgstr "Impossibile caricare %r: %s"
#, python-format
msgid "Data download error: %s"
msgstr "Errore di download dei dati: %s"
@ -289,10 +280,6 @@ msgstr "Errore di download dei dati: %s"
msgid "Devices pass completed: %.02fs"
msgstr "Trasmissione dei dispositivi completata: %.02fs"
#, python-format
msgid "Directory %r does not map to a valid policy (%s)"
msgstr "La directory %r non è associata ad una politica valida (%s)"
#, python-format
msgid "ERROR %(db_file)s: %(validate_sync_to_err)s"
msgstr "ERRORE %(db_file)s: %(validate_sync_to_err)s"
@ -323,14 +310,6 @@ msgstr ""
"%(device)s (verrà eseguito un nuovo tentativo successivamente): Risposta "
"%(status)s %(reason)s"
#, python-format
msgid ""
"ERROR Account update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"ERRORE Aggiornamento dell'account non riuscito: numero differente di host e "
"dispositivi nella richiesta: \"%s\" vs \"%s\""
#, python-format
msgid "ERROR Bad response %(status)s from %(host)s"
msgstr "ERRORE Risposta errata %(status)s da %(host)s"
@ -348,14 +327,6 @@ msgstr ""
"l'aggiornamento asincrono successivamente): %(status)d risposta da %(ip)s:"
"%(port)s/%(dev)s"
#, python-format
msgid ""
"ERROR Container update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"ERRORE Aggiornamento del contenitore non riuscito: numero differente di host "
"e dispositivi nella richiesta: \"%s\" vs \"%s\""
#, python-format
msgid "ERROR Could not get account info %s"
msgstr "ERRORE Impossibile ottenere le informazioni sull'account %s"
@ -512,10 +483,6 @@ msgstr "Errore durante la codifica in UTF-8: %s"
msgid "Error hashing suffix"
msgstr "Errore durante l'hash del suffisso"
#, python-format
msgid "Error in %r with mtime_check_interval: %s"
msgstr "Errore in %r con mtime_check_interval: %s"
#, python-format
msgid "Error limiting server %s"
msgstr "Errore durante la limitazione del server %s"
@ -670,10 +637,6 @@ msgstr "%(given_domain)s associato a %(found_domain)s"
msgid "No %s running"
msgstr "Nessun %s in esecuzione"
#, python-format
msgid "No cluster endpoint for %r %r"
msgstr "Nessun endpoint del cluster per %r %r"
#, python-format
msgid "No permission to signal PID %d"
msgstr "Nessuna autorizzazione per la segnalazione del PID %d"
@ -799,19 +762,6 @@ msgstr "Parametri, query e frammenti non consentiti in X-Container-Sync-To"
msgid "Partition times: max %(max).4fs, min %(min).4fs, med %(med).4fs"
msgstr "Tempi partizione: max %(max).4fs, min %(min).4fs, med %(med).4fs"
#, python-format
msgid "Pass beginning; %s possible containers; %s possible objects"
msgstr ""
"Avvio della trasmissione; %s contenitori possibili; %s oggetti possibili"
#, python-format
msgid "Pass completed in %ds; %d objects expired"
msgstr "Trasmissione completata in %ds; %d oggetti scaduti"
#, python-format
msgid "Pass so far %ds; %d objects expired"
msgstr "Trasmissione eseguita fino ad ora %ds; %d oggetti scaduti"
msgid "Path required in X-Container-Sync-To"
msgstr "Percorso richiesto in X-Container-Sync-To"
@ -1009,10 +959,6 @@ msgstr "Tentativo di scrittura in %s"
msgid "UNCAUGHT EXCEPTION"
msgstr "ECCEZIONE NON RILEVATA"
#, python-format
msgid "Unable to load internal client from config: %r (%s)"
msgstr "Impossibile caricare il client interno dalla configurazione: %r (%s)"
#, python-format
msgid "Unable to locate %s in libc. Leaving as a no-op."
msgstr "Impossibile individuare %s in libc. Lasciato come no-op."

View File

@ -7,9 +7,9 @@
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
msgid ""
msgstr ""
"Project-Id-Version: swift 2.7.1.dev50\n"
"Project-Id-Version: swift 2.7.1.dev169\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2016-04-17 21:20+0000\n"
"POT-Creation-Date: 2016-06-02 04:58+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -262,14 +262,6 @@ msgstr ""
"%(path)s のコンテナー更新スイープが完了しました: %(elapsed).02fs、成功 "
"%(success)s、失敗 %(fail)s、未変更 %(no_change)s"
#, python-format
msgid "Could not bind to %s:%s after trying for %s seconds"
msgstr "%s 秒間の試行後に %s:%s にバインドできませんでした"
#, python-format
msgid "Could not load %r: %s"
msgstr "%r をロードできませんでした: %s"
#, python-format
msgid "Data download error: %s"
msgstr "データダウンロードエラー: %s"
@ -278,10 +270,6 @@ msgstr "データダウンロードエラー: %s"
msgid "Devices pass completed: %.02fs"
msgstr "デバイスの処理が完了しました: %.02fs"
#, python-format
msgid "Directory %r does not map to a valid policy (%s)"
msgstr "ディレクトリー %r は有効なポリシーにマップしていません (%s) "
#, python-format
msgid "ERROR %(db_file)s: %(validate_sync_to_err)s"
msgstr "エラー %(db_file)s: %(validate_sync_to_err)s"
@ -310,14 +298,6 @@ msgstr ""
"エラー: アカウント更新が %(ip)s:%(port)s/%(device)s で失敗しました(後で再試行"
"されます): 応答 %(status)s %(reason)s"
#, python-format
msgid ""
"ERROR Account update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"エラー: アカウント更新に失敗しました。要求内のホスト数およびデバイス数が異な"
"ります: 「%s」vs「%s」"
#, python-format
msgid "ERROR Bad response %(status)s from %(host)s"
msgstr "エラー: ホスト %(host)s からの応答 %(status)s が正しくありません"
@ -334,14 +314,6 @@ msgstr ""
"エラー: コンテナー更新に失敗しました (後の非同期更新のために保存中): %(ip)s:"
"%(port)s/%(dev)s からの %(status)d 応答"
#, python-format
msgid ""
"ERROR Container update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"エラー: コンテナー更新に失敗しました。要求内のホスト数およびデバイス数が異な"
"ります: 「%s」vs「%s」"
#, python-format
msgid "ERROR Could not get account info %s"
msgstr "ERROR アカウント情報 %s が取得できませんでした"
@ -496,10 +468,6 @@ msgstr "UTF-8 へのエンコードエラー: %s"
msgid "Error hashing suffix"
msgstr "サフィックスのハッシュエラー"
#, python-format
msgid "Error in %r with mtime_check_interval: %s"
msgstr "mtime_check_interval で %r にエラーがあります: %s"
#, python-format
msgid "Error limiting server %s"
msgstr "サーバー %s の制限エラー"
@ -651,10 +619,6 @@ msgstr "%(given_domain)s が %(found_domain)s にマップされました"
msgid "No %s running"
msgstr "%s が実行されていません"
#, python-format
msgid "No cluster endpoint for %r %r"
msgstr "%r %r のエンドポイントクラスターがありません"
#, python-format
msgid "No permission to signal PID %d"
msgstr "PID %d にシグナル通知する許可がありません"
@ -783,19 +747,6 @@ msgstr ""
msgid "Partition times: max %(max).4fs, min %(min).4fs, med %(med).4fs"
msgstr "パーティション時間: 最大 %(max).4fs、最小 %(min).4fs、中間 %(med).4fs"
#, python-format
msgid "Pass beginning; %s possible containers; %s possible objects"
msgstr ""
"パスの開始中。%s コンテナーおよび %s オブジェクトが存在する可能性があります"
#, python-format
msgid "Pass completed in %ds; %d objects expired"
msgstr "%d でパスが完了しました。%d オブジェクトの有効期限が切れました"
#, python-format
msgid "Pass so far %ds; %d objects expired"
msgstr "現在までのパス %d。%d オブジェクトの有効期限が切れました"
msgid "Path required in X-Container-Sync-To"
msgstr "X-Container-Sync-To にパスが必要です"
@ -984,10 +935,6 @@ msgstr "%s への書き込みを試行中"
msgid "UNCAUGHT EXCEPTION"
msgstr "キャッチされていない例外"
#, python-format
msgid "Unable to load internal client from config: %r (%s)"
msgstr "設定から内部クライアントをロードできません: %r (%s)"
#, python-format
msgid "Unable to locate %s in libc. Leaving as a no-op."
msgstr "%s が libc に見つかりません。no-op として終了します。"

View File

@ -8,9 +8,9 @@
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
msgid ""
msgstr ""
"Project-Id-Version: swift 2.7.1.dev50\n"
"Project-Id-Version: swift 2.7.1.dev169\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2016-04-17 21:20+0000\n"
"POT-Creation-Date: 2016-06-02 04:58+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -263,14 +263,6 @@ msgstr ""
"%(path)s의 컨테이너 업데이트 스윕 완료: %(elapsed).02fs, %(success)s개 성공, "
"%(fail)s개 실패, %(no_change)s개 변경 없음"
#, python-format
msgid "Could not bind to %s:%s after trying for %s seconds"
msgstr "%s초 동안 시도한 후 %s:%s에 바인드할 수 없음"
#, python-format
msgid "Could not load %r: %s"
msgstr "%r을(를) 로드할 수 없음: %s"
#, python-format
msgid "Data download error: %s"
msgstr "데이터 다운로드 오류: %s"
@ -279,10 +271,6 @@ msgstr "데이터 다운로드 오류: %s"
msgid "Devices pass completed: %.02fs"
msgstr "장치 패스 완료 : %.02fs"
#, python-format
msgid "Directory %r does not map to a valid policy (%s)"
msgstr "%r 디렉토리가 올바른 정책(%s)에 맵핑되지 않음"
#, python-format
msgid "ERROR %(db_file)s: %(validate_sync_to_err)s"
msgstr "오류 %(db_file)s: %(validate_sync_to_err)s"
@ -311,14 +299,6 @@ msgstr ""
"오류. %(ip)s:%(port)s/%(device)s(으)로 계정 업데이트 실패(나중에 다시 시도): "
"응답 %(status)s %(reason)s"
#, python-format
msgid ""
"ERROR Account update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"오류. 계정 업데이트 실패: 다음 요청에서 호스트 및 디바이스 수가 서로 다름: "
"\"%s\" 대 \"%s\""
#, python-format
msgid "ERROR Bad response %(status)s from %(host)s"
msgstr "오류. %(host)s의 잘못된 응답 %(status)s"
@ -335,14 +315,6 @@ msgstr ""
"오류. 컨테이너 업데이트 실패(이후 비동기 업데이트용으로 저장): %(status)d응"
"답. 출처: %(ip)s:%(port)s/%(dev)s"
#, python-format
msgid ""
"ERROR Container update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"오류. 컨테이너 업데이트 실패: 다음 요청에서 호스트 및 디바이스 수가 서로 다"
"름: \"%s\" 대 \"%s\""
#, python-format
msgid "ERROR Could not get account info %s"
msgstr "오류는 %s의 계정 정보를 얻을 수 없습니다"
@ -493,10 +465,6 @@ msgstr "UTF-8: %s 으로 변환 오류"
msgid "Error hashing suffix"
msgstr "접미부를 해싱하는 중 오류 발생"
#, python-format
msgid "Error in %r with mtime_check_interval: %s"
msgstr "%r에서 mtime_check_interval 오류 발생: %s"
#, python-format
msgid "Error limiting server %s"
msgstr "서버 %s 제한 오류"
@ -646,10 +614,6 @@ msgstr "%(given_domain)s을(를) %(found_domain)s(으)로 맵핑함"
msgid "No %s running"
msgstr "%s이(가) 실행되지 않음"
#, python-format
msgid "No cluster endpoint for %r %r"
msgstr "%r %r에 대한 클러스터 엔드포인트가 없음"
#, python-format
msgid "No permission to signal PID %d"
msgstr "PID %d을(를) 표시할 권한이 없음"
@ -775,18 +739,6 @@ msgstr "X-Container-Sync-To에 매개변수, 조회, 단편이 허용되지 않
msgid "Partition times: max %(max).4fs, min %(min).4fs, med %(med).4fs"
msgstr "파티션 시간: 최대 %(max).4f초, 최소 %(min).4f초, 중간 %(med).4f초"
#, python-format
msgid "Pass beginning; %s possible containers; %s possible objects"
msgstr "전달 시작, %s개의 컨테이너 사용 가능, %s개의 오브젝트 사용 가능"
#, python-format
msgid "Pass completed in %ds; %d objects expired"
msgstr "%d초 안에 전달이 완료됨. %d개의 오브젝트가 만료됨"
#, python-format
msgid "Pass so far %ds; %d objects expired"
msgstr "현재 %d개 전달, %d개의 오브젝트가 만료됨"
msgid "Path required in X-Container-Sync-To"
msgstr "X-Container-Sync-To에 경로가 필요함"
@ -970,10 +922,6 @@ msgstr "%s에 쓰기 시도 중"
msgid "UNCAUGHT EXCEPTION"
msgstr "미발견 예외"
#, python-format
msgid "Unable to load internal client from config: %r (%s)"
msgstr "구성에서 내부 클라이언트를 로드할 수 없음: %r (%s)"
#, python-format
msgid "Unable to locate %s in libc. Leaving as a no-op."
msgstr "libc에서 %s을(를) 찾을 수 없습니다. no-op로 남겨 둡니다."

View File

@ -10,9 +10,9 @@
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
msgid ""
msgstr ""
"Project-Id-Version: swift 2.7.1.dev50\n"
"Project-Id-Version: swift 2.7.1.dev169\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2016-04-17 21:20+0000\n"
"POT-Creation-Date: 2016-06-02 04:58+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -267,14 +267,6 @@ msgstr ""
"%(elapsed).02fs, %(success)s com êxito, %(fail)s com falha, %(no_change)s "
"sem alterações"
#, python-format
msgid "Could not bind to %s:%s after trying for %s seconds"
msgstr "Não foi possível conectar a %s:%s após tentar por %s segundos"
#, python-format
msgid "Could not load %r: %s"
msgstr "Não é possível carregar %r: %s"
#, python-format
msgid "Data download error: %s"
msgstr "Erro ao fazer download de dados: %s"
@ -283,10 +275,6 @@ msgstr "Erro ao fazer download de dados: %s"
msgid "Devices pass completed: %.02fs"
msgstr "Dispositivos finalizados: %.02fs"
#, python-format
msgid "Directory %r does not map to a valid policy (%s)"
msgstr "O diretório %r não está mapeado para uma política válida (%s)"
#, python-format
msgid "ERROR %(db_file)s: %(validate_sync_to_err)s"
msgstr "ERRO %(db_file)s: %(validate_sync_to_err)s"
@ -315,14 +303,6 @@ msgstr ""
"ERRO A atualização da conta falhou com %(ip)s:%(port)s/%(device)s (tente "
"novamente mais tarde): Resposta %(status)s %(reason)s"
#, python-format
msgid ""
"ERROR Account update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"ERRO A atualização da conta falhou: números diferentes de hosts e "
"dispositivos na solicitação: \"%s\" vs \"%s\""
#, python-format
msgid "ERROR Bad response %(status)s from %(host)s"
msgstr "ERRO Resposta inválida %(status)s a partir de %(host)s"
@ -339,14 +319,6 @@ msgstr ""
"ERRO A atualização do contêiner falhou (salvando para atualização assíncrona "
"posterior): %(status)d resposta do %(ip)s:%(port)s/%(dev)s"
#, python-format
msgid ""
"ERROR Container update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"ERRO A atualização do contêiner falhou: números diferentes de hosts e "
"dispositivos na solicitação: \"%s\" vs \"%s\""
#, python-format
msgid "ERROR Could not get account info %s"
msgstr "ERRO Não foi possível recuperar as informações da conta %s"
@ -499,10 +471,6 @@ msgstr "Erro encodificando para UTF-8: %s"
msgid "Error hashing suffix"
msgstr "Erro ao efetuar hash do sufixo"
#, python-format
msgid "Error in %r with mtime_check_interval: %s"
msgstr "Erro em %r com mtime_check_interval: %s"
#, python-format
msgid "Error limiting server %s"
msgstr "Erro ao limitar o servidor %s"
@ -652,10 +620,6 @@ msgstr "%(given_domain)s mapeado para %(found_domain)s"
msgid "No %s running"
msgstr "Nenhum %s rodando"
#, python-format
msgid "No cluster endpoint for %r %r"
msgstr "Nenhum terminal de cluster para %r %r"
#, python-format
msgid "No permission to signal PID %d"
msgstr "Nenhuma permissão para PID do sinal %d"
@ -786,18 +750,6 @@ msgid "Partition times: max %(max).4fs, min %(min).4fs, med %(med).4fs"
msgstr ""
"Tempos de partição: máximo %(max).4fs, mínimo %(min).4fs, médio %(med).4fs"
#, python-format
msgid "Pass beginning; %s possible containers; %s possible objects"
msgstr "Início da aprovação; %s contêineres possíveis; %s objetos possíveis"
#, python-format
msgid "Pass completed in %ds; %d objects expired"
msgstr "Aprovação concluída em %ds; %d objetos expirados"
#, python-format
msgid "Pass so far %ds; %d objects expired"
msgstr "Aprovados até aqui %ds; %d objetos expirados"
msgid "Path required in X-Container-Sync-To"
msgstr "Caminho necessário em X-Container-Sync-To"
@ -991,11 +943,6 @@ msgstr "Tentando escrever para %s"
msgid "UNCAUGHT EXCEPTION"
msgstr "EXCEÇÃO NÃO CAPTURADA"
#, python-format
msgid "Unable to load internal client from config: %r (%s)"
msgstr ""
"Não é possível carregar cliente interno a partir da configuração: %r (%s)"
#, python-format
msgid "Unable to locate %s in libc. Leaving as a no-op."
msgstr "Não é possível localizar %s em libc. Saindo como um não operacional."

View File

@ -6,9 +6,9 @@
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
msgid ""
msgstr ""
"Project-Id-Version: swift 2.7.1.dev50\n"
"Project-Id-Version: swift 2.7.1.dev169\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2016-04-17 21:20+0000\n"
"POT-Creation-Date: 2016-06-02 04:58+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -265,14 +265,6 @@ msgstr ""
"%(elapsed).02fs, успешно: %(success)s, сбоев: %(fail)s, без изменений: "
"%(no_change)s"
#, python-format
msgid "Could not bind to %s:%s after trying for %s seconds"
msgstr "Не удалось подключиться к порту %s:%s по истечении %s секунд"
#, python-format
msgid "Could not load %r: %s"
msgstr "Не удалось загрузить %r: %s"
#, python-format
msgid "Data download error: %s"
msgstr "Ошибка загрузки данных: %s"
@ -281,10 +273,6 @@ msgstr "Ошибка загрузки данных: %s"
msgid "Devices pass completed: %.02fs"
msgstr "Проход устройств выполнен: %.02fs"
#, python-format
msgid "Directory %r does not map to a valid policy (%s)"
msgstr "Каталог %r не связан со стратегией policy (%s)"
#, python-format
msgid "ERROR %(db_file)s: %(validate_sync_to_err)s"
msgstr "Ошибка %(db_file)s: %(validate_sync_to_err)s"
@ -315,14 +303,6 @@ msgstr ""
"Ошибка: обновление учетной записи не выполнено для %(ip)s:%(port)s/"
"%(device)s (операция будет повторена позднее): Ответ: %(status)s %(reason)s"
#, python-format
msgid ""
"ERROR Account update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"Ошибка: обновление учетной записи не выполнено, в запросе указано разное "
"число хостов и устройств: \"%s\" и \"%s\""
#, python-format
msgid "ERROR Bad response %(status)s from %(host)s"
msgstr "Ошибка: Неправильный запрос %(status)s из %(host)s"
@ -340,14 +320,6 @@ msgstr ""
"обновлений будет выполнено позднее): %(status)d ответ от %(ip)s:%(port)s/"
"%(dev)s"
#, python-format
msgid ""
"ERROR Container update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"Ошибка: обновление контейнера не выполнено, в запросе указано разное число "
"хостов и устройств: \"%s\" и \"%s\""
#, python-format
msgid "ERROR Could not get account info %s"
msgstr "Ошибка: не удалось получить сведения об учетной записи %s"
@ -506,10 +478,6 @@ msgstr "Ошибка кодирования в UTF-8: %s"
msgid "Error hashing suffix"
msgstr "Ошибка хэширования суффикса"
#, python-format
msgid "Error in %r with mtime_check_interval: %s"
msgstr "Ошибка в %r с mtime_check_interval: %s"
#, python-format
msgid "Error limiting server %s"
msgstr "Ошибка ограничения сервера %s"
@ -662,10 +630,6 @@ msgstr "Преобразовано %(given_domain)s в %(found_domain)s"
msgid "No %s running"
msgstr "%s не выполняется"
#, python-format
msgid "No cluster endpoint for %r %r"
msgstr "Отсутствует конечная точка кластера для %r %r"
#, python-format
msgid "No permission to signal PID %d"
msgstr "Нет прав доступа для отправки сигнала в PID %d"
@ -794,18 +758,6 @@ msgid "Partition times: max %(max).4fs, min %(min).4fs, med %(med).4fs"
msgstr ""
"Время раздела: максимум: %(max).4fs, минимум: %(min).4fs, среднее: %(med).4fs"
#, python-format
msgid "Pass beginning; %s possible containers; %s possible objects"
msgstr "Проход запущен; возможных контейнеров: %s; возможных объектов: %s"
#, python-format
msgid "Pass completed in %ds; %d objects expired"
msgstr "Проход выполнен за %ds; устарело объектов: %d"
#, python-format
msgid "Pass so far %ds; %d objects expired"
msgstr "Проход выполняется до настоящего времени %ds; устарело объектов: %d"
msgid "Path required in X-Container-Sync-To"
msgstr "Требуется путь в X-Container-Sync-To"
@ -1002,10 +954,6 @@ msgstr "Попытка записи в %s"
msgid "UNCAUGHT EXCEPTION"
msgstr "Необрабатываемая исключительная ситуация"
#, python-format
msgid "Unable to load internal client from config: %r (%s)"
msgstr "Не удалось загрузить клиент из конфигурации: %r (%s)"
#, python-format
msgid "Unable to locate %s in libc. Leaving as a no-op."
msgstr "Не удалось найти %s в libc. Оставлено как no-op."

File diff suppressed because it is too large Load Diff

View File

@ -7,9 +7,9 @@
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
msgid ""
msgstr ""
"Project-Id-Version: swift 2.7.1.dev50\n"
"Project-Id-Version: swift 2.7.1.dev169\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2016-04-17 21:20+0000\n"
"POT-Creation-Date: 2016-06-02 04:58+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -259,14 +259,6 @@ msgstr ""
"%(path)s in kap güncelleme süpürmesi tamamlandı: %(elapsed).02fs, "
"%(success)s başarılı, %(fail)s başarısız, %(no_change)s değişiklik yok"
#, python-format
msgid "Could not bind to %s:%s after trying for %s seconds"
msgstr "%s:%s'e bağlanılamadı, %s saniye beklendi"
#, python-format
msgid "Could not load %r: %s"
msgstr "%r yüklenemedi: %s"
#, python-format
msgid "Data download error: %s"
msgstr "Veri indirme hatası: %s"
@ -275,10 +267,6 @@ msgstr "Veri indirme hatası: %s"
msgid "Devices pass completed: %.02fs"
msgstr "Aygıtlar geçişi tamamlandı: %.02fs"
#, python-format
msgid "Directory %r does not map to a valid policy (%s)"
msgstr "Dizin %r geçerli bir ilkeye eşleştirilmemiş (%s)"
#, python-format
msgid "ERROR %(db_file)s: %(validate_sync_to_err)s"
msgstr "HATA %(db_file)s: %(validate_sync_to_err)s"
@ -307,14 +295,6 @@ msgstr ""
"HATA %(ip)s:%(port)s/%(device)s ile hesap güncelleme başarısız (sonra tekrar "
"denenecek): Yanıt %(status)s %(reason)s"
#, python-format
msgid ""
"ERROR Account update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"HATA Hesap güncelleme başarısız: istekte farklı sayıda istemci ve aygıt "
"var: \"%s\" \"%s\""
#, python-format
msgid "ERROR Bad response %(status)s from %(host)s"
msgstr "HATA %(host)s dan kötü yanıt %(status)s"
@ -331,14 +311,6 @@ msgstr ""
"HATA Kap güncelleme başarısız (daha sonraki async güncellemesi için "
"kaydediliyor): %(ip)s:%(port)s/%(dev)s den %(status)d yanıtı"
#, python-format
msgid ""
"ERROR Container update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr ""
"HATA Kap güncelleme başarısız: istekte farklı sayıda istemci ve aygıt var: "
"\"%s\" e karşı \"%s\""
#, python-format
msgid "ERROR Could not get account info %s"
msgstr "HATA hesap bilgisi %s alınamadı"
@ -488,10 +460,6 @@ msgstr "UTF-8 ile kodlama hatası: %s"
msgid "Error hashing suffix"
msgstr "Sonek özetini çıkarmada hata"
#, python-format
msgid "Error in %r with mtime_check_interval: %s"
msgstr "mtime_check_interval ile %r de hata: %s"
#, python-format
msgid "Error limiting server %s"
msgstr "%s sunucusu sınırlandırılırken hata"
@ -633,10 +601,6 @@ msgstr "%(given_domain)s %(found_domain)s eşleştirildi"
msgid "No %s running"
msgstr "Çalışan %s yok"
#, python-format
msgid "No cluster endpoint for %r %r"
msgstr "%r %r için küme uç noktası yok"
#, python-format
msgid "No permission to signal PID %d"
msgstr "%d PID'ine sinyalleme izni yok"
@ -750,18 +714,6 @@ msgid "Partition times: max %(max).4fs, min %(min).4fs, med %(med).4fs"
msgstr ""
"Bölüm zamanları: azami %(max).4fs, asgari %(min).4fs, ortalama %(med).4fs"
#, python-format
msgid "Pass beginning; %s possible containers; %s possible objects"
msgstr "Geçiş başlıyor; %s olası kap; %s olası nesne"
#, python-format
msgid "Pass completed in %ds; %d objects expired"
msgstr "Geçiş %ds de tamamlandı; %d nesnenin süresi doldu"
#, python-format
msgid "Pass so far %ds; %d objects expired"
msgstr "Şimdiye kadarki geçiş %ds; %d nesnenin süresi doldu"
msgid "Path required in X-Container-Sync-To"
msgstr "X-Container-Sync-To'de yol gerekli"
@ -947,10 +899,6 @@ msgstr "%s'e yazmaya çalışılıyor"
msgid "UNCAUGHT EXCEPTION"
msgstr "YAKALANMAYAN İSTİSNA"
#, python-format
msgid "Unable to load internal client from config: %r (%s)"
msgstr "Yapılandırmadan dahili istemci yüklenemedi: %r (%s)"
#, python-format
msgid "Unable to locate %s in libc. Leaving as a no-op."
msgstr "%s libc'de bulunamadı. No-op olarak çıkılıyor."

View File

@ -7,9 +7,9 @@
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
msgid ""
msgstr ""
"Project-Id-Version: swift 2.7.1.dev50\n"
"Project-Id-Version: swift 2.7.1.dev169\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2016-04-17 21:20+0000\n"
"POT-Creation-Date: 2016-06-02 04:58+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -257,14 +257,6 @@ msgstr ""
"通过路径%(path)s容器更新扫除完成%(elapsed).02fs, %(success)s 成功, "
"%(fail)s 失败, %(no_change)s 无更改"
#, python-format
msgid "Could not bind to %s:%s after trying for %s seconds"
msgstr "尝试过%s秒后无法捆绑%s:%s"
#, python-format
msgid "Could not load %r: %s"
msgstr "无法下载%r: %s"
#, python-format
msgid "Data download error: %s"
msgstr "数据下载错误:%s"
@ -273,10 +265,6 @@ msgstr "数据下载错误:%s"
msgid "Devices pass completed: %.02fs"
msgstr "设备通过完成: %.02fs"
#, python-format
msgid "Directory %r does not map to a valid policy (%s)"
msgstr "目录 %r 未映射至有效策略 (%s)"
#, python-format
msgid "ERROR %(db_file)s: %(validate_sync_to_err)s"
msgstr "错误 %(db_file)s: %(validate_sync_to_err)s"
@ -305,12 +293,6 @@ msgstr ""
"出现错误 账号更新失败: %(ip)s:%(port)s/%(device)s (稍后尝试): 回应 "
"%(status)s %(reason)s"
#, python-format
msgid ""
"ERROR Account update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr "出现错误 账号更新失败:本机数量与设备数量不符: \"%s\" vs \"%s\""
#, python-format
msgid "ERROR Bad response %(status)s from %(host)s"
msgstr "失败响应错误%(status)s来自%(host)s"
@ -327,12 +309,6 @@ msgstr ""
"错误 容器更新失败(正在保存 稍后同步更新)%(status)d回应来自%(ip)s:%(port)s/"
"%(dev)s"
#, python-format
msgid ""
"ERROR Container update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr "错误 容器更新失败:主机数量和设备数量不符合请求: \"%s\" vs \"%s\""
#, python-format
msgid "ERROR Could not get account info %s"
msgstr "错误:无法获取账号信息%s"
@ -479,10 +455,6 @@ msgstr "UTF-8编码错误%s"
msgid "Error hashing suffix"
msgstr "执行Hashing后缀时发生错误"
#, python-format
msgid "Error in %r with mtime_check_interval: %s"
msgstr "%r中mtime_check_interval出现错误%s"
#, python-format
msgid "Error limiting server %s"
msgstr "服务器出现错误%s "
@ -627,10 +599,6 @@ msgstr "集合%(given_domain)s到%(found_domain)s"
msgid "No %s running"
msgstr "无%s账号运行"
#, python-format
msgid "No cluster endpoint for %r %r"
msgstr "%r %r的集群节点不存在"
#, python-format
msgid "No permission to signal PID %d"
msgstr "无权限发送信号PID%d"
@ -753,18 +721,6 @@ msgstr "在X-Container-Sync-To中变量查询和碎片不被允许"
msgid "Partition times: max %(max).4fs, min %(min).4fs, med %(med).4fs"
msgstr "分区时间: max %(max).4fs, min %(min).4fs, med %(med).4fs"
#, python-format
msgid "Pass beginning; %s possible containers; %s possible objects"
msgstr "开始通过;%s可能容器%s可能对象"
#, python-format
msgid "Pass completed in %ds; %d objects expired"
msgstr "%ds通过完成; %d对象过期"
#, python-format
msgid "Pass so far %ds; %d objects expired"
msgstr "%ds目前通过%d对象过期"
msgid "Path required in X-Container-Sync-To"
msgstr "在X-Container-Sync-To中路径是必须的"
@ -945,10 +901,6 @@ msgstr "尝试执行书写%s"
msgid "UNCAUGHT EXCEPTION"
msgstr "未捕获的异常"
#, python-format
msgid "Unable to load internal client from config: %r (%s)"
msgstr "无法从配置装入内部客户机:%r (%s)"
#, python-format
msgid "Unable to locate %s in libc. Leaving as a no-op."
msgstr "无法查询到%s 保留为no-op"

View File

@ -6,9 +6,9 @@
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
msgid ""
msgstr ""
"Project-Id-Version: swift 2.7.1.dev50\n"
"Project-Id-Version: swift 2.7.1.dev169\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2016-04-17 21:20+0000\n"
"POT-Creation-Date: 2016-06-02 04:58+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -257,14 +257,6 @@ msgstr ""
"%(path)s 的儲存器更新清理已完成:%(elapsed).02fs%(success)s 個成"
"功,%(fail)s 個失敗,%(no_change)s 個無變更"
#, python-format
msgid "Could not bind to %s:%s after trying for %s seconds"
msgstr "嘗試 %s 秒後仍無法連結至 %s:%s"
#, python-format
msgid "Could not load %r: %s"
msgstr "無法載入 %r%s"
#, python-format
msgid "Data download error: %s"
msgstr "資料下載錯誤:%s"
@ -273,10 +265,6 @@ msgstr "資料下載錯誤:%s"
msgid "Devices pass completed: %.02fs"
msgstr "裝置通過已完成:%.02fs"
#, python-format
msgid "Directory %r does not map to a valid policy (%s)"
msgstr "目錄 %r 未對映至有效的原則 (%s)"
#, python-format
msgid "ERROR %(db_file)s: %(validate_sync_to_err)s"
msgstr "錯誤:%(db_file)s%(validate_sync_to_err)s"
@ -305,12 +293,6 @@ msgstr ""
"錯誤:%(ip)s:%(port)s/%(device)s 的帳戶更新失敗(將稍後重試):回應 "
"%(status)s %(reason)s"
#, python-format
msgid ""
"ERROR Account update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr "錯誤:帳戶更新失敗:要求中的主機與裝置數目不同:\"%s\" 對 \"%s\""
#, python-format
msgid "ERROR Bad response %(status)s from %(host)s"
msgstr "錯誤:來自 %(host)s 的回應 %(status)s 不當"
@ -327,12 +309,6 @@ msgstr ""
"錯誤:儲存器更新失敗(儲存以稍後進行非同步更新):%(status)d回應來自 "
"%(ip)s:%(port)s/%(dev)s"
#, python-format
msgid ""
"ERROR Container update failed: different numbers of hosts and devices in "
"request: \"%s\" vs \"%s\""
msgstr "錯誤:儲存器更新失敗:要求中的主機與裝置數目不同:\"%s\" 對 \"%s\""
#, python-format
msgid "ERROR Could not get account info %s"
msgstr "錯誤:無法取得帳戶資訊 %s"
@ -480,10 +456,6 @@ msgstr "編碼為 UTF-8 時發生錯誤:%s"
msgid "Error hashing suffix"
msgstr "混合字尾時發生錯誤"
#, python-format
msgid "Error in %r with mtime_check_interval: %s"
msgstr "在 mtime_check_interval 中,%r 發生錯誤:%s"
#, python-format
msgid "Error limiting server %s"
msgstr "限制伺服器 %s 時發生錯誤"
@ -628,10 +600,6 @@ msgstr "已將 %(given_domain)s 對映至 %(found_domain)s"
msgid "No %s running"
msgstr "沒有 %s 在執行中"
#, python-format
msgid "No cluster endpoint for %r %r"
msgstr "沒有 %r %r 的叢集端點"
#, python-format
msgid "No permission to signal PID %d"
msgstr "沒有信號 PID %d 的許可權"
@ -755,18 +723,6 @@ msgstr "X-Container-Sync-To 中不容許參數、查詢及片段"
msgid "Partition times: max %(max).4fs, min %(min).4fs, med %(med).4fs"
msgstr "分割區時間:最大 %(max).4fs,最小 %(min).4fs,中間 %(med).4fs"
#, python-format
msgid "Pass beginning; %s possible containers; %s possible objects"
msgstr "通過正在開始;%s 個可能儲存器;%s 個可能物件"
#, python-format
msgid "Pass completed in %ds; %d objects expired"
msgstr "已完成通過 %ds 個;%d 個物件已過期"
#, python-format
msgid "Pass so far %ds; %d objects expired"
msgstr "目前為止通過 %ds 個;%d 個物件過期"
msgid "Path required in X-Container-Sync-To"
msgstr "X-Container-Sync-To 中需要路徑"
@ -950,10 +906,6 @@ msgstr "正在嘗試寫入至 %s"
msgid "UNCAUGHT EXCEPTION"
msgstr "未捕捉的異常狀況"
#, python-format
msgid "Unable to load internal client from config: %r (%s)"
msgstr "無法從配置載入內部用戶端:%r (%s)"
#, python-format
msgid "Unable to locate %s in libc. Leaving as a no-op."
msgstr "在 libc 中找不到 %s。保留為 no-op。"

View File

@ -559,8 +559,8 @@ class ObjectController(BaseStorageServer):
except (DiskFileXattrNotSupported, DiskFileNoSpace):
return HTTPInsufficientStorage(drive=device, request=request)
if (content_type_headers['Content-Type-Timestamp'] !=
disk_file.data_timestamp):
if (content_type_headers['Content-Type-Timestamp']
!= disk_file.data_timestamp):
# Current content-type is not from the datafile, but the datafile
# content-type may have a swift_bytes param that was appended by
# SLO and we must continue to send that with the container update.
@ -583,15 +583,19 @@ class ObjectController(BaseStorageServer):
'x-meta-timestamp': metadata['X-Timestamp'],
'x-etag': orig_metadata['ETag']})
# Special cases for backwards compatibility.
# For EC policy, send X-Object-Sysmeta-Ec-Etag which is same as the
# X-Backend-Container-Update-Override-Etag value sent with the original
# PUT. Similarly send X-Object-Sysmeta-Ec-Content-Length which is the
# same as the X-Backend-Container-Update-Override-Size value. We have
# to send Etag and size with a POST container update because the
# original PUT container update may have failed or be in async_pending.
if 'X-Object-Sysmeta-Ec-Etag' in orig_metadata:
# Special case for backwards compatibility.
# For EC policy, send X-Object-Sysmeta-Ec-Etag which is same as the
# X-Backend-Container-Update-Override-Etag value sent with the
# original PUT. We have to send Etag (and size etc) with a POST
# container update because the original PUT container update may
# have failed or be in async_pending.
update_headers['X-Etag'] = orig_metadata[
'X-Object-Sysmeta-Ec-Etag']
if 'X-Object-Sysmeta-Ec-Content-Length' in orig_metadata:
update_headers['X-Size'] = orig_metadata[
'X-Object-Sysmeta-Ec-Content-Length']
self._check_container_override(update_headers, orig_metadata)

View File

@ -58,18 +58,16 @@ def get_server_number(ipport, ipport2server):
return server, number
def start_server(ipport, ipport2server, pids, check=True):
def start_server(ipport, ipport2server):
server, number = get_server_number(ipport, ipport2server)
err = Manager([server]).start(number=number, wait=False)
if err:
raise Exception('unable to start %s' % (
server if not number else '%s%s' % (server, number)))
if check:
return check_server(ipport, ipport2server, pids)
return None
return check_server(ipport, ipport2server)
def check_server(ipport, ipport2server, pids, timeout=CHECK_SERVER_TIMEOUT):
def check_server(ipport, ipport2server):
server = ipport2server[ipport]
if server[:-1] in ('account', 'container', 'object'):
if int(server[-1]) > 4:
@ -79,7 +77,7 @@ def check_server(ipport, ipport2server, pids, timeout=CHECK_SERVER_TIMEOUT):
path += '/3'
elif server[:-1] == 'object':
path += '/3/4'
try_until = time() + timeout
try_until = time() + CHECK_SERVER_TIMEOUT
while True:
try:
conn = HTTPConnection(*ipport)
@ -95,11 +93,11 @@ def check_server(ipport, ipport2server, pids, timeout=CHECK_SERVER_TIMEOUT):
if time() > try_until:
print(err)
print('Giving up on %s:%s after %s seconds.' % (
server, ipport, timeout))
server, ipport, CHECK_SERVER_TIMEOUT))
raise err
sleep(0.1)
else:
try_until = time() + timeout
try_until = time() + CHECK_SERVER_TIMEOUT
while True:
try:
url, token = get_auth('http://%s:%d/auth/v1.0' % ipport,
@ -116,7 +114,7 @@ def check_server(ipport, ipport2server, pids, timeout=CHECK_SERVER_TIMEOUT):
return None
def kill_server(ipport, ipport2server, pids):
def kill_server(ipport, ipport2server):
server, number = get_server_number(ipport, ipport2server)
err = Manager([server]).kill(number=number)
if err:
@ -136,7 +134,7 @@ def kill_server(ipport, ipport2server, pids):
sleep(0.1)
def kill_nonprimary_server(primary_nodes, ipport2server, pids):
def kill_nonprimary_server(primary_nodes, ipport2server):
primary_ipports = [(n['ip'], n['port']) for n in primary_nodes]
for ipport, server in ipport2server.items():
if ipport in primary_ipports:
@ -146,7 +144,7 @@ def kill_nonprimary_server(primary_nodes, ipport2server, pids):
raise Exception('Cannot figure out server type for %r' % primary_nodes)
for ipport, server in list(ipport2server.items()):
if server[:-1] == server_type and ipport not in primary_ipports:
kill_server(ipport, ipport2server, pids)
kill_server(ipport, ipport2server)
return ipport
@ -322,7 +320,6 @@ class ProbeTest(unittest.TestCase):
def setUp(self):
resetswift()
self.pids = {}
try:
self.ipport2server = {}
self.configs = defaultdict(dict)
@ -354,11 +351,11 @@ class ProbeTest(unittest.TestCase):
Manager(['main']).start(wait=False)
for ipport in self.ipport2server:
check_server(ipport, self.ipport2server, self.pids)
check_server(ipport, self.ipport2server)
proxy_ipport = ('127.0.0.1', 8080)
self.ipport2server[proxy_ipport] = 'proxy'
self.url, self.token, self.account = check_server(
proxy_ipport, self.ipport2server, self.pids)
proxy_ipport, self.ipport2server)
self.replicators = Manager(
['account-replicator', 'container-replicator',
'object-replicator'])
@ -443,10 +440,13 @@ class ProbeTest(unittest.TestCase):
swift_dir = /etc/swift
[pipeline:main]
pipeline = catch_errors cache proxy-server
pipeline = catch_errors cache copy proxy-server
[app:proxy-server]
use = egg:swift#proxy
[filter:copy]
use = egg:swift#copy
object_post_as_copy = %s
[filter:cache]

View File

@ -97,9 +97,8 @@ class TestAccountFailures(ReplProbeTest):
self.assertTrue(found2)
apart, anodes = self.account_ring.get_nodes(self.account)
kill_nonprimary_server(anodes, self.ipport2server, self.pids)
kill_server((anodes[0]['ip'], anodes[0]['port']),
self.ipport2server, self.pids)
kill_nonprimary_server(anodes, self.ipport2server)
kill_server((anodes[0]['ip'], anodes[0]['port']), self.ipport2server)
# Kill account servers excepting two of the primaries
# Delete container1
@ -147,8 +146,7 @@ class TestAccountFailures(ReplProbeTest):
self.assertTrue(found2)
# Restart other primary account server
start_server((anodes[0]['ip'], anodes[0]['port']),
self.ipport2server, self.pids)
start_server((anodes[0]['ip'], anodes[0]['port']), self.ipport2server)
# Assert that server doesn't know about container1's deletion or the
# new container2/object2 yet

View File

@ -49,16 +49,14 @@ class TestContainerFailures(ReplProbeTest):
client.put_container(self.url, self.token, container1)
# Kill container1 servers excepting two of the primaries
kill_nonprimary_server(cnodes, self.ipport2server, self.pids)
kill_server((cnodes[0]['ip'], cnodes[0]['port']),
self.ipport2server, self.pids)
kill_nonprimary_server(cnodes, self.ipport2server)
kill_server((cnodes[0]['ip'], cnodes[0]['port']), self.ipport2server)
# Delete container1
client.delete_container(self.url, self.token, container1)
# Restart other container1 primary server
start_server((cnodes[0]['ip'], cnodes[0]['port']),
self.ipport2server, self.pids)
start_server((cnodes[0]['ip'], cnodes[0]['port']), self.ipport2server)
# Create container1/object1 (allowed because at least server thinks the
# container exists)
@ -89,12 +87,11 @@ class TestContainerFailures(ReplProbeTest):
client.put_container(self.url, self.token, container1)
# Kill container1 servers excepting one of the primaries
cnp_ipport = kill_nonprimary_server(cnodes, self.ipport2server,
self.pids)
cnp_ipport = kill_nonprimary_server(cnodes, self.ipport2server)
kill_server((cnodes[0]['ip'], cnodes[0]['port']),
self.ipport2server, self.pids)
self.ipport2server)
kill_server((cnodes[1]['ip'], cnodes[1]['port']),
self.ipport2server, self.pids)
self.ipport2server)
# Delete container1 directly to the one primary still up
direct_client.direct_delete_container(cnodes[2], cpart, self.account,
@ -102,10 +99,10 @@ class TestContainerFailures(ReplProbeTest):
# Restart other container1 servers
start_server((cnodes[0]['ip'], cnodes[0]['port']),
self.ipport2server, self.pids)
self.ipport2server)
start_server((cnodes[1]['ip'], cnodes[1]['port']),
self.ipport2server, self.pids)
start_server(cnp_ipport, self.ipport2server, self.pids)
self.ipport2server)
start_server(cnp_ipport, self.ipport2server)
# Get to a final state
self.get_to_final_state()

View File

@ -58,8 +58,7 @@ class TestEmptyDevice(ReplProbeTest):
onode = onodes[0]
# Kill one container/obj primary server
kill_server((onode['ip'], onode['port']),
self.ipport2server, self.pids)
kill_server((onode['ip'], onode['port']), self.ipport2server)
# Delete the default data directory for objects on the primary server
obj_dir = '%s/%s' % (self._get_objects_dir(onode),
@ -84,8 +83,7 @@ class TestEmptyDevice(ReplProbeTest):
# Kill other two container/obj primary servers
# to ensure GET handoff works
for node in onodes[1:]:
kill_server((node['ip'], node['port']),
self.ipport2server, self.pids)
kill_server((node['ip'], node['port']), self.ipport2server)
# Indirectly through proxy assert we can get container/obj
odata = client.get_object(self.url, self.token, container, obj)[-1]
@ -94,8 +92,7 @@ class TestEmptyDevice(ReplProbeTest):
'returned: %s' % repr(odata))
# Restart those other two container/obj primary servers
for node in onodes[1:]:
start_server((node['ip'], node['port']),
self.ipport2server, self.pids)
start_server((node['ip'], node['port']), self.ipport2server)
self.assertFalse(os.path.exists(obj_dir))
# We've indirectly verified the handoff node has the object, but
# let's directly verify it.
@ -132,8 +129,7 @@ class TestEmptyDevice(ReplProbeTest):
missing)
# Bring the first container/obj primary server back up
start_server((onode['ip'], onode['port']),
self.ipport2server, self.pids)
start_server((onode['ip'], onode['port']), self.ipport2server)
# Assert that it doesn't have container/obj yet
self.assertFalse(os.path.exists(obj_dir))

View File

@ -14,21 +14,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import shutil
from io import StringIO
from tempfile import mkdtemp
from textwrap import dedent
from unittest import main
from uuid import uuid4
from swiftclient import client
from swift.common import direct_client, internal_client
from swift.common import direct_client
from swift.common.manager import Manager
from test.probe.common import kill_nonprimary_server, \
kill_server, ReplProbeTest, start_server
kill_server, ReplProbeTest, start_server, ECProbeTest
class TestObjectAsyncUpdate(ReplProbeTest):
@ -41,17 +36,15 @@ class TestObjectAsyncUpdate(ReplProbeTest):
# Kill container servers excepting two of the primaries
cpart, cnodes = self.container_ring.get_nodes(self.account, container)
cnode = cnodes[0]
kill_nonprimary_server(cnodes, self.ipport2server, self.pids)
kill_server((cnode['ip'], cnode['port']),
self.ipport2server, self.pids)
kill_nonprimary_server(cnodes, self.ipport2server)
kill_server((cnode['ip'], cnode['port']), self.ipport2server)
# Create container/obj
obj = 'object-%s' % uuid4()
client.put_object(self.url, self.token, container, obj, '')
# Restart other primary server
start_server((cnode['ip'], cnode['port']),
self.ipport2server, self.pids)
start_server((cnode['ip'], cnode['port']), self.ipport2server)
# Assert it does not know about container/obj
self.assertFalse(direct_client.direct_get_container(
@ -73,39 +66,9 @@ class TestUpdateOverrides(ReplProbeTest):
Verify that the update override headers take effect and override
values propagate to the container server.
"""
def setUp(self):
"""
Reset all environment and start all servers.
"""
super(TestUpdateOverrides, self).setUp()
self.tempdir = mkdtemp()
conf_path = os.path.join(self.tempdir, 'internal_client.conf')
conf_body = """
[DEFAULT]
swift_dir = /etc/swift
[pipeline:main]
pipeline = catch_errors cache proxy-server
[app:proxy-server]
use = egg:swift#proxy
[filter:cache]
use = egg:swift#memcache
[filter:catch_errors]
use = egg:swift#catch_errors
"""
with open(conf_path, 'w') as f:
f.write(dedent(conf_body))
self.int_client = internal_client.InternalClient(conf_path, 'test', 1)
def tearDown(self):
super(TestUpdateOverrides, self).tearDown()
shutil.rmtree(self.tempdir)
def _test_update_override_headers(self, override_headers):
# verify that update override headers are sent in container updates
int_client = self.make_internal_client()
container_name = 'c-%s' % uuid4()
obj_name = 'o-%s' % uuid4()
client.put_container(self.url, self.token, container_name,
@ -113,24 +76,26 @@ class TestUpdateOverrides(ReplProbeTest):
self.policy.name})
override_headers['Content-Type'] = 'text/plain'
self.int_client.upload_object(StringIO(u'stuff'), self.account,
container_name, obj_name,
override_headers)
int_client.upload_object(StringIO(u'stuff'), self.account,
container_name, obj_name,
override_headers)
# Run the object-updaters to be sure updates are done
Manager(['object-updater']).once()
meta = self.int_client.get_object_metadata(
meta = int_client.get_object_metadata(
self.account, container_name, obj_name)
self.assertEqual('text/plain', meta['content-type'])
self.assertEqual('c13d88cb4cb02003daedb8a84e5d272a', meta['etag'])
self.assertEqual('5', meta['content-length'])
obj_iter = self.int_client.iter_objects(self.account, container_name)
obj_iter = int_client.iter_objects(self.account, container_name)
for obj in obj_iter:
if obj['name'] == obj_name:
self.assertEqual('override-etag', obj['hash'])
self.assertEqual('override-type', obj['content_type'])
self.assertEqual(1999, obj['bytes'])
break
else:
self.fail('Failed to find object %s in listing for %s' %
@ -140,7 +105,8 @@ class TestUpdateOverrides(ReplProbeTest):
headers = {
'X-Object-Sysmeta-Container-Update-Override-Etag': 'override-etag',
'X-Object-Sysmeta-Container-Update-Override-Content-Type':
'override-type'
'override-type',
'X-Object-Sysmeta-Container-Update-Override-Size': '1999'
}
self._test_update_override_headers(headers)
@ -148,9 +114,167 @@ class TestUpdateOverrides(ReplProbeTest):
# older proxies used these headers to override container update values
headers = {
'X-Backend-Container-Update-Override-Etag': 'override-etag',
'X-Backend-Container-Update-Override-Content-Type': 'override-type'
'X-Backend-Container-Update-Override-Content-Type':
'override-type',
'X-Backend-Container-Update-Override-Size': '1999'
}
self._test_update_override_headers(headers)
class TestUpdateOverridesEC(ECProbeTest):
# verify that the container update overrides used with EC policies make
# it to the container servers when container updates are sync or async
# and possibly re-ordered with respect to object PUT and POST requests.
def test_async_update_after_PUT(self):
cpart, cnodes = self.container_ring.get_nodes(self.account, 'c1')
client.put_container(self.url, self.token, 'c1',
headers={'X-Storage-Policy':
self.policy.name})
# put an object while one container server is stopped so that we force
# an async update to it
kill_server((cnodes[0]['ip'], cnodes[0]['port']), self.ipport2server)
content = u'stuff'
client.put_object(self.url, self.token, 'c1', 'o1', contents=content)
meta = client.head_object(self.url, self.token, 'c1', 'o1')
# re-start the container server and assert that it does not yet know
# about the object
start_server((cnodes[0]['ip'], cnodes[0]['port']), self.ipport2server)
self.assertFalse(direct_client.direct_get_container(
cnodes[0], cpart, self.account, 'c1')[1])
# Run the object-updaters to be sure updates are done
Manager(['object-updater']).once()
# check the re-started container server got same update as others.
# we cannot assert the actual etag value because it may be encrypted
listing_etags = set()
for cnode in cnodes:
obj = direct_client.direct_get_container(
cnode, cpart, self.account, 'c1')[1][0]
self.assertEqual(len(content), obj['bytes'])
listing_etags.add(obj['hash'])
self.assertEqual(1, len(listing_etags))
# check that listing meta returned to client is consistent with object
# meta returned to client
hdrs, listing = client.get_container(self.url, self.token, 'c1')
self.assertEqual(1, len(listing))
self.assertEqual('o1', listing[0]['name'])
self.assertEqual(len(content), listing[0]['bytes'])
self.assertEqual(meta['etag'], listing[0]['hash'])
def test_update_during_POST_only(self):
# verify correct update values when PUT update is missed but then a
# POST update succeeds *before* the PUT async pending update is sent
cpart, cnodes = self.container_ring.get_nodes(self.account, 'c1')
client.put_container(self.url, self.token, 'c1',
headers={'X-Storage-Policy':
self.policy.name})
# put an object while one container server is stopped so that we force
# an async update to it
kill_server((cnodes[0]['ip'], cnodes[0]['port']), self.ipport2server)
content = u'stuff'
client.put_object(self.url, self.token, 'c1', 'o1', contents=content)
meta = client.head_object(self.url, self.token, 'c1', 'o1')
# re-start the container server and assert that it does not yet know
# about the object
start_server((cnodes[0]['ip'], cnodes[0]['port']), self.ipport2server)
self.assertFalse(direct_client.direct_get_container(
cnodes[0], cpart, self.account, 'c1')[1])
# use internal client for POST so we can force fast-post mode
int_client = self.make_internal_client(object_post_as_copy=False)
int_client.set_object_metadata(
self.account, 'c1', 'o1', {'X-Object-Meta-Fruit': 'Tomato'})
self.assertEqual(
'Tomato',
int_client.get_object_metadata(self.account, 'c1', 'o1')
['x-object-meta-fruit']) # sanity
# check the re-started container server got same update as others.
# we cannot assert the actual etag value because it may be encrypted
listing_etags = set()
for cnode in cnodes:
obj = direct_client.direct_get_container(
cnode, cpart, self.account, 'c1')[1][0]
self.assertEqual(len(content), obj['bytes'])
listing_etags.add(obj['hash'])
self.assertEqual(1, len(listing_etags))
# check that listing meta returned to client is consistent with object
# meta returned to client
hdrs, listing = client.get_container(self.url, self.token, 'c1')
self.assertEqual(1, len(listing))
self.assertEqual('o1', listing[0]['name'])
self.assertEqual(len(content), listing[0]['bytes'])
self.assertEqual(meta['etag'], listing[0]['hash'])
# Run the object-updaters to send the async pending from the PUT
Manager(['object-updater']).once()
# check container listing metadata is still correct
for cnode in cnodes:
obj = direct_client.direct_get_container(
cnode, cpart, self.account, 'c1')[1][0]
self.assertEqual(len(content), obj['bytes'])
listing_etags.add(obj['hash'])
self.assertEqual(1, len(listing_etags))
def test_async_updates_after_PUT_and_POST(self):
# verify correct update values when PUT update and POST updates are
# missed but then async updates are sent
cpart, cnodes = self.container_ring.get_nodes(self.account, 'c1')
client.put_container(self.url, self.token, 'c1',
headers={'X-Storage-Policy':
self.policy.name})
# PUT and POST to object while one container server is stopped so that
# we force async updates to it
kill_server((cnodes[0]['ip'], cnodes[0]['port']), self.ipport2server)
content = u'stuff'
client.put_object(self.url, self.token, 'c1', 'o1', contents=content)
meta = client.head_object(self.url, self.token, 'c1', 'o1')
# use internal client for POST so we can force fast-post mode
int_client = self.make_internal_client(object_post_as_copy=False)
int_client.set_object_metadata(
self.account, 'c1', 'o1', {'X-Object-Meta-Fruit': 'Tomato'})
self.assertEqual(
'Tomato',
int_client.get_object_metadata(self.account, 'c1', 'o1')
['x-object-meta-fruit']) # sanity
# re-start the container server and assert that it does not yet know
# about the object
start_server((cnodes[0]['ip'], cnodes[0]['port']), self.ipport2server)
self.assertFalse(direct_client.direct_get_container(
cnodes[0], cpart, self.account, 'c1')[1])
# Run the object-updaters to send the async pendings
Manager(['object-updater']).once()
# check the re-started container server got same update as others.
# we cannot assert the actual etag value because it may be encrypted
listing_etags = set()
for cnode in cnodes:
obj = direct_client.direct_get_container(
cnode, cpart, self.account, 'c1')[1][0]
self.assertEqual(len(content), obj['bytes'])
listing_etags.add(obj['hash'])
self.assertEqual(1, len(listing_etags))
# check that listing meta returned to client is consistent with object
# meta returned to client
hdrs, listing = client.get_container(self.url, self.token, 'c1')
self.assertEqual(1, len(listing))
self.assertEqual('o1', listing[0]['name'])
self.assertEqual(len(content), listing[0]['bytes'])
self.assertEqual(meta['etag'], listing[0]['hash'])
if __name__ == '__main__':
main()

View File

@ -46,8 +46,7 @@ class TestObjectHandoff(ReplProbeTest):
opart, onodes = self.object_ring.get_nodes(
self.account, container, obj)
onode = onodes[0]
kill_server((onode['ip'], onode['port']),
self.ipport2server, self.pids)
kill_server((onode['ip'], onode['port']), self.ipport2server)
# Create container/obj (goes to two primary servers and one handoff)
client.put_object(self.url, self.token, container, obj, 'VERIFY')
@ -66,8 +65,7 @@ class TestObjectHandoff(ReplProbeTest):
# Kill other two container/obj primary servers
# to ensure GET handoff works
for node in onodes[1:]:
kill_server((node['ip'], node['port']),
self.ipport2server, self.pids)
kill_server((node['ip'], node['port']), self.ipport2server)
# Indirectly through proxy assert we can get container/obj
odata = client.get_object(self.url, self.token, container, obj)[-1]
@ -77,8 +75,7 @@ class TestObjectHandoff(ReplProbeTest):
# Restart those other two container/obj primary servers
for node in onodes[1:]:
start_server((node['ip'], node['port']),
self.ipport2server, self.pids)
start_server((node['ip'], node['port']), self.ipport2server)
# We've indirectly verified the handoff node has the container/object,
# but let's directly verify it.
@ -119,8 +116,7 @@ class TestObjectHandoff(ReplProbeTest):
(cnode['ip'], cnode['port']))
# Bring the first container/obj primary server back up
start_server((onode['ip'], onode['port']),
self.ipport2server, self.pids)
start_server((onode['ip'], onode['port']), self.ipport2server)
# Assert that it doesn't have container/obj yet
try:
@ -180,8 +176,7 @@ class TestObjectHandoff(ReplProbeTest):
# Kill the first container/obj primary server again (we have two
# primaries and the handoff up now)
kill_server((onode['ip'], onode['port']),
self.ipport2server, self.pids)
kill_server((onode['ip'], onode['port']), self.ipport2server)
# Delete container/obj
try:
@ -218,8 +213,7 @@ class TestObjectHandoff(ReplProbeTest):
(cnode['ip'], cnode['port']))
# Restart the first container/obj primary server again
start_server((onode['ip'], onode['port']),
self.ipport2server, self.pids)
start_server((onode['ip'], onode['port']), self.ipport2server)
# Assert it still has container/obj
direct_client.direct_get_object(

View File

@ -30,9 +30,10 @@
import hmac
import itertools
import mock
import unittest
from hashlib import sha1
from time import time
from time import time, strftime, gmtime
from swift.common.middleware import tempauth, tempurl
from swift.common.header_key_dict import HeaderKeyDict
@ -135,6 +136,9 @@ class TestTempURL(unittest.TestCase):
self.assertEqual(resp.status_int, 200)
self.assertEqual(resp.headers['content-disposition'],
'attachment; filename="o"; ' + "filename*=UTF-8''o")
self.assertEqual(resp.headers['expires'],
strftime('%a, %d %b %Y %H:%M:%S GMT',
gmtime(expires)))
self.assertEqual(req.environ['swift.authorize_override'], True)
self.assertEqual(req.environ['REMOTE_USER'], '.wsgi.tempurl')
@ -183,9 +187,10 @@ class TestTempURL(unittest.TestCase):
for sig in (sig1, sig2):
self.assert_valid_sig(expires, path, account_keys, sig, environ)
def test_get_valid_with_filename(self):
@mock.patch('swift.common.middleware.tempurl.time', return_value=0)
def test_get_valid_with_filename(self, mock_time):
method = 'GET'
expires = int(time() + 86400)
expires = (((24 + 1) * 60 + 1) * 60) + 1
path = '/v1/a/c/o'
key = 'abc'
hmac_body = '%s\n%s\n%s' % (method, expires, path)
@ -199,10 +204,13 @@ class TestTempURL(unittest.TestCase):
self.assertEqual(resp.headers['content-disposition'],
'attachment; filename="bob %22killer%22.txt"; ' +
"filename*=UTF-8''bob%20%22killer%22.txt")
self.assertIn('expires', resp.headers)
self.assertEqual('Fri, 02 Jan 1970 01:01:01 GMT',
resp.headers['expires'])
self.assertEqual(req.environ['swift.authorize_override'], True)
self.assertEqual(req.environ['REMOTE_USER'], '.wsgi.tempurl')
def test_head_valid(self):
def test_head_valid_with_filename(self):
method = 'HEAD'
expires = int(time() + 86400)
path = '/v1/a/c/o'
@ -211,11 +219,14 @@ class TestTempURL(unittest.TestCase):
sig = hmac.new(key, hmac_body, sha1).hexdigest()
req = self._make_request(path, keys=[key], environ={
'REQUEST_METHOD': 'HEAD',
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s'
% (sig, expires)})
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&'
'filename=bob_killer.txt' % (sig, expires)})
self.tempurl.app = FakeApp(iter([('200 Ok', (), '123')]))
resp = req.get_response(self.tempurl)
self.assertEqual(resp.status_int, 200)
self.assertEqual(resp.headers['content-disposition'],
'attachment; filename="bob_killer.txt"; ' +
"filename*=UTF-8''bob_killer.txt")
def test_head_and_get_headers_match(self):
method = 'HEAD'
@ -242,9 +253,10 @@ class TestTempURL(unittest.TestCase):
get_resp = get_req.get_response(self.tempurl)
self.assertEqual(resp.headers, get_resp.headers)
def test_get_valid_with_filename_and_inline(self):
@mock.patch('swift.common.middleware.tempurl.time', return_value=0)
def test_get_valid_with_filename_and_inline(self, mock_time):
method = 'GET'
expires = int(time() + 86400)
expires = 1
path = '/v1/a/c/o'
key = 'abc'
hmac_body = '%s\n%s\n%s' % (method, expires, path)
@ -256,6 +268,9 @@ class TestTempURL(unittest.TestCase):
resp = req.get_response(self.tempurl)
self.assertEqual(resp.status_int, 200)
self.assertEqual(resp.headers['content-disposition'], 'inline')
self.assertIn('expires', resp.headers)
self.assertEqual('Thu, 01 Jan 1970 00:00:01 GMT',
resp.headers['expires'])
self.assertEqual(req.environ['swift.authorize_override'], True)
self.assertEqual(req.environ['REMOTE_USER'], '.wsgi.tempurl')
@ -273,6 +288,7 @@ class TestTempURL(unittest.TestCase):
resp = req.get_response(self.tempurl)
self.assertEqual(resp.status_int, 200)
self.assertEqual(resp.headers['content-disposition'], 'inline')
self.assertIn('expires', resp.headers)
self.assertEqual(req.environ['swift.authorize_override'], True)
self.assertEqual(req.environ['REMOTE_USER'], '.wsgi.tempurl')
@ -292,6 +308,7 @@ class TestTempURL(unittest.TestCase):
self.assertEqual(resp.headers['content-disposition'],
'attachment; filename="a%0D%0Ab"; ' +
"filename*=UTF-8''a%0D%0Ab")
self.assertIn('expires', resp.headers)
self.assertEqual(req.environ['swift.authorize_override'], True)
self.assertEqual(req.environ['REMOTE_USER'], '.wsgi.tempurl')
@ -311,6 +328,7 @@ class TestTempURL(unittest.TestCase):
self.assertEqual(resp.status_int, 200)
self.assertEqual(resp.headers['content-disposition'],
'attachment; filename="fu%0Abar"')
self.assertIn('expires', resp.headers)
self.assertEqual(req.environ['swift.authorize_override'], True)
self.assertEqual(req.environ['REMOTE_USER'], '.wsgi.tempurl')
@ -330,6 +348,7 @@ class TestTempURL(unittest.TestCase):
self.assertEqual(resp.headers['content-disposition'],
'attachment; filename="o"; ' +
"filename*=UTF-8''o")
self.assertIn('expires', resp.headers)
self.assertEqual(req.environ['swift.authorize_override'], True)
self.assertEqual(req.environ['REMOTE_USER'], '.wsgi.tempurl')
@ -350,6 +369,7 @@ class TestTempURL(unittest.TestCase):
resp.headers['content-disposition'],
'attachment; filename="/i/want/this/just/as/it/is/"; ' +
"filename*=UTF-8''/i/want/this/just/as/it/is/")
self.assertIn('expires', resp.headers)
self.assertEqual(req.environ['swift.authorize_override'], True)
self.assertEqual(req.environ['REMOTE_USER'], '.wsgi.tempurl')
@ -366,7 +386,8 @@ class TestTempURL(unittest.TestCase):
sig, expires)})
resp = req.get_response(self.tempurl)
self.assertEqual(resp.status_int, 404)
self.assertFalse('content-disposition' in resp.headers)
self.assertNotIn('content-disposition', resp.headers)
self.assertNotIn('expires', resp.headers)
self.assertEqual(req.environ['swift.authorize_override'], True)
self.assertEqual(req.environ['REMOTE_USER'], '.wsgi.tempurl')

View File

@ -507,21 +507,27 @@ class TestObjectController(unittest.TestCase):
headers_out, objdevice, policy):
calls_made.append((headers_out, policy))
body = 'test'
headers = {
'X-Timestamp': t[1].internal,
'Content-Type': 'application/octet-stream;swift_bytes=123456789',
'Content-Length': '4',
'X-Backend-Storage-Policy-Index': int(policy)}
if policy.policy_type == EC_POLICY:
# EC fragments will typically have a different size to the body and
# for small bodies the fragments may be longer. For this test all
# that matters is that the fragment and body lengths differ.
body = body + 'ec_overhead'
headers['X-Object-Sysmeta-Container-Update-Override-Etag'] = \
update_etag
headers['X-Object-Sysmeta-Container-Update-Override-Size'] = '4'
headers['X-Object-Sysmeta-Ec-Etag'] = update_etag
headers['X-Object-Sysmeta-Ec-Content-Length'] = '4'
headers['X-Object-Sysmeta-Ec-Frag-Index'] = 2
headers['Content-Length'] = str(len(body))
req = Request.blank('/sda1/p/a/c/o',
req = Request.blank('/sda1/p/a/c/o', body=body,
environ={'REQUEST_METHOD': 'PUT'},
headers=headers, body='test')
headers=headers)
with mock.patch('swift.obj.server.ObjectController.container_update',
mock_container_update):
resp = req.get_response(self.object_controller)
@ -725,10 +731,12 @@ class TestObjectController(unittest.TestCase):
# make PUT with given headers and verify correct etag is sent in
# container update
body = 'test ec overhead'
headers['X-Timestamp'] = ts_put.internal
headers['Content-Length'] = len(body)
req = Request.blank('/sda1/p/a/c/o',
environ={'REQUEST_METHOD': 'PUT'},
headers=headers, body='test')
headers=headers, body=body)
with mock.patch(
'swift.obj.server.ObjectController.container_update',
@ -774,13 +782,13 @@ class TestObjectController(unittest.TestCase):
base_headers = {
'Content-Type': 'application/octet-stream;swift_bytes=123456789',
'Content-Length': '4',
'X-Backend-Storage-Policy-Index': int(policy),
'X-Object-Sysmeta-Ec-Frag-Index': 2}
# PUT - old style headers are sufficient
headers = dict(base_headers)
headers['X-Backend-Container-Update-Override-Etag'] = 'expected'
headers['X-Object-Sysmeta-Container-Update-Override-Size'] = '4'
headers['X-Object-Sysmeta-Ec-Etag'] = 'expected'
do_test(headers)
@ -790,6 +798,7 @@ class TestObjectController(unittest.TestCase):
# update with the correct etag).
headers = dict(base_headers)
headers['X-Object-Sysmeta-Container-Update-Override-Etag'] = 'expected'
headers['X-Object-Sysmeta-Container-Update-Override-Size'] = '4'
do_test(headers)
# PUT - X-Object-Sysmeta-Container-Update-Override-Etag trumps
@ -797,6 +806,7 @@ class TestObjectController(unittest.TestCase):
headers = dict(base_headers)
headers['X-Object-Sysmeta-Ec-Etag'] = 'ec etag'
headers['X-Object-Sysmeta-Container-Update-Override-Etag'] = 'expected'
headers['X-Object-Sysmeta-Container-Update-Override-Size'] = '4'
do_test(headers)
def _test_PUT_then_POST_async_pendings(self, policy, update_etag=None):