142 lines
4.1 KiB
Bash
Executable File
142 lines
4.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Shared helpers for GREE Controller operational scripts.
|
|
set -Eeuo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
SERVICE_NAME="gree-controller.service"
|
|
SERVICE_USER="gree-controller"
|
|
SERVICE_GROUP="gree-controller"
|
|
INSTALL_DIR="/opt/gree-controller"
|
|
INSTALL_BINARY="$INSTALL_DIR/gree-controller"
|
|
DATA_DIR="/var/lib/gree-controller"
|
|
ENV_FILE="/etc/gree-controller.env"
|
|
SERVICE_FILE="/etc/systemd/system/$SERVICE_NAME"
|
|
BACKUP_ROOT="/var/backups/gree-controller"
|
|
|
|
say() { printf '\033[1;32m==>\033[0m %s\n' "$*"; }
|
|
warn() { printf '\033[1;33mWARNING:\033[0m %s\n' "$*" >&2; }
|
|
fail() { printf '\033[1;31mERROR:\033[0m %s\n' "$*" >&2; exit 1; }
|
|
|
|
require_root() {
|
|
[[ ${EUID:-$(id -u)} -eq 0 ]] || fail "Run this script as root (for example: sudo $0)."
|
|
}
|
|
|
|
require_systemd() {
|
|
command -v systemctl >/dev/null 2>&1 || fail "systemd/systemctl is required for the LXC installation."
|
|
}
|
|
|
|
run_privileged() {
|
|
if [[ ${EUID:-$(id -u)} -eq 0 ]]; then
|
|
"$@"
|
|
elif command -v sudo >/dev/null 2>&1; then
|
|
sudo "$@"
|
|
else
|
|
fail "Root/sudo privileges are required: $*"
|
|
fi
|
|
}
|
|
|
|
install_build_dependencies() {
|
|
local missing=0
|
|
for cmd in curl cc make pkg-config; do
|
|
command -v "$cmd" >/dev/null 2>&1 || missing=1
|
|
done
|
|
command -v python3 >/dev/null 2>&1 || missing=1
|
|
[[ "$missing" -eq 1 ]] || return 0
|
|
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
say "Installing build dependencies"
|
|
run_privileged apt-get update
|
|
run_privileged apt-get install -y --no-install-recommends \
|
|
build-essential curl ca-certificates pkg-config python3
|
|
elif command -v dnf >/dev/null 2>&1; then
|
|
say "Installing build dependencies"
|
|
run_privileged dnf install -y gcc gcc-c++ make curl ca-certificates pkgconf-pkg-config python3
|
|
elif command -v apk >/dev/null 2>&1; then
|
|
say "Installing build dependencies"
|
|
run_privileged apk add --no-cache build-base curl ca-certificates pkgconf python3
|
|
else
|
|
fail "Unsupported package manager. Install a C compiler, make, curl, pkg-config, Python 3 and CA certificates."
|
|
fi
|
|
}
|
|
|
|
build_web_assets_if_available() {
|
|
local tailwind="$PROJECT_ROOT/node_modules/.bin/tailwindcss"
|
|
if [[ -x "$tailwind" ]]; then
|
|
"$PROJECT_ROOT/scripts/build-web.sh"
|
|
else
|
|
say "Using committed offline Web UI CSS (web/styles.css)"
|
|
fi
|
|
}
|
|
|
|
ensure_rust() {
|
|
if command -v cargo >/dev/null 2>&1; then
|
|
return 0
|
|
fi
|
|
command -v curl >/dev/null 2>&1 || fail "curl is required to install Rust."
|
|
say "Installing stable Rust with rustup"
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
|
|
export PATH="${CARGO_HOME:-$HOME/.cargo}/bin:$PATH"
|
|
command -v cargo >/dev/null 2>&1 || fail "Cargo is unavailable after rustup installation."
|
|
}
|
|
|
|
project_version() {
|
|
awk '
|
|
/^\[package\]/ { package=1; next }
|
|
/^\[/ && package { exit }
|
|
package && /^version[[:space:]]*=/ {
|
|
gsub(/.*=[[:space:]]*"|".*/, "", $0); print; exit
|
|
}
|
|
' "$PROJECT_ROOT/Cargo.toml"
|
|
}
|
|
|
|
read_env_value() {
|
|
local key="$1" default_value="${2:-}" value=""
|
|
if [[ -f "$ENV_FILE" ]]; then
|
|
value="$(grep -E "^[[:space:]]*${key}=" "$ENV_FILE" | tail -n1 | cut -d= -f2- || true)"
|
|
value="${value%\"}"; value="${value#\"}"
|
|
value="${value%\'}"; value="${value#\'}"
|
|
fi
|
|
printf '%s' "${value:-$default_value}"
|
|
}
|
|
|
|
health_url() {
|
|
local bind port
|
|
bind="$(read_env_value GREE_CONTROLLER_BIND '0.0.0.0:8787')"
|
|
port="${bind##*:}"
|
|
printf 'http://127.0.0.1:%s/api/health' "$port"
|
|
}
|
|
|
|
database_path() {
|
|
local db
|
|
db="$(read_env_value GREE_CONTROLLER_DATABASE "$DATA_DIR/gree-controller.db")"
|
|
if [[ "$db" != /* ]]; then
|
|
db="$DATA_DIR/$db"
|
|
fi
|
|
printf '%s' "$db"
|
|
}
|
|
|
|
panel_url() {
|
|
local bind port ip
|
|
bind="$(read_env_value GREE_CONTROLLER_BIND '0.0.0.0:8787')"
|
|
port="${bind##*:}"
|
|
ip="$(hostname -I 2>/dev/null | awk '{print $1}')"
|
|
printf 'http://%s:%s' "${ip:-LXC_ADDRESS}" "$port"
|
|
}
|
|
|
|
wait_for_health() {
|
|
local url attempts="${1:-60}"
|
|
url="$(health_url)"
|
|
for _ in $(seq 1 "$attempts"); do
|
|
if curl -fsS --max-time 2 "$url" >/dev/null 2>&1; then
|
|
return 0
|
|
fi
|
|
sleep 0.5
|
|
done
|
|
return 1
|
|
}
|
|
|
|
backup_timestamp() {
|
|
date -u +'%Y%m%dT%H%M%SZ'
|
|
}
|