pyenv
This commit is contained in:
191
npm_install.py
191
npm_install.py
@@ -214,127 +214,122 @@ 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")):
|
||||||
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"
|
||||||
|
PYENV_BIN_CANDIDATES = ["pyenv", "/usr/bin/pyenv", "/usr/lib/pyenv/bin/pyenv"]
|
||||||
|
|
||||||
def _is_ubuntu() -> bool:
|
try:
|
||||||
try:
|
apt_try_install([
|
||||||
with open("/etc/os-release") as f:
|
"pyenv", "build-essential", "gcc", "make", "pkg-config",
|
||||||
return any(line.strip().lower() == "id=ubuntu" for line in f)
|
"libssl-dev", "zlib1g-dev", "libbz2-dev", "libreadline-dev",
|
||||||
except Exception:
|
"libsqlite3-dev", "tk-dev", "libncursesw5-dev", "libgdbm-dev",
|
||||||
return False
|
"libffi-dev", "uuid-dev", "liblzma-dev", "ca-certificates", "curl"
|
||||||
|
])
|
||||||
|
except Exception:
|
||||||
|
run(["apt-get", "update"], check=False)
|
||||||
|
run(["apt-get", "install", "-y",
|
||||||
|
"pyenv", "build-essential", "gcc", "make", "pkg-config",
|
||||||
|
"libssl-dev", "zlib1g-dev", "libbz2-dev", "libreadline-dev",
|
||||||
|
"libsqlite3-dev", "tk-dev", "libncursesw5-dev", "libgdbm-dev",
|
||||||
|
"libffi-dev", "uuid-dev", "liblzma-dev", "ca-certificates", "curl"
|
||||||
|
], check=False)
|
||||||
|
|
||||||
def ensure_pyenv_installed_with_installer(pyenv_root: Path, owner: str):
|
Path("/opt/npm").mkdir(parents=True, exist_ok=True)
|
||||||
if (pyenv_root / "bin" / "pyenv").exists():
|
|
||||||
return
|
|
||||||
apt_try_install(["curl", "git", "ca-certificates"])
|
|
||||||
PARENT_HOME.mkdir(parents=True, exist_ok=True)
|
|
||||||
run(["chown", "-R", f"{owner}:{owner}", str(PARENT_HOME)], check=False)
|
|
||||||
run([
|
|
||||||
"sudo","-u", owner, "-H", "env",
|
|
||||||
f"HOME={PARENT_HOME}",
|
|
||||||
"bash","-lc",
|
|
||||||
"curl -fsSL https://pyenv.run | bash"
|
|
||||||
], check=True)
|
|
||||||
src = PARENT_HOME / ".pyenv"
|
|
||||||
if src.exists() and str(src) != str(pyenv_root):
|
|
||||||
run(["sudo","-u", owner, "-H", "bash","-lc",
|
|
||||||
f'mv "{src}" "{pyenv_root}"'], check=True)
|
|
||||||
|
|
||||||
build_deps = [
|
|
||||||
"build-essential","gcc","make","pkg-config","libssl-dev","zlib1g-dev",
|
|
||||||
"libbz2-dev","libreadline-dev","libsqlite3-dev","tk-dev","libncursesw5-dev",
|
|
||||||
"libgdbm-dev","libffi-dev","uuid-dev","liblzma-dev","ca-certificates","curl","git"
|
|
||||||
]
|
|
||||||
if _is_ubuntu():
|
|
||||||
apt_try_install(build_deps)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
apt_try_install(["pyenv"] + build_deps)
|
|
||||||
except Exception:
|
|
||||||
run(["apt-get","update"], check=False)
|
|
||||||
run(["apt-get","install","-y","pyenv"] + build_deps, check=False)
|
|
||||||
|
|
||||||
PARENT_HOME.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}", str(PARENT_HOME)], check=False)
|
run(["chown", "-R", f"{PYENV_OWNER}:{PYENV_OWNER}", "/opt/npm"], check=False)
|
||||||
|
|
||||||
if _is_ubuntu():
|
|
||||||
ensure_pyenv_installed_with_installer(PYENV_ROOT, PYENV_OWNER)
|
|
||||||
|
|
||||||
PYENV_BIN_CANDIDATES = [
|
|
||||||
str(PYENV_ROOT / "bin" / "pyenv"),
|
|
||||||
"/usr/lib/pyenv/bin/pyenv",
|
|
||||||
"/usr/bin/pyenv",
|
|
||||||
"pyenv",
|
|
||||||
]
|
|
||||||
pyenv_bin = next((c for c in PYENV_BIN_CANDIDATES if shutil.which(c)), None)
|
pyenv_bin = next((c for c in PYENV_BIN_CANDIDATES if shutil.which(c)), None)
|
||||||
if not pyenv_bin and (PYENV_ROOT / "bin" / "pyenv").exists():
|
|
||||||
pyenv_bin = str(PYENV_ROOT / "bin" / "pyenv")
|
|
||||||
if not pyenv_bin:
|
if not pyenv_bin:
|
||||||
raise RuntimeError("Nie znaleziono 'pyenv' (APT lub installer).")
|
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 '
|
||||||
|
' 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 = (
|
||||||
|
'export HOME=/opt/npm; '
|
||||||
|
'export PYENV_ROOT=/opt/npm/.pyenv; '
|
||||||
|
'export PATH="$PYENV_ROOT/bin:/usr/bin:/bin"; '
|
||||||
|
'mkdir -p "$PYENV_ROOT"; cd "$HOME"; '
|
||||||
|
f'pyenv install -s {PYTHON_VERSION}'
|
||||||
|
)
|
||||||
|
run([
|
||||||
|
"sudo", "-u", PYENV_OWNER, "env", "-i",
|
||||||
|
"HOME=/opt/npm",
|
||||||
|
f"PYENV_ROOT={PYENV_ROOT}",
|
||||||
|
f"PATH={PYENV_ROOT}/bin:/usr/bin:/bin",
|
||||||
|
"bash", "-lc", install_cmd
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
profile_snippet = f"""# Auto-generated by setup_certbot_venv
|
profile_snippet = f"""# Auto-generated by setup_certbot_venv
|
||||||
# Ustawienia pyenv dla uzytkownika '{PYENV_OWNER}'
|
# pyenv for '{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 -)"
|
case "$-" in *i*) _interactive=1 ;; *) _interactive=0 ;; esac
|
||||||
|
if [ "$_interactive" = 1 ] && {{ [ "${{USER:-}}" = "{PYENV_OWNER}" ] || [ "${{SUDO_USER:-}}" = "{PYENV_OWNER}" ]; }}; then
|
||||||
|
if command -v pyenv >/dev/null 2>&1; then
|
||||||
|
eval "$(pyenv init -)"
|
||||||
|
elif [ -x "{PYENV_ROOT}/bin/pyenv" ]; then
|
||||||
|
eval "$("{PYENV_ROOT}/bin/pyenv" init -)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
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)
|
||||||
|
|
||||||
run([
|
python311 = PYENV_ROOT / "versions" / PYTHON_VERSION / "bin" / "python3.11"
|
||||||
"sudo","-u", PYENV_OWNER, "-H", "env",
|
if not python311.exists():
|
||||||
f"HOME={PARENT_HOME}",
|
python311 = PYENV_ROOT / "versions" / PYTHON_VERSION / "bin" / "python3"
|
||||||
"bash","-lc",
|
if not python311.exists():
|
||||||
f'export PYENV_ROOT="{PYENV_ROOT}"; '
|
raise RuntimeError(f"No python {PYTHON_VERSION} in {PYENV_ROOT}/versions/.")
|
||||||
f'export PATH="$PYENV_ROOT/bin:$PATH"; '
|
|
||||||
f'eval "$({pyenv_bin} init -)"; '
|
|
||||||
f'"{pyenv_bin}" install -s {PYTHON_VERSION}; '
|
|
||||||
f'"{pyenv_bin}" versions'
|
|
||||||
], check=True)
|
|
||||||
|
|
||||||
py_cmd = run([
|
venv_bin = venv_dir / "bin"
|
||||||
"sudo","-u", PYENV_OWNER, "-H", "env",
|
pip_path = venv_bin / "pip"
|
||||||
f"HOME={PARENT_HOME}",
|
certbot_path = venv_bin / "certbot"
|
||||||
"bash","-lc",
|
|
||||||
f'export PYENV_ROOT="{PYENV_ROOT}"; '
|
|
||||||
f'export PATH="$PYENV_ROOT/bin:$PATH"; '
|
|
||||||
f'echo "$({pyenv_bin} prefix {PYTHON_VERSION})/bin/python3"'
|
|
||||||
], check=True)
|
|
||||||
python_path = (py_cmd.stdout.decode().strip() if hasattr(py_cmd, "stdout") else "").strip()
|
|
||||||
if not python_path:
|
|
||||||
raise RuntimeError("Nie udało się ustalić ścieżki do python3 z pyenv.")
|
|
||||||
|
|
||||||
venv_dir.mkdir(parents=True, exist_ok=True)
|
with step(f"Preparing Certbot venv at {venv_dir} (Python {PYTHON_VERSION})"):
|
||||||
run([python_path, "-m", "venv", str(venv_dir)], check=True)
|
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)])
|
||||||
|
|
||||||
pip_path = venv_dir / "bin" / "pip"
|
env_build = os.environ.copy()
|
||||||
certbot_bin = venv_dir / "bin" / "certbot"
|
env_build["SETUPTOOLS_USE_DISTUTILS"] = "local"
|
||||||
|
|
||||||
env_build = os.environ.copy()
|
run([str(pip_path), "install", "-U", "pip", "setuptools", "wheel"], env=env_build)
|
||||||
env_build["SETUPTOOLS_USE_DISTUTILS"] = "local"
|
run([str(pip_path), "install", "-U",
|
||||||
|
"cryptography", "cffi", "certbot", "tldextract"], env=env_build)
|
||||||
|
|
||||||
run([str(venv_dir / "bin" / "python"), "-m", "pip", "install", "-U", "pip", "setuptools", "wheel"], env=env_build, check=True)
|
Path("/usr/local/bin").mkdir(parents=True, exist_ok=True)
|
||||||
run([str(pip_path), "install", "-U", "cryptography", "cffi", "certbot", "tldextract"], env=env_build, check=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)
|
||||||
|
|
||||||
Path("/usr/local/bin").mkdir(parents=True, exist_ok=True)
|
cb_ver = run_out([str(certbot_path), "--version"], check=False) or ""
|
||||||
target = Path("/usr/local/bin/certbot")
|
pip_ver = run_out([str(pip_path), "--version"], check=False) or ""
|
||||||
if target.exists() or target.is_symlink():
|
print(f"Certbot: {cb_ver.strip()} | Pip: {pip_ver.strip()}")
|
||||||
try:
|
|
||||||
target.unlink()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
target.symlink_to(certbot_bin)
|
|
||||||
|
|
||||||
cb_ver = run_out([str(certbot_bin), "--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)
|
|
||||||
|
|
||||||
|
run(["chown", "-R", f"{PYENV_OWNER}:{PYENV_OWNER}", str(PYENV_ROOT)], check=False)
|
||||||
|
|
||||||
|
|
||||||
def configure_letsencrypt():
|
def configure_letsencrypt():
|
||||||
|
|||||||
Reference in New Issue
Block a user