mirror of
https://github.com/certbot/certbot.git
synced 2026-06-08 08:12:15 -04:00
In Phase 2, recreate a venv and reinstall Python packages only if necessary.
* Teach the build script how to do special vars. Factor up file reading. * Use a static string for the PyPI JSON location, as it will soon be overrideable via an env var for testing.
This commit is contained in:
parent
02255fa024
commit
46779da3b5
3 changed files with 72 additions and 43 deletions
|
|
@ -2,7 +2,8 @@
|
|||
"""Stitch together the letsencrypt-auto script.
|
||||
|
||||
Implement a simple templating language in which {{ some/file }} turns into the
|
||||
contents of the file at ./pieces/some/file.
|
||||
contents of the file at ./pieces/some/file except for certain tokens which have
|
||||
other, special definitions.
|
||||
|
||||
"""
|
||||
from os.path import dirname, join
|
||||
|
|
@ -10,18 +11,37 @@ import re
|
|||
from sys import argv
|
||||
|
||||
|
||||
def le_version(build_script_dir):
|
||||
"""Return the version number stamped in letsencrypt/__init__.py."""
|
||||
return re.search('''^__version__ = ['"](.+)['"].*''',
|
||||
file_contents(join(dirname(build_script_dir),
|
||||
'letsencrypt',
|
||||
'__init__.py')),
|
||||
re.M).group(1)
|
||||
|
||||
|
||||
def file_contents(path):
|
||||
with open(path) as file:
|
||||
return file.read()
|
||||
|
||||
|
||||
def main():
|
||||
dir = dirname(argv[0])
|
||||
|
||||
def replacer(match):
|
||||
rel_path = match.group(1)
|
||||
with open(join(dir, 'pieces', rel_path)) as replacement:
|
||||
return replacement.read()
|
||||
special_replacements = {
|
||||
'LE_AUTO_VERSION': le_version(dir)
|
||||
}
|
||||
|
||||
with open(join(dir, 'letsencrypt-auto.template')) as template:
|
||||
result = re.sub(r'{{\s*([A-Za-z0-9_./-]+)\s*}}',
|
||||
replacer,
|
||||
template.read())
|
||||
def replacer(match):
|
||||
token = match.group(1)
|
||||
if token in special_replacements:
|
||||
return special_replacements[token]
|
||||
else:
|
||||
return file_contents(join(dir, 'pieces', token))
|
||||
|
||||
result = re.sub(r'{{\s*([A-Za-z0-9_./-]+)\s*}}',
|
||||
replacer,
|
||||
file_contents(join(dir, 'letsencrypt-auto.template')))
|
||||
with open(join(dir, 'letsencrypt-auto'), 'w') as out:
|
||||
out.write(result)
|
||||
|
||||
|
|
|
|||
|
|
@ -160,43 +160,49 @@ elif [ "$1" = "--no-self-upgrade" ]; then
|
|||
# Phase 2: Create venv, install LE, and run.
|
||||
|
||||
shift 1 # the --no-self-upgrade arg
|
||||
echo "Creating virtual environment..."
|
||||
# TODO: Embed LE version here, and compare it against letsencrypt --version.
|
||||
# If it matches, there's no need to recreate the venv.
|
||||
rm -rf "$VENV_PATH"
|
||||
DeterminePythonVersion
|
||||
if [ "$VERBOSE" = 1 ]; then
|
||||
virtualenv --no-site-packages --python $LE_PYTHON $VENV_PATH
|
||||
if [ -f $VENV_BIN/letsencrypt ]; then
|
||||
INSTALLED_VERSION=$($VENV_BIN/letsencrypt --version 2>&1 | cut -d " " -f 2)
|
||||
else
|
||||
virtualenv --no-site-packages --python $LE_PYTHON $VENV_PATH > /dev/null
|
||||
INSTALLED_VERSION="0.0.0"
|
||||
fi
|
||||
if [ "{{ LE_AUTO_VERSION }}" = $INSTALLED_VERSION ]; then
|
||||
echo "Reusing old virtual environment."
|
||||
else
|
||||
echo "Creating virtual environment..."
|
||||
rm -rf "$VENV_PATH"
|
||||
DeterminePythonVersion
|
||||
if [ "$VERBOSE" = 1 ]; then
|
||||
virtualenv --no-site-packages --python $LE_PYTHON $VENV_PATH
|
||||
else
|
||||
virtualenv --no-site-packages --python $LE_PYTHON $VENV_PATH > /dev/null
|
||||
fi
|
||||
|
||||
# Install Python dependencies with peep, then run letsencrypt.
|
||||
echo "Installing Python package dependencies..."
|
||||
TEMP_DIR=`mktemp -d 2>/dev/null || mktemp -d -t 'le'` # Linux || OS X
|
||||
# ---------------------------------------------------------------------------
|
||||
cat << "UNLIKELY_EOF" > $TEMP_DIR/letsencrypt-auto-requirements.txt
|
||||
# Install Python dependencies with peep, then run letsencrypt.
|
||||
echo "Installing Python package dependencies..."
|
||||
TEMP_DIR=`mktemp -d 2>/dev/null || mktemp -d -t 'le'` # Linux || OS X
|
||||
# ---------------------------------------------------------------------------
|
||||
cat << "UNLIKELY_EOF" > $TEMP_DIR/letsencrypt-auto-requirements.txt
|
||||
{{ letsencrypt-auto-requirements.txt }}
|
||||
UNLIKELY_EOF
|
||||
# ---------------------------------------------------------------------------
|
||||
cat << "UNLIKELY_EOF" > $TEMP_DIR/peep.py
|
||||
# ---------------------------------------------------------------------------
|
||||
cat << "UNLIKELY_EOF" > $TEMP_DIR/peep.py
|
||||
{{ peep.py }}
|
||||
UNLIKELY_EOF
|
||||
# ---------------------------------------------------------------------------
|
||||
set +e
|
||||
PEEP_OUT=`$VENV_BIN/python $TEMP_DIR/peep.py install -r $TEMP_DIR/letsencrypt-auto-requirements.txt`
|
||||
PEEP_STATUS=$?
|
||||
set -e
|
||||
rm -rf $TEMP_DIR
|
||||
if [ "$PEEP_STATUS" = 0 ]; then
|
||||
echo "Running letsencrypt..."
|
||||
echo " " $SUDO $VENV_BIN/letsencrypt "$@"
|
||||
$SUDO $VENV_BIN/letsencrypt "$@"
|
||||
else
|
||||
# Report error:
|
||||
echo $PEEP_OUT
|
||||
exit 1
|
||||
# ---------------------------------------------------------------------------
|
||||
set +e
|
||||
PEEP_OUT=`$VENV_BIN/python $TEMP_DIR/peep.py install -r $TEMP_DIR/letsencrypt-auto-requirements.txt`
|
||||
PEEP_STATUS=$?
|
||||
set -e
|
||||
rm -rf $TEMP_DIR
|
||||
if [ "$PEEP_STATUS" != 0 ]; then
|
||||
# Report error:
|
||||
echo $PEEP_OUT
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo "Running letsencrypt..."
|
||||
echo " " $SUDO $VENV_BIN/letsencrypt "$@"
|
||||
$SUDO $VENV_BIN/letsencrypt "$@"
|
||||
else
|
||||
# Phase 1: Upgrade letsencrypt-auto if neceesary, then self-invoke.
|
||||
|
||||
|
|
@ -215,9 +221,7 @@ else
|
|||
# dependencies (curl, etc.), for better flow control, and for the option of
|
||||
# future Windows compatibility.
|
||||
#
|
||||
# This Python script prints a path to a temp dir containing a new copy of
|
||||
# letsencrypt-auto or returns non-zero. There is no $ interpolation due to
|
||||
# quotes on heredoc delimiters.
|
||||
# There is no $ interpolation due to quotes on heredoc delimiters.
|
||||
set +e
|
||||
# -------------------------------------------------------------------------
|
||||
TEMP_DIR=`$LE_PYTHON - << "UNLIKELY_EOF"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
"""Print a path to a temp dir containing a new copy of letsencrypt-auto.
|
||||
|
||||
On failure, return non-zero.
|
||||
|
||||
"""
|
||||
from distutils.version import LooseVersion
|
||||
from json import loads
|
||||
from os import devnull
|
||||
|
|
@ -67,7 +72,7 @@ class TempDir(object):
|
|||
def latest_stable_version(get, package):
|
||||
"""Apply a fairly safe heuristic to determine the latest stable release of
|
||||
a PyPI package."""
|
||||
metadata = loads(get('https://pypi.python.org/pypi/%s/json' % package))
|
||||
metadata = loads(get('https://pypi.python.org/pypi/letsencrypt/json'))
|
||||
# metadata['info']['version'] actually returns the latest of any kind of
|
||||
# release release, contrary to https://wiki.python.org/moin/PyPIJSON.
|
||||
return str(max(LooseVersion(r) for r
|
||||
|
|
@ -108,7 +113,7 @@ def main():
|
|||
get = HttpsGetter().get
|
||||
temp = TempDir()
|
||||
try:
|
||||
stable_tag = 'v' + latest_stable_version(get, 'letsencrypt')
|
||||
stable_tag = 'v' + latest_stable_version(get)
|
||||
print dirname(verified_new_le_auto(get, stable_tag, temp))
|
||||
except ExpectedError as exc:
|
||||
print exc.args[0], exc.args[1]
|
||||
|
|
|
|||
Loading…
Reference in a new issue