dw 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. #!/bin/bash
  2. #
  3. # Dune Weaver CLI
  4. #
  5. # Usage: dw <command>
  6. #
  7. # Commands:
  8. # install Run initial setup
  9. # start Start Dune Weaver
  10. # stop Stop Dune Weaver
  11. # restart Restart Dune Weaver
  12. # update Pull latest changes and restart
  13. # logs View live logs (Ctrl+C to exit)
  14. # status Show service status
  15. # shell Open a shell with the venv activated
  16. # checkout Switch to a branch and rebuild
  17. # touch Manage touch screen app
  18. # wifi Manage WiFi and hotspot
  19. # help Show this help message
  20. #
  21. set -e
  22. # Colors
  23. RED='\033[0;31m'
  24. GREEN='\033[0;32m'
  25. YELLOW='\033[1;33m'
  26. BLUE='\033[0;34m'
  27. NC='\033[0m'
  28. # Find dune-weaver directory
  29. find_install_dir() {
  30. # Check common locations
  31. if [[ -f "$HOME/dune-weaver/main.py" ]]; then
  32. echo "$HOME/dune-weaver"
  33. elif [[ -f "/home/pi/dune-weaver/main.py" ]]; then
  34. echo "/home/pi/dune-weaver"
  35. elif [[ -f "./main.py" ]]; then
  36. pwd
  37. else
  38. echo ""
  39. fi
  40. }
  41. INSTALL_DIR=$(find_install_dir)
  42. # Check if installed
  43. check_installed() {
  44. if [[ -z "$INSTALL_DIR" ]]; then
  45. echo -e "${RED}Error: Dune Weaver not found${NC}"
  46. echo ""
  47. echo "Please install first:"
  48. echo " git clone https://github.com/tuanchris/dune-weaver --single-branch"
  49. echo " cd dune-weaver"
  50. echo " dw install"
  51. exit 1
  52. fi
  53. }
  54. # Commands
  55. cmd_install() {
  56. if [[ -z "$INSTALL_DIR" ]]; then
  57. # Not installed, check if we're in the right directory
  58. if [[ -f "./main.py" ]] && [[ -f "./requirements.txt" ]]; then
  59. INSTALL_DIR=$(pwd)
  60. else
  61. echo -e "${RED}Error: Run this from the dune-weaver directory${NC}"
  62. echo ""
  63. echo " git clone https://github.com/tuanchris/dune-weaver --single-branch"
  64. echo " cd dune-weaver"
  65. echo " dw install"
  66. exit 1
  67. fi
  68. fi
  69. cd "$INSTALL_DIR"
  70. bash setup-pi.sh "$@"
  71. }
  72. cmd_start() {
  73. check_installed
  74. echo -e "${BLUE}Starting Dune Weaver...${NC}"
  75. sudo systemctl start dune-weaver
  76. echo -e "${GREEN}Started!${NC} Access at http://$(hostname -I | awk '{print $1}')"
  77. }
  78. cmd_stop() {
  79. check_installed
  80. echo -e "${BLUE}Stopping Dune Weaver...${NC}"
  81. sudo systemctl stop dune-weaver
  82. echo -e "${GREEN}Stopped${NC}"
  83. }
  84. cmd_restart() {
  85. check_installed
  86. echo -e "${BLUE}Restarting Dune Weaver...${NC}"
  87. sudo systemctl restart dune-weaver
  88. echo -e "${GREEN}Restarted${NC}"
  89. }
  90. cmd_update() {
  91. check_installed
  92. echo -e "${BLUE}Updating Dune Weaver...${NC}"
  93. cd "$INSTALL_DIR"
  94. # Check if we should skip the pull phase (called after re-exec)
  95. if [[ "$1" != "--continue" ]]; then
  96. echo "Pulling latest code..."
  97. git pull
  98. # Update dw CLI
  99. echo "Updating dw command..."
  100. sudo cp "$INSTALL_DIR/dw" /usr/local/bin/dw
  101. sudo chmod +x /usr/local/bin/dw
  102. # Re-exec with the new script to ensure new code runs
  103. echo "Restarting with updated CLI..."
  104. exec /usr/local/bin/dw update --continue
  105. fi
  106. echo "Updating Python dependencies..."
  107. source .venv/bin/activate
  108. pip install -r requirements.txt
  109. echo "Rebuilding frontend..."
  110. cd "$INSTALL_DIR/frontend"
  111. npm ci --loglevel=error
  112. npx vite build
  113. cd "$INSTALL_DIR"
  114. # Update nginx config
  115. echo "Updating nginx config..."
  116. sudo cp "$INSTALL_DIR/nginx/dune-weaver.conf" /etc/nginx/sites-available/dune-weaver.conf
  117. sudo sed -i "s|INSTALL_DIR_PLACEHOLDER|$INSTALL_DIR|g" /etc/nginx/sites-available/dune-weaver.conf
  118. sudo nginx -t && sudo systemctl restart nginx
  119. # Update systemd service
  120. echo "Updating systemd service..."
  121. sudo cp "$INSTALL_DIR/dune-weaver.service" /etc/systemd/system/dune-weaver.service
  122. sudo sed -i "s|USER_PLACEHOLDER|$USER|g" /etc/systemd/system/dune-weaver.service
  123. sudo sed -i "s|INSTALL_DIR_PLACEHOLDER|$INSTALL_DIR|g" /etc/systemd/system/dune-weaver.service
  124. sudo systemctl daemon-reload
  125. echo "Restarting service..."
  126. sudo systemctl restart dune-weaver
  127. # Install/update WiFi host scripts if not present
  128. if [[ -f "$INSTALL_DIR/wifi/setup-wifi.sh" ]]; then
  129. if [[ ! -f /usr/local/bin/autohotspot ]]; then
  130. echo ""
  131. echo -e "${BLUE}Installing autohotspot WiFi scripts...${NC}"
  132. sudo bash "$INSTALL_DIR/wifi/setup-wifi.sh"
  133. else
  134. # Always update the script and service files to latest
  135. echo "Updating WiFi host scripts..."
  136. sudo cp "$INSTALL_DIR/wifi/autohotspot" /usr/local/bin/autohotspot
  137. sudo chmod +x /usr/local/bin/autohotspot
  138. # Update service/timer files
  139. sudo cp "$INSTALL_DIR/wifi/autohotspot.service" /etc/systemd/system/autohotspot.service
  140. sudo cp "$INSTALL_DIR/wifi/autohotspot-check.service" /etc/systemd/system/autohotspot-check.service 2>/dev/null || true
  141. sudo cp "$INSTALL_DIR/wifi/autohotspot-check.timer" /etc/systemd/system/autohotspot-check.timer 2>/dev/null || true
  142. sudo systemctl daemon-reload
  143. sudo systemctl enable autohotspot-check.timer 2>/dev/null || true
  144. fi
  145. fi
  146. # Update touch app if installed (check both directory and service exist)
  147. local touch_dir="$INSTALL_DIR/dune-weaver-touch"
  148. if [[ -d "$touch_dir" ]] && systemctl list-unit-files dune-weaver-touch.service 2>/dev/null | grep -q dune-weaver-touch; then
  149. echo ""
  150. echo -e "${BLUE}Updating touch app...${NC}"
  151. cd "$touch_dir"
  152. # Update Python dependencies (code already pulled with main repo)
  153. if [[ -f "requirements.txt" ]] && [[ -d ".venv" ]]; then
  154. echo "Updating touch app dependencies..."
  155. source .venv/bin/activate
  156. pip install -q -r requirements.txt
  157. deactivate
  158. fi
  159. # Restart to apply changes
  160. sudo systemctl restart dune-weaver-touch
  161. echo -e "${GREEN}Touch app updated!${NC}"
  162. fi
  163. echo -e "${GREEN}Update complete!${NC}"
  164. }
  165. cmd_logs() {
  166. check_installed
  167. # Parse optional line count (e.g., dw logs 100)
  168. local lines="${1:-}"
  169. if [[ -n "$lines" ]]; then
  170. sudo journalctl -u dune-weaver -n "$lines"
  171. else
  172. sudo journalctl -u dune-weaver -f
  173. fi
  174. }
  175. cmd_status() {
  176. check_installed
  177. sudo systemctl status dune-weaver
  178. }
  179. cmd_shell() {
  180. check_installed
  181. cd "$INSTALL_DIR"
  182. echo -e "${BLUE}Activating venv...${NC}"
  183. exec bash --init-file <(echo "source '$INSTALL_DIR/.venv/bin/activate'; cd '$INSTALL_DIR'; echo 'Dune Weaver venv activated. Type \"exit\" to leave.'")
  184. }
  185. # Touch app commands (systemd service)
  186. cmd_touch() {
  187. local subcmd="${1:-help}"
  188. case "$subcmd" in
  189. logs)
  190. local lines="${2:-}"
  191. if [[ -n "$lines" ]]; then
  192. sudo journalctl -u dune-weaver-touch -n "$lines"
  193. else
  194. sudo journalctl -u dune-weaver-touch -f
  195. fi
  196. ;;
  197. restart)
  198. echo -e "${BLUE}Restarting touch app...${NC}"
  199. sudo systemctl restart dune-weaver-touch
  200. echo -e "${GREEN}Touch app restarted${NC}"
  201. ;;
  202. stop)
  203. echo -e "${BLUE}Stopping touch app...${NC}"
  204. sudo systemctl stop dune-weaver-touch
  205. echo -e "${GREEN}Touch app stopped${NC}"
  206. ;;
  207. start)
  208. echo -e "${BLUE}Starting touch app...${NC}"
  209. sudo systemctl start dune-weaver-touch
  210. echo -e "${GREEN}Touch app started${NC}"
  211. ;;
  212. status)
  213. sudo systemctl status dune-weaver-touch
  214. ;;
  215. install)
  216. check_installed
  217. local touch_dir="$INSTALL_DIR/dune-weaver-touch"
  218. if [[ ! -f "$touch_dir/install.sh" ]]; then
  219. echo -e "${RED}Touch app installer not found at $touch_dir/install.sh${NC}"
  220. echo "Make sure you have the dune-weaver-touch directory in your dune-weaver folder."
  221. exit 1
  222. fi
  223. echo -e "${BLUE}Running touch app installer...${NC}"
  224. cd "$touch_dir"
  225. sudo bash install.sh
  226. ;;
  227. help|*)
  228. echo -e "${GREEN}Touch App Commands${NC}"
  229. echo ""
  230. echo "Usage: dw touch <command>"
  231. echo ""
  232. echo "Commands:"
  233. echo " install Install touch app (clone, setup, enable service)"
  234. echo " logs [N] View logs (N lines or follow if omitted)"
  235. echo " restart Restart touch app"
  236. echo " stop Stop touch app"
  237. echo " start Start touch app"
  238. echo " status Show touch app status"
  239. echo " help Show this help message"
  240. ;;
  241. esac
  242. }
  243. cmd_checkout() {
  244. check_installed
  245. local branch="$1"
  246. if [[ -z "$branch" ]]; then
  247. echo -e "${RED}Usage: dw checkout <branch>${NC}"
  248. echo ""
  249. echo "Examples:"
  250. echo " dw checkout main"
  251. echo " dw checkout feature/security-settings-split"
  252. echo ""
  253. echo "Current branch: $(git -C "$INSTALL_DIR" rev-parse --abbrev-ref HEAD)"
  254. exit 1
  255. fi
  256. cd "$INSTALL_DIR"
  257. # Repo may be cloned with --single-branch; fetch the target branch explicitly
  258. echo -e "${BLUE}Fetching branch ${branch}...${NC}"
  259. if ! git fetch origin "$branch" 2>/dev/null; then
  260. echo -e "${RED}Branch '${branch}' not found on remote${NC}"
  261. exit 1
  262. fi
  263. # Checkout: create local tracking branch if it doesn't exist
  264. if git show-ref --verify --quiet "refs/heads/$branch"; then
  265. git checkout "$branch"
  266. git pull
  267. else
  268. git checkout -b "$branch" "origin/$branch"
  269. fi
  270. echo -e "Switched to branch: ${GREEN}${branch}${NC}"
  271. # Rebuild frontend
  272. echo "Rebuilding frontend..."
  273. cd "$INSTALL_DIR/frontend"
  274. npm ci --loglevel=error
  275. npx vite build
  276. cd "$INSTALL_DIR"
  277. # Update Python dependencies
  278. echo "Updating Python dependencies..."
  279. source .venv/bin/activate
  280. pip install -r requirements.txt
  281. # Update dw CLI from the new branch
  282. sudo cp "$INSTALL_DIR/dw" /usr/local/bin/dw
  283. sudo chmod +x /usr/local/bin/dw
  284. # Restart service
  285. sudo systemctl restart dune-weaver
  286. # Install WiFi scripts if available on this branch but not yet installed
  287. if [[ -f "$INSTALL_DIR/wifi/setup-wifi.sh" ]] && [[ ! -f /usr/local/bin/autohotspot ]]; then
  288. echo ""
  289. echo -e "${BLUE}Installing autohotspot WiFi scripts...${NC}"
  290. sudo bash "$INSTALL_DIR/wifi/setup-wifi.sh"
  291. fi
  292. echo -e "${GREEN}Checkout complete!${NC}"
  293. }
  294. # WiFi / Hotspot commands
  295. cmd_wifi() {
  296. local subcmd="${1:-help}"
  297. case "$subcmd" in
  298. status)
  299. check_installed
  300. echo -e "${BLUE}WiFi Status${NC}"
  301. echo ""
  302. # Show current mode
  303. local mode="unknown"
  304. if [[ -f /tmp/dw-wifi-mode ]]; then
  305. mode=$(cat /tmp/dw-wifi-mode)
  306. fi
  307. echo -e "Mode: ${GREEN}${mode}${NC}"
  308. # Show connected network
  309. local ssid
  310. ssid=$(nmcli -t -f GENERAL.CONNECTION dev show wlan0 2>/dev/null | head -1 | cut -d: -f2)
  311. if [[ -n "$ssid" && "$ssid" != "--" ]]; then
  312. echo -e "Network: ${GREEN}${ssid}${NC}"
  313. fi
  314. # Show IP
  315. local ip
  316. ip=$(nmcli -t -f IP4.ADDRESS dev show wlan0 2>/dev/null | head -1 | cut -d: -f2 | cut -d/ -f1)
  317. if [[ -n "$ip" ]]; then
  318. echo -e "IP: ${GREEN}${ip}${NC}"
  319. fi
  320. ;;
  321. scan)
  322. echo -e "${BLUE}Scanning for WiFi networks...${NC}"
  323. nmcli dev wifi rescan 2>/dev/null || true
  324. sleep 2
  325. nmcli dev wifi list
  326. ;;
  327. connect)
  328. echo -e "${BLUE}Available WiFi networks:${NC}"
  329. nmcli dev wifi rescan 2>/dev/null || true
  330. sleep 2
  331. nmcli dev wifi list
  332. echo ""
  333. read -p "Enter SSID to connect to: " ssid
  334. if [[ -z "$ssid" ]]; then
  335. echo -e "${RED}No SSID provided${NC}"
  336. exit 1
  337. fi
  338. read -sp "Enter password (leave empty for open networks): " password
  339. echo ""
  340. # Delete any stale connection profile for this SSID
  341. sudo nmcli con delete "$ssid" 2>/dev/null || true
  342. if [[ -n "$password" ]]; then
  343. # Create connection with explicit security settings
  344. # (nmcli dev wifi connect can fail on Trixie without key-mgmt)
  345. sudo nmcli con add type wifi ifname wlan0 con-name "$ssid" \
  346. ssid "$ssid" \
  347. wifi-sec.key-mgmt wpa-psk \
  348. wifi-sec.psk "$password"
  349. else
  350. sudo nmcli con add type wifi ifname wlan0 con-name "$ssid" \
  351. ssid "$ssid"
  352. fi
  353. echo -e "${BLUE}Connecting to '$ssid'...${NC}"
  354. if sudo nmcli con up "$ssid"; then
  355. echo -e "${GREEN}Connected!${NC}"
  356. else
  357. echo -e "${RED}Failed to connect. Check password and try again.${NC}"
  358. sudo nmcli con delete "$ssid" 2>/dev/null || true
  359. exit 1
  360. fi
  361. ;;
  362. hotspot)
  363. echo -e "${BLUE}Switching to hotspot mode...${NC}"
  364. sudo nmcli dev disconnect wlan0 2>/dev/null || true
  365. sudo nmcli con up DuneWeaver-Hotspot 2>/dev/null
  366. echo "hotspot" | sudo tee /tmp/dw-wifi-mode > /dev/null
  367. echo -e "${GREEN}Hotspot active!${NC} Connect to the 'Dune Weaver' WiFi network."
  368. ;;
  369. setup)
  370. check_installed
  371. cd "$INSTALL_DIR"
  372. sudo bash wifi/setup-wifi.sh
  373. ;;
  374. help|*)
  375. echo -e "${GREEN}WiFi Commands${NC}"
  376. echo ""
  377. echo "Usage: dw wifi <command>"
  378. echo ""
  379. echo "Commands:"
  380. echo " status Show current WiFi mode and connection"
  381. echo " scan Scan for available networks"
  382. echo " connect Interactive: scan + select + connect"
  383. echo " hotspot Force hotspot mode"
  384. echo " setup Run initial autohotspot setup"
  385. echo " help Show this help message"
  386. ;;
  387. esac
  388. }
  389. cmd_help() {
  390. echo -e "${GREEN}Dune Weaver CLI${NC}"
  391. echo ""
  392. echo "Usage: dw <command>"
  393. echo ""
  394. echo "Commands:"
  395. echo " install Run initial setup"
  396. echo " start Start Dune Weaver"
  397. echo " stop Stop Dune Weaver"
  398. echo " restart Restart Dune Weaver"
  399. echo " update Pull latest changes and restart"
  400. echo " checkout Switch to a branch and rebuild"
  401. echo " logs [N] View logs (N=number of lines, or follow if omitted)"
  402. echo " status Show service status"
  403. echo " shell Open a shell with the venv activated"
  404. echo " touch Manage touch screen app (run 'dw touch help')"
  405. echo " wifi Manage WiFi and hotspot (run 'dw wifi help')"
  406. echo " help Show this help message"
  407. echo ""
  408. if [[ -n "$INSTALL_DIR" ]]; then
  409. echo -e "Install directory: ${BLUE}$INSTALL_DIR${NC}"
  410. fi
  411. }
  412. # Main
  413. case "${1:-help}" in
  414. install)
  415. shift
  416. cmd_install "$@"
  417. ;;
  418. start)
  419. cmd_start
  420. ;;
  421. stop)
  422. cmd_stop
  423. ;;
  424. restart)
  425. cmd_restart
  426. ;;
  427. update)
  428. cmd_update "$2"
  429. ;;
  430. checkout)
  431. cmd_checkout "$2"
  432. ;;
  433. logs)
  434. cmd_logs "$2"
  435. ;;
  436. status)
  437. cmd_status
  438. ;;
  439. shell)
  440. cmd_shell
  441. ;;
  442. touch)
  443. shift
  444. cmd_touch "$@"
  445. ;;
  446. wifi)
  447. shift
  448. cmd_wifi "$@"
  449. ;;
  450. help|--help|-h)
  451. cmd_help
  452. ;;
  453. *)
  454. echo -e "${RED}Unknown command: $1${NC}"
  455. echo ""
  456. cmd_help
  457. exit 1
  458. ;;
  459. esac