Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/certbot/certbot.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrien Ferrand <adferrand@users.noreply.github.com>2020-12-16 21:49:31 +0300
committerGitHub <noreply@github.com>2020-12-16 21:49:31 +0300
commitd38766e05c306a81d1bd7798187dfb8f96a66d5d (patch)
tree36d43845a2da351b36ef9d1e84fc8373dc30f60a /windows-installer
parentc5a0b1ae5d49b766cd38e8648a02317290e870dc (diff)
Enable again build isolation with proper pinning of build dependencies (#8443)
Fixes #8256 First let's sum up the problem to solve. We disabled the build isolation available in pip>=19 because it could potential break certbot build without a control on our side. Basically builds are not reproductible. Indeed the build isolation triggers build of PEP-517 enabled transitive dependencies (like `cryptography`) with the build dependencies defined in their `pyproject.toml`. For `cryptography` in particular these requirements include `setuptools>=40.6.0`, and quite logically pip will install the latest version of `setuptools` for the build. And when `setuptools` broke with the version 50, our build did the same. But disabling the build isolation is not a long term solution, as more and more project will migrate on this approach and it basically provides a lot of benefit in how dependencies are built. The ideal solution would be to be able to apply version constraints on our side on the build dependencies, in order to pin `setuptools` for instance, and decide precisely when we upgrade to a newer version. However for now pip does not provide a mechanism for that (like a `--build-constraint` flag or propagation of existing `--constraint` flag). Until I saw https://github.com/pypa/pip/issues/9081 and https://github.com/pypa/pip/issues/8439. Apart the fact that https://github.com/pypa/pip/issues/9081 shows that pip maintainers are working on this issue, it explains how pip works regarding PEP-517 and infers which workaround can be used to still pin the build dependencies. It turns out that pip invokes itself in each build isolation to install the build dependencies. It means that even if some flags (like `--constraint`) are not explicitly passed to the pip sub call, the global environment remains, in particular the environment variables. Thus it is known that every pip flag can alternatively be set by environment variable using the following pattern for the variable name: `PIP_[FLAG_NAME_UPPERCASE]`. So for `--constraint`, it is `PIP_CONSTRAINT`. And so you can pass a constraint file to the pip sub call through that mechanism. I made some tests with a constraint file containing pinning for `setuptools`: indeed under isolation zone, the constraint file has been honored and the provided pinned version has been used to build the dependencies (I tested it with `cryptography`). Finally this PR takes advantage of this mechanism, by setting `PIP_CONSTRAINT` to `pip_install`, the snap building process, the Dockerfiles and the windows installer building process. I also extracted out the requirements of the new `pipstrap.py` to be reusable in these various build processes. * Use workaround to fix build requirements in build isolation, and renable build isolation * Clean imports in pipstrap * Externalize pipstrap reqs to be reusable * Inject pipstrap constraints during pip_install * Update docker build * Update snapcraft build * Prepare installer build * Fix pipstrap constraints in snap build * Add back --no-build-cache option in Docker images build * Update snap/snapcraft.yaml * Use proper flags with pip Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
Diffstat (limited to 'windows-installer')
-rw-r--r--windows-installer/construct.py19
1 files changed, 13 insertions, 6 deletions
diff --git a/windows-installer/construct.py b/windows-installer/construct.py
index 14f770959..1ce4811ac 100644
--- a/windows-installer/construct.py
+++ b/windows-installer/construct.py
@@ -46,9 +46,11 @@ def _compile_wheels(repo_path, build_path, venv_python):
wheels_project = [os.path.join(repo_path, package) for package in certbot_packages]
with _prepare_constraints(repo_path) as constraints_file_path:
- command = [venv_python, '-m', 'pip', 'wheel', '-w', wheels_path, '--constraint', constraints_file_path]
+ env = os.environ.copy()
+ env['PIP_CONSTRAINT'] = constraints_file_path
+ command = [venv_python, '-m', 'pip', 'wheel', '-w', wheels_path]
command.extend(wheels_project)
- subprocess.check_call(command)
+ subprocess.check_call(command, env=env)
def _prepare_build_tools(venv_path, venv_python, repo_path):
@@ -61,15 +63,20 @@ def _prepare_build_tools(venv_path, venv_python, repo_path):
@contextlib.contextmanager
def _prepare_constraints(repo_path):
- requirements = os.path.join(repo_path, 'letsencrypt-auto-source', 'pieces', 'dependency-requirements.txt')
- constraints = subprocess.check_output(
- [sys.executable, os.path.join(repo_path, 'tools', 'strip_hashes.py'), requirements],
+ reqs_certbot = os.path.join(repo_path, 'letsencrypt-auto-source', 'pieces', 'dependency-requirements.txt')
+ reqs_pipstrap = os.path.join(repo_path, 'tools', 'pipstrap_constraints.txt')
+ constraints_certbot = subprocess.check_output(
+ [sys.executable, os.path.join(repo_path, 'tools', 'strip_hashes.py'), reqs_certbot],
+ universal_newlines=True)
+ constraints_pipstrap = subprocess.check_output(
+ [sys.executable, os.path.join(repo_path, 'tools', 'strip_hashes.py'), reqs_pipstrap],
universal_newlines=True)
workdir = tempfile.mkdtemp()
try:
constraints_file_path = os.path.join(workdir, 'constraints.txt')
with open(constraints_file_path, 'a') as file_h:
- file_h.write(constraints)
+ file_h.write(constraints_pipstrap)
+ file_h.write(constraints_certbot)
file_h.write('pywin32=={0}'.format(PYWIN32_VERSION))
yield constraints_file_path
finally: