From 95d65706ceab91eaffb00374a3b8c93a40b7651b Mon Sep 17 00:00:00 2001 From: Andreas Jaeger Date: Mon, 17 Apr 2017 19:34:53 +0200 Subject: [PATCH] Retire repo This repo was created by accident, use deb-python-oslo.concurrency instead. Needed-By: I1ac1a06931c8b6dd7c2e73620a0302c29e605f03 Change-Id: I81894aea69b9d09b0977039623c26781093a397a --- .coveragerc | 8 - .gitignore | 55 -- .gitreview | 4 - .mailmap | 3 - .testr.conf | 7 - CONTRIBUTING.rst | 16 - HACKING.rst | 4 - LICENSE | 175 ---- README.rst | 20 - README.txt | 13 + babel.cfg | 1 - doc/source/api/fixture.lockutils.rst | 8 - doc/source/api/index.rst | 8 - doc/source/api/lockutils.rst | 8 - doc/source/api/opts.rst | 8 - doc/source/api/processutils.rst | 8 - doc/source/api/watchdog.rst | 8 - doc/source/conf.py | 80 -- doc/source/contributing.rst | 5 - doc/source/history.rst | 1 - doc/source/index.rst | 40 - doc/source/installation.rst | 12 - doc/source/opts.rst | 8 - doc/source/usage.rst | 74 -- oslo_concurrency/__init__.py | 0 oslo_concurrency/_i18n.py | 32 - oslo_concurrency/fixture/__init__.py | 0 oslo_concurrency/fixture/lockutils.py | 78 -- .../LC_MESSAGES/oslo_concurrency-log-info.po | 19 - .../locale/de/LC_MESSAGES/oslo_concurrency.po | 101 -- .../LC_MESSAGES/oslo_concurrency-log-info.po | 27 - .../en_GB/LC_MESSAGES/oslo_concurrency.po | 100 -- .../LC_MESSAGES/oslo_concurrency-log-info.po | 27 - .../locale/es/LC_MESSAGES/oslo_concurrency.po | 100 -- .../LC_MESSAGES/oslo_concurrency-log-info.po | 27 - .../locale/fr/LC_MESSAGES/oslo_concurrency.po | 100 -- oslo_concurrency/lockutils.py | 371 -------- oslo_concurrency/opts.py | 45 - oslo_concurrency/prlimit.py | 110 --- oslo_concurrency/processutils.py | 542 ----------- oslo_concurrency/tests/__init__.py | 19 - oslo_concurrency/tests/unit/__init__.py | 0 oslo_concurrency/tests/unit/test_lockutils.py | 527 ---------- .../tests/unit/test_lockutils_eventlet.py | 59 -- .../tests/unit/test_processutils.py | 897 ------------------ oslo_concurrency/version.py | 18 - oslo_concurrency/watchdog.py | 76 -- .../notes/add_reno-3b4ae0789e9c45b4.yaml | 3 - releasenotes/source/_static/.placeholder | 0 releasenotes/source/_templates/.placeholder | 0 releasenotes/source/conf.py | 273 ------ releasenotes/source/index.rst | 8 - .../locale/en_GB/LC_MESSAGES/releasenotes.po | 30 - releasenotes/source/unreleased.rst | 5 - requirements.txt | 13 - setup.cfg | 58 -- setup.py | 29 - test-requirements.txt | 16 - tox.ini | 42 - 59 files changed, 13 insertions(+), 4313 deletions(-) delete mode 100644 .coveragerc delete mode 100644 .gitignore delete mode 100644 .gitreview delete mode 100644 .mailmap delete mode 100644 .testr.conf delete mode 100644 CONTRIBUTING.rst delete mode 100644 HACKING.rst delete mode 100644 LICENSE delete mode 100644 README.rst create mode 100644 README.txt delete mode 100644 babel.cfg delete mode 100644 doc/source/api/fixture.lockutils.rst delete mode 100644 doc/source/api/index.rst delete mode 100644 doc/source/api/lockutils.rst delete mode 100644 doc/source/api/opts.rst delete mode 100644 doc/source/api/processutils.rst delete mode 100644 doc/source/api/watchdog.rst delete mode 100755 doc/source/conf.py delete mode 100644 doc/source/contributing.rst delete mode 100644 doc/source/history.rst delete mode 100644 doc/source/index.rst delete mode 100644 doc/source/installation.rst delete mode 100644 doc/source/opts.rst delete mode 100644 doc/source/usage.rst delete mode 100644 oslo_concurrency/__init__.py delete mode 100644 oslo_concurrency/_i18n.py delete mode 100644 oslo_concurrency/fixture/__init__.py delete mode 100644 oslo_concurrency/fixture/lockutils.py delete mode 100644 oslo_concurrency/locale/de/LC_MESSAGES/oslo_concurrency-log-info.po delete mode 100644 oslo_concurrency/locale/de/LC_MESSAGES/oslo_concurrency.po delete mode 100644 oslo_concurrency/locale/en_GB/LC_MESSAGES/oslo_concurrency-log-info.po delete mode 100644 oslo_concurrency/locale/en_GB/LC_MESSAGES/oslo_concurrency.po delete mode 100644 oslo_concurrency/locale/es/LC_MESSAGES/oslo_concurrency-log-info.po delete mode 100644 oslo_concurrency/locale/es/LC_MESSAGES/oslo_concurrency.po delete mode 100644 oslo_concurrency/locale/fr/LC_MESSAGES/oslo_concurrency-log-info.po delete mode 100644 oslo_concurrency/locale/fr/LC_MESSAGES/oslo_concurrency.po delete mode 100644 oslo_concurrency/lockutils.py delete mode 100644 oslo_concurrency/opts.py delete mode 100644 oslo_concurrency/prlimit.py delete mode 100644 oslo_concurrency/processutils.py delete mode 100644 oslo_concurrency/tests/__init__.py delete mode 100644 oslo_concurrency/tests/unit/__init__.py delete mode 100644 oslo_concurrency/tests/unit/test_lockutils.py delete mode 100644 oslo_concurrency/tests/unit/test_lockutils_eventlet.py delete mode 100644 oslo_concurrency/tests/unit/test_processutils.py delete mode 100644 oslo_concurrency/version.py delete mode 100644 oslo_concurrency/watchdog.py delete mode 100644 releasenotes/notes/add_reno-3b4ae0789e9c45b4.yaml delete mode 100644 releasenotes/source/_static/.placeholder delete mode 100644 releasenotes/source/_templates/.placeholder delete mode 100644 releasenotes/source/conf.py delete mode 100644 releasenotes/source/index.rst delete mode 100644 releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po delete mode 100644 releasenotes/source/unreleased.rst delete mode 100644 requirements.txt delete mode 100644 setup.cfg delete mode 100644 setup.py delete mode 100644 test-requirements.txt delete mode 100644 tox.ini diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 4ed8f62..0000000 --- a/.coveragerc +++ /dev/null @@ -1,8 +0,0 @@ -[run] -branch = True -source = oslo_concurrency -omit = oslo_concurrency/tests/* - -[report] -ignore_errors = True -precision = 2 diff --git a/.gitignore b/.gitignore deleted file mode 100644 index baab79c..0000000 --- a/.gitignore +++ /dev/null @@ -1,55 +0,0 @@ -*.py[cod] - -# C extensions -*.so - -# Packages -*.egg -*.egg-info -dist -build -eggs -parts -bin -var -sdist -develop-eggs -.installed.cfg -lib -lib64 - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -.coverage -cover -.tox -nosetests.xml -.testrepository - -# Translations -*.mo - -# Mr Developer -.mr.developer.cfg -.project -.pydevproject - -# Complexity -output/*.html -output/*/index.html - -# Sphinx -doc/build - -# pbr generates these -AUTHORS -ChangeLog - -# Editors -*~ -.*.swp - -# reno build -releasenotes/build diff --git a/.gitreview b/.gitreview deleted file mode 100644 index 7e4b4bb..0000000 --- a/.gitreview +++ /dev/null @@ -1,4 +0,0 @@ -[gerrit] -host=review.openstack.org -port=29418 -project=openstack/oslo.concurrency.git \ No newline at end of file diff --git a/.mailmap b/.mailmap deleted file mode 100644 index cc92f17..0000000 --- a/.mailmap +++ /dev/null @@ -1,3 +0,0 @@ -# Format is: -# -# \ No newline at end of file diff --git a/.testr.conf b/.testr.conf deleted file mode 100644 index fb62267..0000000 --- a/.testr.conf +++ /dev/null @@ -1,7 +0,0 @@ -[DEFAULT] -test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ - OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ - OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \ - ${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION -test_id_option=--load-list $IDFILE -test_list_option=--list \ No newline at end of file diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst deleted file mode 100644 index c4506f7..0000000 --- a/CONTRIBUTING.rst +++ /dev/null @@ -1,16 +0,0 @@ -If you would like to contribute to the development of OpenStack, -you must follow the steps in this page: - - http://docs.openstack.org/infra/manual/developers.html - -Once those steps have been completed, changes to OpenStack -should be submitted for review via the Gerrit tool, following -the workflow documented at: - - http://docs.openstack.org/infra/manual/developers.html#development-workflow - -Pull requests submitted through GitHub will be ignored. - -Bugs should be filed on Launchpad, not GitHub: - - https://bugs.launchpad.net/oslo.concurrency diff --git a/HACKING.rst b/HACKING.rst deleted file mode 100644 index d68115a..0000000 --- a/HACKING.rst +++ /dev/null @@ -1,4 +0,0 @@ -oslo.concurrency Style Commandments -====================================================== - -Read the OpenStack Style Commandments http://docs.openstack.org/developer/hacking/ \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 67db858..0000000 --- a/LICENSE +++ /dev/null @@ -1,175 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. diff --git a/README.rst b/README.rst deleted file mode 100644 index d0b3b59..0000000 --- a/README.rst +++ /dev/null @@ -1,20 +0,0 @@ -================== - oslo.concurrency -================== - -.. image:: https://img.shields.io/pypi/v/oslo.concurrency.svg - :target: https://pypi.python.org/pypi/oslo.concurrency/ - :alt: Latest Version - -.. image:: https://img.shields.io/pypi/dm/oslo.concurrency.svg - :target: https://pypi.python.org/pypi/oslo.concurrency/ - :alt: Downloads - -The oslo.concurrency library has utilities for safely running multi-thread, -multi-process applications using locking mechanisms and for running -external processes. - -* Free software: Apache license -* Documentation: http://docs.openstack.org/developer/oslo.concurrency -* Source: http://git.openstack.org/cgit/openstack/oslo.concurrency -* Bugs: http://bugs.launchpad.net/oslo.concurrency diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..4dd4d0e --- /dev/null +++ b/README.txt @@ -0,0 +1,13 @@ +This project is no longer maintained. + +The contents of this repository are still available in the Git +source code management system. To see the contents of this +repository before it reached its end of life, please check out the +previous commit with "git checkout HEAD^1". + +Use instead the project deb-python-oslo.concurrency at +http://git.openstack.org/cgit/openstack/deb-python-oslo.concurrency . + +For any further questions, please email +openstack-dev@lists.openstack.org or join #openstack-dev on +Freenode. diff --git a/babel.cfg b/babel.cfg deleted file mode 100644 index efceab8..0000000 --- a/babel.cfg +++ /dev/null @@ -1 +0,0 @@ -[python: **.py] diff --git a/doc/source/api/fixture.lockutils.rst b/doc/source/api/fixture.lockutils.rst deleted file mode 100644 index 8f82f40..0000000 --- a/doc/source/api/fixture.lockutils.rst +++ /dev/null @@ -1,8 +0,0 @@ -=========================================== - :mod:`oslo_concurrency.fixture.lockutils` -=========================================== - -.. automodule:: oslo_concurrency.fixture.lockutils - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/source/api/index.rst b/doc/source/api/index.rst deleted file mode 100644 index 2ee39d8..0000000 --- a/doc/source/api/index.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. toctree:: - :maxdepth: 1 - - fixture.lockutils - lockutils - opts - processutils - watchdog diff --git a/doc/source/api/lockutils.rst b/doc/source/api/lockutils.rst deleted file mode 100644 index 76a37fa..0000000 --- a/doc/source/api/lockutils.rst +++ /dev/null @@ -1,8 +0,0 @@ -=================================== - :mod:`oslo_concurrency.lockutils` -=================================== - -.. automodule:: oslo_concurrency.lockutils - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/source/api/opts.rst b/doc/source/api/opts.rst deleted file mode 100644 index 8972b27..0000000 --- a/doc/source/api/opts.rst +++ /dev/null @@ -1,8 +0,0 @@ -============================== - :mod:`oslo_concurrency.opts` -============================== - -.. automodule:: oslo_concurrency.opts - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/source/api/processutils.rst b/doc/source/api/processutils.rst deleted file mode 100644 index 787095c..0000000 --- a/doc/source/api/processutils.rst +++ /dev/null @@ -1,8 +0,0 @@ -====================================== - :mod:`oslo_concurrency.processutils` -====================================== - -.. automodule:: oslo_concurrency.processutils - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/source/api/watchdog.rst b/doc/source/api/watchdog.rst deleted file mode 100644 index feccaeb..0000000 --- a/doc/source/api/watchdog.rst +++ /dev/null @@ -1,8 +0,0 @@ -================================== - :mod:`oslo_concurrency.watchdog` -================================== - -.. automodule:: oslo_concurrency.watchdog - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/source/conf.py b/doc/source/conf.py deleted file mode 100755 index 850bbfe..0000000 --- a/doc/source/conf.py +++ /dev/null @@ -1,80 +0,0 @@ -# -*- coding: utf-8 -*- -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import sys - - -sys.path.insert(0, os.path.abspath('../..')) -# -- General configuration ---------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [ - 'sphinx.ext.autodoc', - 'oslosphinx', - 'oslo_config.sphinxext', -] - -# autodoc generation is a bit aggressive and a nuisance when doing heavy -# text edit cycles. -# execute "export SPHINX_DEBUG=1" in your terminal to disable - -# A list of glob-style patterns that should be excluded when looking for source -# files. -exclude_patterns = [] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'oslo.concurrency' -copyright = u'2014, OpenStack Foundation' - -# If true, '()' will be appended to :func: etc. cross-reference text. -add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -add_module_names = True - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# -- Options for HTML output -------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. Major themes that come with -# Sphinx are currently 'default' and 'sphinxdoc'. -# html_theme_path = ["."] -# html_theme = '_theme' -# html_static_path = ['static'] - -# Output file base name for HTML help builder. -htmlhelp_basename = '%sdoc' % project - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass -# [howto/manual]). -latex_documents = [ - ('index', - '%s.tex' % project, - u'%s Documentation' % project, - u'OpenStack Foundation', 'manual'), -] - -# Example configuration for intersphinx: refer to the Python standard library. -# intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/doc/source/contributing.rst b/doc/source/contributing.rst deleted file mode 100644 index 2ca75d1..0000000 --- a/doc/source/contributing.rst +++ /dev/null @@ -1,5 +0,0 @@ -============== - Contributing -============== - -.. include:: ../../CONTRIBUTING.rst diff --git a/doc/source/history.rst b/doc/source/history.rst deleted file mode 100644 index 69ed4fe..0000000 --- a/doc/source/history.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../ChangeLog diff --git a/doc/source/index.rst b/doc/source/index.rst deleted file mode 100644 index 4ff4a70..0000000 --- a/doc/source/index.rst +++ /dev/null @@ -1,40 +0,0 @@ -============================================ -Welcome to oslo.concurrency's documentation! -============================================ - -The `oslo`_ concurrency library has utilities for safely running multi-thread, -multi-process applications using locking mechanisms and for running -external processes. - -.. toctree:: - :maxdepth: 1 - - installation - usage - opts - contributing - -API Documentation -================= - -.. toctree:: - :maxdepth: 1 - - api/index - -Release Notes -============= - -.. toctree:: - :maxdepth: 1 - - history - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _oslo: https://wiki.openstack.org/wiki/Oslo diff --git a/doc/source/installation.rst b/doc/source/installation.rst deleted file mode 100644 index 0f63912..0000000 --- a/doc/source/installation.rst +++ /dev/null @@ -1,12 +0,0 @@ -============ -Installation -============ - -At the command line:: - - $ pip install oslo.concurrency - -Or, if you have virtualenvwrapper installed:: - - $ mkvirtualenv oslo.concurrency - $ pip install oslo.concurrency \ No newline at end of file diff --git a/doc/source/opts.rst b/doc/source/opts.rst deleted file mode 100644 index 27ee4fb..0000000 --- a/doc/source/opts.rst +++ /dev/null @@ -1,8 +0,0 @@ -======================= - Configuration Options -======================= - -oslo.concurrency uses oslo.config to define and manage configuration options -to allow the deployer to control how an application uses this library. - -.. show-options:: oslo.concurrency diff --git a/doc/source/usage.rst b/doc/source/usage.rst deleted file mode 100644 index dd8ba98..0000000 --- a/doc/source/usage.rst +++ /dev/null @@ -1,74 +0,0 @@ -======= - Usage -======= - -To use oslo.concurrency in a project, import the relevant module. For -example:: - - from oslo_concurrency import lockutils - from oslo_concurrency import processutils - -.. seealso:: - - * :doc:`API Documentation ` - -Locking a function (local to a process) -======================================= - -To ensure that a function (which is not thread safe) is only used in -a thread safe manner (typically such type of function should be refactored -to avoid this problem but if not then the following can help):: - - @lockutils.synchronized('not_thread_safe') - def not_thread_safe(): - pass - -Once decorated later callers of this function will be able to call into -this method and the contract that two threads will **not** enter this -function at the same time will be upheld. Make sure that the names of the -locks used are carefully chosen (typically by namespacing them to your -app so that other apps will not chose the same names). - -Locking a function (local to a process as well as across process) -================================================================= - -To ensure that a function (which is not thread safe **or** multi-process -safe) is only used in a safe manner (typically such type of function should -be refactored to avoid this problem but if not then the following can help):: - - @lockutils.synchronized('not_thread_process_safe', external=True) - def not_thread_process_safe(): - pass - -Once decorated later callers of this function will be able to call into -this method and the contract that two threads (or any two processes) -will **not** enter this function at the same time will be upheld. Make -sure that the names of the locks used are carefully chosen (typically by -namespacing them to your app so that other apps will not chose the same -names). - -Common ways to prefix/namespace the synchronized decorator -========================================================== - -Since it is **highly** recommended to prefix (or namespace) the usage -of the synchronized there are a few helpers that can make this much easier -to achieve. - -An example is:: - - myapp_synchronized = lockutils.synchronized_with_prefix("myapp") - -Then further usage of the ``lockutils.synchronized`` would instead now use -this decorator created above instead of using ``lockutils.synchronized`` -directly. - -Command Line Wrapper -==================== - -``oslo.concurrency`` includes a command line tool for use in test jobs -that need the environment variable :envvar:`OSLO_LOCK_PATH` set. To -use it, prefix the command to be run with -:command:`lockutils-wrapper`. For example:: - - $ lockutils-wrapper env | grep OSLO_LOCK_PATH - OSLO_LOCK_PATH=/tmp/tmpbFHK45 diff --git a/oslo_concurrency/__init__.py b/oslo_concurrency/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oslo_concurrency/_i18n.py b/oslo_concurrency/_i18n.py deleted file mode 100644 index 7524106..0000000 --- a/oslo_concurrency/_i18n.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2014 Mirantis 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 oslo_i18n - -_translators = oslo_i18n.TranslatorFactory(domain='oslo_concurrency') - -# The primary translation function using the well-known name "_" -_ = _translators.primary - -# Translators for log levels. -# -# The abbreviated names are meant to reflect the usual use of a short -# name like '_'. The "L" is for "log" and the other letter comes from -# the level. -_LI = _translators.log_info -_LW = _translators.log_warning -_LE = _translators.log_error -_LC = _translators.log_critical diff --git a/oslo_concurrency/fixture/__init__.py b/oslo_concurrency/fixture/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oslo_concurrency/fixture/lockutils.py b/oslo_concurrency/fixture/lockutils.py deleted file mode 100644 index e53816d..0000000 --- a/oslo_concurrency/fixture/lockutils.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright 2011 OpenStack Foundation. -# 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 fixtures -from oslo_config import fixture as config - -from oslo_concurrency import lockutils - - -class LockFixture(fixtures.Fixture): - """External locking fixture. - - This fixture is basically an alternative to the synchronized decorator with - the external flag so that tearDowns and addCleanups will be included in - the lock context for locking between tests. The fixture is recommended to - be the first line in a test method, like so:: - - def test_method(self): - self.useFixture(LockFixture('lock_name')) - ... - - or the first line in setUp if all the test methods in the class are - required to be serialized. Something like:: - - class TestCase(testtools.testcase): - def setUp(self): - self.useFixture(LockFixture('lock_name')) - super(TestCase, self).setUp() - ... - - This is because addCleanups are put on a LIFO queue that gets run after the - test method exits. (either by completing or raising an exception) - """ - def __init__(self, name, lock_file_prefix=None): - self.mgr = lockutils.lock(name, lock_file_prefix, True) - - def setUp(self): - super(LockFixture, self).setUp() - self.addCleanup(self.mgr.__exit__, None, None, None) - self.lock = self.mgr.__enter__() - - -class ExternalLockFixture(fixtures.Fixture): - """Configure lock_path so external locks can be used in unit tests. - - Creates a temporary directory to hold file locks and sets the oslo.config - lock_path opt to use it. This can be used to enable external locking - on a per-test basis, rather than globally with the OSLO_LOCK_PATH - environment variable. - - Example:: - - def test_method(self): - self.useFixture(ExternalLockFixture()) - something_that_needs_external_locks() - - Alternatively, the useFixture call could be placed in a test class's - setUp method to provide this functionality to all tests in the class. - - .. versionadded:: 0.3 - """ - def setUp(self): - super(ExternalLockFixture, self).setUp() - temp_dir = self.useFixture(fixtures.TempDir()) - conf = self.useFixture(config.Config(lockutils.CONF)).config - conf(lock_path=temp_dir.path, group='oslo_concurrency') diff --git a/oslo_concurrency/locale/de/LC_MESSAGES/oslo_concurrency-log-info.po b/oslo_concurrency/locale/de/LC_MESSAGES/oslo_concurrency-log-info.po deleted file mode 100644 index effcd0d..0000000 --- a/oslo_concurrency/locale/de/LC_MESSAGES/oslo_concurrency-log-info.po +++ /dev/null @@ -1,19 +0,0 @@ -# Andreas Jaeger , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.concurrency 3.9.1.dev2\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-06-04 05:27+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2016-06-02 07:05+0000\n" -"Last-Translator: Andreas Jaeger \n" -"Language-Team: German\n" -"Language: de\n" -"X-Generator: Zanata 3.7.3\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -#, python-format -msgid "Failed to remove file %(file)s" -msgstr "Fehler beim Entfernen der Datei %(file)s" diff --git a/oslo_concurrency/locale/de/LC_MESSAGES/oslo_concurrency.po b/oslo_concurrency/locale/de/LC_MESSAGES/oslo_concurrency.po deleted file mode 100644 index 58dfce3..0000000 --- a/oslo_concurrency/locale/de/LC_MESSAGES/oslo_concurrency.po +++ /dev/null @@ -1,101 +0,0 @@ -# Translations template for oslo.concurrency. -# Copyright (C) 2015 ORGANIZATION -# This file is distributed under the same license as the oslo.concurrency -# project. -# -# Translators: -# Christian Berendt , 2014 -# Ettore Atalan , 2014 -# Andreas Jaeger , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.concurrency 3.9.1.dev3\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-06-07 17:48+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2016-06-08 06:36+0000\n" -"Last-Translator: Andreas Jaeger \n" -"Language: de\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"Generated-By: Babel 2.0\n" -"X-Generator: Zanata 3.7.3\n" -"Language-Team: German\n" - -#, python-format -msgid "" -"%(desc)r\n" -"command: %(cmd)r\n" -"exit code: %(code)r\n" -"stdout: %(stdout)r\n" -"stderr: %(stderr)r" -msgstr "" -"%(desc)r\n" -"Kommando: %(cmd)r\n" -"Abschlusscode: %(code)r\n" -"Stdout: %(stdout)r\n" -"Stderr: %(stderr)r" - -#, python-format -msgid "" -"%(description)s\n" -"Command: %(cmd)s\n" -"Exit code: %(exit_code)s\n" -"Stdout: %(stdout)r\n" -"Stderr: %(stderr)r" -msgstr "" -"%(description)s\n" -"Befehl: %(cmd)s.\n" -"Beendigungscode: %(exit_code)s.\n" -"Standardausgabe: %(stdout)r\n" -"Standardfehler: %(stderr)r" - -#, python-format -msgid "%r failed. Not Retrying." -msgstr "%r fehlgeschlagen. Wird nicht wiederholt." - -#, python-format -msgid "%r failed. Retrying." -msgstr "%r fehlgeschlagen. Neuversuch." - -msgid "" -"Calling lockutils directly is no longer supported. Please use the lockutils-" -"wrapper console script instead." -msgstr "" -"Ein direkter Aufruf von lockutils wird nicht mehr unterstützt. Verwenden Sie " -"stattdessen das lockutils-wrapper Konsolescript." - -msgid "Command requested root, but did not specify a root helper." -msgstr "Kommando braucht root, es wurde aber kein root helper spezifiziert." - -msgid "Environment not supported over SSH" -msgstr "Umgebung wird nicht über SSH unterstützt" - -#, python-format -msgid "" -"Got an OSError\n" -"command: %(cmd)r\n" -"errno: %(errno)r" -msgstr "" -"OS Fehler aufgetreten:\n" -"Kommando: %(cmd)r\n" -"Fehlernummer: %(errno)r" - -#, python-format -msgid "Got invalid arg log_errors: %r" -msgstr "Ungültiges Argument für log_errors: %r" - -#, python-format -msgid "Got unknown keyword args: %r" -msgstr "Ungültige Schlüsswelwortargumente: %r" - -#, python-format -msgid "Running cmd (subprocess): %s" -msgstr "Führe Kommando (subprocess) aus: %s" - -msgid "Unexpected error while running command." -msgstr "Unerwarteter Fehler bei der Ausführung des Kommandos." - -msgid "process_input not supported over SSH" -msgstr "process_input wird nicht über SSH unterstützt" diff --git a/oslo_concurrency/locale/en_GB/LC_MESSAGES/oslo_concurrency-log-info.po b/oslo_concurrency/locale/en_GB/LC_MESSAGES/oslo_concurrency-log-info.po deleted file mode 100644 index 13d651c..0000000 --- a/oslo_concurrency/locale/en_GB/LC_MESSAGES/oslo_concurrency-log-info.po +++ /dev/null @@ -1,27 +0,0 @@ -# Translations template for oslo.concurrency. -# Copyright (C) 2015 ORGANIZATION -# This file is distributed under the same license as the oslo.concurrency -# project. -# -# Translators: -# Andi Chandler , 2014 -# Andreas Jaeger , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.concurrency 3.6.1.dev10\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-04-19 12:20+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2015-06-10 11:06+0000\n" -"Last-Translator: openstackjenkins \n" -"Language: en-GB\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"Generated-By: Babel 2.0\n" -"X-Generator: Zanata 3.7.3\n" -"Language-Team: English (United Kingdom)\n" - -#, python-format -msgid "Failed to remove file %(file)s" -msgstr "Failed to remove file %(file)s" diff --git a/oslo_concurrency/locale/en_GB/LC_MESSAGES/oslo_concurrency.po b/oslo_concurrency/locale/en_GB/LC_MESSAGES/oslo_concurrency.po deleted file mode 100644 index ec764d4..0000000 --- a/oslo_concurrency/locale/en_GB/LC_MESSAGES/oslo_concurrency.po +++ /dev/null @@ -1,100 +0,0 @@ -# Translations template for oslo.concurrency. -# Copyright (C) 2015 ORGANIZATION -# This file is distributed under the same license as the oslo.concurrency -# project. -# -# Translators: -# Andi Chandler , 2014-2015 -# Andreas Jaeger , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.concurrency 3.6.1.dev10\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-04-19 12:20+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2015-06-10 11:06+0000\n" -"Last-Translator: openstackjenkins \n" -"Language: en-GB\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"Generated-By: Babel 2.0\n" -"X-Generator: Zanata 3.7.3\n" -"Language-Team: English (United Kingdom)\n" - -#, python-format -msgid "" -"%(desc)r\n" -"command: %(cmd)r\n" -"exit code: %(code)r\n" -"stdout: %(stdout)r\n" -"stderr: %(stderr)r" -msgstr "" -"%(desc)r\n" -"command: %(cmd)r\n" -"exit code: %(code)r\n" -"stdout: %(stdout)r\n" -"stderr: %(stderr)r" - -#, python-format -msgid "" -"%(description)s\n" -"Command: %(cmd)s\n" -"Exit code: %(exit_code)s\n" -"Stdout: %(stdout)r\n" -"Stderr: %(stderr)r" -msgstr "" -"%(description)s\n" -"Command: %(cmd)s\n" -"Exit code: %(exit_code)s\n" -"Stdout: %(stdout)r\n" -"Stderr: %(stderr)r" - -#, python-format -msgid "%r failed. Not Retrying." -msgstr "%r failed. Not Retrying." - -#, python-format -msgid "%r failed. Retrying." -msgstr "%r failed. Retrying." - -msgid "" -"Calling lockutils directly is no longer supported. Please use the lockutils-" -"wrapper console script instead." -msgstr "" -"Calling lockutils directly is no longer supported. Please use the lockutils-" -"wrapper console script instead." - -msgid "Command requested root, but did not specify a root helper." -msgstr "Command requested root, but did not specify a root helper." - -msgid "Environment not supported over SSH" -msgstr "Environment not supported over SSH" - -#, python-format -msgid "" -"Got an OSError\n" -"command: %(cmd)r\n" -"errno: %(errno)r" -msgstr "" -"Got an OSError\n" -"command: %(cmd)r\n" -"errno: %(errno)r" - -#, python-format -msgid "Got invalid arg log_errors: %r" -msgstr "Got invalid arg log_errors: %r" - -#, python-format -msgid "Got unknown keyword args: %r" -msgstr "Got unknown keyword args: %r" - -#, python-format -msgid "Running cmd (subprocess): %s" -msgstr "Running cmd (subprocess): %s" - -msgid "Unexpected error while running command." -msgstr "Unexpected error while running command." - -msgid "process_input not supported over SSH" -msgstr "process_input not supported over SSH" diff --git a/oslo_concurrency/locale/es/LC_MESSAGES/oslo_concurrency-log-info.po b/oslo_concurrency/locale/es/LC_MESSAGES/oslo_concurrency-log-info.po deleted file mode 100644 index 3f96f11..0000000 --- a/oslo_concurrency/locale/es/LC_MESSAGES/oslo_concurrency-log-info.po +++ /dev/null @@ -1,27 +0,0 @@ -# Translations template for oslo.concurrency. -# Copyright (C) 2015 ORGANIZATION -# This file is distributed under the same license as the oslo.concurrency -# project. -# -# Translators: -# Adriana Chisco Landazábal , 2015 -# Andreas Jaeger , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.concurrency 3.6.1.dev10\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-04-19 12:20+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2015-06-22 09:27+0000\n" -"Last-Translator: Adriana Chisco Landazábal \n" -"Language: es\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"Generated-By: Babel 2.0\n" -"X-Generator: Zanata 3.7.3\n" -"Language-Team: Spanish\n" - -#, python-format -msgid "Failed to remove file %(file)s" -msgstr "No se ha podido eliminar el fichero %(file)s" diff --git a/oslo_concurrency/locale/es/LC_MESSAGES/oslo_concurrency.po b/oslo_concurrency/locale/es/LC_MESSAGES/oslo_concurrency.po deleted file mode 100644 index bccbdd3..0000000 --- a/oslo_concurrency/locale/es/LC_MESSAGES/oslo_concurrency.po +++ /dev/null @@ -1,100 +0,0 @@ -# Translations template for oslo.concurrency. -# Copyright (C) 2015 ORGANIZATION -# This file is distributed under the same license as the oslo.concurrency -# project. -# -# Translators: -# Adriana Chisco Landazábal , 2015 -# Andreas Jaeger , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.concurrency 3.6.1.dev10\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-04-19 12:20+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2015-06-22 09:35+0000\n" -"Last-Translator: Adriana Chisco Landazábal \n" -"Language: es\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"Generated-By: Babel 2.0\n" -"X-Generator: Zanata 3.7.3\n" -"Language-Team: Spanish\n" - -#, python-format -msgid "" -"%(desc)r\n" -"command: %(cmd)r\n" -"exit code: %(code)r\n" -"stdout: %(stdout)r\n" -"stderr: %(stderr)r" -msgstr "" -"%(desc)r\n" -"comando: %(cmd)r\n" -"código de salida: %(code)r\n" -"stdout: %(stdout)r\n" -"stderr: %(stderr)r" - -#, python-format -msgid "" -"%(description)s\n" -"Command: %(cmd)s\n" -"Exit code: %(exit_code)s\n" -"Stdout: %(stdout)r\n" -"Stderr: %(stderr)r" -msgstr "" -"%(description)s\n" -"Comando: %(cmd)s\n" -"Código de salida: %(exit_code)s\n" -"Stdout: %(stdout)r\n" -"Stderr: %(stderr)r" - -#, python-format -msgid "%r failed. Not Retrying." -msgstr "%r ha fallado. No se está intentando de nuevo." - -#, python-format -msgid "%r failed. Retrying." -msgstr "%r ha fallado. Intentando de nuevo." - -msgid "" -"Calling lockutils directly is no longer supported. Please use the lockutils-" -"wrapper console script instead." -msgstr "" -"Ya no se soporta llamar LockUtil. Por favor utilice a cambio la consola " -"script lockutils-wrapper." - -msgid "Command requested root, but did not specify a root helper." -msgstr "Comando ha solicitado root, pero no especificó un auxiliar root." - -msgid "Environment not supported over SSH" -msgstr "Ambiente no soportado a través de SSH" - -#, python-format -msgid "" -"Got an OSError\n" -"command: %(cmd)r\n" -"errno: %(errno)r" -msgstr "" -"Se obtuvo error de Sistema Operativo\n" -"comando: %(cmd)r\n" -"errno: %(errno)r" - -#, python-format -msgid "Got invalid arg log_errors: %r" -msgstr "Se obtuvo argumento no válido: %r" - -#, python-format -msgid "Got unknown keyword args: %r" -msgstr "Se obtuvieron argumentos de palabra clave: %r" - -#, python-format -msgid "Running cmd (subprocess): %s" -msgstr "Ejecutando cmd (subproceso): %s" - -msgid "Unexpected error while running command." -msgstr "Error inesperado mientras se ejecutaba el comando." - -msgid "process_input not supported over SSH" -msgstr "entrada de proceso no soportada a través de SSH" diff --git a/oslo_concurrency/locale/fr/LC_MESSAGES/oslo_concurrency-log-info.po b/oslo_concurrency/locale/fr/LC_MESSAGES/oslo_concurrency-log-info.po deleted file mode 100644 index 2708bf7..0000000 --- a/oslo_concurrency/locale/fr/LC_MESSAGES/oslo_concurrency-log-info.po +++ /dev/null @@ -1,27 +0,0 @@ -# Translations template for oslo.concurrency. -# Copyright (C) 2015 ORGANIZATION -# This file is distributed under the same license as the oslo.concurrency -# project. -# -# Translators: -# Maxime COQUEREL , 2015 -# Andreas Jaeger , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.concurrency 3.6.1.dev10\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-04-19 12:20+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2015-06-10 11:06+0000\n" -"Last-Translator: openstackjenkins \n" -"Language: fr\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"Generated-By: Babel 2.0\n" -"X-Generator: Zanata 3.7.3\n" -"Language-Team: French\n" - -#, python-format -msgid "Failed to remove file %(file)s" -msgstr "Échec lors de la suppression du fichier %(file)s" diff --git a/oslo_concurrency/locale/fr/LC_MESSAGES/oslo_concurrency.po b/oslo_concurrency/locale/fr/LC_MESSAGES/oslo_concurrency.po deleted file mode 100644 index 1b53f1e..0000000 --- a/oslo_concurrency/locale/fr/LC_MESSAGES/oslo_concurrency.po +++ /dev/null @@ -1,100 +0,0 @@ -# Translations template for oslo.concurrency. -# Copyright (C) 2015 ORGANIZATION -# This file is distributed under the same license as the oslo.concurrency -# project. -# -# Translators: -# Maxime COQUEREL , 2015 -# Andreas Jaeger , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.concurrency 3.6.1.dev10\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-04-19 12:20+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2015-06-10 11:06+0000\n" -"Last-Translator: openstackjenkins \n" -"Language: fr\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"Generated-By: Babel 2.0\n" -"X-Generator: Zanata 3.7.3\n" -"Language-Team: French\n" - -#, python-format -msgid "" -"%(desc)r\n" -"command: %(cmd)r\n" -"exit code: %(code)r\n" -"stdout: %(stdout)r\n" -"stderr: %(stderr)r" -msgstr "" -"%(desc)r\n" -"commande: %(cmd)r\n" -"Code de sortie: %(code)r\n" -"stdout: %(stdout)r\n" -"stderr: %(stderr)r" - -#, python-format -msgid "" -"%(description)s\n" -"Command: %(cmd)s\n" -"Exit code: %(exit_code)s\n" -"Stdout: %(stdout)r\n" -"Stderr: %(stderr)r" -msgstr "" -"%(description)s\n" -"Commande: %(cmd)s\n" -"Code de sortie: %(exit_code)s\n" -"Stdout: %(stdout)r\n" -"Stderr: %(stderr)r" - -#, python-format -msgid "%r failed. Not Retrying." -msgstr "Echec de %r. Nouvelle tentative." - -#, python-format -msgid "%r failed. Retrying." -msgstr "Echec de %r. Nouvelle tentative." - -msgid "" -"Calling lockutils directly is no longer supported. Please use the lockutils-" -"wrapper console script instead." -msgstr "" -"Lockutils appelant directement n'est plus pris en charge. Merci d'utiliser " -"le script de la console lockutils -wrapper à la place." - -msgid "Command requested root, but did not specify a root helper." -msgstr "La commande exigeait root, mais n'indiquait pas comment obtenir root." - -msgid "Environment not supported over SSH" -msgstr "Environnement non prise en charge sur SSH" - -#, python-format -msgid "" -"Got an OSError\n" -"command: %(cmd)r\n" -"errno: %(errno)r" -msgstr "" -"Erreur du Système\n" -"commande: %(cmd)r\n" -"errno: %(errno)r" - -#, python-format -msgid "Got invalid arg log_errors: %r" -msgstr "Argument reçu non valide log_errors: %r" - -#, python-format -msgid "Got unknown keyword args: %r" -msgstr "Ags, mot clé inconnu: %r" - -#, python-format -msgid "Running cmd (subprocess): %s" -msgstr "Exécution de la commande (sous-processus): %s" - -msgid "Unexpected error while running command." -msgstr "Erreur inattendue lors de l’exécution de la commande." - -msgid "process_input not supported over SSH" -msgstr "process_input non pris en charge sur SSH" diff --git a/oslo_concurrency/lockutils.py b/oslo_concurrency/lockutils.py deleted file mode 100644 index ea67571..0000000 --- a/oslo_concurrency/lockutils.py +++ /dev/null @@ -1,371 +0,0 @@ -# Copyright 2011 OpenStack Foundation. -# 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 contextlib -import functools -import logging -import os -import shutil -import subprocess -import sys -import tempfile -import threading -import weakref - -import fasteners -from oslo_config import cfg -from oslo_utils import reflection -from oslo_utils import timeutils -import six - -from oslo_concurrency._i18n import _, _LI - - -LOG = logging.getLogger(__name__) - - -_opts = [ - cfg.BoolOpt('disable_process_locking', default=False, - help='Enables or disables inter-process locks.', - deprecated_group='DEFAULT'), - cfg.StrOpt('lock_path', - default=os.environ.get("OSLO_LOCK_PATH"), - help='Directory to use for lock files. For security, the ' - 'specified directory should only be writable by the user ' - 'running the processes that need locking. ' - 'Defaults to environment variable OSLO_LOCK_PATH. ' - 'If external locks are used, a lock path must be set.', - deprecated_group='DEFAULT') -] - - -def _register_opts(conf): - conf.register_opts(_opts, group='oslo_concurrency') - - -CONF = cfg.CONF -_register_opts(CONF) - - -def set_defaults(lock_path): - """Set value for lock_path. - - This can be used by tests to set lock_path to a temporary directory. - """ - cfg.set_defaults(_opts, lock_path=lock_path) - - -def get_lock_path(conf): - """Return the path used for external file-based locks. - - :param conf: Configuration object - :type conf: oslo_config.cfg.ConfigOpts - - .. versionadded:: 1.8 - """ - _register_opts(conf) - return conf.oslo_concurrency.lock_path - - -InterProcessLock = fasteners.InterProcessLock -ReaderWriterLock = fasteners.ReaderWriterLock -"""A reader/writer lock. - -.. versionadded:: 0.4 -""" - - -class Semaphores(object): - """A garbage collected container of semaphores. - - This collection internally uses a weak value dictionary so that when a - semaphore is no longer in use (by any threads) it will automatically be - removed from this container by the garbage collector. - - .. versionadded:: 0.3 - """ - - def __init__(self): - self._semaphores = weakref.WeakValueDictionary() - self._lock = threading.Lock() - - def get(self, name): - """Gets (or creates) a semaphore with a given name. - - :param name: The semaphore name to get/create (used to associate - previously created names with the same semaphore). - - Returns an newly constructed semaphore (or an existing one if it was - already created for the given name). - """ - with self._lock: - try: - return self._semaphores[name] - except KeyError: - sem = threading.Semaphore() - self._semaphores[name] = sem - return sem - - def __len__(self): - """Returns how many semaphores exist at the current time.""" - return len(self._semaphores) - - -_semaphores = Semaphores() - - -def _get_lock_path(name, lock_file_prefix, lock_path=None): - # NOTE(mikal): the lock name cannot contain directory - # separators - name = name.replace(os.sep, '_') - if lock_file_prefix: - sep = '' if lock_file_prefix.endswith('-') else '-' - name = '%s%s%s' % (lock_file_prefix, sep, name) - - local_lock_path = lock_path or CONF.oslo_concurrency.lock_path - - if not local_lock_path: - raise cfg.RequiredOptError('lock_path') - - return os.path.join(local_lock_path, name) - - -def external_lock(name, lock_file_prefix=None, lock_path=None): - lock_file_path = _get_lock_path(name, lock_file_prefix, lock_path) - - return InterProcessLock(lock_file_path) - - -def remove_external_lock_file(name, lock_file_prefix=None, lock_path=None, - semaphores=None): - """Remove an external lock file when it's not used anymore - This will be helpful when we have a lot of lock files - """ - with internal_lock(name, semaphores=semaphores): - lock_file_path = _get_lock_path(name, lock_file_prefix, lock_path) - try: - os.remove(lock_file_path) - except OSError: - LOG.info(_LI('Failed to remove file %(file)s'), - {'file': lock_file_path}) - - -def internal_lock(name, semaphores=None): - if semaphores is None: - semaphores = _semaphores - return semaphores.get(name) - - -@contextlib.contextmanager -def lock(name, lock_file_prefix=None, external=False, lock_path=None, - do_log=True, semaphores=None, delay=0.01): - """Context based lock - - This function yields a `threading.Semaphore` instance (if we don't use - eventlet.monkey_patch(), else `semaphore.Semaphore`) unless external is - True, in which case, it'll yield an InterProcessLock instance. - - :param lock_file_prefix: The lock_file_prefix argument is used to provide - lock files on disk with a meaningful prefix. - - :param external: The external keyword argument denotes whether this lock - should work across multiple processes. This means that if two different - workers both run a method decorated with @synchronized('mylock', - external=True), only one of them will execute at a time. - - :param lock_path: The path in which to store external lock files. For - external locking to work properly, this must be the same for all - references to the lock. - - :param do_log: Whether to log acquire/release messages. This is primarily - intended to reduce log message duplication when `lock` is used from the - `synchronized` decorator. - - :param semaphores: Container that provides semaphores to use when locking. - This ensures that threads inside the same application can not collide, - due to the fact that external process locks are unaware of a processes - active threads. - - :param delay: Delay between acquisition attempts (in seconds). - - .. versionchanged:: 0.2 - Added *do_log* optional parameter. - - .. versionchanged:: 0.3 - Added *delay* and *semaphores* optional parameters. - """ - int_lock = internal_lock(name, semaphores=semaphores) - with int_lock: - if do_log: - LOG.debug('Acquired semaphore "%(lock)s"', {'lock': name}) - try: - if external and not CONF.oslo_concurrency.disable_process_locking: - ext_lock = external_lock(name, lock_file_prefix, lock_path) - ext_lock.acquire(delay=delay) - try: - yield ext_lock - finally: - ext_lock.release() - else: - yield int_lock - finally: - if do_log: - LOG.debug('Releasing semaphore "%(lock)s"', {'lock': name}) - - -def synchronized(name, lock_file_prefix=None, external=False, lock_path=None, - semaphores=None, delay=0.01): - """Synchronization decorator. - - Decorating a method like so:: - - @synchronized('mylock') - def foo(self, *args): - ... - - ensures that only one thread will execute the foo method at a time. - - Different methods can share the same lock:: - - @synchronized('mylock') - def foo(self, *args): - ... - - @synchronized('mylock') - def bar(self, *args): - ... - - This way only one of either foo or bar can be executing at a time. - - .. versionchanged:: 0.3 - Added *delay* and *semaphores* optional parameter. - """ - - def wrap(f): - - @six.wraps(f) - def inner(*args, **kwargs): - t1 = timeutils.now() - t2 = None - try: - with lock(name, lock_file_prefix, external, lock_path, - do_log=False, semaphores=semaphores, delay=delay): - t2 = timeutils.now() - LOG.debug('Lock "%(name)s" acquired by "%(function)s" :: ' - 'waited %(wait_secs)0.3fs', - {'name': name, - 'function': reflection.get_callable_name(f), - 'wait_secs': (t2 - t1)}) - return f(*args, **kwargs) - finally: - t3 = timeutils.now() - if t2 is None: - held_secs = "N/A" - else: - held_secs = "%0.3fs" % (t3 - t2) - LOG.debug('Lock "%(name)s" released by "%(function)s" :: held ' - '%(held_secs)s', - {'name': name, - 'function': reflection.get_callable_name(f), - 'held_secs': held_secs}) - return inner - - return wrap - - -def synchronized_with_prefix(lock_file_prefix): - """Partial object generator for the synchronization decorator. - - Redefine @synchronized in each project like so:: - - (in nova/utils.py) - from oslo_concurrency import lockutils - - synchronized = lockutils.synchronized_with_prefix('nova-') - - - (in nova/foo.py) - from nova import utils - - @utils.synchronized('mylock') - def bar(self, *args): - ... - - The lock_file_prefix argument is used to provide lock files on disk with a - meaningful prefix. - """ - - return functools.partial(synchronized, lock_file_prefix=lock_file_prefix) - - -def remove_external_lock_file_with_prefix(lock_file_prefix): - """Partial object generator for the remove lock file function. - - Redefine remove_external_lock_file_with_prefix in each project like so:: - - (in nova/utils.py) - from oslo_concurrency import lockutils - - synchronized = lockutils.synchronized_with_prefix('nova-') - synchronized_remove = lockutils.remove_external_lock_file_with_prefix( - 'nova-') - - (in nova/foo.py) - from nova import utils - - @utils.synchronized('mylock') - def bar(self, *args): - ... - - - - The lock_file_prefix argument is used to provide lock files on disk with a - meaningful prefix. - """ - return functools.partial(remove_external_lock_file, - lock_file_prefix=lock_file_prefix) - - -def _lock_wrapper(argv): - """Create a dir for locks and pass it to command from arguments - - This is exposed as a console script entry point named - lockutils-wrapper - - If you run this: - lockutils-wrapper python setup.py testr - - a temporary directory will be created for all your locks and passed to all - your tests in an environment variable. The temporary dir will be deleted - afterwards and the return value will be preserved. - """ - - lock_dir = tempfile.mkdtemp() - os.environ["OSLO_LOCK_PATH"] = lock_dir - try: - ret_val = subprocess.call(argv[1:]) - finally: - shutil.rmtree(lock_dir, ignore_errors=True) - return ret_val - - -def main(): - sys.exit(_lock_wrapper(sys.argv)) - - -if __name__ == '__main__': - raise NotImplementedError(_('Calling lockutils directly is no longer ' - 'supported. Please use the ' - 'lockutils-wrapper console script instead.')) diff --git a/oslo_concurrency/opts.py b/oslo_concurrency/opts.py deleted file mode 100644 index 8189ab4..0000000 --- a/oslo_concurrency/opts.py +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2014 Red Hat, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -__all__ = [ - 'list_opts', -] - - -import copy - -from oslo_concurrency import lockutils - - -def list_opts(): - """Return a list of oslo.config options available in the library. - - The returned list includes all oslo.config options which may be registered - at runtime by the library. - - Each element of the list is a tuple. The first element is the name of the - group under which the list of elements in the second element will be - registered. A group name of None corresponds to the [DEFAULT] group in - config files. - - This function is also discoverable via the 'oslo_concurrency' entry point - under the 'oslo.config.opts' namespace. - - The purpose of this is to allow tools like the Oslo sample config file - generator to discover the options exposed to users by this library. - - :returns: a list of (group_name, opts) tuples - """ - return [('oslo_concurrency', copy.deepcopy(lockutils._opts))] diff --git a/oslo_concurrency/prlimit.py b/oslo_concurrency/prlimit.py deleted file mode 100644 index e0fc4e3..0000000 --- a/oslo_concurrency/prlimit.py +++ /dev/null @@ -1,110 +0,0 @@ -# Copyright 2016 Red Hat. -# 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 __future__ import print_function - -import argparse -import os -import resource -import sys - -USAGE_PROGRAM = ('%s -m oslo_concurrency.prlimit' - % os.path.basename(sys.executable)) - -RESOURCES = ( - # argparse argument => resource - ('as', resource.RLIMIT_AS), - ('core', resource.RLIMIT_CORE), - ('cpu', resource.RLIMIT_CPU), - ('data', resource.RLIMIT_DATA), - ('fsize', resource.RLIMIT_FSIZE), - ('memlock', resource.RLIMIT_MEMLOCK), - ('nofile', resource.RLIMIT_NOFILE), - ('nproc', resource.RLIMIT_NPROC), - ('rss', resource.RLIMIT_RSS), - ('stack', resource.RLIMIT_STACK), -) - - -def parse_args(): - parser = argparse.ArgumentParser(description='prlimit', prog=USAGE_PROGRAM) - parser.add_argument('--as', type=int, - help='Address space limit in bytes') - parser.add_argument('--core', type=int, - help='Core file size limit in bytes') - parser.add_argument('--cpu', type=int, - help='CPU time limit in seconds') - parser.add_argument('--data', type=int, - help='Data size limit in bytes') - parser.add_argument('--fsize', type=int, - help='File size limit in bytes') - parser.add_argument('--memlock', type=int, - help='Locked memory limit in bytes') - parser.add_argument('--nofile', type=int, - help='Maximum number of open files') - parser.add_argument('--nproc', type=int, - help='Maximum number of processes') - parser.add_argument('--rss', type=int, - help='Maximum Resident Set Size (RSS) in bytes') - parser.add_argument('--stack', type=int, - help='Stack size limit in bytes') - parser.add_argument('program', - help='Program (absolute path)') - parser.add_argument('program_args', metavar="arg", nargs='...', - help='Program parameters') - - args = parser.parse_args() - return args - - -def main(): - args = parse_args() - - program = args.program - if not os.path.isabs(program): - # program uses a relative path: try to find the absolute path - # to the executable - if sys.version_info >= (3, 3): - import shutil - program_abs = shutil.which(program) - else: - import distutils.spawn - program_abs = distutils.spawn.find_executable(program) - if program_abs: - program = program_abs - - for arg_name, rlimit in RESOURCES: - value = getattr(args, arg_name) - if value is None: - continue - try: - resource.setrlimit(rlimit, (value, value)) - except ValueError as exc: - print("%s: failed to set the %s resource limit: %s" - % (USAGE_PROGRAM, arg_name.upper(), exc), - file=sys.stderr) - sys.exit(1) - - try: - os.execv(program, [program] + args.program_args) - except Exception as exc: - print("%s: failed to execute %s: %s" - % (USAGE_PROGRAM, program, exc), - file=sys.stderr) - sys.exit(1) - - -if __name__ == "__main__": - main() diff --git a/oslo_concurrency/processutils.py b/oslo_concurrency/processutils.py deleted file mode 100644 index 808ae2a..0000000 --- a/oslo_concurrency/processutils.py +++ /dev/null @@ -1,542 +0,0 @@ -# Copyright 2011 OpenStack Foundation. -# 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 functools -import logging -import multiprocessing -import os -import random -import shlex -import signal -import sys -import time - -import enum -from oslo_utils import importutils -from oslo_utils import strutils -from oslo_utils import timeutils -import six - -from oslo_concurrency._i18n import _ - - -# NOTE(bnemec): eventlet doesn't monkey patch subprocess, so we need to -# determine the proper subprocess module to use ourselves. I'm using the -# time module as the check because that's a monkey patched module we use -# in combination with subprocess below, so they need to match. -eventlet = importutils.try_import('eventlet') -if eventlet and eventlet.patcher.is_monkey_patched(time): - from eventlet.green import subprocess -else: - import subprocess - - -LOG = logging.getLogger(__name__) - - -class InvalidArgumentError(Exception): - def __init__(self, message=None): - super(InvalidArgumentError, self).__init__(message) - - -class UnknownArgumentError(Exception): - def __init__(self, message=None): - super(UnknownArgumentError, self).__init__(message) - - -class ProcessExecutionError(Exception): - def __init__(self, stdout=None, stderr=None, exit_code=None, cmd=None, - description=None): - super(ProcessExecutionError, self).__init__( - stdout, stderr, exit_code, cmd, description) - self.exit_code = exit_code - self.stderr = stderr - self.stdout = stdout - self.cmd = cmd - self.description = description - - def __str__(self): - description = self.description - if description is None: - description = _("Unexpected error while running command.") - - exit_code = self.exit_code - if exit_code is None: - exit_code = '-' - - message = _('%(description)s\n' - 'Command: %(cmd)s\n' - 'Exit code: %(exit_code)s\n' - 'Stdout: %(stdout)r\n' - 'Stderr: %(stderr)r') % {'description': description, - 'cmd': self.cmd, - 'exit_code': exit_code, - 'stdout': self.stdout, - 'stderr': self.stderr} - return message - - -class NoRootWrapSpecified(Exception): - def __init__(self, message=None): - super(NoRootWrapSpecified, self).__init__(message) - - -def _subprocess_setup(on_preexec_fn): - # Python installs a SIGPIPE handler by default. This is usually not what - # non-Python subprocesses expect. - signal.signal(signal.SIGPIPE, signal.SIG_DFL) - if on_preexec_fn: - on_preexec_fn() - - -@enum.unique -class LogErrors(enum.IntEnum): - """Enumerations that affect if stdout and stderr are logged on error. - - .. versionadded:: 2.7 - """ - - #: No logging on errors. - DEFAULT = 0 - - #: Log an error on **each** occurence of an error. - ALL = 1 - - #: Log an error on the last attempt that errored **only**. - FINAL = 2 - - -# Retain these aliases for a number of releases... -LOG_ALL_ERRORS = LogErrors.ALL -LOG_FINAL_ERROR = LogErrors.FINAL -LOG_DEFAULT_ERROR = LogErrors.DEFAULT - - -class ProcessLimits(object): - """Resource limits on a process. - - Attributes: - - * address_space: Address space limit in bytes - * core_file_size: Core file size limit in bytes - * cpu_time: CPU time limit in seconds - * data_size: Data size limit in bytes - * file_size: File size limit in bytes - * memory_locked: Locked memory limit in bytes - * number_files: Maximum number of open files - * number_processes: Maximum number of processes - * resident_set_size: Maximum Resident Set Size (RSS) in bytes - * stack_size: Stack size limit in bytes - - This object can be used for the *prlimit* parameter of :func:`execute`. - """ - - _LIMITS = { - "address_space": "--as", - "core_file_size": "--core", - "cpu_time": "--cpu", - "data_size": "--data", - "file_size": "--fsize", - "memory_locked": "--memlock", - "number_files": "--nofile", - "number_processes": "--nproc", - "resident_set_size": "--rss", - "stack_size": "--stack", - } - - def __init__(self, **kw): - for limit in self._LIMITS.keys(): - setattr(self, limit, kw.pop(limit, None)) - - if kw: - raise ValueError("invalid limits: %s" - % ', '.join(sorted(kw.keys()))) - - def prlimit_args(self): - """Create a list of arguments for the prlimit command line.""" - args = [] - for limit in self._LIMITS.keys(): - val = getattr(self, limit) - if val is not None: - args.append("%s=%s" % (self._LIMITS[limit], val)) - return args - - -def execute(*cmd, **kwargs): - """Helper method to shell out and execute a command through subprocess. - - Allows optional retry. - - :param cmd: Passed to subprocess.Popen. - :type cmd: string - :param cwd: Set the current working directory - :type cwd: string - :param process_input: Send to opened process. - :type process_input: string - :param env_variables: Environment variables and their values that - will be set for the process. - :type env_variables: dict - :param check_exit_code: Single bool, int, or list of allowed exit - codes. Defaults to [0]. Raise - :class:`ProcessExecutionError` unless - program exits with one of these code. - :type check_exit_code: boolean, int, or [int] - :param delay_on_retry: True | False. Defaults to True. If set to True, - wait a short amount of time before retrying. - :type delay_on_retry: boolean - :param attempts: How many times to retry cmd. - :type attempts: int - :param run_as_root: True | False. Defaults to False. If set to True, - the command is prefixed by the command specified - in the root_helper kwarg. - :type run_as_root: boolean - :param root_helper: command to prefix to commands called with - run_as_root=True - :type root_helper: string - :param shell: whether or not there should be a shell used to - execute this command. Defaults to false. - :type shell: boolean - :param loglevel: log level for execute commands. - :type loglevel: int. (Should be logging.DEBUG or logging.INFO) - :param log_errors: Should stdout and stderr be logged on error? - Possible values are - :py:attr:`~.LogErrors.DEFAULT`, - :py:attr:`~.LogErrors.FINAL`, or - :py:attr:`~.LogErrors.ALL`. Note that the - values :py:attr:`~.LogErrors.FINAL` and - :py:attr:`~.LogErrors.ALL` - are **only** relevant when multiple attempts of - command execution are requested using the - ``attempts`` parameter. - :type log_errors: :py:class:`~.LogErrors` - :param binary: On Python 3, return stdout and stderr as bytes if - binary is True, as Unicode otherwise. - :type binary: boolean - :param on_execute: This function will be called upon process creation - with the object as a argument. The Purpose of this - is to allow the caller of `processutils.execute` to - track process creation asynchronously. - :type on_execute: function(:class:`subprocess.Popen`) - :param on_completion: This function will be called upon process - completion with the object as a argument. The - Purpose of this is to allow the caller of - `processutils.execute` to track process completion - asynchronously. - :type on_completion: function(:class:`subprocess.Popen`) - :param preexec_fn: This function will be called - in the child process just before the child - is executed. WARNING: On windows, we silently - drop this preexec_fn as it is not supported by - subprocess.Popen on windows (throws a - ValueError) - :type preexec_fn: function() - :param prlimit: Set resource limits on the child process. See - below for a detailed description. - :type prlimit: :class:`ProcessLimits` - :returns: (stdout, stderr) from process execution - :raises: :class:`UnknownArgumentError` on - receiving unknown arguments - :raises: :class:`ProcessExecutionError` - :raises: :class:`OSError` - - The *prlimit* parameter can be used to set resource limits on the child - process. If this parameter is used, the child process will be spawned by a - wrapper process which will set limits before spawning the command. - - .. versionchanged:: 3.4 - Added *prlimit* optional parameter. - - .. versionchanged:: 1.5 - Added *cwd* optional parameter. - - .. versionchanged:: 1.9 - Added *binary* optional parameter. On Python 3, *stdout* and *stdout* - are now returned as Unicode strings by default, or bytes if *binary* is - true. - - .. versionchanged:: 2.1 - Added *on_execute* and *on_completion* optional parameters. - - .. versionchanged:: 2.3 - Added *preexec_fn* optional parameter. - """ - - cwd = kwargs.pop('cwd', None) - process_input = kwargs.pop('process_input', None) - env_variables = kwargs.pop('env_variables', None) - check_exit_code = kwargs.pop('check_exit_code', [0]) - ignore_exit_code = False - delay_on_retry = kwargs.pop('delay_on_retry', True) - attempts = kwargs.pop('attempts', 1) - run_as_root = kwargs.pop('run_as_root', False) - root_helper = kwargs.pop('root_helper', '') - shell = kwargs.pop('shell', False) - loglevel = kwargs.pop('loglevel', logging.DEBUG) - log_errors = kwargs.pop('log_errors', None) - if log_errors is None: - log_errors = LogErrors.DEFAULT - binary = kwargs.pop('binary', False) - on_execute = kwargs.pop('on_execute', None) - on_completion = kwargs.pop('on_completion', None) - preexec_fn = kwargs.pop('preexec_fn', None) - prlimit = kwargs.pop('prlimit', None) - - if isinstance(check_exit_code, bool): - ignore_exit_code = not check_exit_code - check_exit_code = [0] - elif isinstance(check_exit_code, int): - check_exit_code = [check_exit_code] - - if kwargs: - raise UnknownArgumentError(_('Got unknown keyword args: %r') % kwargs) - - if isinstance(log_errors, six.integer_types): - log_errors = LogErrors(log_errors) - if not isinstance(log_errors, LogErrors): - raise InvalidArgumentError(_('Got invalid arg log_errors: %r') % - log_errors) - - if run_as_root and hasattr(os, 'geteuid') and os.geteuid() != 0: - if not root_helper: - raise NoRootWrapSpecified( - message=_('Command requested root, but did not ' - 'specify a root helper.')) - if shell: - # root helper has to be injected into the command string - cmd = [' '.join((root_helper, cmd[0]))] + list(cmd[1:]) - else: - # root helper has to be tokenized into argument list - cmd = shlex.split(root_helper) + list(cmd) - - cmd = [str(c) for c in cmd] - - if prlimit: - args = [sys.executable, '-m', 'oslo_concurrency.prlimit'] - args.extend(prlimit.prlimit_args()) - args.append('--') - args.extend(cmd) - cmd = args - - sanitized_cmd = strutils.mask_password(' '.join(cmd)) - - watch = timeutils.StopWatch() - while attempts > 0: - attempts -= 1 - watch.restart() - - try: - LOG.log(loglevel, _('Running cmd (subprocess): %s'), sanitized_cmd) - _PIPE = subprocess.PIPE # pylint: disable=E1101 - - if os.name == 'nt': - on_preexec_fn = None - close_fds = False - else: - on_preexec_fn = functools.partial(_subprocess_setup, - preexec_fn) - close_fds = True - - obj = subprocess.Popen(cmd, - stdin=_PIPE, - stdout=_PIPE, - stderr=_PIPE, - close_fds=close_fds, - preexec_fn=on_preexec_fn, - shell=shell, - cwd=cwd, - env=env_variables) - - if on_execute: - on_execute(obj) - - try: - result = obj.communicate(process_input) - - obj.stdin.close() # pylint: disable=E1101 - _returncode = obj.returncode # pylint: disable=E1101 - LOG.log(loglevel, 'CMD "%s" returned: %s in %0.3fs', - sanitized_cmd, _returncode, watch.elapsed()) - finally: - if on_completion: - on_completion(obj) - - if not ignore_exit_code and _returncode not in check_exit_code: - (stdout, stderr) = result - if six.PY3: - stdout = os.fsdecode(stdout) - stderr = os.fsdecode(stderr) - sanitized_stdout = strutils.mask_password(stdout) - sanitized_stderr = strutils.mask_password(stderr) - raise ProcessExecutionError(exit_code=_returncode, - stdout=sanitized_stdout, - stderr=sanitized_stderr, - cmd=sanitized_cmd) - if six.PY3 and not binary and result is not None: - (stdout, stderr) = result - # Decode from the locale using using the surrogateescape error - # handler (decoding cannot fail) - stdout = os.fsdecode(stdout) - stderr = os.fsdecode(stderr) - return (stdout, stderr) - else: - return result - - except (ProcessExecutionError, OSError) as err: - # if we want to always log the errors or if this is - # the final attempt that failed and we want to log that. - if log_errors == LOG_ALL_ERRORS or ( - log_errors == LOG_FINAL_ERROR and not attempts): - if isinstance(err, ProcessExecutionError): - format = _('%(desc)r\ncommand: %(cmd)r\n' - 'exit code: %(code)r\nstdout: %(stdout)r\n' - 'stderr: %(stderr)r') - LOG.log(loglevel, format, {"desc": err.description, - "cmd": err.cmd, - "code": err.exit_code, - "stdout": err.stdout, - "stderr": err.stderr}) - else: - format = _('Got an OSError\ncommand: %(cmd)r\n' - 'errno: %(errno)r') - LOG.log(loglevel, format, {"cmd": sanitized_cmd, - "errno": err.errno}) - - if not attempts: - LOG.log(loglevel, _('%r failed. Not Retrying.'), - sanitized_cmd) - raise - else: - LOG.log(loglevel, _('%r failed. Retrying.'), - sanitized_cmd) - if delay_on_retry: - time.sleep(random.randint(20, 200) / 100.0) - finally: - # NOTE(termie): this appears to be necessary to let the subprocess - # call clean something up in between calls, without - # it two execute calls in a row hangs the second one - # NOTE(bnemec): termie's comment above is probably specific to the - # eventlet subprocess module, but since we still - # have to support that we're leaving the sleep. It - # won't hurt anything in the stdlib case anyway. - time.sleep(0) - - -def trycmd(*args, **kwargs): - """A wrapper around execute() to more easily handle warnings and errors. - - Returns an (out, err) tuple of strings containing the output of - the command's stdout and stderr. If 'err' is not empty then the - command can be considered to have failed. - - :discard_warnings True | False. Defaults to False. If set to True, - then for succeeding commands, stderr is cleared - - """ - discard_warnings = kwargs.pop('discard_warnings', False) - - try: - out, err = execute(*args, **kwargs) - failed = False - except ProcessExecutionError as exn: - out, err = '', six.text_type(exn) - failed = True - - if not failed and discard_warnings and err: - # Handle commands that output to stderr but otherwise succeed - err = '' - - return out, err - - -def ssh_execute(ssh, cmd, process_input=None, - addl_env=None, check_exit_code=True, - binary=False, timeout=None): - """Run a command through SSH. - - .. versionchanged:: 1.9 - Added *binary* optional parameter. - """ - sanitized_cmd = strutils.mask_password(cmd) - LOG.debug('Running cmd (SSH): %s', sanitized_cmd) - if addl_env: - raise InvalidArgumentError(_('Environment not supported over SSH')) - - if process_input: - # This is (probably) fixable if we need it... - raise InvalidArgumentError(_('process_input not supported over SSH')) - - stdin_stream, stdout_stream, stderr_stream = ssh.exec_command( - cmd, timeout=timeout) - channel = stdout_stream.channel - - # NOTE(justinsb): This seems suspicious... - # ...other SSH clients have buffering issues with this approach - stdout = stdout_stream.read() - stderr = stderr_stream.read() - - stdin_stream.close() - - exit_status = channel.recv_exit_status() - - if six.PY3: - # Decode from the locale using using the surrogateescape error handler - # (decoding cannot fail). Decode even if binary is True because - # mask_password() requires Unicode on Python 3 - stdout = os.fsdecode(stdout) - stderr = os.fsdecode(stderr) - stdout = strutils.mask_password(stdout) - stderr = strutils.mask_password(stderr) - - # exit_status == -1 if no exit code was returned - if exit_status != -1: - LOG.debug('Result was %s' % exit_status) - if check_exit_code and exit_status != 0: - raise ProcessExecutionError(exit_code=exit_status, - stdout=stdout, - stderr=stderr, - cmd=sanitized_cmd) - - if binary: - if six.PY2: - # On Python 2, stdout is a bytes string if mask_password() failed - # to decode it, or an Unicode string otherwise. Encode to the - # default encoding (ASCII) because mask_password() decodes from - # the same encoding. - if isinstance(stdout, unicode): - stdout = stdout.encode() - if isinstance(stderr, unicode): - stderr = stderr.encode() - else: - # fsencode() is the reverse operation of fsdecode() - stdout = os.fsencode(stdout) - stderr = os.fsencode(stderr) - - return (stdout, stderr) - - -def get_worker_count(): - """Utility to get the default worker count. - - @return: The number of CPUs if that can be determined, else a default - worker count of 1 is returned. - """ - try: - return multiprocessing.cpu_count() - except NotImplementedError: - return 1 diff --git a/oslo_concurrency/tests/__init__.py b/oslo_concurrency/tests/__init__.py deleted file mode 100644 index bd455c4..0000000 --- a/oslo_concurrency/tests/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2014 Red Hat, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os - -if os.environ.get('TEST_EVENTLET'): - import eventlet - eventlet.monkey_patch() diff --git a/oslo_concurrency/tests/unit/__init__.py b/oslo_concurrency/tests/unit/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oslo_concurrency/tests/unit/test_lockutils.py b/oslo_concurrency/tests/unit/test_lockutils.py deleted file mode 100644 index 75d324a..0000000 --- a/oslo_concurrency/tests/unit/test_lockutils.py +++ /dev/null @@ -1,527 +0,0 @@ -# Copyright 2011 Justin Santa Barbara -# -# 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 collections -import fcntl -import os -import shutil -import signal -import subprocess -import sys -import tempfile -import threading -import time - -from oslo_config import cfg -from oslotest import base as test_base -import six - -from oslo_concurrency.fixture import lockutils as fixtures -from oslo_concurrency import lockutils -from oslo_config import fixture as config - - -class LockTestCase(test_base.BaseTestCase): - - def setUp(self): - super(LockTestCase, self).setUp() - self.config = self.useFixture(config.Config(lockutils.CONF)).config - - def test_synchronized_wrapped_function_metadata(self): - @lockutils.synchronized('whatever', 'test-') - def foo(): - """Bar.""" - pass - - self.assertEqual('Bar.', foo.__doc__, "Wrapped function's docstring " - "got lost") - self.assertEqual('foo', foo.__name__, "Wrapped function's name " - "got mangled") - - def test_lock_internally_different_collections(self): - s1 = lockutils.Semaphores() - s2 = lockutils.Semaphores() - trigger = threading.Event() - who_ran = collections.deque() - - def f(name, semaphores, pull_trigger): - with lockutils.internal_lock('testing', semaphores=semaphores): - if pull_trigger: - trigger.set() - else: - trigger.wait() - who_ran.append(name) - - threads = [ - threading.Thread(target=f, args=(1, s1, True)), - threading.Thread(target=f, args=(2, s2, False)), - ] - for thread in threads: - thread.start() - for thread in threads: - thread.join() - self.assertEqual([1, 2], sorted(who_ran)) - - def test_lock_internally(self): - """We can lock across multiple threads.""" - saved_sem_num = len(lockutils._semaphores) - seen_threads = list() - - def f(_id): - with lockutils.lock('testlock2', 'test-', external=False): - for x in range(10): - seen_threads.append(_id) - - threads = [] - for i in range(10): - thread = threading.Thread(target=f, args=(i,)) - threads.append(thread) - thread.start() - - for thread in threads: - thread.join() - - self.assertEqual(100, len(seen_threads)) - # Looking at the seen threads, split it into chunks of 10, and verify - # that the last 9 match the first in each chunk. - for i in range(10): - for j in range(9): - self.assertEqual(seen_threads[i * 10], - seen_threads[i * 10 + 1 + j]) - - self.assertEqual(saved_sem_num, len(lockutils._semaphores), - "Semaphore leak detected") - - def test_nested_synchronized_external_works(self): - """We can nest external syncs.""" - tempdir = tempfile.mkdtemp() - try: - self.config(lock_path=tempdir, group='oslo_concurrency') - sentinel = object() - - @lockutils.synchronized('testlock1', 'test-', external=True) - def outer_lock(): - - @lockutils.synchronized('testlock2', 'test-', external=True) - def inner_lock(): - return sentinel - return inner_lock() - - self.assertEqual(sentinel, outer_lock()) - - finally: - if os.path.exists(tempdir): - shutil.rmtree(tempdir) - - def _do_test_lock_externally(self): - """We can lock across multiple processes.""" - - def lock_files(handles_dir): - - with lockutils.lock('external', 'test-', external=True): - # Open some files we can use for locking - handles = [] - for n in range(50): - path = os.path.join(handles_dir, ('file-%s' % n)) - handles.append(open(path, 'w')) - - # Loop over all the handles and try locking the file - # without blocking, keep a count of how many files we - # were able to lock and then unlock. If the lock fails - # we get an IOError and bail out with bad exit code - count = 0 - for handle in handles: - try: - fcntl.flock(handle, fcntl.LOCK_EX | fcntl.LOCK_NB) - count += 1 - fcntl.flock(handle, fcntl.LOCK_UN) - except IOError: - os._exit(2) - finally: - handle.close() - - # Check if we were able to open all files - self.assertEqual(50, count) - - handles_dir = tempfile.mkdtemp() - try: - children = [] - for n in range(50): - pid = os.fork() - if pid: - children.append(pid) - else: - try: - lock_files(handles_dir) - finally: - os._exit(0) - - for child in children: - (pid, status) = os.waitpid(child, 0) - if pid: - self.assertEqual(0, status) - finally: - if os.path.exists(handles_dir): - shutil.rmtree(handles_dir, ignore_errors=True) - - def test_lock_externally(self): - lock_dir = tempfile.mkdtemp() - self.config(lock_path=lock_dir, group='oslo_concurrency') - - try: - self._do_test_lock_externally() - finally: - if os.path.exists(lock_dir): - shutil.rmtree(lock_dir, ignore_errors=True) - - def test_lock_externally_lock_dir_not_exist(self): - lock_dir = tempfile.mkdtemp() - os.rmdir(lock_dir) - self.config(lock_path=lock_dir, group='oslo_concurrency') - - try: - self._do_test_lock_externally() - finally: - if os.path.exists(lock_dir): - shutil.rmtree(lock_dir, ignore_errors=True) - - def test_synchronized_with_prefix(self): - lock_name = 'mylock' - lock_pfix = 'mypfix-' - - foo = lockutils.synchronized_with_prefix(lock_pfix) - - @foo(lock_name, external=True) - def bar(dirpath, pfix, name): - return True - - lock_dir = tempfile.mkdtemp() - self.config(lock_path=lock_dir, group='oslo_concurrency') - - self.assertTrue(bar(lock_dir, lock_pfix, lock_name)) - - def test_synchronized_without_prefix(self): - lock_dir = tempfile.mkdtemp() - self.config(lock_path=lock_dir, group='oslo_concurrency') - - @lockutils.synchronized('lock', external=True) - def test_without_prefix(): - # We can't check much - pass - - try: - test_without_prefix() - finally: - if os.path.exists(lock_dir): - shutil.rmtree(lock_dir, ignore_errors=True) - - def test_synchronized_prefix_without_hypen(self): - lock_dir = tempfile.mkdtemp() - self.config(lock_path=lock_dir, group='oslo_concurrency') - - @lockutils.synchronized('lock', 'hypen', True) - def test_without_hypen(): - # We can't check much - pass - - try: - test_without_hypen() - finally: - if os.path.exists(lock_dir): - shutil.rmtree(lock_dir, ignore_errors=True) - - def test_contextlock(self): - lock_dir = tempfile.mkdtemp() - self.config(lock_path=lock_dir, group='oslo_concurrency') - - try: - # Note(flaper87): Lock is not external, which means - # a semaphore will be yielded - with lockutils.lock("test") as sem: - if six.PY2: - self.assertTrue(isinstance(sem, threading._Semaphore)) - else: - self.assertTrue(isinstance(sem, threading.Semaphore)) - - # NOTE(flaper87): Lock is external so an InterProcessLock - # will be yielded. - with lockutils.lock("test2", external=True) as lock: - self.assertTrue(lock.exists()) - - with lockutils.lock("test1", - external=True) as lock1: - self.assertTrue(isinstance(lock1, - lockutils.InterProcessLock)) - finally: - if os.path.exists(lock_dir): - shutil.rmtree(lock_dir, ignore_errors=True) - - def test_contextlock_unlocks(self): - lock_dir = tempfile.mkdtemp() - self.config(lock_path=lock_dir, group='oslo_concurrency') - - sem = None - - try: - with lockutils.lock("test") as sem: - if six.PY2: - self.assertTrue(isinstance(sem, threading._Semaphore)) - else: - self.assertTrue(isinstance(sem, threading.Semaphore)) - - with lockutils.lock("test2", external=True) as lock: - self.assertTrue(lock.exists()) - - # NOTE(flaper87): Lock should be free - with lockutils.lock("test2", external=True) as lock: - self.assertTrue(lock.exists()) - - # NOTE(flaper87): Lock should be free - # but semaphore should already exist. - with lockutils.lock("test") as sem2: - self.assertEqual(sem, sem2) - finally: - if os.path.exists(lock_dir): - shutil.rmtree(lock_dir, ignore_errors=True) - - def _test_remove_lock_external_file(self, lock_dir, use_external=False): - lock_name = 'mylock' - lock_pfix = 'mypfix-remove-lock-test-' - - if use_external: - lock_path = lock_dir - else: - lock_path = None - - lockutils.remove_external_lock_file(lock_name, lock_pfix, lock_path) - - for ent in os.listdir(lock_dir): - self.assertRaises(OSError, ent.startswith, lock_pfix) - - if os.path.exists(lock_dir): - shutil.rmtree(lock_dir, ignore_errors=True) - - def test_remove_lock_external_file(self): - lock_dir = tempfile.mkdtemp() - self.config(lock_path=lock_dir, group='oslo_concurrency') - self._test_remove_lock_external_file(lock_dir) - - def test_remove_lock_external_file_lock_path(self): - lock_dir = tempfile.mkdtemp() - self._test_remove_lock_external_file(lock_dir, - use_external=True) - - def test_no_slash_in_b64(self): - # base64(sha1(foobar)) has a slash in it - with lockutils.lock("foobar"): - pass - - def test_deprecated_names(self): - paths = self.create_tempfiles([['fake.conf', '\n'.join([ - '[DEFAULT]', - 'lock_path=foo', - 'disable_process_locking=True']) - ]]) - conf = cfg.ConfigOpts() - conf(['--config-file', paths[0]]) - conf.register_opts(lockutils._opts, 'oslo_concurrency') - self.assertEqual('foo', conf.oslo_concurrency.lock_path) - self.assertTrue(conf.oslo_concurrency.disable_process_locking) - - -class FileBasedLockingTestCase(test_base.BaseTestCase): - def setUp(self): - super(FileBasedLockingTestCase, self).setUp() - self.lock_dir = tempfile.mkdtemp() - - def test_lock_file_exists(self): - lock_file = os.path.join(self.lock_dir, 'lock-file') - - @lockutils.synchronized('lock-file', external=True, - lock_path=self.lock_dir) - def foo(): - self.assertTrue(os.path.exists(lock_file)) - - foo() - - def test_interprocess_lock(self): - lock_file = os.path.join(self.lock_dir, 'processlock') - - pid = os.fork() - if pid: - # Make sure the child grabs the lock first - start = time.time() - while not os.path.exists(lock_file): - if time.time() - start > 5: - self.fail('Timed out waiting for child to grab lock') - time.sleep(0) - lock1 = lockutils.InterProcessLock('foo') - lock1.lockfile = open(lock_file, 'w') - # NOTE(bnemec): There is a brief window between when the lock file - # is created and when it actually becomes locked. If we happen to - # context switch in that window we may succeed in locking the - # file. Keep retrying until we either get the expected exception - # or timeout waiting. - while time.time() - start < 5: - try: - lock1.trylock() - lock1.unlock() - time.sleep(0) - except IOError: - # This is what we expect to happen - break - else: - self.fail('Never caught expected lock exception') - # We don't need to wait for the full sleep in the child here - os.kill(pid, signal.SIGKILL) - else: - try: - lock2 = lockutils.InterProcessLock('foo') - lock2.lockfile = open(lock_file, 'w') - have_lock = False - while not have_lock: - try: - lock2.trylock() - have_lock = True - except IOError: - pass - finally: - # NOTE(bnemec): This is racy, but I don't want to add any - # synchronization primitives that might mask a problem - # with the one we're trying to test here. - time.sleep(.5) - os._exit(0) - - def test_interthread_external_lock(self): - call_list = [] - - @lockutils.synchronized('foo', external=True, lock_path=self.lock_dir) - def foo(param): - """Simulate a long-running threaded operation.""" - call_list.append(param) - # NOTE(bnemec): This is racy, but I don't want to add any - # synchronization primitives that might mask a problem - # with the one we're trying to test here. - time.sleep(.5) - call_list.append(param) - - def other(param): - foo(param) - - thread = threading.Thread(target=other, args=('other',)) - thread.start() - # Make sure the other thread grabs the lock - # NOTE(bnemec): File locks do not actually work between threads, so - # this test is verifying that the local semaphore is still enforcing - # external locks in that case. This means this test does not have - # the same race problem as the process test above because when the - # file is created the semaphore has already been grabbed. - start = time.time() - while not os.path.exists(os.path.join(self.lock_dir, 'foo')): - if time.time() - start > 5: - self.fail('Timed out waiting for thread to grab lock') - time.sleep(0) - thread1 = threading.Thread(target=other, args=('main',)) - thread1.start() - thread1.join() - thread.join() - self.assertEqual(['other', 'other', 'main', 'main'], call_list) - - def test_non_destructive(self): - lock_file = os.path.join(self.lock_dir, 'not-destroyed') - with open(lock_file, 'w') as f: - f.write('test') - with lockutils.lock('not-destroyed', external=True, - lock_path=self.lock_dir): - with open(lock_file) as f: - self.assertEqual('test', f.read()) - - -class LockutilsModuleTestCase(test_base.BaseTestCase): - - def setUp(self): - super(LockutilsModuleTestCase, self).setUp() - self.old_env = os.environ.get('OSLO_LOCK_PATH') - if self.old_env is not None: - del os.environ['OSLO_LOCK_PATH'] - - def tearDown(self): - if self.old_env is not None: - os.environ['OSLO_LOCK_PATH'] = self.old_env - super(LockutilsModuleTestCase, self).tearDown() - - def test_main(self): - script = '\n'.join([ - 'import os', - 'lock_path = os.environ.get("OSLO_LOCK_PATH")', - 'assert lock_path is not None', - 'assert os.path.isdir(lock_path)', - ]) - argv = ['', sys.executable, '-c', script] - retval = lockutils._lock_wrapper(argv) - self.assertEqual(0, retval, "Bad OSLO_LOCK_PATH has been set") - - def test_return_value_maintained(self): - script = '\n'.join([ - 'import sys', - 'sys.exit(1)', - ]) - argv = ['', sys.executable, '-c', script] - retval = lockutils._lock_wrapper(argv) - self.assertEqual(1, retval) - - def test_direct_call_explodes(self): - cmd = [sys.executable, '-m', 'oslo_concurrency.lockutils'] - with open(os.devnull, 'w') as devnull: - retval = subprocess.call(cmd, stderr=devnull) - self.assertEqual(1, retval) - - -class TestLockFixture(test_base.BaseTestCase): - - def setUp(self): - super(TestLockFixture, self).setUp() - self.config = self.useFixture(config.Config(lockutils.CONF)).config - self.tempdir = tempfile.mkdtemp() - - def _check_in_lock(self): - self.assertTrue(self.lock.exists()) - - def tearDown(self): - self._check_in_lock() - super(TestLockFixture, self).tearDown() - - def test_lock_fixture(self): - # Setup lock fixture to test that teardown is inside the lock - self.config(lock_path=self.tempdir, group='oslo_concurrency') - fixture = fixtures.LockFixture('test-lock') - self.useFixture(fixture) - self.lock = fixture.lock - - -class TestGetLockPath(test_base.BaseTestCase): - - def setUp(self): - super(TestGetLockPath, self).setUp() - self.conf = self.useFixture(config.Config(lockutils.CONF)).conf - - def test_get_default(self): - lockutils.set_defaults(lock_path='/the/path') - self.assertEqual('/the/path', lockutils.get_lock_path(self.conf)) - - def test_get_override(self): - lockutils._register_opts(self.conf) - self.conf.set_override('lock_path', '/alternate/path', - group='oslo_concurrency') - self.assertEqual('/alternate/path', lockutils.get_lock_path(self.conf)) diff --git a/oslo_concurrency/tests/unit/test_lockutils_eventlet.py b/oslo_concurrency/tests/unit/test_lockutils_eventlet.py deleted file mode 100644 index bb333d7..0000000 --- a/oslo_concurrency/tests/unit/test_lockutils_eventlet.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2011 Justin Santa Barbara -# -# 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 os -import shutil -import tempfile - -import eventlet -from eventlet import greenpool -from oslotest import base as test_base - -from oslo_concurrency import lockutils - - -class TestFileLocks(test_base.BaseTestCase): - - def test_concurrent_green_lock_succeeds(self): - """Verify spawn_n greenthreads with two locks run concurrently.""" - tmpdir = tempfile.mkdtemp() - try: - self.completed = False - - def locka(wait): - a = lockutils.InterProcessLock(os.path.join(tmpdir, 'a')) - with a: - wait.wait() - self.completed = True - - def lockb(wait): - b = lockutils.InterProcessLock(os.path.join(tmpdir, 'b')) - with b: - wait.wait() - - wait1 = eventlet.event.Event() - wait2 = eventlet.event.Event() - pool = greenpool.GreenPool() - pool.spawn_n(locka, wait1) - pool.spawn_n(lockb, wait2) - wait2.send() - eventlet.sleep(0) - wait1.send() - pool.waitall() - - self.assertTrue(self.completed) - - finally: - if os.path.exists(tmpdir): - shutil.rmtree(tmpdir) diff --git a/oslo_concurrency/tests/unit/test_processutils.py b/oslo_concurrency/tests/unit/test_processutils.py deleted file mode 100644 index 7f68be3..0000000 --- a/oslo_concurrency/tests/unit/test_processutils.py +++ /dev/null @@ -1,897 +0,0 @@ -# Copyright 2011 OpenStack Foundation. -# 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 __future__ import print_function - -import errno -import logging -import multiprocessing -import os -import pickle -import resource -import socket -import stat -import subprocess -import sys -import tempfile - -import fixtures -import mock -from oslotest import base as test_base -import six - -from oslo_concurrency import processutils -from oslotest import mockpatch - - -PROCESS_EXECUTION_ERROR_LOGGING_TEST = """#!/bin/bash -exit 41""" - -TEST_EXCEPTION_AND_MASKING_SCRIPT = """#!/bin/bash -# This is to test stdout and stderr -# and the command returned in an exception -# when a non-zero exit code is returned -echo onstdout --password='"secret"' -echo onstderr --password='"secret"' 1>&2 -exit 38""" - -# This byte sequence is undecodable from most encoding -UNDECODABLE_BYTES = b'[a\x80\xe9\xff]' - -TRUE_UTILITY = (sys.platform.startswith('darwin') and - '/usr/bin/true' or '/bin/true') - - -class UtilsTest(test_base.BaseTestCase): - # NOTE(jkoelker) Moar tests from nova need to be ported. But they - # need to be mock'd out. Currently they require actually - # running code. - def test_execute_unknown_kwargs(self): - self.assertRaises(processutils.UnknownArgumentError, - processutils.execute, - hozer=True) - - @mock.patch.object(multiprocessing, 'cpu_count', return_value=8) - def test_get_worker_count(self, mock_cpu_count): - self.assertEqual(8, processutils.get_worker_count()) - - @mock.patch.object(multiprocessing, 'cpu_count', - side_effect=NotImplementedError()) - def test_get_worker_count_cpu_count_not_implemented(self, - mock_cpu_count): - self.assertEqual(1, processutils.get_worker_count()) - - def test_execute_with_callback(self): - on_execute_callback = mock.Mock() - on_completion_callback = mock.Mock() - processutils.execute(TRUE_UTILITY) - self.assertEqual(0, on_execute_callback.call_count) - self.assertEqual(0, on_completion_callback.call_count) - - processutils.execute(TRUE_UTILITY, on_execute=on_execute_callback, - on_completion=on_completion_callback) - self.assertEqual(1, on_execute_callback.call_count) - self.assertEqual(1, on_completion_callback.call_count) - - @mock.patch.object(subprocess.Popen, "communicate") - def test_execute_with_callback_and_errors(self, mock_comm): - on_execute_callback = mock.Mock() - on_completion_callback = mock.Mock() - - def fake_communicate(*args): - raise IOError("Broken pipe") - - mock_comm.side_effect = fake_communicate - - self.assertRaises(IOError, - processutils.execute, - TRUE_UTILITY, - on_execute=on_execute_callback, - on_completion=on_completion_callback) - self.assertEqual(1, on_execute_callback.call_count) - self.assertEqual(1, on_completion_callback.call_count) - - def test_execute_with_preexec_fn(self): - # NOTE(dims): preexec_fn is set to a callable object, this object - # will be called in the child process just before the child is - # executed. So we cannot pass share variables etc, simplest is to - # check if a specific exception is thrown which can be caught here. - def preexec_fn(): - raise processutils.InvalidArgumentError() - - processutils.execute(TRUE_UTILITY) - - expected_exception = (processutils.InvalidArgumentError if six.PY2 - else subprocess.SubprocessError) - self.assertRaises(expected_exception, - processutils.execute, - TRUE_UTILITY, - preexec_fn=preexec_fn) - - -class ProcessExecutionErrorTest(test_base.BaseTestCase): - - def test_defaults(self): - err = processutils.ProcessExecutionError() - self.assertTrue('None\n' in six.text_type(err)) - self.assertTrue('code: -\n' in six.text_type(err)) - - def test_with_description(self): - description = 'The Narwhal Bacons at Midnight' - err = processutils.ProcessExecutionError(description=description) - self.assertTrue(description in six.text_type(err)) - - def test_with_exit_code(self): - exit_code = 0 - err = processutils.ProcessExecutionError(exit_code=exit_code) - self.assertTrue(str(exit_code) in six.text_type(err)) - - def test_with_cmd(self): - cmd = 'telinit' - err = processutils.ProcessExecutionError(cmd=cmd) - self.assertTrue(cmd in six.text_type(err)) - - def test_with_stdout(self): - stdout = """ - Lo, praise of the prowess of people-kings - of spear-armed Danes, in days long sped, - we have heard, and what honot the athelings won! - Oft Scyld the Scefing from squadroned foes, - from many a tribe, the mead-bench tore, - awing the earls. Since erse he lay - friendless, a foundling, fate repaid him: - for he waxed under welkin, in wealth he trove, - till before him the folk, both far and near, - who house by the whale-path, heard his mandate, - gabe him gits: a good king he! - To him an heir was afterward born, - a son in his halls, whom heaven sent - to favor the fol, feeling their woe - that erst they had lacked an earl for leader - so long a while; the Lord endowed him, - the Wielder of Wonder, with world's renown. - """.strip() - err = processutils.ProcessExecutionError(stdout=stdout) - print(six.text_type(err)) - self.assertTrue('people-kings' in six.text_type(err)) - - def test_with_stderr(self): - stderr = 'Cottonian library' - err = processutils.ProcessExecutionError(stderr=stderr) - self.assertTrue(stderr in six.text_type(err)) - - def test_retry_on_failure(self): - fd, tmpfilename = tempfile.mkstemp() - _, tmpfilename2 = tempfile.mkstemp() - try: - fp = os.fdopen(fd, 'w+') - fp.write('''#!/bin/sh -# If stdin fails to get passed during one of the runs, make a note. -if ! grep -q foo -then - echo 'failure' > "$1" -fi -# If stdin has failed to get passed during this or a previous run, exit early. -if grep failure "$1" -then - exit 1 -fi -runs="$(cat $1)" -if [ -z "$runs" ] -then - runs=0 -fi -runs=$(($runs + 1)) -echo $runs > "$1" -exit 1 -''') - fp.close() - os.chmod(tmpfilename, 0o755) - self.assertRaises(processutils.ProcessExecutionError, - processutils.execute, - tmpfilename, tmpfilename2, attempts=10, - process_input=b'foo', - delay_on_retry=False) - fp = open(tmpfilename2, 'r') - runs = fp.read() - fp.close() - self.assertNotEqual('failure', 'stdin did not ' - 'always get passed ' - 'correctly', - runs.strip()) - runs = int(runs.strip()) - self.assertEqual(10, runs, 'Ran %d times instead of 10.' % (runs,)) - finally: - os.unlink(tmpfilename) - os.unlink(tmpfilename2) - - def test_unknown_kwargs_raises_error(self): - self.assertRaises(processutils.UnknownArgumentError, - processutils.execute, - '/usr/bin/env', 'true', - this_is_not_a_valid_kwarg=True) - - def test_check_exit_code_boolean(self): - processutils.execute('/usr/bin/env', 'false', check_exit_code=False) - self.assertRaises(processutils.ProcessExecutionError, - processutils.execute, - '/usr/bin/env', 'false', check_exit_code=True) - - def test_check_cwd(self): - tmpdir = tempfile.mkdtemp() - out, err = processutils.execute('/usr/bin/env', - 'sh', '-c', 'pwd', - cwd=tmpdir) - self.assertIn(tmpdir, out) - - def test_check_exit_code_list(self): - processutils.execute('/usr/bin/env', 'sh', '-c', 'exit 101', - check_exit_code=(101, 102)) - processutils.execute('/usr/bin/env', 'sh', '-c', 'exit 102', - check_exit_code=(101, 102)) - self.assertRaises(processutils.ProcessExecutionError, - processutils.execute, - '/usr/bin/env', 'sh', '-c', 'exit 103', - check_exit_code=(101, 102)) - self.assertRaises(processutils.ProcessExecutionError, - processutils.execute, - '/usr/bin/env', 'sh', '-c', 'exit 0', - check_exit_code=(101, 102)) - - def test_no_retry_on_success(self): - fd, tmpfilename = tempfile.mkstemp() - _, tmpfilename2 = tempfile.mkstemp() - try: - fp = os.fdopen(fd, 'w+') - fp.write("""#!/bin/sh -# If we've already run, bail out. -grep -q foo "$1" && exit 1 -# Mark that we've run before. -echo foo > "$1" -# Check that stdin gets passed correctly. -grep foo -""") - fp.close() - os.chmod(tmpfilename, 0o755) - processutils.execute(tmpfilename, - tmpfilename2, - process_input=b'foo', - attempts=2) - finally: - os.unlink(tmpfilename) - os.unlink(tmpfilename2) - - # This test and the one below ensures that when communicate raises - # an OSError, we do the right thing(s) - def test_exception_on_communicate_error(self): - mock = self.useFixture(mockpatch.Patch( - 'subprocess.Popen.communicate', - side_effect=OSError(errno.EAGAIN, 'fake-test'))) - - self.assertRaises(OSError, - processutils.execute, - '/usr/bin/env', - 'false', - check_exit_code=False) - - self.assertEqual(1, mock.mock.call_count) - - def test_retry_on_communicate_error(self): - mock = self.useFixture(mockpatch.Patch( - 'subprocess.Popen.communicate', - side_effect=OSError(errno.EAGAIN, 'fake-test'))) - - self.assertRaises(OSError, - processutils.execute, - '/usr/bin/env', - 'false', - check_exit_code=False, - attempts=5) - - self.assertEqual(5, mock.mock.call_count) - - def _test_and_check_logging_communicate_errors(self, log_errors=None, - attempts=None): - mock = self.useFixture(mockpatch.Patch( - 'subprocess.Popen.communicate', - side_effect=OSError(errno.EAGAIN, 'fake-test'))) - - fixture = self.useFixture(fixtures.FakeLogger(level=logging.DEBUG)) - kwargs = {} - - if log_errors: - kwargs.update({"log_errors": log_errors}) - - if attempts: - kwargs.update({"attempts": attempts}) - - self.assertRaises(OSError, - processutils.execute, - '/usr/bin/env', - 'false', - **kwargs) - - self.assertEqual(attempts if attempts else 1, mock.mock.call_count) - self.assertIn('Got an OSError', fixture.output) - self.assertIn('errno: %d' % errno.EAGAIN, fixture.output) - self.assertIn("'/usr/bin/env false'", fixture.output) - - def test_logging_on_communicate_error_1(self): - self._test_and_check_logging_communicate_errors( - log_errors=processutils.LOG_FINAL_ERROR, - attempts=None) - - def test_logging_on_communicate_error_2(self): - self._test_and_check_logging_communicate_errors( - log_errors=processutils.LOG_FINAL_ERROR, - attempts=1) - - def test_logging_on_communicate_error_3(self): - self._test_and_check_logging_communicate_errors( - log_errors=processutils.LOG_FINAL_ERROR, - attempts=5) - - def test_logging_on_communicate_error_4(self): - self._test_and_check_logging_communicate_errors( - log_errors=processutils.LOG_ALL_ERRORS, - attempts=None) - - def test_logging_on_communicate_error_5(self): - self._test_and_check_logging_communicate_errors( - log_errors=processutils.LOG_ALL_ERRORS, - attempts=1) - - def test_logging_on_communicate_error_6(self): - self._test_and_check_logging_communicate_errors( - log_errors=processutils.LOG_ALL_ERRORS, - attempts=5) - - def test_with_env_variables(self): - env_vars = {'SUPER_UNIQUE_VAR': 'The answer is 42'} - - out, err = processutils.execute('/usr/bin/env', env_variables=env_vars) - self.assertIsInstance(out, str) - self.assertIsInstance(err, str) - - self.assertIn('SUPER_UNIQUE_VAR=The answer is 42', out) - - def test_binary(self): - env_vars = {'SUPER_UNIQUE_VAR': 'The answer is 42'} - - out, err = processutils.execute('/usr/bin/env', - env_variables=env_vars, - binary=True) - self.assertIsInstance(out, bytes) - self.assertIsInstance(err, bytes) - - self.assertIn(b'SUPER_UNIQUE_VAR=The answer is 42', out) - - def test_exception_and_masking(self): - tmpfilename = self.create_tempfiles( - [["test_exceptions_and_masking", - TEST_EXCEPTION_AND_MASKING_SCRIPT]], ext='bash')[0] - - os.chmod(tmpfilename, (stat.S_IRWXU | - stat.S_IRGRP | - stat.S_IXGRP | - stat.S_IROTH | - stat.S_IXOTH)) - - err = self.assertRaises(processutils.ProcessExecutionError, - processutils.execute, - tmpfilename, 'password="secret"', - 'something') - - self.assertEqual(38, err.exit_code) - self.assertIsInstance(err.stdout, six.text_type) - self.assertIsInstance(err.stderr, six.text_type) - self.assertIn('onstdout --password="***"', err.stdout) - self.assertIn('onstderr --password="***"', err.stderr) - self.assertEqual(' '.join([tmpfilename, - 'password="***"', - 'something']), - err.cmd) - self.assertNotIn('secret', str(err)) - - def execute_undecodable_bytes(self, out_bytes, err_bytes, - exitcode=0, binary=False): - if six.PY3: - code = ';'.join(('import sys', - 'sys.stdout.buffer.write(%a)' % out_bytes, - 'sys.stdout.flush()', - 'sys.stderr.buffer.write(%a)' % err_bytes, - 'sys.stderr.flush()', - 'sys.exit(%s)' % exitcode)) - else: - code = ';'.join(('import sys', - 'sys.stdout.write(%r)' % out_bytes, - 'sys.stdout.flush()', - 'sys.stderr.write(%r)' % err_bytes, - 'sys.stderr.flush()', - 'sys.exit(%s)' % exitcode)) - - return processutils.execute(sys.executable, '-c', code, binary=binary) - - def check_undecodable_bytes(self, binary): - out_bytes = b'out: ' + UNDECODABLE_BYTES - err_bytes = b'err: ' + UNDECODABLE_BYTES - out, err = self.execute_undecodable_bytes(out_bytes, err_bytes, - binary=binary) - if six.PY3 and not binary: - self.assertEqual(os.fsdecode(out_bytes), out) - self.assertEqual(os.fsdecode(err_bytes), err) - else: - self.assertEqual(out, out_bytes) - self.assertEqual(err, err_bytes) - - def test_undecodable_bytes(self): - self.check_undecodable_bytes(False) - - def test_binary_undecodable_bytes(self): - self.check_undecodable_bytes(True) - - def check_undecodable_bytes_error(self, binary): - out_bytes = b'out: password="secret1" ' + UNDECODABLE_BYTES - err_bytes = b'err: password="secret2" ' + UNDECODABLE_BYTES - exc = self.assertRaises(processutils.ProcessExecutionError, - self.execute_undecodable_bytes, - out_bytes, err_bytes, exitcode=1, - binary=binary) - - out = exc.stdout - err = exc.stderr - out_bytes = b'out: password="***" ' + UNDECODABLE_BYTES - err_bytes = b'err: password="***" ' + UNDECODABLE_BYTES - if six.PY3: - # On Python 3, stdout and stderr attributes of - # ProcessExecutionError must always be Unicode - self.assertEqual(os.fsdecode(out_bytes), out) - self.assertEqual(os.fsdecode(err_bytes), err) - else: - # On Python 2, stdout and stderr attributes of - # ProcessExecutionError must always be bytes - self.assertEqual(out_bytes, out) - self.assertEqual(err_bytes, err) - - def test_undecodable_bytes_error(self): - self.check_undecodable_bytes_error(False) - - def test_binary_undecodable_bytes_error(self): - self.check_undecodable_bytes_error(True) - - def test_picklable(self): - exc = processutils.ProcessExecutionError( - stdout='my stdout', stderr='my stderr', - exit_code=42, cmd='my cmd', - description='my description') - exc_message = str(exc) - - exc = pickle.loads(pickle.dumps(exc)) - self.assertEqual('my stdout', exc.stdout) - self.assertEqual('my stderr', exc.stderr) - self.assertEqual(42, exc.exit_code) - self.assertEqual('my cmd', exc.cmd) - self.assertEqual('my description', exc.description) - self.assertEqual(str(exc), exc_message) - - -class ProcessExecutionErrorLoggingTest(test_base.BaseTestCase): - def setUp(self): - super(ProcessExecutionErrorLoggingTest, self).setUp() - self.tmpfilename = self.create_tempfiles( - [["process_execution_error_logging_test", - PROCESS_EXECUTION_ERROR_LOGGING_TEST]], - ext='bash')[0] - - os.chmod(self.tmpfilename, (stat.S_IRWXU | stat.S_IRGRP | - stat.S_IXGRP | stat.S_IROTH | - stat.S_IXOTH)) - - def _test_and_check(self, log_errors=None, attempts=None): - fixture = self.useFixture(fixtures.FakeLogger(level=logging.DEBUG)) - kwargs = {} - - if log_errors: - kwargs.update({"log_errors": log_errors}) - - if attempts: - kwargs.update({"attempts": attempts}) - - err = self.assertRaises(processutils.ProcessExecutionError, - processutils.execute, - self.tmpfilename, - **kwargs) - - self.assertEqual(41, err.exit_code) - self.assertIn(self.tmpfilename, fixture.output) - - def test_with_invalid_log_errors(self): - self.assertRaises(processutils.InvalidArgumentError, - processutils.execute, - self.tmpfilename, - log_errors='invalid') - - def test_with_log_errors_NONE(self): - self._test_and_check(log_errors=None, attempts=None) - - def test_with_log_errors_final(self): - self._test_and_check(log_errors=processutils.LOG_FINAL_ERROR, - attempts=None) - - def test_with_log_errors_all(self): - self._test_and_check(log_errors=processutils.LOG_ALL_ERRORS, - attempts=None) - - def test_multiattempt_with_log_errors_NONE(self): - self._test_and_check(log_errors=None, attempts=3) - - def test_multiattempt_with_log_errors_final(self): - self._test_and_check(log_errors=processutils.LOG_FINAL_ERROR, - attempts=3) - - def test_multiattempt_with_log_errors_all(self): - self._test_and_check(log_errors=processutils.LOG_ALL_ERRORS, - attempts=3) - - -def fake_execute(*cmd, **kwargs): - return 'stdout', 'stderr' - - -def fake_execute_raises(*cmd, **kwargs): - raise processutils.ProcessExecutionError(exit_code=42, - stdout='stdout', - stderr='stderr', - cmd=['this', 'is', 'a', - 'command']) - - -class TryCmdTestCase(test_base.BaseTestCase): - def test_keep_warnings(self): - self.useFixture(fixtures.MonkeyPatch( - 'oslo_concurrency.processutils.execute', fake_execute)) - o, e = processutils.trycmd('this is a command'.split(' ')) - self.assertNotEqual('', o) - self.assertNotEqual('', e) - - def test_keep_warnings_from_raise(self): - self.useFixture(fixtures.MonkeyPatch( - 'oslo_concurrency.processutils.execute', fake_execute_raises)) - o, e = processutils.trycmd('this is a command'.split(' '), - discard_warnings=True) - self.assertIsNotNone(o) - self.assertNotEqual('', e) - - def test_discard_warnings(self): - self.useFixture(fixtures.MonkeyPatch( - 'oslo_concurrency.processutils.execute', fake_execute)) - o, e = processutils.trycmd('this is a command'.split(' '), - discard_warnings=True) - self.assertIsNotNone(o) - self.assertEqual('', e) - - -class FakeSshChannel(object): - def __init__(self, rc): - self.rc = rc - - def recv_exit_status(self): - return self.rc - - -class FakeSshStream(six.BytesIO): - def setup_channel(self, rc): - self.channel = FakeSshChannel(rc) - - -class FakeSshConnection(object): - def __init__(self, rc, out=b'stdout', err=b'stderr'): - self.rc = rc - self.out = out - self.err = err - - def exec_command(self, cmd, timeout=None): - if timeout: - raise socket.timeout() - stdout = FakeSshStream(self.out) - stdout.setup_channel(self.rc) - return (six.BytesIO(), - stdout, - six.BytesIO(self.err)) - - -class SshExecuteTestCase(test_base.BaseTestCase): - def test_invalid_addl_env(self): - self.assertRaises(processutils.InvalidArgumentError, - processutils.ssh_execute, - None, 'ls', addl_env='important') - - def test_invalid_process_input(self): - self.assertRaises(processutils.InvalidArgumentError, - processutils.ssh_execute, - None, 'ls', process_input='important') - - def test_timeout_error(self): - self.assertRaises(socket.timeout, - processutils.ssh_execute, - FakeSshConnection(0), 'ls', - timeout=10) - - def test_works(self): - out, err = processutils.ssh_execute(FakeSshConnection(0), 'ls') - self.assertEqual('stdout', out) - self.assertEqual('stderr', err) - self.assertIsInstance(out, six.text_type) - self.assertIsInstance(err, six.text_type) - - def test_binary(self): - o, e = processutils.ssh_execute(FakeSshConnection(0), 'ls', - binary=True) - self.assertEqual(b'stdout', o) - self.assertEqual(b'stderr', e) - self.assertIsInstance(o, bytes) - self.assertIsInstance(e, bytes) - - def check_undecodable_bytes(self, binary): - out_bytes = b'out: ' + UNDECODABLE_BYTES - err_bytes = b'err: ' + UNDECODABLE_BYTES - conn = FakeSshConnection(0, out=out_bytes, err=err_bytes) - - out, err = processutils.ssh_execute(conn, 'ls', binary=binary) - if six.PY3 and not binary: - self.assertEqual(os.fsdecode(out_bytes), out) - self.assertEqual(os.fsdecode(err_bytes), err) - else: - self.assertEqual(out_bytes, out) - self.assertEqual(err_bytes, err) - - def test_undecodable_bytes(self): - self.check_undecodable_bytes(False) - - def test_binary_undecodable_bytes(self): - self.check_undecodable_bytes(True) - - def check_undecodable_bytes_error(self, binary): - out_bytes = b'out: password="secret1" ' + UNDECODABLE_BYTES - err_bytes = b'err: password="secret2" ' + UNDECODABLE_BYTES - conn = FakeSshConnection(1, out=out_bytes, err=err_bytes) - - out_bytes = b'out: password="***" ' + UNDECODABLE_BYTES - err_bytes = b'err: password="***" ' + UNDECODABLE_BYTES - - exc = self.assertRaises(processutils.ProcessExecutionError, - processutils.ssh_execute, - conn, 'ls', - binary=binary, check_exit_code=True) - - out = exc.stdout - err = exc.stderr - if six.PY3: - # On Python 3, stdout and stderr attributes of - # ProcessExecutionError must always be Unicode - self.assertEqual(os.fsdecode(out_bytes), out) - self.assertEqual(os.fsdecode(err_bytes), err) - else: - # On Python 2, stdout and stderr attributes of - # ProcessExecutionError must always be bytes - self.assertEqual(out_bytes, out) - self.assertEqual(err_bytes, err) - - def test_undecodable_bytes_error(self): - self.check_undecodable_bytes_error(False) - - def test_binary_undecodable_bytes_error(self): - self.check_undecodable_bytes_error(True) - - def test_fails(self): - self.assertRaises(processutils.ProcessExecutionError, - processutils.ssh_execute, FakeSshConnection(1), 'ls') - - def _test_compromising_ssh(self, rc, check): - fixture = self.useFixture(fixtures.FakeLogger(level=logging.DEBUG)) - fake_stdin = six.BytesIO() - - fake_stdout = mock.Mock() - fake_stdout.channel.recv_exit_status.return_value = rc - fake_stdout.read.return_value = b'password="secret"' - - fake_stderr = six.BytesIO(b'password="foobar"') - - command = 'ls --password="bar"' - - connection = mock.Mock() - connection.exec_command.return_value = (fake_stdin, fake_stdout, - fake_stderr) - - if check and rc != -1 and rc != 0: - err = self.assertRaises(processutils.ProcessExecutionError, - processutils.ssh_execute, - connection, command, - check_exit_code=check) - - self.assertEqual(rc, err.exit_code) - self.assertEqual('password="***"', err.stdout) - self.assertEqual('password="***"', err.stderr) - self.assertEqual('ls --password="***"', err.cmd) - self.assertNotIn('secret', str(err)) - self.assertNotIn('foobar', str(err)) - else: - o, e = processutils.ssh_execute(connection, command, - check_exit_code=check) - self.assertEqual('password="***"', o) - self.assertEqual('password="***"', e) - self.assertIn('password="***"', fixture.output) - self.assertNotIn('bar', fixture.output) - - def test_compromising_ssh1(self): - self._test_compromising_ssh(rc=-1, check=True) - - def test_compromising_ssh2(self): - self._test_compromising_ssh(rc=0, check=True) - - def test_compromising_ssh3(self): - self._test_compromising_ssh(rc=1, check=True) - - def test_compromising_ssh4(self): - self._test_compromising_ssh(rc=1, check=False) - - def test_compromising_ssh5(self): - self._test_compromising_ssh(rc=0, check=False) - - def test_compromising_ssh6(self): - self._test_compromising_ssh(rc=-1, check=False) - - -class PrlimitTestCase(test_base.BaseTestCase): - # Simply program that does nothing and returns an exit code 0. - # Use Python to be portable. - SIMPLE_PROGRAM = [sys.executable, '-c', 'pass'] - - def soft_limit(self, res, substract, default_limit): - # Create a new soft limit for a resource, lower than the current - # soft limit. - soft_limit, hard_limit = resource.getrlimit(res) - if soft_limit <= 0: - soft_limit = default_limit - else: - soft_limit -= substract - return soft_limit - - def memory_limit(self, res): - # Substract 1 kB just to get a different limit. Don't substract too - # much to avoid memory allocation issues. - # - # Use 1 GB by default. Limit high enough to be able to load shared - # libraries. Limit low enough to be work on 32-bit platforms. - return self.soft_limit(res, 1024, 1024 ** 3) - - def limit_address_space(self): - max_memory = self.memory_limit(resource.RLIMIT_AS) - return processutils.ProcessLimits(address_space=max_memory) - - def test_simple(self): - # Simple test running a program (/bin/true) with no parameter - prlimit = self.limit_address_space() - stdout, stderr = processutils.execute(*self.SIMPLE_PROGRAM, - prlimit=prlimit) - self.assertEqual('', stdout.rstrip()) - self.assertEqual(stderr.rstrip(), '') - - def check_limit(self, prlimit, resource, value): - code = ';'.join(('import resource', - 'print(resource.getrlimit(resource.%s))' % resource)) - args = [sys.executable, '-c', code] - stdout, stderr = processutils.execute(*args, prlimit=prlimit) - expected = (value, value) - self.assertEqual(str(expected), stdout.rstrip()) - - def test_address_space(self): - prlimit = self.limit_address_space() - self.check_limit(prlimit, 'RLIMIT_AS', prlimit.address_space) - - def test_core_size(self): - size = self.soft_limit(resource.RLIMIT_CORE, 1, 1024) - prlimit = processutils.ProcessLimits(core_file_size=size) - self.check_limit(prlimit, 'RLIMIT_CORE', prlimit.core_file_size) - - def test_cpu_time(self): - time = self.soft_limit(resource.RLIMIT_CPU, 1, 1024) - prlimit = processutils.ProcessLimits(cpu_time=time) - self.check_limit(prlimit, 'RLIMIT_CPU', prlimit.cpu_time) - - def test_data_size(self): - max_memory = self.memory_limit(resource.RLIMIT_DATA) - prlimit = processutils.ProcessLimits(data_size=max_memory) - self.check_limit(prlimit, 'RLIMIT_DATA', max_memory) - - def test_file_size(self): - size = self.soft_limit(resource.RLIMIT_FSIZE, 1, 1024) - prlimit = processutils.ProcessLimits(file_size=size) - self.check_limit(prlimit, 'RLIMIT_FSIZE', prlimit.file_size) - - def test_memory_locked(self): - max_memory = self.memory_limit(resource.RLIMIT_MEMLOCK) - prlimit = processutils.ProcessLimits(memory_locked=max_memory) - self.check_limit(prlimit, 'RLIMIT_MEMLOCK', max_memory) - - def test_resident_set_size(self): - max_memory = self.memory_limit(resource.RLIMIT_RSS) - prlimit = processutils.ProcessLimits(resident_set_size=max_memory) - self.check_limit(prlimit, 'RLIMIT_RSS', max_memory) - - def test_number_files(self): - nfiles = self.soft_limit(resource.RLIMIT_NOFILE, 1, 1024) - prlimit = processutils.ProcessLimits(number_files=nfiles) - self.check_limit(prlimit, 'RLIMIT_NOFILE', nfiles) - - def test_number_processes(self): - nprocs = self.soft_limit(resource.RLIMIT_NPROC, 1, 65535) - prlimit = processutils.ProcessLimits(number_processes=nprocs) - self.check_limit(prlimit, 'RLIMIT_NPROC', nprocs) - - def test_stack_size(self): - max_memory = self.memory_limit(resource.RLIMIT_STACK) - prlimit = processutils.ProcessLimits(stack_size=max_memory) - self.check_limit(prlimit, 'RLIMIT_STACK', max_memory) - - def test_unsupported_prlimit(self): - self.assertRaises(ValueError, processutils.ProcessLimits, xxx=33) - - def test_relative_path(self): - prlimit = self.limit_address_space() - program = sys.executable - - env = dict(os.environ) - env['PATH'] = os.path.dirname(program) - args = [os.path.basename(program), '-c', 'pass'] - processutils.execute(*args, prlimit=prlimit, env_variables=env) - - def test_execv_error(self): - prlimit = self.limit_address_space() - args = ['/missing_path/dont_exist/program'] - try: - processutils.execute(*args, prlimit=prlimit) - except processutils.ProcessExecutionError as exc: - self.assertEqual(1, exc.exit_code) - self.assertEqual('', exc.stdout) - expected = ('%s -m oslo_concurrency.prlimit: ' - 'failed to execute /missing_path/dont_exist/program: ' - % os.path.basename(sys.executable)) - self.assertIn(expected, exc.stderr) - else: - self.fail("ProcessExecutionError not raised") - - def test_setrlimit_error(self): - prlimit = self.limit_address_space() - - # trying to set a limit higher than the current hard limit - # with setrlimit() should fail. - higher_limit = prlimit.address_space + 1024 - - args = [sys.executable, '-m', 'oslo_concurrency.prlimit', - '--as=%s' % higher_limit, - '--'] - args.extend(self.SIMPLE_PROGRAM) - try: - processutils.execute(*args, prlimit=prlimit) - except processutils.ProcessExecutionError as exc: - self.assertEqual(1, exc.exit_code) - self.assertEqual('', exc.stdout) - expected = ('%s -m oslo_concurrency.prlimit: ' - 'failed to set the AS resource limit: ' - % os.path.basename(sys.executable)) - self.assertIn(expected, exc.stderr) - else: - self.fail("ProcessExecutionError not raised") diff --git a/oslo_concurrency/version.py b/oslo_concurrency/version.py deleted file mode 100644 index 76da3e4..0000000 --- a/oslo_concurrency/version.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2016 OpenStack Foundation -# -# 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 pbr.version - -version_info = pbr.version.VersionInfo('oslo_concurrency') diff --git a/oslo_concurrency/watchdog.py b/oslo_concurrency/watchdog.py deleted file mode 100644 index 7e48f20..0000000 --- a/oslo_concurrency/watchdog.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright (c) 2015 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. - -""" -Watchdog module. - -.. versionadded:: 0.4 -""" - -import contextlib -import logging -import threading - -from oslo_utils import timeutils - - -@contextlib.contextmanager -def watch(logger, action, level=logging.DEBUG, after=5.0): - """Log a message if an operation exceeds a time threshold. - - This context manager is expected to be used when you are going to - do an operation in code which might either deadlock or take an - extraordinary amount of time, and you'd like to emit a status - message back to the user that the operation is still ongoing but - has not completed in an expected amount of time. This is more user - friendly than logging 'start' and 'end' events and making users - correlate the events to figure out they ended up in a deadlock. - - :param logger: an object that complies to the logger definition - (has a .log method). - - :param action: a meaningful string that describes the thing you - are about to do. - - :param level: the logging level the message should be emitted - at. Defaults to logging.DEBUG. - - :param after: the duration in seconds before the message is - emitted. Defaults to 5.0 seconds. - - Example usage:: - - FORMAT = '%(asctime)-15s %(message)s' - logging.basicConfig(format=FORMAT) - LOG = logging.getLogger('mylogger') - - with watchdog.watch(LOG, "subprocess call", logging.ERROR): - subprocess.call("sleep 10", shell=True) - print "done" - - """ - watch = timeutils.StopWatch() - watch.start() - - def log(): - msg = "%s not completed after %0.3fs" % (action, watch.elapsed()) - logger.log(level, msg) - - timer = threading.Timer(after, log) - timer.start() - try: - yield - finally: - timer.cancel() - timer.join() diff --git a/releasenotes/notes/add_reno-3b4ae0789e9c45b4.yaml b/releasenotes/notes/add_reno-3b4ae0789e9c45b4.yaml deleted file mode 100644 index 46a2da6..0000000 --- a/releasenotes/notes/add_reno-3b4ae0789e9c45b4.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -other: - - Switch to reno for managing release notes. \ No newline at end of file diff --git a/releasenotes/source/_static/.placeholder b/releasenotes/source/_static/.placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/releasenotes/source/_templates/.placeholder b/releasenotes/source/_templates/.placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py deleted file mode 100644 index c55bb14..0000000 --- a/releasenotes/source/conf.py +++ /dev/null @@ -1,273 +0,0 @@ -# -*- coding: utf-8 -*- -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'oslosphinx', - 'reno.sphinxext', -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -# source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'oslo.concurrency Release Notes' -copyright = u'2016, oslo.concurrency Developers' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -from oslo_concurrency.version import version_info as oslo_concurrency_version -# The full version, including alpha/beta/rc tags. -release = oslo_concurrency_version.version_string_with_vcs() -# The short X.Y version. -version = oslo_concurrency_version.canonical_version_string() - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# today = '' -# Else, today_fmt is used as the format for a strftime call. -# today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -# keep_warnings = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'default' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -# html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -# html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# html_additional_pages = {} - -# If false, no module index is generated. -# html_domain_indices = True - -# If false, no index is generated. -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'oslo.concurrencyReleaseNotesDoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # 'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ('index', 'oslo.concurrencyReleaseNotes.tex', - u'oslo.concurrency Release Notes Documentation', - u'oslo.concurrency Developers', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# latex_use_parts = False - -# If true, show page references after internal links. -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# latex_appendices = [] - -# If false, no module index is generated. -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'oslo.concurrencyReleaseNotes', - u'oslo.concurrency Release Notes Documentation', - [u'oslo.concurrency Developers'], 1) -] - -# If true, show URL addresses after external links. -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'oslo.concurrencyReleaseNotes', - u'oslo.concurrency Release Notes Documentation', - u'oslo.concurrency Developers', 'oslo.concurrencyReleaseNotes', - 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -# texinfo_appendices = [] - -# If false, no module index is generated. -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# texinfo_no_detailmenu = False diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst deleted file mode 100644 index 1e0e149..0000000 --- a/releasenotes/source/index.rst +++ /dev/null @@ -1,8 +0,0 @@ -=============================== - oslo.concurrency Release Notes -=============================== - - .. toctree:: - :maxdepth: 1 - - unreleased diff --git a/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po b/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po deleted file mode 100644 index 12b9136..0000000 --- a/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po +++ /dev/null @@ -1,30 +0,0 @@ -# Andi Chandler , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.concurrency Release Notes 3.11.1\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-07-01 03:44+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2016-06-28 05:54+0000\n" -"Last-Translator: Andi Chandler \n" -"Language-Team: English (United Kingdom)\n" -"Language: en-GB\n" -"X-Generator: Zanata 3.7.3\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -msgid "3.10.0" -msgstr "3.10.0" - -msgid "Other Notes" -msgstr "Other Notes" - -msgid "Switch to reno for managing release notes." -msgstr "Switch to reno for managing release notes." - -msgid "Unreleased Release Notes" -msgstr "Unreleased Release Notes" - -msgid "oslo.concurrency Release Notes" -msgstr "oslo.concurrency Release Notes" diff --git a/releasenotes/source/unreleased.rst b/releasenotes/source/unreleased.rst deleted file mode 100644 index 5860a46..0000000 --- a/releasenotes/source/unreleased.rst +++ /dev/null @@ -1,5 +0,0 @@ -========================== - Unreleased Release Notes -========================== - -.. release-notes:: diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 81d8537..0000000 --- a/requirements.txt +++ /dev/null @@ -1,13 +0,0 @@ -# The order of packages is significant, because pip processes them in the order -# of appearance. Changing the order has an impact on the overall integration -# process, which may cause wedges in the gate later. - -pbr>=1.6 # Apache-2.0 -enum34;python_version=='2.7' or python_version=='2.6' or python_version=='3.3' # BSD -iso8601>=0.1.11 # MIT -oslo.config>=3.12.0 # Apache-2.0 -oslo.i18n>=2.1.0 # Apache-2.0 -oslo.utils>=3.16.0 # Apache-2.0 -six>=1.9.0 # MIT -fasteners>=0.7 # Apache-2.0 -retrying!=1.3.0,>=1.2.3 # Apache-2.0 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 9654f91..0000000 --- a/setup.cfg +++ /dev/null @@ -1,58 +0,0 @@ -[metadata] -name = oslo.concurrency -summary = Oslo Concurrency library -description-file = - README.rst -author = OpenStack -author-email = openstack-dev@lists.openstack.org -home-page = http://launchpad.net/oslo -classifier = - Environment :: OpenStack - Intended Audience :: Information Technology - Intended Audience :: System Administrators - License :: OSI Approved :: Apache Software License - Operating System :: POSIX :: Linux - Programming Language :: Python - Programming Language :: Python :: 2 - Programming Language :: Python :: 2.7 - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.4 - Programming Language :: Python :: 3.5 - -[files] -packages = - oslo_concurrency - -[entry_points] -oslo.config.opts = - oslo.concurrency = oslo_concurrency.opts:list_opts -console_scripts = - lockutils-wrapper = oslo_concurrency.lockutils:main - -[build_sphinx] -source-dir = doc/source -build-dir = doc/build -all_files = 1 - -[upload_sphinx] -upload-dir = doc/build/html - -[compile_catalog] -directory = oslo_concurrency/locale -domain = oslo_concurrency - -[update_catalog] -domain = oslo_concurrency -output_dir = oslo_concurrency/locale -input_file = oslo_concurrency/locale/oslo_concurrency.pot - -[extract_messages] -keywords = _ gettext ngettext l_ lazy_gettext -mapping_file = babel.cfg -output_file = oslo_concurrency/locale/oslo_concurrency.pot - -[pbr] -warnerrors = True - -[wheel] -universal = 1 diff --git a/setup.py b/setup.py deleted file mode 100644 index 782bb21..0000000 --- a/setup.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 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. - -# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT -import setuptools - -# In python < 2.7.4, a lazy loading of package `pbr` will break -# setuptools if some other modules registered functions in `atexit`. -# solution from: http://bugs.python.org/issue15881#msg170215 -try: - import multiprocessing # noqa -except ImportError: - pass - -setuptools.setup( - setup_requires=['pbr>=1.8'], - pbr=True) diff --git a/test-requirements.txt b/test-requirements.txt deleted file mode 100644 index e431107..0000000 --- a/test-requirements.txt +++ /dev/null @@ -1,16 +0,0 @@ -# The order of packages is significant, because pip processes them in the order -# of appearance. Changing the order has an impact on the overall integration -# process, which may cause wedges in the gate later. - -hacking<0.11,>=0.10.0 -oslotest>=1.10.0 # Apache-2.0 -coverage>=3.6 # Apache-2.0 -futures>=3.0;python_version=='2.7' or python_version=='2.6' # BSD -fixtures>=3.0.0 # Apache-2.0/BSD - -# These are needed for docs generation -oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0 -sphinx!=1.3b1,<1.3,>=1.2.1 # BSD -reno>=1.8.0 # Apache2 - -eventlet!=0.18.3,>=0.18.2 # MIT diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 580f08e..0000000 --- a/tox.ini +++ /dev/null @@ -1,42 +0,0 @@ -[tox] -minversion = 1.6 -envlist = py35,py34,py27,pep8 - -[testenv] -deps = -r{toxinidir}/test-requirements.txt -# We want to support both vanilla stdlib and eventlet monkey patched -commands = - lockutils-wrapper python setup.py testr --slowest --testr-args='{posargs}' - env TEST_EVENTLET=1 lockutils-wrapper python setup.py testr --slowest --testr-args='{posargs}' - -[testenv:pep8] -commands = flake8 - -[testenv:venv] -commands = {posargs} - -[testenv:docs] -commands = python setup.py build_sphinx - -[testenv:cover] -commands = python setup.py test --coverage --coverage-package-name=oslo_concurrency --testr-args='{posargs}' - -[flake8] -show-source = True -ignore = H405 -exclude=.venv,.git,.tox,dist,*lib/python*,*egg,build - -[hacking] -import_exceptions = - oslo_concurrency._i18n - -[testenv:pip-missing-reqs] -# do not install test-requirements as that will pollute the virtualenv for -# determining missing packages -# this also means that pip-missing-reqs must be installed separately, outside -# of the requirements.txt files -deps = pip_missing_reqs -commands = pip-missing-reqs -d --ignore-module=oslo_concurrency* --ignore-file=oslo_concurrency/tests/* --ignore-file=tests/ oslo_concurrency - -[testenv:releasenotes] -commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html