diff --git a/certbot-ci/MANIFEST.in b/certbot-ci/MANIFEST.in index 64d68999e..7be27c3dc 100644 --- a/certbot-ci/MANIFEST.in +++ b/certbot-ci/MANIFEST.in @@ -1,4 +1,3 @@ recursive-include certbot_integration_tests/assets * include certbot_integration_tests/py.typed include snap_integration_tests/py.typed -include windows_installer_integration_tests/py.typed diff --git a/certbot-ci/windows_installer_integration_tests/__init__.py b/certbot-ci/windows_installer_integration_tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/certbot-ci/windows_installer_integration_tests/conftest.py b/certbot-ci/windows_installer_integration_tests/conftest.py deleted file mode 100644 index c0917013d..000000000 --- a/certbot-ci/windows_installer_integration_tests/conftest.py +++ /dev/null @@ -1,38 +0,0 @@ -# type: ignore -""" -General conftest for pytest execution of all integration tests lying -in the window_installer_integration tests package. -As stated by pytest documentation, conftest module is used to set on -for a directory a specific configuration using built-in pytest hooks. - -See https://docs.pytest.org/en/latest/reference.html#hook-reference -""" - -import os - -ROOT_PATH = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) - - -def pytest_addoption(parser): - """ - Standard pytest hook to add options to the pytest parser. - :param parser: current pytest parser that will be used on the CLI - """ - parser.addoption('--installer-path', - default=os.path.join(ROOT_PATH, 'windows-installer', 'build', - 'nsis', 'certbot-beta-installer-win_amd64.exe'), - help='set the path of the windows installer to use, default to ' - 'CERTBOT_ROOT_PATH\\windows-installer\\build\\nsis\\certbot-beta-installer-win_amd64.exe') # pylint: disable=line-too-long - parser.addoption('--allow-persistent-changes', action='store_true', - help='needs to be set, and confirm that the test will make persistent changes on this machine') # pylint: disable=line-too-long - - -def pytest_configure(config): - """ - Standard pytest hook used to add a configuration logic for each node of a pytest run. - :param config: the current pytest configuration - """ - if not config.option.allow_persistent_changes: - raise RuntimeError('This integration test would install Certbot on your machine. ' - 'Please run it again with the `--allow-persistent-changes` ' - 'flag set to acknowledge.') diff --git a/certbot-ci/windows_installer_integration_tests/py.typed b/certbot-ci/windows_installer_integration_tests/py.typed deleted file mode 100644 index e69de29bb..000000000 diff --git a/certbot-ci/windows_installer_integration_tests/test_main.py b/certbot-ci/windows_installer_integration_tests/test_main.py deleted file mode 100644 index 635335522..000000000 --- a/certbot-ci/windows_installer_integration_tests/test_main.py +++ /dev/null @@ -1,69 +0,0 @@ -"""Module executing integration tests for the windows installer.""" -import os -import re -import subprocess -import time -from typing import Any - -import pytest - - -@pytest.mark.skipif(os.name != 'nt', reason='Windows installer tests must be run on Windows.') -def test_it(request: pytest.FixtureRequest) -> None: - try: - subprocess.check_call(['certbot', '--version']) - except (subprocess.CalledProcessError, OSError): - pass - else: - raise AssertionError('Expect certbot to not be available in the PATH.') - - try: - # Install certbot - subprocess.check_call([request.config.option.installer_path, '/S']) - - # Assert certbot is installed and runnable - output = subprocess.check_output(['certbot', '--version'], universal_newlines=True) - assert re.match(r'^certbot \d+\.\d+\.\d+.*$', - output), 'Flag --version does not output a version.' - - # Assert renew task is installed and ready - output = _ps('(Get-ScheduledTask -TaskName "Certbot Renew Task").State', - capture_stdout=True) - assert output.strip() == 'Ready' - - # Assert renew task is working - now = time.time() - _ps('Start-ScheduledTask -TaskName "Certbot Renew Task"') - - status = 'Running' - while status != 'Ready': - status = _ps('(Get-ScheduledTask -TaskName "Certbot Renew Task").State', - capture_stdout=True).strip() - time.sleep(1) - - log_path = os.path.join('C:\\', 'Certbot', 'log', 'letsencrypt.log') - - modification_time = os.path.getmtime(log_path) - assert now < modification_time, 'Certbot log file has not been modified by the renew task.' - - with open(log_path) as file_h: - data = file_h.read() - assert 'no renewal failures' in data, 'Renew task did not execute properly.' - - finally: - # Sadly this command cannot work in non interactive mode: uninstaller will - # ask explicitly permission in an UAC prompt - # print('Uninstalling Certbot ...') - # uninstall_path = _ps('(gci "HKLM:\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"' # pylint: disable=line-too-long - # ' | foreach { gp $_.PSPath }' - # ' | ? { $_ -match "Certbot" }' - # ' | select UninstallString)' - # '.UninstallString', capture_stdout=True) - # subprocess.check_call([uninstall_path, '/S']) - pass - - -def _ps(powershell_str: str, capture_stdout: bool = False) -> Any: - fn = subprocess.check_output if capture_stdout else subprocess.check_call - return fn(['powershell.exe', '-c', powershell_str], # type: ignore[operator] - universal_newlines=True) diff --git a/certbot/certbot/_internal/renewal.py b/certbot/certbot/_internal/renewal.py index 62e31f865..bad314538 100644 --- a/certbot/certbot/_internal/renewal.py +++ b/certbot/certbot/_internal/renewal.py @@ -568,8 +568,6 @@ def handle_renewal_request(config: configuration.NamespaceConfig) -> Tuple[list, raise errors.Error( f"{len(renew_failures)} renew failure(s), {len(parse_failures)} parse failure(s)") - # Windows installer integration tests rely on handle_renewal_request behavior here. - # If the text below changes, these tests will need to be updated accordingly. logger.debug("no renewal failures") return (renewed_domains, failed_domains) diff --git a/certbot/docs/contributing.rst b/certbot/docs/contributing.rst index 2af5f3016..cf2927656 100644 --- a/certbot/docs/contributing.rst +++ b/certbot/docs/contributing.rst @@ -238,8 +238,6 @@ certbot-apache and certbot-nginx client code to configure specific web servers certbot-dns-* client code to configure DNS providers -windows installer - Installs Certbot on Windows and is built using the files in windows-installer/ Plugin-architecture ------------------- @@ -587,8 +585,7 @@ Certbot's dependencies We attempt to pin all of Certbot's dependencies whenever we can for reliability and consistency. Some of the places we have Certbot's dependencies pinned -include our snaps, Docker images, Windows installer, CI, and our development -environments. +include our snaps, Docker images, CI, and our development environments. In most cases, the file where dependency versions are specified is ``tools/requirements.txt``. The one exception to this is our "oldest" tests diff --git a/tools/pinning/current/pyproject.toml b/tools/pinning/current/pyproject.toml index ae7df57a9..9443d5b44 100644 --- a/tools/pinning/current/pyproject.toml +++ b/tools/pinning/current/pyproject.toml @@ -35,7 +35,6 @@ certbot-apache = {path = "../../../certbot-apache", extras = ["dev"]} certbot = {path = "../../../certbot", extras = ["all"]} acme = {path = "../../../acme", extras = ["docs", "test"]} letstest = {path = "../../../letstest"} -windows-installer = {path = "../../../windows-installer"} # Extra dependencies # As of writing this, cython is a build dependency of pyyaml. Since there diff --git a/tools/requirements.txt b/tools/requirements.txt index 73e9061c4..48074d93a 100644 --- a/tools/requirements.txt +++ b/tools/requirements.txt @@ -15,8 +15,8 @@ azure-devops==7.1.0b4 ; python_version >= "3.9" and python_version < "4.0" babel==2.16.0 ; python_version >= "3.9" and python_version < "4.0" bcrypt==4.2.1 ; python_version >= "3.9" and python_version < "4.0" beautifulsoup4==4.12.3 ; python_version >= "3.9" and python_version < "4.0" -boto3==1.35.78 ; python_version >= "3.9" and python_version < "4.0" -botocore==1.35.78 ; python_version >= "3.9" and python_version < "4.0" +boto3==1.35.79 ; python_version >= "3.9" and python_version < "4.0" +botocore==1.35.79 ; python_version >= "3.9" and python_version < "4.0" build==1.2.2.post1 ; python_version >= "3.9" and python_version < "4.0" cachecontrol==0.14.1 ; python_version >= "3.9" and python_version < "4.0" cachetools==5.5.0 ; python_version >= "3.9" and python_version < "4.0" @@ -49,9 +49,9 @@ fabric==3.2.2 ; python_version >= "3.9" and python_version < "4.0" fastjsonschema==2.21.1 ; python_version >= "3.9" and python_version < "4.0" filelock==3.16.1 ; python_version >= "3.9" and python_version < "4.0" google-api-core==2.24.0 ; python_version >= "3.9" and python_version < "4.0" -google-api-python-client==2.154.0 ; python_version >= "3.9" and python_version < "4.0" +google-api-python-client==2.155.0 ; python_version >= "3.9" and python_version < "4.0" google-auth-httplib2==0.2.0 ; python_version >= "3.9" and python_version < "4.0" -google-auth==2.36.0 ; python_version >= "3.9" and python_version < "4.0" +google-auth==2.37.0 ; python_version >= "3.9" and python_version < "4.0" googleapis-common-protos==1.66.0 ; python_version >= "3.9" and python_version < "4.0" httplib2==0.22.0 ; python_version >= "3.9" and python_version < "4.0" idna==3.10 ; python_version >= "3.9" and python_version < "4.0" @@ -109,7 +109,6 @@ pycparser==2.22 ; python_version >= "3.9" and python_version < "4.0" pygments==2.18.0 ; python_version >= "3.9" and python_version < "4.0" pylint==3.0.2 ; python_version >= "3.9" and python_version < "4.0" pynacl==1.5.0 ; python_version >= "3.9" and python_version < "4.0" -pynsist==2.7 ; python_version >= "3.9" and python_version < "4.0" pyopenssl==24.3.0 ; python_version >= "3.9" and python_version < "4.0" pyotp==2.9.0 ; python_version >= "3.9" and python_version < "4.0" pyparsing==3.2.0 ; python_version >= "3.9" and python_version < "4.0" @@ -128,7 +127,6 @@ pywin32==308 ; python_version >= "3.9" and python_version < "4.0" and sys_platfo pyyaml==6.0.2 ; python_version >= "3.9" and python_version < "4.0" rapidfuzz==3.10.1 ; python_version >= "3.9" and python_version < "4.0" readme-renderer==44.0 ; python_version >= "3.9" and python_version < "4.0" -requests-download==0.1.2 ; python_version >= "3.9" and python_version < "4.0" requests-file==2.1.0 ; python_version >= "3.9" and python_version < "4.0" requests-oauthlib==2.0.0 ; python_version >= "3.9" and python_version < "4.0" requests-toolbelt==1.0.0 ; python_version >= "3.9" and python_version < "4.0" @@ -180,5 +178,4 @@ wcwidth==0.2.13 ; python_version >= "3.9" and python_version < "4.0" wheel==0.45.1 ; python_version >= "3.9" and python_version < "4.0" wrapt==1.17.0 ; python_version >= "3.9" and python_version < "4.0" xattr==1.1.0 ; python_version >= "3.9" and python_version < "4.0" and sys_platform == "darwin" -yarg==0.1.10 ; python_version >= "3.9" and python_version < "4.0" zipp==3.21.0 ; python_version >= "3.9" and python_version < "3.12" diff --git a/tools/venv.py b/tools/venv.py index 4044258ef..d8165f089 100755 --- a/tools/venv.py +++ b/tools/venv.py @@ -46,7 +46,6 @@ REQUIREMENTS = [ ] if sys.platform == 'win32': - REQUIREMENTS.append('-e windows-installer') REQUIREMENTS.remove('-e certbot-apache') REQUIREMENTS.remove('-e certbot-compatibility-test') diff --git a/windows-installer/.gitignore b/windows-installer/.gitignore deleted file mode 100644 index a1a48d6b8..000000000 --- a/windows-installer/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -build.* diff --git a/windows-installer/assets/certbot.ico b/windows-installer/assets/certbot.ico deleted file mode 100644 index 364c32098..000000000 Binary files a/windows-installer/assets/certbot.ico and /dev/null differ diff --git a/windows-installer/assets/preamble.py b/windows-installer/assets/preamble.py deleted file mode 100644 index fea8e9fd8..000000000 --- a/windows-installer/assets/preamble.py +++ /dev/null @@ -1,12 +0,0 @@ -"""Pynsist extra_preamble for the Certbot entry point. - -This preamble ensures that Certbot on Windows always runs with the --preconfigured-renewal -flag set. Since Pynsist creates a Scheduled Task for renewal, we want this flag to be set -so that we can provide the right automated renewal advice to Certbot on Windows users. - -""" - - -import sys - -sys.argv += ["--preconfigured-renewal"] diff --git a/windows-installer/assets/renew-down.ps1 b/windows-installer/assets/renew-down.ps1 deleted file mode 100644 index 60dc4d9e6..000000000 --- a/windows-installer/assets/renew-down.ps1 +++ /dev/null @@ -1,6 +0,0 @@ -$taskName = "Certbot Renew Task" - -$exists = Get-ScheduledTask | Where-Object {$_.TaskName -like $taskName} -if ($exists) { - Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -} diff --git a/windows-installer/assets/renew-up.ps1 b/windows-installer/assets/renew-up.ps1 deleted file mode 100644 index 224458748..000000000 --- a/windows-installer/assets/renew-up.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -function Get-ScriptDirectory { Split-Path $MyInvocation.ScriptName } -$down = Join-Path (Get-ScriptDirectory) 'renew-down.ps1' -& $down - -$taskName = "Certbot Renew Task" - -$action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument '-NoProfile -WindowStyle Hidden -Command "certbot renew"' -$delay = New-TimeSpan -Hours 12 -$triggerAM = New-ScheduledTaskTrigger -Daily -At 12am -RandomDelay $delay -$triggerPM = New-ScheduledTaskTrigger -Daily -At 12pm -RandomDelay $delay -# NB: For now scheduled task is set up under Administrators group account because Certbot Installer installs Certbot for all users. -# If in the future we allow the Installer to install Certbot for one specific user, the scheduled task will need to -# switch to this user, since Certbot will be available only for him. -$adminsSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544") -$adminsGroupID = $adminsSID.Translate([System.Security.Principal.NTAccount]).Value -$principal = New-ScheduledTaskPrincipal -GroupId $adminsGroupID -RunLevel Highest -Register-ScheduledTask -Action $action -Trigger $triggerAM,$triggerPM -TaskName $taskName -Description "Execute twice a day the 'certbot renew' command, to renew managed certificates if needed." -Principal $principal diff --git a/windows-installer/assets/run.bat b/windows-installer/assets/run.bat deleted file mode 100644 index efba28800..000000000 --- a/windows-installer/assets/run.bat +++ /dev/null @@ -1,31 +0,0 @@ -@echo off - -:: BatchGotAdmin -:------------------------------------- -REM --> Check for permissions - IF "%PROCESSOR_ARCHITECTURE%" EQU "amd64" ( ->nul 2>&1 "%SYSTEMROOT%\SysWOW64\cacls.exe" "%SYSTEMROOT%\SysWOW64\config\system" -) ELSE ( ->nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system" -) - -REM --> If error flag set, we do not have admin. -if '%errorlevel%' NEQ '0' ( - echo Requesting administrative privileges... - goto UACPrompt -) else ( goto gotAdmin ) - -:UACPrompt - echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs" - set params= %* - echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params:"=""%", "", "runas", 1 >> "%temp%\getadmin.vbs" - - "%temp%\getadmin.vbs" - del "%temp%\getadmin.vbs" - exit /B - -:gotAdmin - pushd "%CD%" - CD /D "%~dp0" -:-------------------------------------- -cmd.exe /k echo You can run 'certbot' commands here. Type 'certbot --help' for more information. diff --git a/windows-installer/assets/template.nsi b/windows-installer/assets/template.nsi deleted file mode 100644 index 5c551729a..000000000 --- a/windows-installer/assets/template.nsi +++ /dev/null @@ -1,285 +0,0 @@ -; This NSIS template is based on the built-in one in pynsist 2.7. -; Added lines are enclosed within "CERTBOT CUSTOM BEGIN/END" comments. -; If pynsist is upgraded, this template must be updated if necessary using the new built-in one. -; Original file can be found here: https://github.com/takluyver/pynsist/blob/2.7/nsist/pyapp.nsi - -!define PRODUCT_NAME "[[ib.appname]]" -!define PRODUCT_VERSION "[[ib.version]]" -!define PY_VERSION "[[ib.py_version]]" -!define PY_MAJOR_VERSION "[[ib.py_major_version]]" -!define BITNESS "[[ib.py_bitness]]" -!define ARCH_TAG "[[arch_tag]]" -!define INSTALLER_NAME "[[ib.installer_name]]" -!define PRODUCT_ICON "[[icon]]" - -; Marker file to tell the uninstaller that it's a user installation -!define USER_INSTALL_MARKER _user_install_marker - -SetCompressor lzma - -!if "${NSIS_PACKEDVERSION}" >= 0x03000000 - Unicode true - ManifestDPIAware true -!endif - -; CERTBOT CUSTOM BEGIN -; Administrator privileges are required to insert a new task in Windows Scheduler. -; Also comment out some options to disable ability to choose AllUsers/CurrentUser install mode. -; As a result, installer run always with admin privileges (because of MULTIUSER_EXECUTIONLEVEL), -; using the AllUsers installation mode by default (because of MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER -; not set), and this default behavior cannot be overridden (because of MULTIUSER_MUI not set). -; See https://nsis.sourceforge.io/Docs/MultiUser/Readme.html -!define MULTIUSER_EXECUTIONLEVEL Admin -;!define MULTIUSER_EXECUTIONLEVEL Highest -;!define MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER -;!define MULTIUSER_MUI -;!define MULTIUSER_INSTALLMODE_COMMANDLINE -; CERTBOT CUSTOM END -!define MULTIUSER_INSTALLMODE_INSTDIR "[[ib.appname]]" -[% if ib.py_bitness == 64 %] -!define MULTIUSER_INSTALLMODE_FUNCTION correct_prog_files -[% endif %] -!include MultiUser.nsh -!include FileFunc.nsh - -[% block modernui %] -; Modern UI installer stuff -!include "MUI2.nsh" -!define MUI_ABORTWARNING -!define MUI_ICON "[[icon]]" -!define MUI_UNICON "[[icon]]" - -; UI pages -[% block ui_pages %] -!insertmacro MUI_PAGE_WELCOME -[% if license_file %] -!insertmacro MUI_PAGE_LICENSE [[license_file]] -[% endif %] -; CERTBOT CUSTOM BEGIN -; Disable the installation mode page (AllUsers/CurrentUser) -;!insertmacro MULTIUSER_PAGE_INSTALLMODE -; CERTBOT CUSTOM END -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_PAGE_FINISH -[% endblock ui_pages %] -!insertmacro MUI_LANGUAGE "English" -[% endblock modernui %] - -; CERTBOT CUSTOM BEGIN -Name "${PRODUCT_NAME} (beta) ${PRODUCT_VERSION}" -;Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" -; CERTBOT CUSTOM END -OutFile "${INSTALLER_NAME}" -ShowInstDetails show - -Var cmdLineInstallDir - -Section -SETTINGS - SetOutPath "$INSTDIR" - SetOverwrite ifnewer -SectionEnd - -[% block sections %] - -Section "!${PRODUCT_NAME}" sec_app - ; CERTBOT CUSTOM BEGIN - ; Try to cleanup Certbot pkg directory to avoid dependencies conflicts - RMDir /r "$INSTDIR\pkgs" - ; CERTBOT CUSTOM END - - SetRegView [[ib.py_bitness]] - SectionIn RO - File ${PRODUCT_ICON} - SetOutPath "$INSTDIR\pkgs" - File /r "pkgs\*.*" - SetOutPath "$INSTDIR" - - ; Marker file for per-user install - StrCmp $MultiUser.InstallMode CurrentUser 0 +3 - FileOpen $0 "$INSTDIR\${USER_INSTALL_MARKER}" w - FileClose $0 - SetFileAttributes "$INSTDIR\${USER_INSTALL_MARKER}" HIDDEN - - [% block install_files %] - ; Install files - [% for destination, group in grouped_files %] - SetOutPath "[[destination]]" - [% for file in group %] - File "[[ file ]]" - [% endfor %] - [% endfor %] - - ; Install directories - [% for dir, destination in ib.install_dirs %] - SetOutPath "[[ pjoin(destination, dir) ]]" - File /r "[[dir]]\*.*" - [% endfor %] - [% endblock install_files %] - - [% block install_shortcuts %] - ; Install shortcuts - ; The output path becomes the working directory for shortcuts - SetOutPath "%HOMEDRIVE%\%HOMEPATH%" - [% if single_shortcut %] - [% for scname, sc in ib.shortcuts.items() %] - CreateShortCut "$SMPROGRAMS\[[scname]].lnk" "[[sc['target'] ]]" \ - '[[ sc['parameters'] ]]' "$INSTDIR\[[ sc['icon'] ]]" - [% endfor %] - [% else %] - [# Multiple shortcuts: create a directory for them #] - CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" - [% for scname, sc in ib.shortcuts.items() %] - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\[[scname]].lnk" "[[sc['target'] ]]" \ - '[[ sc['parameters'] ]]' "$INSTDIR\[[ sc['icon'] ]]" - [% endfor %] - [% endif %] - SetOutPath "$INSTDIR" - [% endblock install_shortcuts %] - - [% block install_commands %] - [% if has_commands %] - DetailPrint "Setting up command-line launchers..." - - StrCmp $MultiUser.InstallMode CurrentUser 0 AddSysPathSystem - ; Add to PATH for current user - nsExec::ExecToLog '[[ python ]] -Es "$INSTDIR\_system_path.py" add_user "$INSTDIR\bin"' - GoTo AddedSysPath - AddSysPathSystem: - ; Add to PATH for all users - nsExec::ExecToLog '[[ python ]] -Es "$INSTDIR\_system_path.py" add "$INSTDIR\bin"' - AddedSysPath: - [% endif %] - [% endblock install_commands %] - - ; Byte-compile Python files. - DetailPrint "Byte-compiling Python modules..." - nsExec::ExecToLog '[[ python ]] -m compileall -q "$INSTDIR\pkgs"' - WriteUninstaller $INSTDIR\uninstall.exe - ; Add ourselves to Add/remove programs - WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \ - "DisplayName" "${PRODUCT_NAME}" - WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \ - "UninstallString" '"$INSTDIR\uninstall.exe"' - WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \ - "InstallLocation" "$INSTDIR" - WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \ - "DisplayIcon" "$INSTDIR\${PRODUCT_ICON}" - [% if ib.publisher is not none %] - WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \ - "Publisher" "[[ib.publisher]]" - [% endif %] - WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \ - "DisplayVersion" "${PRODUCT_VERSION}" - WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \ - "NoModify" 1 - WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \ - "NoRepair" 1 - - ; CERTBOT CUSTOM BEGIN - ; Execute ps script to create the certbot renew task - DetailPrint "Setting up certbot renew scheduled task" - nsExec::ExecToStack 'powershell -inputformat none -ExecutionPolicy RemoteSigned -File "$INSTDIR\renew-up.ps1"' - ; CERTBOT CUSTOM END - - ; Check if we need to reboot - IfRebootFlag 0 noreboot - MessageBox MB_YESNO "A reboot is required to finish the installation. Do you wish to reboot now?" \ - /SD IDNO IDNO noreboot - Reboot - noreboot: -SectionEnd - -Section "Uninstall" - ; CERTBOT CUSTOM BEGIN - ; Execute ps script to remove the certbot renew task - nsExec::ExecToStack 'powershell -inputformat none -ExecutionPolicy RemoteSigned -File "$INSTDIR\renew-down.ps1"' - ; CERTBOT CUSTOM END - - SetRegView [[ib.py_bitness]] - SetShellVarContext all - IfFileExists "$INSTDIR\${USER_INSTALL_MARKER}" 0 +3 - SetShellVarContext current - Delete "$INSTDIR\${USER_INSTALL_MARKER}" - - Delete $INSTDIR\uninstall.exe - Delete "$INSTDIR\${PRODUCT_ICON}" - RMDir /r "$INSTDIR\pkgs" - - ; Remove ourselves from %PATH% - [% block uninstall_commands %] - [% if has_commands %] - nsExec::ExecToLog '[[ python ]] -Es "$INSTDIR\_system_path.py" remove "$INSTDIR\bin"' - [% endif %] - [% endblock uninstall_commands %] - - [% block uninstall_files %] - ; Uninstall files - [% for file, destination in ib.install_files %] - Delete "[[pjoin(destination, file)]]" - [% endfor %] - ; Uninstall directories - [% for dir, destination in ib.install_dirs %] - RMDir /r "[[pjoin(destination, dir)]]" - [% endfor %] - [% endblock uninstall_files %] - - [% block uninstall_shortcuts %] - ; Uninstall shortcuts - [% if single_shortcut %] - [% for scname in ib.shortcuts %] - Delete "$SMPROGRAMS\[[scname]].lnk" - [% endfor %] - [% else %] - RMDir /r "$SMPROGRAMS\${PRODUCT_NAME}" - [% endif %] - [% endblock uninstall_shortcuts %] - RMDir $INSTDIR - DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" -SectionEnd - -[% endblock sections %] - -; Functions - -Function .onMouseOverSection - ; Find which section the mouse is over, and set the corresponding description. - FindWindow $R0 "#32770" "" $HWNDPARENT - GetDlgItem $R0 $R0 1043 ; description item (must be added to the UI) - - [% block mouseover_messages %] - StrCmp $0 ${sec_app} "" +2 - SendMessage $R0 ${WM_SETTEXT} 0 "STR:${PRODUCT_NAME}" - - [% endblock mouseover_messages %] -FunctionEnd - -Function .onInit - ; Multiuser.nsh breaks /D command line parameter. Parse /INSTDIR instead. - ; Cribbing from https://nsis-dev.github.io/NSIS-Forums/html/t-299280.html - ${GetParameters} $0 - ClearErrors - ${GetOptions} '$0' "/INSTDIR=" $1 - IfErrors +2 ; Error means flag not found - StrCpy $cmdLineInstallDir $1 - ClearErrors - - !insertmacro MULTIUSER_INIT - - ; If cmd line included /INSTDIR, override the install dir set by MultiUser - StrCmp $cmdLineInstallDir "" +2 - StrCpy $INSTDIR $cmdLineInstallDir -FunctionEnd - -Function un.onInit - !insertmacro MULTIUSER_UNINIT -FunctionEnd - -[% if ib.py_bitness == 64 %] -Function correct_prog_files - ; The multiuser machinery doesn't know about the different Program files - ; folder for 64-bit applications. Override the install dir it set. - StrCmp $MultiUser.InstallMode AllUsers 0 +2 - StrCpy $INSTDIR "$PROGRAMFILES64\${MULTIUSER_INSTALLMODE_INSTDIR}" -FunctionEnd -[% endif %] diff --git a/windows-installer/setup.py b/windows-installer/setup.py deleted file mode 100644 index 62d8e4323..000000000 --- a/windows-installer/setup.py +++ /dev/null @@ -1,45 +0,0 @@ -from setuptools import find_packages -from setuptools import setup - -version = '1.0' - -setup( - name='windows-installer', - version=version, - description='Environment to build the Certbot Windows installer', - url='https://github.com/certbot/certbot', - author="Certbot Project", - author_email='certbot-dev@eff.org', - license='Apache License 2.0', - python_requires='>=3.9', - classifiers=[ - 'Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Operating System :: Microsoft :: Windows', - 'Topic :: Software Development :: Build Tools', - ], - - packages=find_packages(), - include_package_data=True, - install_requires=[ - # pynsist is pinned to an exact version so we can update - # assets/template.nsi as needed. The file is based on the default - # pynsist NSIS template and pynsist's documentation warns that custom - # templates may need to be updated for them to work with new versions - # of pynsist. See - # https://pynsist.readthedocs.io/en/latest/cfgfile.html#build-section. - 'pynsist==2.7' - ], - entry_points={ - 'console_scripts': [ - 'construct-windows-installer = windows_installer.construct:main', - ], - }, -) diff --git a/windows-installer/windows_installer/__init__.py b/windows-installer/windows_installer/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/windows-installer/windows_installer/construct.py b/windows-installer/windows_installer/construct.py deleted file mode 100644 index 0948b4cfe..000000000 --- a/windows-installer/windows_installer/construct.py +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/env python3 -import ctypes -import os -import shutil -import struct -import subprocess -import sys -import time - -PYTHON_VERSION = (3, 9, 11) -PYTHON_BITNESS = 64 -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) - shutil.copy(os.path.join(repo_path, 'windows-installer', 'assets', 'preamble.py'), 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-win_amd64.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 -extra_preamble=preamble.py -'''.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()