dw 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. #!/bin/bash
  2. #
  3. # Dune Weaver CLI
  4. #
  5. # Usage: dw <command>
  6. #
  7. # Commands:
  8. # install Run initial setup (Docker + WiFi fix)
  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 container status
  15. # shell Open a shell in the container
  16. # checkout Switch to a branch and pull its Docker images
  17. # touch Manage touch screen app
  18. # help Show this help message
  19. #
  20. set -e
  21. # Colors
  22. RED='\033[0;31m'
  23. GREEN='\033[0;32m'
  24. YELLOW='\033[1;33m'
  25. BLUE='\033[0;34m'
  26. NC='\033[0m'
  27. # Find dune-weaver directory
  28. find_install_dir() {
  29. # Check common locations
  30. if [[ -f "$HOME/dune-weaver/main.py" ]]; then
  31. echo "$HOME/dune-weaver"
  32. elif [[ -f "/home/pi/dune-weaver/main.py" ]]; then
  33. echo "/home/pi/dune-weaver"
  34. elif [[ -f "./main.py" ]]; then
  35. pwd
  36. else
  37. echo ""
  38. fi
  39. }
  40. # Check if using Docker or systemd
  41. is_docker_mode() {
  42. # Docker mode if docker-compose.yml exists and docker is available
  43. [[ -f "$INSTALL_DIR/docker-compose.yml" ]] && command -v docker &> /dev/null
  44. }
  45. # Set IMAGE_TAG from current git branch (e.g. feature/foo -> feature-foo)
  46. set_image_tag() {
  47. local branch
  48. branch=$(git -C "$INSTALL_DIR" rev-parse --abbrev-ref HEAD)
  49. export IMAGE_TAG="${branch//\//-}"
  50. }
  51. INSTALL_DIR=$(find_install_dir)
  52. # Check if installed
  53. check_installed() {
  54. if [[ -z "$INSTALL_DIR" ]]; then
  55. echo -e "${RED}Error: Dune Weaver not found${NC}"
  56. echo ""
  57. echo "Please install first:"
  58. echo " git clone https://github.com/tuanchris/dune-weaver --single-branch"
  59. echo " cd dune-weaver"
  60. echo " dw install"
  61. exit 1
  62. fi
  63. }
  64. # Commands
  65. cmd_install() {
  66. if [[ -z "$INSTALL_DIR" ]]; then
  67. # Not installed, check if we're in the right directory
  68. if [[ -f "./docker-compose.yml" ]] && [[ -f "./main.py" ]]; then
  69. INSTALL_DIR=$(pwd)
  70. else
  71. echo -e "${RED}Error: Run this from the dune-weaver directory${NC}"
  72. echo ""
  73. echo " git clone https://github.com/tuanchris/dune-weaver --single-branch"
  74. echo " cd dune-weaver"
  75. echo " dw install"
  76. exit 1
  77. fi
  78. fi
  79. cd "$INSTALL_DIR"
  80. bash setup-pi.sh "$@"
  81. }
  82. cmd_start() {
  83. check_installed
  84. echo -e "${BLUE}Starting Dune Weaver...${NC}"
  85. cd "$INSTALL_DIR"
  86. if is_docker_mode; then
  87. set_image_tag
  88. sudo -E docker compose up -d
  89. else
  90. sudo systemctl start dune-weaver
  91. fi
  92. echo -e "${GREEN}Started!${NC} Access at http://$(hostname -I | awk '{print $1}'):8080"
  93. }
  94. cmd_stop() {
  95. check_installed
  96. echo -e "${BLUE}Stopping Dune Weaver...${NC}"
  97. cd "$INSTALL_DIR"
  98. if is_docker_mode; then
  99. sudo docker compose down
  100. else
  101. sudo systemctl stop dune-weaver
  102. fi
  103. echo -e "${GREEN}Stopped${NC}"
  104. }
  105. cmd_restart() {
  106. check_installed
  107. echo -e "${BLUE}Restarting Dune Weaver...${NC}"
  108. cd "$INSTALL_DIR"
  109. if is_docker_mode; then
  110. set_image_tag
  111. sudo -E docker compose restart
  112. else
  113. sudo systemctl restart dune-weaver
  114. fi
  115. echo -e "${GREEN}Restarted${NC}"
  116. }
  117. cmd_update() {
  118. check_installed
  119. echo -e "${BLUE}Updating Dune Weaver...${NC}"
  120. cd "$INSTALL_DIR"
  121. # Check if we should skip the pull phase (called after re-exec)
  122. if [[ "$1" != "--continue" ]]; then
  123. echo "Pulling latest code..."
  124. git pull
  125. # Update dw CLI
  126. echo "Updating dw command..."
  127. sudo cp "$INSTALL_DIR/dw" /usr/local/bin/dw
  128. sudo chmod +x /usr/local/bin/dw
  129. # Re-exec with the new script to ensure new code runs
  130. echo "Restarting with updated CLI..."
  131. exec /usr/local/bin/dw update --continue
  132. fi
  133. if is_docker_mode; then
  134. set_image_tag
  135. echo -e "Image tag: ${BLUE}${IMAGE_TAG}${NC}"
  136. echo "Pulling latest Docker image..."
  137. sudo -E docker compose pull
  138. echo "Stopping current container..."
  139. sudo docker compose down
  140. echo "Starting with new version..."
  141. sudo -E docker compose up -d --remove-orphans
  142. echo "Cleaning up unused Docker resources..."
  143. sudo docker image prune -f
  144. sudo docker container prune -f
  145. else
  146. echo "Updating Python dependencies..."
  147. source .venv/bin/activate
  148. pip install -r requirements.txt
  149. echo "Restarting service..."
  150. sudo systemctl restart dune-weaver
  151. fi
  152. # Update touch app if installed (check both directory and service exist)
  153. local touch_dir="$INSTALL_DIR/dune-weaver-touch"
  154. if [[ -d "$touch_dir" ]] && systemctl list-unit-files dune-weaver-touch.service 2>/dev/null | grep -q dune-weaver-touch; then
  155. echo ""
  156. echo -e "${BLUE}Updating touch app...${NC}"
  157. cd "$touch_dir"
  158. # Update Python dependencies (code already pulled with main repo)
  159. if [[ -f "requirements.txt" ]] && [[ -d ".venv" ]]; then
  160. echo "Updating touch app dependencies..."
  161. source .venv/bin/activate
  162. pip install -q -r requirements.txt
  163. deactivate
  164. fi
  165. # Restart to apply changes
  166. sudo systemctl restart dune-weaver-touch
  167. echo -e "${GREEN}Touch app updated!${NC}"
  168. fi
  169. echo -e "${GREEN}Update complete!${NC}"
  170. }
  171. cmd_logs() {
  172. check_installed
  173. cd "$INSTALL_DIR"
  174. # Parse optional line count (e.g., dw logs 100)
  175. local lines="${1:-}"
  176. local follow="-f"
  177. if [[ -n "$lines" ]]; then
  178. follow="--tail $lines"
  179. fi
  180. if is_docker_mode; then
  181. sudo docker compose logs $follow
  182. else
  183. if [[ -n "$lines" ]]; then
  184. sudo journalctl -u dune-weaver -n "$lines"
  185. else
  186. sudo journalctl -u dune-weaver -f
  187. fi
  188. fi
  189. }
  190. cmd_status() {
  191. check_installed
  192. cd "$INSTALL_DIR"
  193. if is_docker_mode; then
  194. sudo docker compose ps
  195. else
  196. sudo systemctl status dune-weaver
  197. fi
  198. }
  199. cmd_shell() {
  200. check_installed
  201. cd "$INSTALL_DIR"
  202. if is_docker_mode; then
  203. sudo docker compose exec dune-weaver /bin/bash
  204. else
  205. echo -e "${YELLOW}Shell not available in systemd mode${NC}"
  206. echo "Use: cd $INSTALL_DIR && source .venv/bin/activate"
  207. fi
  208. }
  209. # Touch app commands (systemd service)
  210. cmd_touch() {
  211. local subcmd="${1:-help}"
  212. case "$subcmd" in
  213. logs)
  214. local lines="${2:-}"
  215. if [[ -n "$lines" ]]; then
  216. sudo journalctl -u dune-weaver-touch -n "$lines"
  217. else
  218. sudo journalctl -u dune-weaver-touch -f
  219. fi
  220. ;;
  221. restart)
  222. echo -e "${BLUE}Restarting touch app...${NC}"
  223. sudo systemctl restart dune-weaver-touch
  224. echo -e "${GREEN}Touch app restarted${NC}"
  225. ;;
  226. stop)
  227. echo -e "${BLUE}Stopping touch app...${NC}"
  228. sudo systemctl stop dune-weaver-touch
  229. echo -e "${GREEN}Touch app stopped${NC}"
  230. ;;
  231. start)
  232. echo -e "${BLUE}Starting touch app...${NC}"
  233. sudo systemctl start dune-weaver-touch
  234. echo -e "${GREEN}Touch app started${NC}"
  235. ;;
  236. status)
  237. sudo systemctl status dune-weaver-touch
  238. ;;
  239. install)
  240. check_installed
  241. local touch_dir="$INSTALL_DIR/dune-weaver-touch"
  242. if [[ ! -f "$touch_dir/install.sh" ]]; then
  243. echo -e "${RED}Touch app installer not found at $touch_dir/install.sh${NC}"
  244. echo "Make sure you have the dune-weaver-touch directory in your dune-weaver folder."
  245. exit 1
  246. fi
  247. echo -e "${BLUE}Running touch app installer...${NC}"
  248. cd "$touch_dir"
  249. sudo bash install.sh
  250. ;;
  251. help|*)
  252. echo -e "${GREEN}Touch App Commands${NC}"
  253. echo ""
  254. echo "Usage: dw touch <command>"
  255. echo ""
  256. echo "Commands:"
  257. echo " install Install touch app (clone, setup, enable service)"
  258. echo " logs [N] View logs (N lines or follow if omitted)"
  259. echo " restart Restart touch app"
  260. echo " stop Stop touch app"
  261. echo " start Start touch app"
  262. echo " status Show touch app status"
  263. echo " help Show this help message"
  264. ;;
  265. esac
  266. }
  267. cmd_checkout() {
  268. check_installed
  269. local branch="$1"
  270. if [[ -z "$branch" ]]; then
  271. echo -e "${RED}Usage: dw checkout <branch>${NC}"
  272. echo ""
  273. echo "Examples:"
  274. echo " dw checkout main"
  275. echo " dw checkout feature/security-settings-split"
  276. echo ""
  277. echo "Current branch: $(git -C "$INSTALL_DIR" rev-parse --abbrev-ref HEAD)"
  278. exit 1
  279. fi
  280. cd "$INSTALL_DIR"
  281. # Repo may be cloned with --single-branch; fetch the target branch explicitly
  282. echo -e "${BLUE}Fetching branch ${branch}...${NC}"
  283. if ! git fetch origin "$branch" 2>/dev/null; then
  284. echo -e "${RED}Branch '${branch}' not found on remote${NC}"
  285. exit 1
  286. fi
  287. # Checkout: create local tracking branch if it doesn't exist
  288. if git show-ref --verify --quiet "refs/heads/$branch"; then
  289. git checkout "$branch"
  290. git pull
  291. else
  292. git checkout -b "$branch" "origin/$branch"
  293. fi
  294. echo -e "Switched to branch: ${GREEN}${branch}${NC}"
  295. # Pull and restart Docker images for the new branch
  296. if is_docker_mode; then
  297. set_image_tag
  298. echo -e "Image tag: ${BLUE}${IMAGE_TAG}${NC}"
  299. echo "Pulling Docker images..."
  300. sudo -E docker compose pull
  301. echo "Restarting with new images..."
  302. sudo docker compose down
  303. sudo -E docker compose up -d --remove-orphans
  304. echo "Cleaning up old images..."
  305. sudo docker image prune -f
  306. fi
  307. # Update dw CLI from the new branch
  308. sudo cp "$INSTALL_DIR/dw" /usr/local/bin/dw
  309. sudo chmod +x /usr/local/bin/dw
  310. echo -e "${GREEN}Checkout complete!${NC}"
  311. }
  312. cmd_help() {
  313. echo -e "${GREEN}Dune Weaver CLI${NC}"
  314. echo ""
  315. echo "Usage: dw <command>"
  316. echo ""
  317. echo "Commands:"
  318. echo " install Run initial setup (Docker + WiFi fix)"
  319. echo " start Start Dune Weaver"
  320. echo " stop Stop Dune Weaver"
  321. echo " restart Restart Dune Weaver"
  322. echo " update Pull latest changes and restart"
  323. echo " checkout Switch to a branch and pull its Docker images"
  324. echo " logs [N] View logs (N=number of lines, or follow if omitted)"
  325. echo " status Show container status"
  326. echo " shell Open a shell in the container"
  327. echo " touch Manage touch screen app (run 'dw touch help')"
  328. echo " help Show this help message"
  329. echo ""
  330. if [[ -n "$INSTALL_DIR" ]]; then
  331. echo -e "Install directory: ${BLUE}$INSTALL_DIR${NC}"
  332. fi
  333. }
  334. # Main
  335. case "${1:-help}" in
  336. install)
  337. shift
  338. cmd_install "$@"
  339. ;;
  340. start)
  341. cmd_start
  342. ;;
  343. stop)
  344. cmd_stop
  345. ;;
  346. restart)
  347. cmd_restart
  348. ;;
  349. update)
  350. cmd_update "$2"
  351. ;;
  352. checkout)
  353. cmd_checkout "$2"
  354. ;;
  355. logs)
  356. cmd_logs "$2"
  357. ;;
  358. status)
  359. cmd_status
  360. ;;
  361. shell)
  362. cmd_shell
  363. ;;
  364. touch)
  365. shift
  366. cmd_touch "$@"
  367. ;;
  368. help|--help|-h)
  369. cmd_help
  370. ;;
  371. *)
  372. echo -e "${RED}Unknown command: $1${NC}"
  373. echo ""
  374. cmd_help
  375. exit 1
  376. ;;
  377. esac