ubuntu deadsneaks

This commit is contained in:
Mateusz Gruszczyński
2025-10-24 20:52:06 +02:00
parent 32b866c4c4
commit bf96a22963

View File

@@ -211,10 +211,72 @@ def sync_backup_nginx_conf():
print(f"Warning: sync failed for {p} -> {target}: {e}") 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")): 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_ROOT = Path("/opt/npm/.pyenv")
PYENV_OWNER = "npm" 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"] PYENV_BIN_CANDIDATES = ["pyenv", "/usr/bin/pyenv", "/usr/lib/pyenv/bin/pyenv"]
try: try:
@@ -241,16 +303,9 @@ def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")):
if not pyenv_bin: if not pyenv_bin:
raise RuntimeError("No 'pyenv' (try /usr/bin/pyenv or /usr/lib/pyenv/bin/pyenv).") 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}"): 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([ run([
"sudo", "-u", PYENV_OWNER, "bash", "-lc", "sudo", "-u", PYENV_OWNER, "bash", "-lc",
'if [ ! -x "/opt/npm/.pyenv/bin/pyenv" ]; then ' '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; ' ' git clone --depth=1 https://github.com/pyenv/pyenv.git /opt/npm/.pyenv; '
"fi" "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; '
@@ -274,7 +328,6 @@ def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")):
"bash", "-lc", install_cmd "bash", "-lc", install_cmd
]) ])
profile_snippet = f"""# Auto-generated by setup_certbot_venv profile_snippet = f"""# Auto-generated by setup_certbot_venv
# pyenv for '{PYENV_OWNER}' # pyenv for '{PYENV_OWNER}'
if [ -d "{PYENV_ROOT}" ]; then if [ -d "{PYENV_ROOT}" ]; then
@@ -311,26 +364,20 @@ fi
env_build = os.environ.copy() env_build = os.environ.copy()
env_build["SETUPTOOLS_USE_DISTUTILS"] = "local" env_build["SETUPTOOLS_USE_DISTUTILS"] = "local"
run([str(pip_path), "install", "-U", "pip", "setuptools", "wheel"], env=env_build) run([str(pip_path), "install", "-U", "pip", "setuptools", "wheel"], env=env_build)
run([str(pip_path), "install", "-U", run([str(pip_path), "install", "-U", "cryptography", "cffi", "certbot", "tldextract"], env=env_build)
"cryptography", "cffi", "certbot", "tldextract"], env=env_build)
Path("/usr/local/bin").mkdir(parents=True, exist_ok=True) Path("/usr/local/bin").mkdir(parents=True, exist_ok=True)
target = Path("/usr/local/bin/certbot") target = Path("/usr/local/bin/certbot")
if target.exists() or target.is_symlink(): if target.exists() or target.is_symlink():
try: try: target.unlink()
target.unlink() except Exception: pass
except Exception:
pass
target.symlink_to(certbot_path) target.symlink_to(certbot_path)
cb_ver = run_out([str(certbot_path), "--version"], check=False) or "" cb_ver = run_out([str(certbot_path), "--version"], check=False) or ""
pip_ver = run_out([str(pip_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()}") 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(): def configure_letsencrypt():
with step("configure letsencrypt"): with step("configure letsencrypt"):