fix install v2.15.X
This commit is contained in:
+160
-140
@@ -593,13 +593,23 @@ def github_latest_release_tag(repo: str, override: str = None) -> str:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _sanitize_angie_log_config(text: str) -> str:
|
||||||
|
"""Make log formats valid in global http/stream context.
|
||||||
|
|
||||||
|
`$server` is only defined inside generated proxy_host server blocks. When it
|
||||||
|
appears in a global log_format, `angie -t` fails with: unknown "server"
|
||||||
|
variable. Use built-in `$upstream_addr` instead.
|
||||||
|
"""
|
||||||
|
return text.replace("$server", "$upstream_addr")
|
||||||
|
|
||||||
|
|
||||||
def ensure_angie_log_include_files():
|
def ensure_angie_log_include_files():
|
||||||
"""Ensure split log include files required by ANGIE_CONF_TEMPLATE exist.
|
"""Ensure split log include files required by ANGIE_CONF_TEMPLATE exist.
|
||||||
|
|
||||||
Older installs may only have /etc/angie/conf.d/include/log.conf from the
|
Older installs may only have /etc/angie/conf.d/include/log.conf from the
|
||||||
upstream NPM rootfs. The Angie template used by this installer includes
|
upstream NPM rootfs. The Angie template used by this installer includes
|
||||||
log-proxy.conf in http{} and log-stream.conf in stream{}, so update mode
|
log-proxy.conf in http{} and log-stream.conf in stream{}, so fresh/update
|
||||||
must create them before running `angie -t`.
|
mode must create them before running `angie -t`.
|
||||||
"""
|
"""
|
||||||
include_dir = Path("/etc/angie/conf.d/include")
|
include_dir = Path("/etc/angie/conf.d/include")
|
||||||
include_dir.mkdir(parents=True, exist_ok=True)
|
include_dir.mkdir(parents=True, exist_ok=True)
|
||||||
@@ -608,7 +618,7 @@ def ensure_angie_log_include_files():
|
|||||||
log_proxy = include_dir / "log-proxy.conf"
|
log_proxy = include_dir / "log-proxy.conf"
|
||||||
log_stream = include_dir / "log-stream.conf"
|
log_stream = include_dir / "log-stream.conf"
|
||||||
|
|
||||||
default_proxy = """log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_user_agent" "$http_referer"';
|
default_proxy = """log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $upstream_addr] "$http_user_agent" "$http_referer"';
|
||||||
log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"';
|
log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"';
|
||||||
|
|
||||||
access_log /data/logs/fallback_access.log proxy;
|
access_log /data/logs/fallback_access.log proxy;
|
||||||
@@ -620,14 +630,22 @@ access_log /data/logs/fallback_stream_access.log stream;
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
if log_conf.exists():
|
||||||
|
proxy_text = _sanitize_angie_log_config(log_conf.read_text(encoding="utf-8"))
|
||||||
|
if not proxy_text.strip():
|
||||||
|
proxy_text = default_proxy
|
||||||
|
else:
|
||||||
|
proxy_text = default_proxy
|
||||||
|
|
||||||
if not log_proxy.exists():
|
if not log_proxy.exists():
|
||||||
if log_conf.exists():
|
write_file(log_proxy, proxy_text, 0o644)
|
||||||
txt = log_conf.read_text(encoding="utf-8")
|
|
||||||
# Upstream log.conf is the HTTP/proxy log include in older installs.
|
|
||||||
write_file(log_proxy, txt if txt.strip() else default_proxy, 0o644)
|
|
||||||
else:
|
|
||||||
write_file(log_proxy, default_proxy, 0o644)
|
|
||||||
print(f" ✓ Created missing {log_proxy.name}")
|
print(f" ✓ Created missing {log_proxy.name}")
|
||||||
|
else:
|
||||||
|
current = log_proxy.read_text(encoding="utf-8")
|
||||||
|
sanitized = _sanitize_angie_log_config(current)
|
||||||
|
if sanitized != current:
|
||||||
|
write_file(log_proxy, sanitized, 0o644)
|
||||||
|
print(f" ✓ Fixed invalid $server variable in {log_proxy.name}")
|
||||||
|
|
||||||
if not log_stream.exists():
|
if not log_stream.exists():
|
||||||
write_file(log_stream, default_stream, 0o644)
|
write_file(log_stream, default_stream, 0o644)
|
||||||
@@ -635,8 +653,14 @@ access_log /data/logs/fallback_stream_access.log stream;
|
|||||||
|
|
||||||
# Keep legacy log.conf present for compatibility with older/custom configs.
|
# Keep legacy log.conf present for compatibility with older/custom configs.
|
||||||
if not log_conf.exists():
|
if not log_conf.exists():
|
||||||
write_file(log_conf, default_proxy, 0o644)
|
write_file(log_conf, proxy_text, 0o644)
|
||||||
print(f" ✓ Created missing {log_conf.name}")
|
print(f" ✓ Created missing {log_conf.name}")
|
||||||
|
else:
|
||||||
|
current = log_conf.read_text(encoding="utf-8")
|
||||||
|
sanitized = _sanitize_angie_log_config(current)
|
||||||
|
if sanitized != current:
|
||||||
|
write_file(log_conf, sanitized, 0o644)
|
||||||
|
print(f" ✓ Fixed invalid $server variable in {log_conf.name}")
|
||||||
|
|
||||||
run(["chown", "root:root", str(log_proxy), str(log_stream), str(log_conf)], check=False)
|
run(["chown", "root:root", str(log_proxy), str(log_stream), str(log_conf)], check=False)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -1050,6 +1074,92 @@ def _detect_certbot_version(certbot_path: Path) -> str:
|
|||||||
return m.group(1)
|
return m.group(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def run_logged(cmd, log_path: Path, timeout=1200, check=True, env=None):
|
||||||
|
"""Run command with stdout/stderr saved to a log file.
|
||||||
|
|
||||||
|
Normal installer output stays concise, but failed builds/installations leave
|
||||||
|
actionable diagnostics instead of hiding stderr in /dev/null.
|
||||||
|
"""
|
||||||
|
log_path = Path(log_path)
|
||||||
|
log_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
with log_path.open("a", encoding="utf-8", errors="replace") as log:
|
||||||
|
log.write("\n\n$ " + " ".join(map(str, cmd)) + "\n")
|
||||||
|
log.flush()
|
||||||
|
result = subprocess.run(
|
||||||
|
cmd,
|
||||||
|
timeout=timeout,
|
||||||
|
check=False,
|
||||||
|
env=env,
|
||||||
|
stdout=log,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
text=True,
|
||||||
|
)
|
||||||
|
if check and result.returncode != 0:
|
||||||
|
print(f" ✖ Command failed, log: {log_path}")
|
||||||
|
try:
|
||||||
|
lines = log_path.read_text(encoding="utf-8", errors="replace").splitlines()
|
||||||
|
tail = lines[-40:]
|
||||||
|
if tail:
|
||||||
|
print(" --- log tail ---")
|
||||||
|
for line in tail:
|
||||||
|
print(" " + line[:220])
|
||||||
|
print(" --- end log tail ---")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
raise subprocess.CalledProcessError(result.returncode, cmd)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _python_version(exe: str) -> tuple[int, int] | None:
|
||||||
|
try:
|
||||||
|
out = run_out([exe, "--version"], check=False).strip()
|
||||||
|
m = re.search(r"Python\s+(\d+)\.(\d+)", out)
|
||||||
|
if m:
|
||||||
|
return (int(m.group(1)), int(m.group(2)))
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _find_certbot_system_python() -> tuple[str | None, str | None]:
|
||||||
|
"""Prefer python3.11 when installed; otherwise use distro python >= 3.11.
|
||||||
|
|
||||||
|
Debian 13 ships a newer Python (for example 3.13). That is suitable for the
|
||||||
|
certbot venv and avoids compiling Python 3.11 through pyenv on fresh/update.
|
||||||
|
"""
|
||||||
|
candidates = ["python3.11", "python3", "python3.13", "python3.12"]
|
||||||
|
seen = set()
|
||||||
|
for exe in candidates:
|
||||||
|
if exe in seen or not shutil.which(exe):
|
||||||
|
continue
|
||||||
|
seen.add(exe)
|
||||||
|
ver = _python_version(exe)
|
||||||
|
if ver and ver[0] == 3 and ver[1] >= 11:
|
||||||
|
out = run_out([exe, "--version"], check=False).strip()
|
||||||
|
return exe, out
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
|
||||||
|
def _create_certbot_venv_with_python(python_exe: str, python_label: str, venv_dir: Path):
|
||||||
|
with step(f"Using {python_label} for certbot venv"):
|
||||||
|
venv_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
run([python_exe, "-m", "venv", str(venv_dir)])
|
||||||
|
|
||||||
|
venv_bin = venv_dir / "bin"
|
||||||
|
pip_path = venv_bin / "pip"
|
||||||
|
certbot_path = venv_bin / "certbot"
|
||||||
|
env_build = os.environ.copy()
|
||||||
|
env_build["SETUPTOOLS_USE_DISTUTILS"] = "local"
|
||||||
|
|
||||||
|
_install_certbot_stack(pip_path, certbot_path, env_build)
|
||||||
|
|
||||||
|
cb_ver = run_out([str(certbot_path), "--version"], check=False) or ""
|
||||||
|
pip_ver = run_out([str(pip_path), "--version"], check=False) or ""
|
||||||
|
print(f" Python: {python_label}")
|
||||||
|
print(f" Certbot: {cb_ver.strip()}")
|
||||||
|
print(f" Pip: {pip_ver.strip().split(' from ')[0]}")
|
||||||
|
|
||||||
def _install_certbot_stack(pip_path: Path, certbot_path: Path, env_build: dict):
|
def _install_certbot_stack(pip_path: Path, certbot_path: Path, env_build: dict):
|
||||||
"""Install Certbot and DNS plugins in one venv with matching versions.
|
"""Install Certbot and DNS plugins in one venv with matching versions.
|
||||||
|
|
||||||
@@ -1057,11 +1167,13 @@ def _install_certbot_stack(pip_path: Path, certbot_path: Path, env_build: dict):
|
|||||||
installs this can fail with 'acme==undefined'. We prevent that by making
|
installs this can fail with 'acme==undefined'. We prevent that by making
|
||||||
the venv complete before npm.service starts.
|
the venv complete before npm.service starts.
|
||||||
"""
|
"""
|
||||||
run(
|
log_path = Path("/tmp/npm-certbot-venv.log")
|
||||||
|
run_logged(
|
||||||
[str(pip_path), "install", "-U", "pip", "setuptools", "wheel"],
|
[str(pip_path), "install", "-U", "pip", "setuptools", "wheel"],
|
||||||
|
log_path,
|
||||||
env=env_build,
|
env=env_build,
|
||||||
)
|
)
|
||||||
run(
|
run_logged(
|
||||||
[
|
[
|
||||||
str(pip_path),
|
str(pip_path),
|
||||||
"install",
|
"install",
|
||||||
@@ -1071,11 +1183,12 @@ def _install_certbot_stack(pip_path: Path, certbot_path: Path, env_build: dict):
|
|||||||
"certbot",
|
"certbot",
|
||||||
"tldextract",
|
"tldextract",
|
||||||
],
|
],
|
||||||
|
log_path,
|
||||||
env=env_build,
|
env=env_build,
|
||||||
)
|
)
|
||||||
|
|
||||||
certbot_ver = _detect_certbot_version(certbot_path)
|
certbot_ver = _detect_certbot_version(certbot_path)
|
||||||
run(
|
run_logged(
|
||||||
[
|
[
|
||||||
str(pip_path),
|
str(pip_path),
|
||||||
"install",
|
"install",
|
||||||
@@ -1084,6 +1197,7 @@ def _install_certbot_stack(pip_path: Path, certbot_path: Path, env_build: dict):
|
|||||||
f"certbot-dns-cloudflare=={certbot_ver}",
|
f"certbot-dns-cloudflare=={certbot_ver}",
|
||||||
f"certbot-dns-rfc2136=={certbot_ver}",
|
f"certbot-dns-rfc2136=={certbot_ver}",
|
||||||
],
|
],
|
||||||
|
log_path,
|
||||||
env=env_build,
|
env=env_build,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1207,53 +1321,22 @@ def ensure_certbot_venv_ready(venv_dir: Path = Path("/opt/certbot"), force_rebui
|
|||||||
def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")):
|
def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")):
|
||||||
info = os_release()
|
info = os_release()
|
||||||
distro_id = (info.get("ID") or "").lower()
|
distro_id = (info.get("ID") or "").lower()
|
||||||
|
version_id = (info.get("VERSION_ID") or "").strip()
|
||||||
|
|
||||||
# ============================================================
|
# Prefer system Python 3.11 if present. On Debian 13, use distro Python
|
||||||
# STEP 1: Check if Python 3.11 is already available
|
# (for example Python 3.13) instead of compiling Python 3.11 via pyenv.
|
||||||
# ============================================================
|
if distro_id == "debian" and version_id.startswith("13"):
|
||||||
python311_available = False
|
apt_try_install(["python3", "python3-venv", "python3-pip", "python3-dev"])
|
||||||
if shutil.which("python3.11"):
|
else:
|
||||||
try:
|
apt_try_install(["python3.11-venv", "python3-venv", "python3-pip"])
|
||||||
ver_output = run_out(["python3.11", "--version"], check=False).strip()
|
|
||||||
match = re.search(r"Python (\d+)\.(\d+)", ver_output)
|
|
||||||
if match:
|
|
||||||
major, minor = int(match.group(1)), int(match.group(2))
|
|
||||||
if major == 3 and minor == 11:
|
|
||||||
python311_available = True
|
|
||||||
if DEBUG:
|
|
||||||
print(f"✔ Found system Python 3.11: {ver_output}")
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# ============================================================
|
python_exe, python_label = _find_certbot_system_python()
|
||||||
# STEP 2: Use system Python 3.11 if available
|
if python_exe:
|
||||||
# ============================================================
|
_create_certbot_venv_with_python(python_exe, python_label, venv_dir)
|
||||||
if python311_available:
|
|
||||||
with step(f"Using system Python 3.11 for certbot venv"):
|
|
||||||
# Ensure python3.11-venv is installed
|
|
||||||
apt_try_install(["python3.11-venv", "python3-pip"])
|
|
||||||
|
|
||||||
venv_dir.mkdir(parents=True, exist_ok=True)
|
|
||||||
run(["python3.11", "-m", "venv", str(venv_dir)])
|
|
||||||
|
|
||||||
venv_bin = venv_dir / "bin"
|
|
||||||
pip_path = venv_bin / "pip"
|
|
||||||
certbot_path = venv_bin / "certbot"
|
|
||||||
env_build = os.environ.copy()
|
|
||||||
env_build["SETUPTOOLS_USE_DISTUTILS"] = "local"
|
|
||||||
|
|
||||||
_install_certbot_stack(pip_path, certbot_path, env_build)
|
|
||||||
|
|
||||||
cb_ver = run_out([str(certbot_path), "--version"], check=False) or ""
|
|
||||||
pip_ver = run_out([str(pip_path), "--version"], check=False) or ""
|
|
||||||
print(f" Python: {ver_output}")
|
|
||||||
print(f" Certbot: {cb_ver.strip()}")
|
|
||||||
print(f" Pip: {pip_ver.strip().split(' from ')[0]}")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# ============================================================
|
# Ubuntu fallback: install Python 3.11 from deadsnakes when no suitable
|
||||||
# STEP 3: Ubuntu - install Python 3.11 from deadsnakes PPA
|
# system Python is available.
|
||||||
# ============================================================
|
|
||||||
if distro_id == "ubuntu":
|
if distro_id == "ubuntu":
|
||||||
with step(
|
with step(
|
||||||
f"Ubuntu detected: {info.get('PRETTY','Ubuntu')}. Install Python 3.11 via deadsnakes"
|
f"Ubuntu detected: {info.get('PRETTY','Ubuntu')}. Install Python 3.11 via deadsnakes"
|
||||||
@@ -1262,42 +1345,22 @@ def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")):
|
|||||||
run(["apt-get", "update", "-y"], check=False)
|
run(["apt-get", "update", "-y"], check=False)
|
||||||
apt_try_install(["software-properties-common"])
|
apt_try_install(["software-properties-common"])
|
||||||
except Exception:
|
except Exception:
|
||||||
run(
|
run(["apt-get", "install", "-y", "software-properties-common"], check=False)
|
||||||
["apt-get", "install", "-y", "software-properties-common"],
|
|
||||||
check=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
run(["add-apt-repository", "-y", "ppa:deadsnakes/ppa"])
|
run(["add-apt-repository", "-y", "ppa:deadsnakes/ppa"])
|
||||||
run(["apt-get", "update", "-y"], check=False)
|
run(["apt-get", "update", "-y"], check=False)
|
||||||
run(["apt-get", "install", "-y", "python3.11", "python3.11-venv"])
|
run(["apt-get", "install", "-y", "python3.11", "python3.11-venv"])
|
||||||
|
|
||||||
with step(f"Create venv at {venv_dir} using python3.11"):
|
_create_certbot_venv_with_python("python3.11", "Python 3.11 (deadsnakes)", venv_dir)
|
||||||
venv_dir.mkdir(parents=True, exist_ok=True)
|
|
||||||
run(["python3.11", "-m", "venv", str(venv_dir)])
|
|
||||||
|
|
||||||
venv_bin = venv_dir / "bin"
|
|
||||||
pip_path = venv_bin / "pip"
|
|
||||||
certbot_path = venv_bin / "certbot"
|
|
||||||
env_build = os.environ.copy()
|
|
||||||
env_build["SETUPTOOLS_USE_DISTUTILS"] = "local"
|
|
||||||
|
|
||||||
_install_certbot_stack(pip_path, certbot_path, env_build)
|
|
||||||
|
|
||||||
cb_ver = run_out([str(certbot_path), "--version"], check=False) or ""
|
|
||||||
pip_ver = run_out([str(pip_path), "--version"], check=False) or ""
|
|
||||||
print(f" Python: Python 3.11 (deadsnakes)")
|
|
||||||
print(f" Certbot: {cb_ver.strip()}")
|
|
||||||
print(f" Pip: {pip_ver.strip().split(' from ')[0]}")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# ============================================================
|
# Last resort only: pyenv. Debian 13 should not normally reach this path,
|
||||||
# STEP 4: Debian - install Python 3.11 via pyenv
|
# because it has a suitable distro Python.
|
||||||
# ============================================================
|
|
||||||
PYENV_ROOT = Path("/opt/npm/.pyenv")
|
PYENV_ROOT = Path("/opt/npm/.pyenv")
|
||||||
PYENV_OWNER = "npm"
|
PYENV_OWNER = "npm"
|
||||||
PYTHON_VERSION = "3.11.14"
|
PYTHON_VERSION = "3.11.14"
|
||||||
|
pyenv_log = Path("/tmp/npm-pyenv-python-build.log")
|
||||||
|
|
||||||
# Build dependencies dla pyenv
|
|
||||||
with step("Installing pyenv build dependencies"):
|
with step("Installing pyenv build dependencies"):
|
||||||
apt_install(
|
apt_install(
|
||||||
[
|
[
|
||||||
@@ -1316,9 +1379,9 @@ def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")):
|
|||||||
"libffi-dev",
|
"libffi-dev",
|
||||||
"uuid-dev",
|
"uuid-dev",
|
||||||
"liblzma-dev",
|
"liblzma-dev",
|
||||||
# "ca-certificates",
|
"curl",
|
||||||
# "curl",
|
"git",
|
||||||
# "git",
|
"ca-certificates",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1328,59 +1391,34 @@ def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")):
|
|||||||
|
|
||||||
with step(f"Ensuring pyenv is available at {PYENV_ROOT}"):
|
with step(f"Ensuring pyenv is available at {PYENV_ROOT}"):
|
||||||
pyenv_bin_path = PYENV_ROOT / "bin" / "pyenv"
|
pyenv_bin_path = PYENV_ROOT / "bin" / "pyenv"
|
||||||
|
|
||||||
if not pyenv_bin_path.exists():
|
if not pyenv_bin_path.exists():
|
||||||
run(
|
run_logged(
|
||||||
[
|
[
|
||||||
"sudo",
|
"sudo",
|
||||||
"-u",
|
"-u",
|
||||||
PYENV_OWNER,
|
PYENV_OWNER,
|
||||||
"bash",
|
"bash",
|
||||||
"-lc",
|
"-lc",
|
||||||
'if [ ! -x "/opt/npm/.pyenv/bin/pyenv" ]; then '
|
'if [ ! -x "/opt/npm/.pyenv/bin/pyenv" ]; then git clone --depth=1 https://github.com/pyenv/pyenv.git /opt/npm/.pyenv; fi',
|
||||||
" command -v git >/dev/null 2>&1 || sudo apt-get install -y git; "
|
],
|
||||||
" git clone --depth=1 https://github.com/pyenv/pyenv.git /opt/npm/.pyenv; "
|
pyenv_log,
|
||||||
"fi",
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
PYENV_BIN_CANDIDATES = [
|
pyenv_bin = PYENV_ROOT / "bin" / "pyenv"
|
||||||
str(PYENV_ROOT / "bin" / "pyenv"),
|
if not pyenv_bin.exists():
|
||||||
"pyenv",
|
|
||||||
"/usr/bin/pyenv",
|
|
||||||
"/usr/lib/pyenv/bin/pyenv",
|
|
||||||
]
|
|
||||||
|
|
||||||
pyenv_bin = next(
|
|
||||||
(c for c in PYENV_BIN_CANDIDATES if shutil.which(c) or Path(c).exists()), None
|
|
||||||
)
|
|
||||||
if not pyenv_bin:
|
|
||||||
raise RuntimeError("No 'pyenv' found even after git clone attempt.")
|
raise RuntimeError("No 'pyenv' found even after git clone attempt.")
|
||||||
|
|
||||||
with step(f"Installing Python {PYTHON_VERSION} via pyenv into {PYENV_ROOT}"):
|
with step(f"Installing Python {PYTHON_VERSION} via pyenv into {PYENV_ROOT}"):
|
||||||
run(["mkdir", "-p", str(PYENV_ROOT)])
|
run(["mkdir", "-p", str(PYENV_ROOT)])
|
||||||
run(["chown", "-R", f"{PYENV_OWNER}:{PYENV_OWNER}", "/opt/npm"], check=False)
|
run(["chown", "-R", f"{PYENV_OWNER}:{PYENV_OWNER}", "/opt/npm"], check=False)
|
||||||
run(
|
|
||||||
[
|
|
||||||
"sudo",
|
|
||||||
"-u",
|
|
||||||
PYENV_OWNER,
|
|
||||||
"bash",
|
|
||||||
"-lc",
|
|
||||||
'if [ ! -x "/opt/npm/.pyenv/bin/pyenv" ]; then '
|
|
||||||
" command -v git >/dev/null 2>&1 || sudo apt-get install -y git; "
|
|
||||||
" git clone --depth=1 https://github.com/pyenv/pyenv.git /opt/npm/.pyenv; "
|
|
||||||
"fi",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
install_cmd = (
|
install_cmd = (
|
||||||
"export HOME=/opt/npm; "
|
"export HOME=/opt/npm; "
|
||||||
"export PYENV_ROOT=/opt/npm/.pyenv; "
|
"export PYENV_ROOT=/opt/npm/.pyenv; "
|
||||||
'export PATH="$PYENV_ROOT/bin:/usr/bin:/bin"; '
|
'export PATH="$PYENV_ROOT/bin:/usr/bin:/bin"; '
|
||||||
'mkdir -p "$PYENV_ROOT"; cd "$HOME"; '
|
'mkdir -p "$PYENV_ROOT"; cd "$HOME"; '
|
||||||
f"pyenv install -s {PYTHON_VERSION}"
|
f"pyenv install -v -s {PYTHON_VERSION}"
|
||||||
)
|
)
|
||||||
run(
|
run_logged(
|
||||||
[
|
[
|
||||||
"sudo",
|
"sudo",
|
||||||
"-u",
|
"-u",
|
||||||
@@ -1393,7 +1431,9 @@ def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")):
|
|||||||
"bash",
|
"bash",
|
||||||
"-lc",
|
"-lc",
|
||||||
install_cmd,
|
install_cmd,
|
||||||
]
|
],
|
||||||
|
pyenv_log,
|
||||||
|
timeout=3600,
|
||||||
)
|
)
|
||||||
|
|
||||||
profile_snippet = f"""# Auto-generated by npm-angie-auto-install
|
profile_snippet = f"""# Auto-generated by npm-angie-auto-install
|
||||||
@@ -1421,29 +1461,9 @@ fi
|
|||||||
if not python311.exists():
|
if not python311.exists():
|
||||||
raise RuntimeError(f"No python {PYTHON_VERSION} in {PYENV_ROOT}/versions/.")
|
raise RuntimeError(f"No python {PYTHON_VERSION} in {PYENV_ROOT}/versions/.")
|
||||||
|
|
||||||
venv_bin = venv_dir / "bin"
|
_create_certbot_venv_with_python(str(python311), f"Python {PYTHON_VERSION} (pyenv)", venv_dir)
|
||||||
pip_path = venv_bin / "pip"
|
|
||||||
certbot_path = venv_bin / "certbot"
|
|
||||||
|
|
||||||
with step(f"Preparing Certbot venv at {venv_dir} (Python {PYTHON_VERSION})"):
|
|
||||||
venv_dir.mkdir(parents=True, exist_ok=True)
|
|
||||||
if not venv_dir.exists() or not pip_path.exists():
|
|
||||||
run([str(python311), "-m", "venv", str(venv_dir)])
|
|
||||||
|
|
||||||
env_build = os.environ.copy()
|
|
||||||
env_build["SETUPTOOLS_USE_DISTUTILS"] = "local"
|
|
||||||
|
|
||||||
_install_certbot_stack(pip_path, certbot_path, env_build)
|
|
||||||
|
|
||||||
cb_ver = run_out([str(certbot_path), "--version"], check=False) or ""
|
|
||||||
pip_ver = run_out([str(pip_path), "--version"], check=False) or ""
|
|
||||||
print(f" Python: {PYTHON_VERSION} (pyenv)")
|
|
||||||
print(f" Certbot: {cb_ver.strip()}")
|
|
||||||
print(f" Pip: {pip_ver.strip().split(' from ')[0]}")
|
|
||||||
|
|
||||||
run(["chown", "-R", f"{PYENV_OWNER}:{PYENV_OWNER}", str(PYENV_ROOT)], check=False)
|
run(["chown", "-R", f"{PYENV_OWNER}:{PYENV_OWNER}", str(PYENV_ROOT)], check=False)
|
||||||
|
|
||||||
|
|
||||||
def configure_letsencrypt():
|
def configure_letsencrypt():
|
||||||
with step("configure letsencrypt"):
|
with step("configure letsencrypt"):
|
||||||
run(["chown", "-R", "npm:npm", "/opt/certbot"], check=False)
|
run(["chown", "-R", "npm:npm", "/opt/certbot"], check=False)
|
||||||
@@ -3181,7 +3201,7 @@ def update_config_file(
|
|||||||
|
|
||||||
if owner:
|
if owner:
|
||||||
try:
|
try:
|
||||||
run("chown", owner, str(filepath), check=False)
|
run(["chown", owner, str(filepath)], check=False)
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
print(f" Owner set to: {owner}")
|
print(f" Owner set to: {owner}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user