[BUG] pip.install from local index fails using Salt 3005.1 onedir package
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 15.7k
- Forks
- 5.6k
- Avg merge
- 2d 44m
- Merged PRs (30d)
- 80
Description
Description
When I try to install a pip package from a local pip mirror/index, the installation fails with an "pip._vendor.pep517.wrappers.BackendInvalid" exception. It looks like this only happens when some building requirements are not (yet) met.
The minion is completely air-gapped, so we need to use a local pip repository.
When I connect the test minion to the internet and remove the "index_url", "find_links" and "trusted_host" parameters, the state runs fine.
Setup
Minion VM with Ubuntu 20.04 or Windows server 2019, with salt 3005.1 onedir packaging.
Using a local pip repository containing all necessary packages and dependencies, provisioned with pypi-mirror.
Steps to Reproduce the behavior
An example is the installation of pip-system-certs (but this error also occurs during installation of other pip packages with dependencies).
my_testing_installation:
pip.installed:
- name: pip-system-certs
- index_url: "http://repo.foo.lan/pip"
- find_links: "http://repo.foo.lan/pip"
- trusted_host: "repo.foo.lan"
Version 3.1 of pip-system-certs tries to install setuptools-65.4.1.tar.gz.
Using an air-gapped minion with access to a local pip repository (http://repo.foo.lan/pip).
Expected behavior
In previous versions of Salt (3004.1), all pip packages and dependencies were installed from our local pip repository using the given state.
The state is also working fine on 3005.1 when the minion is connected to the internet and the index_url/find_links/trusted_host parameters are omitted.
ID: my_testing_installation
Function: pip.installed
Name: pip-system-certs
Result: True
Comment: All packages were successfully installed
Started: 13:29:29.609256
Duration: 70575.297 ms
Changes:
----------
pip-system-certs==3.1:
Installed
Screenshots
The installation on 3005.1 onedir (air-gapped minion with local pip repo) fails with the following error:
----------
ID: my_testing_installation
Function: pip.installed
Name: pip-system-certs
Result: False
Comment: Failed to install packages: pip-system-certs. Error: Looking in indexes: http://repo.foo.lan/pip
Looking in links: http://repo.foo.lan/pip, http://repo.foo.lan/pip
Collecting pip-system-certs
Using cached http://repo.foo.lan/pip/pip-system-certs/pip_system_certs-3.1.tar.gz (4.9 kB)
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'error' error: subprocess-exited-with-error
python setup.py egg_info did not run successfully.
exit code: 1
[111 lines of output]
setuptools/installer.py:27: SetuptoolsDeprecationWarning: setuptools.installer is deprecated. Requirements should be satisfied by a PEP 517 installer.
warnings.warn(
error: subprocess-exited-with-error
pip subprocess to install build dependencies did not run successfully.
exit code: 2
[59 lines of output]
Looking in indexes: http://repo.foo.lan/pip
Looking in links: http://repo.foo.lan/pip, http://repo.foo.lan/pip
Collecting setuptools>=45
Using cached http://repo.foo.lan/pip/setuptools/setuptools-65.4.1.tar.gz (2.6 MB)
Getting requirements to build wheel: started
Getting requirements to build wheel: finished with status 'done'
ERROR: Exception:
Traceback (most recent call last):
File "pip/_internal/cli/base_command.py", line 167, in exc_logging_wrapper
status = run_func(*args)
File "pip/_internal/cli/req_command.py", line 247, in wrapper
return func(self, options, args)
File "pip/_internal/commands/install.py", line 369, in run
requirement_set = resolver.resolve(
File "pip/_internal/resolution/resolvelib/resolver.py", line 92, in resolve
result = self._result = resolver.resolve(
File "pip/_vendor/resolvelib/resolvers.py", line 481, in resolve
state = resolution.resolve(requirements, max_rounds=max_rounds)
File "pip/_vendor/resolvelib/resolvers.py", line 348, in resolve
self._add_to_criteria(self.state.criteria, r, parent=None)
File "pip/_vendor/resolvelib/resolvers.py", line 172, in _add_to_criteria
if not criterion.candidates:
File "pip/_vendor/resolvelib/structs.py", line 151, in __bool__
return bool(self._sequence)
File "pip/_internal/resolution/resolvelib/found_candidates.py", line 155, in __bool__
return any(self)
File "pip/_internal/resolution/resolvelib/found_candidates.py", line 143, in <genexpr>
return (c for c in iterator if id(c) not in self._incompatible_ids)
File "pip/_internal/resolution/resolvelib/found_candidates.py", line 47, in _iter_built
candidate = func()
File "pip/_internal/resolution/resolvelib/factory.py", line 206, in _make_candidate_from_link
self._link_candidate_cache[link] = LinkCandidate(
File "pip/_internal/resolution/resolvelib/candidates.py", line 297, in __init__
super().__init__(
File "pip/_internal/resolution/resolvelib/candidates.py", line 162, in __init__
self.dist = self._prepare()
File "pip/_internal/resolution/resolvelib/candidates.py", line 231, in _prepare
dist = self._prepare_distribution()
File "pip/_internal/resolution/resolvelib/candidates.py", line 308, in _prepare_distribution
return preparer.prepare_linked_requirement(self._ireq, parallel_builds=True)
File "pip/_internal/operations/prepare.py", line 438, in prepare_linked_requirement
return self._prepare_linked_requirement(req, parallel_builds)
File "pip/_internal/operations/prepare.py", line 524, in _prepare_linked_requirement
dist = _get_prepared_distribution(
File "pip/_internal/operations/prepare.py", line 68, in _get_prepared_distribution
abstract_dist.prepare_distribution_metadata(
File "pip/_internal/distributions/sdist.py", line 48, in prepare_distribution_metadata
self._install_build_reqs(finder)
File "pip/_internal/distributions/sdist.py", line 118, in _install_build_reqs
build_reqs = self._get_build_requires_wheel()
File "pip/_internal/distributions/sdist.py", line 95, in _get_build_requires_wheel
return backend.get_requires_for_build_wheel()
File "pip/_internal/utils/misc.py", line 685, in get_requires_for_build_wheel
return super().get_requires_for_build_wheel(config_settings=cs)
File "pip/_vendor/pep517/wrappers.py", line 172, in get_requires_for_build_wheel
return self._call_hook('get_requires_for_build_wheel', {
File "pip/_vendor/pep517/wrappers.py", line 334, in _call_hook
raise BackendInvalid(
pip._vendor.pep517.wrappers.BackendInvalid
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error
pip subprocess to install build dependencies did not run successfully.
exit code: 2
See above for output.
note: This error originates from a subprocess, and is likely not a problem with pip.
Traceback (most recent call last):
File "setuptools/installer.py", line 82, in fetch_build_egg
subprocess.check_call(cmd)
File "subprocess.py", line 373, in check_call
subprocess.CalledProcessError: Command '['/opt/saltstack/salt/run/run', '-m', 'pip', '--disable-pip-version-check', 'wheel', '--no-deps', '-w', '/tmp/tmpnr764scx', '--quiet', 'setuptools_scm']' returned non-zero exit status 1.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "tiamatpip/cli.py", line 383, in _handle_runpy_return
runpy_f(*args, **kwargs)
File "runpy.py", line 87, in _run_code
File "<tiamat-pip-run-code>", line 2, in <module>
File "<pip-setuptools-caller>", line 34, in <module>
File "/tmp/pip-install-gm5jr0o3/pip-system-certs_70f845dcadfa48f898ab8d848bd0114a/setup.py", line 37, in <module>
setup(
File "setuptools/__init__.py", line 154, in setup
_install_setup_requires(attrs)
File "setuptools/__init__.py", line 148, in _install_setup_requires
dist.fetch_build_eggs(dist.setup_requires)
File "setuptools/dist.py", line 820, in fetch_build_eggs
resolved_dists = pkg_resources.working_set.resolve(
File "pkg_resources/__init__.py", line 771, in resolve
dist = best[req.key] = env.best_match(
File "pkg_resources/__init__.py", line 1056, in best_match
return self.obtain(req, installer)
File "pkg_resources/__init__.py", line 1068, in obtain
return installer(requirement)
File "setuptools/dist.py", line 891, in fetch_build_egg
return fetch_build_egg(self, req)
File "setuptools/installer.py", line 84, in fetch_build_egg
raise DistutilsError(str(e)) from e
distutils.errors.DistutilsError: Command '['/opt/saltstack/salt/run/run', '-m', 'pip', '--disable-pip-version-check', 'wheel', '--no-deps', '-w', '/tmp/tmpnr764scx', '--quiet', 'setuptools_scm']' returned non-zero exit status 1.
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed
Encountered error while generating package metadata.
See above for output.
note: This is an issue with the package mentioned above, not pip.
hint: See above for details.
Started: 12:55:36.308463
Duration: 13579.152 ms
Versions Report
salt --versions-report
Salt Version:
Salt: 3005.1
Dependency Versions:
cffi: 1.14.6
cherrypy: 18.6.1
dateutil: 2.8.1
docker-py: Not Installed
gitdb: Not Installed
gitpython: Not Installed
Jinja2: 3.1.0
libgit2: Not Installed
M2Crypto: Not Installed
Mako: Not Installed
msgpack: 1.0.2
msgpack-pure: Not Installed
mysql-python: Not Installed
pycparser: 2.21
pycrypto: Not Installed
pycryptodome: 3.9.8
pygit2: Not Installed
Python: 3.9.14 (main, Oct 3 2022, 21:19:16)
python-gnupg: 0.4.8
PyYAML: 5.4.1
PyZMQ: 23.2.0
smmap: Not Installed
timelib: 0.2.4
Tornado: 4.5.3
ZMQ: 4.3.4
System Versions:
dist: ubuntu 20.04 focal
locale: utf-8
machine: x86_64
release: 5.4.0-126-generic
system: Linux
version: Ubuntu 20.04 focal
(Also tested on Windows server 2019 with Salt 3005.1 onedir).
Additional context
I tried setting the index_url/find_links/trusted_host parameters via env_vars, extra_args and/or pip config too, but those don't work either.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the pip.installed state using the provided air-gapped local-index reproduction on Salt 3005.1, comparing it with Salt 3004.1 and the internet-connected case. Trace how build requirements are installed for the onedir package, especially the failing setuptools_scm command. Done means pip packages and dependencies install successfully from the configured local repository without the BackendInvalid failure.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devops, infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100