Files
pyMC_Repeater/scripts/proxmox-install.sh

264 lines
12 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# pyMC Repeater - Proxmox LXC Installer
# Creates an LXC container with USB passthrough and installs pyMC Repeater
#
# Usage (run on the Proxmox host):
# bash -c "$(curl -fsSL https://raw.githubusercontent.com/rightup/pyMC_Repeater/main/scripts/proxmox-install.sh)"
#
# License: MIT
# Source: https://github.com/rightup/pyMC_Repeater
set -euo pipefail
# ── Defaults ───────────────────────────────────────────────────────────────
REPO="https://github.com/rightup/pyMC_Repeater.git"
BRANCH="feat/newRadios"
CT_TEMPLATE="debian-12-standard"
CT_RAM=1024
CT_SWAP=512
CT_DISK=4
CT_CORES=2
CT_HOSTNAME="pymc-repeater"
CT_BRIDGE="vmbr0"
CT_STORAGE="local-lvm"
CT_TEMPLATE_STORAGE="local"
CH341_VID="1a86"
CH341_PID="5512"
# ── Colors ─────────────────────────────────────────────────────────────────
RD="\033[01;31m" GN="\033[1;92m" YW="\033[33m" BL="\033[36m" BLD="\033[1m" CL="\033[m"
msg_info() { echo -e " ${BL}${CL} ${1}"; }
msg_ok() { echo -e " ${GN}${CL} ${1}"; }
msg_warn() { echo -e " ${YW}${CL} ${1}"; }
msg_error() { echo -e " ${RD}${CL} ${1}"; }
header() {
clear
echo -e "${BLD}"
echo "═══════════════════════════════════════════════════════════════"
echo " pyMC Repeater - Proxmox LXC Installer"
echo "═══════════════════════════════════════════════════════════════"
echo -e "${CL}"
}
cleanup() {
local exit_code=$?
if [ $exit_code -ne 0 ] && [ -n "${CTID:-}" ] && pct status "$CTID" &>/dev/null; then
echo ""
read -p " Delete the failed container ${CTID}? [y/N]: " -r
if [[ "$REPLY" =~ ^[Yy]$ ]]; then
pct stop "$CTID" 2>/dev/null || true
pct destroy "$CTID" 2>/dev/null || true
msg_ok "Container ${CTID} removed"
fi
fi
}
trap cleanup EXIT
# ── Preflight checks ──────────────────────────────────────────────────────
header
if ! command -v pct &>/dev/null; then
msg_error "This script must be run on a Proxmox VE host."
exit 1
fi
if [ "$EUID" -ne 0 ]; then
msg_error "Please run as root"
exit 1
fi
msg_ok "Running on Proxmox host as root"
# Check for CH341
echo ""
if lsusb -d "${CH341_VID}:${CH341_PID}" &>/dev/null; then
msg_ok "CH341 USB device detected"
else
msg_warn "CH341 USB device not found — plug it in before starting the repeater"
fi
# ── Interactive settings ──────────────────────────────────────────────────
echo ""
echo -e "${BLD}Container Settings${CL} (press Enter for defaults):"
echo ""
read -p " Hostname [${CT_HOSTNAME}]: " -r input; CT_HOSTNAME="${input:-$CT_HOSTNAME}"
read -p " RAM in MB [${CT_RAM}]: " -r input; CT_RAM="${input:-$CT_RAM}"
read -p " Disk in GB [${CT_DISK}]: " -r input; CT_DISK="${input:-$CT_DISK}"
read -p " CPU cores [${CT_CORES}]: " -r input; CT_CORES="${input:-$CT_CORES}"
read -p " Bridge [${CT_BRIDGE}]: " -r input; CT_BRIDGE="${input:-$CT_BRIDGE}"
AVAILABLE_STORAGES=$(pvesm status -content rootdir 2>/dev/null | awk 'NR>1 {print $1}' || echo "local-lvm")
echo " Available storages: ${AVAILABLE_STORAGES}"
read -p " Storage [${CT_STORAGE}]: " -r input; CT_STORAGE="${input:-$CT_STORAGE}"
read -p " Git branch [${BRANCH}]: " -r input; BRANCH="${input:-$BRANCH}"
read -sp " Root password [pymc]: " CT_PASSWORD; echo
CT_PASSWORD="${CT_PASSWORD:-pymc}"
# ── Get next CTID ─────────────────────────────────────────────────────────
CTID=$(pvesh get /cluster/nextid)
# ── Confirmation ──────────────────────────────────────────────────────────
echo ""
echo -e "${BLD}Summary:${CL}"
echo " CTID: ${CTID} Host: ${CT_HOSTNAME} RAM: ${CT_RAM}MB Disk: ${CT_DISK}GB"
echo " Cores: ${CT_CORES} Storage: ${CT_STORAGE} Bridge: ${CT_BRIDGE} Branch: ${BRANCH}"
echo " Mode: privileged (required for USB passthrough)"
echo ""
read -p " Proceed? [Y/n]: " -r
[[ "${REPLY:-Y}" =~ ^[Nn]$ ]] && { msg_warn "Aborted"; exit 0; }
# ── Download template ─────────────────────────────────────────────────────
echo ""
msg_info "Downloading Debian 12 template..."
TEMPLATE_FILE=$(pveam available -section system 2>/dev/null | grep "${CT_TEMPLATE}" | sort -t- -k4 -V | tail -1 | awk '{print $2}')
[ -z "$TEMPLATE_FILE" ] && { msg_error "Template not found. Run: pveam update"; exit 1; }
pveam list "$CT_TEMPLATE_STORAGE" 2>/dev/null | grep -q "$TEMPLATE_FILE" || \
pveam download "$CT_TEMPLATE_STORAGE" "$TEMPLATE_FILE"
msg_ok "Template ready"
# ── Create container ──────────────────────────────────────────────────────
msg_info "Creating LXC container ${CTID}..."
pct create "$CTID" "${CT_TEMPLATE_STORAGE}:vztmpl/${TEMPLATE_FILE}" \
--hostname "$CT_HOSTNAME" \
--memory "$CT_RAM" \
--swap "$CT_SWAP" \
--cores "$CT_CORES" \
--rootfs "${CT_STORAGE}:${CT_DISK}" \
--net0 "name=eth0,bridge=${CT_BRIDGE},ip=dhcp" \
--unprivileged 0 \
--features nesting=1 \
--onboot 1 \
--start 0 \
--password "$CT_PASSWORD" \
--ostype debian
msg_ok "Container created"
# ── USB passthrough ───────────────────────────────────────────────────────
msg_info "Configuring USB passthrough..."
cat >> "/etc/pve/lxc/${CTID}.conf" <<'EOF'
# CH341 USB passthrough for pyMC Repeater
lxc.cgroup2.devices.allow: c 189:* rwm
lxc.mount.entry: /dev/bus/usb dev/bus/usb none bind,optional,create=dir 0 0
EOF
msg_ok "USB passthrough configured"
# ── Host udev rule ────────────────────────────────────────────────────────
msg_info "Installing CH341 udev rule on host..."
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="1a86", ATTR{idProduct}=="5512", MODE="0666"' \
> /etc/udev/rules.d/99-ch341.rules
udevadm control --reload-rules
udevadm trigger --subsystem-match=usb --action=change
msg_ok "Host udev rule installed"
# ── Start container & wait for network ────────────────────────────────────
msg_info "Starting container..."
pct start "$CTID"
sleep 3
for _ in $(seq 1 30); do
pct exec "$CTID" -- ping -c1 -W1 8.8.8.8 &>/dev/null && break
sleep 1
done
msg_ok "Container running with network"
# ── Bootstrap: install git, clone repo ────────────────────────────────────
msg_info "Installing git inside container..."
pct exec "$CTID" -- bash -c "
export DEBIAN_FRONTEND=noninteractive
# Fix locale warnings
apt-get update -qq
apt-get install -y locales >/dev/null 2>&1
sed -i 's/# en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen
locale-gen >/dev/null 2>&1
echo 'LANG=en_US.UTF-8' > /etc/default/locale
apt-get install -y git whiptail >/dev/null 2>&1
# Enable auto-login on console (no password prompt in Proxmox web console)
mkdir -p /etc/systemd/system/container-getty@1.service.d
cat > /etc/systemd/system/container-getty@1.service.d/override.conf <<'AUTOLOGIN'
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM
AUTOLOGIN
systemctl daemon-reload
# Login banner with system info
cat > /etc/profile.d/pymc-motd.sh <<'MOTD'
#!/bin/sh
HOSTNAME=\$(hostname)
IP=\$(hostname -I | awk '{print \$1}')
OS=\$(. /etc/os-release && echo \"\$NAME\")
VER=\$(. /etc/os-release && echo \"\$VERSION_ID\")
echo \"\"
echo \" pyMC Repeater LXC Container\"
echo \" 🌐 GitHub: https://github.com/rightup/pyMC_Repeater\"
echo \"\"
echo \" 🖥️ OS: \$OS - Version: \$VER\"
echo \" 🏠 Hostname: \$HOSTNAME\"
echo \" 💡 IP Address: \$IP\"
echo \" 📡 Dashboard: http://\$IP:8000\"
echo \"\"
echo \" Management: cd /opt/pymc_repeater && bash manage.sh\"
echo \"\"
MOTD
chmod +x /etc/profile.d/pymc-motd.sh
"
msg_ok "Git installed, locale fixed, console auto-login enabled"
msg_info "Cloning pyMC_Repeater (branch: ${BRANCH})..."
pct exec "$CTID" -- bash -c "git clone --branch ${BRANCH} ${REPO} /root/pyMC_Repeater"
msg_ok "Repository cloned"
# Pre-seed config with CH341 radio type and correct GPIO pins
pct exec "$CTID" -- bash -c "
mkdir -p /etc/pymc_repeater
if [ -f /root/pyMC_Repeater/config.yaml.example ]; then
cp /root/pyMC_Repeater/config.yaml.example /etc/pymc_repeater/config.yaml
# Set radio type to CH341
sed -i 's/^radio_type: sx1262$/radio_type: sx1262_ch341/' /etc/pymc_repeater/config.yaml
# Replace Pi BCM GPIO pins with CH341 GPIO pin numbers (0-7)
sed -i 's/cs_pin: 21/cs_pin: 0/' /etc/pymc_repeater/config.yaml
sed -i 's/reset_pin: 18/reset_pin: 2/' /etc/pymc_repeater/config.yaml
sed -i 's/busy_pin: 20/busy_pin: 4/' /etc/pymc_repeater/config.yaml
sed -i 's/irq_pin: 16/irq_pin: 6/' /etc/pymc_repeater/config.yaml
sed -i 's/rxen_pin: -1/rxen_pin: 1/' /etc/pymc_repeater/config.yaml
# Enable TCXO and DIO2 RF switch for E22 module
sed -i 's/use_dio3_tcxo: false/use_dio3_tcxo: true/' /etc/pymc_repeater/config.yaml
sed -i 's/use_dio2_rf: false/use_dio2_rf: true/' /etc/pymc_repeater/config.yaml
fi
"
# ── Run manage.sh install ─────────────────────────────────────────────────
msg_info "Running manage.sh install (this will take several minutes)..."
echo ""
# Use lxc-attach with a pty so manage.sh gets an interactive terminal
lxc-attach -n "$CTID" -- bash -c "cd /root/pyMC_Repeater && TERM=xterm bash manage.sh install"
echo ""
msg_ok "manage.sh install completed"
# ── Get container IP ──────────────────────────────────────────────────────
sleep 2
CT_IP=$(pct exec "$CTID" -- hostname -I 2>/dev/null | awk '{print $1}')
# ── Done ──────────────────────────────────────────────────────────────────
echo ""
echo -e "${BLD}"
echo "═══════════════════════════════════════════════════════════════"
echo " ✓ pyMC Repeater Installation Complete!"
echo "═══════════════════════════════════════════════════════════════"
echo -e "${CL}"
echo -e " Container: ${GN}${CTID}${CL} (${CT_HOSTNAME})"
echo -e " IP Address: ${GN}${CT_IP:-unknown}${CL}"
echo -e " Dashboard: ${GN}http://${CT_IP:-<ip>}:8000${CL}"
echo ""
echo " Next: open the dashboard and complete the setup wizard"
echo " Management: pct enter ${CTID}, then: cd /opt/pymc_repeater && bash manage.sh"
echo ""
echo "═══════════════════════════════════════════════════════════════"