pyenv ubuntu

This commit is contained in:
Mateusz Gruszczyński
2025-10-24 15:35:19 +02:00
parent dfc0864d60
commit 7b59b914a0

View File

@@ -212,40 +212,35 @@ def sync_backup_nginx_conf():
def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")): def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")):
# Parametry
PYENV_ROOT = Path("/opt/npm/.pyenv") PYENV_ROOT = Path("/opt/npm/.pyenv")
PYENV_OWNER = "npm" PYENV_OWNER = "npm"
PARENT_HOME = Path("/opt/npm")
PYTHON_VERSION = "3.11.11" PYTHON_VERSION = "3.11.11"
# Rozpoznanie dystrybucji
def _is_ubuntu() -> bool: def _is_ubuntu() -> bool:
try: try:
with open("/etc/os-release") as f: with open("/etc/os-release") as f:
data = f.read().lower() return any(line.strip().lower() == "id=ubuntu" for line in f)
return "id=ubuntu" in data
except Exception: except Exception:
return False return False
# Instalacja pyenv przez installer (curl | bash) do PYENV_ROOT
def ensure_pyenv_installed_with_installer(pyenv_root: Path, owner: str): def ensure_pyenv_installed_with_installer(pyenv_root: Path, owner: str):
if (pyenv_root / "bin" / "pyenv").exists(): if (pyenv_root / "bin" / "pyenv").exists():
return return
apt_try_install(["curl", "git", "ca-certificates"]) apt_try_install(["curl", "git", "ca-certificates"])
parent_home = pyenv_root.parent # /opt/npm PARENT_HOME.mkdir(parents=True, exist_ok=True)
Path(parent_home).mkdir(parents=True, exist_ok=True) run(["chown", "-R", f"{owner}:{owner}", str(PARENT_HOME)], check=False)
run(["chown", "-R", f"{owner}:{owner}", str(parent_home)], check=False)
run([ run([
"sudo", "-u", owner, "-H", "env", "sudo","-u", owner, "-H", "env",
f"HOME={parent_home}", f"HOME={PARENT_HOME}",
"bash", "-lc", "bash","-lc",
"curl -fsSL https://pyenv.run | bash" "curl -fsSL https://pyenv.run | bash"
], check=True) ], check=True)
src = parent_home / ".pyenv" src = PARENT_HOME / ".pyenv"
if src.exists() and str(src) != str(pyenv_root): if src.exists() and str(src) != str(pyenv_root):
run(["sudo", "-u", owner, "-H", "bash", "-lc", run(["sudo","-u", owner, "-H", "bash","-lc",
f'mv "{src}" "{pyenv_root}"'], check=True) f'mv "{src}" "{pyenv_root}"'], check=True)
# Zależności
build_deps = [ build_deps = [
"build-essential","gcc","make","pkg-config","libssl-dev","zlib1g-dev", "build-essential","gcc","make","pkg-config","libssl-dev","zlib1g-dev",
"libbz2-dev","libreadline-dev","libsqlite3-dev","tk-dev","libncursesw5-dev", "libbz2-dev","libreadline-dev","libsqlite3-dev","tk-dev","libncursesw5-dev",
@@ -257,19 +252,16 @@ def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")):
try: try:
apt_try_install(["pyenv"] + build_deps) apt_try_install(["pyenv"] + build_deps)
except Exception: except Exception:
run(["apt-get", "update"], check=False) run(["apt-get","update"], check=False)
run(["apt-get", "install", "-y", "pyenv"] + build_deps, check=False) run(["apt-get","install","-y","pyenv"] + build_deps, check=False)
# Katalogi i właściciel PARENT_HOME.mkdir(parents=True, exist_ok=True)
Path("/opt/npm").mkdir(parents=True, exist_ok=True)
PYENV_ROOT.mkdir(parents=True, exist_ok=True) PYENV_ROOT.mkdir(parents=True, exist_ok=True)
run(["chown", "-R", f"{PYENV_OWNER}:{PYENV_OWNER}", "/opt/npm"], check=False) run(["chown","-R", f"{PYENV_OWNER}:{PYENV_OWNER}", str(PARENT_HOME)], check=False)
# Ubuntu: instalacja pyenv instalatorem; Debian: może być z APT
if _is_ubuntu(): if _is_ubuntu():
ensure_pyenv_installed_with_installer(PYENV_ROOT, PYENV_OWNER) ensure_pyenv_installed_with_installer(PYENV_ROOT, PYENV_OWNER)
# Wybór binarki pyenv
PYENV_BIN_CANDIDATES = [ PYENV_BIN_CANDIDATES = [
str(PYENV_ROOT / "bin" / "pyenv"), str(PYENV_ROOT / "bin" / "pyenv"),
"/usr/lib/pyenv/bin/pyenv", "/usr/lib/pyenv/bin/pyenv",
@@ -282,22 +274,21 @@ def setup_certbot_venv(venv_dir: Path = Path("/opt/certbot")):
if not pyenv_bin: if not pyenv_bin:
raise RuntimeError("Nie znaleziono 'pyenv' (APT lub installer).") raise RuntimeError("Nie znaleziono 'pyenv' (APT lub installer).")
# Snippet profilowy
profile_snippet = f"""# Auto-generated by setup_certbot_venv profile_snippet = f"""# Auto-generated by setup_certbot_venv
# Ustawienia pyenv dla uzytkownika '{PYENV_OWNER}' # Ustawienia pyenv dla uzytkownika '{PYENV_OWNER}'
if [ -d "{PYENV_ROOT}" ]; then if [ -d "{PYENV_ROOT}" ]; then
export PYENV_ROOT="{PYENV_ROOT}" export PYENV_ROOT="{PYENV_ROOT}"
case ":$PATH:" in *":{PYENV_ROOT}/bin:"*) ;; *) PATH="{PYENV_ROOT}/bin:$PATH" ;; esac case ":$PATH:" in *":{PYENV_ROOT}/bin:"*) ;; *) PATH="{PYENV_ROOT}/bin:$PATH" ;; esac
case ":$PATH:" in *":/usr/lib/pyenv/bin:"*) ;; *) PATH="/usr/lib/pyenv/bin:$PATH" ;; esac
export PATH export PATH
eval "$({pyenv_bin} init -)" eval "$({pyenv_bin} init -)"
fi fi
""" """
write_file(Path("/etc/profile.d/npm-pyenv.sh"), profile_snippet, 0o644) write_file(Path("/etc/profile.d/npm-pyenv.sh"), profile_snippet, 0o644)
# Instalacja Pythona
run([ run([
"sudo","-u", PYENV_OWNER, "-H", "bash","-lc", "sudo","-u", PYENV_OWNER, "-H", "env",
f"HOME={PARENT_HOME}",
"bash","-lc",
f'export PYENV_ROOT="{PYENV_ROOT}"; ' f'export PYENV_ROOT="{PYENV_ROOT}"; '
f'export PATH="$PYENV_ROOT/bin:$PATH"; ' f'export PATH="$PYENV_ROOT/bin:$PATH"; '
f'eval "$({pyenv_bin} init -)"; ' f'eval "$({pyenv_bin} init -)"; '
@@ -305,9 +296,10 @@ fi
f'"{pyenv_bin}" versions' f'"{pyenv_bin}" versions'
], check=True) ], check=True)
# Ścieżka do python3
py_cmd = run([ py_cmd = run([
"sudo","-u", PYENV_OWNER, "-H", "bash","-lc", "sudo","-u", PYENV_OWNER, "-H", "env",
f"HOME={PARENT_HOME}",
"bash","-lc",
f'export PYENV_ROOT="{PYENV_ROOT}"; ' f'export PYENV_ROOT="{PYENV_ROOT}"; '
f'export PATH="$PYENV_ROOT/bin:$PATH"; ' f'export PATH="$PYENV_ROOT/bin:$PATH"; '
f'echo "$({pyenv_bin} prefix {PYTHON_VERSION})/bin/python3"' f'echo "$({pyenv_bin} prefix {PYTHON_VERSION})/bin/python3"'
@@ -316,7 +308,6 @@ fi
if not python_path: if not python_path:
raise RuntimeError("Nie udało się ustalić ścieżki do python3 z pyenv.") raise RuntimeError("Nie udało się ustalić ścieżki do python3 z pyenv.")
# Venv i pakiety
venv_dir.mkdir(parents=True, exist_ok=True) venv_dir.mkdir(parents=True, exist_ok=True)
run([python_path, "-m", "venv", str(venv_dir)], check=True) run([python_path, "-m", "venv", str(venv_dir)], check=True)
@@ -329,7 +320,6 @@ fi
run([str(venv_dir / "bin" / "python"), "-m", "pip", "install", "-U", "pip", "setuptools", "wheel"], env=env_build, check=True) run([str(venv_dir / "bin" / "python"), "-m", "pip", "install", "-U", "pip", "setuptools", "wheel"], env=env_build, check=True)
run([str(pip_path), "install", "-U", "cryptography", "cffi", "certbot", "tldextract"], env=env_build, check=True) run([str(pip_path), "install", "-U", "cryptography", "cffi", "certbot", "tldextract"], env=env_build, check=True)
# Symlink
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():
@@ -339,12 +329,12 @@ fi
pass pass
target.symlink_to(certbot_bin) target.symlink_to(certbot_bin)
# Informacje
cb_ver = run_out([str(certbot_bin), "--version"], check=False) or "" cb_ver = run_out([str(certbot_bin), "--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) run(["chown","-R", f"{PYENV_OWNER}:{PYENV_OWNER}", str(PYENV_ROOT)], check=False)
def configure_letsencrypt(): def configure_letsencrypt():