#!/bin/bash # # Dune Weaver CLI # # Usage: dw # # Commands: # install Run initial setup # start Start Dune Weaver # stop Stop Dune Weaver # restart Restart Dune Weaver # update Pull latest changes and restart # logs View live logs (Ctrl+C to exit) # status Show service status # shell Open a shell with the venv activated # checkout Switch to a branch and rebuild # touch Manage touch screen app # wifi Manage WiFi and hotspot # help Show this help message # set -e # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # Find dune-weaver directory find_install_dir() { # Check common locations if [[ -f "$HOME/dune-weaver/main.py" ]]; then echo "$HOME/dune-weaver" elif [[ -f "/home/pi/dune-weaver/main.py" ]]; then echo "/home/pi/dune-weaver" elif [[ -f "./main.py" ]]; then pwd else echo "" fi } INSTALL_DIR=$(find_install_dir) # Check if installed check_installed() { if [[ -z "$INSTALL_DIR" ]]; then echo -e "${RED}Error: Dune Weaver not found${NC}" echo "" echo "Please install first:" echo " git clone https://github.com/tuanchris/dune-weaver --single-branch" echo " cd dune-weaver" echo " dw install" exit 1 fi } # Commands cmd_install() { if [[ -z "$INSTALL_DIR" ]]; then # Not installed, check if we're in the right directory if [[ -f "./main.py" ]] && [[ -f "./requirements.txt" ]]; then INSTALL_DIR=$(pwd) else echo -e "${RED}Error: Run this from the dune-weaver directory${NC}" echo "" echo " git clone https://github.com/tuanchris/dune-weaver --single-branch" echo " cd dune-weaver" echo " dw install" exit 1 fi fi cd "$INSTALL_DIR" bash setup-pi.sh "$@" } cmd_start() { check_installed echo -e "${BLUE}Starting Dune Weaver...${NC}" sudo systemctl start dune-weaver echo -e "${GREEN}Started!${NC} Access at http://$(hostname -I | awk '{print $1}')" } cmd_stop() { check_installed echo -e "${BLUE}Stopping Dune Weaver...${NC}" sudo systemctl stop dune-weaver echo -e "${GREEN}Stopped${NC}" } cmd_restart() { check_installed echo -e "${BLUE}Restarting Dune Weaver...${NC}" sudo systemctl restart dune-weaver echo -e "${GREEN}Restarted${NC}" } cmd_update() { check_installed echo -e "${BLUE}Updating Dune Weaver...${NC}" cd "$INSTALL_DIR" # Check if we should skip the pull phase (called after re-exec) if [[ "$1" != "--continue" ]]; then echo "Pulling latest code..." git config --global --add safe.directory "$INSTALL_DIR" 2>/dev/null || true local branch branch=$(git rev-parse --abbrev-ref HEAD) git fetch origin "$branch" git reset --hard "origin/$branch" # Update dw CLI echo "Updating dw command..." sudo cp "$INSTALL_DIR/dw" /usr/local/bin/dw sudo chmod +x /usr/local/bin/dw # Re-exec with the new script to ensure new code runs echo "Restarting with updated CLI..." exec /usr/local/bin/dw update --continue fi # Detect Docker-to-native migration: no venv means first native run if [[ ! -d "$INSTALL_DIR/.venv" ]]; then echo "" echo -e "${YELLOW}Migrating to native deployment (first time setup)...${NC}" echo "This may take a few minutes." echo "" # Install native system dependencies (nginx, python3-venv, gcc, etc.) echo "Installing system dependencies..." sudo apt update sudo DEBIAN_FRONTEND=noninteractive apt install -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" \ python3-venv python3-pip python3-dev \ gcc g++ make swig unzip wget \ libjpeg-dev zlib1g-dev \ libgpiod-dev gpiod \ nginx # Create Python venv echo "Creating Python virtual environment..." python3 -m venv .venv # Stop and remove Docker containers/service if running if command -v docker &> /dev/null; then echo "Stopping Docker containers..." sudo docker compose down 2>/dev/null || true fi fi echo "Updating Python dependencies..." source .venv/bin/activate pip install -r requirements.txt # Update nginx config echo "Updating nginx config..." sudo cp "$INSTALL_DIR/nginx/dune-weaver.conf" /etc/nginx/sites-available/dune-weaver.conf sudo sed -i "s|INSTALL_DIR_PLACEHOLDER|$INSTALL_DIR|g" /etc/nginx/sites-available/dune-weaver.conf sudo ln -sf /etc/nginx/sites-available/dune-weaver.conf /etc/nginx/sites-enabled/dune-weaver.conf sudo rm -f /etc/nginx/sites-enabled/default sudo nginx -t && sudo systemctl restart nginx # Update systemd service echo "Updating systemd service..." sudo cp "$INSTALL_DIR/dune-weaver.service" /etc/systemd/system/dune-weaver.service sudo sed -i "s|USER_PLACEHOLDER|$USER|g" /etc/systemd/system/dune-weaver.service sudo sed -i "s|INSTALL_DIR_PLACEHOLDER|$INSTALL_DIR|g" /etc/systemd/system/dune-weaver.service sudo systemctl daemon-reload sudo systemctl enable dune-weaver echo "Restarting service..." sudo systemctl restart dune-weaver # Install/update WiFi host scripts if not present if [[ -f "$INSTALL_DIR/wifi/setup-wifi.sh" ]]; then if [[ ! -f /usr/local/bin/autohotspot ]]; then echo "" echo -e "${BLUE}Installing autohotspot WiFi scripts...${NC}" sudo bash "$INSTALL_DIR/wifi/setup-wifi.sh" else # Always update the script and service files to latest echo "Updating WiFi host scripts..." sudo cp "$INSTALL_DIR/wifi/autohotspot" /usr/local/bin/autohotspot sudo chmod +x /usr/local/bin/autohotspot # Update service/timer files sudo cp "$INSTALL_DIR/wifi/autohotspot.service" /etc/systemd/system/autohotspot.service sudo cp "$INSTALL_DIR/wifi/autohotspot-check.service" /etc/systemd/system/autohotspot-check.service 2>/dev/null || true sudo cp "$INSTALL_DIR/wifi/autohotspot-check.timer" /etc/systemd/system/autohotspot-check.timer 2>/dev/null || true sudo systemctl daemon-reload sudo systemctl enable autohotspot-check.timer 2>/dev/null || true fi fi # Update touch app if installed (check both directory and service exist) local touch_dir="$INSTALL_DIR/dune-weaver-touch" if [[ -d "$touch_dir" ]] && systemctl list-unit-files dune-weaver-touch.service 2>/dev/null | grep -q dune-weaver-touch; then echo "" echo -e "${BLUE}Updating touch app...${NC}" cd "$touch_dir" # Update Python dependencies (code already pulled with main repo) if [[ -f "requirements.txt" ]] && [[ -d ".venv" ]]; then echo "Updating touch app dependencies..." source .venv/bin/activate pip install -q -r requirements.txt deactivate fi # Restart to apply changes sudo systemctl restart dune-weaver-touch echo -e "${GREEN}Touch app updated!${NC}" fi echo -e "${GREEN}Update complete!${NC}" echo "" echo -e "${YELLOW}Please reload the web page in your browser to see the changes.${NC}" } cmd_logs() { check_installed # Parse optional line count (e.g., dw logs 100) local lines="${1:-}" if [[ -n "$lines" ]]; then sudo journalctl -u dune-weaver -n "$lines" else sudo journalctl -u dune-weaver -f fi } cmd_status() { check_installed sudo systemctl status dune-weaver } cmd_shell() { check_installed cd "$INSTALL_DIR" echo -e "${BLUE}Activating venv...${NC}" exec bash --init-file <(echo "source '$INSTALL_DIR/.venv/bin/activate'; cd '$INSTALL_DIR'; echo 'Dune Weaver venv activated. Type \"exit\" to leave.'") } # Touch app commands (systemd service) cmd_touch() { local subcmd="${1:-help}" case "$subcmd" in logs) local lines="${2:-}" if [[ -n "$lines" ]]; then sudo journalctl -u dune-weaver-touch -n "$lines" else sudo journalctl -u dune-weaver-touch -f fi ;; restart) echo -e "${BLUE}Restarting touch app...${NC}" sudo systemctl restart dune-weaver-touch echo -e "${GREEN}Touch app restarted${NC}" ;; stop) echo -e "${BLUE}Stopping touch app...${NC}" sudo systemctl stop dune-weaver-touch echo -e "${GREEN}Touch app stopped${NC}" ;; start) echo -e "${BLUE}Starting touch app...${NC}" sudo systemctl start dune-weaver-touch echo -e "${GREEN}Touch app started${NC}" ;; status) sudo systemctl status dune-weaver-touch ;; install) check_installed local touch_dir="$INSTALL_DIR/dune-weaver-touch" if [[ ! -f "$touch_dir/install.sh" ]]; then echo -e "${RED}Touch app installer not found at $touch_dir/install.sh${NC}" echo "Make sure you have the dune-weaver-touch directory in your dune-weaver folder." exit 1 fi echo -e "${BLUE}Running touch app installer...${NC}" cd "$touch_dir" sudo bash install.sh ;; help|*) echo -e "${GREEN}Touch App Commands${NC}" echo "" echo "Usage: dw touch " echo "" echo "Commands:" echo " install Install touch app (clone, setup, enable service)" echo " logs [N] View logs (N lines or follow if omitted)" echo " restart Restart touch app" echo " stop Stop touch app" echo " start Start touch app" echo " status Show touch app status" echo " help Show this help message" ;; esac } cmd_checkout() { check_installed local branch="$1" if [[ -z "$branch" ]]; then echo -e "${RED}Usage: dw checkout ${NC}" echo "" echo "Examples:" echo " dw checkout main" echo " dw checkout feature/security-settings-split" echo "" echo "Current branch: $(git -C "$INSTALL_DIR" rev-parse --abbrev-ref HEAD)" exit 1 fi cd "$INSTALL_DIR" # Repo may be cloned with --single-branch; fetch the target branch explicitly echo -e "${BLUE}Fetching branch ${branch}...${NC}" if ! git fetch origin "$branch" 2>/dev/null; then echo -e "${RED}Branch '${branch}' not found on remote${NC}" exit 1 fi # Checkout: create local tracking branch if it doesn't exist if git show-ref --verify --quiet "refs/heads/$branch"; then git checkout "$branch" git reset --hard "origin/$branch" else git checkout -b "$branch" "origin/$branch" fi echo -e "Switched to branch: ${GREEN}${branch}${NC}" # Update Python dependencies echo "Updating Python dependencies..." source .venv/bin/activate pip install -r requirements.txt # Update dw CLI from the new branch sudo cp "$INSTALL_DIR/dw" /usr/local/bin/dw sudo chmod +x /usr/local/bin/dw # Restart service sudo systemctl restart dune-weaver # Install WiFi scripts if available on this branch but not yet installed if [[ -f "$INSTALL_DIR/wifi/setup-wifi.sh" ]] && [[ ! -f /usr/local/bin/autohotspot ]]; then echo "" echo -e "${BLUE}Installing autohotspot WiFi scripts...${NC}" sudo bash "$INSTALL_DIR/wifi/setup-wifi.sh" fi echo -e "${GREEN}Checkout complete!${NC}" } # WiFi / Hotspot commands cmd_wifi() { local subcmd="${1:-help}" case "$subcmd" in status) check_installed echo -e "${BLUE}WiFi Status${NC}" echo "" # Show current mode local mode="unknown" if [[ -f /tmp/dw-wifi-mode ]]; then mode=$(cat /tmp/dw-wifi-mode) fi echo -e "Mode: ${GREEN}${mode}${NC}" # Show connected network local ssid ssid=$(nmcli -t -f GENERAL.CONNECTION dev show wlan0 2>/dev/null | head -1 | cut -d: -f2) if [[ -n "$ssid" && "$ssid" != "--" ]]; then echo -e "Network: ${GREEN}${ssid}${NC}" fi # Show IP local ip ip=$(nmcli -t -f IP4.ADDRESS dev show wlan0 2>/dev/null | head -1 | cut -d: -f2 | cut -d/ -f1) if [[ -n "$ip" ]]; then echo -e "IP: ${GREEN}${ip}${NC}" fi ;; scan) echo -e "${BLUE}Scanning for WiFi networks...${NC}" nmcli dev wifi rescan 2>/dev/null || true sleep 2 nmcli dev wifi list ;; connect) echo -e "${BLUE}Available WiFi networks:${NC}" nmcli dev wifi rescan 2>/dev/null || true sleep 2 nmcli dev wifi list echo "" read -p "Enter SSID to connect to: " ssid if [[ -z "$ssid" ]]; then echo -e "${RED}No SSID provided${NC}" exit 1 fi read -sp "Enter password (leave empty for open networks): " password echo "" # Delete any stale connection profile for this SSID sudo nmcli con delete "$ssid" 2>/dev/null || true if [[ -n "$password" ]]; then # Create connection with explicit security settings # (nmcli dev wifi connect can fail on Trixie without key-mgmt) sudo nmcli con add type wifi ifname wlan0 con-name "$ssid" \ ssid "$ssid" \ wifi-sec.key-mgmt wpa-psk \ wifi-sec.psk "$password" else sudo nmcli con add type wifi ifname wlan0 con-name "$ssid" \ ssid "$ssid" fi echo -e "${BLUE}Connecting to '$ssid'...${NC}" if sudo nmcli con up "$ssid"; then echo -e "${GREEN}Connected!${NC}" else echo -e "${RED}Failed to connect. Check password and try again.${NC}" sudo nmcli con delete "$ssid" 2>/dev/null || true exit 1 fi ;; hotspot) echo -e "${BLUE}Switching to hotspot mode...${NC}" sudo nmcli dev disconnect wlan0 2>/dev/null || true sudo nmcli con up DuneWeaver-Hotspot 2>/dev/null echo "hotspot" | sudo tee /tmp/dw-wifi-mode > /dev/null echo -e "${GREEN}Hotspot active!${NC} Connect to the 'Dune Weaver' WiFi network." ;; setup) check_installed cd "$INSTALL_DIR" sudo bash wifi/setup-wifi.sh ;; help|*) echo -e "${GREEN}WiFi Commands${NC}" echo "" echo "Usage: dw wifi " echo "" echo "Commands:" echo " status Show current WiFi mode and connection" echo " scan Scan for available networks" echo " connect Interactive: scan + select + connect" echo " hotspot Force hotspot mode" echo " setup Run initial autohotspot setup" echo " help Show this help message" ;; esac } cmd_help() { echo -e "${GREEN}Dune Weaver CLI${NC}" echo "" echo "Usage: dw " echo "" echo "Commands:" echo " install Run initial setup" echo " start Start Dune Weaver" echo " stop Stop Dune Weaver" echo " restart Restart Dune Weaver" echo " update Pull latest changes and restart" echo " checkout Switch to a branch and rebuild" echo " logs [N] View logs (N=number of lines, or follow if omitted)" echo " status Show service status" echo " shell Open a shell with the venv activated" echo " touch Manage touch screen app (run 'dw touch help')" echo " wifi Manage WiFi and hotspot (run 'dw wifi help')" echo " help Show this help message" echo "" if [[ -n "$INSTALL_DIR" ]]; then echo -e "Install directory: ${BLUE}$INSTALL_DIR${NC}" fi } # Main case "${1:-help}" in install) shift cmd_install "$@" ;; start) cmd_start ;; stop) cmd_stop ;; restart) cmd_restart ;; update) cmd_update "$2" ;; checkout) cmd_checkout "$2" ;; logs) cmd_logs "$2" ;; status) cmd_status ;; shell) cmd_shell ;; touch) shift cmd_touch "$@" ;; wifi) shift cmd_wifi "$@" ;; help|--help|-h) cmd_help ;; *) echo -e "${RED}Unknown command: $1${NC}" echo "" cmd_help exit 1 ;; esac