From bcadc53d2659c756d31effb9ddaba593601ad6a3 Mon Sep 17 00:00:00 2001 From: Adrien Ferrand Date: Tue, 17 Sep 2019 21:55:04 +0200 Subject: [PATCH] Improvements after review --- letsencrypt-auto-source/letsencrypt-auto | 42 +++-- .../letsencrypt-auto.template | 27 ++-- .../bootstrappers/rpm_python3_legacy.sh | 15 +- .../tests/centos6_tests.sh | 143 ++++++++++-------- 4 files changed, 128 insertions(+), 99 deletions(-) diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 93e41fea5..b4aa975d7 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -256,8 +256,10 @@ DeprecationBootstrap() { fi } -MIN_PYTHON_VERSION="2.7" -MIN_PYVER=$(echo "$MIN_PYTHON_VERSION" | sed 's/\.//') +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/\.//') # Sets LE_PYTHON to Python version string and PYVER to the first two # digits of the python version DeterminePythonVersion() { @@ -285,7 +287,15 @@ DeterminePythonVersion() { fi fi - PYVER=`"$LE_PYTHON" -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//'` + if [ "$USE_PYTHON_3" = 1 ]; then + MIN_PYVER=$MIN_PYVER3 + MIN_PYTHON_VERSION=$MIN_PYTHON_3_VERSION + else + MIN_PYVER=$MIN_PYVER2 + MIN_PYTHON_VERSION=$MIN_PYTHON_2_VERSION + fi + + 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..." @@ -471,6 +481,17 @@ BootstrapRpmCommon() { # number must be increased. BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION=1 +EnablePython36SCL() { + set +e + # Do nothing if Python 3.6 is already available + ! "$EXISTS" python3.6 > /dev/null 2> /dev/null || return + # Do nothing if SCL Python 3.6 is not installed + scl --list 2>/dev/null | grep -q rh-python36 || return + # Install SCL rh-python36 + . scl_source enable rh-python36 + set -e +} + BootstrapRpmPython3Legacy() { # Tested with: # - CentOS 6 @@ -510,8 +531,8 @@ BootstrapRpmPython3Legacy() { BootstrapRpmCommonBase "${python_pkgs}" - # Try now to enable SCL rh-python36 for systems that are not yet bootstrapped - # NB: function EnablePython36SCL has been defined along with BootstrapRpmPython3Legacy in certbot-auto + # Enable SCL rh-python36 after bootstrapping. + # NB: EnablePython36SCL has been defined along with BootstrapRpmPython3Legacy in certbot-auto EnablePython36SCL } @@ -795,17 +816,6 @@ elif [ -f /etc/redhat-release ]; then BootstrapMessage "Legacy Red Hat-based OSes that will use Python3" BootstrapRpmPython3Legacy } - EnablePython36SCL() { - # Do nothing if Python 3.6 is already available - if ! python3.6 --version > /dev/null 2> /dev/null; then - # Do nothing if SCL Python 3.6 is not installed - if [ -f /opt/rh/rh-python36/enable ]; then - set +e - . scl_source enable rh-python36 - set -e - fi - fi - } USE_PYTHON_3=1 BOOTSTRAP_VERSION="BootstrapRpmPython3Legacy $BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION" diff --git a/letsencrypt-auto-source/letsencrypt-auto.template b/letsencrypt-auto-source/letsencrypt-auto.template index 63c133a41..acb93e9df 100755 --- a/letsencrypt-auto-source/letsencrypt-auto.template +++ b/letsencrypt-auto-source/letsencrypt-auto.template @@ -256,8 +256,10 @@ DeprecationBootstrap() { fi } -MIN_PYTHON_VERSION="2.7" -MIN_PYVER=$(echo "$MIN_PYTHON_VERSION" | sed 's/\.//') +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/\.//') # Sets LE_PYTHON to Python version string and PYVER to the first two # digits of the python version DeterminePythonVersion() { @@ -285,7 +287,15 @@ DeterminePythonVersion() { fi fi - PYVER=`"$LE_PYTHON" -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//'` + if [ "$USE_PYTHON_3" = 1 ]; then + MIN_PYVER=$MIN_PYVER3 + MIN_PYTHON_VERSION=$MIN_PYTHON_3_VERSION + else + MIN_PYVER=$MIN_PYVER2 + MIN_PYTHON_VERSION=$MIN_PYTHON_2_VERSION + fi + + 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..." @@ -351,17 +361,6 @@ elif [ -f /etc/redhat-release ]; then BootstrapMessage "Legacy Red Hat-based OSes that will use Python3" BootstrapRpmPython3Legacy } - EnablePython36SCL() { - # Do nothing if Python 3.6 is already available - if ! "$EXISTS" python3.6 > /dev/null 2> /dev/null; then - # Do nothing if SCL Python 3.6 is not installed - if [ -f /opt/rh/rh-python36/enable ]; then - set +e - . scl_source enable rh-python36 - set -e - fi - fi - } USE_PYTHON_3=1 BOOTSTRAP_VERSION="BootstrapRpmPython3Legacy $BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION" diff --git a/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3_legacy.sh b/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3_legacy.sh index b3034f5e2..f7152a8f7 100644 --- a/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3_legacy.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3_legacy.sh @@ -2,6 +2,17 @@ # number must be increased. BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION=1 +EnablePython36SCL() { + set +e + # Do nothing if Python 3.6 is already available + ! "$EXISTS" python3.6 > /dev/null 2> /dev/null || return + # Do nothing if SCL Python 3.6 is not installed + scl --list 2>/dev/null | grep -q rh-python36 || return + # Install SCL rh-python36 + . scl_source enable rh-python36 + set -e +} + BootstrapRpmPython3Legacy() { # Tested with: # - CentOS 6 @@ -41,7 +52,7 @@ BootstrapRpmPython3Legacy() { BootstrapRpmCommonBase "${python_pkgs}" - # Try now to enable SCL rh-python36 for systems that are not yet bootstrapped - # NB: function EnablePython36SCL has been defined along with BootstrapRpmPython3Legacy in certbot-auto + # Enable SCL rh-python36 after bootstrapping. + # NB: EnablePython36SCL has been defined along with BootstrapRpmPython3Legacy in certbot-auto EnablePython36SCL } diff --git a/letsencrypt-auto-source/tests/centos6_tests.sh b/letsencrypt-auto-source/tests/centos6_tests.sh index dd97b1308..26a7c53d6 100644 --- a/letsencrypt-auto-source/tests/centos6_tests.sh +++ b/letsencrypt-auto-source/tests/centos6_tests.sh @@ -1,48 +1,48 @@ #!/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" # we're going to modify env variables, so do this in a subshell ( -. scl_source enable python27 + . scl_source enable python27 -# 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 >/dev/null 2>/dev/null + RESULT=$? + if [ $RESULT -eq 0 ]; then + echo "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 >/dev/null 2>/dev/null + RESULT=$? + if [ $RESULT -ne 0 ]; then + echo "ERROR: Python2.7 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 >/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 -echo "PASSED: Did not upgrade to Python3 when Python2.7 is present." + 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 >/dev/null 2>/dev/null RESULT=$? if [ $RESULT -eq 0 ]; then error "ERROR: Python2.7 is still available." @@ -55,29 +55,11 @@ if ! "$LE_AUTO" 2>&1 | grep -q "WARNING: couldn't find Python"; then exit 1 fi -# 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 -cat > /tmp/run.sh << UNLIKELY_EOF -#!/bin/bash -/tmp/certbot-auto > /dev/null 2> /dev/null -UNLIKELY_EOF -chmod +x /tmp/run.sh -/tmp/run.sh | tee /dev/null -rm -f /tmp/certbot-auto /tmp/run.sh -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 installed Python3.6 in a non-interactive shell with --non-interactive flag not set." - # bootstrap from the old letsencrypt-auto, this time installing python3.4 -"$LE_AUTO_PY_34" --no-self-upgrade -n > /dev/null 2> /dev/null +prev_version=$("$LE_AUTO_PY_34" --no-self-upgrade -n --version 2>/dev/null | tail -2 | head -1) # ensure python 3.4 is installed -python3.4 --version > /dev/null 2> /dev/null +python3.4 --version >/dev/null 2>/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." @@ -86,29 +68,56 @@ fi echo "PASSED: Successfully upgraded to Python3.4 using letsencrypt-auto < 0.37.0 when only Python2.6 is present." +# 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 +version=$(/tmp/certbot-auto --version 2>/dev/null | tee /dev/null | tail -2 | head -1) + +if ! echo "$version" | grep -q certbot; then + echo "Invalid certbot version: ${version}" + exit 1 +fi + +if [ "$version" != "$prev_version" ]; then + echo "ERROR: certbot-auto upgraded certbot in a non-interactive shell with --non-interactive flag not set." + 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 +"$LE_AUTO" --no-self-upgrade -n >/dev/null 2>/dev/null -# enable SCL rh-python36 -. scl_source enable rh-python36 +# Following tests are 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 + # 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 curent letsencrypt-auto when only Python2.6/Python3.4 are present." + echo "PASSED: Successfully upgraded to Python3.6 using current letsencrypt-auto when only Python2.6/Python3.4 are present." -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 -unset VENV_PATH + 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 +) # test using python3 pytest -v -s certbot/letsencrypt-auto-source/tests