Initial commit: Busbar Designer

Web tool for designing nickel/copper busbars over cylindrical-cell battery
packs (21700, 18650) in hex holders. Flask + build123d backend exports
STEP/DXF/SVG; vanilla JS frontend with live preview, multi-project SQLite
persistence, snapshot history.

Deploy scripts in deploy/ (proxmox-lxc.sh, install.sh, update.sh).
This commit is contained in:
wenil
2026-05-24 18:59:50 +03:00
commit d8cb0dc06d
28 changed files with 4172 additions and 0 deletions
+195
View File
@@ -0,0 +1,195 @@
#!/usr/bin/env bash
# proxmox-lxc.sh — create an unprivileged Debian 12 LXC on a Proxmox VE host
# and install Busbar Designer into it. Inspired by the community-scripts style.
#
# Run on the Proxmox host as root, e.g.:
#
# bash -c "$(curl -fsSL https://gitea.local/me/busbar-designer/raw/branch/main/deploy/proxmox-lxc.sh)"
#
# Interactive whiptail prompts; or pre-set everything via env to skip prompts:
#
# REPO_URL=https://gitea.local/me/busbar-designer.git \
# CTID=210 HOSTNAME=busbar DISK_SIZE=4 CORES=2 RAM=1024 \
# BRIDGE=vmbr0 IP=dhcp STORAGE=local-lvm \
# bash proxmox-lxc.sh
set -euo pipefail
# ---- colors ----------------------------------------------------------------
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'
BLUE='\033[0;34m'; BOLD='\033[1m'; NC='\033[0m'
log() { echo -e "${GREEN}${NC} $*"; }
warn() { echo -e "${YELLOW}!${NC} $*"; }
die() { echo -e "${RED}$*${NC}" >&2; exit 1; }
banner() {
cat <<'EOF'
____ _ ____ _
| __ ) _ _ ___| |__ __ _ _ __ | _ \ ___ ___(_) __ _ _ __ ___ _ __
| _ \| | | / __| '_ \ / _` | '__| | | | |/ _ \/ __| |/ _` | '_ \ / _ \ '__|
| |_) | |_| \__ \ |_) | (_| | | | |_| | __/\__ \ | (_| | | | | __/ |
|____/ \__,_|___/_.__/ \__,_|_| |____/ \___||___/_|\__, |_| |_|\___|_|
|___/
Proxmox VE LXC installer
EOF
}
# ---- preflight -------------------------------------------------------------
[[ $EUID -eq 0 ]] || die "Run as root on the Proxmox host."
command -v pveversion >/dev/null 2>&1 || die "pveversion not found — is this a Proxmox VE host?"
command -v pct >/dev/null 2>&1 || die "pct not found — Proxmox VE tools missing?"
banner
# ---- defaults --------------------------------------------------------------
CTID_DEFAULT=$(pvesh get /cluster/nextid 2>/dev/null || echo "200")
CTID="${CTID:-$CTID_DEFAULT}"
HOSTNAME="${HOSTNAME:-busbar-designer}"
DISK_SIZE="${DISK_SIZE:-4}"
CORES="${CORES:-2}"
RAM="${RAM:-1024}"
SWAP="${SWAP:-512}"
BRIDGE="${BRIDGE:-vmbr0}"
IP="${IP:-dhcp}"
STORAGE="${STORAGE:-local-lvm}"
TEMPLATE_STORAGE="${TEMPLATE_STORAGE:-local}"
REPO_URL="${REPO_URL:-}"
BRANCH="${BRANCH:-main}"
GIT_SSL_NO_VERIFY="${GIT_SSL_NO_VERIFY:-0}"
# ---- interactive prompts (whiptail) ----------------------------------------
ask() {
local var="$1" prompt="$2" default="$3" h="${4:-8}" w="${5:-60}"
local val
if [[ -t 0 ]] && command -v whiptail >/dev/null 2>&1; then
val=$(whiptail --title "Busbar Designer" --inputbox "$prompt" "$h" "$w" "$default" \
3>&1 1>&2 2>&3) || die "Cancelled."
else
read -rp "$prompt [$default]: " val
val="${val:-$default}"
fi
printf -v "$var" '%s' "$val"
}
yesno() {
local prompt="$1" default="${2:-no}"
if [[ -t 0 ]] && command -v whiptail >/dev/null 2>&1; then
if [[ "$default" == "yes" ]]; then
whiptail --title "Busbar Designer" --yesno "$prompt" 8 60
else
whiptail --title "Busbar Designer" --yesno "$prompt" --defaultno 8 60
fi
else
read -rp "$prompt [$default]: " val
[[ "${val:-$default}" =~ ^(y|yes)$ ]]
fi
}
if [[ -z "$REPO_URL" ]] || [[ -t 0 ]]; then
ask CTID "Container ID" "$CTID"
ask HOSTNAME "Hostname" "$HOSTNAME"
ask DISK_SIZE "Root disk size (GB)" "$DISK_SIZE"
ask CORES "CPU cores" "$CORES"
ask RAM "RAM (MB)" "$RAM"
ask STORAGE "Storage pool for rootfs (e.g. local-lvm, local-zfs)" "$STORAGE" 8 70
ask BRIDGE "Network bridge" "$BRIDGE"
ask IP "IP config: 'dhcp' or 'a.b.c.d/24,gw=a.b.c.1'" "$IP" 8 70
ask REPO_URL "Git URL of busbar-designer repo (your Gitea / GitHub)" \
"${REPO_URL:-https://gitea.local/me/busbar-designer.git}" 10 70
ask BRANCH "Branch" "$BRANCH"
if yesno "Skip TLS verification for git? (only if your Gitea uses a self-signed cert)"; then
GIT_SSL_NO_VERIFY=1
fi
fi
[[ -n "$REPO_URL" ]] || die "REPO_URL is required."
# ---- template --------------------------------------------------------------
log "Looking for a Debian 12 template..."
TEMPLATE=$(pveam available --section system 2>/dev/null \
| awk '/debian-12-standard/ {print $2}' | sort -r | head -n 1)
[[ -n "$TEMPLATE" ]] || die "Couldn't find debian-12-standard in 'pveam available'. Run 'pveam update' first."
LOCAL_TEMPLATE="/var/lib/vz/template/cache/$TEMPLATE"
if [[ ! -f "$LOCAL_TEMPLATE" ]]; then
log "Downloading template $TEMPLATE..."
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE"
fi
# ---- create LXC ------------------------------------------------------------
if pct status "$CTID" >/dev/null 2>&1; then
die "Container $CTID already exists. Pick a different CTID."
fi
PASSWORD="$(openssl rand -base64 12 | tr -d '/+=' | cut -c1-16)"
if [[ "$IP" == "dhcp" ]]; then
NET="name=eth0,bridge=$BRIDGE,ip=dhcp"
else
NET="name=eth0,bridge=$BRIDGE,ip=$IP"
fi
log "Creating LXC $CTID ($HOSTNAME)..."
pct create "$CTID" "$TEMPLATE_STORAGE:vztmpl/$TEMPLATE" \
--hostname "$HOSTNAME" \
--cores "$CORES" \
--memory "$RAM" \
--swap "$SWAP" \
--rootfs "$STORAGE:$DISK_SIZE" \
--net0 "$NET" \
--password "$PASSWORD" \
--features nesting=1 \
--unprivileged 1 \
--onboot 1 \
--start 1 \
--description "Busbar Designer · $REPO_URL ($BRANCH)" >/dev/null
# ---- wait for network ------------------------------------------------------
log "Waiting for network in CT $CTID..."
for i in {1..30}; do
if pct exec "$CTID" -- bash -c "getent hosts deb.debian.org >/dev/null" 2>/dev/null; then
break
fi
sleep 2
done
# ---- run installer inside the LXC ------------------------------------------
log "Bootstrapping git + curl in the container..."
pct exec "$CTID" -- bash -c "
set -e
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get install -y -qq git ca-certificates curl
" || die "Failed to install bootstrap packages in CT."
log "Cloning repo and running deploy/install.sh inside CT $CTID..."
pct exec "$CTID" -- bash -c "
set -e
${GIT_SSL_NO_VERIFY:+export GIT_SSL_NO_VERIFY=true}
rm -rf /opt/busbar-designer
git clone --depth 1 -b '$BRANCH' '$REPO_URL' /opt/busbar-designer
REPO_URL='$REPO_URL' BRANCH='$BRANCH' \
${GIT_SSL_NO_VERIFY:+GIT_SSL_NO_VERIFY=1} \
bash /opt/busbar-designer/deploy/install.sh
" || die "Installer failed. Inspect with: pct enter $CTID"
# ---- report ---------------------------------------------------------------
IP_ADDR=$(pct exec "$CTID" -- bash -c "hostname -I | awk '{print \$1}'" 2>/dev/null || true)
[[ -n "$IP_ADDR" ]] || IP_ADDR="<unknown — check 'pct exec $CTID -- ip a'>"
echo
log "================================================================"
log " ${BOLD}✓ Busbar Designer LXC ready${NC}"
log ""
log " Container ID: $CTID"
log " Hostname: $HOSTNAME"
log " Root password: $PASSWORD"
log " URL: http://$IP_ADDR:5000"
log ""
log " Update: pct exec $CTID -- bash /opt/busbar-designer/deploy/update.sh"
log " Logs: pct exec $CTID -- journalctl -u busbar-designer -f"
log " Enter: pct enter $CTID"
log " Backup: pct exec $CTID -- cat /opt/busbar-designer/data/busbar.db > backup.db"
log "================================================================"