mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-17 01:50:47 -04:00
debian-laptop
This commit is contained in:
+164
-26
@@ -1,11 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Installer for the roverd agent on Raspberry Pi
|
||||
# Installer for the roverd agent on Raspberry Pi and Debian laptop rover hosts.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
BINARY_SRC="dist/roverd"
|
||||
CONFIG_SRC="pi/roverd/roverd.sample.yaml"
|
||||
PROFILE="pi"
|
||||
BINARY_SRC=""
|
||||
CONFIG_SRC=""
|
||||
REPO_ROOT="$(pwd -P)"
|
||||
|
||||
usage() {
|
||||
@@ -13,6 +14,8 @@ usage() {
|
||||
Usage: sudo ./pi/install_roverd.sh [options]
|
||||
|
||||
Options:
|
||||
--profile <name> Install profile: pi or debian-laptop (default: pi)
|
||||
--debian-laptop Shortcut for --profile debian-laptop
|
||||
-b, --binary <path> Path to the roverd binary (default: dist/roverd)
|
||||
-c, --config <path> Source config to install if /etc/roverd.yaml is missing
|
||||
(default: pi/roverd/roverd.sample.yaml)
|
||||
@@ -21,8 +24,8 @@ Options:
|
||||
The script must run from the repository root and as root (sudo). It will:
|
||||
* create system users/groups if needed
|
||||
* install /usr/local/bin/roverd and /etc/roverd.yaml
|
||||
* install /usr/local/bin/video/audio helpers and systemd units
|
||||
* install fixed-location Google Chrome TTS assets for roverd
|
||||
* install profile-specific video helpers and shared audio helpers
|
||||
* install Pi-only Google Chrome TTS assets when using the pi profile
|
||||
* install the fixed-command self-update helper used by admin-triggered updates
|
||||
* enable roverd.service and media publisher/listener services
|
||||
USAGE
|
||||
@@ -30,6 +33,14 @@ USAGE
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--profile)
|
||||
PROFILE="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--debian-laptop)
|
||||
PROFILE="debian-laptop"
|
||||
shift
|
||||
;;
|
||||
-b|--binary)
|
||||
BINARY_SRC="${2:-}"
|
||||
shift 2
|
||||
@@ -50,6 +61,32 @@ while [[ $# -gt 0 ]]; do
|
||||
esac
|
||||
done
|
||||
|
||||
case "$PROFILE" in
|
||||
pi)
|
||||
BINARY_SRC="${BINARY_SRC:-dist/roverd}"
|
||||
CONFIG_SRC="${CONFIG_SRC:-pi/roverd/roverd.sample.yaml}"
|
||||
VIDEO_HELPER_SRC="pi/bin/video-publisher.sh"
|
||||
VIDEO_HELPER_DEST="/usr/local/bin/video-publisher"
|
||||
VIDEO_SERVICE_SRC="pi/systemd/video-publisher.service"
|
||||
VIDEO_SERVICE_NAME="video-publisher.service"
|
||||
ROVERD_GROUPS="dialout,gpio,video,render,audio"
|
||||
;;
|
||||
debian-laptop)
|
||||
BINARY_SRC="${BINARY_SRC:-dist/roverd-debian-laptop}"
|
||||
CONFIG_SRC="${CONFIG_SRC:-pi/roverd/roverd.debian-laptop.sample.yaml}"
|
||||
VIDEO_HELPER_SRC="pi/bin/debian-laptop-video-publisher.sh"
|
||||
VIDEO_HELPER_DEST="/usr/local/bin/debian-laptop-video-publisher"
|
||||
VIDEO_SERVICE_SRC="pi/systemd/debian-laptop-video-publisher.service"
|
||||
VIDEO_SERVICE_NAME="debian-laptop-video-publisher.service"
|
||||
ROVERD_GROUPS="dialout,video,render,audio"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown profile: $PROFILE" >&2
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "${EUID}" -ne 0 ]]; then
|
||||
echo "Please run as root (sudo)" >&2
|
||||
exit 1
|
||||
@@ -68,14 +105,37 @@ fi
|
||||
ensure_user() {
|
||||
local user="$1"
|
||||
local groups="${2:-}"
|
||||
local existing_groups=""
|
||||
if ! id -u "$user" >/dev/null 2>&1; then
|
||||
if [[ -n "$groups" ]]; then
|
||||
useradd -r -s /usr/sbin/nologin -G "$groups" "$user"
|
||||
local group
|
||||
IFS=',' read -ra group_list <<< "$groups"
|
||||
for group in "${group_list[@]}"; do
|
||||
if getent group "$group" >/dev/null 2>&1; then
|
||||
existing_groups="${existing_groups:+$existing_groups,}$group"
|
||||
else
|
||||
log "Skipping missing system group '$group' for $user"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ -n "$existing_groups" ]]; then
|
||||
useradd -r -s /usr/sbin/nologin -G "$existing_groups" "$user"
|
||||
else
|
||||
useradd -r -s /usr/sbin/nologin "$user"
|
||||
fi
|
||||
elif [[ -n "$groups" ]]; then
|
||||
usermod -a -G "$groups" "$user"
|
||||
local group
|
||||
IFS=',' read -ra group_list <<< "$groups"
|
||||
for group in "${group_list[@]}"; do
|
||||
if getent group "$group" >/dev/null 2>&1; then
|
||||
existing_groups="${existing_groups:+$existing_groups,}$group"
|
||||
else
|
||||
log "Skipping missing system group '$group' for $user"
|
||||
fi
|
||||
done
|
||||
if [[ -n "$existing_groups" ]]; then
|
||||
usermod -a -G "$existing_groups" "$user"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -83,7 +143,7 @@ log() {
|
||||
echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*"
|
||||
}
|
||||
|
||||
if ! command -v rpicam-vid >/dev/null 2>&1 && ! command -v libcamera-vid >/dev/null 2>&1; then
|
||||
if [[ "$PROFILE" == "pi" ]] && ! command -v rpicam-vid >/dev/null 2>&1 && ! command -v libcamera-vid >/dev/null 2>&1; then
|
||||
log "WARNING: neither rpicam-vid nor libcamera-vid found in PATH; install libcamera-apps."
|
||||
fi
|
||||
|
||||
@@ -97,6 +157,23 @@ install_video_deps() {
|
||||
apt-get install -y --no-install-recommends libcamera-apps ffmpeg
|
||||
}
|
||||
|
||||
install_debian_laptop_deps() {
|
||||
# The debian-laptop profile is intentionally Debian-specific, so using apt
|
||||
# and systemd directly is simpler than pretending this installer is a
|
||||
# cross-distro abstraction. v4l-utils is included for local camera inspection
|
||||
# with tools such as v4l2-ctl while ffmpeg owns publishing.
|
||||
if command -v ffmpeg >/dev/null 2>&1 \
|
||||
&& command -v arecord >/dev/null 2>&1 \
|
||||
&& command -v aplay >/dev/null 2>&1 \
|
||||
&& command -v v4l2-ctl >/dev/null 2>&1; then
|
||||
log "Debian laptop media dependencies already installed; skipping apt install"
|
||||
return
|
||||
fi
|
||||
log "Installing Debian laptop media dependencies (ffmpeg, ALSA tools, V4L2 tools)..."
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends ffmpeg alsa-utils v4l-utils ca-certificates
|
||||
}
|
||||
|
||||
find_boot_config() {
|
||||
if [[ -f /boot/firmware/config.txt ]]; then
|
||||
printf "/boot/firmware/config.txt"
|
||||
@@ -129,9 +206,35 @@ ensure_pwm_overlay() {
|
||||
log "Enabled dtoverlay=pwm-2chan on GPIO12/13 in $boot_config (backup at $backup). Reboot required for changes to apply."
|
||||
}
|
||||
|
||||
ensure_user roverd "dialout,gpio,video,render,audio"
|
||||
install_profile_dependencies() {
|
||||
case "$PROFILE" in
|
||||
pi)
|
||||
install_video_deps
|
||||
ensure_pwm_overlay
|
||||
;;
|
||||
debian-laptop)
|
||||
install_debian_laptop_deps
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_profile_audio_support() {
|
||||
case "$PROFILE" in
|
||||
pi)
|
||||
install_audio_support
|
||||
;;
|
||||
debian-laptop)
|
||||
# Laptop audio uses the distro's normal ALSA "default" device by
|
||||
# default. Avoid installing the Raspberry Pi AIY asound.conf because
|
||||
# that would break ordinary laptop sound routing.
|
||||
log "Skipping Pi AIY audio setup for debian-laptop profile"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
ensure_user roverd "$ROVERD_GROUPS"
|
||||
install -o roverd -g roverd -m 0755 "$BINARY_SRC" /usr/local/bin/roverd
|
||||
log "Installed roverd binary"
|
||||
log "Installed roverd binary for profile $PROFILE"
|
||||
|
||||
install_self_update_support() {
|
||||
local sudoers_file="/etc/sudoers.d/roverd-self-update"
|
||||
@@ -185,8 +288,7 @@ fi
|
||||
install -m 0644 pi/systemd/roverd.service /etc/systemd/system/roverd.service
|
||||
log "Installed roverd systemd unit"
|
||||
|
||||
install_video_deps
|
||||
ensure_pwm_overlay
|
||||
install_profile_dependencies
|
||||
|
||||
# Enable Google AIY v1 sound card, ALSA defaults, and TTS engines
|
||||
install_audio_support() {
|
||||
@@ -298,11 +400,13 @@ install_google_tts_assets() {
|
||||
log "Installed Google Chrome TTS assets to $asset_dir"
|
||||
}
|
||||
|
||||
# Install video publisher assets
|
||||
install -D -o root -g root -m 0755 pi/bin/video-publisher.sh /usr/local/bin/video-publisher
|
||||
log "Installed video-publisher helper"
|
||||
install -m 0644 pi/systemd/video-publisher.service /etc/systemd/system/video-publisher.service
|
||||
log "Installed video-publisher systemd unit"
|
||||
# Install the profile-specific video publisher. The audio publisher/listener are
|
||||
# shared because both Pi and Debian laptop profiles use the same media.env audio
|
||||
# contract and ffmpeg/ALSA command shape.
|
||||
install -D -o root -g root -m 0755 "$VIDEO_HELPER_SRC" "$VIDEO_HELPER_DEST"
|
||||
log "Installed $PROFILE video publisher helper"
|
||||
install -m 0644 "$VIDEO_SERVICE_SRC" "/etc/systemd/system/$VIDEO_SERVICE_NAME"
|
||||
log "Installed $PROFILE video publisher systemd unit"
|
||||
# Install audio-only publisher assets
|
||||
install -D -o root -g root -m 0755 pi/bin/audio-only-publisher.sh /usr/local/bin/audio-only-publisher
|
||||
install -m 0644 pi/systemd/audio-only-publisher.service /etc/systemd/system/audio-only-publisher.service
|
||||
@@ -312,7 +416,9 @@ install -D -o root -g root -m 0755 pi/bin/audio-forward-listener.sh /usr/local/b
|
||||
install -m 0644 pi/systemd/audio-forward-listener.service /etc/systemd/system/audio-forward-listener.service
|
||||
log "Installed audio-forward listener helper + systemd unit"
|
||||
install -d -o roverd -g roverd /var/lib/roverd
|
||||
cat > /var/lib/roverd/media.env <<'ENV'
|
||||
case "$PROFILE" in
|
||||
pi)
|
||||
cat > /var/lib/roverd/media.env <<'ENV'
|
||||
# Managed by roverd; placeholder values will be overwritten at runtime.
|
||||
ROVERD_VIDEO_ENABLE=1
|
||||
ROVERD_VIDEO_PUBLISHER=pi-libcamera
|
||||
@@ -336,6 +442,34 @@ ROVERD_AUDIO_PLAYBACK_DEVICE=forward
|
||||
ROVERD_AUDIO_PLAYBACK_NORMALIZE=1
|
||||
ROVERD_AUDIO_PLAYBACK_NORMALIZE_FILTER=dynaudnorm=f=75:g=15:m=10:p=0.9,alimiter=limit=0.85:level=disabled
|
||||
ENV
|
||||
;;
|
||||
debian-laptop)
|
||||
cat > /var/lib/roverd/media.env <<'ENV'
|
||||
# Managed by roverd; placeholder values will be overwritten at runtime.
|
||||
ROVERD_VIDEO_ENABLE=1
|
||||
ROVERD_VIDEO_PUBLISHER=debian-laptop-v4l2
|
||||
ROVERD_VIDEO_PUBLISH_URL=srt://192.168.0.86:9000?streamid=#!::r=CHANGE_ME,m=publish&latency=10&mode=caller&transtype=live&pkt_size=1316
|
||||
ROVERD_VIDEO_DEVICE=/dev/video0
|
||||
ROVERD_VIDEO_WIDTH=640
|
||||
ROVERD_VIDEO_HEIGHT=480
|
||||
ROVERD_VIDEO_FPS=30
|
||||
ROVERD_VIDEO_BITRATE=2000000
|
||||
ROVERD_VIDEO_INVERT=0
|
||||
ROVERD_VIDEO_SENSOR_MODE=
|
||||
ROVERD_AUDIO_CAPTURE_ENABLE=1
|
||||
ROVERD_AUDIO_CAPTURE_PUBLISH_URL=srt://192.168.0.86:9000?streamid=#!::r=CHANGE_ME-audio,m=publish&latency=10&mode=caller&transtype=live&pkt_size=1316
|
||||
ROVERD_AUDIO_CAPTURE_DEVICE=default
|
||||
ROVERD_AUDIO_CAPTURE_SAMPLE_RATE=48000
|
||||
ROVERD_AUDIO_CAPTURE_CHANNELS=2
|
||||
ROVERD_AUDIO_CAPTURE_BITRATE=510000
|
||||
ROVERD_AUDIO_PLAYBACK_ENABLE=1
|
||||
ROVERD_AUDIO_PLAYBACK_FORWARD_URL=srt://192.168.0.86:9000?streamid=#!::r=CHANGE_ME-fwd,m=request&latency=10&mode=caller&transtype=live&pkt_size=1316
|
||||
ROVERD_AUDIO_PLAYBACK_DEVICE=default
|
||||
ROVERD_AUDIO_PLAYBACK_NORMALIZE=1
|
||||
ROVERD_AUDIO_PLAYBACK_NORMALIZE_FILTER=dynaudnorm=f=75:g=15:m=10:p=0.9,alimiter=limit=0.85:level=disabled
|
||||
ENV
|
||||
;;
|
||||
esac
|
||||
chown roverd:roverd /var/lib/roverd/media.env
|
||||
chmod 0640 /var/lib/roverd/media.env
|
||||
# Create persistent audio FIFO for capture -> publisher
|
||||
@@ -349,25 +483,29 @@ else
|
||||
chown roverd:audio "$FIFO_PATH"
|
||||
chmod 0660 "$FIFO_PATH"
|
||||
fi
|
||||
# Ensure ALSA config is in place for rovermic device
|
||||
install -m 0644 pi/asound.conf /etc/asound.conf
|
||||
log "Installed ALSA config (/etc/asound.conf)"
|
||||
if [[ "$PROFILE" == "pi" ]]; then
|
||||
# Ensure ALSA config is in place for the Raspberry Pi Google Voice HAT
|
||||
# rovermic/forward devices. Debian laptop installs should keep their normal
|
||||
# distro sound configuration and use device: default in roverd.yaml.
|
||||
install -m 0644 pi/asound.conf /etc/asound.conf
|
||||
log "Installed ALSA config (/etc/asound.conf)"
|
||||
fi
|
||||
|
||||
install_audio_support
|
||||
install_profile_audio_support
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable roverd.service
|
||||
systemctl enable video-publisher.service
|
||||
systemctl enable "$VIDEO_SERVICE_NAME"
|
||||
systemctl enable audio-only-publisher.service
|
||||
systemctl enable audio-forward-listener.service
|
||||
if [[ $CONFIG_EXISTS -eq 1 ]]; then
|
||||
systemctl restart roverd.service
|
||||
systemctl restart video-publisher.service
|
||||
systemctl restart "$VIDEO_SERVICE_NAME"
|
||||
systemctl restart audio-only-publisher.service
|
||||
systemctl restart audio-forward-listener.service
|
||||
log "Restarted roverd + media publishers/listener"
|
||||
else
|
||||
log "Skipped auto-start because config is the sample; edit $CONFIG_DEST then run: sudo systemctl restart roverd video-publisher audio-only-publisher audio-forward-listener"
|
||||
log "Skipped auto-start because config is the sample; edit $CONFIG_DEST then run: sudo systemctl restart roverd ${VIDEO_SERVICE_NAME%.service} audio-only-publisher audio-forward-listener"
|
||||
fi
|
||||
|
||||
log "Install complete"
|
||||
log "Install complete for profile $PROFILE"
|
||||
|
||||
Reference in New Issue
Block a user