Files
sensorpajen/debian/postinst
Fredrik Wahlberg 773453bd51 Fix Bluetooth permission error with AmbientCapabilities and enhanced postinst
- Add AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN to systemd service files
- Add sensorpajen user to bluetooth group in postinst
- Improve setcap error handling in postinst with clearer messaging
- Add comprehensive troubleshooting section for Bluetooth permission errors

This fixes the 'Operation not permitted' error when the service tries to
access Bluetooth hardware. The fix uses two layers of protection:
1. systemd AmbientCapabilities (modern, robust)
2. File capabilities via setcap (traditional, wider compatibility)
2026-02-20 08:57:28 +01:00

174 lines
7.4 KiB
Bash
Executable File

#!/bin/bash
set -e
case "$1" in
configure)
# Create sensorpajen system user if it doesn't exist
if ! getent passwd sensorpajen > /dev/null; then
useradd --system --no-create-home --shell /usr/sbin/nologin sensorpajen
echo "Created system user: sensorpajen"
fi
# Add sensorpajen user to bluetooth group if it exists (for BLE access)
if getent group bluetooth > /dev/null; then
usermod -aG bluetooth sensorpajen || true
echo "Added sensorpajen user to bluetooth group"
fi
# Create config directory with proper permissions
mkdir -p /etc/sensorpajen
chown sensorpajen:sensorpajen /etc/sensorpajen
chmod 750 /etc/sensorpajen
# Create state directory with proper permissions (writable at runtime)
mkdir -p /var/lib/sensorpajen
chown sensorpajen:sensorpajen /var/lib/sensorpajen
chmod 750 /var/lib/sensorpajen
# Copy example configs to /etc/sensorpajen if they don't exist
for sample in sensorpajen.env.example sensors.json.example; do
source_file="/usr/share/doc/sensorpajen/examples/$sample"
target_file="/etc/sensorpajen/${sample%.example}"
if [ -f "$source_file" ] && [ ! -f "$target_file" ]; then
cp "$source_file" "$target_file"
chown sensorpajen:sensorpajen "$target_file"
# Set restrictive permissions on env file (contains credentials)
if [ "$sample" = "sensorpajen.env.example" ]; then
chmod 600 "$target_file"
echo "Created $target_file (edit this file with your MQTT credentials)"
else
chmod 640 "$target_file"
echo "Created $target_file"
fi
fi
done
# Create virtual environment in /opt/sensorpajen
cd /opt/sensorpajen
if [ ! -d "venv" ]; then
echo "Creating Python virtual environment..."
python3 -m venv venv
venv/bin/pip install --upgrade pip setuptools wheel
fi
# Install Python dependencies from requirements.txt
echo "Installing Python dependencies..."
if [ -f "/opt/sensorpajen/requirements.txt" ]; then
venv/bin/pip install -r /opt/sensorpajen/requirements.txt
else
echo "Warning: requirements.txt not found, installing bluepy and paho-mqtt directly"
venv/bin/pip install bluepy paho-mqtt pybluez
fi
if [ $? -ne 0 ]; then
echo "Error: Failed to install dependencies"
exit 1
fi
# Install sensorpajen package itself
echo "Installing sensorpajen application..."
cd /opt/sensorpajen
# Clean up any stale bytecode before building wheel
find . -name "*.pyc" -delete
find . -name "__pycache__" -type d -delete
venv/bin/pip install --no-deps . || {
echo "Error: Failed to install sensorpajen package"
exit 1
}
cd /
# Set ownership of application directory BEFORE setting capabilities
chown -R sensorpajen:sensorpajen /opt/sensorpajen
# Set Bluetooth capabilities on Python executable (after ownership change)
# Note: The systemd service also uses AmbientCapabilities as a fallback
PYTHON_PATH=$(readlink -f /opt/sensorpajen/venv/bin/python3)
if command -v setcap >/dev/null 2>&1; then
if setcap cap_net_raw,cap_net_admin+eip "$PYTHON_PATH" 2>/dev/null; then
echo "Bluetooth capabilities set on $PYTHON_PATH"
getcap "$PYTHON_PATH" || true
else
echo "Warning: setcap failed. Relying on systemd AmbientCapabilities instead."
echo "If Bluetooth access fails, manually run:"
echo " sudo setcap cap_net_raw,cap_net_admin+eip $PYTHON_PATH"
fi
else
echo "Warning: setcap not found (install libcap2-bin package)"
echo "Relying on systemd AmbientCapabilities for Bluetooth access"
fi
# v2 installed a unit into /etc/systemd/system/, which overrides packaged units
# and prevents upgrades from taking effect. If that file exists and is identical
# to the packaged unit, remove the override.
if [ -f /etc/systemd/system/sensorpajen.service ]; then
PACKAGED_UNIT=""
if [ -f /lib/systemd/system/sensorpajen.service ]; then
PACKAGED_UNIT="/lib/systemd/system/sensorpajen.service"
elif [ -f /usr/lib/systemd/system/sensorpajen.service ]; then
PACKAGED_UNIT="/usr/lib/systemd/system/sensorpajen.service"
fi
if [ -n "$PACKAGED_UNIT" ] && diff -q /etc/systemd/system/sensorpajen.service "$PACKAGED_UNIT" >/dev/null 2>&1; then
rm -f /etc/systemd/system/sensorpajen.service
echo "Removed redundant /etc override unit (upgrade-safe)"
fi
fi
# Reload systemd
systemctl daemon-reload
# Enable service (but don't start - needs configuration first)
systemctl enable sensorpajen.service || {
echo "Warning: Could not enable sensorpajen service"
}
# Check if configuration is ready
if [ -f /etc/sensorpajen/sensorpajen.env ] && [ -f /etc/sensorpajen/sensors.json ]; then
# Check if env file has been configured (not default values)
if grep -q "MQTT_HOST=192.168.0.114" /etc/sensorpajen/sensorpajen.env; then
echo ""
echo "======================================================================"
echo " Configuration needed!"
echo "======================================================================"
echo " Edit /etc/sensorpajen/sensorpajen.env with your MQTT settings"
echo " Edit /etc/sensorpajen/sensors.json with your sensor list"
echo " Then run: sudo systemctl start sensorpajen"
echo "======================================================================"
echo ""
else
# Configuration appears to be customized, restart service
systemctl restart sensorpajen.service && {
echo "Sensorpajen service started"
echo "View logs: sudo journalctl -u sensorpajen -f"
} || {
echo "Failed to start service. Check: sudo systemctl status sensorpajen"
}
fi
else
echo ""
echo "======================================================================"
echo " Sensorpajen installed successfully!"
echo "======================================================================"
echo " Next steps:"
echo " 1. Edit /etc/sensorpajen/sensorpajen.env"
echo " 2. Edit /etc/sensorpajen/sensors.json"
echo " 3. sudo systemctl start sensorpajen"
echo " 4. sudo journalctl -u sensorpajen -f"
echo "======================================================================"
echo ""
fi
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
exit 0