6bc922cabf
Server-side OpenSCAD renders STL from bundled hex_cell.scad with parameter
overrides via -D. Frontend is a Three.js viewer with auto-form generated
from /api/holder/params. 'Design busbars →' button posts the computed
cell coordinates to /api/projects and redirects to the busbar editor with
the holder cells pre-loaded.
- holder.py: openscad subprocess wrapper + compute_cells()
(Python mirror of get_hex_center_points_*)
- scad/hex_cell.scad: verbatim copy of Addy/Hex-Cell-Holder source
- app.py: /holder route + /api/holder/{params,render,cells}
- static/holder.html etc: parameter form + Three.js STL viewer
- Dockerfile / install.sh: apt install openscad
- static/index.html: nav link Holder ↔ Busbars in topbar
123 lines
4.7 KiB
Bash
123 lines
4.7 KiB
Bash
#!/usr/bin/env bash
|
|
# install.sh — install Busbar Designer on Debian / Ubuntu.
|
|
#
|
|
# Runs inside an LXC, VM, or bare-metal host. Idempotent (safe to re-run).
|
|
#
|
|
# Required env:
|
|
# REPO_URL Git URL of the busbar-designer repo
|
|
# (e.g. https://gitea.local/me/busbar-designer.git)
|
|
#
|
|
# Optional env:
|
|
# BRANCH git branch to track (default: main)
|
|
# INSTALL_DIR install location (default: /opt/busbar-designer)
|
|
# SVC_USER systemd service user (default: busbar)
|
|
# PORT HTTP port (default: 5000)
|
|
# GIT_SSL_NO_VERIFY=1 skip TLS verify for self-signed Gitea certs
|
|
|
|
set -euo pipefail
|
|
|
|
REPO_URL="${REPO_URL:-}"
|
|
BRANCH="${BRANCH:-main}"
|
|
INSTALL_DIR="${INSTALL_DIR:-/opt/busbar-designer}"
|
|
SVC_USER="${SVC_USER:-busbar}"
|
|
PORT="${PORT:-5000}"
|
|
|
|
# ---- helpers ---------------------------------------------------------------
|
|
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
|
|
log() { echo -e "${GREEN}▸${NC} $*"; }
|
|
warn() { echo -e "${YELLOW}!${NC} $*"; }
|
|
die() { echo -e "${RED}✗ $*${NC}" >&2; exit 1; }
|
|
|
|
[[ $EUID -eq 0 ]] || die "Run as root (or via sudo)."
|
|
[[ -n "$REPO_URL" ]] || die "REPO_URL is required (export REPO_URL=https://gitea.local/me/busbar-designer.git)"
|
|
|
|
if [[ "${GIT_SSL_NO_VERIFY:-0}" == "1" ]]; then
|
|
warn "GIT_SSL_NO_VERIFY=1 — skipping TLS verification for git."
|
|
export GIT_SSL_NO_VERIFY=true
|
|
fi
|
|
|
|
# ---- system packages -------------------------------------------------------
|
|
log "Installing system packages..."
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get update -qq
|
|
apt-get install -y -qq \
|
|
git ca-certificates curl \
|
|
python3 python3-venv python3-pip \
|
|
libgl1 libglu1-mesa libxrender1 libxext6 libsm6 libgomp1 \
|
|
openscad xvfb
|
|
|
|
# ---- service user ----------------------------------------------------------
|
|
if ! id "$SVC_USER" >/dev/null 2>&1; then
|
|
log "Creating service user '$SVC_USER'..."
|
|
useradd --system --create-home --shell /usr/sbin/nologin "$SVC_USER"
|
|
else
|
|
log "Service user '$SVC_USER' already exists."
|
|
fi
|
|
|
|
# ---- source tree -----------------------------------------------------------
|
|
mkdir -p "$(dirname "$INSTALL_DIR")"
|
|
|
|
if [[ -d "$INSTALL_DIR/.git" ]]; then
|
|
log "Updating existing checkout at $INSTALL_DIR..."
|
|
chown -R "$SVC_USER:$SVC_USER" "$INSTALL_DIR"
|
|
sudo -u "$SVC_USER" git -C "$INSTALL_DIR" remote set-url origin "$REPO_URL"
|
|
sudo -u "$SVC_USER" git -C "$INSTALL_DIR" fetch --depth 1 origin "$BRANCH"
|
|
sudo -u "$SVC_USER" git -C "$INSTALL_DIR" reset --hard "origin/$BRANCH"
|
|
else
|
|
log "Cloning $REPO_URL (branch $BRANCH) into $INSTALL_DIR..."
|
|
rm -rf "$INSTALL_DIR"
|
|
git clone --depth 1 --branch "$BRANCH" "$REPO_URL" "$INSTALL_DIR"
|
|
chown -R "$SVC_USER:$SVC_USER" "$INSTALL_DIR"
|
|
fi
|
|
|
|
# ---- virtualenv + python deps ---------------------------------------------
|
|
if [[ ! -x "$INSTALL_DIR/.venv/bin/python" ]]; then
|
|
log "Creating Python venv..."
|
|
sudo -u "$SVC_USER" python3 -m venv "$INSTALL_DIR/.venv"
|
|
fi
|
|
|
|
log "Installing Python dependencies (build123d pulls OpenCASCADE — may take a few minutes)..."
|
|
sudo -u "$SVC_USER" "$INSTALL_DIR/.venv/bin/pip" install --quiet --upgrade pip
|
|
sudo -u "$SVC_USER" "$INSTALL_DIR/.venv/bin/pip" install --quiet \
|
|
-r "$INSTALL_DIR/requirements.txt" gunicorn
|
|
|
|
# ---- data dir (for SQLite) -------------------------------------------------
|
|
sudo -u "$SVC_USER" mkdir -p "$INSTALL_DIR/data"
|
|
|
|
# ---- systemd unit ----------------------------------------------------------
|
|
log "Installing systemd unit..."
|
|
UNIT_SRC="$INSTALL_DIR/deploy/busbar-designer.service"
|
|
UNIT_DST="/etc/systemd/system/busbar-designer.service"
|
|
[[ -f "$UNIT_SRC" ]] || die "deploy/busbar-designer.service missing in the repo."
|
|
|
|
# Substitute paths / user / port into the unit.
|
|
sed -e "s|/opt/busbar-designer|$INSTALL_DIR|g" \
|
|
-e "s|User=busbar|User=$SVC_USER|g" \
|
|
-e "s|Group=busbar|Group=$SVC_USER|g" \
|
|
-e "s|--bind=0.0.0.0:5000|--bind=0.0.0.0:$PORT|g" \
|
|
-e "s|Environment=PORT=5000|Environment=PORT=$PORT|g" \
|
|
"$UNIT_SRC" > "$UNIT_DST"
|
|
|
|
systemctl daemon-reload
|
|
systemctl enable --now busbar-designer
|
|
sleep 2
|
|
|
|
if ! systemctl is-active --quiet busbar-designer; then
|
|
warn "Service is not active. Last 30 log lines:"
|
|
journalctl -u busbar-designer -n 30 --no-pager
|
|
die "Service failed to start."
|
|
fi
|
|
|
|
IP_ADDR=$(hostname -I 2>/dev/null | awk '{print $1}')
|
|
[[ -n "$IP_ADDR" ]] || IP_ADDR="$(hostname)"
|
|
|
|
echo
|
|
log "================================================================"
|
|
log " ✓ Busbar Designer installed."
|
|
log ""
|
|
log " URL: http://$IP_ADDR:$PORT"
|
|
log " Logs: journalctl -u busbar-designer -f"
|
|
log " Update: sudo bash $INSTALL_DIR/deploy/update.sh"
|
|
log " Backup: cp $INSTALL_DIR/data/busbar.db ..."
|
|
log "================================================================"
|