musare.sh 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. #!/bin/bash
  2. export PATH=/usr/local/bin:/usr/bin:/bin
  3. CYAN='\033[33;36m';
  4. RED='\033[0;31m'
  5. YELLOW='\033[0;93m'
  6. GREEN='\033[0;32m'
  7. NC='\033[0m'
  8. scriptLocation=$(dirname -- "$(readlink -fn -- "$0"; echo x)")
  9. cd "${scriptLocation%x}" || exit 1
  10. if [[ -f .env ]]; then
  11. # shellcheck disable=SC1091
  12. source .env
  13. else
  14. echo -e "${RED}Error: .env does not exist${NC}"
  15. exit 2
  16. fi
  17. if [[ -z ${DOCKER_COMMAND} ]]; then
  18. DOCKER_COMMAND="docker"
  19. elif [[ ${DOCKER_COMMAND} != "docker" && ${DOCKER_COMMAND} != "podman" ]]; then
  20. echo -e "${RED}Error: Invalid DOCKER_COMMAND${NC}"
  21. exit 1
  22. fi
  23. docker="${DOCKER_COMMAND}"
  24. ${docker} --version > /dev/null 2>&1
  25. dockerInstalled=$?
  26. dockerCompose="${docker} compose"
  27. ${dockerCompose} version > /dev/null 2>&1
  28. composeInstalled=$?
  29. if [[ ${composeInstalled} -gt 0 ]]; then
  30. dockerCompose="${docker}-compose"
  31. ${dockerCompose} --version > /dev/null 2>&1
  32. composeInstalled=$?
  33. fi
  34. if [[ ${dockerInstalled} -gt 0 || ${composeInstalled} -gt 0 ]]; then
  35. if [[ ${dockerInstalled} -eq 0 && ${composeInstalled} -gt 0 ]]; then
  36. echo -e "${RED}Error: ${dockerCompose} not installed.${NC}"
  37. elif [[ ${dockerInstalled} -gt 0 && ${composeInstalled} -eq 0 ]]; then
  38. echo -e "${RED}Error: ${docker} not installed.${NC}"
  39. else
  40. echo -e "${RED}Error: ${docker} and ${dockerCompose} not installed.${NC}"
  41. fi
  42. exit 1
  43. fi
  44. composeFiles="-f docker-compose.yml"
  45. if [[ ${CONTAINER_MODE} == "dev" ]]; then
  46. composeFiles="${composeFiles} -f docker-compose.dev.yml"
  47. fi
  48. if [[ -f docker-compose.override.yml ]]; then
  49. composeFiles="${composeFiles} -f docker-compose.override.yml"
  50. fi
  51. dockerCompose="${dockerCompose} ${composeFiles}"
  52. handleServices()
  53. {
  54. validServices=($1)
  55. servicesArray=()
  56. invalidServices=false
  57. for x in "${@:2}"; do
  58. if [[ ${validServices[*]} =~ (^|[[:space:]])"$x"($|[[:space:]]) ]]; then
  59. if ! [[ ${servicesArray[*]} =~ (^|[[:space:]])"$x"($|[[:space:]]) ]]; then
  60. servicesArray+=("${x}")
  61. fi
  62. else
  63. if [[ $invalidServices == false ]]; then
  64. invalidServices="${x}"
  65. else
  66. invalidServices="${invalidServices} ${x}"
  67. fi
  68. fi
  69. done
  70. if [[ $invalidServices == false && ${#servicesArray[@]} -gt 0 ]]; then
  71. echo "1|${servicesArray[*]}"
  72. elif [[ $invalidServices == false ]]; then
  73. echo "1|all"
  74. else
  75. echo "0|Invalid Service(s): ${invalidServices}"
  76. fi
  77. }
  78. runDockerCommand()
  79. {
  80. validCommands=(start stop restart pull build ps logs)
  81. if [[ ${validCommands[*]} =~ (^|[[:space:]])"$2"($|[[:space:]]) ]]; then
  82. servicesString=$(handleServices "backend frontend mongo redis" "${@:3}")
  83. if [[ ${servicesString:0:1} == 1 ]]; then
  84. if [[ ${servicesString:2:4} == "all" ]]; then
  85. servicesString=""
  86. pullServices="mongo redis"
  87. buildServices="backend frontend"
  88. else
  89. servicesString=${servicesString:2}
  90. pullArray=()
  91. buildArray=()
  92. if [[ "${servicesString}" == *mongo* ]]; then
  93. pullArray+=("mongo")
  94. fi
  95. if [[ "${servicesString}" == *redis* ]]; then
  96. pullArray+=("redis")
  97. fi
  98. if [[ "${servicesString}" == *backend* ]]; then
  99. buildArray+=("backend")
  100. fi
  101. if [[ "${servicesString}" == *frontend* ]]; then
  102. buildArray+=("frontend")
  103. fi
  104. pullServices="${pullArray[*]}"
  105. buildServices="${buildArray[*]}"
  106. fi
  107. if [[ ${2} == "stop" || ${2} == "restart" ]]; then
  108. # shellcheck disable=SC2086
  109. ${dockerCompose} stop ${servicesString}
  110. fi
  111. if [[ ${2} == "start" || ${2} == "restart" ]]; then
  112. # shellcheck disable=SC2086
  113. ${dockerCompose} up -d ${servicesString}
  114. fi
  115. if [[ ${2} == "pull" && ${pullServices} != "" ]]; then
  116. # shellcheck disable=SC2086
  117. ${dockerCompose} "${2}" ${pullServices}
  118. fi
  119. if [[ ${2} == "build" && ${buildServices} != "" ]]; then
  120. # shellcheck disable=SC2086
  121. ${dockerCompose} "${2}" ${buildServices}
  122. fi
  123. if [[ ${2} == "ps" || ${2} == "logs" ]]; then
  124. # shellcheck disable=SC2086
  125. ${dockerCompose} "${2}" ${servicesString}
  126. fi
  127. exitValue=$?
  128. if [[ ${exitValue} -gt 0 ]]; then
  129. exit ${exitValue}
  130. fi
  131. else
  132. echo -e "${RED}${servicesString:2}\n${YELLOW}Usage: ${1} [backend, frontend, mongo, redis]${NC}"
  133. exit 1
  134. fi
  135. else
  136. echo -e "${RED}Error: Invalid runDockerCommand input${NC}"
  137. exit 1
  138. fi
  139. }
  140. getContainerId()
  141. {
  142. if [[ ${DOCKER_COMMAND} == "docker" ]]; then
  143. containerId=$(${dockerCompose} ps -q "${1}")
  144. else
  145. containerId=$(${dockerCompose} ps | sed '0,/CONTAINER/d' | awk "/${1}/ {print \$1;exit}")
  146. fi
  147. echo "${containerId}"
  148. }
  149. case $1 in
  150. start)
  151. echo -e "${CYAN}Musare | Start Services${NC}"
  152. # shellcheck disable=SC2068
  153. runDockerCommand "$(basename "$0") $1" start ${@:2}
  154. ;;
  155. stop)
  156. echo -e "${CYAN}Musare | Stop Services${NC}"
  157. # shellcheck disable=SC2068
  158. runDockerCommand "$(basename "$0") $1" stop ${@:2}
  159. ;;
  160. restart)
  161. echo -e "${CYAN}Musare | Restart Services${NC}"
  162. # shellcheck disable=SC2068
  163. runDockerCommand "$(basename "$0") $1" restart ${@:2}
  164. ;;
  165. build)
  166. echo -e "${CYAN}Musare | Build Services${NC}"
  167. # shellcheck disable=SC2068
  168. runDockerCommand "$(basename "$0") $1" pull ${@:2}
  169. # shellcheck disable=SC2068
  170. runDockerCommand "$(basename "$0") $1" build ${@:2}
  171. ;;
  172. status)
  173. echo -e "${CYAN}Musare | Service Status${NC}"
  174. # shellcheck disable=SC2068
  175. runDockerCommand "$(basename "$0") $1" ps ${@:2}
  176. ;;
  177. reset)
  178. echo -e "${CYAN}Musare | Reset Services${NC}"
  179. servicesString=$(handleServices "backend frontend mongo redis" "${@:2}")
  180. if [[ ${servicesString:0:1} == 1 && ${servicesString:2:4} == "all" ]]; then
  181. echo -e "${RED}Resetting will remove the ${REDIS_DATA_LOCATION} and ${MONGO_DATA_LOCATION} directories.${NC}"
  182. echo -e "${GREEN}Are you sure you want to reset all data? ${YELLOW}[y,n]: ${NC}"
  183. read -r confirm
  184. if [[ "${confirm}" == y* ]]; then
  185. runDockerCommand "$(basename "$0") $1" stop
  186. ${dockerCompose} rm -v --force
  187. if [[ -d $REDIS_DATA_LOCATION ]]; then
  188. rm -rf "${REDIS_DATA_LOCATION}"
  189. fi
  190. if [[ -d $MONGO_DATA_LOCATION ]]; then
  191. rm -rf "${MONGO_DATA_LOCATION}"
  192. fi
  193. else
  194. echo -e "${RED}Cancelled reset${NC}"
  195. fi
  196. elif [[ ${servicesString:0:1} == 1 ]]; then
  197. if [[ "${servicesString:2}" == *redis* && "${servicesString:2}" == *mongo* ]]; then
  198. echo -e "${RED}Resetting will remove the ${REDIS_DATA_LOCATION} and ${MONGO_DATA_LOCATION} directories.${NC}"
  199. elif [[ "${servicesString:2}" == *redis* ]]; then
  200. echo -e "${RED}Resetting will remove the ${REDIS_DATA_LOCATION} directory.${NC}"
  201. elif [[ "${servicesString:2}" == *mongo* ]]; then
  202. echo -e "${RED}Resetting will remove the ${MONGO_DATA_LOCATION} directory.${NC}"
  203. fi
  204. echo -e "${GREEN}Are you sure you want to reset all data for $(echo "${servicesString:2}" | tr ' ' ',')? ${YELLOW}[y,n]: ${NC}"
  205. read -r confirm
  206. if [[ "${confirm}" == y* ]]; then
  207. # shellcheck disable=SC2086
  208. runDockerCommand "$(basename "$0") $1" stop ${servicesString:2}
  209. # shellcheck disable=SC2086
  210. ${dockerCompose} rm -v --force ${servicesString}
  211. if [[ "${servicesString:2}" == *redis* && -d $REDIS_DATA_LOCATION ]]; then
  212. rm -rf "${REDIS_DATA_LOCATION}"
  213. fi
  214. if [[ "${servicesString:2}" == *mongo* && -d $MONGO_DATA_LOCATION ]]; then
  215. rm -rf "${MONGO_DATA_LOCATION}"
  216. fi
  217. else
  218. echo -e "${RED}Cancelled reset${NC}"
  219. fi
  220. else
  221. echo -e "${RED}${servicesString:2}\n${YELLOW}Usage: $(basename "$0") build [backend, frontend, mongo, redis]${NC}"
  222. exit 1
  223. fi
  224. ;;
  225. attach)
  226. echo -e "${CYAN}Musare | Attach${NC}"
  227. if [[ $2 == "backend" ]]; then
  228. containerId=$(getContainerId backend)
  229. if [[ -z $containerId ]]; then
  230. echo -e "${RED}Error: Backend offline, please start to attach.${NC}"
  231. exit 1
  232. else
  233. echo -e "${YELLOW}Detach with CTRL+P+Q${NC}"
  234. ${docker} attach "$containerId"
  235. fi
  236. elif [[ $2 == "mongo" ]]; then
  237. MONGO_VERSION_INT=${MONGO_VERSION:0:1}
  238. if [[ -z $(getContainerId mongo) ]]; then
  239. echo -e "${RED}Error: Mongo offline, please start to attach.${NC}"
  240. exit 1
  241. else
  242. echo -e "${YELLOW}Detach with CTRL+D${NC}"
  243. if [[ $MONGO_VERSION_INT -ge 5 ]]; then
  244. ${dockerCompose} exec mongo mongosh musare -u "${MONGO_USER_USERNAME}" -p "${MONGO_USER_PASSWORD}" --eval "disableTelemetry()" --shell
  245. else
  246. ${dockerCompose} exec mongo mongo musare -u "${MONGO_USER_USERNAME}" -p "${MONGO_USER_PASSWORD}"
  247. fi
  248. fi
  249. elif [[ $2 == "redis" ]]; then
  250. if [[ -z $(getContainerId redis) ]]; then
  251. echo -e "${RED}Error: Redis offline, please start to attach.${NC}"
  252. exit 1
  253. else
  254. echo -e "${YELLOW}Detach with CTRL+C${NC}"
  255. ${dockerCompose} exec redis redis-cli -a "${REDIS_PASSWORD}"
  256. fi
  257. else
  258. echo -e "${RED}Invalid service $2\n${YELLOW}Usage: $(basename "$0") attach [backend,mongo,redis]${NC}"
  259. exit 1
  260. fi
  261. ;;
  262. lint|eslint)
  263. echo -e "${CYAN}Musare | Lint${NC}"
  264. services=$(sed "s/\(\ \)\{0,1\}\(-\)\{0,2\}fix//g;t;q1" <<< "${@:2}")
  265. fixFound=$?
  266. if [[ $fixFound -eq 0 ]]; then
  267. fix="--fix"
  268. echo -e "${GREEN}Auto-fix enabled${NC}"
  269. fi
  270. services=$(sed "s/\(\ \)\{0,1\}\(-\)\{0,2\}no-cache//g;t;q1" <<< "${services}")
  271. noCacheFound=$?
  272. cache="--cache"
  273. if [[ $noCacheFound -eq 0 ]]; then
  274. cache=""
  275. echo -e "${YELLOW}ESlint cache disabled${NC}"
  276. fi
  277. # shellcheck disable=SC2068
  278. servicesString=$(handleServices "backend frontend docs" ${services[@]})
  279. if [[ ${servicesString:0:1} == 1 ]]; then
  280. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *frontend* ]]; then
  281. echo -e "${CYAN}Running frontend lint...${NC}"
  282. ${dockerCompose} exec -T frontend npx eslint $cache src --ext .js,.ts,.vue $fix
  283. frontendExitValue=$?
  284. fi
  285. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *backend* ]]; then
  286. echo -e "${CYAN}Running backend lint...${NC}"
  287. ${dockerCompose} exec -T backend npx eslint $cache logic $fix
  288. backendExitValue=$?
  289. fi
  290. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *docs* ]]; then
  291. echo -e "${CYAN}Running docs lint...${NC}"
  292. ${docker} run -v "${scriptLocation}":/workdir ghcr.io/igorshubovych/markdownlint-cli:latest ".wiki" "*.md" $fix
  293. docsExitValue=$?
  294. fi
  295. if [[ ${frontendExitValue} -gt 0 || ${backendExitValue} -gt 0 || ${docsExitValue} -gt 0 ]]; then
  296. exitValue=1
  297. else
  298. exitValue=0
  299. fi
  300. else
  301. echo -e "${RED}${servicesString:2}\n${YELLOW}Usage: $(basename "$0") lint [backend, frontend, docs] [fix]${NC}"
  302. exitValue=1
  303. fi
  304. if [[ ${exitValue} -gt 0 ]]; then
  305. exit ${exitValue}
  306. fi
  307. ;;
  308. typescript|ts)
  309. echo -e "${CYAN}Musare | TypeScript Check${NC}"
  310. services=$(sed "s/\(\ \)\{0,1\}\(-\)\{0,2\}strict//g;t;q1" <<< "${@:2}")
  311. strictFound=$?
  312. if [[ $strictFound -eq 0 ]]; then
  313. strict="--strict"
  314. echo -e "${GREEN}Strict mode enabled${NC}"
  315. fi
  316. # shellcheck disable=SC2068
  317. servicesString=$(handleServices "backend frontend" ${services[@]})
  318. if [[ ${servicesString:0:1} == 1 ]]; then
  319. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *frontend* ]]; then
  320. echo -e "${CYAN}Running frontend typescript check...${NC}"
  321. ${dockerCompose} exec -T frontend npm run typescript -- $strict
  322. frontendExitValue=$?
  323. fi
  324. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *backend* ]]; then
  325. echo -e "${CYAN}Running backend typescript check...${NC}"
  326. ${dockerCompose} exec -T backend npm run typescript -- $strict
  327. backendExitValue=$?
  328. fi
  329. if [[ ${frontendExitValue} -gt 0 || ${backendExitValue} -gt 0 ]]; then
  330. exitValue=1
  331. else
  332. exitValue=0
  333. fi
  334. else
  335. echo -e "${RED}${servicesString:2}\n${YELLOW}Usage: $(basename "$0") typescript [backend, frontend] [strict]${NC}"
  336. exitValue=1
  337. fi
  338. if [[ ${exitValue} -gt 0 ]]; then
  339. exit ${exitValue}
  340. fi
  341. ;;
  342. test)
  343. echo -e "${CYAN}Musare | Test${NC}"
  344. servicesString=$(handleServices "frontend" "${@:2}")
  345. if [[ ${servicesString:0:1} == 1 ]]; then
  346. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *frontend* ]]; then
  347. echo -e "${CYAN}Running frontend tests...${NC}"
  348. ${dockerCompose} exec -T frontend npm run test -- --run
  349. frontendExitValue=$?
  350. fi
  351. if [[ ${frontendExitValue} -gt 0 ]]; then
  352. exitValue=1
  353. else
  354. exitValue=0
  355. fi
  356. else
  357. echo -e "${RED}${servicesString:2}\n${YELLOW}Usage: $(basename "$0") test [frontend]${NC}"
  358. exitValue=1
  359. fi
  360. if [[ ${exitValue} -gt 0 ]]; then
  361. exit ${exitValue}
  362. fi
  363. ;;
  364. test:coverage)
  365. echo -e "${CYAN}Musare | Test Coverage${NC}"
  366. servicesString=$(handleServices "frontend" "${@:2}")
  367. if [[ ${servicesString:0:1} == 1 ]]; then
  368. if [[ ${servicesString:2:4} == "all" || "${servicesString:2}" == *frontend* ]]; then
  369. echo -e "${CYAN}Running frontend test coverage report...${NC}"
  370. ${dockerCompose} exec -T frontend npm run coverage
  371. frontendExitValue=$?
  372. fi
  373. if [[ ${frontendExitValue} -gt 0 ]]; then
  374. exitValue=1
  375. else
  376. exitValue=0
  377. fi
  378. else
  379. echo -e "${RED}${servicesString:2}\n${YELLOW}Usage: $(basename "$0") test:coverage [frontend]${NC}"
  380. exitValue=1
  381. fi
  382. if [[ ${exitValue} -gt 0 ]]; then
  383. exit ${exitValue}
  384. fi
  385. ;;
  386. update)
  387. echo -e "${CYAN}Musare | Update${NC}"
  388. musareshModified=$(git diff HEAD -- musare.sh)
  389. git fetch
  390. exitValue=$?
  391. if [[ ${exitValue} -gt 0 ]]; then
  392. exit ${exitValue}
  393. fi
  394. updated=$(git log --name-only --oneline HEAD..@\{u\})
  395. if [[ ${updated} == "" ]]; then
  396. echo -e "${GREEN}Already up to date${NC}"
  397. exit ${exitValue}
  398. fi
  399. musareshChange=$(echo "${updated}" | grep "musare.sh")
  400. dbChange=$(echo "${updated}" | grep "backend/logic/db/schemas")
  401. fcChange=$(echo "${updated}" | grep "frontend/dist/config/template.json")
  402. bcChange=$(echo "${updated}" | grep "backend/config/template.json")
  403. if [[ ( $2 == "auto" && -z $dbChange && -z $fcChange && -z $bcChange && -z $musareshChange ) || -z $2 ]]; then
  404. if [[ -n $musareshChange && $(git diff @\{u\} -- musare.sh) != "" ]]; then
  405. if [[ $musareshModified != "" ]]; then
  406. echo -e "${RED}musare.sh has been modified, please reset these changes and run the update command again to continue.${NC}"
  407. else
  408. git checkout @\{u\} -- musare.sh
  409. echo -e "${YELLOW}musare.sh has been updated, please run the update command again to continue.${NC}"
  410. fi
  411. exit 1
  412. else
  413. git pull
  414. exitValue=$?
  415. if [[ ${exitValue} -gt 0 ]]; then
  416. exit ${exitValue}
  417. fi
  418. echo -e "${CYAN}Updating...${NC}"
  419. runDockerCommand "$(basename "$0") $1" pull
  420. runDockerCommand "$(basename "$0") $1" build
  421. runDockerCommand "$(basename "$0") $1" restart
  422. echo -e "${GREEN}Updated!${NC}"
  423. if [[ -n $dbChange ]]; then
  424. echo -e "${RED}Database schema has changed, please run migration!${NC}"
  425. fi
  426. if [[ -n $fcChange ]]; then
  427. echo -e "${RED}Frontend config has changed, please update!${NC}"
  428. fi
  429. if [[ -n $bcChange ]]; then
  430. echo -e "${RED}Backend config has changed, please update!${NC}"
  431. fi
  432. fi
  433. elif [[ $2 == "auto" ]]; then
  434. echo -e "${RED}Auto Update Failed! musare.sh, database and/or config has changed!${NC}"
  435. exit 1
  436. fi
  437. ;;
  438. logs)
  439. echo -e "${CYAN}Musare | Logs${NC}"
  440. # shellcheck disable=SC2068
  441. runDockerCommand "$(basename "$0") $1" logs ${@:2}
  442. ;;
  443. backup)
  444. echo -e "${CYAN}Musare | Backup${NC}"
  445. if [[ -z "${BACKUP_LOCATION}" ]]; then
  446. backupLocation="${scriptLocation%x}/backups"
  447. else
  448. backupLocation="${BACKUP_LOCATION%/}"
  449. fi
  450. if [[ ! -d "${backupLocation}" ]]; then
  451. echo -e "${YELLOW}Creating backup directory at ${backupLocation}${NC}"
  452. mkdir "${backupLocation}"
  453. fi
  454. if [[ -z "${BACKUP_NAME}" ]]; then
  455. backupLocation="${backupLocation}/musare-$(date +"%Y-%m-%d-%s").dump"
  456. else
  457. backupLocation="${backupLocation}/${BACKUP_NAME}"
  458. fi
  459. echo -e "${YELLOW}Creating backup at ${backupLocation}${NC}"
  460. ${dockerCompose} exec -T mongo sh -c "mongodump --authenticationDatabase musare -u ${MONGO_USER_USERNAME} -p ${MONGO_USER_PASSWORD} -d musare --archive" > "${backupLocation}"
  461. ;;
  462. restore)
  463. echo -e "${CYAN}Musare | Restore${NC}"
  464. if [[ -z $2 ]]; then
  465. echo -e "${GREEN}Please enter the full path of the dump you wish to restore: ${NC}"
  466. read -r restoreFile
  467. else
  468. restoreFile=$2
  469. fi
  470. if [[ -z ${restoreFile} ]]; then
  471. echo -e "${RED}Error: no restore path given, cancelled restoration.${NC}"
  472. exit 1
  473. elif [[ -d ${restoreFile} ]]; then
  474. echo -e "${RED}Error: restore path given is a directory, cancelled restoration.${NC}"
  475. exit 1
  476. elif [[ ! -f ${restoreFile} ]]; then
  477. echo -e "${RED}Error: no file at restore path given, cancelled restoration.${NC}"
  478. exit 1
  479. else
  480. ${dockerCompose} exec -T mongo sh -c "mongorestore --authenticationDatabase musare -u ${MONGO_USER_USERNAME} -p ${MONGO_USER_PASSWORD} --archive" < "${restoreFile}"
  481. fi
  482. ;;
  483. admin)
  484. echo -e "${CYAN}Musare | Add Admin${NC}"
  485. MONGO_VERSION_INT=${MONGO_VERSION:0:1}
  486. if [[ $2 == "add" ]]; then
  487. if [[ -z $3 ]]; then
  488. echo -e "${GREEN}Please enter the username of the user you wish to make an admin: ${NC}"
  489. read -r adminUser
  490. else
  491. adminUser=$3
  492. fi
  493. if [[ -z $adminUser ]]; then
  494. echo -e "${RED}Error: Username for new admin not provided.${NC}"
  495. exit 1
  496. else
  497. if [[ $MONGO_VERSION_INT -ge 5 ]]; then
  498. ${dockerCompose} exec mongo mongosh musare -u "${MONGO_USER_USERNAME}" -p "${MONGO_USER_PASSWORD}" --eval "disableTelemetry(); db.users.updateOne({username: '${adminUser}'}, {\$set: {role: 'admin'}})"
  499. else
  500. ${dockerCompose} exec mongo mongo musare -u "${MONGO_USER_USERNAME}" -p "${MONGO_USER_PASSWORD}" --eval "db.users.updateOne({username: '${adminUser}'}, {\$set: {role: 'admin'}})"
  501. fi
  502. fi
  503. elif [[ $2 == "remove" ]]; then
  504. if [[ -z $3 ]]; then
  505. echo -e "${GREEN}Please enter the username of the user you wish to remove as admin: ${NC}"
  506. read -r adminUser
  507. else
  508. adminUser=$3
  509. fi
  510. if [[ -z $adminUser ]]; then
  511. echo -e "${RED}Error: Username for new admin not provided.${NC}"
  512. exit 1
  513. else
  514. if [[ $MONGO_VERSION_INT -ge 5 ]]; then
  515. ${dockerCompose} exec mongo mongosh musare -u "${MONGO_USER_USERNAME}" -p "${MONGO_USER_PASSWORD}" --eval "disableTelemetry(); db.users.updateOne({username: '${adminUser}'}, {\$set: {role: 'default'}})"
  516. else
  517. ${dockerCompose} exec mongo mongo musare -u "${MONGO_USER_USERNAME}" -p "${MONGO_USER_PASSWORD}" --eval "db.users.updateOne({username: '${adminUser}'}, {\$set: {role: 'default'}})"
  518. fi
  519. fi
  520. else
  521. echo -e "${RED}Invalid command $2\n${YELLOW}Usage: $(basename "$0") admin [add,remove] username${NC}"
  522. exit 1
  523. fi
  524. ;;
  525. "")
  526. echo -e "${CYAN}Musare | Available Commands${NC}"
  527. echo -e "${YELLOW}start - Start services${NC}"
  528. echo -e "${YELLOW}stop - Stop services${NC}"
  529. echo -e "${YELLOW}restart - Restart services${NC}"
  530. echo -e "${YELLOW}status - Service status${NC}"
  531. echo -e "${YELLOW}logs - View logs for services${NC}"
  532. echo -e "${YELLOW}update - Update Musare${NC}"
  533. echo -e "${YELLOW}attach [backend,mongo,redis] - Attach to backend service, mongo or redis shell${NC}"
  534. echo -e "${YELLOW}build - Build services${NC}"
  535. echo -e "${YELLOW}lint - Run lint on frontend, backend and/or docs${NC}"
  536. echo -e "${YELLOW}backup - Backup database data to file${NC}"
  537. echo -e "${YELLOW}restore - Restore database data from backup file${NC}"
  538. echo -e "${YELLOW}reset - Reset service data${NC}"
  539. echo -e "${YELLOW}admin [add,remove] - Assign/unassign admin role to/from a user${NC}"
  540. echo -e "${YELLOW}typescript - Run typescript checks on frontend and/or backend${NC}"
  541. ;;
  542. *)
  543. echo -e "${CYAN}Musare${NC}"
  544. echo -e "${RED}Error: Invalid Command $1${NC}"
  545. echo -e "${CYAN}Available Commands:${NC}"
  546. echo -e "${YELLOW}start - Start services${NC}"
  547. echo -e "${YELLOW}stop - Stop services${NC}"
  548. echo -e "${YELLOW}restart - Restart services${NC}"
  549. echo -e "${YELLOW}status - Service status${NC}"
  550. echo -e "${YELLOW}logs - View logs for services${NC}"
  551. echo -e "${YELLOW}update - Update Musare${NC}"
  552. echo -e "${YELLOW}attach [backend,mongo,redis] - Attach to backend service, mongo or redis shell${NC}"
  553. echo -e "${YELLOW}build - Build services${NC}"
  554. echo -e "${YELLOW}lint - Run lint on frontend, backend and/or docs${NC}"
  555. echo -e "${YELLOW}backup - Backup database data to file${NC}"
  556. echo -e "${YELLOW}restore - Restore database data from backup file${NC}"
  557. echo -e "${YELLOW}reset - Reset service data${NC}"
  558. echo -e "${YELLOW}admin [add,remove] - Assign/unassign admin role to/from a user${NC}"
  559. echo -e "${YELLOW}typescript - Run typescript checks on frontend and/or backend${NC}"
  560. exit 1
  561. ;;
  562. esac