menu_functions.sh 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. # The options menu and all its associated functions
  2. # Options are only shown if relevant in that moment (e.g. "setup" only if service is already configured, "configure" only if service has not yet been configured, "reconfigure" if service is already configured, "destroy" only if it has been configured or installed etc...)
  3. # Services marked orange are configured but not installed.
  4. # Services marked green are installed and running
  5. # If containers of a service are currently stopped the services will say (stopped) behind the service name. This only works if the service has been stopped via the dockerbunker menu, because only then the service is marked as stopped in dockerbunker.env
  6. options_menu() {
  7. COLUMNS=12
  8. exitmenu=$(printf "\e[1;4;33mExit\e[0m")
  9. returntopreviousmenu=$(printf "\e[1;4;33mReturn to previous menu\e[0m")
  10. container_check=1
  11. # if service is marked as installed, make sure all containers exist and offer to run them if necessary
  12. if elementInArray "${PROPER_NAME}" "${INSTALLED_SERVICES[@]}";then
  13. for container in "${containers[@]}";do
  14. RUNNING=$(docker ps -a -q --filter name=^/${container}$)
  15. if [[ -z ${RUNNING} ]];then
  16. echo -e "\n\e[3m$container container missing\e[0m\n"
  17. missingContainers=( "$container" )
  18. prompt_confirm "Restore $container?"
  19. if [[ $? == 0 ]];then
  20. restore_container
  21. fi
  22. fi
  23. RUNNING=$(docker ps -a -q --filter name=^/${container}$)
  24. [[ ${RUNNING} ]] && missingContainers=( "${missingContainers[@]}/$container" )
  25. done
  26. fi
  27. if [[ $RUNNING ]];then
  28. menu=( "Reconfigure service" "Reinstall service" "Backup Service" "Upgrade Image(s)" "Destroy \"${PROPER_NAME}\"" "$exitmenu" )
  29. add_ssl_menuentry menu 2
  30. if elementInArray "${PROPER_NAME}" "${STOPPED_SERVICES[@]}";then
  31. insert menu "Start container(s)" 3
  32. else
  33. insert menu "Restart container(s)" 3
  34. insert menu "Stop container(s)" 4
  35. fi
  36. [[ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME} ]] \
  37. && [[ $(ls -A "${BASE_DIR}"/data/backup/${SERVICE_NAME}) ]] \
  38. && insert menu "Restore Service" 6
  39. elif [[ ${missingContainers[@]} ]];then
  40. echo -e "\n\n\e[3m\xe2\x86\x92 \e[3mThe following containers are missing\e[0m"
  41. for container in "${missingContainers[@]}";do echo -e "\n - $container";done
  42. menu=( "Restore missing containers" "Reconfigure service" "Reinstall service" "Backup Service" "Destroy \"${PROPER_NAME}\"" "$exitmenu" )
  43. elif [[ $RUNNING = false ]];then
  44. menu=( "Reconfigure service" "Reinstall service" "Backup Service" "Start container(s)" "Destroy \"${PROPER_NAME}\"" "$exitmenu" )
  45. add_ssl_menuentry menu 2
  46. [[ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME} ]] \
  47. && [[ $(ls -A "${BASE_DIR}"/data/backup/${SERVICE_NAME}) ]] \
  48. && insert menu "Restore Service" 3
  49. else
  50. if ! elementInArray "${PROPER_NAME}" "${CONFIGURED_SERVICES[@]}" \
  51. && ! elementInArray "${PROPER_NAME}" "${INSTALLED_SERVICES[@]}" \
  52. && [[ ! -f "${ENV_DIR}"/${SERVICE_NAME}.env ]];then
  53. [[ ${STATIC} \
  54. && $(ls -A "${ENV_DIR}"/static) ]] \
  55. && menu=( "Configure Site" "Manage Sites" "$exitmenu" ) \
  56. || menu=( "Configure Service" "$exitmenu" )
  57. [[ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME} ]] \
  58. && [[ "${BASE_DIR}"/data/backup/${SERVICE_NAME} ]] \
  59. && [[ $(ls -A "${BASE_DIR}"/data/backup/${SERVICE_NAME}) ]] \
  60. && insert menu "Restore Service" 1
  61. elif ! elementInArray "${PROPER_NAME}" "${CONFIGURED_SERVICES[@]}" \
  62. && ! elementInArray "${PROPER_NAME}" "${INSTALLED_SERVICES[@]}";then
  63. menu=( "Destroy \"${PROPER_NAME}\"" "$exitmenu" )
  64. [[ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME} ]] \
  65. && [[ $(ls -A "${BASE_DIR}"/data/backup/${SERVICE_NAME}) ]] \
  66. && insert menu "Restore Service" 1
  67. error="Environment file found but ${PROPER_NAME} is not marked as configured or installed. Please destroy first!"
  68. elif elementInArray "${PROPER_NAME}" "${CONFIGURED_SERVICES[@]}" \
  69. && [[ ! -f "${ENV_DIR}"/${SERVICE_NAME}.env ]];then
  70. error="Service marked as configured, but configuration file is missing. Please destroy first."
  71. menu=( "Destroy \"${PROPER_NAME}\"" "$exitmenu" )
  72. [[ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME} ]] \
  73. && [[ $(ls -A "${BASE_DIR}"/data/backup/${SERVICE_NAME}) ]] \
  74. && insert menu "Restore Service" 1
  75. elif elementInArray "${PROPER_NAME}" "${CONFIGURED_SERVICES[@]}" \
  76. && [[ -f "${ENV_DIR}"/${SERVICE_NAME}.env ]];then
  77. menu=( "Reconfigure service" "Setup service" "Destroy \"${PROPER_NAME}\"" "$exitmenu" )
  78. [[ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME} ]] \
  79. && [[ $(ls -A "${BASE_DIR}"/data/backup/${SERVICE_NAME}) ]] \
  80. && insert menu "Restore Service" 2
  81. fi
  82. fi
  83. echo ""
  84. echo -e "\e[4m${PROPER_NAME}\e[0m"
  85. if [[ $error ]];then
  86. echo -e "\n\e[3m$error\e[0m\n"
  87. fi
  88. select choice in "${menu[@]}"
  89. do
  90. case $choice in
  91. "Configure Site")
  92. echo -e "\n\e[3m\xe2\x86\x92 Configure ${PROPER_NAME}\e[0m\n"
  93. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh configure
  94. say_done
  95. sleep 0.2
  96. break
  97. ;;
  98. "Configure Service")
  99. echo -e "\n\e[3m\xe2\x86\x92 Configure ${PROPER_NAME}\e[0m\n"
  100. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh configure
  101. sleep 0.2
  102. break
  103. ;;
  104. "Manage Sites")
  105. echo -e "\n\e[3m\xe2\x86\x92 Manage sites\e[0m"
  106. static_menu
  107. sleep 0.2
  108. break
  109. ;;
  110. "Reconfigure service")
  111. echo -e "\n\e[3m\xe2\x86\x92 Reconfigure ${PROPER_NAME}\e[0m"
  112. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh reconfigure
  113. break
  114. ;;
  115. "Setup service")
  116. # Set up nginx container if not yet present
  117. setup_nginx
  118. echo -e "\n\e[3m\xe2\x86\x92 Setup ${PROPER_NAME}\e[0m"
  119. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh setup
  120. sleep 0.2
  121. break
  122. ;;
  123. "Reinstall service")
  124. echo -e "\n\e[3m\xe2\x86\x92 Reinstall ${PROPER_NAME}\e[0m"
  125. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh reinstall
  126. say_done
  127. sleep 0.2
  128. break
  129. ;;
  130. "Restore missing containers")
  131. echo -e "\n\e[3m\xe2\x86\x92 Restoring containers\e[0m"
  132. for container in ${missingContainers[@]};do
  133. restore_container
  134. done
  135. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh
  136. ;;
  137. "Upgrade Image(s)")
  138. echo -e "\n\e[3m\xe2\x86\x92 Upgrade ${PROPER_NAME} images\e[0m"
  139. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh upgrade
  140. say_done
  141. sleep 0.2
  142. break
  143. ;;
  144. "Backup Service")
  145. echo -e "\n\e[3m\xe2\x86\x92 Backup Service\e[0m"
  146. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh backup
  147. say_done
  148. sleep 0.2
  149. break
  150. ;;
  151. "Restore Service")
  152. echo -e "\n\e[3m\xe2\x86\x92 Restore Service\e[0m"
  153. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh restore
  154. say_done
  155. sleep 0.2
  156. break
  157. ;;
  158. "Generate self-signed certificate")
  159. generate_certificate
  160. restart_nginx
  161. say_done
  162. sleep 0.2
  163. break
  164. ;;
  165. "Obtain Let's Encrypt certificate")
  166. get_le_cert
  167. say_done
  168. sleep 0.2
  169. exit
  170. ;;
  171. "Renew Let's Encrypt certificate")
  172. get_le_cert renew
  173. say_done
  174. sleep 0.2
  175. exit
  176. ;;
  177. "Restart container(s)")
  178. echo -e "\n\e[3m\xe2\x86\x92 Restart ${PROPER_NAME} Containers\e[0m"
  179. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh restart_containers
  180. say_done
  181. sleep 0.2
  182. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh
  183. break
  184. ;;
  185. "Start container(s)")
  186. echo -e "\n\e[3m\xe2\x86\x92 Start ${PROPER_NAME} Containers\e[0m"
  187. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh start_containers
  188. say_done
  189. sleep 0.2
  190. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh
  191. break
  192. ;;
  193. "Stop container(s)")
  194. echo -e "\n\e[3m\xe2\x86\x92 Stop ${PROPER_NAME} Containers\e[0m"
  195. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh stop_containers
  196. say_done
  197. sleep 0.2
  198. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh
  199. break
  200. ;;
  201. "Destroy \"${PROPER_NAME}\"")
  202. echo -e "\n\e[3m\xe2\x86\x92 Destroy ${PROPER_NAME}\e[0m"
  203. echo ""
  204. echo "The following will be removed:"
  205. echo ""
  206. for container in ${containers[@]};do
  207. [[ $(docker ps -a -q --filter name=^/${container}$) ]] \
  208. && containers_found+=( $container )
  209. done
  210. [[ ${containers_found[0]} ]] \
  211. && echo "- ${PROPER_NAME} container(s)"
  212. for volume in ${volumes[@]};do
  213. [[ $(docker volume ls -q --filter name=^${volume}$) ]] \
  214. && volumes_found+=( $volume )
  215. done
  216. [[ ${volumes_found[0]} ]] \
  217. && echo "- ${PROPER_NAME} volume(s)"
  218. [[ -f "${ENV_DIR}"/static/${SERVICE_DOMAIN[0]}.env \
  219. || -f "${ENV_DIR}"/${SERVICE_NAME}.env ]] \
  220. && echo "- ${PROPER_NAME} environment file(s)"
  221. [[ -d "${CONF_DIR}"/${SERVICE_NAME} ]] \
  222. && echo "- ${PROPER_NAME} config file(s)"
  223. [[ -f "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf \
  224. || -f "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf ]] \
  225. && echo "- nginx configuration of ${SERVICE_DOMAIN[0]}"
  226. [[ ${SERVICE_DOMAIN[0]} \
  227. && -d "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]} ]] \
  228. && echo "- self-signed certificate for ${SERVICE_DOMAIN[0]}"
  229. echo ""
  230. prompt_confirm "Continue?" \
  231. && prompt_confirm "Are you sure?" \
  232. && . "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh destroy_service
  233. say_done
  234. sleep 0.2
  235. exec ${BASE_DIR}/dockerbunker.sh
  236. ;;
  237. "$exitmenu")
  238. exit 0
  239. ;;
  240. *)
  241. echo "Invalid option."
  242. ;;
  243. esac
  244. done
  245. }
  246. get_le_cert() {
  247. if ! [[ $1 == "renew" ]];then
  248. echo -e "\n\e[3m\xe2\x86\x92 Obtain Let's Encrypt certificate\e[0m"
  249. [[ -z ${LE_EMAIL} ]] && get_le_email
  250. if [[ ${STATIC} ]];then
  251. sed -i "s/SSL_CHOICE=.*/SSL_CHOICE=le/" "${ENV_DIR}"/static/${SERVICE_DOMAIN[0]}.env
  252. sed -i "s/LE_EMAIL=.*/LE_EMAIL="${LE_EMAIL}"/" "${ENV_DIR}"/static/${SERVICE_DOMAIN[0]}.env
  253. else
  254. sed -i "s/SSL_CHOICE=.*/SSL_CHOICE=le/" "${SERVICE_ENV}"
  255. sed -i "s/LE_EMAIL=.*/LE_EMAIL="${LE_EMAIL}"/" "${SERVICE_ENV}"
  256. fi
  257. elementInArray "${PROPER_NAME}" "${STOPPED_SERVICES[@]}" \
  258. && "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh start_containers
  259. if [[ ${SERVICE_DOMAIN[0]} && -d "${CONF_DIR}"/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} \
  260. && ! -L "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/cert.pem ]];then
  261. # Back up self-signed certificate
  262. mv "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/cert.{pem,pem.backup}
  263. mv "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/key.{pem,pem.backup}
  264. # Symlink letsencrypt certificate
  265. ln -sf "/etc/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]}/fullchain.pem" "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/cert.pem
  266. ln -sf "/etc/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]}/privkey.pem" "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/key.pem
  267. fi
  268. letsencrypt issue
  269. else
  270. echo -e "\n\e[3m\xe2\x86\x92 Renew Let's Encrypt certificate\e[0m"
  271. export prevent_nginx_restart=1
  272. bash "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh letsencrypt issue
  273. fi
  274. }
  275. # start/stop/restart nginx container
  276. restart_nginx() {
  277. echo -en "\n\e[1mRestarting nginx container\e[0m"
  278. docker exec -it nginx-dockerbunker nginx -t >/dev/null \
  279. && docker restart ${NGINX_CONTAINER} >/dev/null
  280. exit_response
  281. if [[ $? == 1 ]];then
  282. echo ""
  283. docker exec -it nginx-dockerbunker nginx -t
  284. echo -e "\n\e[3m\xe2\x86\x92 \e[3m\`nginx -t\` failed. Trying to add missing containers to dockerbunker-network.\e[0m"
  285. for container in ${CONTAINERS_IN_DOCKERBUNKER_NETWORK[@]};do
  286. connect_containers_to_network ${container}
  287. done
  288. echo -en "\n\e[1mRestarting nginx container\e[0m"
  289. docker exec -it nginx-dockerbunker nginx -t >/dev/null \
  290. && docker restart ${NGINX_CONTAINER} >/dev/null
  291. exit_response
  292. if [[ $? == 1 ]];then
  293. echo ""
  294. docker exec -it nginx-dockerbunker nginx -t
  295. echo -e "\n\`nginx -t\` failed again. Please resolve issue and try again."
  296. fi
  297. fi
  298. }
  299. start_nginx() {
  300. echo -en "\n\e[1mStarting nginx container\e[0m"
  301. docker start ${NGINX_CONTAINER} >/dev/null
  302. exit_response
  303. }
  304. stop_nginx() {
  305. echo -en "\n\e[1mStopping nginx container\e[0m"
  306. docker stop ${NGINX_CONTAINER} >/dev/null
  307. exit_response
  308. }
  309. # all functions starting/stopping/restarting containers of individual services. This is offered in every service specific menu.
  310. deactivate_nginx_conf() {
  311. if [[ ${SERVICE_NAME} == "nginx" ]] \
  312. || [[ -f "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf ]] \
  313. || elementInArray "${PROPER_NAME}" "${STOPPED_SERVICES[@]}" \
  314. || [[ ${FUNCNAME[2]} == "destroy_service" ]];then \
  315. return
  316. fi
  317. ! [[ -f "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf ]] \
  318. && [[ -z $reconfigure ]] \
  319. && echo -e "\n\e[31mNginx configuration for ${PROPER_NAME} is not active or missing.\nPlease make sure ${PROPER_NAME} is properly configured.\e[0m\n" \
  320. && return
  321. ! [[ -d "${CONF_DIR}"/nginx/conf.inactive.d ]] \
  322. && mkdir "${CONF_DIR}"/nginx/conf.inactive.d
  323. if [[ -f "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf ]];then
  324. echo -en "\n\e[1mDeactivating nginx configuration\e[0m"
  325. [[ -d "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]} ]] \
  326. && mv "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]} "${CONF_DIR}"/nginx/conf.inactive.d/
  327. mv "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf "${CONF_DIR}"/nginx/conf.inactive.d/
  328. exit_response
  329. fi
  330. if ! elementInArray "${PROPER_NAME}" "${STOPPED_SERVICES[@]}";then
  331. STOPPED_SERVICES+=( "${PROPER_NAME}" )
  332. sed -i '/STOPPED_SERVICES/d' "${ENV_DIR}"/dockerbunker.env
  333. declare -p STOPPED_SERVICES >> "${ENV_DIR}"/dockerbunker.env
  334. fi
  335. [[ -z $prevent_nginx_restart ]] && restart_nginx
  336. }
  337. activate_nginx_conf() {
  338. [[ ${SERVICE_NAME} == "nginx" ]] && return
  339. [[ ${FUNCNAME[1]} != "setup" ]] \
  340. && elementInArray "${PROPER_NAME}" "${STOPPED_SERVICES[@]}" \
  341. && ! [[ -f "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf ]] \
  342. && echo -e "\n\e[31mNginx configuration for ${PROPER_NAME} is not inactive or missing. Please make sure ${PROPER_NAME} is properly configured.\e[0m\n" \
  343. && return
  344. # activate nginx config
  345. [[ -d "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]} ]] \
  346. && mv "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]} "${CONF_DIR}"/nginx/conf.d/
  347. [[ -f "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf ]] \
  348. && mv "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf "${CONF_DIR}"/nginx/conf.d/
  349. }
  350. start_containers() {
  351. RUNNING=$(docker inspect --format="{{.State.Running}}" ${NGINX_CONTAINER} 2> /dev/null)
  352. [[ $RUNNING == "false" ]] || [[ -z $RUNNING ]] && bash -c "${SERVICES_DIR}"/nginx/nginx.sh setup
  353. echo -e "\n\e[1mStarting containers\e[0m"
  354. for container in "${containers[@]}";do
  355. [[ $(docker ps -q --filter "status=exited" --filter name=^/${container}$) ]] \
  356. && echo -en "- $container" \
  357. && docker start $container >/dev/null 2>&1 \
  358. && exit_response
  359. done
  360. remove_from_STOPPED_SERVICES
  361. activate_nginx_conf
  362. [[ -z $prevent_nginx_restart ]] && restart_nginx
  363. }
  364. stop_containers() {
  365. deactivate_nginx_conf
  366. echo -e "\n\e[1mStopping containers\e[0m"
  367. for container in "${containers[@]}";do
  368. [[ $(docker ps -q --filter name=^/${container}$) ]] \
  369. && echo -en "- $container" \
  370. && docker stop $container >/dev/null 2>&1 \
  371. && exit_response \
  372. || echo "- $container (not running)"
  373. done
  374. }
  375. restore_container() {
  376. # build image if it does not exist locally
  377. serviceName=$(echo $container | awk -F"-" '{print $2}')
  378. if ! docker inspect --type=image ${IMAGES[$serviceName]} >/dev/null 2>&1;then
  379. docker_build ${IMAGES[$serviceName]}
  380. fi
  381. docker_run ${container//-/_}
  382. echo -en "\n- $container"
  383. exit_response
  384. }
  385. remove_containers() {
  386. for container in ${containers[@]};do
  387. [[ $(docker ps -a -q --filter name=^/${container}$) ]] \
  388. && containers_found+=( $container )
  389. done
  390. if [[ -z ${containers_found[0]} ]];then
  391. echo -e "\n\e[1mRemoving containers\e[0m"
  392. for container in "${containers[@]}";do
  393. [[ $(docker ps -q --filter "status=exited" --filter name=^/${container}$) || $(docker ps -q --filter "status=restarting" --filter name=^/${container}$) ]] \
  394. && echo -en "- $container" \
  395. && docker rm -f $container >/dev/null 2>&1 \
  396. && exit_response \
  397. || echo "- $container (not found)"
  398. done
  399. elif [[ ${#containers_found[@]} > 0 ]];then
  400. echo -e "\n\e[1mRemoving containers\e[0m"
  401. for container in "${containers[@]}";do
  402. echo -en "- $container"
  403. docker rm -f $container >/dev/null 2>&1
  404. exit_response
  405. done
  406. else
  407. return
  408. fi
  409. }
  410. remove_volumes() {
  411. if [[ ${volumes[@]} && -z $keep_volumes ]] || [[ $destroy_all ]];then
  412. echo -e "\n\e[1mRemoving volumes\e[0m"
  413. for volume in "${!volumes[@]}";do
  414. [[ $(docker volume ls -q --filter name=^${volume}$) ]] \
  415. && echo -en "- ${volume}" \
  416. && docker volume rm ${volume} >/dev/null \
  417. && exit_response \
  418. || echo "- ${volume} (not found)"
  419. done
  420. fi
  421. }
  422. remove_networks() {
  423. if [[ ${networks[0]} ]];then
  424. echo -e "\n\e[1mRemoving networks\e[0m"
  425. for network in "${networks[@]}";do
  426. [[ $(docker network ls -q --filter name=^${network}$) ]] \
  427. && echo -en "- $network" \
  428. && docker network rm $network >/dev/null \
  429. && exit_response \
  430. || echo "- $network (not found)"
  431. done
  432. fi
  433. }
  434. restart_containers() {
  435. echo -e "\n\e[1mRestarting containers\e[0m"
  436. [[ $(docker ps -a -q --filter name=^/${NGINX_CONTAINER}$ 2> /dev/null) ]] \
  437. || bash -c "${SERVICES_DIR}"/nginx/nginx.sh setup
  438. for container in "${containers[@]}";do
  439. if [[ $(docker ps -q --filter name=^/${container}$) ]];then
  440. echo -en "- $container";docker restart $container >/dev/null 2>&1
  441. exit_response
  442. fi
  443. done
  444. [[ -z $prevent_nginx_restart ]] && restart_nginx
  445. }
  446. remove_images() {
  447. if [[ ${IMAGES[0]} ]];then
  448. prompt_confirm "Remove all images?"
  449. if [[ $? == 0 ]];then
  450. echo -e "\n\e[1mRemoving images\e[0m"
  451. for image in "${IMAGES[@]}";do
  452. if ! [[ $(docker container ls | awk '{print $2}' | grep "\<${image}\>") ]];then
  453. echo -en "- $image"
  454. docker rmi $image >/dev/null
  455. exit_response
  456. fi
  457. done
  458. fi
  459. fi
  460. }
  461. remove_service_conf() {
  462. [[ -d "${CONF_DIR}/${SERVICE_NAME}" ]] \
  463. && echo -en "\n\e[1mRemoving ${CONF_DIR}/${SERVICE_NAME}\e[0m" \
  464. && rm -r "${CONF_DIR}/${SERVICE_NAME}" \
  465. }
  466. remove_environment_files() {
  467. [[ -f "${ENV_DIR}"/${SERVICE_NAME}.env ]] \
  468. && echo -en "\n\e[1mRemoving ${SERVICE_NAME}.env\e[0m" \
  469. && rm "${ENV_DIR}"/${SERVICE_NAME}.env \
  470. && exit_response
  471. [[ ${SERVICE_SPECIFIC_MX} ]] \
  472. && [[ -f "${ENV_DIR}"/${SERVICE_SPECIFIC_MX}mx.env ]] \
  473. && rm "${ENV_DIR}"/${SERVICE_SPECIFIC_MX}mx.env
  474. [[ ${STATIC} \
  475. && -f "${ENV_DIR}"/static/${SERVICE_DOMAIN[0]}.env ]] \
  476. && echo -en "\n\e[1mRemoving ${SERVICE_DOMAIN[0]}.env\e[0m" \
  477. && rm "${ENV_DIR}"/static/${SERVICE_DOMAIN[0]}.env \
  478. && exit_response
  479. }
  480. remove_ssl_certificate() {
  481. if [[ ${SERVICE_DOMAIN[0]} ]] \
  482. && [[ -d "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]} ]];then
  483. echo -en "\n\e[1mRemoving SSL Certificate\e[0m"
  484. rm -r "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}
  485. exit_response
  486. fi
  487. }
  488. destroy_service() {
  489. if [[ -z ${STATIC} ]];then
  490. disconnect_from_dockerbunker_network
  491. stop_containers
  492. remove_containers
  493. remove_volumes
  494. remove_networks
  495. remove_images
  496. echo -en "\n\e[1mRemoving ${PROPER_NAME} from dockerbunker.env\e[0m"
  497. remove_from_WEB_SERVICES
  498. remove_from_CONFIGURED_SERVICES
  499. remove_from_INSTALLED_SERVICES
  500. remove_from_STOPPED_SERVICES
  501. remove_from_CONTAINERS_IN_DOCKERBUNKER_NETWORK
  502. else
  503. [[ -d ${STATIC_HOME} ]] \
  504. && prompt_confirm "Remove HTML directory [${STATIC_HOME}]" \
  505. && echo -en "\n\e[1mRemoving ${STATIC_HOME}\e[0m" \
  506. && rm -r ${STATIC_HOME} >/dev/null \
  507. && exit_response
  508. echo -en "\n\e[1mRemoving "${SERVICE_DOMAIN[0]}" from dockerbunker.env\e[0m"
  509. remove_from_STATIC_SITES
  510. fi
  511. exit_response
  512. remove_nginx_conf
  513. remove_environment_files
  514. remove_service_conf
  515. remove_ssl_certificate
  516. [[ -z $destroy_all ]] \
  517. && [[ -z ${INSTALLED_SERVICES[@]} ]] \
  518. && [[ $(docker ps -q --filter name=^/${NGINX_CONTAINER}) ]] \
  519. && [[ -z $restoring ]] \
  520. && echo -e "\nNo remaining services running.\n" \
  521. && prompt_confirm "Destroy nginx as well and completely reset dockerbunker?" \
  522. && bash "${SERVICES_DIR}"/nginx/nginx.sh destroy_service \
  523. && return
  524. [[ -z $prevent_nginx_restart ]] \
  525. && [[ ${SERVICE_NAME} != "nginx" ]] \
  526. && restart_nginx
  527. }
  528. # minimal setup routine. if more is needed add custom setup() in data/services/${SERVICE_NAME}/${SERVICE_NAME}.sh
  529. setup() {
  530. initial_setup_routine
  531. SUBSTITUTE=( "\${SERVICE_DOMAIN}" )
  532. basic_nginx
  533. docker_run_all
  534. post_setup_routine
  535. }
  536. # minimal upgrade routine. if more is needed add custom upgrade() in data/services/${SERVICE_NAME}/${SERVICE_NAME}.sh
  537. upgrade() {
  538. pull_and_compare
  539. stop_containers
  540. remove_containers
  541. docker_run_all
  542. delete_old_images
  543. }
  544. reinstall() {
  545. echo ""
  546. prompt_confirm "Keep volumes?" && export keep_volumes=1
  547. disconnect_from_dockerbunker_network
  548. stop_containers
  549. remove_containers
  550. remove_volumes
  551. remove_networks
  552. export reinstall=1
  553. setup
  554. }
  555. remove_nginx_conf() {
  556. if [[ ${SERVICE_DOMAIN[0]} ]];then
  557. if [[ -f "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf || -f "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf ]];then
  558. echo -en "\n\e[1mRemoving nginx configuration\e[0m"
  559. [[ -d "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]} ]] \
  560. && rm -r "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]} \
  561. || true
  562. [[ -d "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]} ]] \
  563. && rm -r "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]} \
  564. || true
  565. [[ -f "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf ]] \
  566. && rm "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf \
  567. || true
  568. [[ -f "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf ]] \
  569. && rm "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf \
  570. || true
  571. exit_response
  572. fi
  573. fi
  574. }
  575. disconnect_from_dockerbunker_network() {
  576. for container in ${add_to_network[@]};do
  577. [[ $container && $(docker ps -q --filter name=^/${container}$) ]] \
  578. && docker network disconnect ${NETWORK} $container >/dev/null
  579. done
  580. }
  581. reconfigure() {
  582. reconfigure=1
  583. if [[ $safe_to_keep_volumes_when_reconfiguring ]];then
  584. echo ""
  585. prompt_confirm "Keep volumes?" && keep_volumes=1
  586. else
  587. echo ""
  588. prompt_confirm "All volumes will be removed. Continue?" || exit 0
  589. fi
  590. disconnect_from_dockerbunker_network
  591. stop_containers
  592. remove_containers
  593. remove_volumes
  594. remove_networks
  595. remove_nginx_conf
  596. remove_ssl_certificate
  597. remove_environment_files
  598. remove_service_conf
  599. [[ $(grep "${PROPER_NAME}" "${ENV_DIR}"/dockerbunker.env) ]] && echo -en "\n\e[1mRemoving ${PROPER_NAME} from dockerbunker.env\e[0m"
  600. remove_from_WEB_SERVICES
  601. remove_from_CONFIGURED_SERVICES
  602. remove_from_INSTALLED_SERVICES
  603. remove_from_STOPPED_SERVICES
  604. remove_from_CONTAINERS_IN_DOCKERBUNKER_NETWORK
  605. exit_response
  606. echo ""
  607. configure
  608. }
  609. # all functions that manipulate all containers
  610. start_all() {
  611. start_nginx
  612. for PROPER_NAME in "${STOPPED_SERVICES[@]}";do
  613. SERVICE_NAME="$(echo -e "${service,,}" | tr -cd '[:alnum:]')"
  614. source "${ENV_DIR}"/${SERVICE_NAME}.env
  615. source "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh start_containers
  616. done
  617. restart_nginx
  618. }
  619. restart_all() {
  620. for service in "${INSTALLED_SERVICES[@]}";do
  621. service="$(echo -e "${service,,}" | tr -cd '[:alnum:]')"
  622. source "${SERVICE_ENV}"
  623. source "${SERVICES_DIR}"/${service}/${service}.sh restart_containers
  624. done
  625. restart_nginx
  626. }
  627. stop_all() {
  628. for service in "${INSTALLED_SERVICES[@]}";do
  629. service="$(echo -e "${service,,}" | tr -cd '[:alnum:]')"
  630. if ! elementInArray "$service" "${STOPPED_SERVICES[@]}";then
  631. source "${SERVICE_ENV}"
  632. source "${SERVICES_DIR}"/${service}/${service}.sh stop_containers
  633. fi
  634. done
  635. stop_nginx
  636. export prevent_nginx_restart=1
  637. }
  638. destroy_all() {
  639. # destroy_service() is calling restart_nginx, we don't want this happening after each service is destroyed
  640. export prevent_nginx_restart=1
  641. export destroy_all=1
  642. all_services=( "${INSTALLED_SERVICES[@]}" "${CONFIGURED_SERVICES[@]}" )
  643. [[ $(docker ps -q --filter name=^/nginx-dockerbunker$) ]] && all_services+=( "nginx" )
  644. if [[ ${all_services[0]} ]];then
  645. printf "\nThe following Services will be removed: \
  646. $(for i in "${all_services[@]}";do \
  647. if [[ "$i" == ${all_services[-1]} ]];then \
  648. (printf "\"\e[33m%s\e[0m\" " "$i" )
  649. else
  650. (printf "\"\e[33m%s\e[0m\", " "$i" )
  651. fi
  652. done) \n\n"
  653. fi
  654. prompt_confirm "Continue?"
  655. [[ $? == 1 ]] && echo "Exiting..." && exit 0
  656. for service in "${all_services[@]}";do
  657. SERVICE_NAME="$(echo -e "${service,,}" | tr -cd '[:alnum:]')"
  658. echo -e "\n\e[3m\xe2\x86\x92 Destroying $service\e[0m"
  659. [[ -f "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh ]] \
  660. && "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh destroy_service
  661. done
  662. [[ -d "${CONF_DIR}"/nginx/conf.inactive.d ]] \
  663. && [[ $(ls -A "${CONF_DIR}"/nginx/conf.inactive.d) ]] \
  664. && rm -r "${CONF_DIR}"/nginx/conf.inactive.d/*
  665. [[ -d "${CONF_DIR}"/nginx/conf.d ]] \
  666. && [[ $(ls -A "${CONF_DIR}"/nginx/conf.d) ]] \
  667. && rm -r "${CONF_DIR}"/nginx/conf.d/*
  668. for cert_dir in $(ls "${CONF_DIR}"/nginx/ssl/);do
  669. [[ $cert_dir != "letsencrypt" ]] \
  670. && rm -r "${CONF_DIR}"/nginx/ssl/$cert_dir
  671. done
  672. [[ -d "${ENV_DIR}"/static ]] \
  673. && [[ $(ls -A "${ENV_DIR}"/static) ]] \
  674. && rm "${ENV_DIR}"/static/*
  675. }
  676. add_ssl_menuentry() {
  677. if [[ $SSL_CHOICE == "le" ]] && [[ -d "${CONF_DIR}"/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} ]];then
  678. # in this case le cert has been obtained previously and everything is as expected
  679. insert $1 "Renew Let's Encrypt certificate" $2
  680. elif ! [[ -d "${CONF_DIR}"/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} ]] && [[ -L "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/cert.pem ]];then
  681. # in this case neither a self-signed nor a le cert could be found. nginx container will refuse to restart until it can find a certificate in /etc/nginx/ssl/${SERVICE_DOMAIN} - so offer to put one there either via LE or generate new self-signed
  682. insert $1 "Generate self-signed certificate" $2
  683. insert $1 "Obtain Let's Encrypt certificate" $2
  684. elif [[ -f "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/cert.pem ]];then
  685. # in this case only a self-signed cert is found and a previous cert for the domain might be present in the le directories (if so it will be used and linked to)
  686. insert $1 "Obtain Let's Encrypt certificate" $2
  687. else
  688. # not sure when this should be the case, but if it does happen, bot options are available
  689. insert $1 "Generate self-signed certificate" $2
  690. insert $1 "Obtain Let's Encrypt certificate" $2
  691. fi
  692. }
  693. static_menu() {
  694. [[ -z ${STATIC_SITES[0]} ]] \
  695. && echo -e "\n\e[1mNo existing sites found\e[0m" \
  696. && exec "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh
  697. # Display all static sites in a menu
  698. # Option menu from directory listing, based on terdon's answer in https://askubuntu.com/a/682146
  699. ## Collect all sites in the array $staticsites
  700. staticsites=( "${BASE_DIR}"/data/env/static/* )
  701. # strip path from directory names
  702. staticsites=( "${staticsites[@]##*/}" )
  703. staticsites=( "${staticsites[@]%.*}" )
  704. ## Enable extended globbing. This lets us use @(foo|bar) to
  705. ## match either 'foo' or 'bar'.
  706. shopt -s extglob
  707. ## Start building the string to match against.
  708. string="@(${staticsites[0]}"
  709. ## Add the rest of the site names to the string
  710. for((i=1;i<${#staticsites[@]};i++))
  711. do
  712. string+="|${staticsites[$i]}"
  713. done
  714. ## Close the parenthesis. $string is now @(site1|site2|...|siteN)
  715. string+=")"
  716. echo ""
  717. ## Show the menu. This will list all Static Sites that have an active environment file
  718. select static in "${staticsites[@]}" "$returntopreviousmenu"
  719. do
  720. case $static in
  721. $string)
  722. if [[ -f "${BASE_DIR}"/data/env/static/${static}.env ]];then
  723. source "${BASE_DIR}"/data/env/static/${static}.env
  724. else
  725. echo "No environment file found for $static. Exiting."
  726. exit 1
  727. fi
  728. echo ""
  729. static_choices=( "Remove site" "$returntopreviousmenu" )
  730. add_ssl_menuentry static_choices 1
  731. select static_choice in "${static_choices[@]}"
  732. do
  733. case $static_choice in
  734. "Remove site")
  735. echo -e "\n\e[4mRemove site\e[0m"
  736. prompt_confirm "Remove $static" && prompt_confirm "Are you sure?" && destroy_service
  737. say_done
  738. sleep 0.2
  739. break
  740. ;;
  741. "Generate self-signed certificate")
  742. generate_certificate
  743. restart_nginx
  744. say_done
  745. sleep 0.2
  746. break
  747. ;;
  748. "Obtain Let's Encrypt certificate")
  749. get_le_cert
  750. say_done
  751. sleep 0.2
  752. break
  753. ;;
  754. "Renew Let's Encrypt certificate")
  755. get_le_cert renew
  756. say_done
  757. sleep 0.2
  758. break
  759. ;;
  760. "$returntopreviousmenu")
  761. static_menu
  762. ;;
  763. *)
  764. echo "Invalid option."
  765. ;;
  766. esac
  767. done
  768. break;
  769. ;;
  770. "$returntopreviousmenu")
  771. exec "${SERVICES_DIR}"/statichtmlsite/statichtmlsite.sh options_menu;;
  772. *)
  773. static=""
  774. echo "Please choose a number from 1 to $((${#staticsites[@]}+1))";;
  775. esac
  776. done
  777. }
  778. backup() {
  779. ! [[ -d ${BASE_DIR}/data/backup/${SERVICE_NAME} ]] && mkdir -p ${BASE_DIR}/data/backup/${SERVICE_NAME}
  780. NOW=$(date -d "today" +"%Y%m%d_%H%M")
  781. # compressing volumes
  782. echo -e "\n\e[1mCompressing volumes\e[0m"
  783. for volume in ${!volumes[@]};do
  784. docker run --rm -i -v ${volume}:/${volumes[$volume]##*/} -v ${BASE_DIR}/data/backup/${SERVICE_NAME}/${NOW}:/backup debian:jessie tar cvfz /backup/${volume}.tar.gz /${volumes[$volume]##*/} 2>/dev/null | cut -b1-$(tput cols) | sed -u 'i\\o033[2K' | stdbuf -o0 tr '\n' '\r';echo -e "\033[2K\c"
  785. echo -en "- $volume"
  786. exit_response
  787. done
  788. if [ -d "${CONF_DIR}"/${SERVICE_NAME} ];then
  789. ! [ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/conf ] \
  790. && mkdir "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/conf
  791. echo -en "\n\e[1mBacking up configuration files\e[0m"
  792. sleep 0.2
  793. cp -r "${CONF_DIR}"/${SERVICE_NAME}/* "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/conf
  794. exit_response
  795. fi
  796. if [[ ${SERVICE_DOMAIN[0]} ]] && [ -d "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]} ];then
  797. ! [ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl ] \
  798. && mkdir "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl
  799. echo -en "\n\e[1mBacking up SSL certificate\e[0m"
  800. sleep 0.2
  801. [[ -d "${CONF_DIR}"/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} ]] \
  802. && mkdir -p \
  803. "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl/letsencrypt/live \
  804. "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl/letsencrypt/archive \
  805. "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl/letsencrypt/renewal \
  806. && cp -r "${CONF_DIR}"/nginx/ssl/letsencrypt/archive/${SERVICE_DOMAIN[0]} "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl/letsencrypt/archive \
  807. && cp -r "${CONF_DIR}"/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl/letsencrypt/live \
  808. && cp -r "${CONF_DIR}"/nginx/ssl/letsencrypt/renewal/${SERVICE_DOMAIN[0]}.conf "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl/letsencrypt/renewal
  809. cp -r "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]} "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl
  810. exit_response
  811. fi
  812. if [ -f "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf ];then
  813. ! [ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/nginx ] \
  814. && mkdir -p "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/nginx
  815. echo -en "\n\e[1mBacking up nginx configuration\e[0m"
  816. sleep 0.2
  817. cp -r "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}* "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/nginx
  818. exit_response
  819. fi
  820. if [ -f "${ENV_DIR}"/${SERVICE_NAME}.env ];then
  821. echo -en "\n\e[1mBacking up environemt file(s)\e[0m"
  822. sleep 0.2
  823. [[ -f "${ENV_DIR}"/${SERVICE_SPECIFIC_MX}mx.env ]] \
  824. && cp "${ENV_DIR}"/${SERVICE_SPECIFIC_MX}mx.env "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}
  825. cp "${ENV_DIR}"/${SERVICE_NAME}.env "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}
  826. exit_response
  827. else
  828. echo -e "\n\e[3mCould not find environment file(s) for ${PROPER_NAME}.\e[0m"
  829. fi
  830. }
  831. restore() {
  832. echo ${FUNCNAME[@]}
  833. restoring=1
  834. ## Collect the backups in the array $backups
  835. backups=( "${BASE_DIR}"/data/backup/${SERVICE_NAME}/* )
  836. # strip path from directory names
  837. backups=( "${backups[@]##*/}" )
  838. ## Enable extended globbing. This lets us use @(foo|bar) to
  839. ## match either 'foo' or 'bar'.
  840. shopt -s extglob
  841. ## Start building the string to match against.
  842. string="@(${backups[0]}"
  843. ## Add the rest of the backups to the string
  844. for((i=1;i<${#backups[@]};i++))
  845. do
  846. string+="|${backups[$i]}"
  847. done
  848. ## Close the parenthesis. $string is now @(backup1|backup2|...|backupN)
  849. string+=")"
  850. # only continue if backup directory is not empty
  851. if [[ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME} ]] \
  852. && [[ $(ls -A "${BASE_DIR}"/data/backup/${SERVICE_NAME}) ]];then
  853. echo ""
  854. echo -e "\e[4mPlease choose a backup\e[0m"
  855. ## Show the menu. This will list all backups and the string "back to previous menu"
  856. select backup in "${backups[@]}" "Back to previous menu"
  857. do
  858. case $backup in
  859. ## If the choice is one of the backups (if it matches $string)
  860. $string)
  861. ! [[ -f "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/${SERVICE_NAME}.env ]] \
  862. && echo -e "\n\e[3mCould not find ${SERVICE_NAME}.env in ${backup}\e[0m" \
  863. && return
  864. # destroy current service if found
  865. if [[ $(docker ps -q -a --filter name=^/"${SERVICE_NAME}-service-dockerbunker"$) ]];then
  866. echo -e "\n\e[3m\xe2\x86\x92 Destroying ${PROPER_NAME}\e[0m"
  867. destroy_service
  868. fi
  869. source "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/${SERVICE_NAME}.env
  870. ! [[ $(docker ps -q --filter name=^/nginx-dockerbunker$) ]] && setup_nginx
  871. echo -e "\n\e[3m\xe2\x86\x92 Restoring ${PROPER_NAME}\e[0m"
  872. for volume in ${!volumes[@]};do
  873. [[ $(docker volume ls --filter name=^${volume}$) ]] \
  874. && docker volume create $volume >/dev/null
  875. docker run --rm -i -v ${volume}:/${volumes[$volume]##*/} -v ${BASE_DIR}/data/backup/${SERVICE_NAME}/${backup}:/backup debian:jessie tar xvfz /backup/${volume}.tar.gz 2>/dev/null | cut -b1-$(tput cols) | sed -u 'i\\o033[2K' | stdbuf -o0 tr '\n' '\r';echo -e "\033[2K\c"
  876. echo -en "\n\e[1mDecompressing $volume\e[0m"
  877. exit_response
  878. done
  879. sleep 0.2
  880. if [ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/conf ];then
  881. ! [ -d "${CONF_DIR}"/${SERVICE_NAME} ] \
  882. && mkdir "${CONF_DIR}"/${SERVICE_NAME}
  883. echo -en "\n\e[1mRestoring configuration files\e[0m"
  884. sleep 0.2
  885. cp -r "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/conf/* "${CONF_DIR}"/${SERVICE_NAME}
  886. exit_response
  887. fi
  888. if [ -f "${BASE_DIR}"/data/backup/${SERVICE_NAME}/$backup/nginx/${SERVICE_DOMAIN}.conf ];then
  889. ! [[ -d "${CONF_DIR}"/nginx/conf.inactive.d ]] \
  890. && mkdir "${CONF_DIR}"/nginx/conf.inactive.d
  891. echo -en "\n\e[1mRestoring nginx configuration\e[0m"
  892. cp -r "${BASE_DIR}"/data/backup/${SERVICE_NAME}/$backup/nginx/${SERVICE_DOMAIN}* "${CONF_DIR}"/nginx/conf.inactive.d
  893. exit_response
  894. fi
  895. sleep 0.2
  896. if [[ ${SERVICE_DOMAIN[0]} ]] && [ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/ssl ];then
  897. ! [ -d "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]} ] \
  898. && mkdir -p "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}
  899. echo -en "\n\e[1mRestoring SSL certificate\e[0m"
  900. sleep 0.2
  901. [[ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} ]] \
  902. && mkdir -p \
  903. "${CONF_DIR}"/nginx/ssl/letsencrypt/live \
  904. "${CONF_DIR}"/nginx/ssl/letsencrypt/archive \
  905. "${CONF_DIR}"/nginx/ssl/letsencrypt/renewal \
  906. && cp -r "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/ssl/letsencrypt/archive/${SERVICE_DOMAIN[0]} "${CONF_DIR}"/nginx/ssl/letsencrypt/archive \
  907. && cp -r "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} "${CONF_DIR}"/nginx/ssl/letsencrypt/live \
  908. && cp -r "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/ssl/letsencrypt/renewal/${SERVICE_DOMAIN[0]}.conf "${CONF_DIR}"/nginx/ssl/letsencrypt/renewal
  909. cp -r "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/ssl/${SERVICE_DOMAIN[0]} "${CONF_DIR}"/nginx/ssl
  910. exit_response
  911. fi
  912. if [ -f "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/${SERVICE_NAME}.env ];then
  913. echo -en "\n\e[1mRestoring environemt file(s)\e[0m"
  914. sleep 0.2
  915. [[ -f "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/${SERVICE_SPECIFIC_MX}mx.env ]] \
  916. && cp "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/${SERVICE_SPECIFIC_MX}mx.env "${ENV_DIR}"
  917. cp "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/${SERVICE_NAME}.env "${ENV_DIR}"
  918. exit_response
  919. fi
  920. create_networks
  921. docker_run_all
  922. activate_nginx_conf
  923. post_setup_routine
  924. exit 0
  925. ;;
  926. "Back to previous menu")
  927. "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh
  928. ;;
  929. *)
  930. backup=""
  931. echo "Please choose a number from 1 to $((${#backups[@]}+1))";;
  932. esac
  933. done
  934. else
  935. echo -e "\n\e[1mNo ${PROPER_NAME} backup found\e[0m"
  936. echo -e "\n\e[3m\xe2\x86\x92 Checking service status"
  937. exec "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh
  938. fi
  939. }