cleaned client with fixed tests. no quotas functionality implemented
This commit is contained in:
parent
9a3e8e15af
commit
041bfa455c
1
.testrepository/format
Normal file
1
.testrepository/format
Normal file
@ -0,0 +1 @@
|
||||
1
|
1
.testrepository/next-stream
Normal file
1
.testrepository/next-stream
Normal file
@ -0,0 +1 @@
|
||||
0
|
BIN
.tox/dist/python-manilaclient-9a3e8e1.zip
vendored
Normal file
BIN
.tox/dist/python-manilaclient-9a3e8e1.zip
vendored
Normal file
Binary file not shown.
253
.tox/log/tox-0.log
Normal file
253
.tox/log/tox-0.log
Normal file
@ -0,0 +1,253 @@
|
||||
actionid=tox
|
||||
msg=packaging
|
||||
cmdargs=['/usr/bin/python', local('/opt/stack/python-manilaclient/setup.py'), 'sdist', '--formats=zip', '--dist-dir', local('/opt/stack/python-manilaclient/.tox/dist')]
|
||||
env=None
|
||||
running sdist
|
||||
running egg_info
|
||||
writing requirements to python_manilaclient.egg-info/requires.txt
|
||||
writing python_manilaclient.egg-info/PKG-INFO
|
||||
writing top-level names to python_manilaclient.egg-info/top_level.txt
|
||||
writing dependency_links to python_manilaclient.egg-info/dependency_links.txt
|
||||
writing entry points to python_manilaclient.egg-info/entry_points.txt
|
||||
reading manifest template 'MANIFEST.in'
|
||||
warning: no previously-included files found matching '.gitreview'
|
||||
writing manifest file 'python_manilaclient.egg-info/SOURCES.txt'
|
||||
warning: LocalSDist: standard file not found: should have one of README, README.txt
|
||||
|
||||
creating python-manilaclient-9a3e8e1
|
||||
creating python-manilaclient-9a3e8e1/doc
|
||||
creating python-manilaclient-9a3e8e1/doc/source
|
||||
creating python-manilaclient-9a3e8e1/manilaclient
|
||||
creating python-manilaclient-9a3e8e1/manilaclient/openstack
|
||||
creating python-manilaclient-9a3e8e1/manilaclient/openstack/common
|
||||
creating python-manilaclient-9a3e8e1/manilaclient/v1
|
||||
creating python-manilaclient-9a3e8e1/manilaclient/v1/contrib
|
||||
creating python-manilaclient-9a3e8e1/manilaclient/v2
|
||||
creating python-manilaclient-9a3e8e1/manilaclient/v2/contrib
|
||||
creating python-manilaclient-9a3e8e1/python_manilaclient.egg-info
|
||||
creating python-manilaclient-9a3e8e1/tests
|
||||
creating python-manilaclient-9a3e8e1/tests/v1
|
||||
creating python-manilaclient-9a3e8e1/tests/v1/contrib
|
||||
creating python-manilaclient-9a3e8e1/tests/v1/shares
|
||||
creating python-manilaclient-9a3e8e1/tests/v2
|
||||
creating python-manilaclient-9a3e8e1/tests/v2/contrib
|
||||
creating python-manilaclient-9a3e8e1/tests/v2/shares
|
||||
creating python-manilaclient-9a3e8e1/tools
|
||||
making hard links in python-manilaclient-9a3e8e1...
|
||||
hard linking AUTHORS -> python-manilaclient-9a3e8e1
|
||||
hard linking ChangeLog -> python-manilaclient-9a3e8e1
|
||||
hard linking HACKING -> python-manilaclient-9a3e8e1
|
||||
hard linking LICENSE -> python-manilaclient-9a3e8e1
|
||||
hard linking MANIFEST.in -> python-manilaclient-9a3e8e1
|
||||
hard linking README.rst -> python-manilaclient-9a3e8e1
|
||||
hard linking openstack-common.conf -> python-manilaclient-9a3e8e1
|
||||
hard linking run_tests.sh -> python-manilaclient-9a3e8e1
|
||||
hard linking setup.cfg -> python-manilaclient-9a3e8e1
|
||||
hard linking setup.py -> python-manilaclient-9a3e8e1
|
||||
hard linking tox.ini -> python-manilaclient-9a3e8e1
|
||||
hard linking doc/.gitignore -> python-manilaclient-9a3e8e1/doc
|
||||
hard linking doc/Makefile -> python-manilaclient-9a3e8e1/doc
|
||||
hard linking doc/source/conf.py -> python-manilaclient-9a3e8e1/doc/source
|
||||
hard linking doc/source/index.rst -> python-manilaclient-9a3e8e1/doc/source
|
||||
hard linking doc/source/shell.rst -> python-manilaclient-9a3e8e1/doc/source
|
||||
hard linking manilaclient/__init__.py -> python-manilaclient-9a3e8e1/manilaclient
|
||||
hard linking manilaclient/base.py -> python-manilaclient-9a3e8e1/manilaclient
|
||||
hard linking manilaclient/client.py -> python-manilaclient-9a3e8e1/manilaclient
|
||||
hard linking manilaclient/exceptions.py -> python-manilaclient-9a3e8e1/manilaclient
|
||||
hard linking manilaclient/extension.py -> python-manilaclient-9a3e8e1/manilaclient
|
||||
hard linking manilaclient/service_catalog.py -> python-manilaclient-9a3e8e1/manilaclient
|
||||
hard linking manilaclient/shell.py -> python-manilaclient-9a3e8e1/manilaclient
|
||||
hard linking manilaclient/utils.py -> python-manilaclient-9a3e8e1/manilaclient
|
||||
hard linking manilaclient/openstack/__init__.py -> python-manilaclient-9a3e8e1/manilaclient/openstack
|
||||
hard linking manilaclient/openstack/common/__init__.py -> python-manilaclient-9a3e8e1/manilaclient/openstack/common
|
||||
hard linking manilaclient/openstack/common/setup.py -> python-manilaclient-9a3e8e1/manilaclient/openstack/common
|
||||
hard linking manilaclient/openstack/common/strutils.py -> python-manilaclient-9a3e8e1/manilaclient/openstack/common
|
||||
hard linking manilaclient/openstack/common/version.py -> python-manilaclient-9a3e8e1/manilaclient/openstack/common
|
||||
hard linking manilaclient/v1/__init__.py -> python-manilaclient-9a3e8e1/manilaclient/v1
|
||||
hard linking manilaclient/v1/client.py -> python-manilaclient-9a3e8e1/manilaclient/v1
|
||||
hard linking manilaclient/v1/limits.py -> python-manilaclient-9a3e8e1/manilaclient/v1
|
||||
hard linking manilaclient/v1/quota_classes.py -> python-manilaclient-9a3e8e1/manilaclient/v1
|
||||
hard linking manilaclient/v1/quotas.py -> python-manilaclient-9a3e8e1/manilaclient/v1
|
||||
hard linking manilaclient/v1/share_snapshots.py -> python-manilaclient-9a3e8e1/manilaclient/v1
|
||||
hard linking manilaclient/v1/shares.py -> python-manilaclient-9a3e8e1/manilaclient/v1
|
||||
hard linking manilaclient/v1/shell.py -> python-manilaclient-9a3e8e1/manilaclient/v1
|
||||
hard linking manilaclient/v1/contrib/__init__.py -> python-manilaclient-9a3e8e1/manilaclient/v1/contrib
|
||||
hard linking manilaclient/v1/contrib/list_extensions.py -> python-manilaclient-9a3e8e1/manilaclient/v1/contrib
|
||||
hard linking manilaclient/v2/__init__.py -> python-manilaclient-9a3e8e1/manilaclient/v2
|
||||
hard linking manilaclient/v2/client.py -> python-manilaclient-9a3e8e1/manilaclient/v2
|
||||
hard linking manilaclient/v2/limits.py -> python-manilaclient-9a3e8e1/manilaclient/v2
|
||||
hard linking manilaclient/v2/quota_classes.py -> python-manilaclient-9a3e8e1/manilaclient/v2
|
||||
hard linking manilaclient/v2/quotas.py -> python-manilaclient-9a3e8e1/manilaclient/v2
|
||||
hard linking manilaclient/v2/share_snapshots.py -> python-manilaclient-9a3e8e1/manilaclient/v2
|
||||
hard linking manilaclient/v2/shares.py -> python-manilaclient-9a3e8e1/manilaclient/v2
|
||||
hard linking manilaclient/v2/shell.py -> python-manilaclient-9a3e8e1/manilaclient/v2
|
||||
hard linking manilaclient/v2/volume_backups.py -> python-manilaclient-9a3e8e1/manilaclient/v2
|
||||
hard linking manilaclient/v2/volume_backups_restore.py -> python-manilaclient-9a3e8e1/manilaclient/v2
|
||||
hard linking manilaclient/v2/volume_snapshots.py -> python-manilaclient-9a3e8e1/manilaclient/v2
|
||||
hard linking manilaclient/v2/volume_types.py -> python-manilaclient-9a3e8e1/manilaclient/v2
|
||||
hard linking manilaclient/v2/volumes.py -> python-manilaclient-9a3e8e1/manilaclient/v2
|
||||
hard linking manilaclient/v2/contrib/__init__.py -> python-manilaclient-9a3e8e1/manilaclient/v2/contrib
|
||||
hard linking manilaclient/v2/contrib/list_extensions.py -> python-manilaclient-9a3e8e1/manilaclient/v2/contrib
|
||||
hard linking python_manilaclient.egg-info/PKG-INFO -> python-manilaclient-9a3e8e1/python_manilaclient.egg-info
|
||||
hard linking python_manilaclient.egg-info/SOURCES.txt -> python-manilaclient-9a3e8e1/python_manilaclient.egg-info
|
||||
hard linking python_manilaclient.egg-info/dependency_links.txt -> python-manilaclient-9a3e8e1/python_manilaclient.egg-info
|
||||
hard linking python_manilaclient.egg-info/entry_points.txt -> python-manilaclient-9a3e8e1/python_manilaclient.egg-info
|
||||
hard linking python_manilaclient.egg-info/requires.txt -> python-manilaclient-9a3e8e1/python_manilaclient.egg-info
|
||||
hard linking python_manilaclient.egg-info/top_level.txt -> python-manilaclient-9a3e8e1/python_manilaclient.egg-info
|
||||
hard linking tests/__init__.py -> python-manilaclient-9a3e8e1/tests
|
||||
hard linking tests/fakes.py -> python-manilaclient-9a3e8e1/tests
|
||||
hard linking tests/test_base.py -> python-manilaclient-9a3e8e1/tests
|
||||
hard linking tests/test_client.py -> python-manilaclient-9a3e8e1/tests
|
||||
hard linking tests/test_http.py -> python-manilaclient-9a3e8e1/tests
|
||||
hard linking tests/test_service_catalog.py -> python-manilaclient-9a3e8e1/tests
|
||||
hard linking tests/test_shell.py -> python-manilaclient-9a3e8e1/tests
|
||||
hard linking tests/test_utils.py -> python-manilaclient-9a3e8e1/tests
|
||||
hard linking tests/utils.py -> python-manilaclient-9a3e8e1/tests
|
||||
hard linking tests/v1/__init__.py -> python-manilaclient-9a3e8e1/tests/v1
|
||||
hard linking tests/v1/fakes.py -> python-manilaclient-9a3e8e1/tests/v1
|
||||
hard linking tests/v1/test_auth.py -> python-manilaclient-9a3e8e1/tests/v1
|
||||
hard linking tests/v1/test_quota_classes.py -> python-manilaclient-9a3e8e1/tests/v1
|
||||
hard linking tests/v1/test_quotas.py -> python-manilaclient-9a3e8e1/tests/v1
|
||||
hard linking tests/v1/test_shell.py -> python-manilaclient-9a3e8e1/tests/v1
|
||||
hard linking tests/v1/test_types.py -> python-manilaclient-9a3e8e1/tests/v1
|
||||
hard linking tests/v1/test_volume_backups.py -> python-manilaclient-9a3e8e1/tests/v1
|
||||
hard linking tests/v1/test_volumes.py -> python-manilaclient-9a3e8e1/tests/v1
|
||||
hard linking tests/v1/testfile.txt -> python-manilaclient-9a3e8e1/tests/v1
|
||||
hard linking tests/v1/contrib/__init__.py -> python-manilaclient-9a3e8e1/tests/v1/contrib
|
||||
hard linking tests/v1/contrib/test_list_extensions.py -> python-manilaclient-9a3e8e1/tests/v1/contrib
|
||||
hard linking tests/v1/shares/__init__.py -> python-manilaclient-9a3e8e1/tests/v1/shares
|
||||
hard linking tests/v1/shares/fakes.py -> python-manilaclient-9a3e8e1/tests/v1/shares
|
||||
hard linking tests/v1/shares/test_share_snapshots.py -> python-manilaclient-9a3e8e1/tests/v1/shares
|
||||
hard linking tests/v1/shares/test_shares.py -> python-manilaclient-9a3e8e1/tests/v1/shares
|
||||
hard linking tests/v2/__init__.py -> python-manilaclient-9a3e8e1/tests/v2
|
||||
hard linking tests/v2/fakes.py -> python-manilaclient-9a3e8e1/tests/v2
|
||||
hard linking tests/v2/test_auth.py -> python-manilaclient-9a3e8e1/tests/v2
|
||||
hard linking tests/v2/test_quota_classes.py -> python-manilaclient-9a3e8e1/tests/v2
|
||||
hard linking tests/v2/test_quotas.py -> python-manilaclient-9a3e8e1/tests/v2
|
||||
hard linking tests/v2/test_shell.py -> python-manilaclient-9a3e8e1/tests/v2
|
||||
hard linking tests/v2/test_types.py -> python-manilaclient-9a3e8e1/tests/v2
|
||||
hard linking tests/v2/test_volume_backups.py -> python-manilaclient-9a3e8e1/tests/v2
|
||||
hard linking tests/v2/test_volumes.py -> python-manilaclient-9a3e8e1/tests/v2
|
||||
hard linking tests/v2/contrib/__init__.py -> python-manilaclient-9a3e8e1/tests/v2/contrib
|
||||
hard linking tests/v2/contrib/test_list_extensions.py -> python-manilaclient-9a3e8e1/tests/v2/contrib
|
||||
hard linking tests/v2/shares/__init__.py -> python-manilaclient-9a3e8e1/tests/v2/shares
|
||||
hard linking tests/v2/shares/fakes.py -> python-manilaclient-9a3e8e1/tests/v2/shares
|
||||
hard linking tests/v2/shares/test_share_snapshots.py -> python-manilaclient-9a3e8e1/tests/v2/shares
|
||||
hard linking tests/v2/shares/test_shares.py -> python-manilaclient-9a3e8e1/tests/v2/shares
|
||||
hard linking tools/cinder.bash_completion -> python-manilaclient-9a3e8e1/tools
|
||||
hard linking tools/generate_authors.sh -> python-manilaclient-9a3e8e1/tools
|
||||
hard linking tools/install_venv.py -> python-manilaclient-9a3e8e1/tools
|
||||
hard linking tools/pip-requires -> python-manilaclient-9a3e8e1/tools
|
||||
hard linking tools/test-requires -> python-manilaclient-9a3e8e1/tools
|
||||
hard linking tools/with_venv.sh -> python-manilaclient-9a3e8e1/tools
|
||||
copying setup.cfg -> python-manilaclient-9a3e8e1
|
||||
Writing python-manilaclient-9a3e8e1/setup.cfg
|
||||
creating '.tox/dist/python-manilaclient-9a3e8e1.zip' and adding 'python-manilaclient-9a3e8e1' to it
|
||||
adding 'python-manilaclient-9a3e8e1/README.rst'
|
||||
adding 'python-manilaclient-9a3e8e1/tox.ini'
|
||||
adding 'python-manilaclient-9a3e8e1/openstack-common.conf'
|
||||
adding 'python-manilaclient-9a3e8e1/setup.py'
|
||||
adding 'python-manilaclient-9a3e8e1/run_tests.sh'
|
||||
adding 'python-manilaclient-9a3e8e1/AUTHORS'
|
||||
adding 'python-manilaclient-9a3e8e1/setup.cfg'
|
||||
adding 'python-manilaclient-9a3e8e1/LICENSE'
|
||||
adding 'python-manilaclient-9a3e8e1/PKG-INFO'
|
||||
adding 'python-manilaclient-9a3e8e1/ChangeLog'
|
||||
adding 'python-manilaclient-9a3e8e1/MANIFEST.in'
|
||||
adding 'python-manilaclient-9a3e8e1/HACKING'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/exceptions.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/shell.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/client.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/service_catalog.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/base.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/__init__.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/utils.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/extension.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/quota_classes.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/volume_snapshots.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/shell.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/client.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/volume_backups.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/quotas.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/limits.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/__init__.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/volume_backups_restore.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/shares.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/volumes.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/share_snapshots.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/volume_types.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/contrib/list_extensions.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v2/contrib/__init__.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/openstack/__init__.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/openstack/common/setup.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/openstack/common/version.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/openstack/common/__init__.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/openstack/common/strutils.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v1/quota_classes.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v1/shell.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v1/client.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v1/quotas.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v1/limits.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v1/__init__.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v1/shares.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v1/share_snapshots.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v1/contrib/list_extensions.py'
|
||||
adding 'python-manilaclient-9a3e8e1/manilaclient/v1/contrib/__init__.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tools/generate_authors.sh'
|
||||
adding 'python-manilaclient-9a3e8e1/tools/with_venv.sh'
|
||||
adding 'python-manilaclient-9a3e8e1/tools/test-requires'
|
||||
adding 'python-manilaclient-9a3e8e1/tools/pip-requires'
|
||||
adding 'python-manilaclient-9a3e8e1/tools/install_venv.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tools/cinder.bash_completion'
|
||||
adding 'python-manilaclient-9a3e8e1/doc/Makefile'
|
||||
adding 'python-manilaclient-9a3e8e1/doc/.gitignore'
|
||||
adding 'python-manilaclient-9a3e8e1/doc/source/shell.rst'
|
||||
adding 'python-manilaclient-9a3e8e1/doc/source/conf.py'
|
||||
adding 'python-manilaclient-9a3e8e1/doc/source/index.rst'
|
||||
adding 'python-manilaclient-9a3e8e1/python_manilaclient.egg-info/top_level.txt'
|
||||
adding 'python-manilaclient-9a3e8e1/python_manilaclient.egg-info/SOURCES.txt'
|
||||
adding 'python-manilaclient-9a3e8e1/python_manilaclient.egg-info/dependency_links.txt'
|
||||
adding 'python-manilaclient-9a3e8e1/python_manilaclient.egg-info/PKG-INFO'
|
||||
adding 'python-manilaclient-9a3e8e1/python_manilaclient.egg-info/requires.txt'
|
||||
adding 'python-manilaclient-9a3e8e1/python_manilaclient.egg-info/entry_points.txt'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/test_shell.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/test_http.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/test_client.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/test_base.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/__init__.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/utils.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/test_utils.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/test_service_catalog.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/fakes.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/test_quota_classes.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/test_shell.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/test_auth.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/test_volumes.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/test_volume_backups.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/test_types.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/test_quotas.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/__init__.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/fakes.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/contrib/__init__.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/contrib/test_list_extensions.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/shares/test_shares.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/shares/test_share_snapshots.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/shares/__init__.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v2/shares/fakes.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/test_quota_classes.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/test_shell.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/test_auth.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/test_volumes.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/test_volume_backups.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/test_types.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/test_quotas.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/__init__.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/testfile.txt'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/fakes.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/contrib/__init__.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/contrib/test_list_extensions.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/shares/test_shares.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/shares/test_share_snapshots.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/shares/__init__.py'
|
||||
adding 'python-manilaclient-9a3e8e1/tests/v1/shares/fakes.py'
|
||||
removing 'python-manilaclient-9a3e8e1' (and everything under it)
|
3
.tox/pep8/.tox-config1
Normal file
3
.tox/pep8/.tox-config1
Normal file
@ -0,0 +1,3 @@
|
||||
00000000000000000000000000000000 /usr/bin/python
|
||||
1.6.1 0 0 0
|
||||
00000000000000000000000000000000 pep8
|
80
.tox/pep8/bin/activate
Normal file
80
.tox/pep8/bin/activate
Normal file
@ -0,0 +1,80 @@
|
||||
# This file must be used with "source bin/activate" *from bash*
|
||||
# you cannot run it directly
|
||||
|
||||
deactivate () {
|
||||
unset pydoc
|
||||
|
||||
# reset old environment variables
|
||||
if [ -n "$_OLD_VIRTUAL_PATH" ] ; then
|
||||
PATH="$_OLD_VIRTUAL_PATH"
|
||||
export PATH
|
||||
unset _OLD_VIRTUAL_PATH
|
||||
fi
|
||||
if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then
|
||||
PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
|
||||
export PYTHONHOME
|
||||
unset _OLD_VIRTUAL_PYTHONHOME
|
||||
fi
|
||||
|
||||
# This should detect bash and zsh, which have a hash command that must
|
||||
# be called to get it to forget past commands. Without forgetting
|
||||
# past commands the $PATH changes we made may not be respected
|
||||
if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
|
||||
hash -r 2>/dev/null
|
||||
fi
|
||||
|
||||
if [ -n "$_OLD_VIRTUAL_PS1" ] ; then
|
||||
PS1="$_OLD_VIRTUAL_PS1"
|
||||
export PS1
|
||||
unset _OLD_VIRTUAL_PS1
|
||||
fi
|
||||
|
||||
unset VIRTUAL_ENV
|
||||
if [ ! "$1" = "nondestructive" ] ; then
|
||||
# Self destruct!
|
||||
unset -f deactivate
|
||||
fi
|
||||
}
|
||||
|
||||
# unset irrelevant variables
|
||||
deactivate nondestructive
|
||||
|
||||
VIRTUAL_ENV="/opt/stack/python-manilaclient/.tox/pep8"
|
||||
export VIRTUAL_ENV
|
||||
|
||||
_OLD_VIRTUAL_PATH="$PATH"
|
||||
PATH="$VIRTUAL_ENV/bin:$PATH"
|
||||
export PATH
|
||||
|
||||
# unset PYTHONHOME if set
|
||||
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
|
||||
# could use `if (set -u; : $PYTHONHOME) ;` in bash
|
||||
if [ -n "$PYTHONHOME" ] ; then
|
||||
_OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME"
|
||||
unset PYTHONHOME
|
||||
fi
|
||||
|
||||
if [ -z "$VIRTUAL_ENV_DISABLE_PROMPT" ] ; then
|
||||
_OLD_VIRTUAL_PS1="$PS1"
|
||||
if [ "x" != x ] ; then
|
||||
PS1="$PS1"
|
||||
else
|
||||
if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
|
||||
# special case for Aspen magic directories
|
||||
# see http://www.zetadev.com/software/aspen/
|
||||
PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
|
||||
else
|
||||
PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
|
||||
fi
|
||||
fi
|
||||
export PS1
|
||||
fi
|
||||
|
||||
alias pydoc="python -m pydoc"
|
||||
|
||||
# This should detect bash and zsh, which have a hash command that must
|
||||
# be called to get it to forget past commands. Without forgetting
|
||||
# past commands the $PATH changes we made may not be respected
|
||||
if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
|
||||
hash -r 2>/dev/null
|
||||
fi
|
42
.tox/pep8/bin/activate.csh
Normal file
42
.tox/pep8/bin/activate.csh
Normal file
@ -0,0 +1,42 @@
|
||||
# This file must be used with "source bin/activate.csh" *from csh*.
|
||||
# You cannot run it directly.
|
||||
# Created by Davide Di Blasi <davidedb@gmail.com>.
|
||||
|
||||
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate && unalias pydoc'
|
||||
|
||||
# Unset irrelevant variables.
|
||||
deactivate nondestructive
|
||||
|
||||
setenv VIRTUAL_ENV "/opt/stack/python-manilaclient/.tox/pep8"
|
||||
|
||||
set _OLD_VIRTUAL_PATH="$PATH"
|
||||
setenv PATH "$VIRTUAL_ENV/bin:$PATH"
|
||||
|
||||
|
||||
|
||||
if ("" != "") then
|
||||
set env_name = ""
|
||||
else
|
||||
if (`basename "$VIRTUAL_ENV"` == "__") then
|
||||
# special case for Aspen magic directories
|
||||
# see http://www.zetadev.com/software/aspen/
|
||||
set env_name = `basename \`dirname "$VIRTUAL_ENV"\``
|
||||
else
|
||||
set env_name = `basename "$VIRTUAL_ENV"`
|
||||
endif
|
||||
endif
|
||||
|
||||
# Could be in a non-interactive environment,
|
||||
# in which case, $prompt is undefined and we wouldn't
|
||||
# care about the prompt anyway.
|
||||
if ( $?prompt ) then
|
||||
set _OLD_VIRTUAL_PROMPT="$prompt"
|
||||
set prompt = "[$env_name] $prompt"
|
||||
endif
|
||||
|
||||
unset env_name
|
||||
|
||||
alias pydoc python -m pydoc
|
||||
|
||||
rehash
|
||||
|
74
.tox/pep8/bin/activate.fish
Normal file
74
.tox/pep8/bin/activate.fish
Normal file
@ -0,0 +1,74 @@
|
||||
# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org)
|
||||
# you cannot run it directly
|
||||
|
||||
function deactivate -d "Exit virtualenv and return to normal shell environment"
|
||||
# reset old environment variables
|
||||
if test -n "$_OLD_VIRTUAL_PATH"
|
||||
set -gx PATH $_OLD_VIRTUAL_PATH
|
||||
set -e _OLD_VIRTUAL_PATH
|
||||
end
|
||||
if test -n "$_OLD_VIRTUAL_PYTHONHOME"
|
||||
set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
|
||||
set -e _OLD_VIRTUAL_PYTHONHOME
|
||||
end
|
||||
|
||||
if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
|
||||
functions -e fish_prompt
|
||||
set -e _OLD_FISH_PROMPT_OVERRIDE
|
||||
. ( begin
|
||||
printf "function fish_prompt\n\t#"
|
||||
functions _old_fish_prompt
|
||||
end | psub )
|
||||
functions -e _old_fish_prompt
|
||||
end
|
||||
|
||||
set -e VIRTUAL_ENV
|
||||
if test "$argv[1]" != "nondestructive"
|
||||
# Self destruct!
|
||||
functions -e deactivate
|
||||
end
|
||||
end
|
||||
|
||||
# unset irrelevant variables
|
||||
deactivate nondestructive
|
||||
|
||||
set -gx VIRTUAL_ENV "/opt/stack/python-manilaclient/.tox/pep8"
|
||||
|
||||
set -gx _OLD_VIRTUAL_PATH $PATH
|
||||
set -gx PATH "$VIRTUAL_ENV/bin" $PATH
|
||||
|
||||
# unset PYTHONHOME if set
|
||||
if set -q PYTHONHOME
|
||||
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
|
||||
set -e PYTHONHOME
|
||||
end
|
||||
|
||||
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
|
||||
# fish uses a function instead of an env var to generate the prompt.
|
||||
|
||||
# save the current fish_prompt function as the function _old_fish_prompt
|
||||
. ( begin
|
||||
printf "function _old_fish_prompt\n\t#"
|
||||
functions fish_prompt
|
||||
end | psub )
|
||||
|
||||
# with the original prompt function renamed, we can override with our own.
|
||||
function fish_prompt
|
||||
# Prompt override?
|
||||
if test -n ""
|
||||
printf "%s%s%s" "" (set_color normal) (_old_fish_prompt)
|
||||
return
|
||||
end
|
||||
# ...Otherwise, prepend env
|
||||
set -l _checkbase (basename "$VIRTUAL_ENV")
|
||||
if test $_checkbase = "__"
|
||||
# special case for Aspen magic directories
|
||||
# see http://www.zetadev.com/software/aspen/
|
||||
printf "%s[%s]%s %s" (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) (_old_fish_prompt)
|
||||
else
|
||||
printf "%s(%s)%s%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) (_old_fish_prompt)
|
||||
end
|
||||
end
|
||||
|
||||
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
|
||||
end
|
34
.tox/pep8/bin/activate_this.py
Normal file
34
.tox/pep8/bin/activate_this.py
Normal file
@ -0,0 +1,34 @@
|
||||
"""By using execfile(this_file, dict(__file__=this_file)) you will
|
||||
activate this virtualenv environment.
|
||||
|
||||
This can be used when you must use an existing Python interpreter, not
|
||||
the virtualenv bin/python
|
||||
"""
|
||||
|
||||
try:
|
||||
__file__
|
||||
except NameError:
|
||||
raise AssertionError(
|
||||
"You must run this like execfile('path/to/activate_this.py', dict(__file__='path/to/activate_this.py'))")
|
||||
import sys
|
||||
import os
|
||||
|
||||
old_os_path = os.environ['PATH']
|
||||
os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + os.pathsep + old_os_path
|
||||
base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
if sys.platform == 'win32':
|
||||
site_packages = os.path.join(base, 'Lib', 'site-packages')
|
||||
else:
|
||||
site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages')
|
||||
prev_sys_path = list(sys.path)
|
||||
import site
|
||||
site.addsitedir(site_packages)
|
||||
sys.real_prefix = sys.prefix
|
||||
sys.prefix = base
|
||||
# Move the added items to the front of the path:
|
||||
new_sys_path = []
|
||||
for item in list(sys.path):
|
||||
if item not in prev_sys_path:
|
||||
new_sys_path.append(item)
|
||||
sys.path.remove(item)
|
||||
sys.path[:0] = new_sys_path
|
10
.tox/pep8/bin/easy_install
Executable file
10
.tox/pep8/bin/easy_install
Executable file
@ -0,0 +1,10 @@
|
||||
#!/opt/stack/python-manilaclient/.tox/pep8/bin/python
|
||||
# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.9.8','console_scripts','easy_install'
|
||||
__requires__ = 'setuptools==0.9.8'
|
||||
import sys
|
||||
from pkg_resources import load_entry_point
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(
|
||||
load_entry_point('setuptools==0.9.8', 'console_scripts', 'easy_install')()
|
||||
)
|
10
.tox/pep8/bin/easy_install-2.7
Executable file
10
.tox/pep8/bin/easy_install-2.7
Executable file
@ -0,0 +1,10 @@
|
||||
#!/opt/stack/python-manilaclient/.tox/pep8/bin/python
|
||||
# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.9.8','console_scripts','easy_install-2.7'
|
||||
__requires__ = 'setuptools==0.9.8'
|
||||
import sys
|
||||
from pkg_resources import load_entry_point
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(
|
||||
load_entry_point('setuptools==0.9.8', 'console_scripts', 'easy_install-2.7')()
|
||||
)
|
10
.tox/pep8/bin/manila
Executable file
10
.tox/pep8/bin/manila
Executable file
@ -0,0 +1,10 @@
|
||||
#!/opt/stack/python-manilaclient/.tox/pep8/bin/python
|
||||
# EASY-INSTALL-ENTRY-SCRIPT: 'python-manilaclient==9a3e8e1','console_scripts','manila'
|
||||
__requires__ = 'python-manilaclient==9a3e8e1'
|
||||
import sys
|
||||
from pkg_resources import load_entry_point
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(
|
||||
load_entry_point('python-manilaclient==9a3e8e1', 'console_scripts', 'manila')()
|
||||
)
|
10
.tox/pep8/bin/pep8
Executable file
10
.tox/pep8/bin/pep8
Executable file
@ -0,0 +1,10 @@
|
||||
#!/opt/stack/python-manilaclient/.tox/pep8/bin/python
|
||||
# EASY-INSTALL-ENTRY-SCRIPT: 'pep8==1.4.6','console_scripts','pep8'
|
||||
__requires__ = 'pep8==1.4.6'
|
||||
import sys
|
||||
from pkg_resources import load_entry_point
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(
|
||||
load_entry_point('pep8==1.4.6', 'console_scripts', 'pep8')()
|
||||
)
|
10
.tox/pep8/bin/pip
Executable file
10
.tox/pep8/bin/pip
Executable file
@ -0,0 +1,10 @@
|
||||
#!/opt/stack/python-manilaclient/.tox/pep8/bin/python
|
||||
# EASY-INSTALL-ENTRY-SCRIPT: 'pip==1.4.1','console_scripts','pip'
|
||||
__requires__ = 'pip==1.4.1'
|
||||
import sys
|
||||
from pkg_resources import load_entry_point
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(
|
||||
load_entry_point('pip==1.4.1', 'console_scripts', 'pip')()
|
||||
)
|
10
.tox/pep8/bin/pip-2.7
Executable file
10
.tox/pep8/bin/pip-2.7
Executable file
@ -0,0 +1,10 @@
|
||||
#!/opt/stack/python-manilaclient/.tox/pep8/bin/python
|
||||
# EASY-INSTALL-ENTRY-SCRIPT: 'pip==1.4.1','console_scripts','pip-2.7'
|
||||
__requires__ = 'pip==1.4.1'
|
||||
import sys
|
||||
from pkg_resources import load_entry_point
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(
|
||||
load_entry_point('pip==1.4.1', 'console_scripts', 'pip-2.7')()
|
||||
)
|
BIN
.tox/pep8/bin/python
Executable file
BIN
.tox/pep8/bin/python
Executable file
Binary file not shown.
1
.tox/pep8/bin/python2
Symbolic link
1
.tox/pep8/bin/python2
Symbolic link
@ -0,0 +1 @@
|
||||
python
|
1
.tox/pep8/bin/python2.7
Symbolic link
1
.tox/pep8/bin/python2.7
Symbolic link
@ -0,0 +1 @@
|
||||
python
|
1
.tox/pep8/include/python2.7
Symbolic link
1
.tox/pep8/include/python2.7
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/include/python2.7
|
1
.tox/pep8/lib/python2.7/UserDict.py
Symbolic link
1
.tox/pep8/lib/python2.7/UserDict.py
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/UserDict.py
|
1
.tox/pep8/lib/python2.7/_abcoll.py
Symbolic link
1
.tox/pep8/lib/python2.7/_abcoll.py
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/_abcoll.py
|
1
.tox/pep8/lib/python2.7/_weakrefset.py
Symbolic link
1
.tox/pep8/lib/python2.7/_weakrefset.py
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/_weakrefset.py
|
1
.tox/pep8/lib/python2.7/abc.py
Symbolic link
1
.tox/pep8/lib/python2.7/abc.py
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/abc.py
|
1
.tox/pep8/lib/python2.7/codecs.py
Symbolic link
1
.tox/pep8/lib/python2.7/codecs.py
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/codecs.py
|
1
.tox/pep8/lib/python2.7/config
Symbolic link
1
.tox/pep8/lib/python2.7/config
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/config
|
1
.tox/pep8/lib/python2.7/copy_reg.py
Symbolic link
1
.tox/pep8/lib/python2.7/copy_reg.py
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/copy_reg.py
|
101
.tox/pep8/lib/python2.7/distutils/__init__.py
Normal file
101
.tox/pep8/lib/python2.7/distutils/__init__.py
Normal file
@ -0,0 +1,101 @@
|
||||
import os
|
||||
import sys
|
||||
import warnings
|
||||
import imp
|
||||
import opcode # opcode is not a virtualenv module, so we can use it to find the stdlib
|
||||
# Important! To work on pypy, this must be a module that resides in the
|
||||
# lib-python/modified-x.y.z directory
|
||||
|
||||
dirname = os.path.dirname
|
||||
|
||||
distutils_path = os.path.join(os.path.dirname(opcode.__file__), 'distutils')
|
||||
if os.path.normpath(distutils_path) == os.path.dirname(os.path.normpath(__file__)):
|
||||
warnings.warn(
|
||||
"The virtualenv distutils package at %s appears to be in the same location as the system distutils?")
|
||||
else:
|
||||
__path__.insert(0, distutils_path)
|
||||
real_distutils = imp.load_module("_virtualenv_distutils", None, distutils_path, ('', '', imp.PKG_DIRECTORY))
|
||||
# Copy the relevant attributes
|
||||
try:
|
||||
__revision__ = real_distutils.__revision__
|
||||
except AttributeError:
|
||||
pass
|
||||
__version__ = real_distutils.__version__
|
||||
|
||||
from distutils import dist, sysconfig
|
||||
|
||||
try:
|
||||
basestring
|
||||
except NameError:
|
||||
basestring = str
|
||||
|
||||
## patch build_ext (distutils doesn't know how to get the libs directory
|
||||
## path on windows - it hardcodes the paths around the patched sys.prefix)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
from distutils.command.build_ext import build_ext as old_build_ext
|
||||
class build_ext(old_build_ext):
|
||||
def finalize_options (self):
|
||||
if self.library_dirs is None:
|
||||
self.library_dirs = []
|
||||
elif isinstance(self.library_dirs, basestring):
|
||||
self.library_dirs = self.library_dirs.split(os.pathsep)
|
||||
|
||||
self.library_dirs.insert(0, os.path.join(sys.real_prefix, "Libs"))
|
||||
old_build_ext.finalize_options(self)
|
||||
|
||||
from distutils.command import build_ext as build_ext_module
|
||||
build_ext_module.build_ext = build_ext
|
||||
|
||||
## distutils.dist patches:
|
||||
|
||||
old_find_config_files = dist.Distribution.find_config_files
|
||||
def find_config_files(self):
|
||||
found = old_find_config_files(self)
|
||||
system_distutils = os.path.join(distutils_path, 'distutils.cfg')
|
||||
#if os.path.exists(system_distutils):
|
||||
# found.insert(0, system_distutils)
|
||||
# What to call the per-user config file
|
||||
if os.name == 'posix':
|
||||
user_filename = ".pydistutils.cfg"
|
||||
else:
|
||||
user_filename = "pydistutils.cfg"
|
||||
user_filename = os.path.join(sys.prefix, user_filename)
|
||||
if os.path.isfile(user_filename):
|
||||
for item in list(found):
|
||||
if item.endswith('pydistutils.cfg'):
|
||||
found.remove(item)
|
||||
found.append(user_filename)
|
||||
return found
|
||||
dist.Distribution.find_config_files = find_config_files
|
||||
|
||||
## distutils.sysconfig patches:
|
||||
|
||||
old_get_python_inc = sysconfig.get_python_inc
|
||||
def sysconfig_get_python_inc(plat_specific=0, prefix=None):
|
||||
if prefix is None:
|
||||
prefix = sys.real_prefix
|
||||
return old_get_python_inc(plat_specific, prefix)
|
||||
sysconfig_get_python_inc.__doc__ = old_get_python_inc.__doc__
|
||||
sysconfig.get_python_inc = sysconfig_get_python_inc
|
||||
|
||||
old_get_python_lib = sysconfig.get_python_lib
|
||||
def sysconfig_get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
|
||||
if standard_lib and prefix is None:
|
||||
prefix = sys.real_prefix
|
||||
return old_get_python_lib(plat_specific, standard_lib, prefix)
|
||||
sysconfig_get_python_lib.__doc__ = old_get_python_lib.__doc__
|
||||
sysconfig.get_python_lib = sysconfig_get_python_lib
|
||||
|
||||
old_get_config_vars = sysconfig.get_config_vars
|
||||
def sysconfig_get_config_vars(*args):
|
||||
real_vars = old_get_config_vars(*args)
|
||||
if sys.platform == 'win32':
|
||||
lib_dir = os.path.join(sys.real_prefix, "libs")
|
||||
if isinstance(real_vars, dict) and 'LIBDIR' not in real_vars:
|
||||
real_vars['LIBDIR'] = lib_dir # asked for all
|
||||
elif isinstance(real_vars, list) and 'LIBDIR' in args:
|
||||
real_vars = real_vars + [lib_dir] # asked for list
|
||||
return real_vars
|
||||
sysconfig_get_config_vars.__doc__ = old_get_config_vars.__doc__
|
||||
sysconfig.get_config_vars = sysconfig_get_config_vars
|
6
.tox/pep8/lib/python2.7/distutils/distutils.cfg
Normal file
6
.tox/pep8/lib/python2.7/distutils/distutils.cfg
Normal file
@ -0,0 +1,6 @@
|
||||
# This is a config file local to this virtualenv installation
|
||||
# You may include options that will be used by all distutils commands,
|
||||
# and by easy_install. For instance:
|
||||
#
|
||||
# [easy_install]
|
||||
# find_links = http://mylocalsite
|
1
.tox/pep8/lib/python2.7/encodings
Symbolic link
1
.tox/pep8/lib/python2.7/encodings
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/encodings
|
1
.tox/pep8/lib/python2.7/fnmatch.py
Symbolic link
1
.tox/pep8/lib/python2.7/fnmatch.py
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/fnmatch.py
|
1
.tox/pep8/lib/python2.7/genericpath.py
Symbolic link
1
.tox/pep8/lib/python2.7/genericpath.py
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/genericpath.py
|
1
.tox/pep8/lib/python2.7/lib-dynload
Symbolic link
1
.tox/pep8/lib/python2.7/lib-dynload
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/lib-dynload
|
1
.tox/pep8/lib/python2.7/linecache.py
Symbolic link
1
.tox/pep8/lib/python2.7/linecache.py
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/linecache.py
|
1
.tox/pep8/lib/python2.7/locale.py
Symbolic link
1
.tox/pep8/lib/python2.7/locale.py
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/locale.py
|
1
.tox/pep8/lib/python2.7/ntpath.py
Symbolic link
1
.tox/pep8/lib/python2.7/ntpath.py
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/ntpath.py
|
1
.tox/pep8/lib/python2.7/orig-prefix.txt
Normal file
1
.tox/pep8/lib/python2.7/orig-prefix.txt
Normal file
@ -0,0 +1 @@
|
||||
/usr
|
1
.tox/pep8/lib/python2.7/os.py
Symbolic link
1
.tox/pep8/lib/python2.7/os.py
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/os.py
|
1
.tox/pep8/lib/python2.7/posixpath.py
Symbolic link
1
.tox/pep8/lib/python2.7/posixpath.py
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/posixpath.py
|
1
.tox/pep8/lib/python2.7/re.py
Symbolic link
1
.tox/pep8/lib/python2.7/re.py
Symbolic link
@ -0,0 +1 @@
|
||||
/usr/lib/python2.7/re.py
|
16
.tox/pep8/lib/python2.7/site-packages/_markerlib/__init__.py
Normal file
16
.tox/pep8/lib/python2.7/site-packages/_markerlib/__init__.py
Normal file
@ -0,0 +1,16 @@
|
||||
try:
|
||||
import ast
|
||||
from _markerlib.markers import default_environment, compile, interpret
|
||||
except ImportError:
|
||||
if 'ast' in globals():
|
||||
raise
|
||||
def default_environment():
|
||||
return {}
|
||||
def compile(marker):
|
||||
def marker_fn(environment=None, override=None):
|
||||
# 'empty markers are True' heuristic won't install extra deps.
|
||||
return not marker.strip()
|
||||
marker_fn.__doc__ = marker
|
||||
return marker_fn
|
||||
def interpret(marker, environment=None, override=None):
|
||||
return compile(marker)()
|
119
.tox/pep8/lib/python2.7/site-packages/_markerlib/markers.py
Normal file
119
.tox/pep8/lib/python2.7/site-packages/_markerlib/markers.py
Normal file
@ -0,0 +1,119 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Interpret PEP 345 environment markers.
|
||||
|
||||
EXPR [in|==|!=|not in] EXPR [or|and] ...
|
||||
|
||||
where EXPR belongs to any of those:
|
||||
|
||||
python_version = '%s.%s' % (sys.version_info[0], sys.version_info[1])
|
||||
python_full_version = sys.version.split()[0]
|
||||
os.name = os.name
|
||||
sys.platform = sys.platform
|
||||
platform.version = platform.version()
|
||||
platform.machine = platform.machine()
|
||||
platform.python_implementation = platform.python_implementation()
|
||||
a free string, like '2.6', or 'win32'
|
||||
"""
|
||||
|
||||
__all__ = ['default_environment', 'compile', 'interpret']
|
||||
|
||||
import ast
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
import weakref
|
||||
|
||||
_builtin_compile = compile
|
||||
|
||||
try:
|
||||
from platform import python_implementation
|
||||
except ImportError:
|
||||
if os.name == "java":
|
||||
# Jython 2.5 has ast module, but not platform.python_implementation() function.
|
||||
def python_implementation():
|
||||
return "Jython"
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
# restricted set of variables
|
||||
_VARS = {'sys.platform': sys.platform,
|
||||
'python_version': '%s.%s' % sys.version_info[:2],
|
||||
# FIXME parsing sys.platform is not reliable, but there is no other
|
||||
# way to get e.g. 2.7.2+, and the PEP is defined with sys.version
|
||||
'python_full_version': sys.version.split(' ', 1)[0],
|
||||
'os.name': os.name,
|
||||
'platform.version': platform.version(),
|
||||
'platform.machine': platform.machine(),
|
||||
'platform.python_implementation': python_implementation(),
|
||||
'extra': None # wheel extension
|
||||
}
|
||||
|
||||
for var in list(_VARS.keys()):
|
||||
if '.' in var:
|
||||
_VARS[var.replace('.', '_')] = _VARS[var]
|
||||
|
||||
def default_environment():
|
||||
"""Return copy of default PEP 385 globals dictionary."""
|
||||
return dict(_VARS)
|
||||
|
||||
class ASTWhitelist(ast.NodeTransformer):
|
||||
def __init__(self, statement):
|
||||
self.statement = statement # for error messages
|
||||
|
||||
ALLOWED = (ast.Compare, ast.BoolOp, ast.Attribute, ast.Name, ast.Load, ast.Str)
|
||||
# Bool operations
|
||||
ALLOWED += (ast.And, ast.Or)
|
||||
# Comparison operations
|
||||
ALLOWED += (ast.Eq, ast.Gt, ast.GtE, ast.In, ast.Is, ast.IsNot, ast.Lt, ast.LtE, ast.NotEq, ast.NotIn)
|
||||
|
||||
def visit(self, node):
|
||||
"""Ensure statement only contains allowed nodes."""
|
||||
if not isinstance(node, self.ALLOWED):
|
||||
raise SyntaxError('Not allowed in environment markers.\n%s\n%s' %
|
||||
(self.statement,
|
||||
(' ' * node.col_offset) + '^'))
|
||||
return ast.NodeTransformer.visit(self, node)
|
||||
|
||||
def visit_Attribute(self, node):
|
||||
"""Flatten one level of attribute access."""
|
||||
new_node = ast.Name("%s.%s" % (node.value.id, node.attr), node.ctx)
|
||||
return ast.copy_location(new_node, node)
|
||||
|
||||
def parse_marker(marker):
|
||||
tree = ast.parse(marker, mode='eval')
|
||||
new_tree = ASTWhitelist(marker).generic_visit(tree)
|
||||
return new_tree
|
||||
|
||||
def compile_marker(parsed_marker):
|
||||
return _builtin_compile(parsed_marker, '<environment marker>', 'eval',
|
||||
dont_inherit=True)
|
||||
|
||||
_cache = weakref.WeakValueDictionary()
|
||||
|
||||
def compile(marker):
|
||||
"""Return compiled marker as a function accepting an environment dict."""
|
||||
try:
|
||||
return _cache[marker]
|
||||
except KeyError:
|
||||
pass
|
||||
if not marker.strip():
|
||||
def marker_fn(environment=None, override=None):
|
||||
""""""
|
||||
return True
|
||||
else:
|
||||
compiled_marker = compile_marker(parse_marker(marker))
|
||||
def marker_fn(environment=None, override=None):
|
||||
"""override updates environment"""
|
||||
if override is None:
|
||||
override = {}
|
||||
if environment is None:
|
||||
environment = default_environment()
|
||||
environment.update(override)
|
||||
return eval(compiled_marker, environment)
|
||||
marker_fn.__doc__ = marker
|
||||
_cache[marker] = marker_fn
|
||||
return _cache[marker]
|
||||
|
||||
def interpret(marker, environment=None):
|
||||
return compile(marker)(environment)
|
5
.tox/pep8/lib/python2.7/site-packages/easy_install.py
Normal file
5
.tox/pep8/lib/python2.7/site-packages/easy_install.py
Normal file
@ -0,0 +1,5 @@
|
||||
"""Run the EasyInstall command"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
from setuptools.command.easy_install import main
|
||||
main()
|
@ -0,0 +1,25 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2012 OpenStack LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from manilaclient.openstack.common import version
|
||||
|
||||
version_info = version.VersionInfo('python-manilaclient')
|
||||
# We have a circular import problem when we first run python setup.py sdist
|
||||
# It's harmless, so deflect it.
|
||||
try:
|
||||
__version__ = version_info.version_string()
|
||||
except AttributeError:
|
||||
__version__ = None
|
293
.tox/pep8/lib/python2.7/site-packages/manilaclient/base.py
Normal file
293
.tox/pep8/lib/python2.7/site-packages/manilaclient/base.py
Normal file
@ -0,0 +1,293 @@
|
||||
# Copyright 2010 Jacob Kaplan-Moss
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
Base utilities to build API operation managers and objects on top of.
|
||||
"""
|
||||
|
||||
import contextlib
|
||||
import hashlib
|
||||
import os
|
||||
from manilaclient import exceptions
|
||||
from manilaclient import utils
|
||||
|
||||
|
||||
# Python 2.4 compat
|
||||
try:
|
||||
all
|
||||
except NameError:
|
||||
def all(iterable):
|
||||
return True not in (not x for x in iterable)
|
||||
|
||||
|
||||
def getid(obj):
|
||||
"""
|
||||
Abstracts the common pattern of allowing both an object or an object's ID
|
||||
as a parameter when dealing with relationships.
|
||||
"""
|
||||
try:
|
||||
return obj.id
|
||||
except AttributeError:
|
||||
return obj
|
||||
|
||||
|
||||
class Manager(utils.HookableMixin):
|
||||
"""
|
||||
Managers interact with a particular type of API (servers, flavors, images,
|
||||
etc.) and provide CRUD operations for them.
|
||||
"""
|
||||
resource_class = None
|
||||
|
||||
def __init__(self, api):
|
||||
self.api = api
|
||||
|
||||
def _list(self, url, response_key, obj_class=None, body=None):
|
||||
resp = None
|
||||
if body:
|
||||
resp, body = self.api.client.post(url, body=body)
|
||||
else:
|
||||
resp, body = self.api.client.get(url)
|
||||
|
||||
if obj_class is None:
|
||||
obj_class = self.resource_class
|
||||
|
||||
data = body[response_key]
|
||||
# NOTE(ja): keystone returns values as list as {'values': [ ... ]}
|
||||
# unlike other services which just return the list...
|
||||
if isinstance(data, dict):
|
||||
try:
|
||||
data = data['values']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
with self.completion_cache('human_id', obj_class, mode="w"):
|
||||
with self.completion_cache('uuid', obj_class, mode="w"):
|
||||
return [obj_class(self, res, loaded=True)
|
||||
for res in data if res]
|
||||
|
||||
@contextlib.contextmanager
|
||||
def completion_cache(self, cache_type, obj_class, mode):
|
||||
"""
|
||||
The completion cache store items that can be used for bash
|
||||
autocompletion, like UUIDs or human-friendly IDs.
|
||||
|
||||
A resource listing will clear and repopulate the cache.
|
||||
|
||||
A resource create will append to the cache.
|
||||
|
||||
Delete is not handled because listings are assumed to be performed
|
||||
often enough to keep the cache reasonably up-to-date.
|
||||
"""
|
||||
base_dir = utils.env('manilaclient_UUID_CACHE_DIR',
|
||||
default="~/.manilaclient")
|
||||
|
||||
# NOTE(sirp): Keep separate UUID caches for each username + endpoint
|
||||
# pair
|
||||
username = utils.env('OS_USERNAME', 'MANILA_USERNAME')
|
||||
url = utils.env('OS_URL', 'MANILA_URL')
|
||||
uniqifier = hashlib.md5(username + url).hexdigest()
|
||||
|
||||
cache_dir = os.path.expanduser(os.path.join(base_dir, uniqifier))
|
||||
|
||||
try:
|
||||
os.makedirs(cache_dir, 0755)
|
||||
except OSError:
|
||||
# NOTE(kiall): This is typicaly either permission denied while
|
||||
# attempting to create the directory, or the directory
|
||||
# already exists. Either way, don't fail.
|
||||
pass
|
||||
|
||||
resource = obj_class.__name__.lower()
|
||||
filename = "%s-%s-cache" % (resource, cache_type.replace('_', '-'))
|
||||
path = os.path.join(cache_dir, filename)
|
||||
|
||||
cache_attr = "_%s_cache" % cache_type
|
||||
|
||||
try:
|
||||
setattr(self, cache_attr, open(path, mode))
|
||||
except IOError:
|
||||
# NOTE(kiall): This is typicaly a permission denied while
|
||||
# attempting to write the cache file.
|
||||
pass
|
||||
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
cache = getattr(self, cache_attr, None)
|
||||
if cache:
|
||||
cache.close()
|
||||
delattr(self, cache_attr)
|
||||
|
||||
def write_to_completion_cache(self, cache_type, val):
|
||||
cache = getattr(self, "_%s_cache" % cache_type, None)
|
||||
if cache:
|
||||
cache.write("%s\n" % val)
|
||||
|
||||
def _get(self, url, response_key=None):
|
||||
resp, body = self.api.client.get(url)
|
||||
if response_key:
|
||||
return self.resource_class(self, body[response_key], loaded=True)
|
||||
else:
|
||||
return self.resource_class(self, body, loaded=True)
|
||||
|
||||
def _create(self, url, body, response_key, return_raw=False, **kwargs):
|
||||
self.run_hooks('modify_body_for_create', body, **kwargs)
|
||||
resp, body = self.api.client.post(url, body=body)
|
||||
if return_raw:
|
||||
return body[response_key]
|
||||
|
||||
with self.completion_cache('human_id', self.resource_class, mode="a"):
|
||||
with self.completion_cache('uuid', self.resource_class, mode="a"):
|
||||
return self.resource_class(self, body[response_key])
|
||||
|
||||
def _delete(self, url):
|
||||
resp, body = self.api.client.delete(url)
|
||||
|
||||
def _update(self, url, body, **kwargs):
|
||||
self.run_hooks('modify_body_for_update', body, **kwargs)
|
||||
resp, body = self.api.client.put(url, body=body)
|
||||
return body
|
||||
|
||||
|
||||
class ManagerWithFind(Manager):
|
||||
"""
|
||||
Like a `Manager`, but with additional `find()`/`findall()` methods.
|
||||
"""
|
||||
def find(self, **kwargs):
|
||||
"""
|
||||
Find a single item with attributes matching ``**kwargs``.
|
||||
|
||||
This isn't very efficient: it loads the entire list then filters on
|
||||
the Python side.
|
||||
"""
|
||||
matches = self.findall(**kwargs)
|
||||
num_matches = len(matches)
|
||||
if num_matches == 0:
|
||||
msg = "No %s matching %s." % (self.resource_class.__name__, kwargs)
|
||||
raise exceptions.NotFound(404, msg)
|
||||
elif num_matches > 1:
|
||||
raise exceptions.NoUniqueMatch
|
||||
else:
|
||||
return matches[0]
|
||||
|
||||
def findall(self, **kwargs):
|
||||
"""
|
||||
Find all items with attributes matching ``**kwargs``.
|
||||
|
||||
This isn't very efficient: it loads the entire list then filters on
|
||||
the Python side.
|
||||
"""
|
||||
found = []
|
||||
searches = kwargs.items()
|
||||
|
||||
for obj in self.list():
|
||||
try:
|
||||
if all(getattr(obj, attr) == value
|
||||
for (attr, value) in searches):
|
||||
found.append(obj)
|
||||
except AttributeError:
|
||||
continue
|
||||
|
||||
return found
|
||||
|
||||
def list(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Resource(object):
|
||||
"""
|
||||
A resource represents a particular instance of an object (server, flavor,
|
||||
etc). This is pretty much just a bag for attributes.
|
||||
|
||||
:param manager: Manager object
|
||||
:param info: dictionary representing resource attributes
|
||||
:param loaded: prevent lazy-loading if set to True
|
||||
"""
|
||||
HUMAN_ID = False
|
||||
|
||||
def __init__(self, manager, info, loaded=False):
|
||||
self.manager = manager
|
||||
self._info = info
|
||||
self._add_details(info)
|
||||
self._loaded = loaded
|
||||
|
||||
# NOTE(sirp): ensure `id` is already present because if it isn't we'll
|
||||
# enter an infinite loop of __getattr__ -> get -> __init__ ->
|
||||
# __getattr__ -> ...
|
||||
if 'id' in self.__dict__ and len(str(self.id)) == 36:
|
||||
self.manager.write_to_completion_cache('uuid', self.id)
|
||||
|
||||
human_id = self.human_id
|
||||
if human_id:
|
||||
self.manager.write_to_completion_cache('human_id', human_id)
|
||||
|
||||
@property
|
||||
def human_id(self):
|
||||
"""Subclasses may override this provide a pretty ID which can be used
|
||||
for bash completion.
|
||||
"""
|
||||
if 'name' in self.__dict__ and self.HUMAN_ID:
|
||||
return utils.slugify(self.name)
|
||||
return None
|
||||
|
||||
def _add_details(self, info):
|
||||
for (k, v) in info.iteritems():
|
||||
try:
|
||||
setattr(self, k, v)
|
||||
except AttributeError:
|
||||
# In this case we already defined the attribute on the class
|
||||
pass
|
||||
|
||||
def __getattr__(self, k):
|
||||
if k not in self.__dict__:
|
||||
#NOTE(bcwaldon): disallow lazy-loading if already loaded once
|
||||
if not self.is_loaded():
|
||||
self.get()
|
||||
return self.__getattr__(k)
|
||||
|
||||
raise AttributeError(k)
|
||||
else:
|
||||
return self.__dict__[k]
|
||||
|
||||
def __repr__(self):
|
||||
reprkeys = sorted(k for k in self.__dict__.keys() if k[0] != '_' and
|
||||
k != 'manager')
|
||||
info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys)
|
||||
return "<%s %s>" % (self.__class__.__name__, info)
|
||||
|
||||
def get(self):
|
||||
# set_loaded() first ... so if we have to bail, we know we tried.
|
||||
self.set_loaded(True)
|
||||
if not hasattr(self.manager, 'get'):
|
||||
return
|
||||
|
||||
new = self.manager.get(self.id)
|
||||
if new:
|
||||
self._add_details(new._info)
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, self.__class__):
|
||||
return False
|
||||
if hasattr(self, 'id') and hasattr(other, 'id'):
|
||||
return self.id == other.id
|
||||
return self._info == other._info
|
||||
|
||||
def is_loaded(self):
|
||||
return self._loaded
|
||||
|
||||
def set_loaded(self, val):
|
||||
self._loaded = val
|
378
.tox/pep8/lib/python2.7/site-packages/manilaclient/client.py
Normal file
378
.tox/pep8/lib/python2.7/site-packages/manilaclient/client.py
Normal file
@ -0,0 +1,378 @@
|
||||
# Copyright 2010 Jacob Kaplan-Moss
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 Piston Cloud Computing, Inc.
|
||||
|
||||
# All Rights Reserved.
|
||||
"""
|
||||
OpenStack Client interface. Handles the REST calls and responses.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import urlparse
|
||||
try:
|
||||
from eventlet import sleep
|
||||
except ImportError:
|
||||
from time import sleep
|
||||
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
import simplejson as json
|
||||
|
||||
# Python 2.5 compat fix
|
||||
if not hasattr(urlparse, 'parse_qsl'):
|
||||
import cgi
|
||||
urlparse.parse_qsl = cgi.parse_qsl
|
||||
|
||||
import requests
|
||||
|
||||
from manilaclient import exceptions
|
||||
from manilaclient import service_catalog
|
||||
from manilaclient import utils
|
||||
|
||||
|
||||
class HTTPClient(object):
|
||||
|
||||
USER_AGENT = 'python-manilaclient'
|
||||
|
||||
def __init__(self, user, password, projectid, auth_url, insecure=False,
|
||||
timeout=None, tenant_id=None, proxy_tenant_id=None,
|
||||
proxy_token=None, region_name=None,
|
||||
endpoint_type='publicURL', service_type=None,
|
||||
service_name=None, share_service_name=None, retries=None,
|
||||
http_log_debug=False, cacert=None):
|
||||
self.user = user
|
||||
self.password = password
|
||||
self.projectid = projectid
|
||||
self.tenant_id = tenant_id
|
||||
self.auth_url = auth_url.rstrip('/')
|
||||
self.version = 'v1'
|
||||
self.region_name = region_name
|
||||
self.endpoint_type = endpoint_type
|
||||
self.service_type = service_type
|
||||
self.service_name = service_name
|
||||
self.share_service_name = share_service_name
|
||||
self.retries = int(retries or 0)
|
||||
self.http_log_debug = http_log_debug
|
||||
|
||||
self.management_url = None
|
||||
self.auth_token = None
|
||||
self.proxy_token = proxy_token
|
||||
self.proxy_tenant_id = proxy_tenant_id
|
||||
|
||||
if insecure:
|
||||
self.verify_cert = False
|
||||
else:
|
||||
if cacert:
|
||||
self.verify_cert = cacert
|
||||
else:
|
||||
self.verify_cert = True
|
||||
|
||||
self._logger = logging.getLogger(__name__)
|
||||
if self.http_log_debug:
|
||||
ch = logging.StreamHandler()
|
||||
self._logger.setLevel(logging.DEBUG)
|
||||
self._logger.addHandler(ch)
|
||||
if hasattr(requests, 'logging'):
|
||||
requests.logging.getLogger(requests.__name__).addHandler(ch)
|
||||
|
||||
def http_log_req(self, args, kwargs):
|
||||
if not self.http_log_debug:
|
||||
return
|
||||
|
||||
string_parts = ['curl -i']
|
||||
for element in args:
|
||||
if element in ('GET', 'POST', 'DELETE', 'PUT'):
|
||||
string_parts.append(' -X %s' % element)
|
||||
else:
|
||||
string_parts.append(' %s' % element)
|
||||
|
||||
for element in kwargs['headers']:
|
||||
header = ' -H "%s: %s"' % (element, kwargs['headers'][element])
|
||||
string_parts.append(header)
|
||||
|
||||
if 'data' in kwargs:
|
||||
string_parts.append(" -d '%s'" % (kwargs['data']))
|
||||
self._logger.debug("\nREQ: %s\n" % "".join(string_parts))
|
||||
|
||||
def http_log_resp(self, resp):
|
||||
if not self.http_log_debug:
|
||||
return
|
||||
self._logger.debug(
|
||||
"RESP: [%s] %s\nRESP BODY: %s\n",
|
||||
resp.status_code,
|
||||
resp.headers,
|
||||
resp.text)
|
||||
|
||||
def request(self, url, method, **kwargs):
|
||||
kwargs.setdefault('headers', kwargs.get('headers', {}))
|
||||
kwargs['headers']['User-Agent'] = self.USER_AGENT
|
||||
kwargs['headers']['Accept'] = 'application/json'
|
||||
if 'body' in kwargs:
|
||||
kwargs['headers']['Content-Type'] = 'application/json'
|
||||
kwargs['data'] = json.dumps(kwargs['body'])
|
||||
del kwargs['body']
|
||||
|
||||
self.http_log_req((url, method,), kwargs)
|
||||
resp = requests.request(
|
||||
method,
|
||||
url,
|
||||
verify=self.verify_cert,
|
||||
**kwargs)
|
||||
self.http_log_resp(resp)
|
||||
|
||||
if resp.text:
|
||||
try:
|
||||
body = json.loads(resp.text)
|
||||
except ValueError:
|
||||
pass
|
||||
body = None
|
||||
else:
|
||||
body = None
|
||||
|
||||
if resp.status_code >= 400:
|
||||
raise exceptions.from_response(resp, body)
|
||||
|
||||
return resp, body
|
||||
|
||||
def _cs_request(self, url, method, **kwargs):
|
||||
auth_attempts = 0
|
||||
attempts = 0
|
||||
backoff = 1
|
||||
while True:
|
||||
attempts += 1
|
||||
if not self.management_url or not self.auth_token:
|
||||
self.authenticate()
|
||||
kwargs.setdefault('headers', {})['X-Auth-Token'] = self.auth_token
|
||||
if self.projectid:
|
||||
kwargs['headers']['X-Auth-Project-Id'] = self.projectid
|
||||
try:
|
||||
resp, body = self.request(self.management_url + url, method,
|
||||
**kwargs)
|
||||
return resp, body
|
||||
except exceptions.BadRequest as e:
|
||||
if attempts > self.retries:
|
||||
raise
|
||||
except exceptions.Unauthorized:
|
||||
if auth_attempts > 0:
|
||||
raise
|
||||
self._logger.debug("Unauthorized, reauthenticating.")
|
||||
self.management_url = self.auth_token = None
|
||||
# First reauth. Discount this attempt.
|
||||
attempts -= 1
|
||||
auth_attempts += 1
|
||||
continue
|
||||
except exceptions.ClientException as e:
|
||||
if attempts > self.retries:
|
||||
raise
|
||||
if 500 <= e.code <= 599:
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
# Catch a connection refused from requests.request
|
||||
self._logger.debug("Connection refused: %s" % e)
|
||||
raise
|
||||
self._logger.debug(
|
||||
"Failed attempt(%s of %s), retrying in %s seconds" %
|
||||
(attempts, self.retries, backoff))
|
||||
sleep(backoff)
|
||||
backoff *= 2
|
||||
|
||||
def get(self, url, **kwargs):
|
||||
return self._cs_request(url, 'GET', **kwargs)
|
||||
|
||||
def post(self, url, **kwargs):
|
||||
return self._cs_request(url, 'POST', **kwargs)
|
||||
|
||||
def put(self, url, **kwargs):
|
||||
return self._cs_request(url, 'PUT', **kwargs)
|
||||
|
||||
def delete(self, url, **kwargs):
|
||||
return self._cs_request(url, 'DELETE', **kwargs)
|
||||
|
||||
def _extract_service_catalog(self, url, resp, body, extract_token=True):
|
||||
"""See what the auth service told us and process the response.
|
||||
We may get redirected to another site, fail or actually get
|
||||
back a service catalog with a token and our endpoints."""
|
||||
|
||||
if resp.status_code == 200: # content must always present
|
||||
try:
|
||||
self.auth_url = url
|
||||
self.service_catalog = \
|
||||
service_catalog.ServiceCatalog(body)
|
||||
|
||||
if extract_token:
|
||||
self.auth_token = self.service_catalog.get_token()
|
||||
|
||||
management_url = self.service_catalog.url_for(
|
||||
attr='region',
|
||||
filter_value=self.region_name,
|
||||
endpoint_type=self.endpoint_type,
|
||||
service_type=self.service_type,
|
||||
service_name=self.service_name,
|
||||
share_service_name=self.share_service_name)
|
||||
self.management_url = management_url.rstrip('/')
|
||||
return None
|
||||
except exceptions.AmbiguousEndpoints:
|
||||
print "Found more than one valid endpoint. Use a more " \
|
||||
"restrictive filter"
|
||||
raise
|
||||
except KeyError:
|
||||
raise exceptions.AuthorizationFailure()
|
||||
except exceptions.EndpointNotFound:
|
||||
print "Could not find any suitable endpoint. Correct region?"
|
||||
raise
|
||||
|
||||
elif resp.status_code == 305:
|
||||
return resp['location']
|
||||
else:
|
||||
raise exceptions.from_response(resp, body)
|
||||
|
||||
def _fetch_endpoints_from_auth(self, url):
|
||||
"""We have a token, but don't know the final endpoint for
|
||||
the region. We have to go back to the auth service and
|
||||
ask again. This request requires an admin-level token
|
||||
to work. The proxy token supplied could be from a low-level enduser.
|
||||
|
||||
We can't get this from the keystone service endpoint, we have to use
|
||||
the admin endpoint.
|
||||
|
||||
This will overwrite our admin token with the user token.
|
||||
"""
|
||||
|
||||
# GET ...:5001/v2.0/tokens/#####/endpoints
|
||||
url = '/'.join([url, 'tokens', '%s?belongsTo=%s'
|
||||
% (self.proxy_token, self.proxy_tenant_id)])
|
||||
self._logger.debug("Using Endpoint URL: %s" % url)
|
||||
resp, body = self.request(url, "GET",
|
||||
headers={'X-Auth-Token': self.auth_token})
|
||||
return self._extract_service_catalog(url, resp, body,
|
||||
extract_token=False)
|
||||
|
||||
def authenticate(self):
|
||||
magic_tuple = urlparse.urlsplit(self.auth_url)
|
||||
scheme, netloc, path, query, frag = magic_tuple
|
||||
port = magic_tuple.port
|
||||
if port is None:
|
||||
port = 80
|
||||
path_parts = path.split('/')
|
||||
for part in path_parts:
|
||||
if len(part) > 0 and part[0] == 'v':
|
||||
self.version = part
|
||||
break
|
||||
|
||||
# TODO(sandy): Assume admin endpoint is 35357 for now.
|
||||
# Ideally this is going to have to be provided by the service catalog.
|
||||
new_netloc = netloc.replace(':%d' % port, ':%d' % (35357,))
|
||||
admin_url = urlparse.urlunsplit((scheme, new_netloc,
|
||||
path, query, frag))
|
||||
|
||||
auth_url = self.auth_url
|
||||
if self.version == "v2.0":
|
||||
while auth_url:
|
||||
if "MANILA_RAX_AUTH" in os.environ:
|
||||
auth_url = self._rax_auth(auth_url)
|
||||
else:
|
||||
auth_url = self._v2_auth(auth_url)
|
||||
|
||||
# Are we acting on behalf of another user via an
|
||||
# existing token? If so, our actual endpoints may
|
||||
# be different than that of the admin token.
|
||||
if self.proxy_token:
|
||||
self._fetch_endpoints_from_auth(admin_url)
|
||||
# Since keystone no longer returns the user token
|
||||
# with the endpoints any more, we need to replace
|
||||
# our service account token with the user token.
|
||||
self.auth_token = self.proxy_token
|
||||
else:
|
||||
try:
|
||||
while auth_url:
|
||||
auth_url = self._v1_auth(auth_url)
|
||||
# In some configurations manila makes redirection to
|
||||
# v2.0 keystone endpoint. Also, new location does not contain
|
||||
# real endpoint, only hostname and port.
|
||||
except exceptions.AuthorizationFailure:
|
||||
if auth_url.find('v2.0') < 0:
|
||||
auth_url = auth_url + '/v2.0'
|
||||
self._v2_auth(auth_url)
|
||||
|
||||
def _v1_auth(self, url):
|
||||
if self.proxy_token:
|
||||
raise exceptions.NoTokenLookupException()
|
||||
|
||||
headers = {'X-Auth-User': self.user,
|
||||
'X-Auth-Key': self.password}
|
||||
if self.projectid:
|
||||
headers['X-Auth-Project-Id'] = self.projectid
|
||||
|
||||
resp, body = self.request(url, 'GET', headers=headers)
|
||||
if resp.status_code in (200, 204): # in some cases we get No Content
|
||||
try:
|
||||
mgmt_header = 'x-server-management-url'
|
||||
self.management_url = resp.headers[mgmt_header].rstrip('/')
|
||||
self.auth_token = resp.headers['x-auth-token']
|
||||
self.auth_url = url
|
||||
except (KeyError, TypeError):
|
||||
raise exceptions.AuthorizationFailure()
|
||||
elif resp.status_code == 305:
|
||||
return resp.headers['location']
|
||||
else:
|
||||
raise exceptions.from_response(resp, body)
|
||||
|
||||
def _v2_auth(self, url):
|
||||
"""Authenticate against a v2.0 auth service."""
|
||||
body = {"auth": {
|
||||
"passwordCredentials": {"username": self.user,
|
||||
"password": self.password}}}
|
||||
|
||||
if self.projectid:
|
||||
body['auth']['tenantName'] = self.projectid
|
||||
elif self.tenant_id:
|
||||
body['auth']['tenantId'] = self.tenant_id
|
||||
|
||||
self._authenticate(url, body)
|
||||
|
||||
def _rax_auth(self, url):
|
||||
"""Authenticate against the Rackspace auth service."""
|
||||
body = {"auth": {
|
||||
"RAX-KSKEY:apiKeyCredentials": {
|
||||
"username": self.user,
|
||||
"apiKey": self.password,
|
||||
"tenantName": self.projectid}}}
|
||||
|
||||
self._authenticate(url, body)
|
||||
|
||||
def _authenticate(self, url, body):
|
||||
"""Authenticate and extract the service catalog."""
|
||||
token_url = url + "/tokens"
|
||||
|
||||
# Make sure we follow redirects when trying to reach Keystone
|
||||
resp, body = self.request(
|
||||
token_url,
|
||||
"POST",
|
||||
body=body,
|
||||
allow_redirects=True)
|
||||
|
||||
return self._extract_service_catalog(url, resp, body)
|
||||
|
||||
|
||||
def get_client_class(version):
|
||||
version_map = {
|
||||
'1': 'manilaclient.v1.client.Client',
|
||||
'2': 'manilaclient.v2.client.Client',
|
||||
}
|
||||
try:
|
||||
client_path = version_map[str(version)]
|
||||
except (KeyError, ValueError):
|
||||
msg = "Invalid client version '%s'. must be one of: %s" % (
|
||||
(version, ', '.join(version_map.keys())))
|
||||
raise exceptions.UnsupportedVersion(msg)
|
||||
|
||||
return utils.import_class(client_path)
|
||||
|
||||
|
||||
def Client(version, *args, **kwargs):
|
||||
client_class = get_client_class(version)
|
||||
return client_class(*args, **kwargs)
|
150
.tox/pep8/lib/python2.7/site-packages/manilaclient/exceptions.py
Normal file
150
.tox/pep8/lib/python2.7/site-packages/manilaclient/exceptions.py
Normal file
@ -0,0 +1,150 @@
|
||||
# Copyright 2010 Jacob Kaplan-Moss
|
||||
"""
|
||||
Exception definitions.
|
||||
"""
|
||||
|
||||
|
||||
class UnsupportedVersion(Exception):
|
||||
"""Indicates that the user is trying to use an unsupported
|
||||
version of the API"""
|
||||
pass
|
||||
|
||||
|
||||
class CommandError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class AuthorizationFailure(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class NoUniqueMatch(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class NoTokenLookupException(Exception):
|
||||
"""This form of authentication does not support looking up
|
||||
endpoints from an existing token."""
|
||||
pass
|
||||
|
||||
|
||||
class EndpointNotFound(Exception):
|
||||
"""Could not find Service or Region in Service Catalog."""
|
||||
pass
|
||||
|
||||
|
||||
class AmbiguousEndpoints(Exception):
|
||||
"""Found more than one matching endpoint in Service Catalog."""
|
||||
def __init__(self, endpoints=None):
|
||||
self.endpoints = endpoints
|
||||
|
||||
def __str__(self):
|
||||
return "AmbiguousEndpoints: %s" % repr(self.endpoints)
|
||||
|
||||
|
||||
class ClientException(Exception):
|
||||
"""
|
||||
The base exception class for all exceptions this library raises.
|
||||
"""
|
||||
def __init__(self, code, message=None, details=None, request_id=None):
|
||||
self.code = code
|
||||
self.message = message or self.__class__.message
|
||||
self.details = details
|
||||
self.request_id = request_id
|
||||
|
||||
def __str__(self):
|
||||
formatted_string = "%s (HTTP %s)" % (self.message, self.code)
|
||||
if self.request_id:
|
||||
formatted_string += " (Request-ID: %s)" % self.request_id
|
||||
|
||||
return formatted_string
|
||||
|
||||
|
||||
class BadRequest(ClientException):
|
||||
"""
|
||||
HTTP 400 - Bad request: you sent some malformed data.
|
||||
"""
|
||||
http_status = 400
|
||||
message = "Bad request"
|
||||
|
||||
|
||||
class Unauthorized(ClientException):
|
||||
"""
|
||||
HTTP 401 - Unauthorized: bad credentials.
|
||||
"""
|
||||
http_status = 401
|
||||
message = "Unauthorized"
|
||||
|
||||
|
||||
class Forbidden(ClientException):
|
||||
"""
|
||||
HTTP 403 - Forbidden: your credentials don't give you access to this
|
||||
resource.
|
||||
"""
|
||||
http_status = 403
|
||||
message = "Forbidden"
|
||||
|
||||
|
||||
class NotFound(ClientException):
|
||||
"""
|
||||
HTTP 404 - Not found
|
||||
"""
|
||||
http_status = 404
|
||||
message = "Not found"
|
||||
|
||||
|
||||
class OverLimit(ClientException):
|
||||
"""
|
||||
HTTP 413 - Over limit: you're over the API limits for this time period.
|
||||
"""
|
||||
http_status = 413
|
||||
message = "Over limit"
|
||||
|
||||
|
||||
# NotImplemented is a python keyword.
|
||||
class HTTPNotImplemented(ClientException):
|
||||
"""
|
||||
HTTP 501 - Not Implemented: the server does not support this operation.
|
||||
"""
|
||||
http_status = 501
|
||||
message = "Not Implemented"
|
||||
|
||||
|
||||
# In Python 2.4 Exception is old-style and thus doesn't have a __subclasses__()
|
||||
# so we can do this:
|
||||
# _code_map = dict((c.http_status, c)
|
||||
# for c in ClientException.__subclasses__())
|
||||
#
|
||||
# Instead, we have to hardcode it:
|
||||
_code_map = dict((c.http_status, c) for c in [BadRequest, Unauthorized,
|
||||
Forbidden, NotFound,
|
||||
OverLimit, HTTPNotImplemented])
|
||||
|
||||
|
||||
def from_response(response, body):
|
||||
"""
|
||||
Return an instance of an ClientException or subclass
|
||||
based on an requests response.
|
||||
|
||||
Usage::
|
||||
|
||||
resp, body = requests.request(...)
|
||||
if resp.status_code != 200:
|
||||
raise exception_from_response(resp, rest.text)
|
||||
"""
|
||||
cls = _code_map.get(response.status_code, ClientException)
|
||||
if response.headers:
|
||||
request_id = response.headers.get('x-compute-request-id')
|
||||
else:
|
||||
request_id = None
|
||||
if body:
|
||||
message = "n/a"
|
||||
details = "n/a"
|
||||
if hasattr(body, 'keys'):
|
||||
error = body[body.keys()[0]]
|
||||
message = error.get('message', None)
|
||||
details = error.get('details', None)
|
||||
return cls(code=response.status_code, message=message, details=details,
|
||||
request_id=request_id)
|
||||
else:
|
||||
return cls(code=response.status_code, request_id=request_id)
|
@ -0,0 +1,39 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from manilaclient import base
|
||||
from manilaclient import utils
|
||||
|
||||
|
||||
class Extension(utils.HookableMixin):
|
||||
"""Extension descriptor."""
|
||||
|
||||
SUPPORTED_HOOKS = ('__pre_parse_args__', '__post_parse_args__')
|
||||
|
||||
def __init__(self, name, module):
|
||||
self.name = name
|
||||
self.module = module
|
||||
self._parse_extension_module()
|
||||
|
||||
def _parse_extension_module(self):
|
||||
self.manager_class = None
|
||||
for attr_name, attr_value in self.module.__dict__.items():
|
||||
if attr_name in self.SUPPORTED_HOOKS:
|
||||
self.add_hook(attr_name, attr_value)
|
||||
elif utils.safe_issubclass(attr_value, base.Manager):
|
||||
self.manager_class = attr_value
|
||||
|
||||
def __repr__(self):
|
||||
return "<Extension '%s'>" % self.name
|
@ -0,0 +1,367 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# Copyright 2012-2013 Hewlett-Packard Development Company, L.P.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
Utilities with minimum-depends for use in setup.py
|
||||
"""
|
||||
|
||||
import email
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from setuptools.command import sdist
|
||||
|
||||
|
||||
def parse_mailmap(mailmap='.mailmap'):
|
||||
mapping = {}
|
||||
if os.path.exists(mailmap):
|
||||
with open(mailmap, 'r') as fp:
|
||||
for l in fp:
|
||||
try:
|
||||
canonical_email, alias = re.match(
|
||||
r'[^#]*?(<.+>).*(<.+>).*', l).groups()
|
||||
except AttributeError:
|
||||
continue
|
||||
mapping[alias] = canonical_email
|
||||
return mapping
|
||||
|
||||
|
||||
def _parse_git_mailmap(git_dir, mailmap='.mailmap'):
|
||||
mailmap = os.path.join(os.path.dirname(git_dir), mailmap)
|
||||
return parse_mailmap(mailmap)
|
||||
|
||||
|
||||
def canonicalize_emails(changelog, mapping):
|
||||
"""Takes in a string and an email alias mapping and replaces all
|
||||
instances of the aliases in the string with their real email.
|
||||
"""
|
||||
for alias, email_address in mapping.iteritems():
|
||||
changelog = changelog.replace(alias, email_address)
|
||||
return changelog
|
||||
|
||||
|
||||
# Get requirements from the first file that exists
|
||||
def get_reqs_from_files(requirements_files):
|
||||
for requirements_file in requirements_files:
|
||||
if os.path.exists(requirements_file):
|
||||
with open(requirements_file, 'r') as fil:
|
||||
return fil.read().split('\n')
|
||||
return []
|
||||
|
||||
|
||||
def parse_requirements(requirements_files=['requirements.txt',
|
||||
'tools/pip-requires']):
|
||||
requirements = []
|
||||
for line in get_reqs_from_files(requirements_files):
|
||||
# For the requirements list, we need to inject only the portion
|
||||
# after egg= so that distutils knows the package it's looking for
|
||||
# such as:
|
||||
# -e git://github.com/openstack/nova/master#egg=nova
|
||||
if re.match(r'\s*-e\s+', line):
|
||||
requirements.append(re.sub(r'\s*-e\s+.*#egg=(.*)$', r'\1',
|
||||
line))
|
||||
# such as:
|
||||
# http://github.com/openstack/nova/zipball/master#egg=nova
|
||||
elif re.match(r'\s*https?:', line):
|
||||
requirements.append(re.sub(r'\s*https?:.*#egg=(.*)$', r'\1',
|
||||
line))
|
||||
# -f lines are for index locations, and don't get used here
|
||||
elif re.match(r'\s*-f\s+', line):
|
||||
pass
|
||||
# argparse is part of the standard library starting with 2.7
|
||||
# adding it to the requirements list screws distro installs
|
||||
elif line == 'argparse' and sys.version_info >= (2, 7):
|
||||
pass
|
||||
else:
|
||||
requirements.append(line)
|
||||
|
||||
return requirements
|
||||
|
||||
|
||||
def parse_dependency_links(requirements_files=['requirements.txt',
|
||||
'tools/pip-requires']):
|
||||
dependency_links = []
|
||||
# dependency_links inject alternate locations to find packages listed
|
||||
# in requirements
|
||||
for line in get_reqs_from_files(requirements_files):
|
||||
# skip comments and blank lines
|
||||
if re.match(r'(\s*#)|(\s*$)', line):
|
||||
continue
|
||||
# lines with -e or -f need the whole line, minus the flag
|
||||
if re.match(r'\s*-[ef]\s+', line):
|
||||
dependency_links.append(re.sub(r'\s*-[ef]\s+', '', line))
|
||||
# lines that are only urls can go in unmolested
|
||||
elif re.match(r'\s*https?:', line):
|
||||
dependency_links.append(line)
|
||||
return dependency_links
|
||||
|
||||
|
||||
def _run_shell_command(cmd, throw_on_error=False):
|
||||
if os.name == 'nt':
|
||||
output = subprocess.Popen(["cmd.exe", "/C", cmd],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
else:
|
||||
output = subprocess.Popen(["/bin/sh", "-c", cmd],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
out = output.communicate()
|
||||
if output.returncode and throw_on_error:
|
||||
raise Exception("%s returned %d" % cmd, output.returncode)
|
||||
if len(out) == 0:
|
||||
return None
|
||||
if len(out[0].strip()) == 0:
|
||||
return None
|
||||
return out[0].strip()
|
||||
|
||||
|
||||
def _get_git_directory():
|
||||
parent_dir = os.path.dirname(__file__)
|
||||
while True:
|
||||
git_dir = os.path.join(parent_dir, '.git')
|
||||
if os.path.exists(git_dir):
|
||||
return git_dir
|
||||
parent_dir, child = os.path.split(parent_dir)
|
||||
if not child: # reached to root dir
|
||||
return None
|
||||
|
||||
|
||||
def write_git_changelog():
|
||||
"""Write a changelog based on the git changelog."""
|
||||
new_changelog = 'ChangeLog'
|
||||
git_dir = _get_git_directory()
|
||||
if not os.getenv('SKIP_WRITE_GIT_CHANGELOG'):
|
||||
if git_dir:
|
||||
git_log_cmd = 'git --git-dir=%s log' % git_dir
|
||||
changelog = _run_shell_command(git_log_cmd)
|
||||
mailmap = _parse_git_mailmap(git_dir)
|
||||
with open(new_changelog, "w") as changelog_file:
|
||||
changelog_file.write(canonicalize_emails(changelog, mailmap))
|
||||
else:
|
||||
open(new_changelog, 'w').close()
|
||||
|
||||
|
||||
def generate_authors():
|
||||
"""Create AUTHORS file using git commits."""
|
||||
jenkins_email = 'jenkins@review.(openstack|stackforge).org'
|
||||
old_authors = 'AUTHORS.in'
|
||||
new_authors = 'AUTHORS'
|
||||
git_dir = _get_git_directory()
|
||||
if not os.getenv('SKIP_GENERATE_AUTHORS'):
|
||||
if git_dir:
|
||||
# don't include jenkins email address in AUTHORS file
|
||||
git_log_cmd = ("git --git-dir=" + git_dir +
|
||||
" log --format='%aN <%aE>' | sort -u | "
|
||||
"egrep -v '" + jenkins_email + "'")
|
||||
changelog = _run_shell_command(git_log_cmd)
|
||||
signed_cmd = ("git --git-dir=" + git_dir +
|
||||
" log | grep -i Co-authored-by: | sort -u")
|
||||
signed_entries = _run_shell_command(signed_cmd)
|
||||
if signed_entries:
|
||||
new_entries = "\n".join(
|
||||
[signed.split(":", 1)[1].strip()
|
||||
for signed in signed_entries.split("\n") if signed])
|
||||
changelog = "\n".join((changelog, new_entries))
|
||||
mailmap = _parse_git_mailmap(git_dir)
|
||||
with open(new_authors, 'w') as new_authors_fh:
|
||||
new_authors_fh.write(canonicalize_emails(changelog, mailmap))
|
||||
if os.path.exists(old_authors):
|
||||
with open(old_authors, "r") as old_authors_fh:
|
||||
new_authors_fh.write('\n' + old_authors_fh.read())
|
||||
else:
|
||||
open(new_authors, 'w').close()
|
||||
|
||||
|
||||
_rst_template = """%(heading)s
|
||||
%(underline)s
|
||||
|
||||
.. automodule:: %(module)s
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
"""
|
||||
|
||||
|
||||
def get_cmdclass():
|
||||
"""Return dict of commands to run from setup.py."""
|
||||
|
||||
cmdclass = dict()
|
||||
|
||||
def _find_modules(arg, dirname, files):
|
||||
for filename in files:
|
||||
if filename.endswith('.py') and filename != '__init__.py':
|
||||
arg["%s.%s" % (dirname.replace('/', '.'),
|
||||
filename[:-3])] = True
|
||||
|
||||
class LocalSDist(sdist.sdist):
|
||||
"""Builds the ChangeLog and Authors files from VC first."""
|
||||
|
||||
def run(self):
|
||||
write_git_changelog()
|
||||
generate_authors()
|
||||
# sdist.sdist is an old style class, can't use super()
|
||||
sdist.sdist.run(self)
|
||||
|
||||
cmdclass['sdist'] = LocalSDist
|
||||
|
||||
# If Sphinx is installed on the box running setup.py,
|
||||
# enable setup.py to build the documentation, otherwise,
|
||||
# just ignore it
|
||||
try:
|
||||
from sphinx.setup_command import BuildDoc
|
||||
|
||||
class LocalBuildDoc(BuildDoc):
|
||||
|
||||
builders = ['html', 'man']
|
||||
|
||||
def generate_autoindex(self):
|
||||
print "**Autodocumenting from %s" % os.path.abspath(os.curdir)
|
||||
modules = {}
|
||||
option_dict = self.distribution.get_option_dict('build_sphinx')
|
||||
source_dir = os.path.join(option_dict['source_dir'][1], 'api')
|
||||
if not os.path.exists(source_dir):
|
||||
os.makedirs(source_dir)
|
||||
for pkg in self.distribution.packages:
|
||||
if '.' not in pkg:
|
||||
os.path.walk(pkg, _find_modules, modules)
|
||||
module_list = modules.keys()
|
||||
module_list.sort()
|
||||
autoindex_filename = os.path.join(source_dir, 'autoindex.rst')
|
||||
with open(autoindex_filename, 'w') as autoindex:
|
||||
autoindex.write(""".. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
""")
|
||||
for module in module_list:
|
||||
output_filename = os.path.join(source_dir,
|
||||
"%s.rst" % module)
|
||||
heading = "The :mod:`%s` Module" % module
|
||||
underline = "=" * len(heading)
|
||||
values = dict(module=module, heading=heading,
|
||||
underline=underline)
|
||||
|
||||
print "Generating %s" % output_filename
|
||||
with open(output_filename, 'w') as output_file:
|
||||
output_file.write(_rst_template % values)
|
||||
autoindex.write(" %s.rst\n" % module)
|
||||
|
||||
def run(self):
|
||||
if not os.getenv('SPHINX_DEBUG'):
|
||||
self.generate_autoindex()
|
||||
|
||||
for builder in self.builders:
|
||||
self.builder = builder
|
||||
self.finalize_options()
|
||||
self.project = self.distribution.get_name()
|
||||
self.version = self.distribution.get_version()
|
||||
self.release = self.distribution.get_version()
|
||||
BuildDoc.run(self)
|
||||
|
||||
class LocalBuildLatex(LocalBuildDoc):
|
||||
builders = ['latex']
|
||||
|
||||
cmdclass['build_sphinx'] = LocalBuildDoc
|
||||
cmdclass['build_sphinx_latex'] = LocalBuildLatex
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
return cmdclass
|
||||
|
||||
|
||||
def _get_revno(git_dir):
|
||||
"""Return the number of commits since the most recent tag.
|
||||
|
||||
We use git-describe to find this out, but if there are no
|
||||
tags then we fall back to counting commits since the beginning
|
||||
of time.
|
||||
"""
|
||||
describe = _run_shell_command(
|
||||
"git --git-dir=%s describe --always" % git_dir)
|
||||
if "-" in describe:
|
||||
return describe.rsplit("-", 2)[-2]
|
||||
|
||||
# no tags found
|
||||
revlist = _run_shell_command(
|
||||
"git --git-dir=%s rev-list --abbrev-commit HEAD" % git_dir)
|
||||
return len(revlist.splitlines())
|
||||
|
||||
|
||||
def _get_version_from_git(pre_version):
|
||||
"""Return a version which is equal to the tag that's on the current
|
||||
revision if there is one, or tag plus number of additional revisions
|
||||
if the current revision has no tag."""
|
||||
|
||||
git_dir = _get_git_directory()
|
||||
if git_dir:
|
||||
if pre_version:
|
||||
try:
|
||||
return _run_shell_command(
|
||||
"git --git-dir=" + git_dir + " describe --exact-match",
|
||||
throw_on_error=True).replace('-', '.')
|
||||
except Exception:
|
||||
sha = _run_shell_command(
|
||||
"git --git-dir=" + git_dir + " log -n1 --pretty=format:%h")
|
||||
return "%s.a%s.g%s" % (pre_version, _get_revno(git_dir), sha)
|
||||
else:
|
||||
return _run_shell_command(
|
||||
"git --git-dir=" + git_dir + " describe --always").replace(
|
||||
'-', '.')
|
||||
return None
|
||||
|
||||
|
||||
def _get_version_from_pkg_info(package_name):
|
||||
"""Get the version from PKG-INFO file if we can."""
|
||||
try:
|
||||
pkg_info_file = open('PKG-INFO', 'r')
|
||||
except (IOError, OSError):
|
||||
return None
|
||||
try:
|
||||
pkg_info = email.message_from_file(pkg_info_file)
|
||||
except email.MessageError:
|
||||
return None
|
||||
# Check to make sure we're in our own dir
|
||||
if pkg_info.get('Name', None) != package_name:
|
||||
return None
|
||||
return pkg_info.get('Version', None)
|
||||
|
||||
|
||||
def get_version(package_name, pre_version=None):
|
||||
"""Get the version of the project. First, try getting it from PKG-INFO, if
|
||||
it exists. If it does, that means we're in a distribution tarball or that
|
||||
install has happened. Otherwise, if there is no PKG-INFO file, pull the
|
||||
version from git.
|
||||
|
||||
We do not support setup.py version sanity in git archive tarballs, nor do
|
||||
we support packagers directly sucking our git repo into theirs. We expect
|
||||
that a source tarball be made from our git repo - or that if someone wants
|
||||
to make a source tarball from a fork of our repo with additional tags in it
|
||||
that they understand and desire the results of doing that.
|
||||
"""
|
||||
version = os.environ.get("OSLO_PACKAGE_VERSION", None)
|
||||
if version:
|
||||
return version
|
||||
version = _get_version_from_pkg_info(package_name)
|
||||
if version:
|
||||
return version
|
||||
version = _get_version_from_git(pre_version)
|
||||
if version:
|
||||
return version
|
||||
raise Exception("Versioning for this project requires either an sdist"
|
||||
" tarball, or access to an upstream git repository.")
|
@ -0,0 +1,133 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
System-level utilities and helper functions.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import sys
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def int_from_bool_as_string(subject):
|
||||
"""
|
||||
Interpret a string as a boolean and return either 1 or 0.
|
||||
|
||||
Any string value in:
|
||||
|
||||
('True', 'true', 'On', 'on', '1')
|
||||
|
||||
is interpreted as a boolean True.
|
||||
|
||||
Useful for JSON-decoded stuff and config file parsing
|
||||
"""
|
||||
return bool_from_string(subject) and 1 or 0
|
||||
|
||||
|
||||
def bool_from_string(subject):
|
||||
"""
|
||||
Interpret a string as a boolean.
|
||||
|
||||
Any string value in:
|
||||
|
||||
('True', 'true', 'On', 'on', 'Yes', 'yes', '1')
|
||||
|
||||
is interpreted as a boolean True.
|
||||
|
||||
Useful for JSON-decoded stuff and config file parsing
|
||||
"""
|
||||
if isinstance(subject, bool):
|
||||
return subject
|
||||
if isinstance(subject, basestring):
|
||||
if subject.strip().lower() in ('true', 'on', 'yes', '1'):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def safe_decode(text, incoming=None, errors='strict'):
|
||||
"""
|
||||
Decodes incoming str using `incoming` if they're
|
||||
not already unicode.
|
||||
|
||||
:param incoming: Text's current encoding
|
||||
:param errors: Errors handling policy. See here for valid
|
||||
values http://docs.python.org/2/library/codecs.html
|
||||
:returns: text or a unicode `incoming` encoded
|
||||
representation of it.
|
||||
:raises TypeError: If text is not an isntance of basestring
|
||||
"""
|
||||
if not isinstance(text, basestring):
|
||||
raise TypeError("%s can't be decoded" % type(text))
|
||||
|
||||
if isinstance(text, unicode):
|
||||
return text
|
||||
|
||||
if not incoming:
|
||||
incoming = (sys.stdin.encoding or
|
||||
sys.getdefaultencoding())
|
||||
|
||||
try:
|
||||
return text.decode(incoming, errors)
|
||||
except UnicodeDecodeError:
|
||||
# Note(flaper87) If we get here, it means that
|
||||
# sys.stdin.encoding / sys.getdefaultencoding
|
||||
# didn't return a suitable encoding to decode
|
||||
# text. This happens mostly when global LANG
|
||||
# var is not set correctly and there's no
|
||||
# default encoding. In this case, most likely
|
||||
# python will use ASCII or ANSI encoders as
|
||||
# default encodings but they won't be capable
|
||||
# of decoding non-ASCII characters.
|
||||
#
|
||||
# Also, UTF-8 is being used since it's an ASCII
|
||||
# extension.
|
||||
return text.decode('utf-8', errors)
|
||||
|
||||
|
||||
def safe_encode(text, incoming=None,
|
||||
encoding='utf-8', errors='strict'):
|
||||
"""
|
||||
Encodes incoming str/unicode using `encoding`. If
|
||||
incoming is not specified, text is expected to
|
||||
be encoded with current python's default encoding.
|
||||
(`sys.getdefaultencoding`)
|
||||
|
||||
:param incoming: Text's current encoding
|
||||
:param encoding: Expected encoding for text (Default UTF-8)
|
||||
:param errors: Errors handling policy. See here for valid
|
||||
values http://docs.python.org/2/library/codecs.html
|
||||
:returns: text or a bytestring `encoding` encoded
|
||||
representation of it.
|
||||
:raises TypeError: If text is not an isntance of basestring
|
||||
"""
|
||||
if not isinstance(text, basestring):
|
||||
raise TypeError("%s can't be encoded" % type(text))
|
||||
|
||||
if not incoming:
|
||||
incoming = (sys.stdin.encoding or
|
||||
sys.getdefaultencoding())
|
||||
|
||||
if isinstance(text, unicode):
|
||||
return text.encode(encoding, errors)
|
||||
elif text and encoding != incoming:
|
||||
# Decode text before encoding it with `encoding`
|
||||
text = safe_decode(text, incoming, errors)
|
||||
return text.encode(encoding, errors)
|
||||
|
||||
return text
|
@ -0,0 +1,94 @@
|
||||
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
# Copyright 2012-2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Utilities for consuming the version from pkg_resources.
|
||||
"""
|
||||
|
||||
import pkg_resources
|
||||
|
||||
|
||||
class VersionInfo(object):
|
||||
|
||||
def __init__(self, package):
|
||||
"""Object that understands versioning for a package
|
||||
:param package: name of the python package, such as glance, or
|
||||
python-glanceclient
|
||||
"""
|
||||
self.package = package
|
||||
self.release = None
|
||||
self.version = None
|
||||
self._cached_version = None
|
||||
|
||||
def __str__(self):
|
||||
"""Make the VersionInfo object behave like a string."""
|
||||
return self.version_string()
|
||||
|
||||
def __repr__(self):
|
||||
"""Include the name."""
|
||||
return "VersionInfo(%s:%s)" % (self.package, self.version_string())
|
||||
|
||||
def _get_version_from_pkg_resources(self):
|
||||
"""Get the version of the package from the pkg_resources record
|
||||
associated with the package."""
|
||||
try:
|
||||
requirement = pkg_resources.Requirement.parse(self.package)
|
||||
provider = pkg_resources.get_provider(requirement)
|
||||
return provider.version
|
||||
except pkg_resources.DistributionNotFound:
|
||||
# The most likely cause for this is running tests in a tree
|
||||
# produced from a tarball where the package itself has not been
|
||||
# installed into anything. Revert to setup-time logic.
|
||||
from manilaclient.openstack.common import setup
|
||||
return setup.get_version(self.package)
|
||||
|
||||
def release_string(self):
|
||||
"""Return the full version of the package including suffixes indicating
|
||||
VCS status.
|
||||
"""
|
||||
if self.release is None:
|
||||
self.release = self._get_version_from_pkg_resources()
|
||||
|
||||
return self.release
|
||||
|
||||
def version_string(self):
|
||||
"""Return the short version minus any alpha/beta tags."""
|
||||
if self.version is None:
|
||||
parts = []
|
||||
for part in self.release_string().split('.'):
|
||||
if part[0].isdigit():
|
||||
parts.append(part)
|
||||
else:
|
||||
break
|
||||
self.version = ".".join(parts)
|
||||
|
||||
return self.version
|
||||
|
||||
# Compatibility functions
|
||||
canonical_version_string = version_string
|
||||
version_string_with_vcs = release_string
|
||||
|
||||
def cached_version_string(self, prefix=""):
|
||||
"""Generate an object which will expand in a string context to
|
||||
the results of version_string(). We do this so that don't
|
||||
call into pkg_resources every time we start up a program when
|
||||
passing version information into the CONF constructor, but
|
||||
rather only do the calculation when and if a version is requested
|
||||
"""
|
||||
if not self._cached_version:
|
||||
self._cached_version = "%s%s" % (prefix,
|
||||
self.version_string())
|
||||
return self._cached_version
|
@ -0,0 +1,77 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011, Piston Cloud Computing, Inc.
|
||||
#
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
import manilaclient.exceptions
|
||||
|
||||
|
||||
class ServiceCatalog(object):
|
||||
"""Helper methods for dealing with a Keystone Service Catalog."""
|
||||
|
||||
def __init__(self, resource_dict):
|
||||
self.catalog = resource_dict
|
||||
|
||||
def get_token(self):
|
||||
return self.catalog['access']['token']['id']
|
||||
|
||||
def url_for(self, attr=None, filter_value=None,
|
||||
service_type=None, endpoint_type='publicURL',
|
||||
service_name=None, share_service_name=None):
|
||||
"""Fetch the public URL from the Compute service for
|
||||
a particular endpoint attribute. If none given, return
|
||||
the first. See tests for sample service catalog."""
|
||||
matching_endpoints = []
|
||||
if 'endpoints' in self.catalog:
|
||||
# We have a bastardized service catalog. Treat it special. :/
|
||||
for endpoint in self.catalog['endpoints']:
|
||||
if not filter_value or endpoint[attr] == filter_value:
|
||||
matching_endpoints.append(endpoint)
|
||||
if not matching_endpoints:
|
||||
raise manilaclient.exceptions.EndpointNotFound()
|
||||
|
||||
# We don't always get a service catalog back ...
|
||||
if not 'serviceCatalog' in self.catalog['access']:
|
||||
return None
|
||||
|
||||
# Full catalog ...
|
||||
catalog = self.catalog['access']['serviceCatalog']
|
||||
|
||||
for service in catalog:
|
||||
if service.get("type") != service_type:
|
||||
continue
|
||||
|
||||
if (service_name and service_type == 'compute' and
|
||||
service.get('name') != service_name):
|
||||
continue
|
||||
|
||||
if (share_service_name and service_type == 'volume' and
|
||||
service.get('name') != share_service_name):
|
||||
continue
|
||||
|
||||
endpoints = service['endpoints']
|
||||
for endpoint in endpoints:
|
||||
if not filter_value or endpoint.get(attr) == filter_value:
|
||||
endpoint["serviceName"] = service.get("name")
|
||||
matching_endpoints.append(endpoint)
|
||||
|
||||
if not matching_endpoints:
|
||||
raise manilaclient.exceptions.EndpointNotFound()
|
||||
elif len(matching_endpoints) > 1:
|
||||
raise manilaclient.exceptions.AmbiguousEndpoints(
|
||||
endpoints=matching_endpoints)
|
||||
else:
|
||||
return matching_endpoints[0][endpoint_type]
|
515
.tox/pep8/lib/python2.7/site-packages/manilaclient/shell.py
Normal file
515
.tox/pep8/lib/python2.7/site-packages/manilaclient/shell.py
Normal file
@ -0,0 +1,515 @@
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
Command-line interface to the OpenStack Manila API.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
import imp
|
||||
import itertools
|
||||
import os
|
||||
import pkgutil
|
||||
import sys
|
||||
import logging
|
||||
|
||||
from manilaclient import client
|
||||
from manilaclient import exceptions as exc
|
||||
import manilaclient.extension
|
||||
from manilaclient.openstack.common import strutils
|
||||
from manilaclient import utils
|
||||
from manilaclient.v1 import shell as shell_v1
|
||||
from manilaclient.v2 import shell as shell_v2
|
||||
|
||||
DEFAULT_OS_SHARE_API_VERSION = "1"
|
||||
DEFAULT_MANILA_ENDPOINT_TYPE = 'publicURL'
|
||||
DEFAULT_MANILA_SERVICE_TYPE = 'share'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class manilaclientArgumentParser(argparse.ArgumentParser):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(manilaclientArgumentParser, self).__init__(*args, **kwargs)
|
||||
|
||||
def error(self, message):
|
||||
"""error(message: string)
|
||||
|
||||
Prints a usage message incorporating the message to stderr and
|
||||
exits.
|
||||
"""
|
||||
self.print_usage(sys.stderr)
|
||||
#FIXME(lzyeval): if changes occur in argparse.ArgParser._check_value
|
||||
choose_from = ' (choose from'
|
||||
progparts = self.prog.partition(' ')
|
||||
self.exit(2, "error: %(errmsg)s\nTry '%(mainp)s help %(subp)s'"
|
||||
" for more information.\n" %
|
||||
{'errmsg': message.split(choose_from)[0],
|
||||
'mainp': progparts[0],
|
||||
'subp': progparts[2]})
|
||||
|
||||
|
||||
class OpenStackManilaShell(object):
|
||||
|
||||
def get_base_parser(self):
|
||||
parser = manilaclientArgumentParser(
|
||||
prog='manila',
|
||||
description=__doc__.strip(),
|
||||
epilog='See "manila help COMMAND" '
|
||||
'for help on a specific command.',
|
||||
add_help=False,
|
||||
formatter_class=OpenStackHelpFormatter,
|
||||
)
|
||||
|
||||
# Global arguments
|
||||
parser.add_argument('-h', '--help',
|
||||
action='store_true',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--version',
|
||||
action='version',
|
||||
version=manilaclient.__version__)
|
||||
|
||||
parser.add_argument('--debug',
|
||||
action='store_true',
|
||||
default=utils.env('manilaclient_DEBUG',
|
||||
default=False),
|
||||
help="Print debugging output")
|
||||
|
||||
parser.add_argument('--os-username',
|
||||
metavar='<auth-user-name>',
|
||||
default=utils.env('OS_USERNAME',
|
||||
'MANILA_USERNAME'),
|
||||
help='Defaults to env[OS_USERNAME].')
|
||||
parser.add_argument('--os_username',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--os-password',
|
||||
metavar='<auth-password>',
|
||||
default=utils.env('OS_PASSWORD',
|
||||
'MANILA_PASSWORD'),
|
||||
help='Defaults to env[OS_PASSWORD].')
|
||||
parser.add_argument('--os_password',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--os-tenant-name',
|
||||
metavar='<auth-tenant-name>',
|
||||
default=utils.env('OS_TENANT_NAME',
|
||||
'MANILA_PROJECT_ID'),
|
||||
help='Defaults to env[OS_TENANT_NAME].')
|
||||
parser.add_argument('--os_tenant_name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--os-tenant-id',
|
||||
metavar='<auth-tenant-id>',
|
||||
default=utils.env('OS_TENANT_ID',
|
||||
'MANILA_TENANT_ID'),
|
||||
help='Defaults to env[OS_TENANT_ID].')
|
||||
parser.add_argument('--os_tenant_id',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--os-auth-url',
|
||||
metavar='<auth-url>',
|
||||
default=utils.env('OS_AUTH_URL',
|
||||
'MANILA_URL'),
|
||||
help='Defaults to env[OS_AUTH_URL].')
|
||||
parser.add_argument('--os_auth_url',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--os-region-name',
|
||||
metavar='<region-name>',
|
||||
default=utils.env('OS_REGION_NAME',
|
||||
'MANILA_REGION_NAME'),
|
||||
help='Defaults to env[OS_REGION_NAME].')
|
||||
parser.add_argument('--os_region_name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--service-type',
|
||||
metavar='<service-type>',
|
||||
help='Defaults to compute for most actions')
|
||||
parser.add_argument('--service_type',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--service-name',
|
||||
metavar='<service-name>',
|
||||
default=utils.env('MANILA_SERVICE_NAME'),
|
||||
help='Defaults to env[MANILA_SERVICE_NAME]')
|
||||
parser.add_argument('--service_name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--share-service-name',
|
||||
metavar='<volume-service-name>',
|
||||
default=utils.env('MANILA_share_service_name'),
|
||||
help='Defaults to env[MANILA_share_service_name]')
|
||||
parser.add_argument('--share_service_name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--endpoint-type',
|
||||
metavar='<endpoint-type>',
|
||||
default=utils.env('MANILA_ENDPOINT_TYPE',
|
||||
default=DEFAULT_MANILA_ENDPOINT_TYPE),
|
||||
help='Defaults to env[MANILA_ENDPOINT_TYPE] or '
|
||||
+ DEFAULT_MANILA_ENDPOINT_TYPE + '.')
|
||||
parser.add_argument('--endpoint_type',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--os-volume-api-version',
|
||||
metavar='<compute-api-ver>',
|
||||
default=utils.env('OS_SHARE_API_VERSION',
|
||||
default=DEFAULT_OS_SHARE_API_VERSION),
|
||||
help='Accepts 1 or 2,defaults '
|
||||
'to env[OS_SHARE_API_VERSION].')
|
||||
parser.add_argument('--os_volume_api_version',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--os-cacert',
|
||||
metavar='<ca-certificate>',
|
||||
default=utils.env('OS_CACERT', default=None),
|
||||
help='Specify a CA bundle file to use in '
|
||||
'verifying a TLS (https) server certificate. '
|
||||
'Defaults to env[OS_CACERT]')
|
||||
|
||||
parser.add_argument('--insecure',
|
||||
default=utils.env('manilaclient_INSECURE',
|
||||
default=False),
|
||||
action='store_true',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--retries',
|
||||
metavar='<retries>',
|
||||
type=int,
|
||||
default=0,
|
||||
help='Number of retries.')
|
||||
|
||||
# FIXME(dtroyer): The args below are here for diablo compatibility,
|
||||
# remove them in folsum cycle
|
||||
|
||||
# alias for --os-username, left in for backwards compatibility
|
||||
parser.add_argument('--username',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
# alias for --os-region_name, left in for backwards compatibility
|
||||
parser.add_argument('--region_name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
# alias for --os-password, left in for backwards compatibility
|
||||
parser.add_argument('--apikey', '--password', dest='apikey',
|
||||
default=utils.env('MANILA_API_KEY'),
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
# alias for --os-tenant-name, left in for backward compatibility
|
||||
parser.add_argument('--projectid', '--tenant_name', dest='projectid',
|
||||
default=utils.env('MANILA_PROJECT_ID'),
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
# alias for --os-auth-url, left in for backward compatibility
|
||||
parser.add_argument('--url', '--auth_url', dest='url',
|
||||
default=utils.env('MANILA_URL'),
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
return parser
|
||||
|
||||
def get_subcommand_parser(self, version):
|
||||
parser = self.get_base_parser()
|
||||
|
||||
self.subcommands = {}
|
||||
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
||||
|
||||
try:
|
||||
actions_module = {
|
||||
'1.1': shell_v1,
|
||||
'2': shell_v2,
|
||||
}[version]
|
||||
except KeyError:
|
||||
actions_module = shell_v1
|
||||
|
||||
self._find_actions(subparsers, actions_module)
|
||||
self._find_actions(subparsers, self)
|
||||
|
||||
for extension in self.extensions:
|
||||
self._find_actions(subparsers, extension.module)
|
||||
|
||||
self._add_bash_completion_subparser(subparsers)
|
||||
|
||||
return parser
|
||||
|
||||
def _discover_extensions(self, version):
|
||||
extensions = []
|
||||
for name, module in itertools.chain(
|
||||
self._discover_via_python_path(version),
|
||||
self._discover_via_contrib_path(version)):
|
||||
|
||||
extension = manilaclient.extension.Extension(name, module)
|
||||
extensions.append(extension)
|
||||
|
||||
return extensions
|
||||
|
||||
def _discover_via_python_path(self, version):
|
||||
for (module_loader, name, ispkg) in pkgutil.iter_modules():
|
||||
if name.endswith('python_manilaclient_ext'):
|
||||
if not hasattr(module_loader, 'load_module'):
|
||||
# Python 2.6 compat: actually get an ImpImporter obj
|
||||
module_loader = module_loader.find_module(name)
|
||||
|
||||
module = module_loader.load_module(name)
|
||||
yield name, module
|
||||
|
||||
def _discover_via_contrib_path(self, version):
|
||||
module_path = os.path.dirname(os.path.abspath(__file__))
|
||||
version_str = "v%s" % version.replace('.', '_')
|
||||
ext_path = os.path.join(module_path, version_str, 'contrib')
|
||||
ext_glob = os.path.join(ext_path, "*.py")
|
||||
|
||||
for ext_path in glob.iglob(ext_glob):
|
||||
name = os.path.basename(ext_path)[:-3]
|
||||
|
||||
if name == "__init__":
|
||||
continue
|
||||
|
||||
module = imp.load_source(name, ext_path)
|
||||
yield name, module
|
||||
|
||||
def _add_bash_completion_subparser(self, subparsers):
|
||||
subparser = subparsers.add_parser(
|
||||
'bash_completion',
|
||||
add_help=False,
|
||||
formatter_class=OpenStackHelpFormatter)
|
||||
|
||||
self.subcommands['bash_completion'] = subparser
|
||||
subparser.set_defaults(func=self.do_bash_completion)
|
||||
|
||||
def _find_actions(self, subparsers, actions_module):
|
||||
for attr in (a for a in dir(actions_module) if a.startswith('do_')):
|
||||
# I prefer to be hypen-separated instead of underscores.
|
||||
command = attr[3:].replace('_', '-')
|
||||
callback = getattr(actions_module, attr)
|
||||
desc = callback.__doc__ or ''
|
||||
help = desc.strip().split('\n')[0]
|
||||
arguments = getattr(callback, 'arguments', [])
|
||||
|
||||
subparser = subparsers.add_parser(
|
||||
command,
|
||||
help=help,
|
||||
description=desc,
|
||||
add_help=False,
|
||||
formatter_class=OpenStackHelpFormatter)
|
||||
|
||||
subparser.add_argument('-h', '--help',
|
||||
action='help',
|
||||
help=argparse.SUPPRESS,)
|
||||
|
||||
self.subcommands[command] = subparser
|
||||
for (args, kwargs) in arguments:
|
||||
subparser.add_argument(*args, **kwargs)
|
||||
subparser.set_defaults(func=callback)
|
||||
|
||||
def setup_debugging(self, debug):
|
||||
if not debug:
|
||||
return
|
||||
|
||||
streamhandler = logging.StreamHandler()
|
||||
streamformat = "%(levelname)s (%(module)s:%(lineno)d) %(message)s"
|
||||
streamhandler.setFormatter(logging.Formatter(streamformat))
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.addHandler(streamhandler)
|
||||
|
||||
def main(self, argv):
|
||||
# Parse args once to find version and debug settings
|
||||
parser = self.get_base_parser()
|
||||
(options, args) = parser.parse_known_args(argv)
|
||||
self.setup_debugging(options.debug)
|
||||
|
||||
# build available subcommands based on version
|
||||
self.extensions = self._discover_extensions(
|
||||
options.os_volume_api_version)
|
||||
self._run_extension_hooks('__pre_parse_args__')
|
||||
|
||||
subcommand_parser = self.get_subcommand_parser(
|
||||
options.os_volume_api_version)
|
||||
self.parser = subcommand_parser
|
||||
|
||||
if options.help or not argv:
|
||||
subcommand_parser.print_help()
|
||||
return 0
|
||||
|
||||
args = subcommand_parser.parse_args(argv)
|
||||
self._run_extension_hooks('__post_parse_args__', args)
|
||||
|
||||
# Short-circuit and deal with help right away.
|
||||
if args.func == self.do_help:
|
||||
self.do_help(args)
|
||||
return 0
|
||||
elif args.func == self.do_bash_completion:
|
||||
self.do_bash_completion(args)
|
||||
return 0
|
||||
|
||||
(os_username, os_password, os_tenant_name, os_auth_url,
|
||||
os_region_name, os_tenant_id, endpoint_type, insecure,
|
||||
service_type, service_name, share_service_name,
|
||||
username, apikey, projectid, url, region_name, cacert) = (
|
||||
args.os_username, args.os_password,
|
||||
args.os_tenant_name, args.os_auth_url,
|
||||
args.os_region_name, args.os_tenant_id,
|
||||
args.endpoint_type, args.insecure,
|
||||
args.service_type, args.service_name,
|
||||
args.share_service_name, args.username,
|
||||
args.apikey, args.projectid,
|
||||
args.url, args.region_name, args.os_cacert)
|
||||
|
||||
if not endpoint_type:
|
||||
endpoint_type = DEFAULT_MANILA_ENDPOINT_TYPE
|
||||
|
||||
if not service_type:
|
||||
service_type = DEFAULT_MANILA_SERVICE_TYPE
|
||||
service_type = utils.get_service_type(args.func) or service_type
|
||||
|
||||
#FIXME(usrleon): Here should be restrict for project id same as
|
||||
# for os_username or os_password but for compatibility it is not.
|
||||
|
||||
if not utils.isunauthenticated(args.func):
|
||||
if not os_username:
|
||||
if not username:
|
||||
raise exc.CommandError(
|
||||
"You must provide a username "
|
||||
"via either --os-username or env[OS_USERNAME]")
|
||||
else:
|
||||
os_username = username
|
||||
|
||||
if not os_password:
|
||||
if not apikey:
|
||||
raise exc.CommandError("You must provide a password "
|
||||
"via either --os-password or via "
|
||||
"env[OS_PASSWORD]")
|
||||
else:
|
||||
os_password = apikey
|
||||
|
||||
if not (os_tenant_name or os_tenant_id):
|
||||
if not projectid:
|
||||
raise exc.CommandError("You must provide a tenant_id "
|
||||
"via either --os-tenant-id or "
|
||||
"env[OS_TENANT_ID]")
|
||||
else:
|
||||
os_tenant_name = projectid
|
||||
|
||||
if not os_auth_url:
|
||||
if not url:
|
||||
raise exc.CommandError(
|
||||
"You must provide an auth url "
|
||||
"via either --os-auth-url or env[OS_AUTH_URL]")
|
||||
else:
|
||||
os_auth_url = url
|
||||
|
||||
if not os_region_name and region_name:
|
||||
os_region_name = region_name
|
||||
|
||||
if not (os_tenant_name or os_tenant_id):
|
||||
raise exc.CommandError(
|
||||
"You must provide a tenant_id "
|
||||
"via either --os-tenant-id or env[OS_TENANT_ID]")
|
||||
|
||||
if not os_auth_url:
|
||||
raise exc.CommandError(
|
||||
"You must provide an auth url "
|
||||
"via either --os-auth-url or env[OS_AUTH_URL]")
|
||||
|
||||
self.cs = client.Client(options.os_volume_api_version, os_username,
|
||||
os_password, os_tenant_name, os_auth_url,
|
||||
insecure, region_name=os_region_name,
|
||||
tenant_id=os_tenant_id,
|
||||
endpoint_type=endpoint_type,
|
||||
extensions=self.extensions,
|
||||
service_type=service_type,
|
||||
service_name=service_name,
|
||||
share_service_name=share_service_name,
|
||||
retries=options.retries,
|
||||
http_log_debug=args.debug,
|
||||
cacert=cacert)
|
||||
|
||||
try:
|
||||
if not utils.isunauthenticated(args.func):
|
||||
self.cs.authenticate()
|
||||
except exc.Unauthorized:
|
||||
raise exc.CommandError("Invalid OpenStack Manila credentials.")
|
||||
except exc.AuthorizationFailure:
|
||||
raise exc.CommandError("Unable to authorize user")
|
||||
|
||||
args.func(self.cs, args)
|
||||
|
||||
def _run_extension_hooks(self, hook_type, *args, **kwargs):
|
||||
"""Run hooks for all registered extensions."""
|
||||
for extension in self.extensions:
|
||||
extension.run_hooks(hook_type, *args, **kwargs)
|
||||
|
||||
def do_bash_completion(self, args):
|
||||
"""Print arguments for bash_completion.
|
||||
|
||||
Prints all of the commands and options to stdout so that the
|
||||
manila.bash_completion script doesn't have to hard code them.
|
||||
"""
|
||||
commands = set()
|
||||
options = set()
|
||||
for sc_str, sc in self.subcommands.items():
|
||||
commands.add(sc_str)
|
||||
for option in sc._optionals._option_string_actions.keys():
|
||||
options.add(option)
|
||||
|
||||
commands.remove('bash-completion')
|
||||
commands.remove('bash_completion')
|
||||
print ' '.join(commands | options)
|
||||
|
||||
@utils.arg('command', metavar='<subcommand>', nargs='?',
|
||||
help='Display help for <subcommand>')
|
||||
def do_help(self, args):
|
||||
"""
|
||||
Display help about this program or one of its subcommands.
|
||||
"""
|
||||
if args.command:
|
||||
if args.command in self.subcommands:
|
||||
self.subcommands[args.command].print_help()
|
||||
else:
|
||||
raise exc.CommandError("'%s' is not a valid subcommand" %
|
||||
args.command)
|
||||
else:
|
||||
self.parser.print_help()
|
||||
|
||||
|
||||
# I'm picky about my shell help.
|
||||
class OpenStackHelpFormatter(argparse.HelpFormatter):
|
||||
def start_section(self, heading):
|
||||
# Title-case the headings
|
||||
heading = '%s%s' % (heading[0].upper(), heading[1:])
|
||||
super(OpenStackHelpFormatter, self).start_section(heading)
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
OpenStackManilaShell().main(map(strutils.safe_decode, sys.argv[1:]))
|
||||
except KeyboardInterrupt:
|
||||
print >> sys.stderr, "... terminating manila client"
|
||||
sys.exit(130)
|
||||
except Exception, e:
|
||||
logger.debug(e, exc_info=1)
|
||||
message = e.message
|
||||
if not isinstance(message, basestring):
|
||||
message = str(message)
|
||||
print >> sys.stderr, "ERROR: %s" % strutils.safe_encode(message)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
266
.tox/pep8/lib/python2.7/site-packages/manilaclient/utils.py
Normal file
266
.tox/pep8/lib/python2.7/site-packages/manilaclient/utils.py
Normal file
@ -0,0 +1,266 @@
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
import prettytable
|
||||
|
||||
from manilaclient import exceptions
|
||||
from manilaclient.openstack.common import strutils
|
||||
|
||||
|
||||
def arg(*args, **kwargs):
|
||||
"""Decorator for CLI args."""
|
||||
def _decorator(func):
|
||||
add_arg(func, *args, **kwargs)
|
||||
return func
|
||||
return _decorator
|
||||
|
||||
|
||||
def env(*vars, **kwargs):
|
||||
"""
|
||||
returns the first environment variable set
|
||||
if none are non-empty, defaults to '' or keyword arg default
|
||||
"""
|
||||
for v in vars:
|
||||
value = os.environ.get(v, None)
|
||||
if value:
|
||||
return value
|
||||
return kwargs.get('default', '')
|
||||
|
||||
|
||||
def add_arg(f, *args, **kwargs):
|
||||
"""Bind CLI arguments to a shell.py `do_foo` function."""
|
||||
|
||||
if not hasattr(f, 'arguments'):
|
||||
f.arguments = []
|
||||
|
||||
# NOTE(sirp): avoid dups that can occur when the module is shared across
|
||||
# tests.
|
||||
if (args, kwargs) not in f.arguments:
|
||||
# Because of the sematics of decorator composition if we just append
|
||||
# to the options list positional options will appear to be backwards.
|
||||
f.arguments.insert(0, (args, kwargs))
|
||||
|
||||
|
||||
def add_resource_manager_extra_kwargs_hook(f, hook):
|
||||
"""Adds hook to bind CLI arguments to ResourceManager calls.
|
||||
|
||||
The `do_foo` calls in shell.py will receive CLI args and then in turn pass
|
||||
them through to the ResourceManager. Before passing through the args, the
|
||||
hooks registered here will be called, giving us a chance to add extra
|
||||
kwargs (taken from the command-line) to what's passed to the
|
||||
ResourceManager.
|
||||
"""
|
||||
if not hasattr(f, 'resource_manager_kwargs_hooks'):
|
||||
f.resource_manager_kwargs_hooks = []
|
||||
|
||||
names = [h.__name__ for h in f.resource_manager_kwargs_hooks]
|
||||
if hook.__name__ not in names:
|
||||
f.resource_manager_kwargs_hooks.append(hook)
|
||||
|
||||
|
||||
def get_resource_manager_extra_kwargs(f, args, allow_conflicts=False):
|
||||
"""Return extra_kwargs by calling resource manager kwargs hooks."""
|
||||
hooks = getattr(f, "resource_manager_kwargs_hooks", [])
|
||||
extra_kwargs = {}
|
||||
for hook in hooks:
|
||||
hook_name = hook.__name__
|
||||
hook_kwargs = hook(args)
|
||||
|
||||
conflicting_keys = set(hook_kwargs.keys()) & set(extra_kwargs.keys())
|
||||
if conflicting_keys and not allow_conflicts:
|
||||
raise Exception("Hook '%(hook_name)s' is attempting to redefine"
|
||||
" attributes '%(conflicting_keys)s'" % locals())
|
||||
|
||||
extra_kwargs.update(hook_kwargs)
|
||||
|
||||
return extra_kwargs
|
||||
|
||||
|
||||
def unauthenticated(f):
|
||||
"""
|
||||
Adds 'unauthenticated' attribute to decorated function.
|
||||
Usage:
|
||||
@unauthenticated
|
||||
def mymethod(f):
|
||||
...
|
||||
"""
|
||||
f.unauthenticated = True
|
||||
return f
|
||||
|
||||
|
||||
def isunauthenticated(f):
|
||||
"""
|
||||
Checks to see if the function is marked as not requiring authentication
|
||||
with the @unauthenticated decorator. Returns True if decorator is
|
||||
set to True, False otherwise.
|
||||
"""
|
||||
return getattr(f, 'unauthenticated', False)
|
||||
|
||||
|
||||
def service_type(stype):
|
||||
"""
|
||||
Adds 'service_type' attribute to decorated function.
|
||||
Usage:
|
||||
@service_type('volume')
|
||||
def mymethod(f):
|
||||
...
|
||||
"""
|
||||
def inner(f):
|
||||
f.service_type = stype
|
||||
return f
|
||||
return inner
|
||||
|
||||
|
||||
def get_service_type(f):
|
||||
"""
|
||||
Retrieves service type from function
|
||||
"""
|
||||
return getattr(f, 'service_type', None)
|
||||
|
||||
|
||||
def pretty_choice_list(l):
|
||||
return ', '.join("'%s'" % i for i in l)
|
||||
|
||||
|
||||
def print_list(objs, fields, formatters={}):
|
||||
mixed_case_fields = ['serverId']
|
||||
pt = prettytable.PrettyTable([f for f in fields], caching=False)
|
||||
pt.aligns = ['l' for f in fields]
|
||||
|
||||
for o in objs:
|
||||
row = []
|
||||
for field in fields:
|
||||
if field in formatters:
|
||||
row.append(formatters[field](o))
|
||||
else:
|
||||
if field in mixed_case_fields:
|
||||
field_name = field.replace(' ', '_')
|
||||
else:
|
||||
field_name = field.lower().replace(' ', '_')
|
||||
data = getattr(o, field_name, '')
|
||||
row.append(data)
|
||||
pt.add_row(row)
|
||||
|
||||
if len(objs) > 0:
|
||||
print strutils.safe_encode(pt.get_string(sortby=fields[0]))
|
||||
|
||||
|
||||
def print_dict(d, property="Property"):
|
||||
pt = prettytable.PrettyTable([property, 'Value'], caching=False)
|
||||
pt.aligns = ['l', 'l']
|
||||
[pt.add_row(list(r)) for r in d.iteritems()]
|
||||
print strutils.safe_encode(pt.get_string(sortby=property))
|
||||
|
||||
|
||||
def find_resource(manager, name_or_id):
|
||||
"""Helper for the _find_* methods."""
|
||||
# first try to get entity as integer id
|
||||
try:
|
||||
if isinstance(name_or_id, int) or name_or_id.isdigit():
|
||||
return manager.get(int(name_or_id))
|
||||
except exceptions.NotFound:
|
||||
pass
|
||||
|
||||
# now try to get entity as uuid
|
||||
try:
|
||||
uuid.UUID(strutils.safe_decode(name_or_id))
|
||||
return manager.get(name_or_id)
|
||||
except (ValueError, exceptions.NotFound):
|
||||
pass
|
||||
|
||||
try:
|
||||
try:
|
||||
return manager.find(human_id=name_or_id)
|
||||
except exceptions.NotFound:
|
||||
pass
|
||||
|
||||
# finally try to find entity by name
|
||||
try:
|
||||
return manager.find(name=name_or_id)
|
||||
except exceptions.NotFound:
|
||||
try:
|
||||
return manager.find(display_name=name_or_id)
|
||||
except (UnicodeDecodeError, exceptions.NotFound):
|
||||
try:
|
||||
# Volumes does not have name, but display_name
|
||||
return manager.find(display_name=name_or_id)
|
||||
except exceptions.NotFound:
|
||||
msg = "No %s with a name or ID of '%s' exists." % \
|
||||
(manager.resource_class.__name__.lower(), name_or_id)
|
||||
raise exceptions.CommandError(msg)
|
||||
except exceptions.NoUniqueMatch:
|
||||
msg = ("Multiple %s matches found for '%s', use an ID to be more"
|
||||
" specific." % (manager.resource_class.__name__.lower(),
|
||||
name_or_id))
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
def _format_servers_list_networks(server):
|
||||
output = []
|
||||
for (network, addresses) in server.networks.items():
|
||||
if len(addresses) == 0:
|
||||
continue
|
||||
addresses_csv = ', '.join(addresses)
|
||||
group = "%s=%s" % (network, addresses_csv)
|
||||
output.append(group)
|
||||
|
||||
return '; '.join(output)
|
||||
|
||||
|
||||
class HookableMixin(object):
|
||||
"""Mixin so classes can register and run hooks."""
|
||||
_hooks_map = {}
|
||||
|
||||
@classmethod
|
||||
def add_hook(cls, hook_type, hook_func):
|
||||
if hook_type not in cls._hooks_map:
|
||||
cls._hooks_map[hook_type] = []
|
||||
|
||||
cls._hooks_map[hook_type].append(hook_func)
|
||||
|
||||
@classmethod
|
||||
def run_hooks(cls, hook_type, *args, **kwargs):
|
||||
hook_funcs = cls._hooks_map.get(hook_type) or []
|
||||
for hook_func in hook_funcs:
|
||||
hook_func(*args, **kwargs)
|
||||
|
||||
|
||||
def safe_issubclass(*args):
|
||||
"""Like issubclass, but will just return False if not a class."""
|
||||
|
||||
try:
|
||||
if issubclass(*args):
|
||||
return True
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def import_class(import_str):
|
||||
"""Returns a class from a string including module and class."""
|
||||
mod_str, _sep, class_str = import_str.rpartition('.')
|
||||
__import__(mod_str)
|
||||
return getattr(sys.modules[mod_str], class_str)
|
||||
|
||||
_slugify_strip_re = re.compile(r'[^\w\s-]')
|
||||
_slugify_hyphenate_re = re.compile(r'[-\s]+')
|
||||
|
||||
|
||||
# http://code.activestate.com/recipes/
|
||||
# 577257-slugify-make-a-string-usable-in-a-url-or-filename/
|
||||
def slugify(value):
|
||||
"""
|
||||
Normalizes string, converts to lowercase, removes non-alpha characters,
|
||||
and converts spaces to hyphens.
|
||||
|
||||
From Django's "django/template/defaultfilters.py".
|
||||
"""
|
||||
import unicodedata
|
||||
if not isinstance(value, unicode):
|
||||
value = unicode(value)
|
||||
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
|
||||
value = unicode(_slugify_strip_re.sub('', value).strip().lower())
|
||||
return _slugify_hyphenate_re.sub('-', value)
|
@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2012 OpenStack, LLC.
|
||||
#
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from manilaclient.v1.client import Client
|
@ -0,0 +1,79 @@
|
||||
from manilaclient import client
|
||||
from manilaclient.v1 import limits
|
||||
from manilaclient.v1 import quota_classes
|
||||
from manilaclient.v1 import quotas
|
||||
from manilaclient.v1 import shares
|
||||
from manilaclient.v1 import share_snapshots
|
||||
|
||||
|
||||
class Client(object):
|
||||
"""
|
||||
Top-level object to access the OpenStack Volume API.
|
||||
|
||||
Create an instance with your creds::
|
||||
|
||||
>>> client = Client(USERNAME, PASSWORD, PROJECT_ID, AUTH_URL)
|
||||
|
||||
Then call methods on its managers::
|
||||
|
||||
>>> client.shares.list()
|
||||
...
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, username, api_key, project_id=None, auth_url='',
|
||||
insecure=False, timeout=None, tenant_id=None,
|
||||
proxy_tenant_id=None, proxy_token=None, region_name=None,
|
||||
endpoint_type='publicURL', extensions=None,
|
||||
service_type='volume', service_name=None,
|
||||
share_service_name=None, retries=None,
|
||||
http_log_debug=False,
|
||||
cacert=None):
|
||||
# FIXME(comstud): Rename the api_key argument above when we
|
||||
# know it's not being used as keyword argument
|
||||
password = api_key
|
||||
self.limits = limits.LimitsManager(self)
|
||||
|
||||
# extensions
|
||||
self.quota_classes = quota_classes.QuotaClassSetManager(self)
|
||||
self.quotas = quotas.QuotaSetManager(self)
|
||||
self.shares = shares.ShareManager(self)
|
||||
self.share_snapshots = share_snapshots.ShareSnapshotManager(self)
|
||||
|
||||
# Add in any extensions...
|
||||
if extensions:
|
||||
for extension in extensions:
|
||||
if extension.manager_class:
|
||||
setattr(self, extension.name,
|
||||
extension.manager_class(self))
|
||||
|
||||
self.client = client.HTTPClient(
|
||||
username,
|
||||
password,
|
||||
project_id,
|
||||
auth_url,
|
||||
insecure=insecure,
|
||||
timeout=timeout,
|
||||
tenant_id=tenant_id,
|
||||
proxy_token=proxy_token,
|
||||
proxy_tenant_id=proxy_tenant_id,
|
||||
region_name=region_name,
|
||||
endpoint_type=endpoint_type,
|
||||
service_type=service_type,
|
||||
service_name=service_name,
|
||||
share_service_name=share_service_name,
|
||||
retries=retries,
|
||||
http_log_debug=http_log_debug,
|
||||
cacert=cacert)
|
||||
|
||||
def authenticate(self):
|
||||
"""
|
||||
Authenticate against the server.
|
||||
|
||||
Normally this is called automatically when you first access the API,
|
||||
but you can call this method to force authentication right now.
|
||||
|
||||
Returns on success; raises :exc:`exceptions.Unauthorized` if the
|
||||
credentials are wrong.
|
||||
"""
|
||||
self.client.authenticate()
|
@ -0,0 +1,47 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from manilaclient import base
|
||||
from manilaclient import utils
|
||||
|
||||
|
||||
class ListExtResource(base.Resource):
|
||||
@property
|
||||
def summary(self):
|
||||
descr = self.description.strip()
|
||||
if not descr:
|
||||
return '??'
|
||||
lines = descr.split("\n")
|
||||
if len(lines) == 1:
|
||||
return lines[0]
|
||||
else:
|
||||
return lines[0] + "..."
|
||||
|
||||
|
||||
class ListExtManager(base.Manager):
|
||||
resource_class = ListExtResource
|
||||
|
||||
def show_all(self):
|
||||
return self._list("/extensions", 'extensions')
|
||||
|
||||
|
||||
@utils.service_type('share')
|
||||
def do_list_extensions(client, _args):
|
||||
"""
|
||||
List all the os-api extensions that are available.
|
||||
"""
|
||||
extensions = client.list_extensions.show_all()
|
||||
fields = ["Name", "Summary", "Alias", "Updated"]
|
||||
utils.print_list(extensions, fields)
|
@ -0,0 +1,79 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
|
||||
from manilaclient import base
|
||||
|
||||
|
||||
class Limits(base.Resource):
|
||||
"""A collection of RateLimit and AbsoluteLimit objects"""
|
||||
|
||||
def __repr__(self):
|
||||
return "<Limits>"
|
||||
|
||||
@property
|
||||
def absolute(self):
|
||||
for (name, value) in self._info['absolute'].items():
|
||||
yield AbsoluteLimit(name, value)
|
||||
|
||||
@property
|
||||
def rate(self):
|
||||
for group in self._info['rate']:
|
||||
uri = group['uri']
|
||||
regex = group['regex']
|
||||
for rate in group['limit']:
|
||||
yield RateLimit(rate['verb'], uri, regex, rate['value'],
|
||||
rate['remaining'], rate['unit'],
|
||||
rate['next-available'])
|
||||
|
||||
|
||||
class RateLimit(object):
|
||||
"""Data model that represents a flattened view of a single rate limit"""
|
||||
|
||||
def __init__(self, verb, uri, regex, value, remain,
|
||||
unit, next_available):
|
||||
self.verb = verb
|
||||
self.uri = uri
|
||||
self.regex = regex
|
||||
self.value = value
|
||||
self.remain = remain
|
||||
self.unit = unit
|
||||
self.next_available = next_available
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.uri == other.uri \
|
||||
and self.regex == other.regex \
|
||||
and self.value == other.value \
|
||||
and self.verb == other.verb \
|
||||
and self.remain == other.remain \
|
||||
and self.unit == other.unit \
|
||||
and self.next_available == other.next_available
|
||||
|
||||
def __repr__(self):
|
||||
return "<RateLimit: method=%s uri=%s>" % (self.method, self.uri)
|
||||
|
||||
|
||||
class AbsoluteLimit(object):
|
||||
"""Data model that represents a single absolute limit"""
|
||||
|
||||
def __init__(self, name, value):
|
||||
self.name = name
|
||||
self.value = value
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.value == other.value and self.name == other.name
|
||||
|
||||
def __repr__(self):
|
||||
return "<AbsoluteLimit: name=%s>" % (self.name)
|
||||
|
||||
|
||||
class LimitsManager(base.Manager):
|
||||
"""Manager object used to interact with limits resource"""
|
||||
|
||||
resource_class = Limits
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Get a specific extension.
|
||||
|
||||
:rtype: :class:`Limits`
|
||||
"""
|
||||
return self._get("/limits", "limits")
|
@ -0,0 +1,52 @@
|
||||
# Copyright 2012 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from manilaclient import base
|
||||
|
||||
|
||||
class QuotaClassSet(base.Resource):
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
"""QuotaClassSet does not have a 'id' attribute but base.Resource
|
||||
needs it to self-refresh and QuotaSet is indexed by class_name"""
|
||||
return self.class_name
|
||||
|
||||
def update(self, *args, **kwargs):
|
||||
self.manager.update(self.class_name, *args, **kwargs)
|
||||
|
||||
|
||||
class QuotaClassSetManager(base.ManagerWithFind):
|
||||
resource_class = QuotaClassSet
|
||||
|
||||
def get(self, class_name):
|
||||
return self._get("/os-quota-class-sets/%s" % (class_name),
|
||||
"quota_class_set")
|
||||
|
||||
def update(self,
|
||||
class_name,
|
||||
volumes=None,
|
||||
gigabytes=None):
|
||||
|
||||
body = {'quota_class_set': {
|
||||
'class_name': class_name,
|
||||
'volumes': volumes,
|
||||
'gigabytes': gigabytes}}
|
||||
|
||||
for key in body['quota_class_set'].keys():
|
||||
if body['quota_class_set'][key] is None:
|
||||
body['quota_class_set'].pop(key)
|
||||
|
||||
self._update('/os-quota-class-sets/%s' % (class_name), body)
|
@ -0,0 +1,55 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from manilaclient import base
|
||||
|
||||
|
||||
class QuotaSet(base.Resource):
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
"""QuotaSet does not have a 'id' attribute but base.Resource needs it
|
||||
to self-refresh and QuotaSet is indexed by tenant_id"""
|
||||
return self.tenant_id
|
||||
|
||||
def update(self, *args, **kwargs):
|
||||
self.manager.update(self.tenant_id, *args, **kwargs)
|
||||
|
||||
|
||||
class QuotaSetManager(base.ManagerWithFind):
|
||||
resource_class = QuotaSet
|
||||
|
||||
def get(self, tenant_id):
|
||||
if hasattr(tenant_id, 'tenant_id'):
|
||||
tenant_id = tenant_id.tenant_id
|
||||
return self._get("/os-quota-sets/%s" % (tenant_id), "quota_set")
|
||||
|
||||
def update(self, tenant_id, volumes=None, snapshots=None, gigabytes=None):
|
||||
|
||||
body = {'quota_set': {
|
||||
'tenant_id': tenant_id,
|
||||
'volumes': volumes,
|
||||
'snapshots': snapshots,
|
||||
'gigabytes': gigabytes}}
|
||||
|
||||
for key in body['quota_set'].keys():
|
||||
if body['quota_set'][key] is None:
|
||||
body['quota_set'].pop(key)
|
||||
|
||||
self._update('/os-quota-sets/%s' % (tenant_id), body)
|
||||
|
||||
def defaults(self, tenant_id):
|
||||
return self._get('/os-quota-sets/%s/defaults' % tenant_id,
|
||||
'quota_set')
|
974
.tox/pep8/lib/python2.7/site-packages/manilaclient/v1/shell.py
Normal file
974
.tox/pep8/lib/python2.7/site-packages/manilaclient/v1/shell.py
Normal file
@ -0,0 +1,974 @@
|
||||
# Copyright 2010 Jacob Kaplan-Moss
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
from manilaclient import exceptions
|
||||
from manilaclient import utils
|
||||
|
||||
|
||||
def _poll_for_status(poll_fn, obj_id, action, final_ok_states,
|
||||
poll_period=5, show_progress=True):
|
||||
"""Block while an action is being performed, periodically printing
|
||||
progress.
|
||||
"""
|
||||
def print_progress(progress):
|
||||
if show_progress:
|
||||
msg = ('\rInstance %(action)s... %(progress)s%% complete'
|
||||
% dict(action=action, progress=progress))
|
||||
else:
|
||||
msg = '\rInstance %(action)s...' % dict(action=action)
|
||||
|
||||
sys.stdout.write(msg)
|
||||
sys.stdout.flush()
|
||||
|
||||
print
|
||||
while True:
|
||||
obj = poll_fn(obj_id)
|
||||
status = obj.status.lower()
|
||||
progress = getattr(obj, 'progress', None) or 0
|
||||
if status in final_ok_states:
|
||||
print_progress(100)
|
||||
print "\nFinished"
|
||||
break
|
||||
elif status == "error":
|
||||
print "\nError %(action)s instance" % locals()
|
||||
break
|
||||
else:
|
||||
print_progress(progress)
|
||||
time.sleep(poll_period)
|
||||
|
||||
|
||||
def _find_volume(cs, volume):
|
||||
"""Get a volume by ID."""
|
||||
return utils.find_resource(cs.volumes, volume)
|
||||
|
||||
|
||||
def _find_volume_snapshot(cs, snapshot):
|
||||
"""Get a volume snapshot by ID."""
|
||||
return utils.find_resource(cs.volume_snapshots, snapshot)
|
||||
|
||||
|
||||
def _find_backup(cs, backup):
|
||||
"""Get a backup by ID."""
|
||||
return utils.find_resource(cs.backups, backup)
|
||||
|
||||
|
||||
def _print_volume(volume):
|
||||
utils.print_dict(volume._info)
|
||||
|
||||
|
||||
def _print_volume_snapshot(snapshot):
|
||||
utils.print_dict(snapshot._info)
|
||||
|
||||
|
||||
def _find_share(cs, share):
|
||||
"""Get a share by ID."""
|
||||
return utils.find_resource(cs.shares, share)
|
||||
|
||||
|
||||
def _print_share(cs, share):
|
||||
info = share._info.copy()
|
||||
info.pop('links', None)
|
||||
utils.print_dict(info)
|
||||
|
||||
|
||||
def _find_share_snapshot(cs, snapshot):
|
||||
"""Get a snapshot by ID."""
|
||||
return utils.find_resource(cs.share_snapshots, snapshot)
|
||||
|
||||
|
||||
def _print_share_snapshot(cs, snapshot):
|
||||
info = snapshot._info.copy()
|
||||
info.pop('links', None)
|
||||
utils.print_dict(info)
|
||||
|
||||
|
||||
def _translate_keys(collection, convert):
|
||||
for item in collection:
|
||||
keys = item.__dict__.keys()
|
||||
for from_key, to_key in convert:
|
||||
if from_key in keys and to_key not in keys:
|
||||
setattr(item, to_key, item._info[from_key])
|
||||
|
||||
|
||||
def _translate_volume_keys(collection):
|
||||
convert = [('displayName', 'display_name'), ('volumeType', 'volume_type')]
|
||||
_translate_keys(collection, convert)
|
||||
|
||||
|
||||
def _translate_volume_snapshot_keys(collection):
|
||||
convert = [('displayName', 'display_name'), ('volumeId', 'volume_id')]
|
||||
_translate_keys(collection, convert)
|
||||
|
||||
|
||||
def _extract_metadata(args):
|
||||
metadata = {}
|
||||
for metadatum in args.metadata:
|
||||
# unset doesn't require a val, so we have the if/else
|
||||
if '=' in metadatum:
|
||||
(key, value) = metadatum.split('=', 1)
|
||||
else:
|
||||
key = metadatum
|
||||
value = None
|
||||
|
||||
metadata[key] = value
|
||||
return metadata
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'--all-tenants',
|
||||
dest='all_tenants',
|
||||
metavar='<0|1>',
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
default=0,
|
||||
help='Display information from all tenants (Admin only).')
|
||||
@utils.arg(
|
||||
'--all_tenants',
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg(
|
||||
'--display-name',
|
||||
metavar='<display-name>',
|
||||
default=None,
|
||||
help='Filter results by display-name')
|
||||
@utils.arg(
|
||||
'--status',
|
||||
metavar='<status>',
|
||||
default=None,
|
||||
help='Filter results by status')
|
||||
@utils.service_type('share')
|
||||
def do_list(cs, args):
|
||||
"""List all the volumes."""
|
||||
all_tenants = int(os.environ.get("ALL_TENANTS", args.all_tenants))
|
||||
search_opts = {
|
||||
'all_tenants': all_tenants,
|
||||
'display_name': args.display_name,
|
||||
'status': args.status,
|
||||
}
|
||||
volumes = cs.volumes.list(search_opts=search_opts)
|
||||
_translate_volume_keys(volumes)
|
||||
|
||||
# Create a list of servers to which the volume is attached
|
||||
for vol in volumes:
|
||||
servers = [s.get('server_id') for s in vol.attachments]
|
||||
setattr(vol, 'attached_to', ','.join(map(str, servers)))
|
||||
utils.print_list(volumes, ['ID', 'Status', 'Display Name',
|
||||
'Size', 'Volume Type', 'Bootable', 'Attached to'])
|
||||
|
||||
|
||||
@utils.arg('volume', metavar='<volume>', help='ID of the volume.')
|
||||
@utils.service_type('share')
|
||||
def do_show(cs, args):
|
||||
"""Show details about a volume."""
|
||||
volume = _find_volume(cs, args.volume)
|
||||
_print_volume(volume)
|
||||
|
||||
|
||||
@utils.arg('size',
|
||||
metavar='<size>',
|
||||
type=int,
|
||||
help='Size of volume in GB')
|
||||
@utils.arg(
|
||||
'--snapshot-id',
|
||||
metavar='<snapshot-id>',
|
||||
default=None,
|
||||
help='Create volume from snapshot id (Optional, Default=None)')
|
||||
@utils.arg(
|
||||
'--snapshot_id',
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg(
|
||||
'--source-volid',
|
||||
metavar='<source-volid>',
|
||||
default=None,
|
||||
help='Create volume from volume id (Optional, Default=None)')
|
||||
@utils.arg(
|
||||
'--source_volid',
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg(
|
||||
'--image-id',
|
||||
metavar='<image-id>',
|
||||
default=None,
|
||||
help='Create volume from image id (Optional, Default=None)')
|
||||
@utils.arg(
|
||||
'--image_id',
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg(
|
||||
'--display-name',
|
||||
metavar='<display-name>',
|
||||
default=None,
|
||||
help='Volume name (Optional, Default=None)')
|
||||
@utils.arg(
|
||||
'--display_name',
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg(
|
||||
'--display-description',
|
||||
metavar='<display-description>',
|
||||
default=None,
|
||||
help='Volume description (Optional, Default=None)')
|
||||
@utils.arg(
|
||||
'--display_description',
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg(
|
||||
'--volume-type',
|
||||
metavar='<volume-type>',
|
||||
default=None,
|
||||
help='Volume type (Optional, Default=None)')
|
||||
@utils.arg(
|
||||
'--volume_type',
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg(
|
||||
'--availability-zone',
|
||||
metavar='<availability-zone>',
|
||||
default=None,
|
||||
help='Availability zone for volume (Optional, Default=None)')
|
||||
@utils.arg(
|
||||
'--availability_zone',
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg('--metadata',
|
||||
type=str,
|
||||
nargs='*',
|
||||
metavar='<key=value>',
|
||||
help='Metadata key=value pairs (Optional, Default=None)',
|
||||
default=None)
|
||||
@utils.service_type('share')
|
||||
def do_create(cs, args):
|
||||
"""Add a new volume."""
|
||||
volume_metadata = None
|
||||
if args.metadata is not None:
|
||||
volume_metadata = _extract_metadata(args)
|
||||
|
||||
volume = cs.volumes.create(args.size,
|
||||
args.snapshot_id,
|
||||
args.source_volid,
|
||||
args.display_name,
|
||||
args.display_description,
|
||||
args.volume_type,
|
||||
availability_zone=args.availability_zone,
|
||||
imageRef=args.image_id,
|
||||
metadata=volume_metadata)
|
||||
_print_volume(volume)
|
||||
|
||||
|
||||
@utils.arg('volume', metavar='<volume>', help='ID of the volume to delete.')
|
||||
@utils.service_type('share')
|
||||
def do_delete(cs, args):
|
||||
"""Remove a volume."""
|
||||
volume = _find_volume(cs, args.volume)
|
||||
volume.delete()
|
||||
|
||||
|
||||
@utils.arg('volume', metavar='<volume>', help='ID of the volume to delete.')
|
||||
@utils.service_type('share')
|
||||
def do_force_delete(cs, args):
|
||||
"""Attempt forced removal of a volume, regardless of its state."""
|
||||
volume = _find_volume(cs, args.volume)
|
||||
volume.force_delete()
|
||||
|
||||
|
||||
@utils.arg('volume', metavar='<volume>', help='ID of the volume to rename.')
|
||||
@utils.arg('display_name', nargs='?', metavar='<display-name>',
|
||||
help='New display-name for the volume.')
|
||||
@utils.arg('--display-description', metavar='<display-description>',
|
||||
help='Optional volume description. (Default=None)',
|
||||
default=None)
|
||||
@utils.service_type('share')
|
||||
def do_rename(cs, args):
|
||||
"""Rename a volume."""
|
||||
kwargs = {}
|
||||
if args.display_name is not None:
|
||||
kwargs['display_name'] = args.display_name
|
||||
if args.display_description is not None:
|
||||
kwargs['display_description'] = args.display_description
|
||||
_find_volume(cs, args.volume).update(**kwargs)
|
||||
|
||||
|
||||
@utils.arg('volume',
|
||||
metavar='<volume>',
|
||||
help='ID of the volume to update metadata on.')
|
||||
@utils.arg('action',
|
||||
metavar='<action>',
|
||||
choices=['set', 'unset'],
|
||||
help="Actions: 'set' or 'unset'")
|
||||
@utils.arg('metadata',
|
||||
metavar='<key=value>',
|
||||
nargs='+',
|
||||
default=[],
|
||||
help='Metadata to set/unset (only key is necessary on unset)')
|
||||
@utils.service_type('share')
|
||||
def do_metadata(cs, args):
|
||||
"""Set or Delete metadata on a volume."""
|
||||
volume = _find_volume(cs, args.volume)
|
||||
metadata = _extract_metadata(args)
|
||||
|
||||
if args.action == 'set':
|
||||
cs.volumes.set_metadata(volume, metadata)
|
||||
elif args.action == 'unset':
|
||||
cs.volumes.delete_metadata(volume, metadata.keys())
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'--all-tenants',
|
||||
dest='all_tenants',
|
||||
metavar='<0|1>',
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
default=0,
|
||||
help='Display information from all tenants (Admin only).')
|
||||
@utils.arg(
|
||||
'--all_tenants',
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg(
|
||||
'--display-name',
|
||||
metavar='<display-name>',
|
||||
default=None,
|
||||
help='Filter results by display-name')
|
||||
@utils.arg(
|
||||
'--status',
|
||||
metavar='<status>',
|
||||
default=None,
|
||||
help='Filter results by status')
|
||||
@utils.arg(
|
||||
'--volume-id',
|
||||
metavar='<volume-id>',
|
||||
default=None,
|
||||
help='Filter results by volume-id')
|
||||
@utils.service_type('share')
|
||||
def do_snapshot_list(cs, args):
|
||||
"""List all the snapshots."""
|
||||
all_tenants = int(os.environ.get("ALL_TENANTS", args.all_tenants))
|
||||
search_opts = {
|
||||
'all_tenants': all_tenants,
|
||||
'display_name': args.display_name,
|
||||
'status': args.status,
|
||||
'volume_id': args.volume_id,
|
||||
}
|
||||
|
||||
snapshots = cs.volume_snapshots.list(search_opts=search_opts)
|
||||
_translate_volume_snapshot_keys(snapshots)
|
||||
utils.print_list(snapshots,
|
||||
['ID', 'Volume ID', 'Status', 'Display Name', 'Size',
|
||||
'Source Type'])
|
||||
|
||||
|
||||
@utils.arg('snapshot', metavar='<snapshot>', help='ID of the snapshot.')
|
||||
@utils.service_type('share')
|
||||
def do_snapshot_show(cs, args):
|
||||
"""Show details about a snapshot."""
|
||||
snapshot = _find_volume_snapshot(cs, args.snapshot)
|
||||
_print_volume_snapshot(snapshot)
|
||||
|
||||
|
||||
@utils.arg('volume_id',
|
||||
metavar='<volume-id>',
|
||||
help='ID of the volume to snapshot')
|
||||
@utils.arg('--force',
|
||||
metavar='<True|False>',
|
||||
help='Optional flag to indicate whether '
|
||||
'to snapshot a volume even if it\'s '
|
||||
'attached to an instance. (Default=False)',
|
||||
default=False)
|
||||
@utils.arg(
|
||||
'--display-name',
|
||||
metavar='<display-name>',
|
||||
default=None,
|
||||
help='Optional snapshot name. (Default=None)')
|
||||
@utils.arg(
|
||||
'--display_name',
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg(
|
||||
'--display-description',
|
||||
metavar='<display-description>',
|
||||
default=None,
|
||||
help='Optional snapshot description. (Default=None)')
|
||||
@utils.arg(
|
||||
'--display_description',
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.service_type('share')
|
||||
def do_snapshot_create(cs, args):
|
||||
"""Add a new snapshot."""
|
||||
snapshot = cs.volume_snapshots.create(args.volume_id,
|
||||
args.force,
|
||||
args.display_name,
|
||||
args.display_description)
|
||||
_print_volume_snapshot(snapshot)
|
||||
|
||||
|
||||
@utils.arg('snapshot_id',
|
||||
metavar='<snapshot-id>',
|
||||
help='ID of the snapshot to delete.')
|
||||
@utils.service_type('share')
|
||||
def do_snapshot_delete(cs, args):
|
||||
"""Remove a snapshot."""
|
||||
snapshot = _find_volume_snapshot(cs, args.snapshot_id)
|
||||
snapshot.delete()
|
||||
|
||||
|
||||
@utils.arg('snapshot', metavar='<snapshot>', help='ID of the snapshot.')
|
||||
@utils.arg('display_name', nargs='?', metavar='<display-name>',
|
||||
help='New display-name for the snapshot.')
|
||||
@utils.arg('--display-description', metavar='<display-description>',
|
||||
help='Optional snapshot description. (Default=None)',
|
||||
default=None)
|
||||
@utils.service_type('share')
|
||||
def do_snapshot_rename(cs, args):
|
||||
"""Rename a snapshot."""
|
||||
kwargs = {}
|
||||
if args.display_name is not None:
|
||||
kwargs['display_name'] = args.display_name
|
||||
if args.display_description is not None:
|
||||
kwargs['display_description'] = args.display_description
|
||||
_find_volume_snapshot(cs, args.snapshot).update(**kwargs)
|
||||
|
||||
|
||||
def _print_volume_type_list(vtypes):
|
||||
utils.print_list(vtypes, ['ID', 'Name'])
|
||||
|
||||
|
||||
def _print_type_and_extra_specs_list(vtypes):
|
||||
formatters = {'extra_specs': _print_type_extra_specs}
|
||||
utils.print_list(vtypes, ['ID', 'Name', 'extra_specs'], formatters)
|
||||
|
||||
|
||||
@utils.service_type('share')
|
||||
def do_type_list(cs, args):
|
||||
"""Print a list of available 'volume types'."""
|
||||
vtypes = cs.volume_types.list()
|
||||
_print_volume_type_list(vtypes)
|
||||
|
||||
|
||||
@utils.service_type('share')
|
||||
def do_extra_specs_list(cs, args):
|
||||
"""Print a list of current 'volume types and extra specs' (Admin Only)."""
|
||||
vtypes = cs.volume_types.list()
|
||||
_print_type_and_extra_specs_list(vtypes)
|
||||
|
||||
|
||||
@utils.arg('name',
|
||||
metavar='<name>',
|
||||
help="Name of the new volume type")
|
||||
@utils.service_type('share')
|
||||
def do_type_create(cs, args):
|
||||
"""Create a new volume type."""
|
||||
vtype = cs.volume_types.create(args.name)
|
||||
_print_volume_type_list([vtype])
|
||||
|
||||
|
||||
@utils.arg('id',
|
||||
metavar='<id>',
|
||||
help="Unique ID of the volume type to delete")
|
||||
@utils.service_type('share')
|
||||
def do_type_delete(cs, args):
|
||||
"""Delete a specific volume type"""
|
||||
cs.volume_types.delete(args.id)
|
||||
|
||||
|
||||
@utils.arg('vtype',
|
||||
metavar='<vtype>',
|
||||
help="Name or ID of the volume type")
|
||||
@utils.arg('action',
|
||||
metavar='<action>',
|
||||
choices=['set', 'unset'],
|
||||
help="Actions: 'set' or 'unset'")
|
||||
@utils.arg('metadata',
|
||||
metavar='<key=value>',
|
||||
nargs='*',
|
||||
default=None,
|
||||
help='Extra_specs to set/unset (only key is necessary on unset)')
|
||||
@utils.service_type('share')
|
||||
def do_type_key(cs, args):
|
||||
"Set or unset extra_spec for a volume type."""
|
||||
vtype = _find_volume_type(cs, args.vtype)
|
||||
|
||||
if args.metadata is not None:
|
||||
keypair = _extract_metadata(args)
|
||||
|
||||
if args.action == 'set':
|
||||
vtype.set_keys(keypair)
|
||||
elif args.action == 'unset':
|
||||
vtype.unset_keys(keypair.keys())
|
||||
|
||||
|
||||
def do_endpoints(cs, args):
|
||||
"""Discover endpoints that get returned from the authenticate services"""
|
||||
catalog = cs.client.service_catalog.catalog
|
||||
for e in catalog['access']['serviceCatalog']:
|
||||
utils.print_dict(e['endpoints'][0], e['name'])
|
||||
|
||||
|
||||
def do_credentials(cs, args):
|
||||
"""Show user credentials returned from auth"""
|
||||
catalog = cs.client.service_catalog.catalog
|
||||
utils.print_dict(catalog['access']['user'], "User Credentials")
|
||||
utils.print_dict(catalog['access']['token'], "Token")
|
||||
|
||||
_quota_resources = ['volumes', 'snapshots', 'gigabytes']
|
||||
|
||||
|
||||
def _quota_show(quotas):
|
||||
quota_dict = {}
|
||||
for resource in _quota_resources:
|
||||
quota_dict[resource] = getattr(quotas, resource, None)
|
||||
utils.print_dict(quota_dict)
|
||||
|
||||
|
||||
def _quota_update(manager, identifier, args):
|
||||
updates = {}
|
||||
for resource in _quota_resources:
|
||||
val = getattr(args, resource, None)
|
||||
if val is not None:
|
||||
updates[resource] = val
|
||||
|
||||
if updates:
|
||||
manager.update(identifier, **updates)
|
||||
|
||||
|
||||
@utils.arg('tenant', metavar='<tenant_id>',
|
||||
help='UUID of tenant to list the quotas for.')
|
||||
@utils.service_type('share')
|
||||
def do_quota_show(cs, args):
|
||||
"""List the quotas for a tenant."""
|
||||
|
||||
_quota_show(cs.quotas.get(args.tenant))
|
||||
|
||||
|
||||
@utils.arg('tenant', metavar='<tenant_id>',
|
||||
help='UUID of tenant to list the default quotas for.')
|
||||
@utils.service_type('share')
|
||||
def do_quota_defaults(cs, args):
|
||||
"""List the default quotas for a tenant."""
|
||||
|
||||
_quota_show(cs.quotas.defaults(args.tenant))
|
||||
|
||||
|
||||
@utils.arg('tenant', metavar='<tenant_id>',
|
||||
help='UUID of tenant to set the quotas for.')
|
||||
@utils.arg('--volumes',
|
||||
metavar='<volumes>',
|
||||
type=int, default=None,
|
||||
help='New value for the "volumes" quota.')
|
||||
@utils.arg('--snapshots',
|
||||
metavar='<snapshots>',
|
||||
type=int, default=None,
|
||||
help='New value for the "snapshots" quota.')
|
||||
@utils.arg('--gigabytes',
|
||||
metavar='<gigabytes>',
|
||||
type=int, default=None,
|
||||
help='New value for the "gigabytes" quota.')
|
||||
@utils.service_type('share')
|
||||
def do_quota_update(cs, args):
|
||||
"""Update the quotas for a tenant."""
|
||||
|
||||
_quota_update(cs.quotas, args.tenant, args)
|
||||
|
||||
|
||||
@utils.arg('class_name', metavar='<class>',
|
||||
help='Name of quota class to list the quotas for.')
|
||||
@utils.service_type('share')
|
||||
def do_quota_class_show(cs, args):
|
||||
"""List the quotas for a quota class."""
|
||||
|
||||
_quota_show(cs.quota_classes.get(args.class_name))
|
||||
|
||||
|
||||
@utils.arg('class_name', metavar='<class>',
|
||||
help='Name of quota class to set the quotas for.')
|
||||
@utils.arg('--volumes',
|
||||
metavar='<volumes>',
|
||||
type=int, default=None,
|
||||
help='New value for the "volumes" quota.')
|
||||
@utils.arg('--snapshots',
|
||||
metavar='<snapshots>',
|
||||
type=int, default=None,
|
||||
help='New value for the "snapshots" quota.')
|
||||
@utils.arg('--gigabytes',
|
||||
metavar='<gigabytes>',
|
||||
type=int, default=None,
|
||||
help='New value for the "gigabytes" quota.')
|
||||
@utils.service_type('share')
|
||||
def do_quota_class_update(cs, args):
|
||||
"""Update the quotas for a quota class."""
|
||||
|
||||
_quota_update(cs.quota_classes, args.class_name, args)
|
||||
|
||||
|
||||
@utils.service_type('share')
|
||||
def do_absolute_limits(cs, args):
|
||||
"""Print a list of absolute limits for a user"""
|
||||
limits = cs.limits.get().absolute
|
||||
columns = ['Name', 'Value']
|
||||
utils.print_list(limits, columns)
|
||||
|
||||
|
||||
@utils.service_type('share')
|
||||
def do_rate_limits(cs, args):
|
||||
"""Print a list of rate limits for a user"""
|
||||
limits = cs.limits.get().rate
|
||||
columns = ['Verb', 'URI', 'Value', 'Remain', 'Unit', 'Next_Available']
|
||||
utils.print_list(limits, columns)
|
||||
|
||||
|
||||
def _print_type_extra_specs(vol_type):
|
||||
try:
|
||||
return vol_type.get_keys()
|
||||
except exceptions.NotFound:
|
||||
return "N/A"
|
||||
|
||||
|
||||
def _find_volume_type(cs, vtype):
|
||||
"""Get a volume type by name or ID."""
|
||||
return utils.find_resource(cs.volume_types, vtype)
|
||||
|
||||
|
||||
@utils.arg('volume_id',
|
||||
metavar='<volume-id>',
|
||||
help='ID of the volume to upload to an image')
|
||||
@utils.arg('--force',
|
||||
metavar='<True|False>',
|
||||
help='Optional flag to indicate whether '
|
||||
'to upload a volume even if it\'s '
|
||||
'attached to an instance. (Default=False)',
|
||||
default=False)
|
||||
@utils.arg('--container-format',
|
||||
metavar='<container-format>',
|
||||
help='Optional type for container format '
|
||||
'(Default=bare)',
|
||||
default='bare')
|
||||
@utils.arg('--disk-format',
|
||||
metavar='<disk-format>',
|
||||
help='Optional type for disk format '
|
||||
'(Default=raw)',
|
||||
default='raw')
|
||||
@utils.arg('image_name',
|
||||
metavar='<image-name>',
|
||||
help='Name for created image')
|
||||
@utils.service_type('share')
|
||||
def do_upload_to_image(cs, args):
|
||||
"""Upload volume to image service as image."""
|
||||
volume = _find_volume(cs, args.volume_id)
|
||||
volume.upload_to_image(args.force,
|
||||
args.image_name,
|
||||
args.container_format,
|
||||
args.disk_format)
|
||||
|
||||
|
||||
@utils.arg('volume', metavar='<volume>',
|
||||
help='ID of the volume to backup.')
|
||||
@utils.arg('--container', metavar='<container>',
|
||||
help='Optional Backup container name. (Default=None)',
|
||||
default=None)
|
||||
@utils.arg('--display-name', metavar='<display-name>',
|
||||
help='Optional backup name. (Default=None)',
|
||||
default=None)
|
||||
@utils.arg('--display-description', metavar='<display-description>',
|
||||
help='Optional backup description. (Default=None)',
|
||||
default=None)
|
||||
@utils.service_type('share')
|
||||
def do_backup_create(cs, args):
|
||||
"""Creates a backup."""
|
||||
cs.backups.create(args.volume,
|
||||
args.container,
|
||||
args.display_name,
|
||||
args.display_description)
|
||||
|
||||
|
||||
@utils.arg('backup', metavar='<backup>', help='ID of the backup.')
|
||||
@utils.service_type('share')
|
||||
def do_backup_show(cs, args):
|
||||
"""Show details about a backup."""
|
||||
backup = _find_backup(cs, args.backup)
|
||||
info = dict()
|
||||
info.update(backup._info)
|
||||
|
||||
if 'links' in info:
|
||||
info.pop('links')
|
||||
|
||||
utils.print_dict(info)
|
||||
|
||||
|
||||
@utils.service_type('share')
|
||||
def do_backup_list(cs, args):
|
||||
"""List all the backups."""
|
||||
backups = cs.backups.list()
|
||||
columns = ['ID', 'Volume ID', 'Status', 'Name', 'Size', 'Object Count',
|
||||
'Container']
|
||||
utils.print_list(backups, columns)
|
||||
|
||||
|
||||
@utils.arg('backup', metavar='<backup>',
|
||||
help='ID of the backup to delete.')
|
||||
@utils.service_type('share')
|
||||
def do_backup_delete(cs, args):
|
||||
"""Remove a backup."""
|
||||
backup = _find_backup(cs, args.backup)
|
||||
backup.delete()
|
||||
|
||||
|
||||
@utils.arg('backup', metavar='<backup>',
|
||||
help='ID of the backup to restore.')
|
||||
@utils.arg('--volume-id', metavar='<volume-id>',
|
||||
help='Optional ID of the volume to restore to.',
|
||||
default=None)
|
||||
@utils.service_type('share')
|
||||
def do_backup_restore(cs, args):
|
||||
"""Restore a backup."""
|
||||
cs.restores.restore(args.backup,
|
||||
args.volume_id)
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'share_protocol',
|
||||
metavar='<share_protocol>',
|
||||
type=str,
|
||||
help='Share type (NFS or CIFS)')
|
||||
@utils.arg(
|
||||
'size',
|
||||
metavar='<size>',
|
||||
type=int,
|
||||
help='Share size in GB')
|
||||
@utils.arg(
|
||||
'--snapshot-id',
|
||||
metavar='<snapshot-id>',
|
||||
help='Optional snapshot id to create the share from. (Default=None)',
|
||||
default=None)
|
||||
@utils.arg(
|
||||
'--display-name',
|
||||
metavar='<display-name>',
|
||||
help='Optional share name. (Default=None)',
|
||||
default=None)
|
||||
@utils.arg(
|
||||
'--display_name',
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg(
|
||||
'--display-description',
|
||||
metavar='<display-description>',
|
||||
help='Optional share description. (Default=None)',
|
||||
default=None)
|
||||
@utils.arg(
|
||||
'--display_description',
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.service_type('share')
|
||||
def do_share_create(cs, args):
|
||||
"""Creates new NAS storage (NFS or CIFS)."""
|
||||
share = cs.shares.create(args.share_protocol, args.size, args.snapshot_id,
|
||||
args.display_name, args.display_description)
|
||||
_print_share(cs, share)
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'share',
|
||||
metavar='<share>',
|
||||
help='ID of the NAS to delete.')
|
||||
@utils.service_type('share')
|
||||
def do_share_delete(cs, args):
|
||||
"""Deletes NAS storage."""
|
||||
cs.shares.delete(args.share)
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'share',
|
||||
metavar='<share>',
|
||||
help='ID of the NAS share.')
|
||||
@utils.service_type('share')
|
||||
def do_share_show(cs, args):
|
||||
"""Show details about a NAS share."""
|
||||
share = _find_share(cs, args.share)
|
||||
_print_share(cs, share)
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'share',
|
||||
metavar='<share>',
|
||||
help='ID of the NAS share to modify.')
|
||||
@utils.arg(
|
||||
'access_type',
|
||||
metavar='<access_type>',
|
||||
help='access rule type (only "ip" is supported).')
|
||||
@utils.arg(
|
||||
'access_to',
|
||||
metavar='<access_to>',
|
||||
help='Value that defines access')
|
||||
@utils.service_type('share')
|
||||
def do_share_allow(cs, args):
|
||||
"""Allow access to the share."""
|
||||
share = _find_share(cs, args.share)
|
||||
share.allow(args.access_type, args.access_to)
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'share',
|
||||
metavar='<share>',
|
||||
help='ID of the NAS share to modify.')
|
||||
@utils.arg(
|
||||
'id',
|
||||
metavar='<id>',
|
||||
help='id of the access rule to be deleted.')
|
||||
@utils.service_type('share')
|
||||
def do_share_deny(cs, args):
|
||||
"""Deny access to a share."""
|
||||
share = _find_share(cs, args.share)
|
||||
share.deny(args.id)
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'share',
|
||||
metavar='<share>',
|
||||
help='ID of the share.')
|
||||
@utils.service_type('share')
|
||||
def do_share_access_list(cs, args):
|
||||
"""Show access list for share."""
|
||||
share = _find_share(cs, args.share)
|
||||
access_list = share.access_list()
|
||||
utils.print_list(access_list, ['id', 'access type', 'access to', 'state'])
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'--all-tenants',
|
||||
dest='all_tenants',
|
||||
metavar='<0|1>',
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
default=0,
|
||||
help='Display information from all tenants (Admin only).')
|
||||
@utils.arg(
|
||||
'--display-name',
|
||||
metavar='<display-name>',
|
||||
default=None,
|
||||
help='Filter results by name')
|
||||
@utils.arg(
|
||||
'--status',
|
||||
metavar='<status>',
|
||||
default=None,
|
||||
help='Filter results by status')
|
||||
@utils.service_type('share')
|
||||
def do_share_list(cs, args):
|
||||
"""List all NAS shares."""
|
||||
all_tenants = int(os.environ.get("ALL_TENANTS", args.all_tenants))
|
||||
search_opts = {
|
||||
'all_tenants': all_tenants,
|
||||
'display_name': args.display_name,
|
||||
'status': args.status,
|
||||
}
|
||||
shares = cs.shares.list(search_opts=search_opts)
|
||||
utils.print_list(shares,
|
||||
['ID', 'Display Name', 'Size', 'Share Proto', 'Status',
|
||||
'Export location'])
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'--all-tenants',
|
||||
dest='all_tenants',
|
||||
metavar='<0|1>',
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
default=0,
|
||||
help='Display information from all tenants (Admin only).')
|
||||
@utils.arg(
|
||||
'--display-name',
|
||||
metavar='<display-name>',
|
||||
default=None,
|
||||
help='Filter results by name')
|
||||
@utils.arg(
|
||||
'--status',
|
||||
metavar='<status>',
|
||||
default=None,
|
||||
help='Filter results by status')
|
||||
@utils.arg(
|
||||
'--share-id',
|
||||
metavar='<share-id>',
|
||||
default=None,
|
||||
help='Filter results by share-id')
|
||||
@utils.service_type('share')
|
||||
def do_share_snapshot_list(cs, args):
|
||||
"""List all the snapshots."""
|
||||
all_tenants = int(os.environ.get("ALL_TENANTS", args.all_tenants))
|
||||
search_opts = {
|
||||
'all_tenants': all_tenants,
|
||||
'display_name': args.display_name,
|
||||
'status': args.status,
|
||||
'share_id': args.share_id,
|
||||
}
|
||||
snapshots = cs.share_snapshots.list(search_opts=search_opts)
|
||||
utils.print_list(snapshots,
|
||||
['ID', 'Share ID', 'Status', 'Display Name',
|
||||
'Share Size'])
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'snapshot',
|
||||
metavar='<snapshot>',
|
||||
help='ID of the snapshot.')
|
||||
@utils.service_type('share')
|
||||
def do_share_snapshot_show(cs, args):
|
||||
"""Show details about a snapshot."""
|
||||
snapshot = _find_share_snapshot(cs, args.snapshot)
|
||||
_print_share_snapshot(cs, snapshot)
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'share_id',
|
||||
metavar='<share-id>',
|
||||
help='ID of the share to snapshot')
|
||||
@utils.arg(
|
||||
'--force',
|
||||
metavar='<True|False>',
|
||||
help='Optional flag to indicate whether '
|
||||
'to snapshot a share even if it\'s busy.'
|
||||
' (Default=False)',
|
||||
default=False)
|
||||
@utils.arg(
|
||||
'--display-name',
|
||||
metavar='<display-name>',
|
||||
default=None,
|
||||
help='Optional snapshot name. (Default=None)')
|
||||
@utils.arg(
|
||||
'--display-description',
|
||||
metavar='<display-description>',
|
||||
default=None,
|
||||
help='Optional snapshot description. (Default=None)')
|
||||
@utils.service_type('share')
|
||||
def do_share_snapshot_create(cs, args):
|
||||
"""Add a new snapshot."""
|
||||
snapshot = cs.share_snapshots.create(args.share_id,
|
||||
args.force,
|
||||
args.display_name,
|
||||
args.display_description)
|
||||
_print_share_snapshot(cs, snapshot)
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'snapshot_id',
|
||||
metavar='<snapshot-id>',
|
||||
help='ID of the snapshot to delete.')
|
||||
@utils.service_type('share')
|
||||
def do_share_snapshot_delete(cs, args):
|
||||
"""Remove a snapshot."""
|
||||
snapshot = _find_share_snapshot(cs, args.snapshot_id)
|
||||
snapshot.delete()
|
@ -29,7 +29,7 @@ class Client(object):
|
||||
proxy_tenant_id=None, proxy_token=None, region_name=None,
|
||||
endpoint_type='publicURL', extensions=None,
|
||||
service_type='volume', service_name=None,
|
||||
volume_service_name=None, retries=None,
|
||||
share_service_name=None, retries=None,
|
||||
http_log_debug=False,
|
||||
cacert=None):
|
||||
# FIXME(comstud): Rename the api_key argument above when we
|
||||
@ -69,7 +69,7 @@ class Client(object):
|
||||
endpoint_type=endpoint_type,
|
||||
service_type=service_type,
|
||||
service_name=service_name,
|
||||
volume_service_name=volume_service_name,
|
||||
share_service_name=share_service_name,
|
||||
retries=retries,
|
||||
http_log_debug=http_log_debug,
|
||||
cacert=cacert)
|
@ -0,0 +1,91 @@
|
||||
# Copyright 2012 NetApp
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Interface for shares extention."""
|
||||
|
||||
import os
|
||||
import urllib
|
||||
|
||||
from manilaclient import base
|
||||
from manilaclient import utils
|
||||
|
||||
|
||||
class ShareSnapshot(base.Resource):
|
||||
"""Represent a snapshot of a share."""
|
||||
|
||||
def __repr__(self):
|
||||
return "<ShareSnapshot: %s>" % self.id
|
||||
|
||||
def delete(self):
|
||||
"""Delete this snapshot."""
|
||||
self.manager.delete(self)
|
||||
|
||||
|
||||
class ShareSnapshotManager(base.ManagerWithFind):
|
||||
"""Manage :class:`ShareSnapshot` resources.
|
||||
"""
|
||||
resource_class = ShareSnapshot
|
||||
|
||||
def create(self, share_id, force=False, name=None, description=None):
|
||||
"""Create a snapshot of the given share.
|
||||
|
||||
:param share_id: The ID of the share to snapshot.
|
||||
:param force: If force is True, create a snapshot even if the
|
||||
share is busy. Default is False.
|
||||
:param name: Name of the snapshot
|
||||
:param description: Description of the snapshot
|
||||
:rtype: :class:`ShareSnapshot`
|
||||
"""
|
||||
body = {'share-snapshot': {'share_id': share_id,
|
||||
'force': force,
|
||||
'name': name,
|
||||
'description': description}}
|
||||
return self._create('/share-snapshots', body, 'share-snapshot')
|
||||
|
||||
def get(self, snapshot_id):
|
||||
"""Get a snapshot.
|
||||
|
||||
:param snapshot_id: The ID of the snapshot to get.
|
||||
:rtype: :class:`ShareSnapshot`
|
||||
"""
|
||||
return self._get('/share-snapshots/%s' % snapshot_id, 'share-snapshot')
|
||||
|
||||
def list(self, detailed=True, search_opts=None):
|
||||
"""Get a list of all snapshots of shares.
|
||||
|
||||
:rtype: list of :class:`ShareSnapshot`
|
||||
"""
|
||||
if search_opts:
|
||||
query_string = urllib.urlencode([(key, value)
|
||||
for (key, value)
|
||||
in search_opts.items()
|
||||
if value])
|
||||
if query_string:
|
||||
query_string = "?%s" % (query_string,)
|
||||
else:
|
||||
query_string = ''
|
||||
|
||||
if detailed:
|
||||
path = "/share-snapshots/detail%s" % (query_string,)
|
||||
else:
|
||||
path = "/share-snapshots%s" % (query_string,)
|
||||
|
||||
return self._list(path, 'share-snapshots')
|
||||
|
||||
def delete(self, snapshot):
|
||||
"""Delete a snapshot of a share.
|
||||
|
||||
:param share: The :class:`ShareSnapshot` to delete.
|
||||
"""
|
||||
self._delete("/share-snapshots/%s" % base.getid(snapshot))
|
182
.tox/pep8/lib/python2.7/site-packages/manilaclient/v2/shares.py
Normal file
182
.tox/pep8/lib/python2.7/site-packages/manilaclient/v2/shares.py
Normal file
@ -0,0 +1,182 @@
|
||||
# Copyright 2012 NetApp
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Interface for shares extention."""
|
||||
|
||||
import collections
|
||||
import os
|
||||
import re
|
||||
import urllib
|
||||
|
||||
from manilaclient import base
|
||||
from manilaclient import exceptions
|
||||
from manilaclient import utils
|
||||
|
||||
|
||||
class Share(base.Resource):
|
||||
"""A share is an extra block level storage to the OpenStack instances."""
|
||||
def __repr__(self):
|
||||
return "<Share: %s>" % self.id
|
||||
|
||||
def delete(self):
|
||||
"""Delete this share."""
|
||||
self.manager.delete(self)
|
||||
|
||||
def allow(self, access_type, access):
|
||||
"""Allow access to a share."""
|
||||
self._validate_access(access_type, access)
|
||||
return self.manager.allow(self, access_type, access)
|
||||
|
||||
def deny(self, id):
|
||||
"""Deny access from IP to a share."""
|
||||
return self.manager.deny(self, id)
|
||||
|
||||
def access_list(self):
|
||||
"""Deny access from IP to a share."""
|
||||
return self.manager.access_list(self)
|
||||
|
||||
def _validate_access(self, access_type, access):
|
||||
if access_type == 'ip':
|
||||
self._validate_ip_range(access)
|
||||
elif access_type == 'passwd':
|
||||
self._validate_username(access)
|
||||
else:
|
||||
raise exceptions.CommandError(
|
||||
'Only ip and passwd type are supported')
|
||||
|
||||
@staticmethod
|
||||
def _validate_username(access):
|
||||
valid_useraname_re = '\w{4,32}'
|
||||
username = access
|
||||
if not re.match(valid_useraname_re, username):
|
||||
exc_str = _('Invalid user name. Must be alphanum 4-32 chars long')
|
||||
raise exceptions.CommandError(exc_str)
|
||||
|
||||
@staticmethod
|
||||
def _validate_ip_range(ip_range):
|
||||
ip_range = ip_range.split('/')
|
||||
exc_str = ('Supported ip format examples:\n'
|
||||
'\t10.0.0.2, 10.0.0.*, 10.0.0.0/24')
|
||||
if len(ip_range) > 2:
|
||||
raise exceptions.CommandError(exc_str)
|
||||
allow_asterisk = (len(ip_range) == 1)
|
||||
ip_range = ip_range[0].split('.')
|
||||
if len(ip_range) != 4:
|
||||
raise exceptions.CommandError(exc_str)
|
||||
for item in ip_range:
|
||||
try:
|
||||
if 0 <= int(item) <= 255:
|
||||
continue
|
||||
raise ValueError()
|
||||
except ValueError:
|
||||
if not (allow_asterisk and item == '*'):
|
||||
raise exceptions.CommandError(exc_str)
|
||||
|
||||
|
||||
class ShareManager(base.ManagerWithFind):
|
||||
"""Manage :class:`Share` resources."""
|
||||
resource_class = Share
|
||||
|
||||
def create(self, share_proto, size, snapshot_id=None, name=None,
|
||||
description=None):
|
||||
"""Create NAS.
|
||||
|
||||
:param size: Size of NAS in GB
|
||||
:param snapshot_id: ID of the snapshot
|
||||
:param name: Name of the NAS
|
||||
:param description: Short description of a share
|
||||
:param share_proto: Type of NAS (NFS or CIFS)
|
||||
:rtype: :class:`Share`
|
||||
"""
|
||||
body = {'share': {'size': size,
|
||||
'snapshot_id': snapshot_id,
|
||||
'name': name,
|
||||
'description': description,
|
||||
'share_proto': share_proto}}
|
||||
return self._create('/shares', body, 'share')
|
||||
|
||||
def get(self, share_id):
|
||||
"""Get a share.
|
||||
|
||||
:param share_id: The ID of the share to delete.
|
||||
:rtype: :class:`Share`
|
||||
"""
|
||||
return self._get("/shares/%s" % share_id, "share")
|
||||
|
||||
def list(self, detailed=True, search_opts=None):
|
||||
"""Get a list of all shares.
|
||||
|
||||
:rtype: list of :class:`Share`
|
||||
"""
|
||||
if search_opts:
|
||||
query_string = urllib.urlencode([(key, value)
|
||||
for (key, value)
|
||||
in search_opts.items()
|
||||
if value])
|
||||
if query_string:
|
||||
query_string = "?%s" % (query_string,)
|
||||
else:
|
||||
query_string = ''
|
||||
|
||||
if detailed:
|
||||
path = "/shares/detail%s" % (query_string,)
|
||||
else:
|
||||
path = "/shares%s" % (query_string,)
|
||||
|
||||
return self._list(path, 'shares')
|
||||
|
||||
def delete(self, share):
|
||||
"""Delete a share.
|
||||
|
||||
:param share: The :class:`Share` to delete.
|
||||
"""
|
||||
self._delete("/shares/%s" % base.getid(share))
|
||||
|
||||
def allow(self, share, access_type, access):
|
||||
"""Allow access from IP to a shares.
|
||||
|
||||
:param share: The :class:`Share` to delete.
|
||||
:param access_type: string that represents access type ('ip','domain')
|
||||
:param access: string that represents access ('127.0.0.1')
|
||||
"""
|
||||
return self._action('os-allow_access', share,
|
||||
{'access_type': access_type,
|
||||
'access_to': access})
|
||||
|
||||
def deny(self, share, id):
|
||||
"""Deny access from IP to a shares.
|
||||
|
||||
:param share: The :class:`Share` to delete.
|
||||
:param ip: string that represents ip address
|
||||
"""
|
||||
return self._action('os-deny_access', share, {'access_id': id})
|
||||
|
||||
def access_list(self, share):
|
||||
"""Get access list to the share."""
|
||||
access_list = self._action("os-access_list", share)[1]["access_list"]
|
||||
if access_list:
|
||||
t = collections.namedtuple('Access', access_list[0].keys())
|
||||
return [t(*value.values()) for value in access_list]
|
||||
else:
|
||||
return []
|
||||
|
||||
def _action(self, action, share, info=None, **kwargs):
|
||||
"""Perform a share 'action'."""
|
||||
body = {action: info}
|
||||
self.run_hooks('modify_body_for_action', body, **kwargs)
|
||||
url = '/shares/%s/action' % base.getid(share)
|
||||
return self.api.client.post(url, body=body)
|
||||
|
||||
|
||||
#########################
|
@ -0,0 +1,569 @@
|
||||
Metadata-Version: 1.1
|
||||
Name: pep8
|
||||
Version: 1.4.6
|
||||
Summary: Python style guide checker
|
||||
Home-page: http://pep8.readthedocs.org/
|
||||
Author: Johann C. Rocholl
|
||||
Author-email: johann@rocholl.net
|
||||
License: Expat license
|
||||
Description: pep8 - Python style guide checker
|
||||
=================================
|
||||
|
||||
pep8 is a tool to check your Python code against some of the style
|
||||
conventions in `PEP 8`_.
|
||||
|
||||
.. _PEP 8: http://www.python.org/dev/peps/pep-0008/
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Plugin architecture: Adding new checks is easy.
|
||||
|
||||
* Parseable output: Jump to error location in your editor.
|
||||
|
||||
* Small: Just one Python file, requires only stdlib. You can use just
|
||||
the pep8.py file for this purpose.
|
||||
|
||||
* Comes with a comprehensive test suite.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
You can install, upgrade, uninstall pep8.py with these commands::
|
||||
|
||||
$ pip install pep8
|
||||
$ pip install --upgrade pep8
|
||||
$ pip uninstall pep8
|
||||
|
||||
There's also a package for Debian/Ubuntu, but it's not always the
|
||||
latest version.
|
||||
|
||||
Example usage and output
|
||||
------------------------
|
||||
|
||||
::
|
||||
|
||||
$ pep8 --first optparse.py
|
||||
optparse.py:69:11: E401 multiple imports on one line
|
||||
optparse.py:77:1: E302 expected 2 blank lines, found 1
|
||||
optparse.py:88:5: E301 expected 1 blank line, found 0
|
||||
optparse.py:222:34: W602 deprecated form of raising exception
|
||||
optparse.py:347:31: E211 whitespace before '('
|
||||
optparse.py:357:17: E201 whitespace after '{'
|
||||
optparse.py:472:29: E221 multiple spaces before operator
|
||||
optparse.py:544:21: W601 .has_key() is deprecated, use 'in'
|
||||
|
||||
You can also make pep8.py show the source code for each error, and
|
||||
even the relevant text from PEP 8::
|
||||
|
||||
$ pep8 --show-source --show-pep8 testsuite/E40.py
|
||||
testsuite/E40.py:2:10: E401 multiple imports on one line
|
||||
import os, sys
|
||||
^
|
||||
Imports should usually be on separate lines.
|
||||
|
||||
Okay: import os\nimport sys
|
||||
E401: import sys, os
|
||||
|
||||
|
||||
Or you can display how often each error was found::
|
||||
|
||||
$ pep8 --statistics -qq Python-2.5/Lib
|
||||
232 E201 whitespace after '['
|
||||
599 E202 whitespace before ')'
|
||||
631 E203 whitespace before ','
|
||||
842 E211 whitespace before '('
|
||||
2531 E221 multiple spaces before operator
|
||||
4473 E301 expected 1 blank line, found 0
|
||||
4006 E302 expected 2 blank lines, found 1
|
||||
165 E303 too many blank lines (4)
|
||||
325 E401 multiple imports on one line
|
||||
3615 E501 line too long (82 characters)
|
||||
612 W601 .has_key() is deprecated, use 'in'
|
||||
1188 W602 deprecated form of raising exception
|
||||
|
||||
Links
|
||||
-----
|
||||
|
||||
.. image:: https://api.travis-ci.org/jcrocholl/pep8.png?branch=master
|
||||
:target: https://travis-ci.org/jcrocholl/pep8
|
||||
:alt: Build status
|
||||
|
||||
* `Read the documentation <http://pep8.readthedocs.org/>`_
|
||||
|
||||
* `Fork me on GitHub <http://github.com/jcrocholl/pep8>`_
|
||||
|
||||
|
||||
Changelog
|
||||
=========
|
||||
|
||||
|
||||
1.4.6 (2013-07-02)
|
||||
------------------
|
||||
|
||||
* Honor ``# noqa`` for errors E711 and E712. (Issue #180)
|
||||
|
||||
* When both a ``tox.ini`` and a ``setup.cfg`` are present in the project
|
||||
directory, merge their contents. The ``tox.ini`` file takes
|
||||
precedence (same as before). (Issue #182)
|
||||
|
||||
* Give priority to ``--select`` over ``--ignore``. (Issue #188)
|
||||
|
||||
* Compare full path when excluding a file. (Issue #186)
|
||||
|
||||
* Correctly report other E12 errors when E123 is ignored. (Issue #103)
|
||||
|
||||
* New option ``--hang-closing`` to switch to the alternative style of
|
||||
closing bracket indentation for hanging indent. Add error E133 for
|
||||
closing bracket which is missing indentation. (Issue #103)
|
||||
|
||||
* Accept both styles of closing bracket indentation for hanging indent.
|
||||
Do not report error E123 in the default configuration. (Issue #103)
|
||||
|
||||
* Do not crash when running AST checks and the document contains null bytes.
|
||||
(Issue #184)
|
||||
|
||||
* Fix false positive E261/E262 when the file contains a BOM. (Issue #193)
|
||||
|
||||
* Fix E701, E702 and E703 not detected sometimes. (Issue #196)
|
||||
|
||||
* Fix E122 not detected in some cases. (Issue #201 and #208)
|
||||
|
||||
* Fix false positive E121 with multiple brackets. (Issue #203)
|
||||
|
||||
|
||||
1.4.5 (2013-03-06)
|
||||
------------------
|
||||
|
||||
* When no path is specified, do not try to read from stdin. The feature
|
||||
was added in 1.4.3, but it is not supported on Windows. Use ``-``
|
||||
filename argument to read from stdin. This usage is supported
|
||||
since 1.3.4. (Issue #170)
|
||||
|
||||
* Do not require ``setuptools`` in setup.py. It works around an issue
|
||||
with ``pip`` and Python 3. (Issue #172)
|
||||
|
||||
* Add ``__pycache__`` to the ignore list.
|
||||
|
||||
* Change misleading message for E251. (Issue #171)
|
||||
|
||||
* Do not report false E302 when the source file has a coding cookie or a
|
||||
comment on the first line. (Issue #174)
|
||||
|
||||
* Reorganize the tests and add tests for the API and for the command line
|
||||
usage and options. (Issues #161 and #162)
|
||||
|
||||
* Ignore all checks which are not explicitly selected when ``select`` is
|
||||
passed to the ``StyleGuide`` constructor.
|
||||
|
||||
|
||||
1.4.4 (2013-02-24)
|
||||
------------------
|
||||
|
||||
* Report E227 or E228 instead of E225 for whitespace around bitwise, shift
|
||||
or modulo operators. (Issue #166)
|
||||
|
||||
* Change the message for E226 to make clear that it is about arithmetic
|
||||
operators.
|
||||
|
||||
* Fix a false positive E128 for continuation line indentation with tabs.
|
||||
|
||||
* Fix regression with the ``--diff`` option. (Issue #169)
|
||||
|
||||
* Fix the ``TestReport`` class to print the unexpected warnings and
|
||||
errors.
|
||||
|
||||
|
||||
1.4.3 (2013-02-22)
|
||||
------------------
|
||||
|
||||
* Hide the ``--doctest`` and ``--testsuite`` options when installed.
|
||||
|
||||
* Fix crash with AST checkers when the syntax is invalid. (Issue #160)
|
||||
|
||||
* Read from standard input if no path is specified.
|
||||
|
||||
* Initiate a graceful shutdown on ``Control+C``.
|
||||
|
||||
* Allow to change the ``checker_class`` for the ``StyleGuide``.
|
||||
|
||||
|
||||
1.4.2 (2013-02-10)
|
||||
------------------
|
||||
|
||||
* Support AST checkers provided by third-party applications.
|
||||
|
||||
* Register new checkers with ``register_check(func_or_cls, codes)``.
|
||||
|
||||
* Allow to construct a ``StyleGuide`` with a custom parser.
|
||||
|
||||
* Accept visual indentation without parenthesis after the ``if``
|
||||
statement. (Issue #151)
|
||||
|
||||
* Fix UnboundLocalError when using ``# noqa`` with continued lines.
|
||||
(Issue #158)
|
||||
|
||||
* Re-order the lines for the ``StandardReport``.
|
||||
|
||||
* Expand tabs when checking E12 continuation lines. (Issue #155)
|
||||
|
||||
* Refactor the testing class ``TestReport`` and the specific test
|
||||
functions into a separate test module.
|
||||
|
||||
|
||||
1.4.1 (2013-01-18)
|
||||
------------------
|
||||
|
||||
* Allow sphinx.ext.autodoc syntax for comments. (Issue #110)
|
||||
|
||||
* Report E703 instead of E702 for the trailing semicolon. (Issue #117)
|
||||
|
||||
* Honor ``# noqa`` in addition to ``# nopep8``. (Issue #149)
|
||||
|
||||
* Expose the ``OptionParser`` factory for better extensibility.
|
||||
|
||||
|
||||
1.4 (2012-12-22)
|
||||
----------------
|
||||
|
||||
* Report E226 instead of E225 for optional whitespace around common
|
||||
operators (``*``, ``**``, ``/``, ``+`` and ``-``). This new error
|
||||
code is ignored in the default configuration because PEP 8 recommends
|
||||
to "use your own judgement". (Issue #96)
|
||||
|
||||
* Lines with a ``# nopep8`` at the end will not issue errors on line
|
||||
length E501 or continuation line indentation E12*. (Issue #27)
|
||||
|
||||
* Fix AssertionError when the source file contains an invalid line
|
||||
ending ``"\r\r\n"``. (Issue #119)
|
||||
|
||||
* Read the ``[pep8]`` section of ``tox.ini`` or ``setup.cfg`` if present.
|
||||
(Issue #93 and #141)
|
||||
|
||||
* Add the Sphinx-based documentation, and publish it
|
||||
on http://pep8.readthedocs.org/. (Issue #105)
|
||||
|
||||
|
||||
1.3.4 (2012-12-18)
|
||||
------------------
|
||||
|
||||
* Fix false positive E124 and E128 with comments. (Issue #100)
|
||||
|
||||
* Fix error on stdin when running with bpython. (Issue #101)
|
||||
|
||||
* Fix false positive E401. (Issue #104)
|
||||
|
||||
* Report E231 for nested dictionary in list. (Issue #142)
|
||||
|
||||
* Catch E271 at the beginning of the line. (Issue #133)
|
||||
|
||||
* Fix false positive E126 for multi-line comments. (Issue #138)
|
||||
|
||||
* Fix false positive E221 when operator is preceded by a comma. (Issue #135)
|
||||
|
||||
* Fix ``--diff`` failing on one-line hunk. (Issue #137)
|
||||
|
||||
* Fix the ``--exclude`` switch for directory paths. (Issue #111)
|
||||
|
||||
* Use ``-`` filename to read from standard input. (Issue #128)
|
||||
|
||||
|
||||
1.3.3 (2012-06-27)
|
||||
------------------
|
||||
|
||||
* Fix regression with continuation line checker. (Issue #98)
|
||||
|
||||
|
||||
1.3.2 (2012-06-26)
|
||||
------------------
|
||||
|
||||
* Revert to the previous behaviour for ``--show-pep8``:
|
||||
do not imply ``--first``. (Issue #89)
|
||||
|
||||
* Add E902 for IO errors. (Issue #87)
|
||||
|
||||
* Fix false positive for E121, and missed E124. (Issue #92)
|
||||
|
||||
* Set a sensible default path for config file on Windows. (Issue #95)
|
||||
|
||||
* Allow ``verbose`` in the configuration file. (Issue #91)
|
||||
|
||||
* Show the enforced ``max-line-length`` in the error message. (Issue #86)
|
||||
|
||||
|
||||
1.3.1 (2012-06-18)
|
||||
------------------
|
||||
|
||||
* Explain which configuration options are expected. Accept and recommend
|
||||
the options names with hyphen instead of underscore. (Issue #82)
|
||||
|
||||
* Do not read the user configuration when used as a module
|
||||
(except if ``config_file=True`` is passed to the ``StyleGuide`` constructor).
|
||||
|
||||
* Fix wrong or missing cases for the E12 series.
|
||||
|
||||
* Fix cases where E122 was missed. (Issue #81)
|
||||
|
||||
|
||||
1.3 (2012-06-15)
|
||||
----------------
|
||||
|
||||
.. warning::
|
||||
The internal API is backwards incompatible.
|
||||
|
||||
* Remove global configuration and refactor the library around
|
||||
a ``StyleGuide`` class; add the ability to configure various
|
||||
reporters. (Issue #35 and #66)
|
||||
|
||||
* Read user configuration from ``~/.config/pep8``
|
||||
and local configuration from ``./.pep8``. (Issue #22)
|
||||
|
||||
* Fix E502 for backslash embedded in multi-line string. (Issue #68)
|
||||
|
||||
* Fix E225 for Python 3 iterable unpacking (PEP 3132). (Issue #72)
|
||||
|
||||
* Enable the new checkers from the E12 series in the default
|
||||
configuration.
|
||||
|
||||
* Suggest less error-prone alternatives for E712 errors.
|
||||
|
||||
* Rewrite checkers to run faster (E22, E251, E27).
|
||||
|
||||
* Fixed a crash when parsed code is invalid (too many
|
||||
closing brackets).
|
||||
|
||||
* Fix E127 and E128 for continuation line indentation. (Issue #74)
|
||||
|
||||
* New option ``--format`` to customize the error format. (Issue #23)
|
||||
|
||||
* New option ``--diff`` to check only modified code. The unified
|
||||
diff is read from STDIN. Example: ``hg diff | pep8 --diff``
|
||||
(Issue #39)
|
||||
|
||||
* Correctly report the count of failures and set the exit code to 1
|
||||
when the ``--doctest`` or the ``--testsuite`` fails.
|
||||
|
||||
* Correctly detect the encoding in Python 3. (Issue #69)
|
||||
|
||||
* Drop support for Python 2.3, 2.4 and 3.0. (Issue #78)
|
||||
|
||||
|
||||
1.2 (2012-06-01)
|
||||
----------------
|
||||
|
||||
* Add E121 through E128 for continuation line indentation. These
|
||||
checks are disabled by default. If you want to force all checks,
|
||||
use switch ``--select=E,W``. Patch by Sam Vilain. (Issue #64)
|
||||
|
||||
* Add E721 for direct type comparisons. (Issue #47)
|
||||
|
||||
* Add E711 and E712 for comparisons to singletons. (Issue #46)
|
||||
|
||||
* Fix spurious E225 and E701 for function annotations. (Issue #29)
|
||||
|
||||
* Add E502 for explicit line join between brackets.
|
||||
|
||||
* Fix E901 when printing source with ``--show-source``.
|
||||
|
||||
* Report all errors for each checker, instead of reporting only the
|
||||
first occurence for each line.
|
||||
|
||||
* Option ``--show-pep8`` implies ``--first``.
|
||||
|
||||
|
||||
1.1 (2012-05-24)
|
||||
----------------
|
||||
|
||||
* Add E901 for syntax errors. (Issues #63 and #30)
|
||||
|
||||
* Add E271, E272, E273 and E274 for extraneous whitespace around
|
||||
keywords. (Issue #57)
|
||||
|
||||
* Add ``tox.ini`` configuration file for tests. (Issue #61)
|
||||
|
||||
* Add ``.travis.yml`` configuration file for continuous integration.
|
||||
(Issue #62)
|
||||
|
||||
|
||||
1.0.1 (2012-04-06)
|
||||
------------------
|
||||
|
||||
* Fix inconsistent version numbers.
|
||||
|
||||
|
||||
1.0 (2012-04-04)
|
||||
----------------
|
||||
|
||||
* Fix W602 ``raise`` to handle multi-char names. (Issue #53)
|
||||
|
||||
|
||||
0.7.0 (2012-03-26)
|
||||
------------------
|
||||
|
||||
* Now ``--first`` prints only the first occurence of each error.
|
||||
The ``--repeat`` flag becomes obsolete because it is the default
|
||||
behaviour. (Issue #6)
|
||||
|
||||
* Allow to specify ``--max-line-length``. (Issue #36)
|
||||
|
||||
* Make the shebang more flexible. (Issue #26)
|
||||
|
||||
* Add testsuite to the bundle. (Issue #25)
|
||||
|
||||
* Fixes for Jython. (Issue #49)
|
||||
|
||||
* Add PyPI classifiers. (Issue #43)
|
||||
|
||||
* Fix the ``--exclude`` option. (Issue #48)
|
||||
|
||||
* Fix W602, accept ``raise`` with 3 arguments. (Issue #34)
|
||||
|
||||
* Correctly select all tests if ``DEFAULT_IGNORE == ''``.
|
||||
|
||||
|
||||
0.6.1 (2010-10-03)
|
||||
------------------
|
||||
|
||||
* Fix inconsistent version numbers. (Issue #21)
|
||||
|
||||
|
||||
0.6.0 (2010-09-19)
|
||||
------------------
|
||||
|
||||
* Test suite reorganized and enhanced in order to check more failures
|
||||
with fewer test files. Read the ``run_tests`` docstring for details
|
||||
about the syntax.
|
||||
|
||||
* Fix E225: accept ``print >>sys.stderr, "..."`` syntax.
|
||||
|
||||
* Fix E501 for lines containing multibyte encoded characters. (Issue #7)
|
||||
|
||||
* Fix E221, E222, E223, E224 not detected in some cases. (Issue #16)
|
||||
|
||||
* Fix E211 to reject ``v = dic['a'] ['b']``. (Issue #17)
|
||||
|
||||
* Exit code is always 1 if any error or warning is found. (Issue #10)
|
||||
|
||||
* ``--ignore`` checks are now really ignored, especially in
|
||||
conjunction with ``--count``. (Issue #8)
|
||||
|
||||
* Blank lines with spaces yield W293 instead of W291: some developers
|
||||
want to ignore this warning and indent the blank lines to paste their
|
||||
code easily in the Python interpreter.
|
||||
|
||||
* Fix E301: do not require a blank line before an indented block. (Issue #14)
|
||||
|
||||
* Fix E203 to accept NumPy slice notation ``a[0, :]``. (Issue #13)
|
||||
|
||||
* Performance improvements.
|
||||
|
||||
* Fix decoding and checking non-UTF8 files in Python 3.
|
||||
|
||||
* Fix E225: reject ``True+False`` when running on Python 3.
|
||||
|
||||
* Fix an exception when the line starts with an operator.
|
||||
|
||||
* Allow a new line before closing ``)``, ``}`` or ``]``. (Issue #5)
|
||||
|
||||
|
||||
0.5.0 (2010-02-17)
|
||||
------------------
|
||||
|
||||
* Changed the ``--count`` switch to print to sys.stderr and set
|
||||
exit code to 1 if any error or warning is found.
|
||||
|
||||
* E241 and E242 are removed from the standard checks. If you want to
|
||||
include these checks, use switch ``--select=E,W``. (Issue #4)
|
||||
|
||||
* Blank line is not mandatory before the first class method or nested
|
||||
function definition, even if there's a docstring. (Issue #1)
|
||||
|
||||
* Add the switch ``--version``.
|
||||
|
||||
* Fix decoding errors with Python 3. (Issue #13 [1]_)
|
||||
|
||||
* Add ``--select`` option which is mirror of ``--ignore``.
|
||||
|
||||
* Add checks E261 and E262 for spaces before inline comments.
|
||||
|
||||
* New check W604 warns about deprecated usage of backticks.
|
||||
|
||||
* New check W603 warns about the deprecated operator ``<>``.
|
||||
|
||||
* Performance improvement, due to rewriting of E225.
|
||||
|
||||
* E225 now accepts:
|
||||
|
||||
- no whitespace after unary operator or similar. (Issue #9 [1]_)
|
||||
|
||||
- lambda function with argument unpacking or keyword defaults.
|
||||
|
||||
* Reserve "2 blank lines" for module-level logical blocks. (E303)
|
||||
|
||||
* Allow multi-line comments. (E302, issue #10 [1]_)
|
||||
|
||||
|
||||
0.4.2 (2009-10-22)
|
||||
------------------
|
||||
|
||||
* Decorators on classes and class methods are OK now.
|
||||
|
||||
|
||||
0.4 (2009-10-20)
|
||||
----------------
|
||||
|
||||
* Support for all versions of Python from 2.3 to 3.1.
|
||||
|
||||
* New and greatly expanded self tests.
|
||||
|
||||
* Added ``--count`` option to print the total number of errors and warnings.
|
||||
|
||||
* Further improvements to the handling of comments and blank lines.
|
||||
(Issue #1 [1]_ and others changes.)
|
||||
|
||||
* Check all py files in directory when passed a directory (Issue
|
||||
#2 [1]_). This also prevents an exception when traversing directories
|
||||
with non ``*.py`` files.
|
||||
|
||||
* E231 should allow commas to be followed by ``)``. (Issue #3 [1]_)
|
||||
|
||||
* Spaces are no longer required around the equals sign for keyword
|
||||
arguments or default parameter values.
|
||||
|
||||
|
||||
.. [1] These issues refer to the `previous issue tracker`__.
|
||||
.. __: http://github.com/cburroughs/pep8.py/issues
|
||||
|
||||
|
||||
0.3.1 (2009-09-14)
|
||||
------------------
|
||||
|
||||
* Fixes for comments: do not count them when checking for blank lines between
|
||||
items.
|
||||
|
||||
* Added setup.py for pypi upload and easy_installability.
|
||||
|
||||
|
||||
0.2 (2007-10-16)
|
||||
----------------
|
||||
|
||||
* Loads of fixes and improvements.
|
||||
|
||||
|
||||
0.1 (2006-10-01)
|
||||
----------------
|
||||
|
||||
* First release.
|
||||
|
||||
Keywords: pep8
|
||||
Platform: UNKNOWN
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Environment :: Console
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: MIT License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
@ -0,0 +1,55 @@
|
||||
CHANGES.txt
|
||||
MANIFEST.in
|
||||
README.rst
|
||||
pep8.py
|
||||
setup.cfg
|
||||
setup.py
|
||||
docs/Makefile
|
||||
docs/advanced.rst
|
||||
docs/api.rst
|
||||
docs/conf.py
|
||||
docs/developer.rst
|
||||
docs/index.rst
|
||||
docs/intro.rst
|
||||
docs/make.bat
|
||||
pep8.egg-info/PKG-INFO
|
||||
pep8.egg-info/SOURCES.txt
|
||||
pep8.egg-info/dependency_links.txt
|
||||
pep8.egg-info/entry_points.txt
|
||||
pep8.egg-info/namespace_packages.txt
|
||||
pep8.egg-info/not-zip-safe
|
||||
pep8.egg-info/top_level.txt
|
||||
testsuite/E10.py
|
||||
testsuite/E11.py
|
||||
testsuite/E12.py
|
||||
testsuite/E12not.py
|
||||
testsuite/E20.py
|
||||
testsuite/E21.py
|
||||
testsuite/E22.py
|
||||
testsuite/E23.py
|
||||
testsuite/E24.py
|
||||
testsuite/E25.py
|
||||
testsuite/E26.py
|
||||
testsuite/E27.py
|
||||
testsuite/E30.py
|
||||
testsuite/E30not.py
|
||||
testsuite/E40.py
|
||||
testsuite/E50.py
|
||||
testsuite/E70.py
|
||||
testsuite/E71.py
|
||||
testsuite/E72.py
|
||||
testsuite/E90.py
|
||||
testsuite/W19.py
|
||||
testsuite/W29.py
|
||||
testsuite/W39.py
|
||||
testsuite/W60.py
|
||||
testsuite/__init__.py
|
||||
testsuite/latin-1.py
|
||||
testsuite/noqa.py
|
||||
testsuite/python3.py
|
||||
testsuite/support.py
|
||||
testsuite/test_all.py
|
||||
testsuite/test_api.py
|
||||
testsuite/test_shell.py
|
||||
testsuite/utf-8-bom.py
|
||||
testsuite/utf-8.py
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1,3 @@
|
||||
[console_scripts]
|
||||
pep8 = pep8:_main
|
||||
|
@ -0,0 +1,11 @@
|
||||
../pep8.py
|
||||
../pep8.pyc
|
||||
./
|
||||
top_level.txt
|
||||
not-zip-safe
|
||||
SOURCES.txt
|
||||
dependency_links.txt
|
||||
PKG-INFO
|
||||
namespace_packages.txt
|
||||
entry_points.txt
|
||||
../../../../bin/pep8
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1 @@
|
||||
pep8
|
1876
.tox/pep8/lib/python2.7/site-packages/pep8.py
Normal file
1876
.tox/pep8/lib/python2.7/site-packages/pep8.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,87 @@
|
||||
Metadata-Version: 1.1
|
||||
Name: pip
|
||||
Version: 1.4.1
|
||||
Summary: A tool for installing and managing Python packages.
|
||||
Home-page: http://www.pip-installer.org
|
||||
Author: The pip developers
|
||||
Author-email: python-virtualenv@groups.google.com
|
||||
License: MIT
|
||||
Description:
|
||||
Project Info
|
||||
============
|
||||
|
||||
* Project Page: https://github.com/pypa/pip
|
||||
* Install howto: http://www.pip-installer.org/en/latest/installing.html
|
||||
* Changelog: http://www.pip-installer.org/en/latest/news.html
|
||||
* Bug Tracking: https://github.com/pypa/pip/issues
|
||||
* Mailing list: http://groups.google.com/group/python-virtualenv
|
||||
* Docs: http://www.pip-installer.org/
|
||||
* IRC: #pip on Freenode.
|
||||
|
||||
Quickstart
|
||||
==========
|
||||
|
||||
Install a package:
|
||||
|
||||
::
|
||||
|
||||
$ pip install SomePackage==1.0
|
||||
[...]
|
||||
Successfully installed SomePackage
|
||||
|
||||
Show what files were installed:
|
||||
|
||||
::
|
||||
|
||||
$ pip show --files SomePackage
|
||||
Name: SomePackage
|
||||
Version: 1.0
|
||||
Location: /my/env/lib/pythonx.x/site-packages
|
||||
Files:
|
||||
../somepackage/__init__.py
|
||||
[...]
|
||||
|
||||
List what packages are outdated:
|
||||
|
||||
::
|
||||
|
||||
$ pip list --outdated
|
||||
SomePackage (Current: 1.0 Latest: 2.0)
|
||||
|
||||
Upgrade a package:
|
||||
|
||||
::
|
||||
|
||||
$ pip install --upgrade SomePackage
|
||||
[...]
|
||||
Found existing installation: SomePackage 1.0
|
||||
Uninstalling SomePackage:
|
||||
Successfully uninstalled SomePackage
|
||||
Running setup.py install for SomePackage
|
||||
Successfully installed SomePackage
|
||||
|
||||
Uninstall a package:
|
||||
|
||||
::
|
||||
|
||||
$ pip uninstall SomePackage
|
||||
Uninstalling SomePackage:
|
||||
/my/env/lib/pythonx.x/site-packages/somepackage
|
||||
Proceed (y/n)? y
|
||||
Successfully uninstalled SomePackage
|
||||
|
||||
|
||||
Keywords: easy_install distutils setuptools egg virtualenv
|
||||
Platform: UNKNOWN
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: MIT License
|
||||
Classifier: Topic :: Software Development :: Build Tools
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.5
|
||||
Classifier: Programming Language :: Python :: 2.6
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.1
|
||||
Classifier: Programming Language :: Python :: 3.2
|
||||
Classifier: Programming Language :: Python :: 3.3
|
@ -0,0 +1,116 @@
|
||||
AUTHORS.txt
|
||||
CHANGES.txt
|
||||
LICENSE.txt
|
||||
MANIFEST.in
|
||||
PROJECT.txt
|
||||
README.rst
|
||||
setup.cfg
|
||||
setup.py
|
||||
docs/configuration.rst
|
||||
docs/cookbook.rst
|
||||
docs/development.rst
|
||||
docs/index.rst
|
||||
docs/installing.rst
|
||||
docs/logic.rst
|
||||
docs/news.rst
|
||||
docs/other-tools.rst
|
||||
docs/quickstart.rst
|
||||
docs/usage.rst
|
||||
pip/__init__.py
|
||||
pip/__main__.py
|
||||
pip/basecommand.py
|
||||
pip/baseparser.py
|
||||
pip/cacert.pem
|
||||
pip/cmdoptions.py
|
||||
pip/download.py
|
||||
pip/exceptions.py
|
||||
pip/index.py
|
||||
pip/locations.py
|
||||
pip/log.py
|
||||
pip/pep425tags.py
|
||||
pip/req.py
|
||||
pip/runner.py
|
||||
pip/status_codes.py
|
||||
pip/util.py
|
||||
pip/wheel.py
|
||||
pip.egg-info/PKG-INFO
|
||||
pip.egg-info/SOURCES.txt
|
||||
pip.egg-info/dependency_links.txt
|
||||
pip.egg-info/entry_points.txt
|
||||
pip.egg-info/not-zip-safe
|
||||
pip.egg-info/requires.txt
|
||||
pip.egg-info/top_level.txt
|
||||
pip/backwardcompat/__init__.py
|
||||
pip/backwardcompat/ssl_match_hostname.py
|
||||
pip/commands/__init__.py
|
||||
pip/commands/bundle.py
|
||||
pip/commands/completion.py
|
||||
pip/commands/freeze.py
|
||||
pip/commands/help.py
|
||||
pip/commands/install.py
|
||||
pip/commands/list.py
|
||||
pip/commands/search.py
|
||||
pip/commands/show.py
|
||||
pip/commands/uninstall.py
|
||||
pip/commands/unzip.py
|
||||
pip/commands/wheel.py
|
||||
pip/commands/zip.py
|
||||
pip/vcs/__init__.py
|
||||
pip/vcs/bazaar.py
|
||||
pip/vcs/git.py
|
||||
pip/vcs/mercurial.py
|
||||
pip/vcs/subversion.py
|
||||
pip/vendor/__init__.py
|
||||
pip/vendor/six.py
|
||||
pip/vendor/distlib/__init__.py
|
||||
pip/vendor/distlib/compat.py
|
||||
pip/vendor/distlib/database.py
|
||||
pip/vendor/distlib/index.py
|
||||
pip/vendor/distlib/locators.py
|
||||
pip/vendor/distlib/manifest.py
|
||||
pip/vendor/distlib/markers.py
|
||||
pip/vendor/distlib/metadata.py
|
||||
pip/vendor/distlib/resources.py
|
||||
pip/vendor/distlib/scripts.py
|
||||
pip/vendor/distlib/util.py
|
||||
pip/vendor/distlib/version.py
|
||||
pip/vendor/distlib/wheel.py
|
||||
pip/vendor/distlib/_backport/__init__.py
|
||||
pip/vendor/distlib/_backport/misc.py
|
||||
pip/vendor/distlib/_backport/shutil.py
|
||||
pip/vendor/distlib/_backport/sysconfig.py
|
||||
pip/vendor/distlib/_backport/tarfile.py
|
||||
pip/vendor/html5lib/__init__.py
|
||||
pip/vendor/html5lib/constants.py
|
||||
pip/vendor/html5lib/html5parser.py
|
||||
pip/vendor/html5lib/ihatexml.py
|
||||
pip/vendor/html5lib/inputstream.py
|
||||
pip/vendor/html5lib/sanitizer.py
|
||||
pip/vendor/html5lib/tokenizer.py
|
||||
pip/vendor/html5lib/utils.py
|
||||
pip/vendor/html5lib/filters/__init__.py
|
||||
pip/vendor/html5lib/filters/_base.py
|
||||
pip/vendor/html5lib/filters/alphabeticalattributes.py
|
||||
pip/vendor/html5lib/filters/inject_meta_charset.py
|
||||
pip/vendor/html5lib/filters/lint.py
|
||||
pip/vendor/html5lib/filters/optionaltags.py
|
||||
pip/vendor/html5lib/filters/sanitizer.py
|
||||
pip/vendor/html5lib/filters/whitespace.py
|
||||
pip/vendor/html5lib/serializer/__init__.py
|
||||
pip/vendor/html5lib/serializer/htmlserializer.py
|
||||
pip/vendor/html5lib/treebuilders/__init__.py
|
||||
pip/vendor/html5lib/treebuilders/_base.py
|
||||
pip/vendor/html5lib/treebuilders/dom.py
|
||||
pip/vendor/html5lib/treebuilders/etree.py
|
||||
pip/vendor/html5lib/treebuilders/etree_lxml.py
|
||||
pip/vendor/html5lib/treewalkers/__init__.py
|
||||
pip/vendor/html5lib/treewalkers/_base.py
|
||||
pip/vendor/html5lib/treewalkers/dom.py
|
||||
pip/vendor/html5lib/treewalkers/etree.py
|
||||
pip/vendor/html5lib/treewalkers/genshistream.py
|
||||
pip/vendor/html5lib/treewalkers/lxmletree.py
|
||||
pip/vendor/html5lib/treewalkers/pulldom.py
|
||||
pip/vendor/html5lib/trie/__init__.py
|
||||
pip/vendor/html5lib/trie/_base.py
|
||||
pip/vendor/html5lib/trie/datrie.py
|
||||
pip/vendor/html5lib/trie/py.py
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1,4 @@
|
||||
[console_scripts]
|
||||
pip = pip:main
|
||||
pip-2.7 = pip:main
|
||||
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1,7 @@
|
||||
|
||||
|
||||
[testing]
|
||||
nose>=1.3.0
|
||||
virtualenv>=1.10
|
||||
scripttest>=1.1.1
|
||||
mock
|
@ -0,0 +1 @@
|
||||
pip
|
235
.tox/pep8/lib/python2.7/site-packages/pip/__init__.py
Normal file
235
.tox/pep8/lib/python2.7/site-packages/pip/__init__.py
Normal file
@ -0,0 +1,235 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import optparse
|
||||
|
||||
import sys
|
||||
import re
|
||||
|
||||
from pip.exceptions import InstallationError, CommandError, PipError
|
||||
from pip.log import logger
|
||||
from pip.util import get_installed_distributions, get_prog
|
||||
from pip.vcs import git, mercurial, subversion, bazaar # noqa
|
||||
from pip.baseparser import create_main_parser
|
||||
from pip.commands import commands, get_similar_commands, get_summaries
|
||||
|
||||
|
||||
# The version as used in the setup.py and the docs conf.py
|
||||
__version__ = "1.4.1"
|
||||
|
||||
def autocomplete():
|
||||
"""Command and option completion for the main option parser (and options)
|
||||
and its subcommands (and options).
|
||||
|
||||
Enable by sourcing one of the completion shell scripts (bash or zsh).
|
||||
"""
|
||||
# Don't complete if user hasn't sourced bash_completion file.
|
||||
if 'PIP_AUTO_COMPLETE' not in os.environ:
|
||||
return
|
||||
cwords = os.environ['COMP_WORDS'].split()[1:]
|
||||
cword = int(os.environ['COMP_CWORD'])
|
||||
try:
|
||||
current = cwords[cword - 1]
|
||||
except IndexError:
|
||||
current = ''
|
||||
|
||||
subcommands = [cmd for cmd, summary in get_summaries()]
|
||||
options = []
|
||||
# subcommand
|
||||
try:
|
||||
subcommand_name = [w for w in cwords if w in subcommands][0]
|
||||
except IndexError:
|
||||
subcommand_name = None
|
||||
|
||||
parser = create_main_parser()
|
||||
# subcommand options
|
||||
if subcommand_name:
|
||||
# special case: 'help' subcommand has no options
|
||||
if subcommand_name == 'help':
|
||||
sys.exit(1)
|
||||
# special case: list locally installed dists for uninstall command
|
||||
if subcommand_name == 'uninstall' and not current.startswith('-'):
|
||||
installed = []
|
||||
lc = current.lower()
|
||||
for dist in get_installed_distributions(local_only=True):
|
||||
if dist.key.startswith(lc) and dist.key not in cwords[1:]:
|
||||
installed.append(dist.key)
|
||||
# if there are no dists installed, fall back to option completion
|
||||
if installed:
|
||||
for dist in installed:
|
||||
print(dist)
|
||||
sys.exit(1)
|
||||
|
||||
subcommand = commands[subcommand_name](parser)
|
||||
options += [(opt.get_opt_string(), opt.nargs)
|
||||
for opt in subcommand.parser.option_list_all
|
||||
if opt.help != optparse.SUPPRESS_HELP]
|
||||
|
||||
# filter out previously specified options from available options
|
||||
prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]]
|
||||
options = [(x, v) for (x, v) in options if x not in prev_opts]
|
||||
# filter options by current input
|
||||
options = [(k, v) for k, v in options if k.startswith(current)]
|
||||
for option in options:
|
||||
opt_label = option[0]
|
||||
# append '=' to options which require args
|
||||
if option[1]:
|
||||
opt_label += '='
|
||||
print(opt_label)
|
||||
else:
|
||||
# show main parser options only when necessary
|
||||
if current.startswith('-') or current.startswith('--'):
|
||||
opts = [i.option_list for i in parser.option_groups]
|
||||
opts.append(parser.option_list)
|
||||
opts = (o for it in opts for o in it)
|
||||
|
||||
subcommands += [i.get_opt_string() for i in opts
|
||||
if i.help != optparse.SUPPRESS_HELP]
|
||||
|
||||
print(' '.join([x for x in subcommands if x.startswith(current)]))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def parseopts(args):
|
||||
parser = create_main_parser()
|
||||
parser.main = True # so the help formatter knows
|
||||
|
||||
# create command listing
|
||||
command_summaries = get_summaries()
|
||||
|
||||
description = [''] + ['%-27s %s' % (i, j) for i, j in command_summaries]
|
||||
parser.description = '\n'.join(description)
|
||||
|
||||
options, args = parser.parse_args(args)
|
||||
|
||||
if options.version:
|
||||
sys.stdout.write(parser.version)
|
||||
sys.stdout.write(os.linesep)
|
||||
sys.exit()
|
||||
|
||||
# pip || pip help || pip --help -> print_help()
|
||||
if not args or (args[0] == 'help' and len(args) == 1):
|
||||
parser.print_help()
|
||||
sys.exit()
|
||||
|
||||
if not args:
|
||||
msg = ('You must give a command '
|
||||
'(use "pip --help" to see a list of commands)')
|
||||
raise CommandError(msg)
|
||||
|
||||
command = args[0].lower()
|
||||
|
||||
if command not in commands:
|
||||
guess = get_similar_commands(command)
|
||||
|
||||
msg = ['unknown command "%s"' % command]
|
||||
if guess:
|
||||
msg.append('maybe you meant "%s"' % guess)
|
||||
|
||||
raise CommandError(' - '.join(msg))
|
||||
|
||||
return command, options, args, parser
|
||||
|
||||
|
||||
def main(initial_args=None):
|
||||
if initial_args is None:
|
||||
initial_args = sys.argv[1:]
|
||||
|
||||
autocomplete()
|
||||
|
||||
try:
|
||||
cmd_name, options, args, parser = parseopts(initial_args)
|
||||
except PipError:
|
||||
e = sys.exc_info()[1]
|
||||
sys.stderr.write("ERROR: %s" % e)
|
||||
sys.stderr.write(os.linesep)
|
||||
sys.exit(1)
|
||||
|
||||
command = commands[cmd_name](parser) # see baseparser.Command
|
||||
return command.main(args[1:], options)
|
||||
|
||||
|
||||
def bootstrap():
|
||||
"""
|
||||
Bootstrapping function to be called from install-pip.py script.
|
||||
"""
|
||||
return main(['install', '--upgrade', 'pip'] + sys.argv[1:])
|
||||
|
||||
############################################################
|
||||
## Writing freeze files
|
||||
|
||||
|
||||
class FrozenRequirement(object):
|
||||
|
||||
def __init__(self, name, req, editable, comments=()):
|
||||
self.name = name
|
||||
self.req = req
|
||||
self.editable = editable
|
||||
self.comments = comments
|
||||
|
||||
_rev_re = re.compile(r'-r(\d+)$')
|
||||
_date_re = re.compile(r'-(20\d\d\d\d\d\d)$')
|
||||
|
||||
@classmethod
|
||||
def from_dist(cls, dist, dependency_links, find_tags=False):
|
||||
location = os.path.normcase(os.path.abspath(dist.location))
|
||||
comments = []
|
||||
from pip.vcs import vcs, get_src_requirement
|
||||
if vcs.get_backend_name(location):
|
||||
editable = True
|
||||
try:
|
||||
req = get_src_requirement(dist, location, find_tags)
|
||||
except InstallationError:
|
||||
ex = sys.exc_info()[1]
|
||||
logger.warn("Error when trying to get requirement for VCS system %s, falling back to uneditable format" % ex)
|
||||
req = None
|
||||
if req is None:
|
||||
logger.warn('Could not determine repository location of %s' % location)
|
||||
comments.append('## !! Could not determine repository location')
|
||||
req = dist.as_requirement()
|
||||
editable = False
|
||||
else:
|
||||
editable = False
|
||||
req = dist.as_requirement()
|
||||
specs = req.specs
|
||||
assert len(specs) == 1 and specs[0][0] == '=='
|
||||
version = specs[0][1]
|
||||
ver_match = cls._rev_re.search(version)
|
||||
date_match = cls._date_re.search(version)
|
||||
if ver_match or date_match:
|
||||
svn_backend = vcs.get_backend('svn')
|
||||
if svn_backend:
|
||||
svn_location = svn_backend(
|
||||
).get_location(dist, dependency_links)
|
||||
if not svn_location:
|
||||
logger.warn(
|
||||
'Warning: cannot find svn location for %s' % req)
|
||||
comments.append('## FIXME: could not find svn URL in dependency_links for this package:')
|
||||
else:
|
||||
comments.append('# Installing as editable to satisfy requirement %s:' % req)
|
||||
if ver_match:
|
||||
rev = ver_match.group(1)
|
||||
else:
|
||||
rev = '{%s}' % date_match.group(1)
|
||||
editable = True
|
||||
req = '%s@%s#egg=%s' % (svn_location, rev, cls.egg_name(dist))
|
||||
return cls(dist.project_name, req, editable, comments)
|
||||
|
||||
@staticmethod
|
||||
def egg_name(dist):
|
||||
name = dist.egg_name()
|
||||
match = re.search(r'-py\d\.\d$', name)
|
||||
if match:
|
||||
name = name[:match.start()]
|
||||
return name
|
||||
|
||||
def __str__(self):
|
||||
req = self.req
|
||||
if self.editable:
|
||||
req = '-e %s' % req
|
||||
return '\n'.join(list(self.comments) + [str(req)]) + '\n'
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
exit = main()
|
||||
if exit:
|
||||
sys.exit(exit)
|
7
.tox/pep8/lib/python2.7/site-packages/pip/__main__.py
Normal file
7
.tox/pep8/lib/python2.7/site-packages/pip/__main__.py
Normal file
@ -0,0 +1,7 @@
|
||||
import sys
|
||||
from .runner import run
|
||||
|
||||
if __name__ == '__main__':
|
||||
exit = run()
|
||||
if exit:
|
||||
sys.exit(exit)
|
@ -0,0 +1,125 @@
|
||||
"""Stuff that differs in different Python versions"""
|
||||
|
||||
import os
|
||||
import imp
|
||||
import sys
|
||||
import site
|
||||
|
||||
__all__ = ['WindowsError']
|
||||
|
||||
uses_pycache = hasattr(imp, 'cache_from_source')
|
||||
|
||||
class NeverUsedException(Exception):
|
||||
"""this exception should never be raised"""
|
||||
|
||||
try:
|
||||
WindowsError = WindowsError
|
||||
except NameError:
|
||||
WindowsError = NeverUsedException
|
||||
|
||||
try:
|
||||
#new in Python 3.3
|
||||
PermissionError = PermissionError
|
||||
except NameError:
|
||||
PermissionError = NeverUsedException
|
||||
|
||||
console_encoding = sys.__stdout__.encoding
|
||||
|
||||
if sys.version_info >= (3,):
|
||||
from io import StringIO, BytesIO
|
||||
from functools import reduce
|
||||
from urllib.error import URLError, HTTPError
|
||||
from queue import Queue, Empty
|
||||
from urllib.request import url2pathname
|
||||
from urllib.request import urlretrieve
|
||||
from email import message as emailmessage
|
||||
import urllib.parse as urllib
|
||||
import urllib.request as urllib2
|
||||
import configparser as ConfigParser
|
||||
import xmlrpc.client as xmlrpclib
|
||||
import urllib.parse as urlparse
|
||||
import http.client as httplib
|
||||
|
||||
def cmp(a, b):
|
||||
return (a > b) - (a < b)
|
||||
|
||||
def b(s):
|
||||
return s.encode('utf-8')
|
||||
|
||||
def u(s):
|
||||
return s.decode('utf-8')
|
||||
|
||||
def console_to_str(s):
|
||||
try:
|
||||
return s.decode(console_encoding)
|
||||
except UnicodeDecodeError:
|
||||
return s.decode('utf_8')
|
||||
|
||||
def fwrite(f, s):
|
||||
f.buffer.write(b(s))
|
||||
|
||||
def get_http_message_param(http_message, param, default_value):
|
||||
return http_message.get_param(param, default_value)
|
||||
|
||||
bytes = bytes
|
||||
string_types = (str,)
|
||||
raw_input = input
|
||||
else:
|
||||
from cStringIO import StringIO
|
||||
from urllib2 import URLError, HTTPError
|
||||
from Queue import Queue, Empty
|
||||
from urllib import url2pathname, urlretrieve
|
||||
from email import Message as emailmessage
|
||||
import urllib
|
||||
import urllib2
|
||||
import urlparse
|
||||
import ConfigParser
|
||||
import xmlrpclib
|
||||
import httplib
|
||||
|
||||
def b(s):
|
||||
return s
|
||||
|
||||
def u(s):
|
||||
return s
|
||||
|
||||
def console_to_str(s):
|
||||
return s
|
||||
|
||||
def fwrite(f, s):
|
||||
f.write(s)
|
||||
|
||||
def get_http_message_param(http_message, param, default_value):
|
||||
result = http_message.getparam(param)
|
||||
return result or default_value
|
||||
|
||||
bytes = str
|
||||
string_types = (basestring,)
|
||||
reduce = reduce
|
||||
cmp = cmp
|
||||
raw_input = raw_input
|
||||
BytesIO = StringIO
|
||||
|
||||
|
||||
from distutils.sysconfig import get_python_lib, get_python_version
|
||||
|
||||
#site.USER_SITE was created in py2.6
|
||||
user_site = getattr(site, 'USER_SITE', None)
|
||||
|
||||
|
||||
def product(*args, **kwds):
|
||||
# product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
|
||||
# product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
|
||||
pools = list(map(tuple, args)) * kwds.get('repeat', 1)
|
||||
result = [[]]
|
||||
for pool in pools:
|
||||
result = [x + [y] for x in result for y in pool]
|
||||
for prod in result:
|
||||
yield tuple(prod)
|
||||
|
||||
|
||||
## only >=py32 has ssl.match_hostname and ssl.CertificateError
|
||||
try:
|
||||
from ssl import match_hostname, CertificateError
|
||||
except ImportError:
|
||||
from ssl_match_hostname import match_hostname, CertificateError
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user