summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS7
-rw-r--r--ChangeLog28
-rw-r--r--README.rst2
-rw-r--r--bindep.txt5
-rw-r--r--doc/manpages/swift.112
-rw-r--r--doc/source/cli.rst442
-rw-r--r--doc/source/cli/index.rst960
-rw-r--r--doc/source/index.rst2
-rw-r--r--releasenotes/notes/340_notes-1777780bbfdb4d96.yaml20
-rw-r--r--releasenotes/source/conf.py356
-rw-r--r--releasenotes/source/current.rst5
-rw-r--r--releasenotes/source/index.rst11
-rw-r--r--releasenotes/source/newton.rst6
-rw-r--r--releasenotes/source/ocata.rst6
-rw-r--r--releasenotes/source/pike.rst6
-rw-r--r--setup.cfg2
-rw-r--r--swiftclient/client.py17
-rw-r--r--swiftclient/service.py25
-rwxr-xr-xswiftclient/shell.py35
-rw-r--r--test-requirements.txt2
-rw-r--r--tests/unit/test_service.py52
-rw-r--r--tests/unit/test_shell.py53
-rw-r--r--tests/unit/test_swiftclient.py20
-rwxr-xr-xtools/tox_install.sh41
-rw-r--r--tox.ini9
25 files changed, 1625 insertions, 499 deletions
diff --git a/AUTHORS b/AUTHORS
index 7c162e0..bf69dba 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -65,11 +65,14 @@ Josh Gachnang (josh@pcsforeducation.com)
Juan J. Martinez (juan@memset.com)
Jude Job (judeopenstack@gmail.com)
Julien Danjou (julien@danjou.info)
+Kazufumi Noto (noto.kazufumi@gmail.com)
Kota Tsuyuzaki (tsuyuzaki.kota@lab.ntt.co.jp)
Kun Huang (gareth@unitedstack.com)
Leah Klearman (lklrmn@gmail.com)
Li Riqiang (lrqrun@gmail.com)
+liuyamin (liuyamin@fiberhome.com)
Luis de Bethencourt (luis@debethencourt.com)
+M V P Nitesh (m.nitesh@nectechnologies.in)
Mahati Chamarthy (mahati.chamarthy@gmail.com)
Marek Kaleta (marek.kaleta@firma.seznam.cz)
Mark Seger (mark.seger@hpe.com)
@@ -82,6 +85,7 @@ Min Min Ren (rminmin@cn.ibm.com)
Mohit Motiani (mohit.motiani@intel.com)
Monty Taylor (mordred@inaugust.com)
Nandini Tata (nandini.tata@intel.com)
+Nelson Marcos (nelsonmarcos@gmail.com)
Nguyen Hung Phuong (phuongnh@vn.fujitsu.com)
Nick Craig-Wood (nick@craig-wood.com)
Ondrej Novy (ondrej.novy@firma.seznam.cz)
@@ -90,6 +94,7 @@ Paul Belanger (pabelanger@redhat.com)
Paulo Ewerton (pauloewerton@lsd.ufcg.edu.br)
Pete Zaitcev (zaitcev@kotori.zaitcev.us)
Peter Lisak (peter.lisak@firma.seznam.cz)
+Petr Kovar (pkovar@redhat.com)
Pradeep Kumar Singh (pradeep.singh@nectechnologies.in)
Pratik Mallya (pratik.mallya@gmail.com)
Qiu Yu (qiuyu@ebaysf.com)
@@ -120,12 +125,14 @@ Thiago da Silva (thiago@redhat.com)
Thomas Goirand (thomas@goirand.fr)
Tihomir Trifonov (t.trifonov@gmail.com)
Tim Burke (tim.burke@gmail.com)
+Timur Alperovich (timuralp@swiftstack.com)
Tong Li (litong01@us.ibm.com)
Tony Breeds (tony@bakeyournoodle.com)
Tristan Cacqueray (tristan.cacqueray@enovance.com)
Vasyl Khomenko (vasiliyk@yahoo-inc.com)
venkatamahesh (venkatamaheshkotha@gmail.com)
Victor Stinner (victor.stinner@enovance.com)
+Vitaly Gridnev (vgridnev@mirantis.com)
wangxiyuan (wangxiyuan@huawei.com)
Wu Wenxiang (wu.wenxiang@99cloud.net)
YangLei (yanglyy@cn.ibm.com)
diff --git a/ChangeLog b/ChangeLog
index 749d22c..967d7e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+3.4.0
+-----
+
+* The `swift` CLI now supports streaming from stdin. If "-" is given
+ as the source, the object content is read from stdin. The
+ `--object-name` must be given when content is loaded from stdin.
+
+* Tolerate RFC-compliant ETags returned from the server.
+
+* Skip checksum validation on partial downloads.
+
+* Buffer reads from disk, resulting in much faster upload throughput.
+
+* Added support for ISO 8601 timestamps for tempurl, matching the
+ feature in Swift 2.13.0.
+
+* Added an option to ignore mtime metadata entry (`--ignore-mtime`).
+
+* When using SwiftService to delete many objects, the bulk delete page
+ size will now be respected. Previously, exceeding this limit would
+ prevent any objects from being deleted.
+
+* Expose `--prefix` as an option for st_delete.
+
+* Imported docs content from openstack-manuals project.
+
+* Various other minor bug fixes and improvements.
+
3.3.0
-----
diff --git a/README.rst b/README.rst
index 42ec277..3810439 100644
--- a/README.rst
+++ b/README.rst
@@ -43,7 +43,7 @@ __ http://github.com/openstack/swift
* `How to Contribute`_
.. _PyPI: https://pypi.python.org/pypi/python-swiftclient
-.. _Online Documentation: http://docs.openstack.org/developer/python-swiftclient
+.. _Online Documentation: https://docs.openstack.org/python-swiftclient/latest/
.. _Launchpad project: https://launchpad.net/python-swiftclient
.. _Blueprints: https://blueprints.launchpad.net/python-swiftclient
.. _Bugs: https://bugs.launchpad.net/python-swiftclient
diff --git a/bindep.txt b/bindep.txt
index e3ea9c1..cc3a770 100644
--- a/bindep.txt
+++ b/bindep.txt
@@ -2,5 +2,6 @@
# see http://docs.openstack.org/infra/bindep/ for additional information.
curl
-pypy [test]
-pypy-dev [test]
+pypy [test !platform:fedora]
+pypy-dev [test platform:dpkg]
+pypy-devel [test platform:rpm !platform:fedora]
diff --git a/doc/manpages/swift.1 b/doc/manpages/swift.1
index 1f288d6..00e1440 100644
--- a/doc/manpages/swift.1
+++ b/doc/manpages/swift.1
@@ -63,8 +63,11 @@ Uploads to the given container the files and directories specified by the
remaining args. The \-c or \-\-changed is an option that will only upload files
that have changed since the last upload. The \-\-object\-name <object\-name> is
an option that will upload file and name object to <object\-name> or upload dir
-and use <object\-name> as object prefix. The \-S <size> or \-\-segment\-size <size>
-and \-\-leave\-segments and others are options as well (see swift upload \-\-help for more).
+and use <object\-name> as object prefix. If the file name is "-", reads the
+content from standard input. In this case, \-\-object\-name is required and no
+other files may be given. The \-S <size> or \-\-segment\-size <size> and
+\-\-leave\-segments and others are options as well (see swift upload \-\-help
+for more).
.RE
\fBpost\fR [\fIcommand-options\fR] [\fIcontainer\fR] [\fIobject\fR]
@@ -102,6 +105,9 @@ with \-\-no-download actually not to write anything to disk.
The \-\-ignore-checksum is an option that turns off checksum validation.
You can specify optional headers with the repeatable cURL-like option
\-H [\-\-header]. For more details and options see swift download \-\-help.
+The \-\-ignore\-mtime option ignores the x\-object\-meta\-mtime metadata entry
+on the object (if present) and instead creates the downloaded files with
+fresh atime and mtime values.
.RE
\fBdelete\fR [\fIcommand-options\fR] [\fIcontainer\fR] [\fIobject\fR] [\fIobject\fR] [...]
@@ -205,4 +211,4 @@ swift \-A https://127.0.0.1:443/auth/v1.0 \-U swiftops:swiftops \-K swiftops sta
.SH DOCUMENTATION
.LP
More in depth documentation about OpenStack Swift as a whole can be found at
-.BI https://docs.openstack.org/developer/swift
+.BI https://docs.openstack.org/swift/latest/
diff --git a/doc/source/cli.rst b/doc/source/cli.rst
deleted file mode 100644
index 8d80d1b..0000000
--- a/doc/source/cli.rst
+++ /dev/null
@@ -1,442 +0,0 @@
-====
-CLI
-====
-
-The ``swift`` tool is a command line utility for communicating with an OpenStack
-Object Storage (swift) environment. It allows one to perform several types of
-operations.
-
-Authentication
-~~~~~~~~~~~~~~
-
-This section covers the options for authenticating with a swift
-object store. The combinations of options required for each authentication
-version are detailed below, but are just a subset of those that can be used
-to successfully authenticate. These are the most common and recommended
-combinations.
-
-You should obtain the details of your authentication version and credentials
-from your storage provider. These details should make it clearer which of the
-authentication sections below are most likely to allow you to connect to your
-storage account.
-
-Keystone v3
------------
-
-.. code-block:: bash
-
- swift --os-auth-url https://api.example.com:5000/v3 --auth-version 3 \
- --os-project-name project1 --os-project-domain-name domain1 \
- --os-username user --os-user-domain-name domain1 \
- --os-password password list
-
- swift --os-auth-url https://api.example.com:5000/v3 --auth-version 3 \
- --os-project-id 0123456789abcdef0123456789abcdef \
- --os-user-id abcdef0123456789abcdef0123456789 \
- --os-password password list
-
-Manually specifying the options above on the command line can be avoided by
-setting the following combinations of environment variables:
-
-.. code-block:: bash
-
- ST_AUTH_VERSION=3
- OS_USERNAME=user
- OS_USER_DOMAIN_NAME=domain1
- OS_PASSWORD=password
- OS_PROJECT_NAME=project1
- OS_PROJECT_DOMAIN_NAME=domain1
- OS_AUTH_URL=https://api.example.com:5000/v3
-
- ST_AUTH_VERSION=3
- OS_USER_ID=abcdef0123456789abcdef0123456789
- OS_PASSWORD=password
- OS_PROJECT_ID=0123456789abcdef0123456789abcdef
- OS_AUTH_URL=https://api.example.com:5000/v3
-
-Keystone v2
------------
-
-.. code-block:: bash
-
- swift --os-auth-url https://api.example.com:5000/v2.0 \
- --os-tenant-name tenant \
- --os-username user --os-password password list
-
-Manually specifying the options above on the command line can be avoided by
-setting the following environment variables:
-
-.. code-block:: bash
-
- ST_AUTH_VERSION=2.0
- OS_USERNAME=user
- OS_PASSWORD=password
- OS_TENANT_NAME=tenant
- OS_AUTH_URL=https://api.example.com:5000/v2.0
-
-Legacy auth systems
--------------------
-
-You can configure swift to work with any number of other authentication systems
-that we will not cover in this document. If your storage provider is not using
-Keystone to provide access tokens, please contact them for instructions on the
-required options. It is likely that the options will need to be specified as
-below:
-
-.. code-block:: bash
-
- swift -A https://api.example.com/v1.0 -U user -K api_key list
-
-Specifying the options above manually on the command line can be avoided by
-setting the following environment variables:
-
-.. code-block:: bash
-
- ST_AUTH_VERSION=1.0
- ST_AUTH=https://api.example.com/v1.0
- ST_USER=user
- ST_KEY=key
-
-It is also possible that you need to use a completely separate auth system, in which
-case ``swiftclient`` cannot request a token for you. In this case you should make the
-authentication request separately and access your storage using the token and
-storage URL options shown below:
-
-.. code-block:: bash
-
- swift --os-auth-token 6ee5eb33efad4e45ab46806eac010566 \
- --os-storage-url https://10.1.5.2:8080/v1/AUTH_ced809b6a4baea7aeab61a \
- list
-
-.. We need the backslash below in order to indent the note
-\
-
- .. note::
-
- Leftover environment variables are a common source of confusion when
- authorization fails.
-
-CLI commands
-~~~~~~~~~~~~
-
-Stat
-----
-
- ``stat [container [object]]``
-
- Displays information for the account, container, or object depending on
- the arguments given (if any). In verbose mode, the storage URL and the
- authentication token are displayed as well.
-
-List
-----
-
- ``list [command-options] [container]``
-
- Lists the containers for the account or the objects for a container.
- The ``-p <prefix>`` or ``--prefix <prefix>`` is an option that will only
- list items beginning with that prefix. The ``-d <delimiter>`` or
- ``--delimiter <delimiter>`` is an option (for container listings only)
- that will roll up items with the given delimiter (see `OpenStack Swift
- general documentation <http://docs.openstack.org/developer/swift/>` for
- what this means).
-
- The ``-l`` and ``--lh`` options provide more detail, similar to ``ls -l``
- and ``ls -lh``, the latter providing sizes in human readable format
- (For example: ``3K``, ``12M``, etc). The latter two switches use more
- overhead to retrieve the displayed details, which is directly proportional
- to the number of container or objects listed.
-
-Upload
-------
-
- ``upload [command-options] container file_or_directory [file_or_directory] [...]``
-
- Uploads the files and directories specified by the remaining arguments to the
- given container. The ``-c`` or ``--changed`` is an option that will only
- upload files that have changed since the last upload. The
- ``--object-name <object-name>`` is an option that will upload a file and
- name object to ``<object-name>`` or upload a directory and use ``<object-name>``
- as object prefix. The ``-S <size>`` or ``--segment-size <size>`` and
- ``--leave-segments`` are options as well (see ``--help`` for more).
-
-Post
-----
-
- ``post [command-options] [container] [object]``
-
- Updates meta information for the account, container, or object depending
- on the arguments given. If the container is not found, the ``swiftclient``
- will create it automatically, but this is not true for accounts and
- objects. Containers also allow the ``-r <read-acl>`` (or ``--read-acl
- <read-acl>``) and ``-w <write-acl>`` (or ``--write-acl <write-acl>``) options.
- The ``-m`` or ``--meta`` option is allowed on accounts, containers and objects,
- and is used to define the user metadata items to set in the form ``Name:Value``.
- You can repeat this option. For example: ``post -m Color:Blue -m Size:Large``
-
- For more information about ACL formats see the documentation:
- `ACLs <http://docs.openstack.org/developer/swift/misc.html#acls/>`_.
-
-Download
---------
-
- ``download [command-options] [container] [object] [object] [...]``
-
- Downloads everything in the account (with ``--all``), or everything in a
- container, or a list of objects depending on the arguments given. For a
- single object download, you may use the ``-o <filename>`` or ``--output <filename>``
- option to redirect the output to a specific file or ``-`` to
- redirect to stdout. The ``--ignore-checksum`` is an option that turn off
- checksum validation. You can specify optional headers with the repeatable
- cURL-like option ``-H [--header <name:value>]``.
-
-Delete
-------
-
- ``delete [command-options] [container] [object] [object] [...]``
-
- Deletes everything in the account (with ``--all``), or everything in a
- container, or a list of objects depending on the arguments given. Segments
- of manifest objects will be deleted as well, unless you specify the
- ``--leave-segments`` option.
-
-Copy
-----
-
- ``copy [command-options] container object``
-
- Copies an object to a new destination or adds user metadata to an object. Depending
- on the options supplied, you can preserve existing metadata in contrast to the post
- command. The ``--destination`` option sets the copy target destination in the form
- ``/container/object``. If not set, the object will be copied onto itself which is useful
- for adding metadata. You can use the ``-M`` or ``--fresh-metadata`` option to copy
- an object without existing user meta data, and the ``-m`` or ``--meta`` option
- to define user meta data items to set in the form ``Name:Value``. You can repeat
- this option. For example: ``copy -m Color:Blue -m Size:Large``.
-
-Capabilities
-------------
-
- ``capabilities [proxy-url]``
-
- Displays cluster capabilities. The output includes the list of the
- activated Swift middlewares as well as relevant options for each ones.
- Additionally the command displays relevant options for the Swift core. If
- the ``proxy-url`` option is not provided, the storage URL retrieved after
- authentication is used as ``proxy-url``.
-
-Tempurl
--------
-
- ``tempurl [command-options] [method] [time] [path] [key]``
-
- Generates a temporary URL for a Swift object. ``method`` option sets an HTTP method to
- allow for this temporary URL that is usually ``GET` or ``PUT``. ``time`` option sets
- the amount of time the temporary URL will be valid for.
- ``time`` can be specified as an integer, denoting the number of seconds
- from now on until the URL shall be valid; or, if ``--absolute``
- is passed, the Unix timestamp when the temporary URL will expire.
- But beyond that, ``time`` can also be specified as an ISO 8601 timestamp
- in one of following formats:
-
- i) Complete date: YYYY-MM-DD (eg 1997-07-16)
-
- ii) Complete date plus hours, minutes and seconds:
- YYYY-MM-DDThh:mm:ss
- (eg 1997-07-16T19:20:30)
-
- iii) Complete date plus hours, minutes and seconds with UTC designator:
- YYYY-MM-DDThh:mm:ssZ
- (eg 1997-07-16T19:20:30Z)
-
- Please be aware that if you don't provide the UTC designator (i.e., Z)
- the timestamp is generated using your local timezone. If only a date is
- specified, the time part used will equal to ``00:00:00``.
-
- ``path`` option sets the full path to the Swift object.
- Example: ``/v1/AUTH_account/c/o``. ``key`` option is
- the secret temporary URL key set on the Swift cluster. To set a key, run
- ``swift post -m "Temp-URL-Key: <your secret key>"``. To generate a prefix-based temporary
- URL use the ``--prefix-based`` option. This URL will contain the path to the prefix. Do not
- forget to append the desired objectname at the end of the path portion (and before the
- query portion) before sharing the URL. It is possible to use ISO 8601 UTC timestamps within the
- URL by using the ``--iso8601`` option.
-
-Auth
-----
-
- ``auth``
-
- Display authentication variables in shell friendly format. Command to run to export storage
- URL and auth token into ``OS_STORAGE_URL`` and ``OS_AUTH_TOKEN``: ``swift auth``.
- Command to append to a runcom file (e.g. ``~/.bashrc``, ``/etc/profile``) for automatic
- authentication: ``swift auth -v -U test:tester -K testing``.
-
-Examples
-~~~~~~~~
-
-In this section we present some example usage of the ``swift`` CLI. To keep the
-examples as short as possible, these examples assume that the relevant authentication
-options have been set using environment variables. You can obtain the full list of
-commands and options available in the ``swift`` CLI by executing the following:
-
-.. code-block:: bash
-
- > swift --help
- > swift <command> --help
-
-Simple examples
----------------
-
-List the existing swift containers:
-
-.. code-block:: bash
-
- > swift list
-
- container_1
-
-Create a new container:
-
-.. code-block:: bash
-
- > swift post TestContainer
-
-Upload an object into a container:
-
-.. code-block:: bash
-
- > swift upload TestContainer testSwift.txt
-
- testSwift.txt
-
-List the contents of a container:
-
-.. code-block:: bash
-
- > swift list TestContainer
-
- testSwift.txt
-
-Copy an object to new destination:
-
-.. code-block:: bash
-
- > swift copy -d /DestContainer/testSwift.txt SourceContainer testSwift.txt
-
- SourceContainer/testSwift.txt copied to /DestContainer/testSwift.txt
-
-Delete an object from a container:
-
-.. code-block:: bash
-
- > swift delete TestContainer testSwift.txt
-
- testSwift.txt
-
-Delete a container:
-
-.. code-block:: bash
-
- > swift delete TestContainer
-
- TestContainer
-
-Display auth related authentication variables in shell friendly format:
-
-.. code-block:: bash
-
- > swift auth
-
- export OS_STORAGE_URL=http://127.0.0.1:8080/v1/AUTH_bf5e63572f7a420a83fcf0aa8c72c2c7
- export OS_AUTH_TOKEN=c597015ae19943a18438b52ef3762e79
-
-Download an object from a container:
-
-.. code-block:: bash
-
- > swift download TestContainer testSwift.txt
-
- testSwift.txt [auth 0.028s, headers 0.045s, total 0.045s, 0.002 MB/s]
-
-.. We need the backslash below in order to indent the note
-\
-
- .. note::
-
- To upload an object to a container, your current working directory must be
- where the file is located or you must provide the complete path to the file.
- In other words, the --object-name <object-name> is an option that will upload
- file and name object to <object-name> or upload directory and use <object-name> as
- object prefix. In the case that you provide the complete path of the file,
- that complete path will be the name of the uploaded object.
-
-For example:
-
-.. code-block:: bash
-
- > swift upload TestContainer /home/swift/testSwift/testSwift.txt
-
- home/swift/testSwift/testSwift.txt
-
- > swift list TestContainer
-
- home/swift/testSwift/testSwift.txt
-
-More complex examples
----------------------
-
-Swift has a single object size limit of 5GiB. In order to upload files larger
-than this, we must create a large object that consists of smaller segments.
-The example below shows how to upload a large video file as a static large
-object in 1GiB segments:
-
-.. code-block:: bash
-
- > swift upload videos --use-slo --segment-size 1G myvideo.mp4
-
- myvideo.mp4 segment 8
- myvideo.mp4 segment 4
- myvideo.mp4 segment 2
- myvideo.mp4 segment 7
- myvideo.mp4 segment 0
- myvideo.mp4 segment 1
- myvideo.mp4 segment 3
- myvideo.mp4 segment 6
- myvideo.mp4 segment 5
- myvideo.mp4
-
-This command will upload segments to a container named ``videos_segments``, and
-create a manifest file describing the entire object in the ``videos`` container.
-For more information on large objects, see the documentation `here
-<http://docs.openstack.org/developer/swift/overview_large_objects.html>`_.
-
-.. code-block:: bash
-
- > swift list videos
-
- myvideo.mp4
-
- > swift list videos_segments
-
- myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000000
- myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000001
- myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000002
- myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000003
- myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000004
- myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000005
- myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000006
- myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000007
- myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000008
-
-Firstly, the key should be set, then generate a temporary URL for a Swift object:
-
-.. code-block:: bash
-
- > swift post -m "Temp-URL-Key:b3968d0207b54ece87cccc06515a89d4"
-
- > swift tempurl GET 6000 /v1/AUTH_bf5e63572f7a420a83fcf0aa8c72c2c7\
- /firstcontainer/clean.sh b3968d0207b54ece87cccc06515a89d4
-
- /v1/AUTH_/firstcontainer/clean.sh?temp_url_sig=\
- 9218fc288cc09e5edd857b6a3d43cf2122b906dc&temp_url_expires=1472203614
diff --git a/doc/source/cli/index.rst b/doc/source/cli/index.rst
new file mode 100644
index 0000000..bec1f5e
--- /dev/null
+++ b/doc/source/cli/index.rst
@@ -0,0 +1,960 @@
+====
+CLI
+====
+
+The ``swift`` tool is a command line utility for communicating with an OpenStack
+Object Storage (swift) environment. It allows one to perform several types of
+operations.
+
+
+For help on a specific :command:`swift` command, enter:
+
+.. code-block:: console
+
+ $ swift COMMAND --help
+
+.. _swift_command_usage:
+
+swift usage
+~~~~~~~~~~~
+
+.. code-block:: console
+
+ Usage: swift [--version] [--help] [--os-help] [--snet] [--verbose]
+ [--debug] [--info] [--quiet] [--auth <auth_url>]
+ [--auth-version <auth_version> |
+ --os-identity-api-version <auth_version> ]
+ [--user <username>]
+ [--key <api_key>] [--retries <num_retries>]
+ [--os-username <auth-user-name>] [--os-password <auth-password>]
+ [--os-user-id <auth-user-id>]
+ [--os-user-domain-id <auth-user-domain-id>]
+ [--os-user-domain-name <auth-user-domain-name>]
+ [--os-tenant-id <auth-tenant-id>]
+ [--os-tenant-name <auth-tenant-name>]
+ [--os-project-id <auth-project-id>]
+ [--os-project-name <auth-project-name>]
+ [--os-project-domain-id <auth-project-domain-id>]
+ [--os-project-domain-name <auth-project-domain-name>]
+ [--os-auth-url <auth-url>] [--os-auth-token <auth-token>]
+ [--os-storage-url <storage-url>] [--os-region-name <region-name>]
+ [--os-service-type <service-type>]
+ [--os-endpoint-type <endpoint-type>]
+ [--os-cacert <ca-certificate>] [--insecure]
+ [--os-cert <client-certificate-file>]
+ [--os-key <client-certificate-key-file>]
+ [--no-ssl-compression]
+ <subcommand> [--help] [<subcommand options>]
+
+**Subcommands:**
+
+``delete``
+ Delete a container or objects within a container.
+
+``download``
+ Download objects from containers.
+
+``list``
+ Lists the containers for the account or the objects
+ for a container.
+
+``post``
+ Updates meta information for the account, container,
+ or object; creates containers if not present.
+
+``copy``
+ Copies object, optionally adds meta
+
+``stat``
+ Displays information for the account, container,
+ or object.
+
+``upload``
+ Uploads files or directories to the given container.
+
+``capabilities``
+ List cluster capabilities.
+
+``tempurl``
+ Create a temporary URL.
+
+``auth``
+ Display auth related environment variables.
+
+.. _swift_command_options:
+
+swift optional arguments
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+``--version``
+ show program's version number and exit
+
+``-h, --help``
+ show this help message and exit
+
+``--os-help``
+ Show OpenStack authentication options.
+
+``-s, --snet``
+ Use SERVICENET internal network.
+
+``-v, --verbose``
+ Print more info.
+
+``--debug``
+ Show the curl commands and results of all http queries
+ regardless of result status.
+
+``--info``
+ Show the curl commands and results of all http queries
+ which return an error.
+
+``-q, --quiet``
+ Suppress status output.
+
+``-A AUTH, --auth=AUTH``
+ URL for obtaining an auth token.
+
+``-V AUTH_VERSION, --auth-version=AUTH_VERSION, --os-identity-api-version=AUTH_VERSION``
+ Specify a version for authentication. Defaults to
+ ``env[ST_AUTH_VERSION]``, ``env[OS_AUTH_VERSION]``,
+ ``env[OS_IDENTITY_API_VERSION]`` or 1.0.
+
+``-U USER, --user=USER``
+ User name for obtaining an auth token.
+
+``-K KEY, --key=KEY``
+ Key for obtaining an auth token.
+
+``-R RETRIES, --retries=RETRIES``
+ The number of times to retry a failed connection.
+
+``--insecure``
+ Allow swiftclient to access servers without having to
+ verify the SSL certificate. Defaults to
+ ``env[SWIFTCLIENT_INSECURE]`` (set to 'true' to enable).
+
+``--no-ssl-compression``
+ This option is deprecated and not used anymore. SSL
+ compression should be disabled by default by the
+ system SSL library.
+
+Authentication
+~~~~~~~~~~~~~~
+
+This section covers the options for authenticating with a swift
+object store. The combinations of options required for each authentication
+version are detailed below, but are just a subset of those that can be used
+to successfully authenticate. These are the most common and recommended
+combinations.
+
+You should obtain the details of your authentication version and credentials
+from your storage provider. These details should make it clearer which of the
+authentication sections below are most likely to allow you to connect to your
+storage account.
+
+Keystone v3
+-----------
+
+.. code-block:: bash
+
+ swift --os-auth-url https://api.example.com:5000/v3 --auth-version 3 \
+ --os-project-name project1 --os-project-domain-name domain1 \
+ --os-username user --os-user-domain-name domain1 \
+ --os-password password list
+
+ swift --os-auth-url https://api.example.com:5000/v3 --auth-version 3 \
+ --os-project-id 0123456789abcdef0123456789abcdef \
+ --os-user-id abcdef0123456789abcdef0123456789 \
+ --os-password password list
+
+Manually specifying the options above on the command line can be avoided by
+setting the following combinations of environment variables:
+
+.. code-block:: bash
+
+ ST_AUTH_VERSION=3
+ OS_USERNAME=user
+ OS_USER_DOMAIN_NAME=domain1
+ OS_PASSWORD=password
+ OS_PROJECT_NAME=project1
+ OS_PROJECT_DOMAIN_NAME=domain1
+ OS_AUTH_URL=https://api.example.com:5000/v3
+
+ ST_AUTH_VERSION=3
+ OS_USER_ID=abcdef0123456789abcdef0123456789
+ OS_PASSWORD=password
+ OS_PROJECT_ID=0123456789abcdef0123456789abcdef
+ OS_AUTH_URL=https://api.example.com:5000/v3
+
+Keystone v2
+-----------
+
+.. code-block:: bash
+
+ swift --os-auth-url https://api.example.com:5000/v2.0 \
+ --os-tenant-name tenant \
+ --os-username user --os-password password list
+
+Manually specifying the options above on the command line can be avoided by
+setting the following environment variables:
+
+.. code-block:: bash
+
+ ST_AUTH_VERSION=2.0
+ OS_USERNAME=user
+ OS_PASSWORD=password
+ OS_TENANT_NAME=tenant
+ OS_AUTH_URL=https://api.example.com:5000/v2.0
+
+Legacy auth systems
+-------------------
+
+You can configure swift to work with any number of other authentication systems
+that we will not cover in this document. If your storage provider is not using
+Keystone to provide access tokens, please contact them for instructions on the
+required options. It is likely that the options will need to be specified as
+below:
+
+.. code-block:: bash
+
+ swift -A https://api.example.com/v1.0 -U user -K api_key list
+
+Specifying the options above manually on the command line can be avoided by
+setting the following environment variables:
+
+.. code-block:: bash
+
+ ST_AUTH_VERSION=1.0
+ ST_AUTH=https://api.example.com/v1.0
+ ST_USER=user
+ ST_KEY=key
+
+It is also possible that you need to use a completely separate auth system, in which
+case ``swiftclient`` cannot request a token for you. In this case you should make the
+authentication request separately and access your storage using the token and
+storage URL options shown below:
+
+.. code-block:: bash
+
+ swift --os-auth-token 6ee5eb33efad4e45ab46806eac010566 \
+ --os-storage-url https://10.1.5.2:8080/v1/AUTH_ced809b6a4baea7aeab61a \
+ list
+
+.. We need the backslash below in order to indent the note
+\
+
+ .. note::
+
+ Leftover environment variables are a common source of confusion when
+ authorization fails.
+
+CLI commands
+~~~~~~~~~~~~
+
+.. _swift_auth:
+
+Auth
+----
+
+.. code-block:: console
+
+ Usage: swift auth
+
+Display authentication variables in shell friendly format. Command to run to export storage
+URL and auth token into ``OS_STORAGE_URL`` and ``OS_AUTH_TOKEN``: ``swift auth``.
+Command to append to a runcom file (e.g. ``~/.bashrc``, ``/etc/profile``) for automatic
+authentication: ``swift auth -v -U test:tester -K testing``.
+
+.. _swift_stat:
+
+swift stat
+----------
+
+.. code-block:: console
+
+ Usage: swift stat [--lh] [--header <header:value>]
+ [<container> [<object>]]
+
+Displays information for the account, container, or object depending on
+the arguments given (if any). In verbose mode, the storage URL and the
+authentication token are displayed as well.
+
+**Positional arguments:**
+
+``[container]``
+ Name of container to stat from.
+
+``[object]``
+ Name of object to stat.
+
+**Optional arguments:**
+
+``--lh``
+ Report sizes in human readable format similar to
+ ls -lh.
+
+``-H, --header <header:value>``
+ Adds a custom request header to use for stat.
+
+.. _swift_list:
+
+swift list
+----------
+
+.. code-block:: console
+
+ Usage: swift list [--long] [--lh] [--totals] [--prefix <prefix>]
+ [--delimiter <delimiter>] [--header <header:value>]
+ [<container>]
+
+Lists the containers for the account or the objects for a container.
+The ``-p <prefix>`` or ``--prefix <prefix>`` is an option that will only
+list items beginning with that prefix. The ``-d <delimiter>`` or
+``--delimiter <delimiter>`` is an option (for container listings only)
+that will roll up items with the given delimiter (see `OpenStack Swift
+general documentation <http://docs.openstack.org/swift/latest/>` for
+what this means).
+
+The ``-l`` and ``--lh`` options provide more detail, similar to ``ls -l``
+and ``ls -lh``, the latter providing sizes in human readable format
+(For example: ``3K``, ``12M``, etc). The latter two switches use more
+overhead to retrieve the displayed details, which is directly proportional
+to the number of container or objects listed.
+
+**Positional arguments:**
+
+``[container]``
+ Name of container to list object in.
+
+**Optional arguments:**
+
+``-l, --long``
+ Long listing format, similar to ls -l.
+
+``--lh``
+ Report sizes in human readable format similar to
+ ls -lh.
+
+``-t, --totals``
+ Used with -l or --lh, only report totals.
+
+``-p <prefix>, --prefix <prefix>``
+ Only list items beginning with the prefix.
+
+``-d <delim>, --delimiter <delim>``
+ Roll up items with the given delimiter. For containers
+ only. See OpenStack Swift API documentation for what
+ this means.
+
+``-H, --header <header:value>``
+ Adds a custom request header to use for listing.
+
+.. _swift_upload:
+
+swift upload
+------------
+
+.. code-block:: console
+
+ Usage: swift upload [--changed] [--skip-identical] [--segment-size <size>]
+ [--segment-container <container>] [--leave-segments]
+ [--object-threads <thread>] [--segment-threads <threads>]
+ [--header <header>] [--use-slo] [--ignore-checksum]
+ [--object-name <object-name>]
+ <container> <file_or_directory> [<file_or_directory>] [...]
+
+Uploads the files and directories specified by the remaining arguments to the
+given container. The ``-c`` or ``--changed`` is an option that will only
+upload files that have changed since the last upload. The
+``--object-name <object-name>`` is an option that will upload a file and
+name object to ``<object-name>`` or upload a directory and use ``<object-name>``
+as object prefix. If the file name is "-", client reads content from standard
+input. In this case ``--object-name`` is required to set the name of the object
+and no other files may be given. The ``-S <size>`` or ``--segment-size <size>``
+and ``--leave-segments`` are options as well (see ``--help`` for more).
+
+**Positional arguments:**
+
+``<container>``
+ Name of container to upload to.
+
+``<file_or_directory>``
+ Name of file or directory to upload. Specify multiple
+ times for multiple uploads.
+
+**Optional arguments:**
+
+``-c, --changed``
+ Only upload files that have changed since the last
+ upload.
+
+``--skip-identical``
+ Skip uploading files that are identical on both sides.
+
+``-S, --segment-size <size>``
+ Upload files in segments no larger than <size> (in
+ Bytes) and then create a "manifest" file that will
+ download all the segments as if it were the original
+ file.
+
+``--segment-container <container>``
+ Upload the segments into the specified container. If
+ not specified, the segments will be uploaded to a
+ <container>_segments container to not pollute the
+ main <container> listings.
+
+``--leave-segments``
+ Indicates that you want the older segments of manifest
+ objects left alone (in the case of overwrites).
+
+``--object-threads <threads>``
+ Number of threads to use for uploading full objects.
+ Default is 10.
+
+``--segment-threads <threads>``
+ Number of threads to use for uploading object segments.
+ Default is 10.
+
+``-H, --header <header:value>``
+ Adds a customized request header. This option may be
+ repeated. Example: -H "content-type:text/plain"
+ -H "Content-Length: 4000".
+
+``--use-slo``
+ When used in conjunction with --segment-size it will
+ create a Static Large Object instead of the default
+ Dynamic Large Object.
+
+``--object-name <object-name>``
+ Upload file and name object to <object-name> or upload
+ dir and use <object-name> as object prefix instead of
+ folder name.
+
+``--ignore-checksum``
+ Turn off checksum validation for uploads.
+
+
+.. _swift_post:
+
+swift post
+----------
+
+.. code-block:: console
+
+ Usage: swift post [--read-acl <acl>] [--write-acl <acl>] [--sync-to]
+ [--sync-key <sync-key>] [--meta <name:value>]
+ [--header <header>]
+ [<container> [<object>]]
+
+Updates meta information for the account, container, or object depending
+on the arguments given. If the container is not found, the ``swiftclient``
+will create it automatically, but this is not true for accounts and
+objects. Containers also allow the ``-r <read-acl>`` (or ``--read-acl
+<read-acl>``) and ``-w <write-acl>`` (or ``--write-acl <write-acl>``) options.
+The ``-m`` or ``--meta`` option is allowed on accounts, containers and objects,
+and is used to define the user metadata items to set in the form ``Name:Value``.
+You can repeat this option. For example: ``post -m Color:Blue -m Size:Large``
+
+For more information about ACL formats see the documentation:
+`ACLs <http://docs.openstack.org/swift/latest/misc.html#acls>`_.
+
+**Positional arguments:**
+
+``[container]``
+ Name of container to post to.
+
+``[object]``
+ Name of object to post.
+
+**Optional arguments:**
+
+``-r, --read-acl <acl>``
+ Read ACL for containers. Quick summary of ACL syntax:
+ ``.r:*``, ``.r:-.example.com``, ``.r:www.example.com``,
+ ``account1`` (v1.0 identity API only),
+ ``account1:*``, ``account2:user2`` (v2.0+ identity API).
+
+``-w, --write-acl <acl>``
+ Write ACL for containers. Quick summary of ACL syntax:
+ ``account1`` (v1.0 identity API only),
+ ``account1:*``, ``account2:user2`` (v2.0+ identity API).
+
+``-t, --sync-to <sync-to>``
+ Sync To for containers, for multi-cluster replication.
+
+``-k, --sync-key <sync-key>``
+ Sync Key for containers, for multi-cluster replication.
+
+``-m, --meta <name:value>``
+ Sets a meta data item. This option may be repeated.
+
+ Example: -m Color:Blue -m Size:Large
+
+``-H, --header <header:value>``
+ Adds a customized request header.
+ This option may be repeated.
+
+ Example: -H "content-type:text/plain" -H "Content-Length: 4000"
+
+.. _swift_download:
+
+swift download
+--------------
+
+.. code-block:: console
+
+ Usage: swift download [--all] [--marker <marker>] [--prefix <prefix>]
+ [--output <out_file>] [--output-dir <out_directory>]
+ [--object-threads <threads>] [--ignore-checksum]
+ [--container-threads <threads>] [--no-download]
+ [--skip-identical] [--remove-prefix]
+ [--header <header:value>] [--no-shuffle]
+ [<container> [<object>] [...]]
+
+Downloads everything in the account (with ``--all``), or everything in a
+container, or a list of objects depending on the arguments given. For a
+single object download, you may use the ``-o <filename>`` or ``--output <filename>``
+option to redirect the output to a specific file or ``-`` to
+redirect to stdout. The ``--ignore-checksum`` is an option that turn off
+checksum validation. You can specify optional headers with the repeatable
+cURL-like option ``-H [--header <name:value>]``. ``--ignore-mtime`` ignores the
+``x-object-meta-mtime`` metadata entry on the object (if present) and instead
+creates the downloaded files with fresh atime and mtime values.
+
+**Positional arguments:**
+
+``<container>``
+ Name of container to download from. To download a
+ whole account, omit this and specify --all.
+
+``<object>``
+ Name of object to download. Specify multiple times
+ for multiple objects. Omit this to download all
+ objects from the container.
+
+**Optional arguments:**
+
+``-a, --all``
+ Indicates that you really want to download
+ everything in the account.
+
+``-m, --marker <marker>``
+ Marker to use when starting a container or account
+ download.
+
+``-p, --prefix <prefix>``
+ Only download items beginning with <prefix>
+
+``-r, --remove-prefix``
+ An optional flag for --prefix <prefix>, use this
+ option to download items without <prefix>
+
+``-o, --output <out_file>``
+ For a single file download, stream the output to
+ <out_file>. Specifying "-" as <out_file> will
+ redirect to stdout.
+
+``-D, --output-dir <out_directory>``
+ An optional directory to which to store objects.
+ By default, all objects are recreated in the current
+ directory.
+
+``--object-threads <threads>``
+ Number of threads to use for downloading objects.
+ Default is 10.
+
+``--container-threads <threads>``
+ Number of threads to use for downloading containers.
+ Default is 10.
+
+``--no-download``
+ Perform download(s), but don't actually write anything
+ to disk.
+
+``-H, --header <header:value>``
+ Adds a customized request header to the query, like
+ "Range" or "If-Match". This option may be repeated.
+
+ Example: --header "content-type:text/plain"
+
+``--skip-identical``
+ Skip downloading files that are identical on both
+ sides.
+
+``--ignore-checksum``
+ Turn off checksum validation for downloads.
+
+``--no-shuffle``
+ By default, when downloading a complete account or
+ container, download order is randomised in order to
+ reduce the load on individual drives when multiple
+ clients are executed simultaneously to download the
+ same set of objects (e.g. a nightly automated download
+ script to multiple servers). Enable this option to
+ submit download jobs to the thread pool in the order
+ they are listed in the object store.
+
+.. _swift_delete:
+
+swift delete
+------------
+
+.. code-block:: console
+
+ Usage: swift delete [--all] [--leave-segments]
+ [--object-threads <threads>]
+ [--container-threads <threads>]
+ [--header <header:value>]
+ [<container> [<object>] [...]]
+
+Deletes everything in the account (with ``--all``), or everything in a
+container, or a list of objects depending on the arguments given. Segments
+of manifest objects will be deleted as well, unless you specify the
+``--leave-segments`` option.
+
+**Positional arguments:**
+
+``[<container>]``
+ Name of container to delete from.
+
+``[<object>]``
+ Name of object to delete. Specify multiple times
+ for multiple objects.
+
+**Optional arguments:**
+
+``-a, --all``
+ Delete all containers and objects.
+
+``--leave-segments``
+ Do not delete segments of manifest objects.
+
+``-H, --header <header:value>``
+ Adds a custom request header to use for deleting
+ objects or an entire container.
+
+
+``--object-threads <threads>``
+ Number of threads to use for deleting objects.
+ Default is 10.
+
+``--container-threads <threads>``
+ Number of threads to use for deleting containers.
+ Default is 10.
+
+.. _swift_copy:
+
+swift copy
+----------
+
+.. code-block:: console
+
+ Usage: swift copy [--destination </container/object>] [--fresh-metadata]
+ [--meta <name:value>] [--header <header>] <container>
+ <object> [<object>] [...]
+
+Copies an object to a new destination or adds user metadata to an object. Depending
+on the options supplied, you can preserve existing metadata in contrast to the post
+command. The ``--destination`` option sets the copy target destination in the form
+``/container/object``. If not set, the object will be copied onto itself which is useful
+for adding metadata. You can use the ``-M`` or ``--fresh-metadata`` option to copy
+an object without existing user meta data, and the ``-m`` or ``--meta`` option
+to define user meta data items to set in the form ``Name:Value``. You can repeat
+this option. For example: ``copy -m Color:Blue -m Size:Large``.
+
+**Positional arguments:**
+
+``<container>``
+ Name of container to copy from.
+
+``<object>``
+ Name of object to copy. Specify multiple times for multiple objects
+
+**Optional arguments:**
+
+``-d, --destination </container[/object]>``
+ The container and name of the destination object. Name
+ of destination object can be omitted, then will be
+ same as name of source object. Supplying multiple
+ objects and destination with object name is invalid.
+
+``-M, --fresh-metadata``
+ Copy the object without any existing metadata,
+ If not set, metadata will be preserved or appended
+
+``-m, --meta <name:value>``
+ Sets a meta data item. This option may be repeated.
+
+ Example: -m Color:Blue -m Size:Large
+
+``-H, --header <header:value>``
+ Adds a customized request header. This option may be repeated.
+
+ Example: -H "content-type:text/plain" -H "Content-Length: 4000"
+
+.. _swift_capabilities:
+
+swift capabilities
+------------------
+
+.. code-block:: console
+
+ Usage: swift capabilities [--json] [<proxy_url>]
+
+Displays cluster capabilities. The output includes the list of the
+activated Swift middlewares as well as relevant options for each ones.
+Additionally the command displays relevant options for the Swift core. If
+the ``proxy-url`` option is not provided, the storage URL retrieved after
+authentication is used as ``proxy-url``.
+
+**Optional positional arguments:**
+
+``<proxy_url>``
+ Proxy URL of the cluster to retrieve capabilities.
+
+``--json``
+ Print the cluster capabilities in JSON format.
+
+.. _swift_tempurl:
+
+swift tempurl
+-------------
+
+.. code-block:: console
+
+ Usage: swift tempurl [--absolute] [--prefix-based]
+ <method> <seconds> <path> <key>
+
+Generates a temporary URL for a Swift object. ``method`` option sets an HTTP method to
+allow for this temporary URL that is usually ``GET`` or ``PUT``. ``time`` option sets
+the amount of time the temporary URL will be valid for.
+``time`` can be specified as an integer, denoting the number of seconds
+from now on until the URL shall be valid; or, if ``--absolute``
+is passed, the Unix timestamp when the temporary URL will expire.
+But beyond that, ``time`` can also be specified as an ISO 8601 timestamp
+in one of following formats:
+
+ i) Complete date: YYYY-MM-DD (eg 1997-07-16)
+
+ ii) Complete date plus hours, minutes and seconds:
+ YYYY-MM-DDThh:mm:ss
+ (eg 1997-07-16T19:20:30)
+
+ iii) Complete date plus hours, minutes and seconds with UTC designator:
+ YYYY-MM-DDThh:mm:ssZ
+ (eg 1997-07-16T19:20:30Z)
+
+Please be aware that if you don't provide the UTC designator (i.e., Z)
+the timestamp is generated using your local timezone. If only a date is
+specified, the time part used will equal to ``00:00:00``.
+
+``path`` option sets the full path to the Swift object.
+Example: ``/v1/AUTH_account/c/o``. ``key`` option is
+the secret temporary URL key set on the Swift cluster. To set a key, run
+``swift post -m "Temp-URL-Key: <your secret key>"``. To generate a prefix-based temporary
+URL use the ``--prefix-based`` option. This URL will contain the path to the prefix. Do not
+forget to append the desired objectname at the end of the path portion (and before the
+query portion) before sharing the URL. It is possible to use ISO 8601 UTC timestamps within the
+URL by using the ``--iso8601`` option.
+
+**Positional arguments:**
+
+``<method>``
+ An HTTP method to allow for this temporary URL.
+ Usually 'GET' or 'PUT'.
+
+``<seconds>``
+ The amount of time in seconds the temporary URL will be
+ valid for; or, if --absolute is passed, the Unix
+ timestamp when the temporary URL will expire.
+
+``<path>``
+ The full path to the Swift object.
+
+ Example: /v1/AUTH_account/c/o
+ or: http://saio:8080/v1/AUTH_account/c/o
+
+``<key>``
+ The secret temporary URL key set on the Swift cluster.
+ To set a key, run 'swift post -m
+ "Temp-URL-Key:b3968d0207b54ece87cccc06515a89d4"'
+
+**Optional arguments:**
+
+``--absolute``
+ Interpret the <seconds> positional argument as a Unix
+ timestamp rather than a number of seconds in the
+ future.
+
+``--prefix-based``
+ If present, a prefix-based tempURL will be generated.
+
+Examples
+~~~~~~~~
+
+In this section we present some example usage of the ``swift`` CLI. To keep the
+examples as short as possible, these examples assume that the relevant authentication
+options have been set using environment variables. You can obtain the full list of
+commands and options available in the ``swift`` CLI by executing the following:
+
+.. code-block:: bash
+
+ > swift --help
+ > swift <command> --help
+
+Simple examples
+---------------
+
+List the existing swift containers:
+
+.. code-block:: bash
+
+ > swift list
+
+ container_1
+
+Create a new container:
+
+.. code-block:: bash
+
+ > swift post TestContainer
+
+Upload an object into a container:
+
+.. code-block:: bash
+
+ > swift upload TestContainer testSwift.txt
+
+ testSwift.txt
+
+List the contents of a container:
+
+.. code-block:: bash
+
+ > swift list TestContainer
+
+ testSwift.txt
+
+Copy an object to new destination:
+
+.. code-block:: bash
+
+ > swift copy -d /DestContainer/testSwift.txt SourceContainer testSwift.txt
+
+ SourceContainer/testSwift.txt copied to /DestContainer/testSwift.txt
+
+Delete an object from a container:
+
+.. code-block:: bash
+
+ > swift delete TestContainer testSwift.txt
+
+ testSwift.txt
+
+Delete a container:
+
+.. code-block:: bash
+
+ > swift delete TestContainer
+
+ TestContainer
+
+Display auth related authentication variables in shell friendly format:
+
+.. code-block:: bash
+
+ > swift auth
+
+ export OS_STORAGE_URL=http://127.0.0.1:8080/v1/AUTH_bf5e63572f7a420a83fcf0aa8c72c2c7
+ export OS_AUTH_TOKEN=c597015ae19943a18438b52ef3762e79
+
+Download an object from a container:
+
+.. code-block:: bash
+
+ > swift download TestContainer testSwift.txt
+
+ testSwift.txt [auth 0.028s, headers 0.045s, total 0.045s, 0.002 MB/s]
+
+.. We need the backslash below in order to indent the note
+\
+
+ .. note::
+
+ To upload an object to a container, your current working directory must be
+ where the file is located or you must provide the complete path to the file.
+ In other words, the --object-name <object-name> is an option that will upload
+ file and name object to <object-name> or upload directory and use <object-name> as
+ object prefix. In the case that you provide the complete path of the file,
+ that complete path will be the name of the uploaded object.
+
+For example:
+
+.. code-block:: bash
+
+ > swift upload TestContainer /home/swift/testSwift/testSwift.txt
+
+ home/swift/testSwift/testSwift.txt
+
+ > swift list TestContainer
+
+ home/swift/testSwift/testSwift.txt
+
+More complex examples
+---------------------
+
+Swift has a single object size limit of 5GiB. In order to upload files larger
+than this, we must create a large object that consists of smaller segments.
+The example below shows how to upload a large video file as a static large
+object in 1GiB segments:
+
+.. code-block:: bash
+
+ > swift upload videos --use-slo --segment-size 1G myvideo.mp4
+
+ myvideo.mp4 segment 8
+ myvideo.mp4 segment 4
+ myvideo.mp4 segment 2
+ myvideo.mp4 segment 7
+ myvideo.mp4 segment 0
+ myvideo.mp4 segment 1
+ myvideo.mp4 segment 3
+ myvideo.mp4 segment 6
+ myvideo.mp4 segment 5
+ myvideo.mp4
+
+This command will upload segments to a container named ``videos_segments``, and
+create a manifest file describing the entire object in the ``videos`` container.
+For more information on large objects, see the documentation `here
+<https://docs.openstack.org/swift/latest/overview_large_objects.html>`_.
+
+.. code-block:: bash
+
+ > swift list videos
+
+ myvideo.mp4
+
+ > swift list videos_segments
+
+ myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000000
+ myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000001
+ myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000002
+ myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000003
+ myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000004
+ myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000005
+ myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000006
+ myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000007
+ myvideo.mp4/slo/1460229233.679546/9341553868/1073741824/00000008
+
+Firstly, the key should be set, then generate a temporary URL for a Swift object:
+
+.. code-block:: bash
+
+ > swift post -m "Temp-URL-Key:b3968d0207b54ece87cccc06515a89d4"
+
+ > swift tempurl GET 6000 /v1/AUTH_bf5e63572f7a420a83fcf0aa8c72c2c7\
+ /firstcontainer/clean.sh b3968d0207b54ece87cccc06515a89d4
+
+ /v1/AUTH_/firstcontainer/clean.sh?temp_url_sig=\
+ 9218fc288cc09e5edd857b6a3d43cf2122b906dc&temp_url_expires=1472203614
diff --git a/doc/source/index.rst b/doc/source/index.rst
index f123b7b..3c2cb1e 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -16,7 +16,7 @@ Developer Documentation
.. toctree::
:maxdepth: 2
- cli
+ cli/index
service-api
client-api
diff --git a/releasenotes/notes/340_notes-1777780bbfdb4d96.yaml b/releasenotes/notes/340_notes-1777780bbfdb4d96.yaml
new file mode 100644
index 0000000..0aae5cf
--- /dev/null
+++ b/releasenotes/notes/340_notes-1777780bbfdb4d96.yaml
@@ -0,0 +1,20 @@
+---
+features:
+
+ - The ``swift`` CLI now supports streaming from stdin. If "-" is given
+ as the source, the object content is read from stdin. The
+ ``--object-name`` must be given when content is loaded from stdin.
+ - Tolerate RFC-compliant ETags returned from the server.
+ - Skip checksum validation on partial downloads.
+ - Buffer reads from disk, resulting in much faster upload throughput.
+ - >
+ Added support for ISO 8601 timestamps for tempurl, matching the
+ feature in Swift 2.13.0.
+ - Added an option to ignore mtime metadata entry (``--ignore-mtime``).
+ - >
+ When using SwiftService to delete many objects, the bulk delete page
+ size will now be respected. Previously, exceeding this limit would
+ prevent any objects from being deleted.
+ - Expose `--prefix` as an option for st_delete.
+ - Imported docs content from openstack-manuals project.
+ - Various other minor bug fixes and improvements.
diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py
new file mode 100644
index 0000000..b27aa96
--- /dev/null
+++ b/releasenotes/source/conf.py
@@ -0,0 +1,356 @@
+# -*- coding: utf-8 -*-
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# swift documentation build configuration file, created by
+# sphinx-quickstart on Mon Oct 3 17:01:55 2016.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+import datetime
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'reno.sphinxext',
+ 'openstackdocstheme',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+# templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+# source_suffix = ['.rst', '.md']
+source_suffix = '.rst'
+
+# The encoding of source files.
+#
+# source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Swift Client Release Notes'
+copyright = u'%d, OpenStack Foundation' % datetime.datetime.now().year
+
+# Release notes are version independent.
+# The short X.Y version.
+version = ''
+# The full version, including alpha/beta/rc tags.
+release = ''
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#
+# today = ''
+#
+# Else, today_fmt is used as the format for a strftime call.
+#
+# today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This patterns also effect to html_static_path and html_extra_path
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#
+# default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#
+# add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#
+# add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#
+# show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+# modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+# keep_warnings = False
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+# todo_include_todos = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'openstackdocs'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#
+# html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+# html_theme_path = []
+
+# The name for this set of Sphinx documents.
+# "<project> v<release> documentation" by default.
+#
+# html_title = u'swift v2.10.0'
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#
+# html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#
+# html_logo = None
+
+# The name of an image file (relative to this directory) to use as a favicon of
+# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#
+# html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+# html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#
+# html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+# html_last_updated_fmt = '%b %d, %Y'
+html_last_updated_fmt = '%Y-%m-%d %H:%M'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#
+# html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#
+# html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#
+# html_additional_pages = {}
+
+# If false, no module index is generated.
+#
+# html_domain_indices = True
+
+# If false, no index is generated.
+#
+# html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#
+# html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#
+# html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#
+# html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#
+# html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#
+# html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+# html_file_suffix = None
+
+# Language to be used for generating the HTML full-text search index.
+# Sphinx supports the following languages:
+# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
+# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh'
+#
+# html_search_language = 'en'
+
+# A dictionary with options for the search language support, empty by default.
+# 'ja' uses this config value.
+# 'zh' user can custom change `jieba` dictionary path.
+#
+# html_search_options = {'type': 'default'}
+
+# The name of a javascript file (relative to the configuration directory) that
+# implements a search results scorer. If empty, the default will be used.
+#
+# html_search_scorer = 'scorer.js'
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'SwiftClientReleaseNotesdoc'
+
+# -- Options for LaTeX output ---------------------------------------------
+
+# latex_elements = {
+# # The paper size ('letterpaper' or 'a4paper').
+# #
+# # 'papersize': 'letterpaper',
+
+# # The font size ('10pt', '11pt' or '12pt').
+# #
+# # 'pointsize': '10pt',
+
+# # Additional stuff for the LaTeX preamble.
+# #
+# # 'preamble': '',
+
+# # Latex figure (float) alignment
+# #
+# # 'figure_align': 'htbp',
+# }
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+# latex_documents = [
+# (master_doc, 'swift.tex', u'swift Documentation',
+# u'swift', 'manual'),
+# ]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#
+# latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#
+# latex_use_parts = False
+
+# If true, show page references after internal links.
+#
+# latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#
+# latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#
+# latex_appendices = []
+
+# It false, will not define \strong, \code, itleref, \crossref ... but only
+# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added
+# packages.
+#
+# latex_keep_old_macro_names = True
+
+# If false, no module index is generated.
+#
+# latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+# man_pages = [
+# (master_doc, 'swift', u'swift Documentation',
+# [author], 1)
+# ]
+
+# If true, show URL addresses after external links.
+#
+# man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+# texinfo_documents = [
+# (master_doc, 'swift', u'swift Documentation',
+# author, 'swift', 'One line description of project.',
+# 'Miscellaneous'),
+# ]
+
+# Documents to append as an appendix to all manuals.
+#
+# texinfo_appendices = []
+
+# If false, no module index is generated.
+#
+# texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#
+# texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#
+# texinfo_no_detailmenu = False
+
+locale_dirs = ['locale/']
+
+# -- Options for openstackdocstheme -------------------------------------------
+repository_name = 'openstack/python-swiftclient'
+bug_project = 'python-swiftclient'
+bug_tag = ''
diff --git a/releasenotes/source/current.rst b/releasenotes/source/current.rst
new file mode 100644
index 0000000..87a748f
--- /dev/null
+++ b/releasenotes/source/current.rst
@@ -0,0 +1,5 @@
+====================================
+ Current (Unreleased) Release Notes
+====================================
+
+.. release-notes::
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
new file mode 100644
index 0000000..6e3419d
--- /dev/null
+++ b/releasenotes/source/index.rst
@@ -0,0 +1,11 @@
+============================
+ Swift Client Release Notes
+============================
+
+.. toctree::
+ :maxdepth: 1
+
+ current
+ pike
+ ocata
+ newton
diff --git a/releasenotes/source/newton.rst b/releasenotes/source/newton.rst
new file mode 100644
index 0000000..59418a3
--- /dev/null
+++ b/releasenotes/source/newton.rst
@@ -0,0 +1,6 @@
+=============================
+ Newton Series Release Notes
+=============================
+
+.. release-notes::
+ :branch: stable/newton
diff --git a/releasenotes/source/ocata.rst b/releasenotes/source/ocata.rst
new file mode 100644
index 0000000..726307b
--- /dev/null
+++ b/releasenotes/source/ocata.rst
@@ -0,0 +1,6 @@
+============================
+ Ocata Series Release Notes
+============================
+
+.. release-notes::
+ :branch: stable/ocata
diff --git a/releasenotes/source/pike.rst b/releasenotes/source/pike.rst
new file mode 100644
index 0000000..e2c4806
--- /dev/null
+++ b/releasenotes/source/pike.rst
@@ -0,0 +1,6 @@
+===========================
+ Pike Series Release Notes
+===========================
+
+.. release-notes::
+ :branch: stable/pike
diff --git a/setup.cfg b/setup.cfg
index 4af3151..e4963db 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -5,7 +5,7 @@ description-file =
README.rst
author = OpenStack
author-email = openstack-dev@lists.openstack.org
-home-page = http://docs.openstack.org/developer/python-swiftclient
+home-page = https://docs.openstack.org/python-swiftclient/latest/
classifier =
Environment :: OpenStack
Intended Audience :: Information Technology
diff --git a/swiftclient/client.py b/swiftclient/client.py
index 80bc4a3..7db75f0 100644
--- a/swiftclient/client.py
+++ b/swiftclient/client.py
@@ -25,7 +25,7 @@ from distutils.version import StrictVersion
from requests.exceptions import RequestException, SSLError
from six.moves import http_client
from six.moves.urllib.parse import quote as _quote, unquote
-from six.moves.urllib.parse import urlparse, urlunparse
+from six.moves.urllib.parse import urljoin, urlparse, urlunparse
from time import sleep, time
import six
@@ -550,9 +550,22 @@ def get_auth_keystone(auth_url, user, key, os_options, **kwargs):
insecure = kwargs.get('insecure', False)
timeout = kwargs.get('timeout', None)
- auth_version = kwargs.get('auth_version', '2.0')
+ auth_version = kwargs.get('auth_version', None)
debug = logger.isEnabledFor(logging.DEBUG)
+ # Add the version suffix in case of versionless Keystone endpoints. If
+ # auth_version is also unset it is likely that it is v3
+ if len(urlparse(auth_url).path) <= 1:
+ if auth_version and auth_version in AUTH_VERSIONS_V2:
+ auth_url = urljoin(auth_url, "v2.0")
+ else:
+ auth_url = urljoin(auth_url, "v3")
+ auth_version = '3'
+ logger.debug("Versionless auth_url - using %s as endpoint" % auth_url)
+
+ # Legacy default if not set
+ if auth_version is None:
+ auth_version = 'v2.0'
ksclient, exceptions = _import_keystone_client(auth_version)
try:
diff --git a/swiftclient/service.py b/swiftclient/service.py
index 8301ae9..7b5ecd4 100644
--- a/swiftclient/service.py
+++ b/swiftclient/service.py
@@ -50,6 +50,7 @@ from swiftclient.exceptions import ClientException
from swiftclient.multithreading import MultiThreadingManager
+DISK_BUFFER = 2 ** 16
logger = logging.getLogger("swiftclient.service")
@@ -203,6 +204,7 @@ _default_local_options = {
'shuffle': False,
'destination': None,
'fresh_metadata': False,
+ 'ignore_mtime': False,
}
POLICY = 'X-Storage-Policy'
@@ -1125,14 +1127,14 @@ class SwiftService(object):
if options['skip_identical']:
filename = out_file if out_file else path
try:
- fp = open(filename, 'rb')
+ fp = open(filename, 'rb', DISK_BUFFER)
except IOError:
pass
else:
with fp:
md5sum = md5()
while True:
- data = fp.read(65536)
+ data = fp.read(DISK_BUFFER)
if not data:
break
md5sum.update(data)
@@ -1140,7 +1142,7 @@ class SwiftService(object):
try:
start_time = time()
- get_args = {'resp_chunk_size': 65536,
+ get_args = {'resp_chunk_size': DISK_BUFFER,
'headers': req_headers,
'response_dict': results_dict}
if options['skip_identical']:
@@ -1223,10 +1225,10 @@ class SwiftService(object):
if not no_file:
if out_file:
- fp = open(out_file, 'wb')
+ fp = open(out_file, 'wb', DISK_BUFFER)
else:
if basename(path):
- fp = open(path, 'wb')
+ fp = open(path, 'wb', DISK_BUFFER)
else:
pseudodir = True
@@ -1240,7 +1242,8 @@ class SwiftService(object):
bytes_read = obj_body.bytes_read()
if fp is not None:
fp.close()
- if 'x-object-meta-mtime' in headers and not no_file:
+ if ('x-object-meta-mtime' in headers and not no_file
+ and not options['ignore_mtime']):
try:
mtime = float(headers['x-object-meta-mtime'])
except ValueError:
@@ -1731,7 +1734,7 @@ class SwiftService(object):
}
fp = None
try:
- fp = open(path, 'rb')
+ fp = open(path, 'rb', DISK_BUFFER)
fp.seek(segment_start)
contents = LengthWrapper(fp, segment_size, md5=options['checksum'])
@@ -1808,8 +1811,10 @@ class SwiftService(object):
return chunks
def _is_identical(self, chunk_data, path):
+ if path is None:
+ return False
try:
- fp = open(path, 'rb')
+ fp = open(path, 'rb', DISK_BUFFER)
except IOError:
return False
@@ -1818,7 +1823,7 @@ class SwiftService(object):
to_read = chunk['bytes']
md5sum = md5()
while to_read:
- data = fp.read(min(65536, to_read))
+ data = fp.read(min(DISK_BUFFER, to_read))
if not data:
return False
md5sum.update(data)
@@ -2032,7 +2037,7 @@ class SwiftService(object):
try:
if path is not None:
content_length = getsize(path)
- fp = open(path, 'rb')
+ fp = open(path, 'rb', DISK_BUFFER)
contents = LengthWrapper(fp,
content_length,
md5=options['checksum'])
diff --git a/swiftclient/shell.py b/swiftclient/shell.py
index 58b9f54..43fcf47 100755
--- a/swiftclient/shell.py
+++ b/swiftclient/shell.py
@@ -17,6 +17,7 @@
from __future__ import print_function, unicode_literals
import argparse
+import io
import json
import logging
import signal
@@ -26,7 +27,7 @@ from os import environ, walk, _exit as os_exit
from os.path import isfile, isdir, join
from six import text_type, PY2
from six.moves.urllib.parse import unquote, urlparse
-from sys import argv as sys_argv, exit, stderr
+from sys import argv as sys_argv, exit, stderr, stdin
from time import gmtime, strftime
from swiftclient import RequestException
@@ -272,6 +273,9 @@ Optional arguments:
script to multiple servers). Enable this option to
submit download jobs to the thread pool in the order
they are listed in the object store.
+ --ignore-mtime Ignore the 'X-Object-Meta-Mtime' header when
+ downloading an object. Instead, create atime and mtime
+ with fresh timestamps.
'''.strip("\n")
@@ -332,6 +336,12 @@ def st_download(parser, args, output_manager):
'nightly automated download script to multiple servers). Enable this '
'option to submit download jobs to the thread pool in the order they '
'are listed in the object store.')
+ parser.add_argument(
+ '--ignore-mtime', action='store_true', dest='ignore_mtime',
+ default=False, help='By default, the object-meta-mtime header is used '
+ 'to store the access and modified timestamp for the downloaded file. '
+ 'With this option, the header is ignored and the timestamps are '
+ 'created freshly.')
(options, args) = parse_args(parser, args)
args = args[1:]
if options['out_file'] == '-':
@@ -892,7 +902,9 @@ Uploads specified files and directories to the given container.
Positional arguments:
<container> Name of container to upload to.
<file_or_directory> Name of file or directory to upload. Specify multiple
- times for multiple uploads.
+ times for multiple uploads. If "-" is specified, reads
+ content from standard input (--object-name is required
+ in this case).
Optional arguments:
-c, --changed Only upload files that have changed since the last
@@ -1000,6 +1012,11 @@ def st_upload(parser, args, output_manager):
else:
container = args[0]
files = args[1:]
+ from_stdin = '-' in files
+ if from_stdin and len(files) > 1:
+ output_manager.error(
+ 'upload from stdin cannot be used along with other files')
+ return
if options['object_name'] is not None:
if len(files) > 1:
@@ -1007,6 +1024,10 @@ def st_upload(parser, args, output_manager):
return
else:
orig_path = files[0]
+ elif from_stdin:
+ output_manager.error(
+ 'object-name must be specified with uploads from stdin')
+ return
if options['segment_size']:
try:
@@ -1045,6 +1066,14 @@ def st_upload(parser, args, output_manager):
objs = []
dir_markers = []
for f in files:
+ if f == '-':
+ fd = io.open(stdin.fileno(), mode='rb')
+ objs.append(SwiftUploadObject(
+ fd, object_name=options['object_name']))
+ # We ensure that there is exactly one "file" to upload in
+ # this case -- stdin
+ break
+
if isfile(f):
objs.append(f)
elif isdir(f):
@@ -1058,7 +1087,7 @@ def st_upload(parser, args, output_manager):
# Now that we've collected all the required files and dir markers
# build the tuples for the call to upload
- if options['object_name'] is not None:
+ if options['object_name'] is not None and not from_stdin:
objs = [
SwiftUploadObject(
o, object_name=o.replace(
diff --git a/test-requirements.txt b/test-requirements.txt
index 0ce9cec..a9a0c7f 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -5,3 +5,5 @@ mock>=1.2
oslosphinx>=4.7.0 # Apache-2.0
sphinx>=1.1.2,<1.2
testrepository>=0.0.18
+reno>=1.8.0,!=2.3.1 # Apache-2.0
+openstackdocstheme>=1.16.0 # Apache-2.0
diff --git a/tests/unit/test_service.py b/tests/unit/test_service.py
index 2a477fe..5ccc081 100644
--- a/tests/unit/test_service.py
+++ b/tests/unit/test_service.py
@@ -1934,7 +1934,7 @@ class TestServiceDownload(_TestServiceBase):
'headers_receipt': 3
}
)
- mock_open.assert_called_once_with('test_o', 'wb')
+ mock_open.assert_called_once_with('test_o', 'wb', 65536)
written_content.write.assert_called_once_with(b'objcontent')
mock_conn.get_object.assert_called_once_with(
@@ -1978,7 +1978,7 @@ class TestServiceDownload(_TestServiceBase):
'headers_receipt': 3
}
)
- mock_open.assert_called_once_with('test_o', 'wb')
+ mock_open.assert_called_once_with('test_o', 'wb', 65536)
mock_utime.assert_called_once_with(
'test_o', (1454113727.682512, 1454113727.682512))
written_content.write.assert_called_once_with(b'objcontent')
@@ -2024,7 +2024,7 @@ class TestServiceDownload(_TestServiceBase):
'headers_receipt': 3
}
)
- mock_open.assert_called_once_with('test_o', 'wb')
+ mock_open.assert_called_once_with('test_o', 'wb', 65536)
self.assertEqual(0, len(mock_utime.mock_calls))
written_content.write.assert_called_once_with(b'objcontent')
@@ -2034,6 +2034,52 @@ class TestServiceDownload(_TestServiceBase):
)
self.assertEqual(expected_r, actual_r)
+ def test_download_object_job_ignore_mtime(self):
+ mock_conn = self._get_mock_connection()
+ objcontent = six.BytesIO(b'objcontent')
+ mock_conn.get_object.side_effect = [
+ ({'content-type': 'text/plain',
+ 'etag': '2cbbfe139a744d6abbe695e17f3c1991',
+ 'x-object-meta-mtime': '1454113727.682512'},
+ objcontent)
+ ]
+ expected_r = self._get_expected({
+ 'success': True,
+ 'start_time': 1,
+ 'finish_time': 2,
+ 'headers_receipt': 3,
+ 'auth_end_time': 4,
+ 'read_length': len(b'objcontent'),
+ })
+
+ with mock.patch.object(builtins, 'open') as mock_open, \
+ mock.patch('swiftclient.service.utime') as mock_utime:
+ written_content = Mock()
+ mock_open.return_value = written_content
+ s = SwiftService()
+ _opts = self.opts.copy()
+ _opts['no_download'] = False
+ _opts['ignore_mtime'] = True
+ actual_r = s._download_object_job(
+ mock_conn, 'test_c', 'test_o', _opts)
+ actual_r = dict( # Need to override the times we got from the call
+ actual_r,
+ **{
+ 'start_time': 1,
+ 'finish_time': 2,
+ 'headers_receipt': 3
+ }
+ )
+ mock_open.assert_called_once_with('test_o', 'wb', 65536)
+ self.assertEqual([], mock_utime.mock_calls)
+ written_content.write.assert_called_once_with(b'objcontent')
+
+ mock_conn.get_object.assert_called_once_with(
+ 'test_c', 'test_o', resp_chunk_size=65536, headers={},
+ response_dict={}
+ )
+ self.assertEqual(expected_r, actual_r)
+
def test_download_object_job_exception(self):
mock_conn = self._get_mock_connection()
mock_conn.get_object = Mock(side_effect=self.exc)
diff --git a/tests/unit/test_shell.py b/tests/unit/test_shell.py
index 3f87c6d..110fb01 100644
--- a/tests/unit/test_shell.py
+++ b/tests/unit/test_shell.py
@@ -27,6 +27,7 @@ from time import localtime, mktime, strftime, strptime
from requests.packages.urllib3.exceptions import InsecureRequestWarning
import six
+import sys
import swiftclient
from swiftclient.service import SwiftError
@@ -473,7 +474,7 @@ class TestShell(unittest.TestCase):
response_dict={})]
connection.return_value.get_object.assert_has_calls(
calls, any_order=True)
- mock_open.assert_called_once_with('object', 'wb')
+ mock_open.assert_called_once_with('object', 'wb', 65536)
self.assertEqual([mock.call('pseudo')], makedirs.mock_calls)
makedirs.reset_mock()
@@ -490,7 +491,7 @@ class TestShell(unittest.TestCase):
connection.return_value.get_object.assert_called_with(
'container', 'object', headers={}, resp_chunk_size=65536,
response_dict={})
- mock_open.assert_called_with('object', 'wb')
+ mock_open.assert_called_with('object', 'wb', 65536)
self.assertEqual([], makedirs.mock_calls)
# Test downloading without md5 checks
@@ -507,7 +508,7 @@ class TestShell(unittest.TestCase):
connection.return_value.get_object.assert_called_with(
'container', 'object', headers={}, resp_chunk_size=65536,
response_dict={})
- mock_open.assert_called_with('object', 'wb')
+ mock_open.assert_called_with('object', 'wb', 65536)
sr.assert_called_once_with('object', mock.ANY, mock.ANY, False)
self.assertEqual([], makedirs.mock_calls)
@@ -553,7 +554,7 @@ class TestShell(unittest.TestCase):
mock_shuffle.assert_any_call(['container'])
mock_shuffle.assert_any_call(['object'])
mock_shuffle.assert_any_call(['pseudo/'])
- mock_open.assert_called_once_with('container/object', 'wb')
+ mock_open.assert_called_once_with('container/object', 'wb', 65536)
self.assertEqual([
mock.call('container'),
mock.call('container/pseudo'),
@@ -577,7 +578,7 @@ class TestShell(unittest.TestCase):
argv = ["", "download", "--all", "--no-shuffle"]
swiftclient.shell.main(argv)
self.assertEqual(0, mock_shuffle.call_count)
- mock_open.assert_called_once_with('container/object', 'wb')
+ mock_open.assert_called_once_with('container/object', 'wb', 65536)
self.assertEqual([
mock.call('container'),
mock.call('container/pseudo'),
@@ -610,7 +611,7 @@ class TestShell(unittest.TestCase):
response_dict={})]
connection.return_value.get_object.assert_has_calls(
calls, any_order=True)
- mock_open.assert_called_once_with('object', 'wb')
+ mock_open.assert_called_once_with('object', 'wb', 65536)
self.assertEqual([
mock.call('pseudo'),
], mock_mkdir.mock_calls)
@@ -721,7 +722,7 @@ class TestShell(unittest.TestCase):
'x-object-meta-mtime': mock.ANY,
},
query_string='multipart-manifest=put',
- response_dict={})
+ response_dict=mock.ANY)
@mock.patch('swiftclient.service.SwiftService.upload')
def test_upload_object_with_account_readonly(self, upload):
@@ -907,6 +908,44 @@ class TestShell(unittest.TestCase):
'x-object-meta-mtime': mock.ANY},
response_dict={})
+ @mock.patch('swiftclient.shell.io.open')
+ @mock.patch('swiftclient.service.SwiftService.upload')
+ def test_upload_from_stdin(self, upload_mock, io_open_mock):
+ def fake_open(fd, mode):
+ mock_io = mock.Mock()
+ mock_io.fileno.return_value = fd
+ return mock_io
+
+ io_open_mock.side_effect = fake_open
+
+ argv = ["", "upload", "container", "-", "--object-name", "foo"]
+ swiftclient.shell.main(argv)
+ upload_mock.assert_called_once_with("container", mock.ANY)
+ # This is a little convoluted: we want to examine the first call ([0]),
+ # the argv list([1]), the second parameter ([1]), and the first
+ # element. This is because the upload method takes a container and a
+ # list of SwiftUploadObjects.
+ swift_upload_obj = upload_mock.mock_calls[0][1][1][0]
+ self.assertEqual(sys.stdin.fileno(), swift_upload_obj.source.fileno())
+ io_open_mock.assert_called_once_with(sys.stdin.fileno(), mode='rb')
+
+ @mock.patch('swiftclient.service.SwiftService.upload')
+ def test_upload_from_stdin_no_name(self, upload_mock):
+ argv = ["", "upload", "container", "-"]
+ with CaptureOutput() as out:
+ self.assertRaises(SystemExit, swiftclient.shell.main, argv)
+ self.assertEqual(0, len(upload_mock.mock_calls))
+ self.assertTrue(out.err.find('object-name must be specified') >= 0)
+
+ @mock.patch('swiftclient.service.SwiftService.upload')
+ def test_upload_from_stdin_and_others(self, upload_mock):
+ argv = ["", "upload", "container", "-", "foo", "--object-name", "bar"]
+ with CaptureOutput() as out:
+ self.assertRaises(SystemExit, swiftclient.shell.main, argv)
+ self.assertEqual(0, len(upload_mock.mock_calls))
+ self.assertTrue(out.err.find(
+ 'upload from stdin cannot be used') >= 0)
+
@mock.patch.object(swiftclient.service.SwiftService,
'_bulk_delete_page_size', lambda *a: 0)
@mock.patch('swiftclient.service.Connection')
diff --git a/tests/unit/test_swiftclient.py b/tests/unit/test_swiftclient.py
index 5384ac7..3de5f02 100644
--- a/tests/unit/test_swiftclient.py
+++ b/tests/unit/test_swiftclient.py
@@ -575,6 +575,26 @@ class TestGetAuth(MockHttpTest):
self.assertTrue(url.startswith("http"))
self.assertTrue(token)
+ def test_get_auth_keystone_versionless(self):
+ fake_ks = FakeKeystone(endpoint='http://some_url', token='secret')
+
+ with mock.patch('swiftclient.client._import_keystone_client',
+ _make_fake_import_keystone_client(fake_ks)):
+ c.get_auth_keystone('http://authurl', 'user', 'key', {})
+ self.assertEqual(1, len(fake_ks.calls))
+ self.assertEqual('http://authurl/v3', fake_ks.calls[0].get('auth_url'))
+
+ def test_get_auth_keystone_versionless_auth_version_set(self):
+ fake_ks = FakeKeystone(endpoint='http://some_url', token='secret')
+
+ with mock.patch('swiftclient.client._import_keystone_client',
+ _make_fake_import_keystone_client(fake_ks)):
+ c.get_auth_keystone('http://auth_url', 'user', 'key',
+ {}, auth_version='2.0')
+ self.assertEqual(1, len(fake_ks.calls))
+ self.assertEqual('http://auth_url/v2.0',
+ fake_ks.calls[0].get('auth_url'))
+
def test_auth_with_session(self):
mock_session = mock.MagicMock()
mock_session.get_endpoint.return_value = 'http://storagehost/v1/acct'
diff --git a/tools/tox_install.sh b/tools/tox_install.sh
index 15aa9de..f3a83e9 100755
--- a/tools/tox_install.sh
+++ b/tools/tox_install.sh
@@ -4,28 +4,27 @@
# with installing the client from source. We should remove the version pin in
# the constraints file before applying it for from-source installation.
+CONSTRAINTS_FILE="$1"
+shift 1
+
set -e
-if [[ -z "$CONSTRAINTS_FILE" ]]; then
- echo 'WARNING: expected $CONSTRAINTS_FILE to be set' >&2
- PIP_FLAGS=(-U)
-else
- # NOTE(tonyb): Place this in the tox enviroment's log dir so it will get
- # published to logs.openstack.org for easy debugging.
- localfile="$VIRTUAL_ENV/log/upper-constraints.txt"
-
- if [[ "$CONSTRAINTS_FILE" != http* ]]; then
- CONSTRAINTS_FILE="file://$CONSTRAINTS_FILE"
- fi
- curl "$CONSTRAINTS_FILE" --insecure --progress-bar --output "$localfile"
-
- pip install -c"$localfile" openstack-requirements
-
- # This is the main purpose of the script: Allow local installation of
- # the current repo. It is listed in constraints file and thus any
- # install will be constrained and we need to unconstrain it.
- edit-constraints "$localfile" -- "$CLIENT_NAME"
- PIP_FLAGS=(-c"$localfile" -U)
+# NOTE(tonyb): Place this in the tox enviroment's log dir so it will get
+# published to logs.openstack.org for easy debugging.
+localfile="$VIRTUAL_ENV/log/upper-constraints.txt"
+
+if [[ "$CONSTRAINTS_FILE" != http* ]]; then
+ CONSTRAINTS_FILE="file://$CONSTRAINTS_FILE"
fi
+# NOTE(tonyb): need to add curl to bindep.txt if the project supports bindep
+curl "$CONSTRAINTS_FILE" --insecure --progress-bar --output "$localfile"
+
+python -m pip install -c"$localfile" openstack-requirements
+
+# This is the main purpose of the script: Allow local installation of
+# the current repo. It is listed in constraints file and thus any
+# install will be constrained and we need to unconstrain it.
+python "$(which edit-constraints)" "$localfile" -- $CLIENT_NAME
-pip install "${PIP_FLAGS[@]}" "$@"
+python -m pip install -c"$localfile" -U "$@"
+exit $?
diff --git a/tox.ini b/tox.ini
index df01bf8..e737241 100644
--- a/tox.ini
+++ b/tox.ini
@@ -5,13 +5,13 @@ skipsdist = True
[testenv]
usedevelop = True
-install_command = {toxinidir}/tools/tox_install.sh {opts} {packages}
+install_command = "{toxinidir}/tools/tox_install.sh" "{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}" {opts} {packages}
+list_dependencies_command = python -m pip freeze
setenv =
LANG=en_US.utf8
VIRTUAL_ENV={envdir}
BRANCH_NAME=master
CLIENT_NAME=python-swiftclient
- CONSTRAINTS_FILE={env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
@@ -25,7 +25,7 @@ passenv = SWIFT_* *_proxy
[testenv:pep8]
commands =
- flake8 swiftclient tests
+ python -m flake8 swiftclient tests
[testenv:venv]
commands = {posargs}
@@ -71,3 +71,6 @@ exclude = .venv,.tox,dist,doc,*egg
usedevelop = False
deps = bindep
commands = bindep test
+
+[testenv:releasenotes]
+commands = sphinx-build -a -W -E -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html