updated server install scripts
This commit is contained in:
parent
7ad68c3983
commit
4224b9d15c
5 changed files with 544 additions and 4 deletions
10
README.md
10
README.md
|
|
@ -144,6 +144,16 @@ re-run commands from scratch every time.
|
|||
Both launchers check prerequisites first (Go, Python 3, and the panel's own
|
||||
dependencies via `tui-panel/requirements-panel.txt`), then start the panel.
|
||||
|
||||
Anything missing is installed for you rather than listed: the launcher hands off
|
||||
to `scripts/install-prereqs.sh` (Arch and Ubuntu/Debian — asks for root once,
|
||||
then installs Go, Python, Docker and OpenSSL) or `scripts/install-prereqs.ps1`
|
||||
(Windows, via winget). Run either directly with `--dry-run` to see what it would
|
||||
install without touching anything.
|
||||
|
||||
Docker on Windows is the one exception: its containers are Linux images, so the
|
||||
daemon needs Docker Desktop's WSL2 backend — an install with a reboot and its own
|
||||
licence terms. The script reports it with a link instead of starting it.
|
||||
|
||||
What it does:
|
||||
|
||||
- 🧙 **First-run setup wizard** — walks through the required `.env` values
|
||||
|
|
|
|||
|
|
@ -71,10 +71,38 @@ if defined PYTHON (
|
|||
)
|
||||
|
||||
if "%PROBLEMS%"=="1" (
|
||||
rem Hand off to the winget installer rather than stopping at a shopping list.
|
||||
rem OWPENGRAM_PREREQS_TRIED bounds this to a single retry, so something that
|
||||
rem will not install ends in a message instead of a loop.
|
||||
if defined OWPENGRAM_PREREQS_TRIED (
|
||||
echo.
|
||||
echo [ERROR] prerequisites are still missing after the install attempt -- see the messages above
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
if not exist "scripts\install-prereqs.ps1" (
|
||||
echo.
|
||||
echo [ERROR] missing prerequisites above -- install them and re-run this script
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo.
|
||||
echo == Installing the missing prerequisites ==
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File "scripts\install-prereqs.ps1"
|
||||
if errorlevel 1 (
|
||||
echo.
|
||||
echo [ERROR] could not install the prerequisites -- see the messages above
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
rem winget writes the new PATH to the registry, but this console still holds
|
||||
rem the one it started with -- reload it so the re-check below can see what
|
||||
rem was just installed instead of asking for a fresh terminal.
|
||||
for /f "usebackq delims=" %%p in (`powershell -NoProfile -Command "[Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [Environment]::GetEnvironmentVariable('Path','User')"`) do set "PATH=%%p"
|
||||
set "OWPENGRAM_PREREQS_TRIED=1"
|
||||
echo.
|
||||
call "%~f0" %*
|
||||
exit /b !errorlevel!
|
||||
)
|
||||
|
||||
echo.
|
||||
|
|
|
|||
|
|
@ -86,7 +86,28 @@ fi
|
|||
|
||||
if [[ "$PROBLEMS" -ne 0 ]]; then
|
||||
echo
|
||||
# Hand off to the installer rather than stopping at a shopping list. It asks
|
||||
# for confirmation once, takes root once, and installs only what is missing.
|
||||
# The re-exec is what makes the freshly installed tools count: this shell
|
||||
# resolved `go`/`python3` before any of them existed. OWPENGRAM_PREREQS_TRIED
|
||||
# bounds it to a single retry, so a package that still will not install ends
|
||||
# in a message instead of a loop.
|
||||
if [[ -n "${OWPENGRAM_PREREQS_TRIED:-}" ]]; then
|
||||
die "prerequisites are still missing after the install attempt -- see the messages above"
|
||||
fi
|
||||
if [[ ! -x scripts/install-prereqs.sh ]]; then
|
||||
die "missing prerequisites above -- install them and re-run this script"
|
||||
fi
|
||||
echo "== Installing the missing prerequisites =="
|
||||
if ! scripts/install-prereqs.sh; then
|
||||
die "could not install the prerequisites -- see the messages above"
|
||||
fi
|
||||
# /etc/profile.d/go.sh only applies to shells started later, and the venv is
|
||||
# not on PATH at all; both are picked up by the re-exec below because the
|
||||
# re-check looks for .venv/bin/python first.
|
||||
[[ -d /usr/local/go/bin ]] && export PATH="$PATH:/usr/local/go/bin"
|
||||
echo
|
||||
OWPENGRAM_PREREQS_TRIED=1 exec "$0" "$@"
|
||||
fi
|
||||
|
||||
echo
|
||||
|
|
|
|||
185
scripts/install-prereqs.ps1
Normal file
185
scripts/install-prereqs.ps1
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
#Requires -Version 5.1
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Installs everything owpengram-server.bat checks for, via winget: Go, Python 3
|
||||
(+ the panel's packages in a venv) and OpenSSL.
|
||||
|
||||
.DESCRIPTION
|
||||
Docker is the deliberate exception. It is only reported, with a link: on Windows
|
||||
the containers this server needs (PostgreSQL, Redis, MinIO) are Linux images, so
|
||||
the daemon has to sit on a Linux kernel -- which means Docker Desktop with WSL2,
|
||||
an install that wants a reboot and carries its own licence terms. That is not a
|
||||
thing to start behind someone's back.
|
||||
|
||||
.PARAMETER DryRun
|
||||
Only report what would be installed.
|
||||
|
||||
.PARAMETER Yes
|
||||
Skip the confirmation prompt.
|
||||
#>
|
||||
param(
|
||||
[switch]$DryRun,
|
||||
[switch]$Yes
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
|
||||
$DockerDocs = 'https://docs.docker.com/desktop/setup/install/windows-install/'
|
||||
$GoMinMinor = 25
|
||||
|
||||
function Write-Ok { param([string]$Text) Write-Host "[ok] $Text" -ForegroundColor Green }
|
||||
function Write-Info { param([string]$Text) Write-Host "[..] $Text" -ForegroundColor Cyan }
|
||||
function Write-Warn { param([string]$Text) Write-Host "[WARN] $Text" -ForegroundColor Yellow }
|
||||
function Write-Err { param([string]$Text) Write-Host "[ERROR] $Text" -ForegroundColor Red }
|
||||
|
||||
function Test-Command { param([string]$Name) [bool](Get-Command $Name -ErrorAction SilentlyContinue) }
|
||||
|
||||
# winget puts new tools on the machine/user PATH, but this process was started
|
||||
# with the old one -- without this the venv step cannot find the Python it just
|
||||
# installed, and the closing "go version" would report the absence of Go.
|
||||
function Update-PathFromRegistry {
|
||||
$machine = [Environment]::GetEnvironmentVariable('Path', 'Machine')
|
||||
$user = [Environment]::GetEnvironmentVariable('Path', 'User')
|
||||
$env:Path = (@($machine, $user) | Where-Object { $_ }) -join ';'
|
||||
}
|
||||
|
||||
# python.exe on a stock Windows is often the Microsoft Store's app-execution
|
||||
# alias: present on PATH, and it opens the Store instead of running anything.
|
||||
# Only a real version string counts, which is the same trap owpengram-server.bat
|
||||
# documents.
|
||||
function Get-WorkingPython {
|
||||
foreach ($candidate in @('py -3', 'python3', 'python')) {
|
||||
$parts = $candidate.Split(' ')
|
||||
if (-not (Test-Command $parts[0])) { continue }
|
||||
try {
|
||||
$out = & $parts[0] @($parts[1..($parts.Length - 1)] + '--version') 2>&1 | Out-String
|
||||
} catch { continue }
|
||||
if ($out -match 'Python 3\.') { return $candidate }
|
||||
}
|
||||
return $null
|
||||
}
|
||||
|
||||
function Test-GoRecentEnough {
|
||||
if (-not (Test-Command 'go')) { return $false }
|
||||
try { $version = (& go env GOVERSION 2>$null | Out-String).Trim() } catch { return $false }
|
||||
if ($version -match '^go1\.(\d+)') { return [int]$Matches[1] -ge $GoMinMinor }
|
||||
return $false
|
||||
}
|
||||
|
||||
# Same precedence owpengram-server.bat uses when it picks an interpreter: the
|
||||
# venv when one exists, otherwise whatever Python is on PATH. Checking only the
|
||||
# venv would report the packages missing on a machine that already has them
|
||||
# installed system-wide, and build a venv nobody asked for.
|
||||
function Test-PanelDepsInstalled {
|
||||
$checker = Join-Path $RepoRoot 'tui-panel\check_deps.py'
|
||||
$venvPython = Join-Path $RepoRoot '.venv\Scripts\python.exe'
|
||||
if (Test-Path $venvPython) {
|
||||
$missing = & $venvPython $checker 2>$null | Out-String
|
||||
return [string]::IsNullOrWhiteSpace($missing)
|
||||
}
|
||||
$fallback = Get-WorkingPython
|
||||
if (-not $fallback) { return $false }
|
||||
$parts = $fallback.Split(' ')
|
||||
$missing = & $parts[0] @($parts[1..($parts.Length - 1)] + $checker) 2>$null | Out-String
|
||||
return [string]::IsNullOrWhiteSpace($missing)
|
||||
}
|
||||
|
||||
function Install-WingetPackage {
|
||||
param([string]$Id, [string]$Label)
|
||||
Write-Info "Installing $Label ($Id)"
|
||||
& winget install --exact --id $Id --source winget `
|
||||
--accept-package-agreements --accept-source-agreements --disable-interactivity
|
||||
# 0 is installed; -1978335189 is "no applicable upgrade", i.e. already current.
|
||||
if ($LASTEXITCODE -ne 0 -and $LASTEXITCODE -ne -1978335189) {
|
||||
throw "winget failed to install $Id (exit $LASTEXITCODE)"
|
||||
}
|
||||
Update-PathFromRegistry
|
||||
}
|
||||
|
||||
if (-not (Test-Command 'winget')) {
|
||||
Write-Err 'winget is not available. Install "App Installer" from the Microsoft Store, then run this again.'
|
||||
exit 1
|
||||
}
|
||||
|
||||
# --- what is missing ---------------------------------------------------------
|
||||
$python = Get-WorkingPython
|
||||
$needed = [System.Collections.Generic.List[string]]::new()
|
||||
if (-not (Test-GoRecentEnough)) { $needed.Add('go') }
|
||||
if (-not $python) { $needed.Add('python') }
|
||||
if (-not (Test-Command 'openssl')) { $needed.Add('openssl') }
|
||||
if (-not (Test-PanelDepsInstalled)) { $needed.Add('pydeps') }
|
||||
$dockerMissing = -not (Test-Command 'docker')
|
||||
|
||||
if ($needed.Count -eq 0 -and -not $dockerMissing) {
|
||||
Write-Ok 'All prerequisites are already installed.'
|
||||
exit 0
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host '== Missing prerequisites ==' -ForegroundColor Yellow
|
||||
foreach ($item in $needed) {
|
||||
switch ($item) {
|
||||
'go' { Write-Host " - Go 1.$GoMinMinor+ (builds owpengram-server and the admin panel)" }
|
||||
'python' { Write-Host ' - Python 3 (runs the server-panel TUI)' }
|
||||
'pydeps' { Write-Host ' - Python packages: textual, psutil, cryptography (into .\.venv)' }
|
||||
'openssl' { Write-Host " - OpenSSL (exports the server's RSA public key for clients)" }
|
||||
}
|
||||
}
|
||||
if ($dockerMissing) { Write-Host ' - Docker (runs PostgreSQL, Redis and MinIO) -- install this one yourself, see below' }
|
||||
Write-Host ''
|
||||
|
||||
if ($DryRun) {
|
||||
Write-Ok 'Dry run -- nothing was installed.'
|
||||
exit 0
|
||||
}
|
||||
|
||||
if ($needed.Count -gt 0 -and -not $Yes) {
|
||||
$answer = Read-Host 'Install these now? [Y/n]'
|
||||
if ($answer -and $answer -notmatch '^(y|yes)$') {
|
||||
Write-Err 'cancelled'
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
if ($needed -contains 'go') { Install-WingetPackage -Id 'GoLang.Go' -Label 'Go' }
|
||||
if ($needed -contains 'python') { Install-WingetPackage -Id 'Python.Python.3.13' -Label 'Python 3.13' }
|
||||
if ($needed -contains 'openssl') { Install-WingetPackage -Id 'ShiningLight.OpenSSL.Light' -Label 'OpenSSL' }
|
||||
|
||||
# --- the panel's Python packages ---------------------------------------------
|
||||
# A venv rather than the machine-wide interpreter, to match what the Linux side
|
||||
# does and what owpengram-server.bat already prefers once one exists.
|
||||
if ($needed -contains 'pydeps' -or $needed -contains 'python') {
|
||||
$python = Get-WorkingPython
|
||||
if (-not $python) {
|
||||
Write-Err 'Python still is not callable. Open a new terminal and run this script again.'
|
||||
exit 1
|
||||
}
|
||||
Write-Info 'Installing the panel''s Python packages into .\.venv'
|
||||
$venvPython = Join-Path $RepoRoot '.venv\Scripts\python.exe'
|
||||
if (-not (Test-Path $venvPython)) {
|
||||
$parts = $python.Split(' ')
|
||||
& $parts[0] @($parts[1..($parts.Length - 1)] + @('-m', 'venv', (Join-Path $RepoRoot '.venv')))
|
||||
if ($LASTEXITCODE -ne 0) { throw 'could not create .venv' }
|
||||
}
|
||||
& $venvPython -m pip install --quiet --upgrade pip
|
||||
& $venvPython -m pip install --quiet -r (Join-Path $RepoRoot 'tui-panel\requirements-panel.txt')
|
||||
if ($LASTEXITCODE -ne 0) { throw 'could not install the panel''s Python packages' }
|
||||
Write-Ok 'Python packages installed'
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
if ($dockerMissing) {
|
||||
Write-Warn 'Docker still has to be installed by hand.'
|
||||
Write-Host " The server's PostgreSQL, Redis and MinIO are Linux containers, so Windows"
|
||||
Write-Host ' needs Docker Desktop (it brings the WSL2 backend that runs them).'
|
||||
Write-Host " $DockerDocs"
|
||||
Write-Host ' Install it, reboot if it asks, then run this script again.'
|
||||
Write-Host ''
|
||||
}
|
||||
if ($needed.Count -gt 0) {
|
||||
Write-Ok 'Prerequisites are ready.'
|
||||
Write-Host ' Open a new terminal so the updated PATH is picked up, then start the server with:'
|
||||
Write-Host ' owpengram-server.bat'
|
||||
}
|
||||
296
scripts/install-prereqs.sh
Executable file
296
scripts/install-prereqs.sh
Executable file
|
|
@ -0,0 +1,296 @@
|
|||
#!/usr/bin/env bash
|
||||
# Installs everything owpengram-server.sh checks for, so a fresh machine needs
|
||||
# one command instead of a shopping list: Go, Python 3 (+ the panel's packages
|
||||
# in a venv), Docker and OpenSSL.
|
||||
#
|
||||
# ./scripts/install-prereqs.sh install whatever is missing
|
||||
# ./scripts/install-prereqs.sh --dry-run only report what it would install
|
||||
# ./scripts/install-prereqs.sh --yes no confirmation prompt
|
||||
#
|
||||
# Supported: Arch (pacman) and Ubuntu/Debian (apt). Anything else is reported
|
||||
# rather than guessed at -- a wrong package manager on a production box is a
|
||||
# worse outcome than a clear "install these yourself".
|
||||
#
|
||||
# Root is taken once, up front, and held for the whole run: a sudo prompt
|
||||
# appearing ten minutes in, after the user walked away, is how half-installed
|
||||
# machines happen.
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
REPO_ROOT="$PWD"
|
||||
|
||||
ok() { printf '[ok] %s\n' "$*"; }
|
||||
info() { printf '[..] %s\n' "$*"; }
|
||||
warn() { printf '[WARN] %s\n' "$*"; }
|
||||
die() { printf '[ERROR] %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
DRY_RUN=0
|
||||
ASSUME_YES=0
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--dry-run) DRY_RUN=1 ;;
|
||||
--yes|-y) ASSUME_YES=1 ;;
|
||||
-h|--help) sed -n '2,14p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||
*) die "unknown argument: $arg" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# --- distro ------------------------------------------------------------------
|
||||
# ID_LIKE is what makes derivatives work without listing every one of them:
|
||||
# EndeavourOS says ID_LIKE=arch, Pop!_OS and Mint say ID_LIKE=ubuntu/debian.
|
||||
FAMILY=""
|
||||
DISTRO_NAME="unknown"
|
||||
if [[ -r /etc/os-release ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
. /etc/os-release
|
||||
DISTRO_NAME="${PRETTY_NAME:-$ID}"
|
||||
case " ${ID:-} ${ID_LIKE:-} " in
|
||||
*" arch "*) FAMILY="arch" ;;
|
||||
*" ubuntu "*|*" debian "*) FAMILY="debian" ;;
|
||||
esac
|
||||
fi
|
||||
[[ -n "$FAMILY" ]] || die "unsupported distribution: ${DISTRO_NAME}. Supported: Arch and Ubuntu/Debian. Install Go 1.25+, Python 3, Docker and OpenSSL by hand, then run ./owpengram-server.sh"
|
||||
|
||||
# --- what is missing ---------------------------------------------------------
|
||||
have() { command -v "$1" >/dev/null 2>&1; }
|
||||
|
||||
# Go's own version gate: go.mod asks for 1.25, and a too-old toolchain fails at
|
||||
# build time with a message that does not obviously point back here.
|
||||
GO_MIN_MINOR=25
|
||||
go_is_recent_enough() {
|
||||
have go || return 1
|
||||
local v minor
|
||||
v="$(go env GOVERSION 2>/dev/null || true)" # e.g. go1.25.7
|
||||
minor="${v#go1.}"
|
||||
minor="${minor%%.*}"
|
||||
[[ "$minor" =~ ^[0-9]+$ ]] && (( minor >= GO_MIN_MINOR ))
|
||||
}
|
||||
|
||||
venv_python() { printf '%s/.venv/bin/python' "$REPO_ROOT"; }
|
||||
|
||||
# Same precedence owpengram-server.sh uses when it picks an interpreter: the
|
||||
# venv when one exists, otherwise whatever python3 is on PATH. Checking only the
|
||||
# venv would report the packages missing on a machine that already has them
|
||||
# installed system-wide, and build a venv nobody asked for.
|
||||
pydeps_satisfied() {
|
||||
local py
|
||||
if [[ -x "$(venv_python)" ]]; then
|
||||
py="$(venv_python)"
|
||||
elif have python3; then
|
||||
py="python3"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
[[ -z "$("$py" tui-panel/check_deps.py 2>/dev/null)" ]]
|
||||
}
|
||||
|
||||
NEEDED=()
|
||||
go_is_recent_enough || NEEDED+=("go")
|
||||
have python3 || NEEDED+=("python")
|
||||
have docker || NEEDED+=("docker")
|
||||
have openssl || NEEDED+=("openssl")
|
||||
# The venv is built with python3, so it can only be settled after Python is.
|
||||
pydeps_satisfied || NEEDED+=("pydeps")
|
||||
|
||||
if [[ ${#NEEDED[@]} -eq 0 ]]; then
|
||||
ok "All prerequisites are already installed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "== Missing prerequisites on ${DISTRO_NAME} =="
|
||||
for item in "${NEEDED[@]}"; do
|
||||
case "$item" in
|
||||
go) echo " - Go 1.${GO_MIN_MINOR}+ (builds owpengram-server and the admin panel)" ;;
|
||||
python) echo " - Python 3 (runs the server-panel TUI)" ;;
|
||||
pydeps) echo " - Python packages: textual, psutil, cryptography (into ./.venv)" ;;
|
||||
docker) echo " - Docker (runs PostgreSQL, Redis and MinIO)" ;;
|
||||
openssl) echo " - OpenSSL (exports the server's RSA public key for clients)" ;;
|
||||
esac
|
||||
done
|
||||
echo
|
||||
|
||||
if [[ "$DRY_RUN" -eq 1 ]]; then
|
||||
ok "Dry run -- nothing was installed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$ASSUME_YES" -ne 1 ]]; then
|
||||
read -r -p "Install these now? This needs root. [Y/n] " answer
|
||||
case "${answer:-y}" in
|
||||
[Yy]|[Yy][Ee][Ss]|"") ;;
|
||||
*) die "cancelled" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Ask for the password once, then refresh the timestamp in the background so a
|
||||
# long Go download or apt run does not hit a second prompt mid-way.
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
have sudo || die "sudo is not installed and this is not running as root"
|
||||
sudo -v || die "could not acquire root"
|
||||
while true; do sudo -n true 2>/dev/null; sleep 50; done &
|
||||
SUDO_KEEPALIVE=$!
|
||||
trap 'kill "$SUDO_KEEPALIVE" 2>/dev/null || true' EXIT
|
||||
SUDO="sudo"
|
||||
else
|
||||
SUDO=""
|
||||
fi
|
||||
|
||||
needs() { local x; for x in "${NEEDED[@]}"; do [[ "$x" == "$1" ]] && return 0; done; return 1; }
|
||||
|
||||
# --- package manager ---------------------------------------------------------
|
||||
APT_UPDATED=0
|
||||
apt_update_once() {
|
||||
if [[ "$APT_UPDATED" -eq 0 ]]; then
|
||||
$SUDO apt-get update -qq
|
||||
APT_UPDATED=1
|
||||
fi
|
||||
}
|
||||
pkg_install() {
|
||||
case "$FAMILY" in
|
||||
arch) $SUDO pacman -S --needed --noconfirm "$@" ;;
|
||||
debian) apt_update_once; $SUDO env DEBIAN_FRONTEND=noninteractive apt-get install -y -qq "$@" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# --- Python + OpenSSL --------------------------------------------------------
|
||||
if needs python; then
|
||||
info "Installing Python 3"
|
||||
case "$FAMILY" in
|
||||
arch) pkg_install python ;;
|
||||
# python3-venv is separate on Debian/Ubuntu and is what the panel's
|
||||
# dependencies go into: both distros mark the system Python
|
||||
# externally-managed, so pip into it is refused by design.
|
||||
debian) pkg_install python3 python3-venv python3-pip ;;
|
||||
esac
|
||||
ok "Python installed: $(python3 --version)"
|
||||
fi
|
||||
|
||||
if needs openssl; then
|
||||
info "Installing OpenSSL"
|
||||
pkg_install openssl
|
||||
ok "OpenSSL installed: $(openssl version)"
|
||||
fi
|
||||
|
||||
# --- Go ----------------------------------------------------------------------
|
||||
# Arch ships a current Go; Debian/Ubuntu do not (24.04 is still on 1.22, below
|
||||
# what go.mod needs), so there the official tarball is the only sane source.
|
||||
install_go_tarball() {
|
||||
local version arch tarball url tmp expected actual
|
||||
version="$(curl -fsSL 'https://go.dev/VERSION?m=text' | head -n1)"
|
||||
[[ "$version" == go* ]] || die "could not determine the latest Go version"
|
||||
case "$(uname -m)" in
|
||||
x86_64) arch="amd64" ;;
|
||||
aarch64) arch="arm64" ;;
|
||||
armv7l) arch="armv6l" ;;
|
||||
*) die "unsupported CPU architecture for the Go tarball: $(uname -m)" ;;
|
||||
esac
|
||||
tarball="${version}.linux-${arch}.tar.gz"
|
||||
url="https://go.dev/dl/${tarball}"
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' RETURN
|
||||
|
||||
info "Downloading ${tarball}"
|
||||
curl -fsSL "$url" -o "$tmp/$tarball"
|
||||
|
||||
# The published checksum lives in go.dev's release index, so the download is
|
||||
# verified against the site's metadata rather than trusted on arrival.
|
||||
expected="$(curl -fsSL 'https://go.dev/dl/?mode=json&include=all' \
|
||||
| python3 -c 'import json,sys
|
||||
want = sys.argv[1]
|
||||
for release in json.load(sys.stdin):
|
||||
for f in release.get("files", []):
|
||||
if f.get("filename") == want:
|
||||
print(f.get("sha256", ""))
|
||||
raise SystemExit
|
||||
' "$tarball")"
|
||||
[[ -n "$expected" ]] || die "no published checksum for ${tarball}"
|
||||
actual="$(sha256sum "$tmp/$tarball" | cut -d' ' -f1)"
|
||||
[[ "$actual" == "$expected" ]] || die "checksum mismatch for ${tarball}: expected ${expected}, got ${actual}"
|
||||
ok "Checksum verified"
|
||||
|
||||
$SUDO rm -rf /usr/local/go
|
||||
$SUDO tar -C /usr/local -xzf "$tmp/$tarball"
|
||||
# /usr/local/go/bin is not on a default PATH; drop a profile snippet so new
|
||||
# shells find it. The current shell still will not, hence the note at the end.
|
||||
printf 'export PATH=$PATH:/usr/local/go/bin\n' | $SUDO tee /etc/profile.d/go.sh >/dev/null
|
||||
$SUDO chmod 0644 /etc/profile.d/go.sh
|
||||
export PATH="$PATH:/usr/local/go/bin"
|
||||
}
|
||||
|
||||
GO_NEEDS_NEW_SHELL=0
|
||||
if needs go; then
|
||||
info "Installing Go"
|
||||
case "$FAMILY" in
|
||||
arch) pkg_install go ;;
|
||||
debian) install_go_tarball; GO_NEEDS_NEW_SHELL=1 ;;
|
||||
esac
|
||||
ok "Go installed: $(go version)"
|
||||
fi
|
||||
|
||||
# --- Docker ------------------------------------------------------------------
|
||||
DOCKER_NEEDS_RELOGIN=0
|
||||
install_docker_debian() {
|
||||
local codename repo_distro
|
||||
# Derivatives (Mint, Pop!_OS) carry their own codename that Docker's repo
|
||||
# does not publish; UBUNTU_CODENAME is the upstream one it does.
|
||||
# shellcheck disable=SC1091
|
||||
. /etc/os-release
|
||||
codename="${UBUNTU_CODENAME:-${VERSION_CODENAME:-}}"
|
||||
[[ -n "$codename" ]] || die "could not determine the distribution codename for Docker's repository"
|
||||
case " ${ID:-} ${ID_LIKE:-} " in
|
||||
*" ubuntu "*) repo_distro="ubuntu" ;;
|
||||
*) repo_distro="debian" ;;
|
||||
esac
|
||||
|
||||
pkg_install ca-certificates curl gnupg
|
||||
$SUDO install -m 0755 -d /etc/apt/keyrings
|
||||
$SUDO curl -fsSL "https://download.docker.com/linux/${repo_distro}/gpg" -o /etc/apt/keyrings/docker.asc
|
||||
$SUDO chmod a+r /etc/apt/keyrings/docker.asc
|
||||
printf 'deb [arch=%s signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/%s %s stable\n' \
|
||||
"$(dpkg --print-architecture)" "$repo_distro" "$codename" \
|
||||
| $SUDO tee /etc/apt/sources.list.d/docker.list >/dev/null
|
||||
APT_UPDATED=0 # the new repository has to be picked up
|
||||
pkg_install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
}
|
||||
|
||||
if needs docker; then
|
||||
info "Installing Docker"
|
||||
case "$FAMILY" in
|
||||
arch) pkg_install docker docker-compose ;;
|
||||
debian) install_docker_debian ;;
|
||||
esac
|
||||
if have systemctl; then
|
||||
$SUDO systemctl enable --now docker
|
||||
ok "Docker service started"
|
||||
else
|
||||
warn "systemd not found -- start the Docker daemon yourself before running ./owpengram-server.sh"
|
||||
fi
|
||||
# Without this every docker call needs sudo, which the panel does not use.
|
||||
if [[ $EUID -ne 0 ]] && ! id -nG "$USER" | tr ' ' '\n' | grep -qx docker; then
|
||||
$SUDO usermod -aG docker "$USER"
|
||||
DOCKER_NEEDS_RELOGIN=1
|
||||
fi
|
||||
ok "Docker installed: $(docker --version)"
|
||||
fi
|
||||
|
||||
# --- the panel's Python packages ---------------------------------------------
|
||||
# Always a venv, never the system interpreter: Arch and Debian both refuse pip
|
||||
# into it (PEP 668), and owpengram-server.sh already prefers ./.venv when present.
|
||||
if needs pydeps; then
|
||||
info "Installing the panel's Python packages into ./.venv"
|
||||
[[ -x "$(venv_python)" ]] || python3 -m venv "$REPO_ROOT/.venv"
|
||||
"$(venv_python)" -m pip install --quiet --upgrade pip
|
||||
"$(venv_python)" -m pip install --quiet -r tui-panel/requirements-panel.txt
|
||||
ok "Python packages installed"
|
||||
fi
|
||||
|
||||
echo
|
||||
ok "Prerequisites are ready."
|
||||
if [[ "$GO_NEEDS_NEW_SHELL" -eq 1 ]]; then
|
||||
echo " Go was installed to /usr/local/go. Open a new shell, or run:"
|
||||
echo " export PATH=\$PATH:/usr/local/go/bin"
|
||||
fi
|
||||
if [[ "$DOCKER_NEEDS_RELOGIN" -eq 1 ]]; then
|
||||
echo " You were added to the 'docker' group. Log out and back in (or run"
|
||||
echo " 'newgrp docker') before docker works without sudo."
|
||||
fi
|
||||
echo " Then start the server with: ./owpengram-server.sh"
|
||||
Loading…
Add table
Add a link
Reference in a new issue