From d87c905c0601918093ffa50d1536cb5704a95190 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Tue, 5 Nov 2019 17:11:23 -0800 Subject: [PATCH] Add back Python 3.4 support (#7510) (#7511) * Revert "Deprecation warnings for Python 3.4 (#7378)" This reverts commit 6fcdfb0e5006be85500fad67a5a67b47befedb2a. * Revert "Migrate certbot-auto users on CentOS 6 to Python 3.6 (#7268)" This reverts commit e19b2e04c75b6df4e3f8a455700aa95fca79bcc3. * add changelog entry * keep mona in authors (cherry picked from commit 9b848b1d65783000a13ef3f94ac5fe0e8c3879e7) --- .travis.yml | 3 - CHANGELOG.md | 9 + acme/acme/__init__.py | 7 - certbot/main.py | 4 - ...{Dockerfile.redhat6 => Dockerfile.centos6} | 21 +- letsencrypt-auto-source/letsencrypt-auto | 212 +++++------------- .../letsencrypt-auto.template | 106 +++------ .../pieces/bootstrappers/rpm_common_base.sh | 24 +- .../pieces/bootstrappers/rpm_python3.sh | 7 + .../bootstrappers/rpm_python3_legacy.sh | 75 ------- .../tests/centos6_tests.sh | 147 ++++-------- .../tests/oraclelinux6_tests.sh | 85 ------- .../letstest/scripts/test_leauto_upgrades.sh | 2 - tests/letstest/scripts/test_sdists.sh | 13 -- tox.ini | 12 +- 15 files changed, 177 insertions(+), 550 deletions(-) rename letsencrypt-auto-source/{Dockerfile.redhat6 => Dockerfile.centos6} (50%) delete mode 100644 letsencrypt-auto-source/pieces/bootstrappers/rpm_python3_legacy.sh delete mode 100644 letsencrypt-auto-source/tests/oraclelinux6_tests.sh diff --git a/.travis.yml b/.travis.yml index a1172f086..22391c84f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -234,9 +234,6 @@ matrix: - sudo: required env: TOXENV=le_auto_centos6 services: docker - - sudo: required - env: TOXENV=le_auto_oraclelinux6 - services: docker <<: *extended-test-suite - sudo: required env: TOXENV=docker_dev diff --git a/CHANGELOG.md b/CHANGELOG.md index a0b6eaaa9..6c18de0d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). +## 0.40.1 - master + +### Changed + +* Added back support for Python 3.4 to Certbot components and certbot-auto due + to a bug when requiring Python 2.7 or 3.5+ on RHEL 6 based systems. + +More details about these changes can be found on our GitHub repo. + ## 0.40.0 - 2019-11-05 ### Added diff --git a/acme/acme/__init__.py b/acme/acme/__init__.py index e68ebd765..7439712b0 100644 --- a/acme/acme/__init__.py +++ b/acme/acme/__init__.py @@ -48,10 +48,3 @@ class _TLSSNI01DeprecationModule(object): def __dir__(self): # pragma: no cover return ['_module'] + dir(self._module) - -if sys.version_info[:2] == (3, 4): - warnings.warn( - "Python 3.4 support will be dropped in the next release of " - "acme. Please upgrade your Python version.", - PendingDeprecationWarning, - ) # pragma: no cover diff --git a/certbot/main.py b/certbot/main.py index 30d0f1d94..fc91aca5f 100644 --- a/certbot/main.py +++ b/certbot/main.py @@ -1368,10 +1368,6 @@ def main(cli_args=None): if config.func != plugins_cmd: raise - if sys.version_info[:2] == (3, 4): - logger.warning("Python 3.4 support will be dropped in the next release " - "of Certbot - please upgrade your Python version.") - set_displayer(config) # Reporter diff --git a/letsencrypt-auto-source/Dockerfile.redhat6 b/letsencrypt-auto-source/Dockerfile.centos6 similarity index 50% rename from letsencrypt-auto-source/Dockerfile.redhat6 rename to letsencrypt-auto-source/Dockerfile.centos6 index d5cdc0458..09aa52dcd 100644 --- a/letsencrypt-auto-source/Dockerfile.redhat6 +++ b/letsencrypt-auto-source/Dockerfile.centos6 @@ -1,13 +1,9 @@ # For running tests, build a docker image with a passwordless sudo and a trust # store we can manipulate. -ARG REDHAT_DIST_FLAVOR -FROM ${REDHAT_DIST_FLAVOR}:6 +FROM centos:6 -ARG REDHAT_DIST_FLAVOR - -RUN curl -O https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm \ - && rpm -ivh epel-release-latest-6.noarch.rpm +RUN yum install -y epel-release # Install pip and sudo: RUN yum install -y python-pip sudo @@ -31,18 +27,11 @@ RUN mkdir -p /home/lea/certbot COPY ./tests/certs/ca/my-root-ca.crt.pem /usr/local/share/ca-certificates/ RUN update-ca-trust -# Copy current letsencrypt-auto: +# Copy code: COPY . /home/lea/certbot/letsencrypt-auto-source -# Fetch previous letsencrypt-auto that was installing python 3.4 -RUN curl https://raw.githubusercontent.com/certbot/certbot/v0.38.0/letsencrypt-auto-source/letsencrypt-auto \ - -o /home/lea/certbot/letsencrypt-auto-source/letsencrypt-auto_py_34 \ - && chmod +x /home/lea/certbot/letsencrypt-auto-source/letsencrypt-auto_py_34 - -RUN cp /home/lea/certbot/letsencrypt-auto-source/tests/${REDHAT_DIST_FLAVOR}6_tests.sh /home/lea/certbot/letsencrypt-auto-source/tests/redhat6_tests.sh \ - && chmod +x /home/lea/certbot/letsencrypt-auto-source/tests/redhat6_tests.sh - USER lea WORKDIR /home/lea -CMD ["sudo", "certbot/letsencrypt-auto-source/tests/redhat6_tests.sh"] +RUN sudo chmod +x certbot/letsencrypt-auto-source/tests/centos6_tests.sh +CMD sudo certbot/letsencrypt-auto-source/tests/centos6_tests.sh diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 5df7f5f30..b2ab0e5dd 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -256,28 +256,20 @@ DeprecationBootstrap() { fi } -MIN_PYTHON_2_VERSION="2.7" -MIN_PYVER2=$(echo "$MIN_PYTHON_2_VERSION" | sed 's/\.//') -MIN_PYTHON_3_VERSION="3.5" -MIN_PYVER3=$(echo "$MIN_PYTHON_3_VERSION" | sed 's/\.//') +MIN_PYTHON_VERSION="2.7" +MIN_PYVER=$(echo "$MIN_PYTHON_VERSION" | sed 's/\.//') # Sets LE_PYTHON to Python version string and PYVER to the first two -# digits of the python version. -# MIN_PYVER and MIN_PYTHON_VERSION are also set by this function, and their -# values depend on if we try to use Python 3 or Python 2. +# digits of the python version DeterminePythonVersion() { # Arguments: "NOCRASH" if we shouldn't crash if we don't find a good python # # If no Python is found, PYVER is set to 0. if [ "$USE_PYTHON_3" = 1 ]; then - MIN_PYVER=$MIN_PYVER3 - MIN_PYTHON_VERSION=$MIN_PYTHON_3_VERSION for LE_PYTHON in "$LE_PYTHON" python3; do # Break (while keeping the LE_PYTHON value) if found. $EXISTS "$LE_PYTHON" > /dev/null && break done else - MIN_PYVER=$MIN_PYVER2 - MIN_PYTHON_VERSION=$MIN_PYTHON_2_VERSION for LE_PYTHON in "$LE_PYTHON" python2.7 python27 python2 python; do # Break (while keeping the LE_PYTHON value) if found. $EXISTS "$LE_PYTHON" > /dev/null && break @@ -293,7 +285,7 @@ DeterminePythonVersion() { fi fi - PYVER=$("$LE_PYTHON" -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//') + PYVER=`"$LE_PYTHON" -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//'` if [ "$PYVER" -lt "$MIN_PYVER" ]; then if [ "$1" != "NOCRASH" ]; then error "You have an ancient version of Python entombed in your operating system..." @@ -376,9 +368,7 @@ BootstrapDebCommon() { # Sets TOOL to the name of the package manager # Sets appropriate values for YES_FLAG and QUIET_FLAG based on $ASSUME_YES and $QUIET_FLAG. -# Note: this function is called both while selecting the bootstrap scripts and -# during the actual bootstrap. Some things like prompting to user can be done in the latter -# case, but not in the former one. +# Enables EPEL if applicable and possible. InitializeRPMCommonBase() { if type dnf 2>/dev/null then @@ -398,6 +388,26 @@ InitializeRPMCommonBase() { if [ "$QUIET" = 1 ]; then QUIET_FLAG='--quiet' fi + + if ! $TOOL list *virtualenv >/dev/null 2>&1; then + echo "To use Certbot, packages from the EPEL repository need to be installed." + if ! $TOOL list epel-release >/dev/null 2>&1; then + error "Enable the EPEL repository and try running Certbot again." + exit 1 + fi + if [ "$ASSUME_YES" = 1 ]; then + /bin/echo -n "Enabling the EPEL repository in 3 seconds..." + sleep 1s + /bin/echo -ne "\e[0K\rEnabling the EPEL repository in 2 seconds..." + sleep 1s + /bin/echo -e "\e[0K\rEnabling the EPEL repository in 1 second..." + sleep 1s + fi + if ! $TOOL install $YES_FLAG $QUIET_FLAG epel-release; then + error "Could not enable EPEL. Aborting bootstrap!" + exit 1 + fi + fi } BootstrapRpmCommonBase() { @@ -478,88 +488,13 @@ BootstrapRpmCommon() { BootstrapRpmCommonBase "$python_pkgs" } -# If new packages are installed by BootstrapRpmPython3 below, this version -# number must be increased. -BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION=1 - -# Checks if rh-python36 can be installed. -Python36SclIsAvailable() { - InitializeRPMCommonBase >/dev/null 2>&1; - - if "${TOOL}" list rh-python36 >/dev/null 2>&1; then - return 0 - fi - if "${TOOL}" list centos-release-scl >/dev/null 2>&1; then - return 0 - fi - return 1 -} - -# Try to enable rh-python36 from SCL if it is necessary and possible. -EnablePython36SCL() { - if "$EXISTS" python3.6 > /dev/null 2> /dev/null; then - return 0 - fi - if ! scl --list 2>/dev/null | grep -q rh-python36; then - return 0 - fi - set +e - . scl_source enable rh-python36 - set -e -} - -# This bootstrap concerns old RedHat-based distributions that do not ship by default -# with Python 2.7, but only Python 2.6. We bootstrap them by enabling SCL and installing -# Python 3.6. Some of these distributions are: CentOS/RHEL/OL/SL 6. -BootstrapRpmPython3Legacy() { - # Tested with: - # - CentOS 6 - - InitializeRPMCommonBase - - if ! "${TOOL}" list rh-python36 >/dev/null 2>&1; then - echo "To use Certbot on this operating system, packages from the SCL repository need to be installed." - if ! "${TOOL}" list centos-release-scl >/dev/null 2>&1; then - error "Enable the SCL repository and try running Certbot again." - exit 1 - fi - if [ "${ASSUME_YES}" = 1 ]; then - /bin/echo -n "Enabling the SCL repository in 3 seconds... (Press Ctrl-C to cancel)" - sleep 1s - /bin/echo -ne "\e[0K\rEnabling the SCL repository in 2 seconds... (Press Ctrl-C to cancel)" - sleep 1s - /bin/echo -e "\e[0K\rEnabling the SCL repository in 1 second... (Press Ctrl-C to cancel)" - sleep 1s - fi - if ! "${TOOL}" install "${YES_FLAG}" "${QUIET_FLAG}" centos-release-scl; then - error "Could not enable SCL. Aborting bootstrap!" - exit 1 - fi - fi - - # CentOS 6 must use rh-python36 from SCL - if "${TOOL}" list rh-python36 >/dev/null 2>&1; then - python_pkgs="rh-python36-python - rh-python36-python-virtualenv - rh-python36-python-devel - " - else - error "No supported Python package available to install. Aborting bootstrap!" - exit 1 - fi - - BootstrapRpmCommonBase "${python_pkgs}" - - # Enable SCL rh-python36 after bootstrapping. - EnablePython36SCL -} - # If new packages are installed by BootstrapRpmPython3 below, this version # number must be increased. BOOTSTRAP_RPM_PYTHON3_VERSION=1 BootstrapRpmPython3() { # Tested with: + # - CentOS 6 # - Fedora 29 InitializeRPMCommonBase @@ -570,6 +505,12 @@ BootstrapRpmPython3() { python3-virtualenv python3-devel " + # EPEL uses python34 + elif $TOOL list python34 >/dev/null 2>&1; then + python_pkgs="python34 + python34-devel + python34-tools + " else error "No supported Python package available to install. Aborting bootstrap!" exit 1 @@ -828,50 +769,31 @@ elif [ -f /etc/redhat-release ]; then RPM_DIST_VERSION=0 fi - # Handle legacy RPM distributions - if [ "$PYVER" -eq 26 ]; then - # Check if an automated bootstrap can be achieved on this system. - if ! Python36SclIsAvailable; then - INTERACTIVE_BOOTSTRAP=1 - fi + # Starting to Fedora 29, python2 is on a deprecation path. Let's move to python3 then. + # RHEL 8 also uses python3 by default. + if [ "$RPM_DIST_NAME" = "fedora" -a "$RPM_DIST_VERSION" -ge 29 -o "$PYVER" -eq 26 ]; then + RPM_USE_PYTHON_3=1 + elif [ "$RPM_DIST_NAME" = "rhel" -a "$RPM_DIST_VERSION" -ge 8 ]; then + RPM_USE_PYTHON_3=1 + elif [ "$RPM_DIST_NAME" = "centos" -a "$RPM_DIST_VERSION" -ge 8 ]; then + RPM_USE_PYTHON_3=1 + else + RPM_USE_PYTHON_3=0 + fi + if [ "$RPM_USE_PYTHON_3" = 1 ]; then Bootstrap() { - BootstrapMessage "Legacy RedHat-based OSes that will use Python3" - BootstrapRpmPython3Legacy + BootstrapMessage "RedHat-based OSes that will use Python3" + BootstrapRpmPython3 } USE_PYTHON_3=1 - BOOTSTRAP_VERSION="BootstrapRpmPython3Legacy $BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION" - - # Try now to enable SCL rh-python36 for systems already bootstrapped - # NB: EnablePython36SCL has been defined along with BootstrapRpmPython3Legacy in certbot-auto - EnablePython36SCL + BOOTSTRAP_VERSION="BootstrapRpmPython3 $BOOTSTRAP_RPM_PYTHON3_VERSION" else - # Starting to Fedora 29, python2 is on a deprecation path. Let's move to python3 then. - # RHEL 8 also uses python3 by default. - if [ "$RPM_DIST_NAME" = "fedora" -a "$RPM_DIST_VERSION" -ge 29 ]; then - RPM_USE_PYTHON_3=1 - elif [ "$RPM_DIST_NAME" = "rhel" -a "$RPM_DIST_VERSION" -ge 8 ]; then - RPM_USE_PYTHON_3=1 - elif [ "$RPM_DIST_NAME" = "centos" -a "$RPM_DIST_VERSION" -ge 8 ]; then - RPM_USE_PYTHON_3=1 - else - RPM_USE_PYTHON_3=0 - fi - - if [ "$RPM_USE_PYTHON_3" = 1 ]; then - Bootstrap() { - BootstrapMessage "RedHat-based OSes that will use Python3" - BootstrapRpmPython3 - } - USE_PYTHON_3=1 - BOOTSTRAP_VERSION="BootstrapRpmPython3 $BOOTSTRAP_RPM_PYTHON3_VERSION" - else - Bootstrap() { - BootstrapMessage "RedHat-based OSes" - BootstrapRpmCommon - } - BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION" - fi + Bootstrap() { + BootstrapMessage "RedHat-based OSes" + BootstrapRpmCommon + } + BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION" fi LE_PYTHON="$prev_le_python" @@ -1156,15 +1078,8 @@ if [ "$1" = "--le-auto-phase2" ]; then # If the selected Bootstrap function isn't a noop and it differs from the # previously used version if [ -n "$BOOTSTRAP_VERSION" -a "$BOOTSTRAP_VERSION" != "$PREV_BOOTSTRAP_VERSION" ]; then - # Check if we can rebootstrap without manual user intervention: this requires that - # certbot-auto is in non-interactive mode AND selected bootstrap does not claim to - # require a manual user intervention. - if [ "$NONINTERACTIVE" = 1 -a "$INTERACTIVE_BOOTSTRAP" != 1 ]; then - CAN_REBOOTSTRAP=1 - fi - # Check if rebootstrap can be done non-interactively and current shell is non-interactive - # (true if stdin and stdout are not attached to a terminal). - if [ \( "$CAN_REBOOTSTRAP" = 1 \) -o \( \( -t 0 \) -a \( -t 1 \) \) ]; then + # if non-interactive mode or stdin and stdout are connected to a terminal + if [ \( "$NONINTERACTIVE" = 1 \) -o \( \( -t 0 \) -a \( -t 1 \) \) ]; then if [ -d "$VENV_PATH" ]; then rm -rf "$VENV_PATH" fi @@ -1175,21 +1090,12 @@ if [ "$1" = "--le-auto-phase2" ]; then ln -s "$VENV_PATH" "$OLD_VENV_PATH" fi RerunWithArgs "$@" - # Otherwise bootstrap needs to be done manually by the user. else - # If it is because bootstrapping is interactive, --non-interactive will be of no use. - if [ "$INTERACTIVE_BOOTSTRAP" = 1 ]; then - error "Skipping upgrade because new OS dependencies may need to be installed." - error "This requires manual user intervention: please run this script again manually." - # If this is because of the environment (eg. non interactive shell without - # --non-interactive flag set), help the user in that direction. - else - error "Skipping upgrade because new OS dependencies may need to be installed." - error - error "To upgrade to a newer version, please run this script again manually so you can" - error "approve changes or with --non-interactive on the command line to automatically" - error "install any required packages." - fi + error "Skipping upgrade because new OS dependencies may need to be installed." + error + error "To upgrade to a newer version, please run this script again manually so you can" + error "approve changes or with --non-interactive on the command line to automatically" + error "install any required packages." # Set INSTALLED_VERSION to be the same so we don't update the venv INSTALLED_VERSION="$LE_AUTO_VERSION" # Continue to use OLD_VENV_PATH if the new venv doesn't exist diff --git a/letsencrypt-auto-source/letsencrypt-auto.template b/letsencrypt-auto-source/letsencrypt-auto.template index bc4b92092..31c5bb134 100755 --- a/letsencrypt-auto-source/letsencrypt-auto.template +++ b/letsencrypt-auto-source/letsencrypt-auto.template @@ -256,28 +256,20 @@ DeprecationBootstrap() { fi } -MIN_PYTHON_2_VERSION="2.7" -MIN_PYVER2=$(echo "$MIN_PYTHON_2_VERSION" | sed 's/\.//') -MIN_PYTHON_3_VERSION="3.5" -MIN_PYVER3=$(echo "$MIN_PYTHON_3_VERSION" | sed 's/\.//') +MIN_PYTHON_VERSION="2.7" +MIN_PYVER=$(echo "$MIN_PYTHON_VERSION" | sed 's/\.//') # Sets LE_PYTHON to Python version string and PYVER to the first two -# digits of the python version. -# MIN_PYVER and MIN_PYTHON_VERSION are also set by this function, and their -# values depend on if we try to use Python 3 or Python 2. +# digits of the python version DeterminePythonVersion() { # Arguments: "NOCRASH" if we shouldn't crash if we don't find a good python # # If no Python is found, PYVER is set to 0. if [ "$USE_PYTHON_3" = 1 ]; then - MIN_PYVER=$MIN_PYVER3 - MIN_PYTHON_VERSION=$MIN_PYTHON_3_VERSION for LE_PYTHON in "$LE_PYTHON" python3; do # Break (while keeping the LE_PYTHON value) if found. $EXISTS "$LE_PYTHON" > /dev/null && break done else - MIN_PYVER=$MIN_PYVER2 - MIN_PYTHON_VERSION=$MIN_PYTHON_2_VERSION for LE_PYTHON in "$LE_PYTHON" python2.7 python27 python2 python; do # Break (while keeping the LE_PYTHON value) if found. $EXISTS "$LE_PYTHON" > /dev/null && break @@ -293,7 +285,7 @@ DeterminePythonVersion() { fi fi - PYVER=$("$LE_PYTHON" -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//') + PYVER=`"$LE_PYTHON" -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//'` if [ "$PYVER" -lt "$MIN_PYVER" ]; then if [ "$1" != "NOCRASH" ]; then error "You have an ancient version of Python entombed in your operating system..." @@ -306,7 +298,6 @@ DeterminePythonVersion() { {{ bootstrappers/deb_common.sh }} {{ bootstrappers/rpm_common_base.sh }} {{ bootstrappers/rpm_common.sh }} -{{ bootstrappers/rpm_python3_legacy.sh }} {{ bootstrappers/rpm_python3.sh }} {{ bootstrappers/suse_common.sh }} {{ bootstrappers/arch_common.sh }} @@ -353,50 +344,31 @@ elif [ -f /etc/redhat-release ]; then RPM_DIST_VERSION=0 fi - # Handle legacy RPM distributions - if [ "$PYVER" -eq 26 ]; then - # Check if an automated bootstrap can be achieved on this system. - if ! Python36SclIsAvailable; then - INTERACTIVE_BOOTSTRAP=1 - fi + # Starting to Fedora 29, python2 is on a deprecation path. Let's move to python3 then. + # RHEL 8 also uses python3 by default. + if [ "$RPM_DIST_NAME" = "fedora" -a "$RPM_DIST_VERSION" -ge 29 -o "$PYVER" -eq 26 ]; then + RPM_USE_PYTHON_3=1 + elif [ "$RPM_DIST_NAME" = "rhel" -a "$RPM_DIST_VERSION" -ge 8 ]; then + RPM_USE_PYTHON_3=1 + elif [ "$RPM_DIST_NAME" = "centos" -a "$RPM_DIST_VERSION" -ge 8 ]; then + RPM_USE_PYTHON_3=1 + else + RPM_USE_PYTHON_3=0 + fi + if [ "$RPM_USE_PYTHON_3" = 1 ]; then Bootstrap() { - BootstrapMessage "Legacy RedHat-based OSes that will use Python3" - BootstrapRpmPython3Legacy + BootstrapMessage "RedHat-based OSes that will use Python3" + BootstrapRpmPython3 } USE_PYTHON_3=1 - BOOTSTRAP_VERSION="BootstrapRpmPython3Legacy $BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION" - - # Try now to enable SCL rh-python36 for systems already bootstrapped - # NB: EnablePython36SCL has been defined along with BootstrapRpmPython3Legacy in certbot-auto - EnablePython36SCL + BOOTSTRAP_VERSION="BootstrapRpmPython3 $BOOTSTRAP_RPM_PYTHON3_VERSION" else - # Starting to Fedora 29, python2 is on a deprecation path. Let's move to python3 then. - # RHEL 8 also uses python3 by default. - if [ "$RPM_DIST_NAME" = "fedora" -a "$RPM_DIST_VERSION" -ge 29 ]; then - RPM_USE_PYTHON_3=1 - elif [ "$RPM_DIST_NAME" = "rhel" -a "$RPM_DIST_VERSION" -ge 8 ]; then - RPM_USE_PYTHON_3=1 - elif [ "$RPM_DIST_NAME" = "centos" -a "$RPM_DIST_VERSION" -ge 8 ]; then - RPM_USE_PYTHON_3=1 - else - RPM_USE_PYTHON_3=0 - fi - - if [ "$RPM_USE_PYTHON_3" = 1 ]; then - Bootstrap() { - BootstrapMessage "RedHat-based OSes that will use Python3" - BootstrapRpmPython3 - } - USE_PYTHON_3=1 - BOOTSTRAP_VERSION="BootstrapRpmPython3 $BOOTSTRAP_RPM_PYTHON3_VERSION" - else - Bootstrap() { - BootstrapMessage "RedHat-based OSes" - BootstrapRpmCommon - } - BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION" - fi + Bootstrap() { + BootstrapMessage "RedHat-based OSes" + BootstrapRpmCommon + } + BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION" fi LE_PYTHON="$prev_le_python" @@ -573,15 +545,8 @@ if [ "$1" = "--le-auto-phase2" ]; then # If the selected Bootstrap function isn't a noop and it differs from the # previously used version if [ -n "$BOOTSTRAP_VERSION" -a "$BOOTSTRAP_VERSION" != "$PREV_BOOTSTRAP_VERSION" ]; then - # Check if we can rebootstrap without manual user intervention: this requires that - # certbot-auto is in non-interactive mode AND selected bootstrap does not claim to - # require a manual user intervention. - if [ "$NONINTERACTIVE" = 1 -a "$INTERACTIVE_BOOTSTRAP" != 1 ]; then - CAN_REBOOTSTRAP=1 - fi - # Check if rebootstrap can be done non-interactively and current shell is non-interactive - # (true if stdin and stdout are not attached to a terminal). - if [ \( "$CAN_REBOOTSTRAP" = 1 \) -o \( \( -t 0 \) -a \( -t 1 \) \) ]; then + # if non-interactive mode or stdin and stdout are connected to a terminal + if [ \( "$NONINTERACTIVE" = 1 \) -o \( \( -t 0 \) -a \( -t 1 \) \) ]; then if [ -d "$VENV_PATH" ]; then rm -rf "$VENV_PATH" fi @@ -592,21 +557,12 @@ if [ "$1" = "--le-auto-phase2" ]; then ln -s "$VENV_PATH" "$OLD_VENV_PATH" fi RerunWithArgs "$@" - # Otherwise bootstrap needs to be done manually by the user. else - # If it is because bootstrapping is interactive, --non-interactive will be of no use. - if [ "$INTERACTIVE_BOOTSTRAP" = 1 ]; then - error "Skipping upgrade because new OS dependencies may need to be installed." - error "This requires manual user intervention: please run this script again manually." - # If this is because of the environment (eg. non interactive shell without - # --non-interactive flag set), help the user in that direction. - else - error "Skipping upgrade because new OS dependencies may need to be installed." - error - error "To upgrade to a newer version, please run this script again manually so you can" - error "approve changes or with --non-interactive on the command line to automatically" - error "install any required packages." - fi + error "Skipping upgrade because new OS dependencies may need to be installed." + error + error "To upgrade to a newer version, please run this script again manually so you can" + error "approve changes or with --non-interactive on the command line to automatically" + error "install any required packages." # Set INSTALLED_VERSION to be the same so we don't update the venv INSTALLED_VERSION="$LE_AUTO_VERSION" # Continue to use OLD_VENV_PATH if the new venv doesn't exist diff --git a/letsencrypt-auto-source/pieces/bootstrappers/rpm_common_base.sh b/letsencrypt-auto-source/pieces/bootstrappers/rpm_common_base.sh index 2b00b199b..326ad8b3f 100644 --- a/letsencrypt-auto-source/pieces/bootstrappers/rpm_common_base.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/rpm_common_base.sh @@ -3,9 +3,7 @@ # Sets TOOL to the name of the package manager # Sets appropriate values for YES_FLAG and QUIET_FLAG based on $ASSUME_YES and $QUIET_FLAG. -# Note: this function is called both while selecting the bootstrap scripts and -# during the actual bootstrap. Some things like prompting to user can be done in the latter -# case, but not in the former one. +# Enables EPEL if applicable and possible. InitializeRPMCommonBase() { if type dnf 2>/dev/null then @@ -25,6 +23,26 @@ InitializeRPMCommonBase() { if [ "$QUIET" = 1 ]; then QUIET_FLAG='--quiet' fi + + if ! $TOOL list *virtualenv >/dev/null 2>&1; then + echo "To use Certbot, packages from the EPEL repository need to be installed." + if ! $TOOL list epel-release >/dev/null 2>&1; then + error "Enable the EPEL repository and try running Certbot again." + exit 1 + fi + if [ "$ASSUME_YES" = 1 ]; then + /bin/echo -n "Enabling the EPEL repository in 3 seconds..." + sleep 1s + /bin/echo -ne "\e[0K\rEnabling the EPEL repository in 2 seconds..." + sleep 1s + /bin/echo -e "\e[0K\rEnabling the EPEL repository in 1 second..." + sleep 1s + fi + if ! $TOOL install $YES_FLAG $QUIET_FLAG epel-release; then + error "Could not enable EPEL. Aborting bootstrap!" + exit 1 + fi + fi } BootstrapRpmCommonBase() { diff --git a/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3.sh b/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3.sh index ac0553db5..f33b07ca9 100644 --- a/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3.sh @@ -4,6 +4,7 @@ BOOTSTRAP_RPM_PYTHON3_VERSION=1 BootstrapRpmPython3() { # Tested with: + # - CentOS 6 # - Fedora 29 InitializeRPMCommonBase @@ -14,6 +15,12 @@ BootstrapRpmPython3() { python3-virtualenv python3-devel " + # EPEL uses python34 + elif $TOOL list python34 >/dev/null 2>&1; then + python_pkgs="python34 + python34-devel + python34-tools + " else error "No supported Python package available to install. Aborting bootstrap!" exit 1 diff --git a/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3_legacy.sh b/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3_legacy.sh deleted file mode 100644 index 0935c1b94..000000000 --- a/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3_legacy.sh +++ /dev/null @@ -1,75 +0,0 @@ -# If new packages are installed by BootstrapRpmPython3 below, this version -# number must be increased. -BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION=1 - -# Checks if rh-python36 can be installed. -Python36SclIsAvailable() { - InitializeRPMCommonBase >/dev/null 2>&1; - - if "${TOOL}" list rh-python36 >/dev/null 2>&1; then - return 0 - fi - if "${TOOL}" list centos-release-scl >/dev/null 2>&1; then - return 0 - fi - return 1 -} - -# Try to enable rh-python36 from SCL if it is necessary and possible. -EnablePython36SCL() { - if "$EXISTS" python3.6 > /dev/null 2> /dev/null; then - return 0 - fi - if ! scl --list 2>/dev/null | grep -q rh-python36; then - return 0 - fi - set +e - . scl_source enable rh-python36 - set -e -} - -# This bootstrap concerns old RedHat-based distributions that do not ship by default -# with Python 2.7, but only Python 2.6. We bootstrap them by enabling SCL and installing -# Python 3.6. Some of these distributions are: CentOS/RHEL/OL/SL 6. -BootstrapRpmPython3Legacy() { - # Tested with: - # - CentOS 6 - - InitializeRPMCommonBase - - if ! "${TOOL}" list rh-python36 >/dev/null 2>&1; then - echo "To use Certbot on this operating system, packages from the SCL repository need to be installed." - if ! "${TOOL}" list centos-release-scl >/dev/null 2>&1; then - error "Enable the SCL repository and try running Certbot again." - exit 1 - fi - if [ "${ASSUME_YES}" = 1 ]; then - /bin/echo -n "Enabling the SCL repository in 3 seconds... (Press Ctrl-C to cancel)" - sleep 1s - /bin/echo -ne "\e[0K\rEnabling the SCL repository in 2 seconds... (Press Ctrl-C to cancel)" - sleep 1s - /bin/echo -e "\e[0K\rEnabling the SCL repository in 1 second... (Press Ctrl-C to cancel)" - sleep 1s - fi - if ! "${TOOL}" install "${YES_FLAG}" "${QUIET_FLAG}" centos-release-scl; then - error "Could not enable SCL. Aborting bootstrap!" - exit 1 - fi - fi - - # CentOS 6 must use rh-python36 from SCL - if "${TOOL}" list rh-python36 >/dev/null 2>&1; then - python_pkgs="rh-python36-python - rh-python36-python-virtualenv - rh-python36-python-devel - " - else - error "No supported Python package available to install. Aborting bootstrap!" - exit 1 - fi - - BootstrapRpmCommonBase "${python_pkgs}" - - # Enable SCL rh-python36 after bootstrapping. - EnablePython36SCL -} diff --git a/letsencrypt-auto-source/tests/centos6_tests.sh b/letsencrypt-auto-source/tests/centos6_tests.sh index c15cd80ec..2c6dcf734 100644 --- a/letsencrypt-auto-source/tests/centos6_tests.sh +++ b/letsencrypt-auto-source/tests/centos6_tests.sh @@ -1,140 +1,81 @@ #!/bin/bash # Start by making sure your system is up-to-date: -yum update -y >/dev/null -yum install -y centos-release-scl >/dev/null -yum install -y python27 >/dev/null 2>/dev/null +yum update -y > /dev/null +yum install -y centos-release-scl > /dev/null +yum install -y python27 > /dev/null 2> /dev/null -LE_AUTO_PY_34="certbot/letsencrypt-auto-source/letsencrypt-auto_py_34" LE_AUTO="certbot/letsencrypt-auto-source/letsencrypt-auto" -# Last version of certbot-auto that was bootstraping Python 3.4 for CentOS 6 users -INITIAL_CERTBOT_VERSION_PY34="certbot 0.38.0" - # we're going to modify env variables, so do this in a subshell ( - . scl_source enable python27 +source /opt/rh/python27/enable - # ensure python 3 isn't installed - python3 --version >/dev/null 2>/dev/null - RESULT=$? - if [ $RESULT -eq 0 ]; then - echo "ERROR: Python3 is already installed." - exit 1 - fi +# ensure python 3 isn't installed +python3 --version 2> /dev/null +RESULT=$? +if [ $RESULT -eq 0 ]; then + error "Python3 is already installed." + exit 1 +fi - # ensure python2.7 is available - python2.7 --version >/dev/null 2>/dev/null - RESULT=$? - if [ $RESULT -ne 0 ]; then - echo "ERROR: Python2.7 is not available." - exit 1 - fi +# ensure python2.7 is available +python2.7 --version 2> /dev/null +RESULT=$? +if [ $RESULT -ne 0 ]; then + error "Python3 is not available." + exit 1 +fi - # bootstrap, but don't install python 3. - "$LE_AUTO" --no-self-upgrade -n >/dev/null 2>/dev/null +# bootstrap, but don't install python 3. +"$LE_AUTO" --no-self-upgrade -n > /dev/null 2> /dev/null - # ensure python 3 isn't installed - python3 --version >/dev/null 2>/dev/null - RESULT=$? - if [ $RESULT -eq 0 ]; then - echo "ERROR: letsencrypt-auto installed Python3 even though Python2.7 is present." - exit 1 - fi +# ensure python 3 isn't installed +python3 --version 2> /dev/null +RESULT=$? +if [ $RESULT -eq 0 ]; then + error "letsencrypt-auto installed Python3 even though Python2.7 is present." + exit 1 +fi - echo "PASSED: Did not upgrade to Python3 when Python2.7 is present." +echo "" +echo "PASSED: Did not upgrade to Python3 when Python2.7 is present." ) # ensure python2.7 isn't available -python2.7 --version >/dev/null 2>/dev/null +python2.7 --version 2> /dev/null RESULT=$? if [ $RESULT -eq 0 ]; then - error "ERROR: Python2.7 is still available." + error "Python2.7 is still available." exit 1 fi # Skip self upgrade due to Python 3 not being available. if ! "$LE_AUTO" 2>&1 | grep -q "WARNING: couldn't find Python"; then - echo "ERROR: Python upgrade failure warning not printed!" + echo "Python upgrade failure warning not printed!" exit 1 fi -# bootstrap from the old letsencrypt-auto, this time installing python3.4 -"$LE_AUTO_PY_34" --no-self-upgrade -n >/dev/null 2>/dev/null +# bootstrap, this time installing python3 +"$LE_AUTO" --no-self-upgrade -n > /dev/null 2> /dev/null -# ensure python 3.4 is installed -python3.4 --version >/dev/null 2>/dev/null +# ensure python 3 is installed +python3 --version > /dev/null RESULT=$? if [ $RESULT -ne 0 ]; then - echo "ERROR: letsencrypt-auto failed to install Python3.4 using letsencrypt-auto < 0.37.0 when only Python2.6 is present." + error "letsencrypt-auto failed to install Python3 when only Python2.6 is present." exit 1 fi -echo "PASSED: Successfully upgraded to Python3.4 using letsencrypt-auto < 0.37.0 when only Python2.6 is present." +echo "PASSED: Successfully upgraded to Python3 when only Python2.6 is present." +echo "" -# As "certbot-auto" (so without implicit --non-interactive flag set), check that the script -# refuses to install SCL Python 3.6 when run in a non interactive shell (simulated here -# using | tee /dev/null) if --non-interactive flag is not provided. -cp "$LE_AUTO" /tmp/certbot-auto -# NB: Readline has an issue on all Python versions for CentOS 6, making `certbot --version` -# output an unprintable ASCII character on a new line at the end. -# So we take the second last line of the output. -version=$(/tmp/certbot-auto --version 2>/dev/null | tee /dev/null | tail -2 | head -1) - -if [ "$version" != "$INITIAL_CERTBOT_VERSION_PY34" ]; then - echo "ERROR: certbot-auto upgraded certbot in a non-interactive shell with --non-interactive flag not set." +export VENV_PATH=$(mktemp -d) +"$LE_AUTO" -n --no-bootstrap --no-self-upgrade --version >/dev/null 2>&1 +if [ "$($VENV_PATH/bin/python -V 2>&1 | cut -d" " -f2 | cut -d. -f1)" != 3 ]; then + echo "Python 3 wasn't used with --no-bootstrap!" exit 1 fi - -echo "PASSED: certbot-auto did not upgrade certbot in a non-interactive shell with --non-interactive flag not set." - -if [ -f /opt/rh/rh-python36/enable ]; then - echo "ERROR: certbot-auto installed Python3.6 in a non-interactive shell with --non-interactive flag not set." - exit 1 -fi - -echo "PASSED: certbot-auto did not install Python3.6 in a non-interactive shell with --non-interactive flag not set." - -# now bootstrap from current letsencrypt-auto, that will install python3.6 from SCL -"$LE_AUTO" --no-self-upgrade -n >/dev/null 2>/dev/null - -# Following test is exectued in a subshell, to not leak any environment variable -( - # enable SCL rh-python36 - . scl_source enable rh-python36 - - # ensure python 3.6 is installed - python3.6 --version >/dev/null 2>/dev/null - RESULT=$? - if [ $RESULT -ne 0 ]; then - echo "ERROR: letsencrypt-auto failed to install Python3.6 using current letsencrypt-auto when only Python2.6/Python3.4 are present." - exit 1 - fi - - echo "PASSED: Successfully upgraded to Python3.6 using current letsencrypt-auto when only Python2.6/Python3.4 are present." -) - -# Following test is exectued in a subshell, to not leak any environment variable -( - export VENV_PATH=$(mktemp -d) - "$LE_AUTO" -n --no-bootstrap --no-self-upgrade --version >/dev/null 2>&1 - if [ "$($VENV_PATH/bin/python -V 2>&1 | cut -d" " -f2 | cut -d. -f1-2)" != "3.6" ]; then - echo "ERROR: Python 3.6 wasn't used with --no-bootstrap!" - exit 1 - fi -) - -# Following test is exectued in a subshell, to not leak any environment variable -( - # enable SCL rh-python36 - . scl_source enable rh-python36 - - # ensure everything works fine with certbot-auto bootstrap when python 3.6 is already enabled - export VENV_PATH=$(mktemp -d) - if ! "$LE_AUTO" --no-self-upgrade -n --version >/dev/null 2>/dev/null; then - echo "ERROR: Certbot-auto broke when Python 3.6 SCL is already enabled." - exit 1 - fi -) +unset VENV_PATH # test using python3 pytest -v -s certbot/letsencrypt-auto-source/tests diff --git a/letsencrypt-auto-source/tests/oraclelinux6_tests.sh b/letsencrypt-auto-source/tests/oraclelinux6_tests.sh deleted file mode 100644 index f3fd952f3..000000000 --- a/letsencrypt-auto-source/tests/oraclelinux6_tests.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/bash -set -eo pipefail -# Start by making sure your system is up-to-date: -yum update -y >/dev/null - -LE_AUTO_PY_34="certbot/letsencrypt-auto-source/letsencrypt-auto_py_34" -LE_AUTO="certbot/letsencrypt-auto-source/letsencrypt-auto" - -# Apply installation instructions from official documentation: -# https://certbot.eff.org/lets-encrypt/centosrhel6-other -cp "$LE_AUTO" /usr/local/bin/certbot-auto -chown root /usr/local/bin/certbot-auto -chmod 0755 /usr/local/bin/certbot-auto -LE_AUTO=/usr/local/bin/certbot-auto - -# Last version of certbot-auto that was bootstraping Python 3.4 for CentOS 6 users -INITIAL_CERTBOT_VERSION_PY34="certbot 0.38.0" - -# Check bootstrap from current certbot-auto will fail, because SCL is not enabled. -set +o pipefail -if ! "$LE_AUTO" -n 2>&1 | grep -q "Enable the SCL repository and try running Certbot again."; then - echo "ERROR: Bootstrap was not aborted although SCL was not installed!" - exit 1 -fi -set -o pipefail - -echo "PASSED: Bootstrap was aborted since SCL was not installed." - -# Bootstrap from the old letsencrypt-auto, Python 3.4 will be installed from EPEL. -"$LE_AUTO_PY_34" --no-self-upgrade -n --install-only >/dev/null 2>/dev/null - -# Ensure Python 3.4 is installed -if ! command -v python3.4 &>/dev/null; then - echo "ERROR: old letsencrypt-auto failed to install Python3.4 using letsencrypt-auto < 0.37.0 when only Python2.6 is present." - exit 1 -fi - -echo "PASSED: Bootstrap from old letsencrypt-auto succeeded and installed Python 3.4" - -# Expect certbot-auto to skip rebootstrapping with a warning since SCL is not installed. -if ! "$LE_AUTO" --non-interactive --version 2>&1 | grep -q "This requires manual user intervention"; then - echo "FAILED: Script certbot-auto did not print a warning about needing manual intervention!" - exit 1 -fi - -echo "PASSED: Script certbot-auto did not rebootstrap." - -# NB: Readline has an issue on all Python versions for OL 6, making `certbot --version` -# output an unprintable ASCII character on a new line at the end. -# So we take the second last line of the output. -version=$($LE_AUTO --version 2>/dev/null | tail -2 | head -1) - -if [ "$version" != "$INITIAL_CERTBOT_VERSION_PY34" ]; then - echo "ERROR: Script certbot-auto upgraded certbot in a non-interactive shell while SCL was not enabled." - exit 1 -fi - -echo "PASSED: Script certbot-auto did not upgrade certbot but started it successfully while SCL was not enabled." - -# Enable SCL -yum install -y oracle-softwarecollection-release-el6 >/dev/null - -# Expect certbot-auto to bootstrap successfully since SCL is available. -"$LE_AUTO" -n --version &>/dev/null - -if [ "$(/opt/eff.org/certbot/venv/bin/python -V 2>&1 | cut -d" " -f2 | cut -d. -f1-2)" != "3.6" ]; then - echo "ERROR: Script certbot-auto failed to bootstrap and install Python 3.6 while SCL is available." - exit 1 -fi - -if ! /opt/eff.org/certbot/venv/bin/certbot --version > /dev/null 2> /dev/null; then - echo "ERROR: Script certbot-auto did not install certbot correctly while SCL is enabled." - exit 1 -fi - -echo "PASSED: Script certbot-auto correctly bootstraped Certbot using rh-python36 when SCL is available." - -# Expect certbot-auto will be totally silent now that everything has been correctly boostraped. -OUTPUT_LEN=$("$LE_AUTO" --install-only --no-self-upgrade --quiet 2>&1 | wc -c) -if [ "$OUTPUT_LEN" != 0 ]; then - echo certbot-auto produced unexpected output! - exit 1 -fi - -echo "PASSED: Script certbot-auto did not print anything in quiet mode." diff --git a/tests/letstest/scripts/test_leauto_upgrades.sh b/tests/letstest/scripts/test_leauto_upgrades.sh index fc7632793..541f54f6b 100755 --- a/tests/letstest/scripts/test_leauto_upgrades.sh +++ b/tests/letstest/scripts/test_leauto_upgrades.sh @@ -117,8 +117,6 @@ if ! diff letsencrypt-auto letsencrypt-auto-source/letsencrypt-auto ; then fi if [ "$RUN_RHEL6_TESTS" = 1 ]; then - # Add the SCL python release to PATH in order to resolve python3 command - PATH="/opt/rh/rh-python36/root/usr/bin:$PATH" if ! command -v python3; then echo "Python3 wasn't properly installed" exit 1 diff --git a/tests/letstest/scripts/test_sdists.sh b/tests/letstest/scripts/test_sdists.sh index c8ce9fe7f..347589e04 100755 --- a/tests/letstest/scripts/test_sdists.sh +++ b/tests/letstest/scripts/test_sdists.sh @@ -1,21 +1,8 @@ #!/bin/sh -xe cd letsencrypt - -# If we're on a RHEL 6 based system, we can be confident Python is already -# installed because the package manager is written in Python. -if command -v python && [ $(python -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//') -eq 26 ]; then - # RHEL/CentOS 6 will need a special treatment, so we need to detect that environment - RUN_RHEL6_TESTS=1 -fi - letsencrypt-auto-source/letsencrypt-auto --install-only -n --debug -if [ "$RUN_RHEL6_TESTS" = 1 ]; then - # Enable the SCL Python 3.6 installed by letsencrypt-auto bootstrap - PATH="/opt/rh/rh-python36/root/usr/bin:$PATH" -fi - PLUGINS="certbot-apache certbot-nginx" PYTHON_MAJOR_VERSION=$(/opt/eff.org/certbot/venv/bin/python --version 2>&1 | cut -d" " -f 2 | cut -d. -f1) TEMP_DIR=$(mktemp -d) diff --git a/tox.ini b/tox.ini index 952204a9e..04715cc2f 100644 --- a/tox.ini +++ b/tox.ini @@ -206,17 +206,7 @@ passenv = DOCKER_* # At the moment, this tests under Python 2.6 only, as only that version is # readily available on the CentOS 6 Docker image. commands = - docker build -f letsencrypt-auto-source/Dockerfile.redhat6 --build-arg REDHAT_DIST_FLAVOR=centos -t lea letsencrypt-auto-source - docker run --rm -t -i lea -whitelist_externals = - docker -passenv = DOCKER_* - -[testenv:le_auto_oraclelinux6] -# At the moment, this tests under Python 2.6 only, as only that version is -# readily available on the Oracle Linux 6 Docker image. -commands = - docker build -f letsencrypt-auto-source/Dockerfile.redhat6 --build-arg REDHAT_DIST_FLAVOR=oraclelinux -t lea letsencrypt-auto-source + docker build -f letsencrypt-auto-source/Dockerfile.centos6 -t lea letsencrypt-auto-source docker run --rm -t -i lea whitelist_externals = docker