130 Commits

Author SHA1 Message Date
Clay Gerrard
4601548dab Deprecate per-service auto_create_account_prefix
If we move it to constraints it's more globally accessible in our code,
but more importantly it's more obvious to ops that everything breaks if
you try to mis-configure different values per-service.

Change-Id: Ib8f7d08bc48da12be5671abe91a17ae2b49ecfee
2020-01-05 09:53:30 -06:00
Clay Gerrard
698717d886 Allow internal clients to use reserved namespace
Reserve the namespace starting with the NULL byte for internal
use-cases.  Backend services will allow path names to include the NULL
byte in urls and validate names in the reserved namespace.  Database
services will filter all names starting with the NULL byte from
responses unless the request includes the header:

    X-Backend-Allow-Reserved-Names: true

The proxy server will not allow path names to include the NULL byte in
urls unless a middlware has set the X-Backend-Allow-Reserved-Names
header.  Middlewares can use the reserved namespace to create objects
and containers that can not be directly manipulated by clients.  Any
objects and bytes created in the reserved namespace will be aggregated
to the user's account totals.

When deploying internal proxys developers and operators may configure
the gatekeeper middleware to translate the X-Allow-Reserved-Names header
to the Backend header so they can manipulate the reserved namespace
directly through the normal API.

UpgradeImpact: it's not safe to rollback from this change

Change-Id: If912f71d8b0d03369680374e8233da85d8d38f85
2019-11-27 11:22:00 -06:00
Tim Burke
d270596b67 Consistently use io.BytesIO
Change-Id: Ic41b37ac75b5596a8307c4962be86f2a4b0d9731
2019-10-15 15:09:46 +02:00
Tim Burke
1ded0d6c87 Allow arbitrary UTF-8 strings as delimiters in listings
AWS seems to support this, so let's allow s3api to do it, too.

Previously, S3 clients trying to use multi-character delimiters would
get 500s back, because s3api didn't know how to handle the 412s that the
container server would send.

As long as we're adding support for container listings, may as well do
it for accounts, too.

Change-Id: I62032ddd50a3493b8b99a40fb48d840ac763d0e7
Co-Authored-By: Thiago da Silva <thiagodasilva@gmail.com>
Closes-Bug: #1797305
2019-09-12 10:44:00 -07:00
Tim Burke
83d0161991 Add operator tool to async-delete some or all objects in a container
Adds a tool, swift-container-deleter, that takes an account/container
and optional prefix, marker, and/or end-marker; spins up an internal
client; makes listing requests against the container; and pushes the
found objects into the object-expirer queue with a special
application/async-deleted content-type.

In order to do this enqueuing efficiently, a new internal-to-the-cluster
container method is introduced: UPDATE. It takes a JSON list of object
entries and runs them through merge_items.

The object-expirer is updated to look for work items with this
content-type and skip the X-If-Deleted-At check that it would normally
do.

Note that the target-container's listing will continue to show the
objects until data is actually deleted, bypassing some of the concerns
raised in the related change about clearing out a container entirely and
then deleting it.

Change-Id: Ia13ee5da3d1b5c536eccaadc7a6fdcd997374443
Related-Change: I50e403dee75585fc1ff2bb385d6b2d2f13653cf8
2019-05-22 13:22:50 -07:00
Gilles Biannic
a4cc353375 Make log format for requests configurable
Add the log_msg_template option in proxy-server.conf and log_format in
a/c/o-server.conf. It is a string parsable by Python's format()
function. Some fields containing user data might be anonymized by using
log_anonymization_method and log_anonymization_salt.

Change-Id: I29e30ef45fe3f8a026e7897127ffae08a6a80cd9
2019-05-02 17:43:25 -06:00
Pete Zaitcev
575538b55b py3: port the container
This started with ShardRanges and its CLI. The sharder is at the
bottom of the dependency chain. Even container backend needs it.
Once we started tinkering with the sharder, it all snowballed to
include the rest of the container services.

Beware, this does affect some of Python 2 code. Mostly it's trivial
and obviously correct, but needs checking by reviewers.

About killing the stray "from __future__ import unicode_literals":
we do not do it in general. The specific problem it caused was
a failure of functional tests because unicode leaked into a field
that was supposed to be encoded. It is just too hard to track the
types when rules change from file to file, so off with its head.

Change-Id: Iba4e65d0e46d8c1f5a91feb96c2c07f99ca7c666
2019-02-20 21:30:46 -06:00
Samuel Merritt
8e651a2d3d Add fallocate_reserve to account and container servers.
The object server can be configured to leave a certain amount of disk
space free; default is 1%. This is useful in avoiding 100%-full
filesystems, as those can get Swift in a state where the filesystem is
too full to write tombstones, so you can't delete objects to free up
space.

When a cluster has accounts/containers and objects on the same disks,
then you can wind up with a 100%-full disk since account and container
servers don't respect fallocate_reserve. This commit makes account and
container servers respect fallocate_reserve so that disks shared
between account/container and object rings won't get 100% full.

When a disk's free space falls below the configured reserve, account
and container PUT, POST, and REPLICATE requests will fail with a 507
status code. These are the operations that can significantly increase
the disk space used by a given database.

I called the parameter "fallocate_reserve" for consistency with the
object server. No actual fallocate() call happens under Swift's
control in the account or container servers (sqlite3 might make such a
call, but it's out of our hands).

Change-Id: I083442eef14bf83c0ea717b1decb3e6b56dbf1d0
2018-07-18 17:27:11 +10:00
Tim Burke
f192f51d37 Have check_drive raise ValueError on errors
...which helps us differentiate between a drive that's not mounted vs.
not a dir better in log messages. We were already doing that a bit in
diskfile.py, and it seems like a useful distinction; let's do it more.

While we're at it, remove some log translations.

Related-Change: I941ffbc568ebfa5964d49964dc20c382a5e2ec2a
Related-Change: I3362a6ebff423016bb367b4b6b322bb41ae08764
Change-Id: Ife0d34f9482adb4524d1ab1fe6c335c6b287c2fd
Partial-Bug: 1674543
2018-06-20 17:15:07 -07:00
Alistair Coles
4a3efe61a9 Redirect object updates to shard containers
Enable the proxy to fetch a shard container location from the
container server in order to redirect an object update to the shard.

Enable the container server to redirect object updates to shard
containers.

Enable object updater to accept redirection of an object update.

Co-Authored-By: Matthew Oliver <matt@oliver.net.au>
Co-Authored-By: Tim Burke <tim.burke@gmail.com>
Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com>

Change-Id: I6ff85827eecdea746b3626c0d401f68139cce19d
2018-05-18 18:48:13 +01:00
Alistair Coles
723eac907c Add shard range support to container server
Support PUTs to container server with json serialized ShardRanges in
body.  Shard range PUTs may autocreate containers.

Support GET of shard ranges from container server.Shard range GETs
support X-Backend-Include-Deleted to include deleted shard ranges in
list and X-Backend-Override-Delete to get shard ranges when container
has been marked as deleted.

The X-Backend-Record-Type = ['object'|'shard'|'auto'] is introduced
to differentiate container server requests for object versus shard
ranges. When 'auto' is used with a GET request the container server
will return whichever record type is appropriate for fetchng object
listings, depending on whether the container is sharded or not.

Support container PUTs with body in direct_client .py

Co-Authored-By: Matthew Oliver <matt@oliver.net.au>
Co-Authored-By: Tim Burke <tim.burke@gmail.com>
Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com>

Change-Id: I029782ae348f38c5fb76d2759609f67a06c883ef
2018-05-18 18:48:01 +01:00
Alistair Coles
14af38a899 Add support for sharding in ContainerBroker
With this patch the ContainerBroker gains several new features:

1. A shard_ranges table to persist ShardRange data, along with
methods to merge and access ShardRange instances to that table,
and to remove expired shard ranges.

2. The ability to create a fresh db file to replace the existing db
file. Fresh db files are named using the hash of the container path
plus an epoch which is a serialized Timestamp value, in the form:

  <hash>_<epoch>.db

During sharding both the fresh and retiring db files co-exist on
disk. The ContainerBroker is now able to choose the newest on disk db
file when instantiated. It also provides a method (get_brokers()) to
gain access to broker instance for either on disk file.

3. Methods to access the current state of the on disk db files i.e.
UNSHARDED (old file only), SHARDING (fresh and retiring files), or
SHARDED (fresh file only with shard ranges).

Container replication is also modified:

1. shard ranges are replicated between container db peers. Unlike
objects, shard ranges are both pushed and pulled during a REPLICATE
event.

2. If a container db is capable of being sharded (i.e. it has a set of
shard ranges) then it will no longer attempt to replicate objects to
its peers. Object record durability is achieved by sharding rather than
peer to peer replication.

Co-Authored-By: Matthew Oliver <matt@oliver.net.au>
Co-Authored-By: Tim Burke <tim.burke@gmail.com>
Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com>

Change-Id: Ie4d2816259e6c25c346976e181fb9d350f947190
2018-05-18 18:42:38 +01:00
Alistair Coles
9d742b85ad Refactoring, test infrastructure changes and cleanup
...in preparation for the container sharding feature.

Co-Authored-By: Matthew Oliver <matt@oliver.net.au>
Co-Authored-By: Tim Burke <tim.burke@gmail.com>
Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com>

Change-Id: I4455677abb114a645cff93cd41b394d227e805de
2018-05-15 18:18:25 +01:00
Clay Gerrard
feee399840 Use check_drive consistently
We added check_drive to the account/container servers to unify how all
the storage wsgi servers treat device dirs/mounts.  Thus pushes that
unification down into the consistency engine.

Drive-by:
 * use FakeLogger less
 * clean up some repeititon in probe utility for device re-"mounting"

Related-Change-Id: I3362a6ebff423016bb367b4b6b322bb41ae08764
Change-Id: I941ffbc568ebfa5964d49964dc20c382a5e2ec2a
2017-11-01 16:33:40 +00:00
Tim Burke
c118059719 Respond 400 Bad Request when Accept headers fail to parse
Change-Id: I6eb4e4bca95e2ee4fecdb703394cb2419737922d
Closes-Bug: 1716509
2017-10-13 12:35:21 -07:00
Tim Burke
4806434cb0 Move listing formatting out to proxy middleware
Make some json -> (text, xml) stuff in a common module, reference that in
account/container servers so we don't break existing clients (including
out-of-date proxies), but have the proxy controllers always force a json
listing.

This simplifies operations on listings (such as the ones already happening in
decrypter, or the ones planned for symlink and sharding) by only needing to
consider a single response type.

There is a downside of larger backend requests for text/plain listings, but
it seems like a net win?

Change-Id: Id3ce37aa0402e2d8dd5784ce329d7cb4fbaf700d
2017-09-15 06:38:26 +00:00
Pavel Kvasnička
163fb4d52a Always require device dir for containers
For test purposes (e.g. saio probetests) even if mount_check is False,
still require check_dir for account/container server storage when real
mount points are not used.

This behavior is consistent with the object-server's checks in diskfile.

Co-Author: Clay Gerrard <clay.gerrard@gmail.com>
Related lp bug #1693005
Related-Change-Id: I344f9daaa038c6946be11e1cf8c4ef104a09e68b
Depends-On: I52c4ecb70b1ae47e613ba243da5a4d94e5adedf2
Change-Id: I3362a6ebff423016bb367b4b6b322bb41ae08764
2017-09-01 10:32:12 -07:00
shangxiaobj
c93c0c0c6e [Trivialfix]Fix typos in swift
Fix typos that found in swift.

Change-Id: I52fad1a4882cec4456f22174b46d54e42ec66d97
2017-08-04 07:50:10 +00:00
lingyongxu
ee9458a250 Using assertIsNone() instead of assertEqual(None)
Following OpenStack Style Guidelines:
[1] http://docs.openstack.org/developer/hacking/#unit-tests-and-assertraises
[H203] Unit test assertions tend to give better messages for more specific
assertions. As a result, assertIsNone(...) is preferred over
assertEqual(None, ...) and assertIs(..., None)

Change-Id: If4db8872c4f5705c1fff017c4891626e9ce4d1e4
2017-06-07 14:05:53 +08:00
Pete Zaitcev
5dfc3a75fb Open-code eventlet.listen()
Recently out gate started blowing up intermittently with a strange
case of ports mixed up. Sometimes a functional tests tries to
authorize on a port that's clearly an object server port, and
the like. As it turns out, eventlet developers added an unavoidable
SO_REUSEPORT into listen(), which makes listen(("localhost",0)
to reuse ports.

There's an issue about it:
 https://github.com/eventlet/eventlet/issues/411

This patch is working around the problem while eventlet people
consider the issue.

Change-Id: I67522909f96495a6a30e1acdb79835dce2189549
2017-05-11 01:39:14 -06:00
Cao Xuan Hoang
3da144a3af Replace 'assertTrue(a not in b)' with 'assertNotIn(a, b)'
trivialfix

Change-Id: I416831c8ad92f8445bc8d9560040a5ebf5c90702
2016-12-12 16:23:09 +07:00
Jenkins
a87b290137 Merge "More Test[Account|Container]Controller test updates" 2016-09-13 01:48:59 +00:00
Jenkins
531a6d46e0 Merge "Remove unnecessary open call and related vars in unit tests" 2016-09-06 18:12:40 +00:00
Christian Schwede
2a58b1efa4 More Test[Account|Container]Controller test updates
Added another test that tries to replicate using an unknown sync method,
with and without an existing DB file.

Change-Id: I09a86615f012e4341268ea30cbc06099528f896b
2016-09-01 09:47:14 +00:00
Jenkins
db5fd6470a Merge "Add unit case" 2016-08-31 13:57:12 +00:00
Kota Tsuyuzaki
eadab846b3 Remove unnecessary open call and related vars in unit tests
Since the methods touching exisiting file is mocked, we don't have to
open the file. (if it is needed, we should close at first anyway)

And cleanup unecessary vars/imports that is used for making the file
path.

This patch is a followup on:
https://review.openstack.org/#/c/350471/

Change-Id: I8fbc0b5b9a01782b6da5a7dd674f52d4b566ca5c
2016-08-04 23:42:21 -07:00
zheng yin
b1b410902d Add unit case
"op" has three judgments in ReplicatorRpc.dispatch, rsync_then_merge,complete_rsync
and other. But it only has two times judgments,including rsync_then_merge and other
in test_REPLICATE_works, so I add complete_rsync in test_account and test_container

Change-Id: I8277b556062dd6b30bf85dedd636d56517f10d8d
2016-08-04 19:24:44 +08:00
Kota Tsuyuzaki
fcb6e4cd3a Last-Modified header support on HEAD/GET container
This patch enables to show a x-put-timestamp as
a last-modified header in container-server.

Note that the last-modified header will be changed only when a
request for container (PUT container or POST container) comes into
Swift. i.e. some requests for objects (e.g. PUT object, POST object)
will never affect the last-modified value but only when using
python-swiftclient like as "swift upload", the last-modified will
be close to the upload time because python-swiftclient will make
a PUT container request for "swift upload" each time.

Change-Id: I9971bf90d24eee8921f67c02b7e2c80fd8995623
2016-06-07 12:02:03 +01:00
Alistair Coles
7b706926a8 Fix setup of manifest responses in SLO tests
The swift_bytes param is removed from the content-type
in the proxy object controller, so the SLO unit tests should
not be registering GET responses with FakeSwift that have
swift_bytes appended to the content-type.

Nor should submanifest segment dicts have swift_bytes appended to
their content-type values.

Also adds a test for the object controller and container server
handling of SLO swift_bytes.

Change-Id: Icf9bd87eee25002c8d9728b16e60c8347060f320
2016-05-23 17:26:28 +01:00
Jenkins
760dcfd53d Merge "Require account/container metadata be UTF-8" 2016-04-20 19:30:22 +00:00
Jenkins
f227072974 Merge "Correctly handle keys starting with the delimiter." 2016-04-01 02:02:44 +00:00
Samuel Merritt
9430f4c9f5 Move HeaderKeyDict to avoid an inline import
There was a function in swift.common.utils that was importing
swob.HeaderKeyDict at call time. It couldn't import it at compilation
time since utils can't import from swob or else it blows up with a
circular import error.

This commit just moves HeaderKeyDict into swift.common.header_key_dict
so that we can remove the inline import.

Change-Id: I656fde8cc2e125327c26c589cf1045cb81ffc7e5
2016-03-07 12:26:48 -08:00
Alistair Coles
e91de49d68 Update container on fast-POST
This patch makes a number of changes to enable content-type
metadata to be updated when using the fast-POST mode of
operation, as proposed in the associated spec [1].

* the object server and diskfile are modified to allow
  content-type to be updated by a POST and the updated value
  to be stored in .meta files.

* the object server accepts PUTs and DELETEs with older
  timestamps than existing .meta files. This is to be
  consistent with replication that will leave a later .meta
  file in place when replicating a .data file.

* the diskfile interface is modified to provide accessor
  methods for the content-type and its timestamp.

* the naming of .meta files is modified to encode two
  timestamps when the .meta file contains a content-type value
  that was set prior to the latest metadata update; this
  enables consistency to be achieved when rsync is used for
  replication.

* ssync is modified to sync meta files when content-type
  differs between local and remote copies of objects.

* the object server issues container updates when handling
  POST requests, notifying the container server of the current
  immutable metadata (etag, size, hash, swift_bytes),
  content-type with their respective timestamps, and the
  mutable metadata timestamp.

* the container server maintains the most recently reported
  values for immutable metadata, content-type and mutable
  metadata, each with their respective timestamps, in a single
  db row.

* new probe tests verify that replication achieves eventual
  consistency of containers and objects after discrete updates
  to content-type and mutable metadata, and that container-sync
  sync's objects after fast-post updates.

[1] spec change-id: I60688efc3df692d3a39557114dca8c5490f7837e

Change-Id: Ia597cd460bb5fd40aa92e886e3e18a7542603d01
2016-03-03 14:25:10 +00:00
Tim Burke
fe70898dac Require account/container metadata be UTF-8
Otherwise, we get a UnicodeDecodeError when we call json.dumps()

Change-Id: Ie200d029e1fd7f0ff0956c8ced98207e11ef9080
2016-02-29 10:27:29 +00:00
Timur Alperovich
432e280aef Correctly handle keys starting with the delimiter.
When processing keys where the names start with the delimiter
character, swift should list only the delimiter character. To get the
list of nested keys, the caller should also supply the prefix which is
equal to the delimiter.

Added a functional test and unit tests to verify this behavior.

Fixes Bug: 1475018

Change-Id: I27701a31bfa22842c272b7781738e8c546b82cbc
2016-01-06 12:29:20 -08:00
Eran Rom
85a0a6a28e Container-Sync to iterate only over synced containers
This change introduces a sync_store which holds only containers that
are enabled for sync. The store is implemented using a directory
structure that resembles that of the containers directory, but has
entries only for containers enabled for sync.
The store is maintained in two ways:
1. Preemptively by the container server when processing
PUT/POST/DELETE operations targeted at containers with
x-container-sync-key / x-container-sync-to
2. In the background using the containers replicator
whenever it processes a container set up for sync

The change updates [1]
[1] http://docs.openstack.org/developer/swift/overview_container_sync.html

Change-Id: I9ae4d4c7ff6336611df4122b7c753cc4fa46c0ff
Closes-Bug: #1476623
2016-01-06 16:46:31 +02:00
Zack M. Davis
1b8b08039a remove remaining simplejson uses, prefer standard library import
a1c32702, 736cf54a, and 38787d0f remove uses of `simplejson` from
various parts of Swift in favor of the standard libary `json`
module (introduced in Python 2.6). This commit performs the remaining
`simplejson` to `json` replacements, removes two comments highlighting
quirks of simplejson with respect to Unicode, and removes the references
to it in setup documentation and requirements.txt.

There were a lot of places where we were importing json from
swift.common.utils, which is less intuitive than a direct `import json`,
so that replacement is made as well.

(And in two more tiny drive-bys, we add some pretty-indenting to an XML
fragment and use `super` rather than naming a base class explicitly.)

Change-Id: I769e88dda7f76ce15cf7ce930dc1874d24f9498a
2015-11-16 12:34:24 -08:00
Sivasathurappan Radhakrishnan
ce173e9ed2 Added unit test cases for server.py
Added unit test cases to cover all code paths in REPLICATE and __call__
functions in account/server.py and container/server.py

Change-Id: Ia335e9a6668821d3e34b12fc3a133a707880e87f
2015-11-10 21:38:47 +00:00
Lisak, Peter
b6b7578190 node_timeout as float in configs
It is more convenient to use float node_timeout for fine tunning latency.

Change-Id: I7c57bba053711a27d3802efe6f2a0bf53483a54f
2015-10-19 21:14:34 +02:00
janonymous
f5f9d791b0 pep8 fix: assertEquals -> assertEqual
assertEquals is deprecated in py3, replacing it.

Change-Id: Ida206abbb13c320095bb9e3b25a2b66cc31bfba8
Co-Authored-By: Ondřej Nový <ondrej.novy@firma.seznam.cz>
2015-10-11 12:57:25 +02:00
Victor Stinner
f2cac20d17 py3: Replace unicode with six.text_type
The unicode type was renamed to str in Python 3. Use six.text_type to
make the modified code compatible with Python 2 and Python 3.

The initial patch was generated by the unicode operation of the sixer
tool on: bin/* swift/ test/.

Change-Id: I9e13748ccde36ee8110756202d55d3ae945d4860
2015-10-08 13:16:43 +02:00
Kota Tsuyuzaki
4de6e32bca Change POST container semantics
To achieve last modified header on GETorHEAD container
we should allow POST container to overwrite put-timestamp.
That is because following patches will change the the put-timestamp
value semantics in both container db and account db as "container
last modified".

If we achieved this and followings, we will be able to retrieve the
container timestamp which is suggested when the container metadata
modified.

Example:
- Create a container.
- Change the ACL with POST container. (e.g. x-container-read)
- After that, we can know the container was changed by comparing
  between the timestamp from container creation and the last modified
  generated from put-timestamp.

Change-Id: I1a545fcd1896798dfa7cb5e5af97c78f5d7d7e4d
2015-08-12 08:26:28 -07:00
janonymous
ed3aec2146 pep8 fix: assertEquals -> assertEqual
assertEquals is deprecated in py3 in
dir: test/unit/container/*

Change-Id: I3333022ed63ce03198bc73147246d91d2442a440
2015-08-06 00:18:52 +05:30
Victor Stinner
389a97e352 Fix pep8 E warning for hacking 0.10
Fix pep8 warnings of the E category of hacking 0.10:

* E113: unexpected indentation
* E121: continuation line under-indented for hanging indent
* E122: continuation line missing indentation or outdented
* E123: closing bracket does not match indentation of opening bracket's
  line
* E126: continuation line over-indented for hanging indent
* E251: unexpected spaces around keyword / parameter equals

Change-Id: I0b24eebdf1a37dc1b572b6c9a3d3d4832d050237
2015-07-30 09:33:41 +02:00
Victor Stinner
d719064e78 Fix warning pep8 E128 warning of hacking 0.10
Fix the warning E128: "continuation line under-indented for visual
indent" of pep8.

Change-Id: Ie6c6ae341fe3d6281f2095c1d756d552fa5937f9
2015-07-30 09:33:41 +02:00
Jenkins
187cea5445 Merge "Replace StringIO with BytesIO for WSGI input" 2015-07-24 06:52:40 +00:00
Jenkins
260e976e50 Merge "Get StringIO and cStringIO from six.moves" 2015-07-24 06:52:36 +00:00
janonymous
cd7b2db550 unit tests: Replace "self.assert_" by "self.assertTrue"
The assert_() method is deprecated and can be safely replaced by assertTrue().
This patch makes sure that running the tests does not create undesired
warnings.

Change-Id: I0602ba39ef93263386644ee68088d5f65fcb4a71
2015-07-21 19:23:00 +05:30
Victor Stinner
8753e452b0 Replace StringIO with BytesIO for WSGI input
wsgi.input is a binary stream (bytes), not a text stream (unicode).

* Replace StringIO with BytesIO for WSGI input
* Replace StringIO('') with StringIO() and replace WsgiStringIO('') with
  WsgiStringIO(): an empty string is already the default value

Change-Id: I09c9527be2265a6847189aeeb74a17261ddc781a
2015-07-15 16:56:33 +02:00
Victor Stinner
6e70f3fa32 Get StringIO and cStringIO from six.moves
* replace "from cStringIO import StringIO"
  with "from six.moves import cStringIO as StringIO"
* replace "from StringIO import StringIO"
  with "from six import StringIO"
* replace "import cStringIO" and "cStringIO.StringIO()"
  with "from six import moves" and "moves.cStringIO()"
* replace "import StringIO" and "StringIO.StringIO()"
  with "import six" and "six.StringIO()"

This patch was generated by the stringio operation of the sixer tool:
https://pypi.python.org/pypi/sixer

Change-Id: Iacba77fec3045f96773d1090c0bd48613729a561
2015-07-15 16:56:33 +02:00