mirror of
https://github.com/certbot/certbot.git
synced 2026-08-01 02:54:34 +02:00
remove the windows installer
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
recursive-include certbot_integration_tests/assets *
|
recursive-include certbot_integration_tests/assets *
|
||||||
include certbot_integration_tests/py.typed
|
include certbot_integration_tests/py.typed
|
||||||
include snap_integration_tests/py.typed
|
include snap_integration_tests/py.typed
|
||||||
include windows_installer_integration_tests/py.typed
|
|
||||||
|
|||||||
@@ -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.')
|
|
||||||
@@ -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)
|
|
||||||
@@ -568,8 +568,6 @@ def handle_renewal_request(config: configuration.NamespaceConfig) -> Tuple[list,
|
|||||||
raise errors.Error(
|
raise errors.Error(
|
||||||
f"{len(renew_failures)} renew failure(s), {len(parse_failures)} parse failure(s)")
|
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")
|
logger.debug("no renewal failures")
|
||||||
|
|
||||||
return (renewed_domains, failed_domains)
|
return (renewed_domains, failed_domains)
|
||||||
|
|||||||
@@ -238,8 +238,6 @@ certbot-apache and certbot-nginx
|
|||||||
client code to configure specific web servers
|
client code to configure specific web servers
|
||||||
certbot-dns-*
|
certbot-dns-*
|
||||||
client code to configure DNS providers
|
client code to configure DNS providers
|
||||||
windows installer
|
|
||||||
Installs Certbot on Windows and is built using the files in windows-installer/
|
|
||||||
|
|
||||||
Plugin-architecture
|
Plugin-architecture
|
||||||
-------------------
|
-------------------
|
||||||
@@ -587,8 +585,7 @@ Certbot's dependencies
|
|||||||
|
|
||||||
We attempt to pin all of Certbot's dependencies whenever we can for reliability
|
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
|
and consistency. Some of the places we have Certbot's dependencies pinned
|
||||||
include our snaps, Docker images, Windows installer, CI, and our development
|
include our snaps, Docker images, CI, and our development environments.
|
||||||
environments.
|
|
||||||
|
|
||||||
In most cases, the file where dependency versions are specified is
|
In most cases, the file where dependency versions are specified is
|
||||||
``tools/requirements.txt``. The one exception to this is our "oldest" tests
|
``tools/requirements.txt``. The one exception to this is our "oldest" tests
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ certbot-apache = {path = "../../../certbot-apache", extras = ["dev"]}
|
|||||||
certbot = {path = "../../../certbot", extras = ["all"]}
|
certbot = {path = "../../../certbot", extras = ["all"]}
|
||||||
acme = {path = "../../../acme", extras = ["docs", "test"]}
|
acme = {path = "../../../acme", extras = ["docs", "test"]}
|
||||||
letstest = {path = "../../../letstest"}
|
letstest = {path = "../../../letstest"}
|
||||||
windows-installer = {path = "../../../windows-installer"}
|
|
||||||
|
|
||||||
# Extra dependencies
|
# Extra dependencies
|
||||||
# As of writing this, cython is a build dependency of pyyaml. Since there
|
# As of writing this, cython is a build dependency of pyyaml. Since there
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ REQUIREMENTS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
REQUIREMENTS.append('-e windows-installer')
|
|
||||||
REQUIREMENTS.remove('-e certbot-apache')
|
REQUIREMENTS.remove('-e certbot-apache')
|
||||||
REQUIREMENTS.remove('-e certbot-compatibility-test')
|
REQUIREMENTS.remove('-e certbot-compatibility-test')
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
build
|
|
||||||
build.*
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 179 KiB |
@@ -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"]
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
$taskName = "Certbot Renew Task"
|
|
||||||
|
|
||||||
$exists = Get-ScheduledTask | Where-Object {$_.TaskName -like $taskName}
|
|
||||||
if ($exists) {
|
|
||||||
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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.
|
|
||||||
@@ -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 %]
|
|
||||||
@@ -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',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
@@ -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()
|
|
||||||
Reference in New Issue
Block a user