musare.sh 24 KB

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