|
#!/usr/bin/env bash |
|
# Proxmox LXC CUPS Print Server Setup Script (Hotplug Resilient) |
|
# Run this script on your Proxmox host as root. |
|
# Gist Description: Automates the creation of an unprivileged Debian LXC container on Proxmox, passing through a USB printer, configuring CUPS + Avahi, and enabling robust hotplug support. |
|
|
|
set -e |
|
|
|
# ================= Configuration ================= |
|
CTID=111 |
|
TEMPLATE="local:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst" |
|
STORAGE="local-lvm" |
|
|
|
# Samsung SCX-4300 IDs |
|
USB_VENDOR="04e8" |
|
USB_PRODUCT="342e" |
|
|
|
PRINTER_NAME="Samsung_SCX-4300" |
|
CUPS_DRIVER="drv:///splix-samsung.drv/scx4300.ppd" |
|
CUPS_ADMIN_PASS="printadmin" |
|
|
|
HOTPLUG_SCRIPT="/usr/local/bin/update-printer-lxc.sh" |
|
# ================================================= |
|
|
|
echo "==> Finding USB Printer ($USB_VENDOR:$USB_PRODUCT)..." |
|
USB_INFO=$(lsusb | grep -i "${USB_VENDOR}:${USB_PRODUCT}") || true |
|
|
|
if [ -z "$USB_INFO" ]; then |
|
echo "Error: Samsung printer not found on USB bus." |
|
exit 1 |
|
fi |
|
|
|
BUS=$(echo "$USB_INFO" | awk '{print $2}') |
|
DEV=$(echo "$USB_INFO" | awk '{print $4}' | tr -d ':') |
|
USB_PATH="/dev/bus/usb/$BUS/$DEV" |
|
|
|
echo "==> Creating LXC Container $CTID on $STORAGE..." |
|
pct create $CTID $TEMPLATE \ |
|
--rootfs ${STORAGE}:8 \ |
|
--ostype debian \ |
|
--memory 512 \ |
|
--cores 1 \ |
|
--net0 name=eth0,bridge=vmbr0,ip=dhcp \ |
|
--hostname cups-server \ |
|
--unprivileged 1 \ |
|
--ssh-public-keys /root/.ssh/authorized_keys || echo "Container might already exist." |
|
|
|
echo "==> Configuring Initial USB Passthrough for $USB_PATH..." |
|
pct set $CTID -dev0 ${USB_PATH},uid=0,gid=7,mode=0660 |
|
|
|
echo "==> Starting Container $CTID..." |
|
pct start $CTID |
|
|
|
echo "==> Waiting for container network to initialize..." |
|
lxc-attach -n $CTID -- bash -c 'while ! ping -c 1 -W 1 1.1.1.1 &>/dev/null; do sleep 1; done' |
|
|
|
echo "==> Setting root password for CUPS web interface..." |
|
echo "root:${CUPS_ADMIN_PASS}" | lxc-attach -n $CTID -- chpasswd |
|
|
|
echo "==> Installing CUPS, Avahi (mDNS/AirPrint), and SpliX drivers..." |
|
lxc-attach -n $CTID -- apt-get update |
|
lxc-attach -n $CTID -- apt-get install -y cups printer-driver-splix avahi-daemon |
|
lxc-attach -n $CTID -- systemctl enable --now cups avahi-daemon |
|
|
|
echo "==> Configuring CUPS network access..." |
|
lxc-attach -n $CTID -- cupsctl --remote-admin --remote-any --share-printers |
|
|
|
echo "==> Discovering actual printer URI inside CUPS..." |
|
PRINTER_URI=$(lxc-attach -n $CTID -- lpinfo -v | grep -i 'usb://' | awk '{print $2}' | head -n 1) |
|
|
|
if [ -n "$PRINTER_URI" ]; then |
|
echo "==> Adding and sharing printer in CUPS..." |
|
lxc-attach -n $CTID -- lpadmin -p $PRINTER_NAME -E -v "$PRINTER_URI" -m "$CUPS_DRIVER" -D "Samsung SCX-4300 Shared" -o printer-is-shared=true |
|
lxc-attach -n $CTID -- lpoptions -d $PRINTER_NAME |
|
else |
|
echo "Warning: Printer URI not found immediately. Hotplug script will handle it." |
|
fi |
|
|
|
echo "==> Setting up automated Hotplug (udev) Support..." |
|
cat << EOF > $HOTPLUG_SCRIPT |
|
#!/bin/bash |
|
sleep 2 |
|
USB_INFO=\$(lsusb | grep -i "${USB_VENDOR}:${USB_PRODUCT}" | head -n 1) |
|
if [ -n "\$USB_INFO" ]; then |
|
BUS=\$(echo "\$USB_INFO" | awk '{print \$2}') |
|
DEV=\$(echo "\$USB_INFO" | awk '{print \$4}' | tr -d ':') |
|
NEW_PATH="/dev/bus/usb/\$BUS/\$DEV" |
|
# Update LXC config dynamically and restart container to apply device nodes |
|
pct set $CTID -dev0 \${NEW_PATH},uid=0,gid=7,mode=0660 |
|
pct reboot $CTID |
|
fi |
|
EOF |
|
chmod +x $HOTPLUG_SCRIPT |
|
|
|
echo "ACTION==\"add\", SUBSYSTEM==\"usb\", ATTR{idVendor}==\"${USB_VENDOR}\", ATTR{idProduct}==\"${USB_PRODUCT}\", RUN+=\"${HOTPLUG_SCRIPT}\"" > /etc/udev/rules.d/99-samsung-printer.rules |
|
udevadm control --reload-rules |
|
|
|
IP_ADDR=$(lxc-attach -n $CTID -- hostname -I | awk '{print $1}') |
|
echo "==========================================================" |
|
echo "SUCCESS!" |
|
echo "CUPS Print Server is running at: https://${IP_ADDR}:631" |
|
echo "Login credentials for Web UI: root / ${CUPS_ADMIN_PASS}" |
|
echo "==========================================================" |