Refactor user group management and add container detection warnings for udev rules

This commit is contained in:
Lloyd
2026-02-24 09:15:21 +00:00
parent 540e5f11fe
commit 4d2943087f
3 changed files with 48 additions and 8 deletions
+29 -7
View File
@@ -233,9 +233,9 @@ install_repeater() {
fi
echo "10"; echo "# Adding user to hardware groups..."
usermod -a -G gpio,i2c,spi "$SERVICE_USER" 2>/dev/null || true
usermod -a -G dialout "$SERVICE_USER" 2>/dev/null || true
usermod -a -G plugdev "$SERVICE_USER" 2>/dev/null || true
for grp in plugdev dialout gpio i2c spi; do
getent group "$grp" >/dev/null 2>&1 && usermod -a -G "$grp" "$SERVICE_USER" 2>/dev/null || true
done
echo "20"; echo "# Creating directories..."
mkdir -p "$INSTALL_DIR" "$CONFIG_DIR" "$LOG_DIR" /var/lib/pymc_repeater
@@ -402,6 +402,23 @@ EOF
echo " • Set admin password"
echo " 3. Log in to your configured repeater"
echo ""
# Container detection: warn about host-side udev rules
if [ -f /run/host/container-manager ] || [ -n "${container:-}" ] || grep -qsai 'container=' /proc/1/environ 2>/dev/null || [ -f /.dockerenv ]; then
echo "═══════════════════════════════════════════════════════════════"
echo " ⚠ CONTAINER ENVIRONMENT DETECTED"
echo "═══════════════════════════════════════════════════════════════"
echo ""
echo " USB device udev rules do NOT work inside containers."
echo " You MUST install the CH341 udev rule on the HOST machine:"
echo ""
echo " echo 'SUBSYSTEM==\"usb\", ATTR{idVendor}==\"1a86\", ATTR{idProduct}==\"5512\", MODE=\"0666\"' \\"
echo " | sudo tee /etc/udev/rules.d/99-ch341.rules"
echo " sudo udevadm control --reload-rules"
echo " sudo udevadm trigger --subsystem-match=usb --action=change"
echo ""
echo " Then unplug and replug the CH341 USB adapter."
echo ""
fi
echo "═══════════════════════════════════════════════════════════════"
echo ""
read -p "Press Enter to return to main menu..." || true
@@ -562,9 +579,9 @@ upgrade_repeater() {
fi
echo "[5.5/9] Ensuring user groups and udev rules..."
usermod -a -G gpio,i2c,spi "$SERVICE_USER" 2>/dev/null || true
usermod -a -G dialout "$SERVICE_USER" 2>/dev/null || true
usermod -a -G plugdev "$SERVICE_USER" 2>/dev/null || true
for grp in plugdev dialout gpio i2c spi; do
getent group "$grp" >/dev/null 2>&1 && usermod -a -G "$grp" "$SERVICE_USER" 2>/dev/null || true
done
# Install/update CH341 udev rules
SCRIPT_DIR_UPGRADE="$(cd "$(dirname "$0")" && pwd)"
if [ -f "$SCRIPT_DIR_UPGRADE/../pyMC_core/99-ch341.rules" ]; then
@@ -656,7 +673,12 @@ EOF
if is_running; then
echo " ✓ Service is running"
show_info "Upgrade Complete" "Upgrade completed successfully!\n\nVersion: $current_version$new_version\n\n✓ Service is running\n✓ Configuration preserved"
# Container detection: warn about host-side udev rules
local container_note=""
if [ -f /run/host/container-manager ] || [ -n "${container:-}" ] || grep -qsai 'container=' /proc/1/environ 2>/dev/null || [ -f /.dockerenv ]; then
container_note="\n\n⚠ CONTAINER DETECTED:\nUSB udev rules must be set on the HOST, not here.\nSee documentation for CH341 host-side setup."
fi
show_info "Upgrade Complete" "Upgrade completed successfully!\n\nVersion: $current_version$new_version\n\n✓ Service is running\n✓ Configuration preserved${container_note}"
else
echo " ✗ Service failed to start"
show_error "Upgrade completed but service failed to start!\n\nVersion updated: $current_version$new_version\n\nCheck logs from the main menu for details."
+1 -1
View File
@@ -31,7 +31,7 @@ SyslogIdentifier=pymc-repeater
# Security (relaxed for proper operation)
NoNewPrivileges=true
ReadWritePaths=/var/log/pymc_repeater /var/lib/pymc_repeater /etc/pymc_repeater
SupplementaryGroups=plugdev dialout gpio i2c spi
SupplementaryGroups=plugdev dialout
[Install]
WantedBy=multi-user.target
+18
View File
@@ -491,10 +491,28 @@ class RepeaterDaemon:
except Exception as e:
logger.debug(f"CH341 reset skipped/failed: {e}")
@staticmethod
def _detect_container() -> bool:
"""Detect if running inside an LXC/Docker/systemd-nspawn container."""
try:
with open("/proc/1/environ", "rb") as f:
if b"container=" in f.read():
return True
except (OSError, PermissionError):
pass
return os.path.exists("/run/host/container-manager")
async def run(self):
logger.info("Repeater daemon started")
# Warn if running inside a container (udev rules won't work here)
if os.path.exists("/.dockerenv") or os.environ.get("container") or self._detect_container():
logger.warning(
"Container environment detected. "
"USB device udev rules must be configured on the HOST, not inside this container."
)
try:
await self.initialize()