From bf96a22963d699186e8a7b33291fbc8b2077ecfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Fri, 24 Oct 2025 20:52:06 +0200 Subject: [PATCH] ubuntu deadsneaks --- npm_install.py | 85 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/npm_install.py b/npm_install.py index 0fb65a2..5941ca6 100644 --- a/npm_install.py +++ b/npm_install.py @@ -211,10 +211,72 @@ def sync_backup_nginx_conf(): print(f"Warning: sync failed for {p} -> {target}: {e}") +def _is_ubuntu() -> bool: + info = os_release() + id_ = (info.get("ID") or "").lower() + if id_ == "ubuntu": + return True + pretty = (info.get("PRETTY") or "").lower() + if "ubuntu" in pretty: + return True + codename = (info.get("CODENAME") or "").lower() + if codename in {"bionic","focal","jammy","kinetic","lunar","mantic","noble","oracular"}: + return True + # /etc/lsb-release fallback + try: + txt = Path("/etc/lsb-release").read_text().lower() + if "distrib_id=ubuntu" in txt: + return True + except Exception: + pass + return False + def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")): + info = os_release() + print(f"[setup_certbot_venv] DETECTED: {info}") + + # --- UBUNTU: PPA deadsnakes + venv --- + if _is_ubuntu(): + with step(f"Ubuntu: install Python 3.11 via deadsnakes ( {info.get('PRETTY','')} )"): + run(["apt-get", "update", "-y"], check=False) + # software-properties-common + PPA + try: + apt_try_install(["software-properties-common"]) + except Exception: + run(["apt-get", "install", "-y", "software-properties-common"], check=False) + run(["add-apt-repository", "-y", "ppa:deadsnakes/ppa"]) + run(["apt-get", "update", "-y"], check=False) + run(["apt-get", "install", "-y", "python3.11", "python3.11-venv"]) + + with step(f"Create venv at {venv_dir} using python3.11"): + venv_dir.mkdir(parents=True, exist_ok=True) + run(["python3.11", "-m", "venv", str(venv_dir)]) + + # wspólny post-setup + 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" + + run([str(pip_path), "install", "-U", "pip", "setuptools", "wheel"], env=env_build) + run([str(pip_path), "install", "-U", "cryptography", "cffi", "certbot", "tldextract"], env=env_build) + + Path("/usr/local/bin").mkdir(parents=True, exist_ok=True) + target = Path("/usr/local/bin/certbot") + if target.exists() or target.is_symlink(): + try: target.unlink() + except Exception: pass + target.symlink_to(certbot_path) + + cb_ver = run_out([str(certbot_path), "--version"], check=False) or "" + pip_ver = run_out([str(pip_path), "--version"], check=False) or "" + print(f"Certbot: {cb_ver.strip()} | Pip: {pip_ver.strip()}") + return + PYENV_ROOT = Path("/opt/npm/.pyenv") PYENV_OWNER = "npm" - PYTHON_VERSION = "3.11.11" + PYTHON_VERSION = "3.11.X" PYENV_BIN_CANDIDATES = ["pyenv", "/usr/bin/pyenv", "/usr/lib/pyenv/bin/pyenv"] try: @@ -241,16 +303,9 @@ def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")): if not pyenv_bin: raise RuntimeError("No 'pyenv' (try /usr/bin/pyenv or /usr/lib/pyenv/bin/pyenv).") - env_pyenv = os.environ.copy() - env_pyenv.update({ - "HOME": "/opt/npm", - "PYENV_ROOT": str(PYENV_ROOT), - "PATH": "/usr/lib/pyenv/bin:/usr/bin:/bin" - }) with step(f"Installing Python {PYTHON_VERSION} via pyenv into {PYENV_ROOT}"): run(["mkdir", "-p", str(PYENV_ROOT)]) 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 ' @@ -258,7 +313,6 @@ def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")): ' git clone --depth=1 https://github.com/pyenv/pyenv.git /opt/npm/.pyenv; ' "fi" ]) - install_cmd = ( 'export HOME=/opt/npm; ' 'export PYENV_ROOT=/opt/npm/.pyenv; ' @@ -274,7 +328,6 @@ def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")): "bash", "-lc", install_cmd ]) - profile_snippet = f"""# Auto-generated by setup_certbot_venv # pyenv for '{PYENV_OWNER}' if [ -d "{PYENV_ROOT}" ]; then @@ -311,26 +364,20 @@ fi env_build = os.environ.copy() env_build["SETUPTOOLS_USE_DISTUTILS"] = "local" - run([str(pip_path), "install", "-U", "pip", "setuptools", "wheel"], env=env_build) - run([str(pip_path), "install", "-U", - "cryptography", "cffi", "certbot", "tldextract"], env=env_build) + run([str(pip_path), "install", "-U", "cryptography", "cffi", "certbot", "tldextract"], env=env_build) Path("/usr/local/bin").mkdir(parents=True, exist_ok=True) target = Path("/usr/local/bin/certbot") if target.exists() or target.is_symlink(): - try: - target.unlink() - except Exception: - pass + try: target.unlink() + except Exception: pass target.symlink_to(certbot_path) cb_ver = run_out([str(certbot_path), "--version"], check=False) or "" pip_ver = run_out([str(pip_path), "--version"], check=False) or "" print(f"Certbot: {cb_ver.strip()} | Pip: {pip_ver.strip()}") - run(["chown", "-R", f"{PYENV_OWNER}:{PYENV_OWNER}", str(PYENV_ROOT)], check=False) - def configure_letsencrypt(): with step("configure letsencrypt"):