mirror of
https://github.com/certbot/certbot.git
synced 2026-01-26 07:41:33 +03:00
Over the weekend, Python released new versions of Python 3.8 and Python 3.9 partially in response to the OpenSSL CVEs discussed at https://github.com/certbot/certbot/pull/8741#issuecomment-809644789. You can see this mentioned in their changelog at https://docs.python.org/release/3.8.9/whatsnew/changelog.html#build. This PR updates the windows installer to use that new release so all of our distribution methods that contain their own copy of OpenSSL are patched for the release tomorrow. You can see tests passing with this change at https://dev.azure.com/certbot/certbot/_build/results?buildId=3751&view=results. You can see Python 3.8.9 being downloaded instead of an older version at https://dev.azure.com/certbot/certbot/_build/results?buildId=3751&view=logs&j=ad29f110-3cce-5317-4ef2-0a692ae1dee7&t=901eeead-396c-5477-aba2-f402fdcfb885&l=1055.
150 lines
5.3 KiB
Python
150 lines
5.3 KiB
Python
#!/usr/bin/env python3
|
|
import ctypes
|
|
import os
|
|
import shutil
|
|
import struct
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
PYTHON_VERSION = (3, 8, 9)
|
|
PYTHON_BITNESS = 32
|
|
NSIS_VERSION = '3.06.1'
|
|
|
|
|
|
def main():
|
|
if os.name != 'nt':
|
|
raise RuntimeError('This script must be run under Windows.')
|
|
|
|
if ctypes.windll.shell32.IsUserAnAdmin() == 0:
|
|
# Administrator privileges are required to properly install NSIS through Chocolatey
|
|
raise RuntimeError('This script must be run with administrator privileges.')
|
|
|
|
if sys.version_info[:2] != PYTHON_VERSION[:2]:
|
|
raise RuntimeError('This script must be run with Python {0}'
|
|
.format('.'.join(str(item) for item in PYTHON_VERSION[0:2])))
|
|
|
|
if struct.calcsize('P') * 8 != PYTHON_BITNESS:
|
|
raise RuntimeError('This script must be run with a {0} bit version of Python.'
|
|
.format(PYTHON_BITNESS))
|
|
|
|
build_path, repo_path, venv_path, venv_python = _prepare_environment()
|
|
|
|
_copy_assets(build_path, repo_path)
|
|
|
|
installer_cfg_path = _generate_pynsist_config(repo_path, build_path)
|
|
|
|
_prepare_build_tools(venv_path, venv_python, repo_path)
|
|
_compile_wheels(repo_path, build_path, venv_python)
|
|
_build_installer(installer_cfg_path)
|
|
|
|
print('Done')
|
|
|
|
|
|
def _build_installer(installer_cfg_path):
|
|
print('Build the installer')
|
|
subprocess.check_call([sys.executable, '-m', 'nsist', installer_cfg_path])
|
|
|
|
|
|
def _compile_wheels(repo_path, build_path, venv_python):
|
|
print('Compile wheels')
|
|
|
|
wheels_path = os.path.join(build_path, 'wheels')
|
|
os.makedirs(wheels_path)
|
|
|
|
certbot_packages = ['acme', 'certbot']
|
|
# Uncomment following line to include all DNS plugins in the installer
|
|
# certbot_packages.extend([name for name in os.listdir(repo_path) if name.startswith('certbot-dns-')])
|
|
wheels_project = [os.path.join(repo_path, package) for package in certbot_packages]
|
|
|
|
constraints_file_path = os.path.join(repo_path, 'tools', 'requirements.txt')
|
|
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, env=env)
|
|
|
|
|
|
def _prepare_build_tools(venv_path, venv_python, repo_path):
|
|
print('Prepare build tools')
|
|
subprocess.check_call([sys.executable, '-m', 'venv', venv_path])
|
|
subprocess.check_call([venv_python, os.path.join(repo_path, 'tools', 'pipstrap.py')])
|
|
subprocess.check_call(['choco', 'upgrade', '--allow-downgrade', '-y', 'nsis', '--version', NSIS_VERSION])
|
|
|
|
|
|
def _copy_assets(build_path, repo_path):
|
|
print('Copy assets')
|
|
if os.path.exists(build_path):
|
|
os.rename(build_path, '{0}.{1}.bak'.format(build_path, int(time.time())))
|
|
os.makedirs(build_path)
|
|
shutil.copy(os.path.join(repo_path, 'windows-installer', 'assets', 'certbot.ico'), build_path)
|
|
shutil.copy(os.path.join(repo_path, 'windows-installer', 'assets', 'run.bat'), build_path)
|
|
shutil.copy(os.path.join(repo_path, 'windows-installer', 'assets', 'template.nsi'), build_path)
|
|
shutil.copy(os.path.join(repo_path, 'windows-installer', 'assets', 'renew-up.ps1'), build_path)
|
|
shutil.copy(os.path.join(repo_path, 'windows-installer', 'assets', 'renew-down.ps1'), build_path)
|
|
|
|
|
|
def _generate_pynsist_config(repo_path, build_path):
|
|
print('Generate pynsist configuration')
|
|
|
|
installer_cfg_path = os.path.join(build_path, 'installer.cfg')
|
|
|
|
certbot_pkg_path = os.path.join(repo_path, 'certbot')
|
|
certbot_version = subprocess.check_output([sys.executable, '-c', 'import certbot; print(certbot.__version__)'],
|
|
universal_newlines=True, cwd=certbot_pkg_path).strip()
|
|
|
|
# If we change the installer name from `certbot-beta-installer-win32.exe`, it should
|
|
# also be changed in tools/create_github_release.py
|
|
with open(installer_cfg_path, 'w') as file_h:
|
|
file_h.write('''\
|
|
[Application]
|
|
name=Certbot
|
|
version={certbot_version}
|
|
icon=certbot.ico
|
|
publisher=Electronic Frontier Foundation
|
|
target=$INSTDIR\\run.bat
|
|
|
|
[Build]
|
|
directory=nsis
|
|
nsi_template=template.nsi
|
|
installer_name=certbot-beta-installer-{installer_suffix}.exe
|
|
|
|
[Python]
|
|
version={python_version}
|
|
bitness={python_bitness}
|
|
|
|
[Include]
|
|
local_wheels=wheels\\*.whl
|
|
files=run.bat
|
|
renew-up.ps1
|
|
renew-down.ps1
|
|
|
|
[Command certbot]
|
|
entry_point=certbot.main:main
|
|
'''.format(certbot_version=certbot_version,
|
|
installer_suffix='win_amd64' if PYTHON_BITNESS == 64 else 'win32',
|
|
python_bitness=PYTHON_BITNESS,
|
|
python_version='.'.join(str(item) for item in PYTHON_VERSION)))
|
|
|
|
return installer_cfg_path
|
|
|
|
|
|
def _prepare_environment():
|
|
print('Prepare environment')
|
|
try:
|
|
subprocess.check_output(['choco', '--version'])
|
|
except subprocess.CalledProcessError:
|
|
raise RuntimeError('Error: Chocolatey (https://chocolatey.org/) needs '
|
|
'to be installed to run this script.')
|
|
script_path = os.path.realpath(__file__)
|
|
repo_path = os.path.dirname(os.path.dirname(os.path.dirname(script_path)))
|
|
build_path = os.path.join(repo_path, 'windows-installer', 'build')
|
|
venv_path = os.path.join(build_path, 'venv-config')
|
|
venv_python = os.path.join(venv_path, 'Scripts', 'python.exe')
|
|
|
|
return build_path, repo_path, venv_path, venv_python
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|