Merge branch 'master' into pytest/cache-unit-tests

This commit is contained in:
Caleb Beard 2022-09-11 23:29:35 -04:00 committed by GitHub
commit 7e161354dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
223 changed files with 5870 additions and 3719 deletions

View file

@ -7,7 +7,7 @@ Versions are `MAJOR.PATCH`.
# Changelog
Salt 3005 (2022-06-30)
Salt 3005 (2022-08-22)
======================
Removed
@ -29,6 +29,11 @@ Removed
- tplfile: When using tplfile in a SLS file in the root directory of file roots it returns empty. Now it returns the filename. (#61697)
- Remove SaltMessageServer.shutdown in favor of close.
Remove LoadBalancerWorker.stop in favor of close. (#61698)
- Removed the PyObjC dependency.
This addresses problems with building a one dir build for macOS.
It became problematic because depending on the macOS version, it pulls different dependencies, and we would either have to build a macos onedir for each macOS supported release, or ship a crippled onedir(because it would be tied to the macOS version where the onedir was built).
Since it's currently not being used, it's removed. (#62432)
Deprecated
@ -43,6 +48,7 @@ Deprecated
- Deprecate all Azure cloud modules (#62183)
- Deprecated ``defaults`` and ``preserve_context`` for ``salt.utils.functools.namespaced_function``.
Additionally, the behavior when ``preserve_namespace=True`` was passed is now the default in order not to require duplicating imports on the modules that are namespacing functions. (#62272)
- Deprecated the cassandra module in favor of the cassandra_cql module/returner. (#62327)
Changed
@ -243,6 +249,19 @@ Fixed
- Fix variable reuse causing requisite_in problems (#62264)
- Adding -G option to pkgdd cmd_prefix list when current_zone_only is True. (#62206)
- Don't expect ``lsof`` to be installed when trying check which minions are connected. (#62303)
- Added a pyinstaller hook that traverses the python used on the tiamat package to add all possible modules as hidden imports. (#62362)
- Fix use of random shuffle and sample functions as Jinja filters (#62372)
- All of the requirements provided in the requirements files are now included. The job of evaluating platform markers is not Salt's it's pip's. (#62392)
- Update all platforms to use pycparser 2.21 or greater for Py 3.9 or higher, fixes fips fault with openssl v3.x (#62400)
- Due to changes in the Netmiko library for the exception paths, need to check the version of Netmiko python library and then import the exceptions from different locations depending on the result. (#62405)
- Fixed urlparse typo in rpmbuild_pkgbuild.py (#62442)
- Fixing changes dict in pkg state to be consistent when installing and test=True. (#60995)
- Use fire_event_async when expecting a coroutine (#62453)
- Fixes import error under windows. (#62459)
- account for revision number in formulas to account for difference between bottle and formula (#62466)
- Fixed stacktrace on Windows when running pkg.list_pkgs (#62479)
- Update sanitizing masking for Salt SSH to include additional password like strings. (#62483)
- Fixes an issue where the minion could not connect to a master after 2 failed attempts (#62489)
Added
@ -301,6 +320,7 @@ Added
* Fix issues when processing inventory and there are groups with no members.
* Allow new types of targets for Ansible roster (#60056)
- Add sample and shuffle functions from random (#62225)
- Add "<tiamat> python" subcommand to allow execution or arbitrary scripts via bundled Python runtime (#62381)
Salt 3004.2 (2022-05-12)

View file

@ -6,6 +6,7 @@ include NOTICE
include README.rst
include SUPPORT.rst
include run.py
include pyproject.toml
include tests/*.py
recursive-include tests *
recursive-include requirements *.txt

1
changelog/47201.fixed Normal file
View file

@ -0,0 +1 @@
Fix mount.mounted with 'mount: False' reports unmounted file system as unchanged when running with test=True

1
changelog/54907.fixed Normal file
View file

@ -0,0 +1 @@
Fix spelling error for python_shell argument in dpkg_lower module

1
changelog/55269.fixed Normal file
View file

@ -0,0 +1 @@
Fixed malformed state return when testing file.managed with unavailable source file

1
changelog/60518.added Normal file
View file

@ -0,0 +1 @@
Added suport for Linux ppc64le core grains (cpu_model, virtual, productname, manufacturer, serialnumber) and arm core grains (serialnumber, productname)

1
changelog/61814.fixed Normal file
View file

@ -0,0 +1 @@
Fixed malformed state return when merge-serializing to an improperly formatted file

1
changelog/61816.fixed Normal file
View file

@ -0,0 +1 @@
Made cmdmod._run[_all]_quiet work during minion startup on MacOS with runas specified (which fixed mac_service)

View file

@ -1 +0,0 @@
Added a pyinstaller hook that traverses the python used on the tiamat package to add all possible modules as hidden imports.

View file

@ -1 +0,0 @@
All of the requirements provided in the requirements files are now included. The job of evaluating platform markers is not Salt's it's pip's.

1
changelog/62483.fixed Normal file
View file

@ -0,0 +1 @@
Update sanitizing masking for Salt SSH to include additional password like strings.

1
changelog/62502.fixed Normal file
View file

@ -0,0 +1 @@
Fix user.present to allow removing groups using optional_groups parameter and enforcing idempotent group membership.

1
changelog/62519.fixed Normal file
View file

@ -0,0 +1 @@
Fix possible tracebacks if there is a package with '------' or '======' in the description is installed on the Debian based minion.

1
changelog/62546.fixed Normal file
View file

@ -0,0 +1 @@
Use str() method instead of repo_line for when python3-apt is installed or not in aptpkg.py.

1
changelog/62576.fixed Normal file
View file

@ -0,0 +1 @@
Update setproctitle version for all platforms

View file

@ -15,6 +15,6 @@ serializer modules
msgpack
plist
python
toml
tomlmod
yaml
yamlex

View file

@ -1,5 +1,5 @@
salt.serializers.toml
=====================
.. automodule:: salt.serializers.toml
.. automodule:: salt.serializers.tomlmod
:members:

View file

@ -33,20 +33,20 @@ python3 you would need to specify the zeromq transport and python3.
.. code-block:: bash
nox -e 'pytest-zeromq-3(coverage=False)'
nox -e 'test-zeromq-3(coverage=False)'
As a contrast, when using the deprecated ``runtests.py`` test runner, the
command would be:
And because zeromq is the default transport, the following nox session can also be used:
.. code-block:: bash
nox -e 'runtests-zeromq-3(coverage=False)'
nox -e 'test-zeromq-3(coverage=False)'
To run all the tests but on the tcp transport, you would need to specify the tcp session.
.. code-block:: bash
nox -e 'pytest-tcp-3(coverage=False)'
nox -e 'test-tcp-3(coverage=False)'
As a contrast, when using the deprecated ``runtests.py`` test runner, the
command would be:
@ -94,7 +94,7 @@ Salt's test suite is located in the ``tests/`` directory in the root of
Salt's codebase.
With the migration to PyTest, Salt has created a separate directory for tests
that are written taking advantage of the full pottential of PyTest. These are
that are written taking advantage of the full potential of PyTest. These are
located under ``tests/pytests``.
As for the old test suite, it is divided into two main groups:
@ -174,14 +174,14 @@ all of the tests included in Salt's test suite:
.. code-block:: bash
nox -e 'pytest-zeromq-3(coverage=False)'
nox -e 'test-3(coverage=False)'
For more information about options you can pass the test runner, see the
``--help`` option:
.. code-block:: bash
nox -e 'pytest-zeromq-3(coverage=False)' -- --help
nox -e 'test-3(coverage=False)' -- --help
.. _running-test-subsections:
@ -192,23 +192,17 @@ Instead of running the entire test suite all at once, which can take a long time
there are several ways to run only specific groups of tests or individual tests:
* Run :ref:`unit tests only<running-unit-tests-no-daemons>`: ``nox -e
'pytest-zeromq-3(coverage=False)' -- tests/unit/``, using the deprecated ``runtests.py`` the command would be ``nox -e
'runtests-zeromq-3(coverage=False)' -- --unit-tests``
'test-3(coverage=False)' -- tests/unit/``.
* Run unit and integration tests for states: ``nox -e
'pytest-zeromq-3(coverage=False)' -- tests/unit/states/ tests/integration/states/``, using the deprecated
``runtests.py`` the command would be ``nox -e 'runtests-zeromq-3(coverage=False)' -- --state-tests``
* Run integration tests for an individual module: ``nox -e 'pytest-zeromq-3(coverage=False)' --
tests/integration/modules/test_virt.py``, using the deprecated ``runtests.py`` the command would be ``nox -e
'runtests-zeromq-3(coverage=False)' -- -n integration.modules.test_virt``
* Run unit tests for an individual module: ``nox -e 'pytest-zeromq-3(coverage=False)' --
tests/unit/modules/test_virt.py``, using the deprecated ``runtests.py`` the command would be ``nox -e
'runtests-zeromq-3(coverage=False)' -- -n unit.modules.test_virt``
'test-3(coverage=False)' -- tests/unit/states/ tests/integration/states/``.
* Run integration tests for an individual module: ``nox -e 'test-3(coverage=False)' --
tests/pytests/integration/modules/test_virt.py``.
* Run unit tests for an individual module: ``nox -e 'test-3(coverage=False)' --
tests/unit/modules/test_virt.py``.
* Run an individual test by using the class and test name (this example is for the
``test_default_kvm_profile`` test in the ``tests/integration/module/test_virt.py``):
``nox -e 'pytest-zeromq-3(coverage=False)' --
tests/integration/modules/test_virt.py::VirtTest::test_default_kvm_profile``, using the deprecated ``runtests.py`` the
command would be ``nox -e 'runtests-zeromq-3(coverage=False)' -- -n
integration.modules.test_virt.VirtTest.test_default_kvm_profile``
``test_default_kvm_profile`` test in the ``tests/pytests/integration/module/test_virt.py``):
``nox -e 'test-3(coverage=False)' --
tests/pytests/integration/modules/test_virt.py::VirtTest::test_default_kvm_profile``.
For more specific examples of how to run various test subsections or individual
@ -231,14 +225,7 @@ integration test daemons, simply add the unit directory as an argument:
.. code-block:: bash
nox -e 'pytest-zeromq-3(coverage=False)' -- tests/unit/
As a contrast, when using the deprecated ``runtests.py`` test runner, the
command would be:
.. code-block:: bash
nox -e 'runtests-zeromq-3(coverage=False)' -- --unit-tests
nox -e 'test-3(coverage=False)' -- tests/unit/
All of the other options to run individual tests, entire classes of tests, or
entire test modules still apply.
@ -269,14 +256,7 @@ To run tests marked as destructive, set the ``--run-destructive`` flag:
.. code-block:: bash
nox -e 'pytest-zeromq-3(coverage=False)' -- --run-destructive
As a contrast, when using the deprecated ``runtests.py`` test runner, the
command would be:
.. code-block:: bash
nox -e 'runtests-zeromq-3(coverage=False)' -- --run-destructive
nox -e 'test-3(coverage=False)' -- --run-destructive
Running Cloud Provider Tests
@ -319,18 +299,12 @@ must be provided:
do not include the single quotes.
Once all of the valid credentials for the cloud provider have been supplied, the
cloud provider tests can be run by setting the ``--cloud-provider-tests`` flag:
cloud provider tests can be run like:
.. code-block:: bash
nox -e 'pytest-cloud-3(coverage=False)'
nox -e 'test-cloud-3(coverage=False)'
As a contrast, when using the deprecated ``runtests.py`` test runner, the
command would be:
.. code-block:: bash
nox -e 'runtests-cloud-3(coverage=False)'
Automated Test Runs
===================
@ -535,37 +509,27 @@ Test Helpers
------------
Several Salt-specific helpers are available. A full list is available by inspecting
functions exported in `tests.support.helpers`.
functions exported under `tests/support/*.py`.
`@expensiveTest` -- Designates a test which typically requires a relatively costly
external resource, like a cloud virtual machine. This decorator is not normally
used by developers outside of the Salt core team.
Test Markers
------------
`@destructiveTest` -- Marks a test as potentially destructive. It will not be run
by the test runner unless the ``-run-destructive`` test is expressly passed.
`@pytest.mark.expensive_test` -- Designates a test which typically requires a
relatively costly external resource, like a cloud virtual machine. This decorator
is not normally used by developers outside of the Salt core team.
`@requires_network` -- Requires a network connection for the test to operate
successfully. If a network connection is not detected, the test will not run.
`@pytest.mark.destructive_test` -- Marks a test as potentially destructive. It
will not be run unless the ``--run-destructive`` flag is expressly passed.
`@requires_salt_modules` -- Requires all the modules in a list of modules in
order for the test to be executed. Otherwise, the test is skipped.
`@pytest.mark.requires_network` -- Requires a network connection for the test to
operate successfully. If a network connection is not detected, the test will not run.
`@requires_system_grains` -- Loads and passes the grains on the system as an
keyword argument to the test function with the name `grains`.
These are just a small preview of the supported marker. For a full listing, please
run:
`@skip_if_binaries_missing(['list', 'of', 'binaries'])` -- If called from inside a test,
the test will be skipped if the binaries are not all present on the system.
.. code-block:: bash
`@skip_if_not_root` -- If the test is not executed as root, it will be skipped.
`@with_system_user` -- Creates and optionally destroys a system user within a test case.
See implementation details in `tests.support.helpers` for details.
`@with_system_group` -- Creates and optionally destroys a system group within a test case.
See implementation details in `tests.support.helpers` for details.
`@with_system_user_and_group` -- Creates and optionally destroys a system user and group
within a test case. See implementation details in `tests.support.helpers` for details.
nox -e 'test-3(coverage=False)' -- --markers
.. _kitchen-salt jenkins setup: https://kitchen.saltproject.io/docs/file/docs/jenkins.md

View file

@ -780,7 +780,7 @@ executed:
.. code-block:: bash
nox -e 'pytest-3(coverage=False)' -- -v tests/pytests/unit/modules/test_fib.py
nox -e 'test-3(coverage=False)' -- -v tests/pytests/unit/modules/test_fib.py
This will report the status of the test: success, failure, or error. The
``-v`` flag increases output verbosity.

View file

@ -4,9 +4,6 @@
Salt 3005 release notes - Codename Phosphorus
=============================================
Salt 3005 is currently under development.
Python 3.5 and 3.6 deprecation
------------------------------
@ -154,20 +151,24 @@ For example:
Known issues
------------
To make use of Salt 3005 or later on a Salt master connected to SaltStack
Config, you must use SaltStack Config version 8.9.0 or later.
- To make use of Salt 3005 or later on a Salt master connected to SaltStack
Config, you must use SaltStack Config version 8.9.0 or later.
The root cause of the issue is a breaking change to
``AsyncClient._proc_function()``` in Salt, which is the function that the
raas-master uses to run ``salt-run`` commands. As this is a private API, there's
no expectation that the API should remain backward-compatible.
The root cause of the issue is a breaking change to
``AsyncClient._proc_function()``` in Salt, which is the function that the
raas-master uses to run ``salt-run`` commands. As this is a private API, there's
no expectation that the API should remain backward-compatible.
It is recommended to upgrade SaltStack Config before upgrading your Salt
masters. However, if a Salt master is upgraded to version 3005 before
upgrading SaltStack Config, the upgrade can still be completed.
It is recommended to upgrade SaltStack Config before upgrading your Salt
masters. However, if a Salt master is upgraded to version 3005 before
upgrading SaltStack Config, the upgrade can still be completed.
After upgrading SaltStack Config, including the SSC plugin on each Salt master,
restart the Salt masters.
After upgrading SaltStack Config, including the SSC plugin on each Salt master,
restart the Salt masters.
- Salt does not currently support napalm 4. Users will need to install napalm 3.x to
ensure they do not run into issue #62468
Removed
@ -189,6 +190,11 @@ Removed
- tplfile: When using tplfile in a SLS file in the root directory of file roots it returns empty. Now it returns the filename. (#61697)
- Remove SaltMessageServer.shutdown in favor of close.
Remove LoadBalancerWorker.stop in favor of close. (#61698)
- Removed the PyObjC dependency.
This addresses problems with building a one dir build for macOS.
It became problematic because depending on the macOS version, it pulls different dependencies, and we would either have to build a macos onedir for each macOS supported release, or ship a crippled onedir(because it would be tied to the macOS version where the onedir was built).
Since it's currently not being used, it's removed. (#62432)
Deprecated
@ -203,6 +209,12 @@ Deprecated
- Deprecate all Azure cloud modules (#62183)
- Deprecated ``defaults`` and ``preserve_context`` for ``salt.utils.functools.namespaced_function``.
Additionally, the behavior when ``preserve_namespace=True`` was passed is now the default in order not to require duplicating imports on the modules that are namespacing functions. (#62272)
- Added a pyinstaller hook that traverses the python used on the tiamat package to add all possible modules as hidden imports. (#62362)
- Fix use of random shuffle and sample functions as Jinja filters (#62372)
- All of the requirements provided in the requirements files are now included. The job of evaluating platform markers is not Salt's it's pip's. (#62392)
- Update all platforms to use pycparser 2.21 or greater for Py 3.9 or higher, fixes fips fault with openssl v3.x (#62400)
- Due to changes in the Netmiko library for the exception paths, need to check the version of Netmiko python library and then import the exceptions from different locations depending on the result. (#62405)
- Deprecated the cassandra module in favor of the cassandra_cql module/returner. (#62327)
Changed
@ -403,6 +415,14 @@ Fixed
- Fix variable reuse causing requisite_in problems (#62264)
- Adding -G option to pkgdd cmd_prefix list when current_zone_only is True. (#62206)
- Don't expect ``lsof`` to be installed when trying check which minions are connected. (#62303)
- Fixed urlparse typo in rpmbuild_pkgbuild.py (#62442)
- Fixing changes dict in pkg state to be consistent when installing and test=True. (#60995)
- Use fire_event_async when expecting a coroutine (#62453)
- Fixes import error under windows. (#62459)
- account for revision number in formulas to account for difference between bottle and formula (#62466)
- Fixed stacktrace on Windows when running pkg.list_pkgs (#62479)
- Update sanitizing masking for Salt SSH to include additional password like strings. (#62483)
- Fixes an issue where the minion could not connect to a master after 2 failed attempts (#62489)
Added
@ -461,3 +481,4 @@ Added
* Fix issues when processing inventory and there are groups with no members.
* Allow new types of targets for Ansible roster (#60056)
- Add sample and shuffle functions from random (#62225)
- Add "<tiamat> python" subcommand to allow execution or arbitrary scripts via bundled Python runtime (#62381)

View file

@ -20,6 +20,7 @@ Previous Releases
:maxdepth: 1
:glob:
3005*
3004*
3003*
3002*
@ -43,7 +44,6 @@ Upcoming Release
:maxdepth: 1
:glob:
3005*
3006*
.. seealso:: :ref:`Legacy salt-cloud release docs <legacy-salt-cloud-release-notes>`

View file

@ -97,7 +97,7 @@ Once all of the :ref:`requirements <getting_set_up_for_tests>` are installed, th
.. code-block:: bash
nox -e 'pytest-zeromq-3(coverage=False)'
nox -e 'test-3(coverage=False)'
The command above, if executed without any options, will run the entire suite of
integration and unit tests. Some tests require certain flags to run, such as
@ -111,10 +111,10 @@ You can pass any pytest options after the nox command like so:
.. code-block:: bash
nox -e 'pytest-zeromq-3(coverage=False)' -- tests/unit/modules/test_ps.py
nox -e 'test-3(coverage=False)' -- tests/unit/modules/test_ps.py
The above command will run the ``test_ps.py`` test with the zeromq transport, python3,
and pytest. The option after ``--`` can include any pytest options.
and pytest. Pass any pytest options after `--`
Running Integration Tests
-------------------------
@ -160,7 +160,7 @@ integration module tests:
.. code-block:: bash
nox -e 'pytest-zeromq-3(coverage=False)' -- tests/integration/modules/
nox -e 'test-3(coverage=False)' -- tests/integration/modules/
Running Unit Tests
------------------
@ -173,7 +173,7 @@ do and execute very quickly compared to the integration tests.
.. code-block:: bash
nox -e 'pytest-zeromq-3(coverage=False)' -- tests/unit/
nox -e 'test-3(coverage=False)' -- tests/unit/
.. _running-specific-tests:
@ -190,7 +190,7 @@ integration test directory, you must provide the file path.
.. code-block:: bash
nox -e 'pytest-zeromq-3(coverage=False)' -- tests/integration/modules/test_pillar.py
nox -e 'test-3(coverage=False)' -- tests/pytests/integration/modules/test_pillar.py
Some test files contain only one test class while other test files contain multiple
test classes. To run a specific test class within the file, append the name of
@ -198,14 +198,14 @@ the test class to the end of the file path:
.. code-block:: bash
nox -e 'pytest-zeromq-3(coverage=False)' -- tests/integration/modules/test_pillar.py::PillarModuleTest
nox -e 'test-3(coverage=False)' -- tests/pytests/integration/modules/test_pillar.py::PillarModuleTest
To run a single test within a file, append both the name of the test class the
individual test belongs to, as well as the name of the test itself:
.. code-block:: bash
nox -e 'pytest-zeromq-3(coverage=False)' -- tests/integration/modules/test_pillar.py::PillarModuleTest::test_data
nox -e 'test-3(coverage=False)' -- tests/pytests/integration/modules/test_pillar.py::PillarModuleTest::test_data
The following command is an example of how to execute a single test found in
@ -213,7 +213,7 @@ the ``tests/unit/modules/test_cp.py`` file:
.. code-block:: bash
nox -e 'pytest-zeromq-3(coverage=False)' -- tests/unit/modules/test_cp.py::CpTestCase::test_get_file_not_found
nox -e 'test-3(coverage=False)' -- tests/pytests/unit/modules/test_cp.py::CpTestCase::test_get_file_not_found
Writing Tests for Salt
======================
@ -322,22 +322,15 @@ Tests can be written to alter the system they are running on. This capability
is what fills in the gap needed to properly test aspects of system management
like package installation.
To write a destructive test, import and use the ``destructiveTest`` decorator for
the test method:
To write a destructive test, decorate the test function with the
``destructive_test``:
.. code-block:: python
import integration
from tests.support.helpers import destructiveTest
class PkgTest(integration.ModuleCase):
@destructiveTest
def test_pkg_install(self):
ret = self.run_function("pkg.install", name="finch")
self.assertSaltTrueReturn(ret)
ret = self.run_function("pkg.purge", name="finch")
self.assertSaltTrueReturn(ret)
@pytest.mark.destructive_test
def test_pkg_install(salt_cli):
ret = salt_cli.run("pkg.install", "finch")
assert ret
Writing Unit Tests
@ -359,7 +352,7 @@ Salt's unit tests utilize Python's mock class as well as `MagicMock`_. The
``@patch`` decorator is also heavily used when "blocking all the exits".
A simple example of a unit test currently in use in Salt is the
``test_get_file_not_found`` test in the ``tests/unit/modules/test_cp.py`` file.
``test_get_file_not_found`` test in the ``tests/pytests/unit/modules/test_cp.py`` file.
This test uses the ``@patch`` decorator and ``MagicMock`` to mock the return
of the call to Salt's ``cp.hash_file`` execution module function. This ensures
that we're testing the ``cp.get_file`` function directly, instead of inadvertently
@ -412,10 +405,10 @@ in the following docs:
Add a python module dependency to the test run
----------------------------------------------
The test dependencies for python modules are managed under the ``requirements/static``
directory. You will need to add your module to the appropriate file under ``requirements/static``.
The test dependencies for python modules are managed under the ``requirements/static/ci``
directory. You will need to add your module to the appropriate file under ``requirements/static/ci``.
When ``pre-commit`` is run it will create all of the needed requirement files
under ``requirements/static/py3{5,6,7}``. Nox will then use these files to install
under ``requirements/static/ci/py3{6,7,8,9}``. Nox will then use these files to install
the requirements for the tests.
Add a system dependency to the test run
@ -436,16 +429,28 @@ can be used
.. code-block:: python
# Import logging handler
from tests.support.helpers import TstSuiteLoggingHandler
def test_issue_58763_a(tmp_path, modules, state_tree, caplog):
venv_dir = tmp_path / "issue-2028-pip-installed"
sls_contents = """
test.random_hash:
module.run:
- size: 10
- hash_type: md5
"""
with pytest.helpers.temp_file("issue-58763.sls", sls_contents, state_tree):
with caplog.at_level(logging.DEBUG):
ret = modules.state.sls(
mods="issue-58763",
)
assert len(ret.raw) == 1
for k in ret.raw:
assert ret.raw[k]["result"] is True
assert (
"Detected legacy module.run syntax: test.random_hash" in caplog.messages
)
# .. inside test
with TstSuiteLoggingHandler() as handler:
for message in handler.messages:
if message.startswith("ERROR: This is the error message we seek"):
break
else:
raise AssertionError("Did not find error message")
Automated Test Runs

View file

@ -25,8 +25,6 @@ if __name__ == "__main__":
import nox # isort:skip
from nox.command import CommandFailed # isort:skip
IS_PY3 = sys.version_info > (2,)
# Be verbose when runing under a CI context
CI_RUN = (
os.environ.get("JENKINS_URL")
@ -34,8 +32,9 @@ CI_RUN = (
or os.environ.get("DRONE") is not None
)
PIP_INSTALL_SILENT = CI_RUN is False
SKIP_REQUIREMENTS_INSTALL = "SKIP_REQUIREMENTS_INSTALL" in os.environ
SKIP_REQUIREMENTS_INSTALL = os.environ.get("SKIP_REQUIREMENTS_INSTALL", "0") == "1"
EXTRA_REQUIREMENTS_INSTALL = os.environ.get("EXTRA_REQUIREMENTS_INSTALL")
COVERAGE_REQUIREMENT = os.environ.get("COVERAGE_REQUIREMENT") or "coverage==5.2"
# Global Path Definitions
REPO_ROOT = pathlib.Path(os.path.dirname(__file__)).resolve()
@ -66,6 +65,13 @@ RUNTESTS_LOGFILE = ARTIFACTS_DIR.joinpath(
os.environ["PYTHONDONTWRITEBYTECODE"] = "1"
def session_warn(session, message):
try:
session.warn(message)
except AttributeError:
session.log("WARNING: {}".format(message))
def session_run_always(session, *command, **kwargs):
"""
Patch nox to allow running some commands which would be skipped if --install-only is passed.
@ -86,16 +92,14 @@ def session_run_always(session, *command, **kwargs):
session._runner.global_config.install_only = old_install_only_value
def find_session_runner(session, name, **kwargs):
def find_session_runner(session, name, python_version, **kwargs):
name += "-{}".format(python_version)
for s, _ in session._runner.manifest.list_all_sessions():
if name not in s.signatures:
continue
for signature in s.signatures:
for key, value in kwargs.items():
param = "{}={!r}".format(key, value)
if IS_PY3:
# Under Python2 repr unicode string are always "u" prefixed, ie, u'a string'.
param = param.replace("u'", "'")
if param not in signature:
break
else:
@ -304,7 +308,7 @@ def _install_requirements(
def _run_with_coverage(session, *test_cmd, env=None):
if SKIP_REQUIREMENTS_INSTALL is False:
session.install(
"--progress-bar=off", "coverage==5.2", silent=PIP_INSTALL_SILENT
"--progress-bar=off", COVERAGE_REQUIREMENT, silent=PIP_INSTALL_SILENT
)
session.run("coverage", "erase")
python_path_env_var = os.environ.get("PYTHONPATH") or None
@ -345,16 +349,6 @@ def _run_with_coverage(session, *test_cmd, env=None):
# Sometimes some of the coverage files are corrupt which would trigger a CommandFailed
# exception
pass
# Generate report for salt code coverage
session.run(
"coverage",
"xml",
"-o",
str(COVERAGE_OUTPUT_DIR.joinpath("salt.xml").relative_to(REPO_ROOT)),
"--omit=tests/*",
"--include=salt/*",
env=coverage_base_env,
)
# Generate report for tests code coverage
session.run(
"coverage",
@ -365,13 +359,95 @@ def _run_with_coverage(session, *test_cmd, env=None):
"--include=tests/*",
env=coverage_base_env,
)
# Generate report for salt code coverage
session.run(
"coverage",
"xml",
"-o",
str(COVERAGE_OUTPUT_DIR.joinpath("salt.xml").relative_to(REPO_ROOT)),
"--omit=tests/*",
"--include=salt/*",
env=coverage_base_env,
)
@nox.session(python=_PYTHON_VERSIONS, name="pytest-parametrized")
def _report_coverage(session):
if SKIP_REQUIREMENTS_INSTALL is False:
session.install(
"--progress-bar=off", COVERAGE_REQUIREMENT, silent=PIP_INSTALL_SILENT
)
env = {
# The full path to the .coverage data file. Makes sure we always write
# them to the same directory
"COVERAGE_FILE": str(COVERAGE_OUTPUT_DIR / ".coverage"),
}
report_section = None
if session.posargs:
report_section = session.posargs.pop(0)
if report_section not in ("salt", "tests"):
session.error("The report section can only be one of 'salt', 'tests'.")
if session.posargs:
session.error(
"Only one argument can be passed to the session, which is optional "
"and is one of 'salt', 'tests'."
)
# Always combine and generate the XML coverage report
try:
session.run("coverage", "combine", env=env)
except CommandFailed:
# Sometimes some of the coverage files are corrupt which would trigger a CommandFailed
# exception
pass
if report_section == "salt":
json_coverage_file = (
COVERAGE_OUTPUT_DIR.relative_to(REPO_ROOT) / "coverage-salt.json"
)
cmd_args = [
"--omit=tests/*",
"--include=salt/*",
]
elif report_section == "tests":
json_coverage_file = (
COVERAGE_OUTPUT_DIR.relative_to(REPO_ROOT) / "coverage-tests.json"
)
cmd_args = [
"--omit=salt/*",
"--include=tests/*",
]
else:
json_coverage_file = (
COVERAGE_OUTPUT_DIR.relative_to(REPO_ROOT) / "coverage.json"
)
cmd_args = [
"--include=salt/*,tests/*",
]
session.run(
"coverage",
"json",
"-o",
str(json_coverage_file),
*cmd_args,
env=env,
)
session.run(
"coverage",
"report",
*cmd_args,
env=env,
)
@nox.session(python=_PYTHON_VERSIONS, name="test-parametrized")
@nox.parametrize("coverage", [False, True])
@nox.parametrize("transport", ["zeromq", "tcp"])
@nox.parametrize("crypto", [None, "m2crypto", "pycryptodome"])
def pytest_parametrized(session, coverage, transport, crypto):
def test_parametrized(session, coverage, transport, crypto):
"""
DO NOT CALL THIS NOX SESSION DIRECTLY
"""
@ -379,7 +455,8 @@ def pytest_parametrized(session, coverage, transport, crypto):
if _install_requirements(session, transport):
if crypto:
session.run(
session_run_always(
session,
"pip",
"uninstall",
"-y",
@ -405,14 +482,15 @@ def pytest_parametrized(session, coverage, transport, crypto):
@nox.session(python=_PYTHON_VERSIONS)
@nox.parametrize("coverage", [False, True])
def pytest(session, coverage):
def test(session, coverage):
"""
pytest session with zeromq transport and default crypto
"""
session.notify(
find_session_runner(
session,
"pytest-parametrized-{}".format(session.python),
"test-parametrized",
session.python,
coverage=coverage,
crypto=None,
transport="zeromq",
@ -420,19 +498,76 @@ def pytest(session, coverage):
)
@nox.session(python=_PYTHON_VERSIONS)
@nox.parametrize("coverage", [False, True])
def pytest(session, coverage):
"""
pytest session with zeromq transport and default crypto
"""
try:
session_name = session.name
except AttributeError:
session_name = session._runner.friendly_name
session_warn(
session,
"This nox session is deprecated, please call {!r} instead".format(
session_name.replace("pytest-", "test-")
),
)
session.notify(session_name.replace("pytest-", "test-"))
@nox.session(python=_PYTHON_VERSIONS, name="test-tcp")
@nox.parametrize("coverage", [False, True])
def test_tcp(session, coverage):
"""
pytest session with TCP transport and default crypto
"""
session.notify(
find_session_runner(
session,
"test-parametrized",
session.python,
coverage=coverage,
crypto=None,
transport="tcp",
)
)
@nox.session(python=_PYTHON_VERSIONS, name="pytest-tcp")
@nox.parametrize("coverage", [False, True])
def pytest_tcp(session, coverage):
"""
pytest session with TCP transport and default crypto
"""
try:
session_name = session.name
except AttributeError:
session_name = session._runner.friendly_name
session_warn(
session,
"This nox session is deprecated, please call {!r} instead".format(
session_name.replace("pytest-", "test-")
),
)
session.notify(session_name.replace("pytest-", "test-"))
@nox.session(python=_PYTHON_VERSIONS, name="test-zeromq")
@nox.parametrize("coverage", [False, True])
def test_zeromq(session, coverage):
"""
pytest session with zeromq transport and default crypto
"""
session.notify(
find_session_runner(
session,
"pytest-parametrized-{}".format(session.python),
"test-parametrized",
session.python,
coverage=coverage,
crypto=None,
transport="tcp",
transport="zeromq",
)
)
@ -443,12 +578,32 @@ def pytest_zeromq(session, coverage):
"""
pytest session with zeromq transport and default crypto
"""
try:
session_name = session.name
except AttributeError:
session_name = session._runner.friendly_name
session_warn(
session,
"This nox session is deprecated, please call {!r} instead".format(
session_name.replace("pytest-", "test-")
),
)
session.notify(session_name.replace("pytest-", "test-"))
@nox.session(python=_PYTHON_VERSIONS, name="test-m2crypto")
@nox.parametrize("coverage", [False, True])
def test_m2crypto(session, coverage):
"""
pytest session with zeromq transport and m2crypto
"""
session.notify(
find_session_runner(
session,
"pytest-parametrized-{}".format(session.python),
"test-parametrized",
session.python,
coverage=coverage,
crypto=None,
crypto="m2crypto",
transport="zeromq",
)
)
@ -460,13 +615,33 @@ def pytest_m2crypto(session, coverage):
"""
pytest session with zeromq transport and m2crypto
"""
try:
session_name = session.name
except AttributeError:
session_name = session._runner.friendly_name
session_warn(
session,
"This nox session is deprecated, please call {!r} instead".format(
session_name.replace("pytest-", "test-")
),
)
session.notify(session_name.replace("pytest-", "test-"))
@nox.session(python=_PYTHON_VERSIONS, name="test-tcp-m2crypto")
@nox.parametrize("coverage", [False, True])
def test_tcp_m2crypto(session, coverage):
"""
pytest session with TCP transport and m2crypto
"""
session.notify(
find_session_runner(
session,
"pytest-parametrized-{}".format(session.python),
"test-parametrized",
session.python,
coverage=coverage,
crypto="m2crypto",
transport="zeromq",
transport="tcp",
)
)
@ -477,13 +652,33 @@ def pytest_tcp_m2crypto(session, coverage):
"""
pytest session with TCP transport and m2crypto
"""
try:
session_name = session.name
except AttributeError:
session_name = session._runner.friendly_name
session_warn(
session,
"This nox session is deprecated, please call {!r} instead".format(
session_name.replace("pytest-", "test-")
),
)
session.notify(session_name.replace("pytest-", "test-"))
@nox.session(python=_PYTHON_VERSIONS, name="test-zeromq-m2crypto")
@nox.parametrize("coverage", [False, True])
def test_zeromq_m2crypto(session, coverage):
"""
pytest session with zeromq transport and m2crypto
"""
session.notify(
find_session_runner(
session,
"pytest-parametrized-{}".format(session.python),
"test-parametrized",
session.python,
coverage=coverage,
crypto="m2crypto",
transport="tcp",
transport="zeromq",
)
)
@ -494,12 +689,32 @@ def pytest_zeromq_m2crypto(session, coverage):
"""
pytest session with zeromq transport and m2crypto
"""
try:
session_name = session.name
except AttributeError:
session_name = session._runner.friendly_name
session_warn(
session,
"This nox session is deprecated, please call {!r} instead".format(
session_name.replace("pytest-", "test-")
),
)
session.notify(session_name.replace("pytest-", "test-"))
@nox.session(python=_PYTHON_VERSIONS, name="test-pycryptodome")
@nox.parametrize("coverage", [False, True])
def test_pycryptodome(session, coverage):
"""
pytest session with zeromq transport and pycryptodome
"""
session.notify(
find_session_runner(
session,
"pytest-parametrized-{}".format(session.python),
"test-parametrized",
session.python,
coverage=coverage,
crypto="m2crypto",
crypto="pycryptodome",
transport="zeromq",
)
)
@ -511,13 +726,33 @@ def pytest_pycryptodome(session, coverage):
"""
pytest session with zeromq transport and pycryptodome
"""
try:
session_name = session.name
except AttributeError:
session_name = session._runner.friendly_name
session_warn(
session,
"This nox session is deprecated, please call {!r} instead".format(
session_name.replace("pytest-", "test-")
),
)
session.notify(session_name.replace("pytest-", "test-"))
@nox.session(python=_PYTHON_VERSIONS, name="test-tcp-pycryptodome")
@nox.parametrize("coverage", [False, True])
def test_tcp_pycryptodome(session, coverage):
"""
pytest session with TCP transport and pycryptodome
"""
session.notify(
find_session_runner(
session,
"pytest-parametrized-{}".format(session.python),
"test-parametrized",
session.python,
coverage=coverage,
crypto="pycryptodome",
transport="zeromq",
transport="tcp",
)
)
@ -528,13 +763,33 @@ def pytest_tcp_pycryptodome(session, coverage):
"""
pytest session with TCP transport and pycryptodome
"""
try:
session_name = session.name
except AttributeError:
session_name = session._runner.friendly_name
session_warn(
session,
"This nox session is deprecated, please call {!r} instead".format(
session_name.replace("pytest-", "test-")
),
)
session.notify(session_name.replace("pytest-", "test-"))
@nox.session(python=_PYTHON_VERSIONS, name="test-zeromq-pycryptodome")
@nox.parametrize("coverage", [False, True])
def test_zeromq_pycryptodome(session, coverage):
"""
pytest session with zeromq transport and pycryptodome
"""
session.notify(
find_session_runner(
session,
"pytest-parametrized-{}".format(session.python),
"test-parametrized",
session.python,
coverage=coverage,
crypto="pycryptodome",
transport="tcp",
transport="zeromq",
)
)
@ -545,20 +800,22 @@ def pytest_zeromq_pycryptodome(session, coverage):
"""
pytest session with zeromq transport and pycryptodome
"""
session.notify(
find_session_runner(
session,
"pytest-parametrized-{}".format(session.python),
coverage=coverage,
crypto="pycryptodome",
transport="zeromq",
)
try:
session_name = session.name
except AttributeError:
session_name = session._runner.friendly_name
session_warn(
session,
"This nox session is deprecated, please call {!r} instead".format(
session_name.replace("pytest-", "test-")
),
)
session.notify(session_name.replace("pytest-", "test-"))
@nox.session(python=_PYTHON_VERSIONS, name="pytest-cloud")
@nox.session(python=_PYTHON_VERSIONS, name="test-cloud")
@nox.parametrize("coverage", [False, True])
def pytest_cloud(session, coverage):
def test_cloud(session, coverage):
"""
pytest cloud tests session
"""
@ -584,9 +841,28 @@ def pytest_cloud(session, coverage):
_pytest(session, coverage, cmd_args)
@nox.session(python=_PYTHON_VERSIONS, name="pytest-tornado")
@nox.session(python=_PYTHON_VERSIONS, name="pytest-cloud")
@nox.parametrize("coverage", [False, True])
def pytest_tornado(session, coverage):
def pytest_cloud(session, coverage):
"""
pytest cloud tests session
"""
try:
session_name = session.name
except AttributeError:
session_name = session._runner.friendly_name
session_warn(
session,
"This nox session is deprecated, please call {!r} instead".format(
session_name.replace("pytest-", "test-")
),
)
session.notify(session_name.replace("pytest-", "test-"))
@nox.session(python=_PYTHON_VERSIONS, name="test-tornado")
@nox.parametrize("coverage", [False, True])
def test_tornado(session, coverage):
"""
pytest tornado tests session
"""
@ -602,6 +878,25 @@ def pytest_tornado(session, coverage):
_pytest(session, coverage, session.posargs)
@nox.session(python=_PYTHON_VERSIONS, name="pytest-tornado")
@nox.parametrize("coverage", [False, True])
def pytest_tornado(session, coverage):
"""
pytest tornado tests session
"""
try:
session_name = session.name
except AttributeError:
session_name = session._runner.friendly_name
session_warn(
session,
"This nox session is deprecated, please call {!r} instead".format(
session_name.replace("pytest-", "test-")
),
)
session.notify(session_name.replace("pytest-", "test-"))
def _pytest(session, coverage, cmd_args):
# Create required artifacts directories
_create_ci_directories()
@ -611,13 +906,17 @@ def _pytest(session, coverage, cmd_args):
args = [
"--rootdir",
str(REPO_ROOT),
"--log-file={}".format(RUNTESTS_LOGFILE),
"--log-file-level=debug",
"--show-capture=no",
"-ra",
"-s",
"--showlocals",
]
for arg in cmd_args:
if arg == "--log-file" or arg.startswith("--log-file="):
break
else:
args.append("--log-file={}".format(RUNTESTS_LOGFILE))
args.extend(cmd_args)
if CI_RUN:
@ -644,6 +943,11 @@ def _pytest(session, coverage, cmd_args):
session.run("python", "-m", "pytest", *args, env=env)
@nox.session(python="3", name="report-coverage")
def report_coverage(session):
_report_coverage(session)
class Tee:
"""
Python class to mimic linux tee behaviour
@ -696,10 +1000,7 @@ def _lint(
stdout.seek(0)
contents = stdout.read()
if contents:
if IS_PY3:
contents = contents.decode("utf-8")
else:
contents = contents.encode("utf-8")
contents = contents.decode("utf-8")
sys.stdout.write(contents)
sys.stdout.flush()
if pylint_report_path:
@ -823,7 +1124,8 @@ def docs(session, compress, update, clean):
session.notify(
find_session_runner(
session,
"docs-man-{}".format(session.python),
"docs-man",
session.python,
compress=compress,
update=update,
clean=clean,

View file

@ -99,7 +99,7 @@ echo "#########################################################################"
################################################################################
if [[ $(id -u) -ne 0 ]]; then
echo ">>>>>> Re-launching as sudo <<<<<<"
exec sudo /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")"
exec sudo -E /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")"
fi
################################################################################

View file

@ -34,7 +34,7 @@ echo "Build Environment Script"
################################################################################
if [[ $(id -u) -ne 0 ]]; then
echo ">>>>>> Re-launching as sudo <<<<<<"
exec sudo /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")"
exec sudo -E /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")"
fi
################################################################################

View file

@ -12,6 +12,13 @@
# This script will upload a copy of the package to apple and wait
# for the notarization to return. This can take several minutes.
#
# This script should be run with sudo. If not, it will attempt to
# elevate and run with sudo. In order for the environment variables
# to be available in sudo you need to pass the `-E` option. For
# example:
#
# sudo -E ./notarize.sh
#
# Requirements:
# - Full Xcode Installation
# I had issues installing Xcode after installing Command Line Tools. This
@ -27,7 +34,7 @@
# Example:
# The following will notarize the 'salt-v2015.8.3-signed.pkg' file
#
# ./notarize.sh salt-v2015.8.3-signed.pkg
# sudo ./notarize.sh salt-v2015.8.3-signed.pkg
#
# Environment Setup:
#
@ -43,6 +50,15 @@
echo "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv"
echo "Notarize Salt Package"
# Make sure the script is launched with sudo
# We're doing this with notarize because the package we're notarizing was
# built with sudo... so, we need sudo here in order to staple the notarization
# to the package
if [[ $(id -u) -ne 0 ]]; then
echo ">>>>>> Re-launching as sudo <<<<<<"
exec sudo -E /bin/bash -c "$(printf '%q ' "${BASH_SOURCE[0]}" "$@")"
fi
################################################################################
# Check input parameters
################################################################################
@ -110,15 +126,27 @@ while sleep 30; do
# Uncomment for debugging
# cat "$NOTARIZE_INFO_LOG"
# once notarization is complete, run stapler and exit
# Continue checking until Status is no longer "in progress"
if ! grep -q "Status: in progress" "$NOTARIZE_INFO_LOG"; then
echo ""
echo "**** Stapling Notarization to the Package"
xcrun stapler staple "$PACKAGE" > /dev/null
break
fi
done
# Make sure the result is "success", then staple
if ! grep -q "Status: success" "$NOTARIZE_INFO_LOG"; then
echo "**** There was a problem notarizing the package"
echo "**** View the log for details:"
awk -F ': ' '/LogFileURL/ {print $2}' "$NOTARIZE_INFO_LOG"
exit 1
fi
echo "**** Stapling Notarization to the Package"
if ! xcrun stapler staple "$PACKAGE" > "$NOTARIZE_INFO_LOG"; then
cat "$NOTARIZE_INFO_LOG" 1>&2
exit 1
fi
echo "Notarize Salt Package Completed Successfully"
echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"

View file

@ -54,7 +54,7 @@ echo "Building Salt Package"
################################################################################
if [[ $(id -u) -ne 0 ]]; then
echo ">>>>>> Re-launching as sudo <<<<<<"
exec sudo /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")"
exec sudo -E /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")"
fi
################################################################################

View file

@ -49,7 +49,7 @@ echo "Signing Binaries"
################################################################################
if [[ $(id -u) -ne 0 ]]; then
echo ">>>>>> Re-launching as sudo <<<<<<"
exec sudo /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")"
exec sudo -E /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")"
fi
################################################################################
@ -69,48 +69,65 @@ echo "**** Setting Variables"
INSTALL_DIR=/opt/salt
PY_VERSION=3.9
PY_DOT_VERSION=3.9.12
CMD_OUTPUT=$(mktemp -t cmd.log)
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
################################################################################
# Add rpath to the Python binaries before signing
################################################################################
echo "**** Setting rpath in binaries"
install_name_tool $INSTALL_DIR/bin/python${PY_VERSION}m \
install_name_tool $INSTALL_DIR/bin/python${PY_VERSION} \
-add_rpath $INSTALL_DIR/.pyenv/versions/$PY_DOT_VERSION/lib \
-add_rpath $INSTALL_DIR/.pyenv/versions/$PY_DOT_VERSION/openssl/lib || echo "already present"
################################################################################
# Add rpath to the Python binaries before signing
################################################################################
echo "**** Setting rpath in binaries"
install_name_tool $INSTALL_DIR/bin/python3.7m \
-add_rpath $INSTALL_DIR/.pyenv/versions/3.7.12/lib \
-add_rpath $INSTALL_DIR/.pyenv/versions/3.7.12/openssl/lib || echo "already present"
################################################################################
# Sign python binaries in `bin` and `lib`
################################################################################
echo "**** Signing binaries that have entitlements (/opt/salt/.pyenv)"
find ${INSTALL_DIR}/.pyenv \
if ! find ${INSTALL_DIR}/.pyenv \
-type f \
-perm -u=x \
-follow \
! -name "*.so" \
! -name "*.dylib" \
! -name "*.py" \
! -name "*.sh" \
! -name "*.bat" \
! -name "*.pl" \
! -name "*.crt" \
! -name "*.key" \
-exec codesign --timestamp \
--options=runtime \
--verbose \
--entitlements ./entitlements.plist \
--sign "$DEV_APP_CERT" "{}" \;
--force \
--entitlements "$SCRIPT_DIR/entitlements.plist" \
--sign "$DEV_APP_CERT" "{}" \; > "$CMD_OUTPUT" 2>&1; then
echo "Failed to sign binaries"
echo "Failed to sign run with entitlements"
echo "output >>>>>>"
cat "$CMD_OUTPUT" 1>&2
echo "<<<<<< output"
exit 1
fi
echo "**** Signing dynamic libraries (*dylib) (/opt/salt/.pyenv)"
find ${INSTALL_DIR}/.pyenv \
if ! find ${INSTALL_DIR}/.pyenv \
-type f \
-name "*dylib" \
-follow \
-exec codesign --timestamp \
--options=runtime \
--verbose \
--sign "$DEV_APP_CERT" "{}" \;
--force \
--sign "$DEV_APP_CERT" "{}" \; > "$CMD_OUTPUT" 2>&1; then
echo "Failed to sign dynamic libraries"
echo "output >>>>>>"
cat "$CMD_OUTPUT" 1>&2
echo "<<<<<< output"
exit 1
fi
echo "**** Signing shared libraries (*.so) (/opt/salt/.pyenv)"
if ! echo "**** Signing shared libraries (*.so) (/opt/salt/.pyenv)"
find ${INSTALL_DIR}/.pyenv \
-type f \
-name "*.so" \
@ -118,7 +135,14 @@ find ${INSTALL_DIR}/.pyenv \
-exec codesign --timestamp \
--options=runtime \
--verbose \
--sign "$DEV_APP_CERT" "{}" \;
--force \
--sign "$DEV_APP_CERT" "{}" \; > "$CMD_OUTPUT" 2>&1; then
echo "Failed to sign shared libraries"
echo "output >>>>>>"
cat "$CMD_OUTPUT" 1>&2
echo "<<<<<< output"
exit 1
fi
echo "**** Signing Binaries Completed Successfully"
echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"

View file

@ -15,7 +15,8 @@ pycparser>=2.21
pyopenssl>=19.0.0
python-dateutil>=2.8.0
python-gnupg>=0.4.4
setproctitle>=1.1.10
setproctitle>=1.1.10 ; python_version < '3.10'
setproctitle>=1.2.3 ; python_version >= '3.10'
timelib>=0.2.5
vultr>=1.0.1

View file

@ -2,8 +2,8 @@ mock >= 3.0.0
# PyTest
pytest >= 6.1.0; python_version < "3.6"
pytest >= 7.0.1; python_version >= "3.6"
pytest-salt-factories >= 1.0.0rc17; sys_platform == 'win32'
pytest-salt-factories[docker] >= 1.0.0rc17; sys_platform != 'win32'
pytest-salt-factories >= 1.0.0rc20; sys_platform == 'win32'
pytest-salt-factories[docker] >= 1.0.0rc20; sys_platform != 'win32'
pytest-tempdir >= 2019.10.12
pytest-helpers-namespace >= 2019.1.8
pytest-subtests

View file

@ -687,9 +687,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via
@ -794,7 +794,7 @@ scp==0.14.1
# via junos-eznc
semantic-version==2.9.0
# via etcd3-py
setproctitle==1.2.2 ; python_version >= "3.10"
setproctitle==1.2.3 ; python_version >= "3.10"
# via -r requirements/static/pkg/linux.in
six==1.16.0
# via

View file

@ -685,9 +685,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via
@ -785,7 +785,7 @@ scp==0.13.2
# via junos-eznc
semantic-version==2.9.0
# via etcd3-py
setproctitle==1.1.10
setproctitle==1.3.2 ; python_version >= "3.10"
# via -r requirements/darwin.txt
six==1.16.0
# via

View file

@ -766,7 +766,7 @@ scp==0.13.6
# via junos-eznc
semantic-version==2.9.0
# via etcd3-py
setproctitle==1.2.2 ; python_version >= "3.10"
setproctitle==1.2.3 ; python_version >= "3.10"
# via -r requirements/static/pkg/linux.in
six==1.16.0
# via

View file

@ -682,9 +682,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via
@ -781,7 +781,7 @@ scp==0.13.2
# via junos-eznc
semantic-version==2.9.0
# via etcd3-py
setproctitle==1.1.10
setproctitle==1.2.3 ; python_version >= "3.10"
# via -r requirements/static/pkg/freebsd.in
six==1.16.0
# via

View file

@ -766,7 +766,7 @@ scp==0.13.6
# via junos-eznc
semantic-version==2.9.0
# via etcd3-py
setproctitle==1.2.2 ; python_version >= "3.10"
setproctitle==1.2.3 ; python_version >= "3.10"
# via -r requirements/static/pkg/linux.in
six==1.16.0
# via

View file

@ -704,9 +704,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via
@ -822,7 +822,7 @@ scp==0.13.2
# via junos-eznc
semantic-version==2.9.0
# via etcd3-py
setproctitle==1.2.2 ; python_version >= "3.10"
setproctitle==1.2.3 ; python_version >= "3.10"
# via -r requirements/static/pkg/linux.in
six==1.16.0
# via

View file

@ -351,7 +351,7 @@ s3transfer==0.3.3
# via boto3
sed==0.3.1
# via -r requirements/static/ci/windows.in
setproctitle==1.1.10
setproctitle==1.2.3; python_version >= "3.10"
# via -r requirements/static/pkg/py3.10/windows.txt
six==1.15.0
# via

View file

@ -735,9 +735,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.1
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via

View file

@ -709,9 +709,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via

View file

@ -726,9 +726,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via

View file

@ -730,9 +730,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via

View file

@ -721,9 +721,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via
@ -825,7 +825,7 @@ scp==0.13.2
# netmiko
semantic-version==2.9.0
# via etcd3-py
setproctitle==1.1.10
setproctitle==1.1.10 ; python_version < "3.10"
# via -r requirements/static/pkg/freebsd.in
six==1.16.0
# via

View file

@ -741,9 +741,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via

View file

@ -264,9 +264,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories==1.0.0rc17 ; sys_platform == "win32"
pytest-salt-factories==1.0.0rc20 ; sys_platform == "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via
@ -358,7 +358,7 @@ sed==0.3.1
# via -r requirements/static/ci/windows.in
semantic-version==2.9.0
# via etcd3-py
setproctitle==1.1.10
setproctitle==1.1.10 ; python_version < "3.10"
# via -r requirements/windows.txt
six==1.16.0
# via

View file

@ -720,9 +720,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via

View file

@ -712,9 +712,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via
@ -816,7 +816,7 @@ scp==0.13.2
# netmiko
semantic-version==2.9.0
# via etcd3-py
setproctitle==1.1.10
setproctitle==1.1.10 ; python_version < "3.10"
# via -r requirements/static/pkg/freebsd.in
six==1.16.0
# via

View file

@ -732,9 +732,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via

View file

@ -253,9 +253,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories==1.0.0rc17 ; sys_platform == "win32"
pytest-salt-factories==1.0.0rc20 ; sys_platform == "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via
@ -347,7 +347,7 @@ sed==0.3.1
# via -r requirements/static/ci/windows.in
semantic-version==2.9.0
# via etcd3-py
setproctitle==1.1.10
setproctitle==1.1.10 ; python_version < "3.10"
# via -r requirements/windows.txt
six==1.15.0
# via

View file

@ -723,9 +723,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via

View file

@ -718,9 +718,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via
@ -823,7 +823,7 @@ scp==0.13.2
# netmiko
semantic-version==2.9.0
# via etcd3-py
setproctitle==1.1.10
setproctitle==1.1.10 ; python_version < "3.10"
# via -r requirements/darwin.txt
six==1.16.0
# via

View file

@ -715,9 +715,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via
@ -819,7 +819,7 @@ scp==0.13.2
# netmiko
semantic-version==2.9.0
# via etcd3-py
setproctitle==1.1.10
setproctitle==1.1.10 ; python_version < "3.10"
# via -r requirements/static/pkg/freebsd.in
six==1.16.0
# via

View file

@ -737,9 +737,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories[docker]==1.0.0rc17 ; sys_platform != "win32"
pytest-salt-factories[docker]==1.0.0rc20 ; sys_platform != "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via

View file

@ -254,9 +254,9 @@ pytest-helpers-namespace==2021.4.29
# pytest-shell-utilities
pytest-httpserver==1.0.4
# via -r requirements/pytest.txt
pytest-salt-factories==1.0.0rc17 ; sys_platform == "win32"
pytest-salt-factories==1.0.0rc20 ; sys_platform == "win32"
# via -r requirements/pytest.txt
pytest-shell-utilities==1.4.0
pytest-shell-utilities==1.6.0
# via pytest-salt-factories
pytest-skip-markers==1.2.0
# via
@ -348,7 +348,7 @@ sed==0.3.1
# via -r requirements/static/ci/windows.in
semantic-version==2.9.0
# via etcd3-py
setproctitle==1.1.10
setproctitle==1.1.10 ; python_version < "3.10"
# via -r requirements/windows.txt
six==1.15.0
# via

View file

@ -6,7 +6,8 @@ pycparser>=2.21; python_version >= '3.9'
pyopenssl>=19.0.0
python-dateutil>=2.8.0
python-gnupg>=0.4.4
setproctitle>=1.1.10
setproctitle>=1.1.10 ; python_version < '3.10'
setproctitle>=1.2.3 ; python_version >= '3.10'
timelib>=0.2.5
distro>=1.3.0
importlib_metadata>=3.3.0; python_version >= '3.6' and python_version < '3.10'

View file

@ -7,8 +7,8 @@ pyopenssl>=19.0.0
python-dateutil>=2.8.0
python-gnupg>=0.4.4
rpm-vercmp
setproctitle>=1.1.10; python_version < '3.10'
setproctitle>=1.2.2; python_version >= '3.10'
setproctitle>=1.1.10 ; python_version < '3.10'
setproctitle>=1.2.3 ; python_version >= '3.10'
timelib>=0.2.5
importlib_metadata>=3.3.0; python_version >= '3.6' and python_version < '3.10'
importlib_metadata==4.6.3; python_version >= '3.10'

View file

@ -93,7 +93,7 @@ requests==2.25.1
# -r requirements/base.txt
# apache-libcloud
# vultr
setproctitle==1.1.10
setproctitle==1.3.2 ; python_version >= "3.10"
# via -r requirements/darwin.txt
six==1.16.0
# via

View file

@ -75,7 +75,7 @@ pyzmq==23.2.0 ; python_version >= "3.9"
# via -r requirements/zeromq.txt
requests==2.25.1
# via -r requirements/base.txt
setproctitle==1.1.10
setproctitle==1.3.2 ; python_version >= "3.10"
# via -r requirements/static/pkg/freebsd.in
six==1.16.0
# via

View file

@ -77,7 +77,7 @@ requests==2.25.1
# via -r requirements/base.txt
rpm-vercmp==0.1.2
# via -r requirements/static/pkg/linux.in
setproctitle==1.2.2 ; python_version >= "3.10"
setproctitle==1.3.2 ; python_version >= "3.10"
# via -r requirements/static/pkg/linux.in
six==1.16.0
# via

View file

@ -108,7 +108,7 @@ requests==2.25.1
# via
# -r requirements/base.txt
# -r requirements/windows.txt
setproctitle==1.1.10
setproctitle==1.2.3 ; python_version >= "3.10"
# via -r requirements/windows.txt
six==1.15.0
# via

View file

@ -75,7 +75,7 @@ pyzmq==18.0.1 ; python_version < "3.9"
# via -r requirements/zeromq.txt
requests==2.25.1
# via -r requirements/base.txt
setproctitle==1.1.10
setproctitle==1.1.10 ; python_version < "3.10"
# via -r requirements/static/pkg/freebsd.in
six==1.16.0
# via

View file

@ -112,7 +112,7 @@ requests==2.25.1
# via
# -r requirements/base.txt
# -r requirements/windows.txt
setproctitle==1.1.10
setproctitle==1.1.10 ; python_version < "3.10"
# via -r requirements/windows.txt
six==1.16.0
# via

View file

@ -75,7 +75,7 @@ pyzmq==19.0.0 ; python_version < "3.9"
# via -r requirements/zeromq.txt
requests==2.25.1
# via -r requirements/base.txt
setproctitle==1.1.10
setproctitle==1.1.10 ; python_version < "3.10"
# via -r requirements/static/pkg/freebsd.in
six==1.16.0
# via

View file

@ -112,7 +112,7 @@ requests==2.25.1
# via
# -r requirements/base.txt
# -r requirements/windows.txt
setproctitle==1.1.10
setproctitle==1.1.10 ; python_version < "3.10"
# via -r requirements/windows.txt
six==1.15.0
# via

View file

@ -95,7 +95,7 @@ requests==2.25.1
# -r requirements/base.txt
# apache-libcloud
# vultr
setproctitle==1.1.10
setproctitle==1.1.10 ; python_version < "3.10"
# via -r requirements/darwin.txt
six==1.16.0
# via

View file

@ -77,7 +77,7 @@ pyzmq==23.2.0 ; python_version >= "3.9"
# via -r requirements/zeromq.txt
requests==2.25.1
# via -r requirements/base.txt
setproctitle==1.1.10
setproctitle==1.1.10 ; python_version < "3.10"
# via -r requirements/static/pkg/freebsd.in
six==1.16.0
# via

View file

@ -112,7 +112,7 @@ requests==2.25.1
# via
# -r requirements/base.txt
# -r requirements/windows.txt
setproctitle==1.1.10
setproctitle==1.1.10 ; python_version < "3.10"
# via -r requirements/windows.txt
six==1.15.0
# via

View file

@ -25,7 +25,8 @@ pyopenssl>=20.0.1
python-dateutil>=2.8.1
python-gnupg>=0.4.7
requests>=2.25.1
setproctitle
setproctitle>=1.1.10 ; python_version < '3.10'
setproctitle>=1.2.3 ; python_version >= '3.10'
timelib>=0.2.5
urllib3>=1.26.5
# Watchdog pulls in a GPL-3 package, argh, which cannot be shipped on the

2
run.py
View file

@ -59,6 +59,8 @@ def py_shell():
def python_runtime():
import traceback
# extract the absolute script path to alter sys.path and specific dunder variables
script = pathlib.Path(sys.argv[2]).expanduser().resolve()
sys.path.insert(0, str(script.parent))

View file

@ -295,7 +295,7 @@ class AsyncReqChannel:
ret = yield self._crypted_transfer(load, timeout=timeout, raw=raw)
break
except Exception as exc: # pylint: disable=broad-except
log.error("Failed to send msg %r", exc)
log.trace("Failed to send msg %r", exc)
if _try >= tries:
raise
else:

File diff suppressed because it is too large Load diff

View file

@ -5,5 +5,58 @@ Do NOT, import any salt modules (salt.utils, salt.config, etc.) into this file,
as this may result in circular imports.
"""
class _Constant:
"""
This class implements a way to create constants in python.
NOTE:
- This is not really a constant, ie, the `is` check will not work, you'll
have to use `==`.
- This class SHALL NOT be considered public API and might change or even
go away at any given time.
"""
__slots__ = ("name", "value")
def __init__(self, name, value=None):
self.name = name
self.value = value
def __hash__(self):
return hash((self.name, self.value))
def __eq__(self, other):
if not isinstance(other, self.__class__):
return False
if self.name != other.name:
return False
return self.value == other.value
def __get_state__(self):
return {
"name": self.name,
"value": self.value,
}
def __set_state__(self, state):
return self.__class__(state["name"], state["value"])
def __repr__(self):
if self.value:
return "<Constant.{} value={}>".format(self.name, self.value)
return "<Constant.{}>".format(self.name)
# Default delimiter for multi-level traversal in targeting
DEFAULT_TARGET_DELIM = ":"
"""
Used in functions to define that a keyword default is not set.
It's used to differentiate from `None`, `True`, `False` which, in some
cases are proper defaults and are also proper values to pass.
"""
NOT_SET = _Constant("NOT_SET")

View file

@ -197,6 +197,15 @@ def _linux_cpudata():
elif key == "Processor":
grains["cpu_model"] = val.split("-")[0]
grains["num_cpus"] = 1
# PPC64LE support - /proc/cpuinfo
#
# processor : 0
# cpu : POWER9 (architected), altivec supported
# clock : 2750.000000MHz
# revision : 2.2 (pvr 004e 0202)
elif key == "cpu":
grains["cpu_model"] = val
if "num_cpus" not in grains:
grains["num_cpus"] = 0
if "cpu_model" not in grains:
@ -878,6 +887,17 @@ def _virtual(osdata):
elif "hyperv" in line:
grains["virtual"] = "HyperV"
break
elif line == "ibm_power-kvm":
grains["virtual"] = "kvm"
break
elif line == "ibm_power-lpar_shared":
grains["virtual"] = "LPAR"
grains["virtual_subtype"] = "shared"
break
elif line == "ibm_power-lpar_dedicated":
grains["virtual"] = "LPAR"
grains["virtual_subtype"] = "dedicated"
break
break
elif command == "dmidecode":
# Product Name: VirtualBox
@ -1533,6 +1553,55 @@ def _osx_platform_data():
return grains
def _linux_devicetree_platform_data():
"""
Additional data for Linux Devicetree subsystem - https://www.kernel.org/doc/html/latest/devicetree/usage-model.html
Returns: A dictionary containing values for the following:
- manufacturer
- produtname
- serialnumber
"""
def _read_dt_string(path):
try:
# /proc/device-tree should be used instead of /sys/firmware/devicetree/base
# see https://github.com/torvalds/linux/blob/v5.13/Documentation/ABI/testing/sysfs-firmware-ofw#L14
loc = "/proc/device-tree/{}".format(path)
if os.path.isfile(loc):
with salt.utils.files.fopen(loc, mode="r") as f:
return f.read().rstrip("\x00") # all strings are null-terminated
except Exception: # pylint: disable=broad-except
return None
return None
grains = {}
model = _read_dt_string("model")
if model:
# Devicetree spec v0.3, section 2.3.2
tmp = model.split(",", 1)
if len(tmp) == 2:
# format "manufacturer,model"
grains["manufacturer"] = tmp[0]
grains["productname"] = tmp[1]
else:
grains["productname"] = tmp[0]
# not in specs, but observed on "Linux on Power" systems
systemid = _read_dt_string("system-id")
if systemid:
grains["serialnumber"] = systemid
# not in spec, but populated for ARM Linux - https://github.com/torvalds/linux/blob/master/arch/arm/kernel/setup.c#L961
# as this is "more correct" naming, this should have priority over system-id
serial = _read_dt_string("serial-number")
if serial:
grains["serialnumber"] = serial
return grains
def id_():
"""
Return the id
@ -2143,6 +2212,10 @@ def os_data():
grains["os"] = _OS_NAME_MAP.get(shortname, distroname)
grains.update(_linux_cpudata())
grains.update(_linux_gpu_data())
# only if devicetree is mounted
if os.path.isdir("/proc/device-tree"):
grains.update(_linux_devicetree_platform_data())
elif grains["kernel"] == "SunOS":
if salt.utils.platform.is_smartos():
# See https://github.com/joyent/smartos-live/issues/224

View file

@ -820,11 +820,11 @@ class MinionBase:
self.connected = True
raise salt.ext.tornado.gen.Return((opts["master"], pub_channel))
except SaltClientError:
if pub_channel:
pub_channel.close()
if attempts == tries:
# Exhausted all attempts. Return exception.
self.connected = False
if pub_channel:
pub_channel.close()
raise
def _discover_masters(self):
@ -1622,7 +1622,7 @@ class Minion(MinionBase):
with salt.utils.event.get_event(
"minion", opts=self.opts, listen=False
) as event:
ret = yield event.fire_event(
ret = yield event.fire_event_async(
load, "__master_req_channel_payload", timeout=timeout
)
raise salt.ext.tornado.gen.Return(ret)

View file

@ -182,6 +182,9 @@ if not HAS_APT:
self.file = str(pathlib.Path(os.sep, "etc", "apt", "sources.list"))
self._parse_sources(line)
def str(self):
return self.repo_line()
def repo_line(self):
"""
Return the repo line for the sources file
@ -2946,7 +2949,7 @@ def mod_repo(repo, saltenv="base", aptkey=True, **kwargs):
if mod_source.uri != repo_uri:
mod_source.uri = repo_uri
mod_source.line = mod_source.repo_line()
mod_source.line = mod_source.str()
sources.save()
# on changes, explicitly refresh

View file

@ -1,4 +1,10 @@
"""
.. warning::
The `cassandra` module is deprecated in favor of the `cassandra_cql`
module.
Cassandra NoSQL Database Module
:depends: - pycassa Cassandra Python adapter
@ -14,6 +20,7 @@ Cassandra NoSQL Database Module
import logging
import salt.utils.path
from salt.utils.versions import warn_until_date
log = logging.getLogger(__name__)
@ -37,6 +44,12 @@ def __virtual__():
"The cassandra execution module cannot be loaded: pycassa not installed.",
)
warn_until_date(
"20240101",
"The cassandra returner is broken and deprecated, and will be removed"
" after {date}. Use the cassandra_cql returner instead",
)
if HAS_PYCASSA and salt.utils.path.which("nodetool"):
return "cassandra"
return (

View file

@ -443,12 +443,13 @@ def _run(
# Ensure environment is correct for a newly logged-in user by running
# the command under bash as a login shell
try:
user_shell = __salt__["user.info"](runas)["shell"]
# Do not rely on populated __salt__ dict (ie avoid __salt__['user.info'])
user_shell = [x for x in pwd.getpwall() if x.pw_name == runas][0].pw_shell
if re.search("bash$", user_shell):
cmd = "{shell} -l -c {cmd}".format(
shell=user_shell, cmd=_cmd_quote(cmd)
)
except KeyError:
except (AttributeError, IndexError):
pass
# Ensure the login is simulated correctly (note: su runs sh, not bash,

View file

@ -271,14 +271,13 @@ def _get_pkg_info(*packages, **kwargs):
"origin:${Origin}\\n"
"homepage:${Homepage}\\n"
"status:${db:Status-Abbrev}\\n"
"======\\n"
"description:${Description}\\n"
"------\\n'"
"\\n*/~^\\\\*\\n'"
)
cmd += " {}".format(" ".join(packages))
cmd = cmd.strip()
call = __salt__["cmd.run_all"](cmd, python_chell=False)
call = __salt__["cmd.run_all"](cmd, python_shell=False)
if call["retcode"]:
if failhard:
raise CommandExecutionError(
@ -287,9 +286,13 @@ def _get_pkg_info(*packages, **kwargs):
else:
return ret
for pkg_info in [elm for elm in re.split(r"------", call["stdout"]) if elm.strip()]:
for pkg_info in [
elm
for elm in re.split(r"\r?\n\*/~\^\\\*(\r?\n|)", call["stdout"])
if elm.strip()
]:
pkg_data = {}
pkg_info, pkg_descr = re.split(r"======", pkg_info)
pkg_info, pkg_descr = pkg_info.split("\ndescription:", 1)
for pkg_info_line in [
el.strip() for el in pkg_info.split(os.linesep) if el.strip()
]:
@ -299,7 +302,7 @@ def _get_pkg_info(*packages, **kwargs):
install_date = _get_pkg_install_time(pkg_data.get("package"))
if install_date:
pkg_data["install_date"] = install_date
pkg_data["description"] = pkg_descr.split(":", 1)[-1]
pkg_data["description"] = pkg_descr
ret.append(pkg_data)
return ret

View file

@ -21,10 +21,11 @@ log = logging.getLogger(__name__)
__virtualname__ = "kernelpkg"
# Import functions from yumpkg
# pylint: disable=invalid-name, protected-access
_yum = salt.utils.functools.namespaced_function(salt.modules.yumpkg._yum, globals())
# pylint: enable=invalid-name, protected-access
if __IMPORT_ERROR is None:
# Import functions from yumpkg
# pylint: disable=invalid-name, protected-access
_yum = salt.utils.functools.namespaced_function(salt.modules.yumpkg._yum, globals())
# pylint: enable=invalid-name, protected-access
def __virtual__():
@ -33,7 +34,7 @@ def __virtual__():
"""
if __IMPORT_ERROR:
return (False, __IMPORT_ERROR)
return False, __IMPORT_ERROR
if __grains__.get("os_family", "") == "RedHat":
return __virtualname__
@ -45,7 +46,7 @@ def __virtual__():
):
return __virtualname__
return (False, "Module kernelpkg_linux_yum: no YUM based system detected")
return False, "Module kernelpkg_linux_yum: no YUM based system detected"
def active():

View file

@ -258,7 +258,10 @@ def latest_version(*names, **kwargs):
def get_version(pkg_info):
# Perhaps this will need an option to pick devel by default
return pkg_info["versions"]["stable"] or pkg_info["versions"]["devel"]
version = pkg_info["versions"]["stable"] or pkg_info["versions"]["devel"]
if pkg_info["versions"]["bottle"] and pkg_info["revision"] >= 1:
version = "{}_{}".format(version, pkg_info["revision"])
return version
versions_dict = {key: get_version(val) for key, val in _info(*names).items()}

View file

@ -14,7 +14,7 @@ import salt.utils.dictupdate
import salt.utils.functools
import salt.utils.odict
import salt.utils.yaml
from salt.defaults import DEFAULT_TARGET_DELIM
from salt.defaults import DEFAULT_TARGET_DELIM, NOT_SET
from salt.exceptions import CommandExecutionError
__proxyenabled__ = ["*"]
@ -24,7 +24,7 @@ log = logging.getLogger(__name__)
def get(
key,
default=None,
default=NOT_SET,
merge=False,
merge_nested_lists=None,
delimiter=DEFAULT_TARGET_DELIM,
@ -122,7 +122,7 @@ def get(
salt '*' pillar.get pkg:apache
salt '*' pillar.get abc::def|ghi delimiter='|'
"""
if default is None:
if default == NOT_SET:
default = KeyError
if not __opts__.get("pillar_raise_on_missing"):
if default is KeyError:

View file

@ -154,7 +154,7 @@ def _get_deps(deps, tree_base, saltenv="base"):
"'deps' must be a Python list or comma-separated string"
)
for deprpm in deps:
parsed = urllib.parse._urlparse(deprpm)
parsed = urllib.parse.urlparse(deprpm)
depbase = os.path.basename(deprpm)
dest = os.path.join(tree_base, depbase)
if parsed.scheme:

View file

@ -178,12 +178,13 @@ Functions to interact with Hashicorp Vault.
import logging
import os
from salt.defaults import NOT_SET
from salt.exceptions import CommandExecutionError
log = logging.getLogger(__name__)
def read_secret(path, key=None, metadata=False, default=None):
def read_secret(path, key=None, metadata=False, default=NOT_SET):
"""
.. versionchanged:: 3001
The ``default`` argument has been added. When the path or path/key
@ -211,7 +212,7 @@ def read_secret(path, key=None, metadata=False, default=None):
first: {{ supersecret.first }}
second: {{ supersecret.second }}
"""
if default is None:
if default == NOT_SET:
default = CommandExecutionError
version2 = __utils__["vault.is_v2"](path)
if version2["v2"]:
@ -358,7 +359,7 @@ def destroy_secret(path, *args):
return False
def list_secrets(path, default=None):
def list_secrets(path, default=NOT_SET):
"""
.. versionchanged:: 3001
The ``default`` argument has been added. When the path or path/key
@ -374,7 +375,7 @@ def list_secrets(path, default=None):
salt '*' vault.list_secrets "secret/my/"
"""
if default is None:
if default == NOT_SET:
default = CommandExecutionError
log.debug("Listing vault secret keys for %s in %s", __grains__["id"], path)
version2 = __utils__["vault.is_v2"](path)

View file

@ -27,9 +27,13 @@ except ImportError:
def __virtual__():
if HAS_LINT:
version = salt.utils.yamllint.version()
version_cmp = salt.utils.versions.version_cmp(version, "1.20.0")
if salt.utils.yamllint.has_yamllint():
version = salt.utils.yamllint.version()
version_cmp = salt.utils.versions.version_cmp(version, "1.20.0")
else:
return (False, "yamllint not installed")
if version_cmp >= 0:
return __virtualname__
else:

View file

@ -14,6 +14,7 @@ import salt.transport.frame
import salt.utils.immutabletypes as immutabletypes
import salt.utils.msgpack
import salt.utils.stringutils
from salt.defaults import _Constant
from salt.exceptions import SaltDeserializationError, SaltReqTimeoutError
from salt.utils.data import CaseInsensitiveDict
@ -77,6 +78,9 @@ def loads(msg, encoding=None, raw=False):
if code == 78:
data = salt.utils.stringutils.to_unicode(data)
return datetime.datetime.strptime(data, "%Y%m%dT%H:%M:%S.%f")
if code == 79:
name, value = salt.utils.msgpack.loads(data, raw=False)
return _Constant(name, value)
return data
gc.disable() # performance optimization for msgpack
@ -144,6 +148,12 @@ def dumps(msg, use_bin_type=False):
78,
salt.utils.stringutils.to_bytes(obj.strftime("%Y%m%dT%H:%M:%S.%f")),
)
elif isinstance(obj, _Constant):
# Special case our constants.
return salt.utils.msgpack.ExtType(
79,
salt.utils.msgpack.dumps((obj.name, obj.value), use_bin_type=True),
)
# The same for immutable types
elif isinstance(obj, immutabletypes.ImmutableDict):
return dict(obj)

View file

@ -1,7 +1,7 @@
import logging
import warnings
import salt.serializers.toml
import salt.serializers.tomlmod
import salt.utils.url
log = logging.getLogger(__name__)
@ -11,7 +11,7 @@ __virtualname__ = "toml"
def __virtual__():
if salt.serializers.toml.HAS_TOML is False:
if salt.serializers.tomlmod.HAS_TOML is False:
return (False, "The 'toml' library is missing")
return __virtualname__
@ -24,7 +24,7 @@ def render(sls_data, saltenv="base", sls="", **kws):
:rtype: A Python data structure
"""
with warnings.catch_warnings(record=True) as warn_list:
data = salt.serializers.toml.deserialize(sls_data) or {}
data = salt.serializers.tomlmod.deserialize(sls_data) or {}
for item in warn_list:
log.warning(

View file

@ -77,7 +77,6 @@ def render(yaml_data, saltenv="base", sls="", argline="", **kws):
)
if not data:
data = {}
log.debug("Results of YAML rendering: \n%s", data)
def _validate_data(data):
"""

View file

@ -1,4 +1,9 @@
"""
.. warning::
The `cassandra` returner is deprecated in favor of the `cassandra_cql`
returner.
Return data to a Cassandra ColumnFamily
Here's an example Keyspace / ColumnFamily setup that works with this
@ -22,6 +27,7 @@ Required python modules: pycassa
import logging
import salt.utils.jid
from salt.utils.versions import warn_until_date
try:
import pycassa # pylint: disable=import-error
@ -46,6 +52,11 @@ __virtualname__ = "cassandra"
def __virtual__():
if not HAS_PYCASSA:
return False, "Could not import cassandra returner; pycassa is not installed."
warn_until_date(
"20240101",
"The cassandra returner is broken and deprecated, and will be removed"
" after {date}. Use the cassandra_cql returner instead",
)
return __virtualname__

View file

@ -103,5 +103,4 @@ class Roster:
except OSError as exc:
log.error("Can't access roster for backend %s: %s", back, exc)
log.debug("Matched minions: %s", targets)
return targets

View file

@ -99,7 +99,7 @@ def _render(roster_file, **kwargs):
__opts__["renderer"],
__opts__["renderer_blacklist"],
__opts__["renderer_whitelist"],
mask_value="passw*",
mask_value="*passw*",
**kwargs
)
result.setdefault("host", "{}.{}".format(os.path.basename(roster_file), domain))

View file

@ -26,7 +26,7 @@ def targets(tgt, tgt_type="glob", **kwargs):
__opts__["renderer"],
__opts__["renderer_blacklist"],
__opts__["renderer_whitelist"],
mask_value="passw*",
mask_value="*passw*",
**kwargs
)
conditioned_raw = {}

View file

@ -1,12 +1,15 @@
"""
salt.serializers.toml
~~~~~~~~~~~~~~~~~~~~~~~~~~~
salt.serializers.tomlmod
~~~~~~~~~~~~~~~~~~~~~~~~
Implements TOML serializer.
It's just a wrapper around the python toml module.
"""
import logging
from salt.serializers import DeserializationError, SerializationError
try:
@ -17,8 +20,18 @@ except ImportError:
HAS_TOML = False
__virtualname__ = "toml"
__all__ = ["deserialize", "serialize", "HAS_TOML"]
log = logging.getLogger(__name__)
def __virtual__():
if HAS_TOML is False:
return (False, "The 'toml' library is missing")
return __virtualname__
def deserialize(stream_or_string, **options):
"""

View file

@ -3134,11 +3134,14 @@ def managed(
reset=win_perms_reset,
)
except CommandExecutionError as exc:
if exc.strerror.startswith("Path not found"):
if not isinstance(
ret["changes"], tuple
) and exc.strerror.startswith("Path not found"):
ret["changes"]["newfile"] = name
if isinstance(ret["changes"], tuple):
ret["result"], ret["comment"] = ret["changes"]
ret["changes"] = {}
elif ret["changes"]:
ret["result"] = None
ret["comment"] = "The file {} is set to be changed".format(name)
@ -8004,7 +8007,7 @@ def serialize(
ret["comment"] = "Failed to deserialize existing data: {}".format(
exc
)
return False
return ret
if existing_data is not None:
merged_data = salt.utils.dictupdate.merge_recurse(

View file

@ -667,7 +667,6 @@ def mounted(
ret["comment"] = "{} not present and not mounted".format(name)
else:
if __opts__["test"]:
ret["result"] = None
ret["comment"] = "{} would not be mounted".format(name)
else:
ret["comment"] = "{} not mounted".format(name)

View file

@ -98,9 +98,9 @@ def _changes(
return False
change = {}
if groups is None:
groups = lusr["groups"]
wanted_groups = sorted(set((groups or []) + (optional_groups or [])))
if not remove_groups:
wanted_groups = sorted(set(wanted_groups + lusr["groups"]))
if uid and lusr["uid"] != uid:
change["uid"] = uid
if gid is not None and lusr["gid"] not in (gid, __salt__["file.group_to_gid"](gid)):

View file

@ -1,14 +1,26 @@
import logging
import yamllint
from yamllint import linter
from yamllint.config import YamlLintConfig
import salt.utils.stringutils
try:
import yamllint
from yamllint import linter
from yamllint.config import YamlLintConfig
HAS_YAMLLINT = True
except ImportError:
HAS_YAMLLINT = False
log = logging.getLogger(__name__)
def has_yamllint():
"""
report if yamllint could be imported safly. allowing for clean import detection
"""
return HAS_YAMLLINT
def version():
"""
report version of yamllint installed for version comparison

View file

@ -59,6 +59,8 @@ if str(CODE_DIR) in sys.path:
sys.path.remove(str(CODE_DIR))
sys.path.insert(0, str(CODE_DIR))
os.environ["REPO_ROOT_DIR"] = str(CODE_DIR)
# Coverage
if "COVERAGE_PROCESS_START" in os.environ:
MAYBE_RUN_COVERAGE = True
@ -683,14 +685,20 @@ def salt_factories_config():
"""
Return a dictionary with the keyworkd arguments for FactoriesManager
"""
return {
if os.environ.get("JENKINS_URL") or os.environ.get("CI"):
start_timeout = 120
else:
start_timeout = 60
kwargs = {
"code_dir": str(CODE_DIR),
"inject_coverage": MAYBE_RUN_COVERAGE,
"inject_sitecustomize": MAYBE_RUN_COVERAGE,
"start_timeout": 120
if (os.environ.get("JENKINS_URL") or os.environ.get("CI"))
else 60,
"start_timeout": start_timeout,
}
if MAYBE_RUN_COVERAGE:
kwargs["coverage_rc_path"] = str(COVERAGERC_FILE)
coverage_db_path = os.environ.get("COVERAGE_FILE")
if coverage_db_path:
kwargs["coverage_db_path"] = coverage_db_path
return kwargs
@pytest.fixture

View file

@ -167,7 +167,7 @@ salt/proxy/*:
- pytests.integration.proxy.test_simple
salt/state.py:
- integration.modules.test_state_jinja_filters
- pytests.functional.modules.state.test_jinja_filters
- integration.states.test_compiler
- integration.states.test_handle_error
- integration.states.test_handle_iorder
@ -178,7 +178,7 @@ salt/utils/decorators/*:
- integration.modules.test_decorators
salt/(utils|renderers)/jinja\.py:
- integration.modules.test_state_jinja_filters
- pytests.functional.modules.state.test_jinja_filters
- integration.states.test_renderers
salt/utils/minions.py:
@ -195,13 +195,13 @@ salt/cli/daemons.py:
salt/(client/ssh/.+|cli/ssh\.py):
- integration.cli.test_custom_module
- integration.ssh.test_deploy
- pytests.integration.ssh.test_deploy
- pytests.integration.ssh.test_grains
- integration.ssh.test_jinja_filters
- integration.ssh.test_master
- integration.ssh.test_mine
- pytests.integration.ssh.test_mine
- pytests.integration.ssh.test_master
- pytests.integration.ssh.test_jinja_filters
- pytests.integration.ssh.test_pillar
- integration.ssh.test_raw
- pytests.integration.ssh.test_raw
- integration.ssh.test_state
- pytests.integration.ssh.test_py_versions
@ -304,10 +304,10 @@ salt/utils/schedule.py:
salt/utils/vt.py:
- integration.cli.test_custom_module
- pytests.integration.ssh.test_grains
- integration.ssh.test_jinja_filters
- integration.ssh.test_mine
- pytests.integration.ssh.test_mine
- pytests.integration.ssh.test_jinja_filters
- pytests.integration.ssh.test_pillar
- integration.ssh.test_raw
- pytests.integration.ssh.test_raw
- integration.ssh.test_state
salt/wheel/*:

View file

@ -1,83 +0,0 @@
import os
import shutil
import stat
import pytest
import salt.utils.files
import salt.utils.stringutils
from tests.support.case import ShellCase
from tests.support.runtests import RUNTIME_VARS
class AutosignGrainsTest(ShellCase):
"""
Test autosigning minions based on grain values.
"""
def setUp(self):
# all read, only owner write
self.autosign_file_permissions = (
stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IWUSR
)
self.autosign_file_path = os.path.join(RUNTIME_VARS.TMP, "autosign_file")
shutil.copyfile(
os.path.join(RUNTIME_VARS.FILES, "autosign_grains", "autosign_file"),
self.autosign_file_path,
)
os.chmod(self.autosign_file_path, self.autosign_file_permissions)
self.run_key("-d minion -y")
self.run_call(
"test.ping -l quiet"
) # get minion to try to authenticate itself again
if "minion" in self.run_key("-l acc"):
self.tearDown()
self.skipTest("Could not deauthorize minion")
if "minion" not in self.run_key("-l un"):
self.tearDown()
self.skipTest("minion did not try to reauthenticate itself")
self.autosign_grains_dir = os.path.join(self.master_opts["autosign_grains_dir"])
if not os.path.isdir(self.autosign_grains_dir):
os.makedirs(self.autosign_grains_dir)
def tearDown(self):
shutil.copyfile(
os.path.join(RUNTIME_VARS.FILES, "autosign_file"), self.autosign_file_path
)
os.chmod(self.autosign_file_path, self.autosign_file_permissions)
self.run_call("test.ping -l quiet") # get minion to authenticate itself again
try:
if os.path.isdir(self.autosign_grains_dir):
shutil.rmtree(self.autosign_grains_dir)
except AttributeError:
pass
@pytest.mark.slow_test
def test_autosign_grains_accept(self):
grain_file_path = os.path.join(self.autosign_grains_dir, "test_grain")
with salt.utils.files.fopen(grain_file_path, "w") as f:
f.write(salt.utils.stringutils.to_str("#invalid_value\ncheese"))
os.chmod(grain_file_path, self.autosign_file_permissions)
self.run_call(
"test.ping -l quiet"
) # get minion to try to authenticate itself again
self.assertIn("minion", self.run_key("-l acc"))
@pytest.mark.slow_test
def test_autosign_grains_fail(self):
grain_file_path = os.path.join(self.autosign_grains_dir, "test_grain")
with salt.utils.files.fopen(grain_file_path, "w") as f:
f.write(salt.utils.stringutils.to_str("#cheese\ninvalid_value"))
os.chmod(grain_file_path, self.autosign_file_permissions)
self.run_call(
"test.ping -l quiet"
) # get minion to try to authenticate itself again
self.assertNotIn("minion", self.run_key("-l acc"))
self.assertIn("minion", self.run_key("-l un"))

View file

@ -1,75 +0,0 @@
"""
Helpers for testing man pages
"""
import logging
import os
import sys
import salt.utils.files
import salt.utils.path
import salt.utils.stringutils
from salt.exceptions import CommandExecutionError
from tests.support.runtests import RUNTIME_VARS
log = logging.getLogger(__name__)
def install(rootdir):
if not os.path.exists(rootdir):
os.makedirs(rootdir)
return __salt__["cmd.run_all"](
[
sys.executable,
os.path.join(RUNTIME_VARS.CODE_DIR, "setup.py"),
"install",
"--root={}".format(rootdir),
],
redirect_stderr=True,
)
def search(manpages, rootdir):
manpage_fns = set(manpages)
manpage_paths = {}
for root, _, files in os.walk(rootdir):
if not manpage_fns:
# All manpages found, no need to keep walking
break
# Using list because we will be modifying the set during iteration
for manpage_fn in list(manpage_fns):
if manpage_fn in files:
manpage_path = salt.utils.path.join(root, manpage_fn)
manpage_paths[manpage_fn] = manpage_path
manpage_fns.remove(manpage_fn)
if manpage_fns:
raise CommandExecutionError(
"The following manpages were not found under {}: {}".format(
rootdir, ", ".join(sorted(manpage_fns))
)
)
failed = {}
for manpage in sorted(manpages):
with salt.utils.files.fopen(manpage_paths[manpage]) as fp_:
contents = salt.utils.stringutils.to_unicode(fp_.read())
# Check for search string in contents
for search_string in manpages[manpage]:
if search_string not in contents:
failed.setdefault(manpage, []).append(
"No match for search string '{}' found in {}".format(
search_string, manpage_paths[manpage]
)
)
# Check for correct install dir
path = "/man{}/".format(manpage.rsplit(".", 1)[-1])
if path not in manpage_paths[manpage]:
failed.setdefault(manpage, []).append(
"{} not found in manpage path {}".format(path, manpage_paths[manpage])
)
if failed:
raise CommandExecutionError("One or more manpages failed", info=failed)
return True

View file

@ -1,18 +1,24 @@
import logging
import os
import pathlib
import time
import salt.utils.decorators
from tests.support.runtests import RUNTIME_VARS
EXIT_CODE_SH = os.path.join(RUNTIME_VARS.BASE_FILES, "exit_code.sh")
EXIT_CODE_CMD = os.path.join(RUNTIME_VARS.BASE_FILES, "exit_code.cmd")
log = logging.getLogger(__name__)
REPO_ROOT_DIR = pathlib.Path(os.environ["REPO_ROOT_DIR"]).resolve()
STATE_BASE_DIR = REPO_ROOT_DIR / "tests" / "integration" / "files" / "file" / "base"
EXIT_CODE_SH = STATE_BASE_DIR / "exit_code.sh"
EXIT_CODE_CMD = STATE_BASE_DIR / "exit_code.cmd"
def _exit_code(code):
if os.name == "nt":
return "cmd /c {} {}".format(EXIT_CODE_CMD, code)
cmd = "cmd /c {} {}".format(EXIT_CODE_CMD, code)
else:
return "/usr/bin/env sh {} {}".format(EXIT_CODE_SH, code)
cmd = "/usr/bin/env sh {} {}".format(EXIT_CODE_SH, code)
return cmd
def _fallbackfunc():

Some files were not shown because too many files have changed in this diff Show more