menu_functions.sh 36 KB

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