menu_functions.sh 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038
  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" "Upgrade Image(s)" "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. connect_containers_to_network $container
  385. restart_nginx
  386. }
  387. remove_containers() {
  388. for container in ${containers[@]};do
  389. [[ $(docker ps -a -q --filter name=^/${container}$) ]] \
  390. && containers_found+=( $container )
  391. done
  392. if [[ -z ${containers_found[0]} ]];then
  393. echo -e "\n\e[1mRemoving containers\e[0m"
  394. for container in "${containers[@]}";do
  395. [[ $(docker ps -q --filter "status=exited" --filter name=^/${container}$) || $(docker ps -q --filter "status=restarting" --filter name=^/${container}$) ]] \
  396. && echo -en "- $container" \
  397. && docker rm -f $container >/dev/null 2>&1 \
  398. && exit_response \
  399. || echo "- $container (not found)"
  400. done
  401. elif [[ ${#containers_found[@]} > 0 ]];then
  402. echo -e "\n\e[1mRemoving containers\e[0m"
  403. for container in "${containers[@]}";do
  404. echo -en "- $container"
  405. docker rm -f $container >/dev/null 2>&1
  406. exit_response
  407. done
  408. else
  409. return
  410. fi
  411. }
  412. remove_volumes() {
  413. if [[ ${volumes[@]} && -z $keep_volumes ]] || [[ $destroy_all ]];then
  414. echo -e "\n\e[1mRemoving volumes\e[0m"
  415. for volume in "${!volumes[@]}";do
  416. [[ $(docker volume ls -q --filter name=^${volume}$) ]] \
  417. && echo -en "- ${volume}" \
  418. && docker volume rm ${volume} >/dev/null \
  419. && exit_response \
  420. || echo "- ${volume} (not found)"
  421. done
  422. fi
  423. }
  424. remove_networks() {
  425. if [[ ${networks[0]} ]];then
  426. echo -e "\n\e[1mRemoving networks\e[0m"
  427. for network in "${networks[@]}";do
  428. [[ $(docker network ls -q --filter name=^${network}$) ]] \
  429. && echo -en "- $network" \
  430. && docker network rm $network >/dev/null \
  431. && exit_response \
  432. || echo "- $network (not found)"
  433. done
  434. fi
  435. }
  436. restart_containers() {
  437. echo -e "\n\e[1mRestarting containers\e[0m"
  438. [[ $(docker ps -a -q --filter name=^/${NGINX_CONTAINER}$ 2> /dev/null) ]] \
  439. || bash -c "${SERVICES_DIR}"/nginx/nginx.sh setup
  440. for container in "${containers[@]}";do
  441. if [[ $(docker ps -q --filter name=^/${container}$) ]];then
  442. echo -en "- $container";docker restart $container >/dev/null 2>&1
  443. exit_response
  444. fi
  445. done
  446. [[ -z $prevent_nginx_restart ]] && restart_nginx
  447. }
  448. remove_images() {
  449. if [[ ${IMAGES[0]} ]];then
  450. prompt_confirm "Remove all images?"
  451. if [[ $? == 0 ]];then
  452. echo -e "\n\e[1mRemoving images\e[0m"
  453. for image in "${IMAGES[@]}";do
  454. if ! [[ $(docker container ls | awk '{print $2}' | grep "\<${image}\>") ]];then
  455. echo -en "- $image"
  456. docker rmi $image >/dev/null
  457. exit_response
  458. fi
  459. done
  460. fi
  461. fi
  462. }
  463. remove_service_conf() {
  464. [[ -d "${CONF_DIR}/${SERVICE_NAME}" ]] \
  465. && echo -en "\n\e[1mRemoving ${CONF_DIR}/${SERVICE_NAME}\e[0m" \
  466. && rm -r "${CONF_DIR}/${SERVICE_NAME}" \
  467. }
  468. remove_environment_files() {
  469. [[ -f "${ENV_DIR}"/${SERVICE_NAME}.env ]] \
  470. && echo -en "\n\e[1mRemoving ${SERVICE_NAME}.env\e[0m" \
  471. && rm "${ENV_DIR}"/${SERVICE_NAME}.env \
  472. && exit_response
  473. [[ ${SERVICE_SPECIFIC_MX} ]] \
  474. && [[ -f "${ENV_DIR}"/${SERVICE_SPECIFIC_MX}mx.env ]] \
  475. && rm "${ENV_DIR}"/${SERVICE_SPECIFIC_MX}mx.env
  476. [[ ${STATIC} \
  477. && -f "${ENV_DIR}"/static/${SERVICE_DOMAIN[0]}.env ]] \
  478. && echo -en "\n\e[1mRemoving ${SERVICE_DOMAIN[0]}.env\e[0m" \
  479. && rm "${ENV_DIR}"/static/${SERVICE_DOMAIN[0]}.env \
  480. && exit_response
  481. }
  482. remove_ssl_certificate() {
  483. if [[ ${SERVICE_DOMAIN[0]} ]] \
  484. && [[ -d "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]} ]];then
  485. echo -en "\n\e[1mRemoving SSL Certificate\e[0m"
  486. rm -r "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}
  487. exit_response
  488. fi
  489. }
  490. destroy_service() {
  491. if [[ -z ${STATIC} ]];then
  492. disconnect_from_dockerbunker_network
  493. stop_containers
  494. remove_containers
  495. remove_volumes
  496. remove_networks
  497. remove_images
  498. echo -en "\n\e[1mRemoving ${PROPER_NAME} from dockerbunker.env\e[0m"
  499. remove_from_WEB_SERVICES
  500. remove_from_CONFIGURED_SERVICES
  501. remove_from_INSTALLED_SERVICES
  502. remove_from_STOPPED_SERVICES
  503. remove_from_CONTAINERS_IN_DOCKERBUNKER_NETWORK
  504. else
  505. [[ -d ${STATIC_HOME} ]] \
  506. && prompt_confirm "Remove HTML directory [${STATIC_HOME}]" \
  507. && echo -en "\n\e[1mRemoving ${STATIC_HOME}\e[0m" \
  508. && rm -r ${STATIC_HOME} >/dev/null \
  509. && exit_response
  510. echo -en "\n\e[1mRemoving "${SERVICE_DOMAIN[0]}" from dockerbunker.env\e[0m"
  511. remove_from_STATIC_SITES
  512. fi
  513. exit_response
  514. remove_nginx_conf
  515. remove_environment_files
  516. remove_service_conf
  517. remove_ssl_certificate
  518. [[ -z $destroy_all ]] \
  519. && [[ -z ${INSTALLED_SERVICES[@]} ]] \
  520. && [[ $(docker ps -q --filter name=^/${NGINX_CONTAINER}) ]] \
  521. && [[ -z $restoring ]] \
  522. && echo -e "\nNo remaining services running.\n" \
  523. && prompt_confirm "Destroy nginx as well and completely reset dockerbunker?" \
  524. && bash "${SERVICES_DIR}"/nginx/nginx.sh destroy_service \
  525. && return
  526. [[ -z $prevent_nginx_restart ]] \
  527. && [[ ${SERVICE_NAME} != "nginx" ]] \
  528. && restart_nginx
  529. }
  530. # minimal setup routine. if more is needed add custom setup() in data/services/${SERVICE_NAME}/${SERVICE_NAME}.sh
  531. setup() {
  532. initial_setup_routine
  533. SUBSTITUTE=( "\${SERVICE_DOMAIN}" )
  534. basic_nginx
  535. docker_run_all
  536. post_setup_routine
  537. }
  538. # minimal upgrade routine. if more is needed add custom upgrade() in data/services/${SERVICE_NAME}/${SERVICE_NAME}.sh
  539. upgrade() {
  540. pull_and_compare
  541. stop_containers
  542. remove_containers
  543. docker_run_all
  544. delete_old_images
  545. }
  546. reinstall() {
  547. echo ""
  548. prompt_confirm "Keep volumes?" && export keep_volumes=1
  549. disconnect_from_dockerbunker_network
  550. stop_containers
  551. remove_containers
  552. remove_volumes
  553. remove_networks
  554. export reinstall=1
  555. setup
  556. }
  557. remove_nginx_conf() {
  558. if [[ ${SERVICE_DOMAIN[0]} ]];then
  559. if [[ -f "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf || -f "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf ]];then
  560. echo -en "\n\e[1mRemoving nginx configuration\e[0m"
  561. [[ -d "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]} ]] \
  562. && rm -r "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]} \
  563. || true
  564. [[ -d "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]} ]] \
  565. && rm -r "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]} \
  566. || true
  567. [[ -f "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf ]] \
  568. && rm "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf \
  569. || true
  570. [[ -f "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf ]] \
  571. && rm "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf \
  572. || true
  573. exit_response
  574. fi
  575. fi
  576. }
  577. disconnect_from_dockerbunker_network() {
  578. for container in ${add_to_network[@]};do
  579. [[ $container && $(docker ps -q --filter name=^/${container}$) ]] \
  580. && docker network disconnect ${NETWORK} $container >/dev/null
  581. done
  582. }
  583. reconfigure() {
  584. reconfigure=1
  585. if [[ $safe_to_keep_volumes_when_reconfiguring ]];then
  586. echo ""
  587. prompt_confirm "Keep volumes?" && keep_volumes=1
  588. else
  589. echo ""
  590. prompt_confirm "All volumes will be removed. Continue?" || exit 0
  591. fi
  592. disconnect_from_dockerbunker_network
  593. stop_containers
  594. remove_containers
  595. remove_volumes
  596. remove_networks
  597. remove_nginx_conf
  598. remove_ssl_certificate
  599. remove_environment_files
  600. remove_service_conf
  601. [[ $(grep "${PROPER_NAME}" "${ENV_DIR}"/dockerbunker.env) ]] && echo -en "\n\e[1mRemoving ${PROPER_NAME} from dockerbunker.env\e[0m"
  602. remove_from_WEB_SERVICES
  603. remove_from_CONFIGURED_SERVICES
  604. remove_from_INSTALLED_SERVICES
  605. remove_from_STOPPED_SERVICES
  606. remove_from_CONTAINERS_IN_DOCKERBUNKER_NETWORK
  607. exit_response
  608. echo ""
  609. configure
  610. }
  611. # all functions that manipulate all containers
  612. start_all() {
  613. start_nginx
  614. for PROPER_NAME in "${STOPPED_SERVICES[@]}";do
  615. SERVICE_NAME="$(echo -e "${service,,}" | tr -cd '[:alnum:]')"
  616. source "${ENV_DIR}"/${SERVICE_NAME}.env
  617. source "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh start_containers
  618. done
  619. restart_nginx
  620. }
  621. restart_all() {
  622. for service in "${INSTALLED_SERVICES[@]}";do
  623. service="$(echo -e "${service,,}" | tr -cd '[:alnum:]')"
  624. source "${SERVICE_ENV}"
  625. source "${SERVICES_DIR}"/${service}/${service}.sh restart_containers
  626. done
  627. restart_nginx
  628. }
  629. stop_all() {
  630. for service in "${INSTALLED_SERVICES[@]}";do
  631. service="$(echo -e "${service,,}" | tr -cd '[:alnum:]')"
  632. if ! elementInArray "$service" "${STOPPED_SERVICES[@]}";then
  633. source "${SERVICE_ENV}"
  634. source "${SERVICES_DIR}"/${service}/${service}.sh stop_containers
  635. fi
  636. done
  637. stop_nginx
  638. export prevent_nginx_restart=1
  639. }
  640. destroy_all() {
  641. # destroy_service() is calling restart_nginx, we don't want this happening after each service is destroyed
  642. export prevent_nginx_restart=1
  643. export destroy_all=1
  644. all_services=( "${INSTALLED_SERVICES[@]}" "${CONFIGURED_SERVICES[@]}" )
  645. [[ $(docker ps -q --filter name=^/nginx-dockerbunker$) ]] && all_services+=( "nginx" )
  646. if [[ ${all_services[0]} ]];then
  647. printf "\nThe following Services will be removed: \
  648. $(for i in "${all_services[@]}";do \
  649. if [[ "$i" == ${all_services[-1]} ]];then \
  650. (printf "\"\e[33m%s\e[0m\" " "$i" )
  651. else
  652. (printf "\"\e[33m%s\e[0m\", " "$i" )
  653. fi
  654. done) \n\n"
  655. fi
  656. prompt_confirm "Continue?"
  657. [[ $? == 1 ]] && echo "Exiting..." && exit 0
  658. for service in "${all_services[@]}";do
  659. SERVICE_NAME="$(echo -e "${service,,}" | tr -cd '[:alnum:]')"
  660. echo -e "\n\e[3m\xe2\x86\x92 Destroying $service\e[0m"
  661. [[ -f "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh ]] \
  662. && "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh destroy_service
  663. done
  664. [[ -d "${CONF_DIR}"/nginx/conf.inactive.d ]] \
  665. && [[ $(ls -A "${CONF_DIR}"/nginx/conf.inactive.d) ]] \
  666. && rm -r "${CONF_DIR}"/nginx/conf.inactive.d/*
  667. [[ -d "${CONF_DIR}"/nginx/conf.d ]] \
  668. && [[ $(ls -A "${CONF_DIR}"/nginx/conf.d) ]] \
  669. && rm -r "${CONF_DIR}"/nginx/conf.d/*
  670. for cert_dir in $(ls "${CONF_DIR}"/nginx/ssl/);do
  671. [[ $cert_dir != "letsencrypt" ]] \
  672. && rm -r "${CONF_DIR}"/nginx/ssl/$cert_dir
  673. done
  674. [[ -d "${ENV_DIR}"/static ]] \
  675. && [[ $(ls -A "${ENV_DIR}"/static) ]] \
  676. && rm "${ENV_DIR}"/static/*
  677. }
  678. add_ssl_menuentry() {
  679. if [[ $SSL_CHOICE == "le" ]] && [[ -d "${CONF_DIR}"/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} ]];then
  680. # in this case le cert has been obtained previously and everything is as expected
  681. insert $1 "Renew Let's Encrypt certificate" $2
  682. elif ! [[ -d "${CONF_DIR}"/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} ]] && [[ -L "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/cert.pem ]];then
  683. # 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
  684. insert $1 "Generate self-signed certificate" $2
  685. insert $1 "Obtain Let's Encrypt certificate" $2
  686. elif [[ -f "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/cert.pem ]];then
  687. # 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)
  688. insert $1 "Obtain Let's Encrypt certificate" $2
  689. else
  690. # not sure when this should be the case, but if it does happen, bot options are available
  691. insert $1 "Generate self-signed certificate" $2
  692. insert $1 "Obtain Let's Encrypt certificate" $2
  693. fi
  694. }
  695. static_menu() {
  696. ! [[ ${STATIC_SITES[@]} ]] \
  697. && echo -e "\n\e[1mNo existing sites found\e[0m" \
  698. && exec "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh
  699. # Display all static sites in a menu
  700. # Option menu from directory listing, based on terdon's answer in https://askubuntu.com/a/682146
  701. ## Collect all sites in the array $staticsites
  702. staticsites=( "${BASE_DIR}"/data/env/static/* )
  703. # strip path from directory names
  704. staticsites=( "${staticsites[@]##*/}" )
  705. staticsites=( "${staticsites[@]%.*}" )
  706. ## Enable extended globbing. This lets us use @(foo|bar) to
  707. ## match either 'foo' or 'bar'.
  708. shopt -s extglob
  709. ## Start building the string to match against.
  710. string="@(${staticsites[0]}"
  711. ## Add the rest of the site names to the string
  712. for((i=1;i<${#staticsites[@]};i++))
  713. do
  714. string+="|${staticsites[$i]}"
  715. done
  716. ## Close the parenthesis. $string is now @(site1|site2|...|siteN)
  717. string+=")"
  718. echo ""
  719. ## Show the menu. This will list all Static Sites that have an active environment file
  720. select static in "${staticsites[@]}" "$returntopreviousmenu"
  721. do
  722. case $static in
  723. $string)
  724. if [[ -f "${BASE_DIR}"/data/env/static/${static}.env ]];then
  725. source "${BASE_DIR}"/data/env/static/${static}.env
  726. else
  727. echo "No environment file found for $static. Exiting."
  728. exit 1
  729. fi
  730. echo ""
  731. static_choices=( "Remove site" "$returntopreviousmenu" )
  732. add_ssl_menuentry static_choices 1
  733. select static_choice in "${static_choices[@]}"
  734. do
  735. case $static_choice in
  736. "Remove site")
  737. echo -e "\n\e[4mRemove site\e[0m"
  738. prompt_confirm "Remove $static" && prompt_confirm "Are you sure?" && destroy_service
  739. say_done
  740. sleep 0.2
  741. break
  742. ;;
  743. "Generate self-signed certificate")
  744. generate_certificate
  745. restart_nginx
  746. say_done
  747. sleep 0.2
  748. break
  749. ;;
  750. "Obtain Let's Encrypt certificate")
  751. get_le_cert
  752. say_done
  753. sleep 0.2
  754. break
  755. ;;
  756. "Renew Let's Encrypt certificate")
  757. get_le_cert renew
  758. say_done
  759. sleep 0.2
  760. break
  761. ;;
  762. "$returntopreviousmenu")
  763. static_menu
  764. ;;
  765. *)
  766. echo "Invalid option."
  767. ;;
  768. esac
  769. done
  770. break;
  771. ;;
  772. "$returntopreviousmenu")
  773. exec "${SERVICES_DIR}"/statichtmlsite/statichtmlsite.sh options_menu;;
  774. *)
  775. static=""
  776. echo "Please choose a number from 1 to $((${#staticsites[@]}+1))";;
  777. esac
  778. done
  779. }
  780. backup() {
  781. ! [[ -d ${BASE_DIR}/data/backup/${SERVICE_NAME} ]] && mkdir -p ${BASE_DIR}/data/backup/${SERVICE_NAME}
  782. NOW=$(date -d "today" +"%Y%m%d_%H%M")
  783. # compressing volumes
  784. echo -e "\n\e[1mCompressing volumes\e[0m"
  785. for volume in ${!volumes[@]};do
  786. 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"
  787. echo -en "- $volume"
  788. exit_response
  789. done
  790. if [ -d "${CONF_DIR}"/${SERVICE_NAME} ];then
  791. ! [ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/conf ] \
  792. && mkdir "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/conf
  793. echo -en "\n\e[1mBacking up configuration files\e[0m"
  794. sleep 0.2
  795. cp -r "${CONF_DIR}"/${SERVICE_NAME}/* "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/conf
  796. exit_response
  797. fi
  798. if [[ ${SERVICE_DOMAIN[0]} ]] && [ -d "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]} ];then
  799. ! [ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl ] \
  800. && mkdir "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl
  801. echo -en "\n\e[1mBacking up SSL certificate\e[0m"
  802. sleep 0.2
  803. [[ -d "${CONF_DIR}"/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} ]] \
  804. && mkdir -p \
  805. "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl/letsencrypt/live \
  806. "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl/letsencrypt/archive \
  807. "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl/letsencrypt/renewal \
  808. && cp -r "${CONF_DIR}"/nginx/ssl/letsencrypt/archive/${SERVICE_DOMAIN[0]} "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl/letsencrypt/archive \
  809. && cp -r "${CONF_DIR}"/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl/letsencrypt/live \
  810. && cp -r "${CONF_DIR}"/nginx/ssl/letsencrypt/renewal/${SERVICE_DOMAIN[0]}.conf "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl/letsencrypt/renewal
  811. cp -r "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]} "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/ssl
  812. exit_response
  813. fi
  814. if [ -f "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf ];then
  815. ! [ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/nginx ] \
  816. && mkdir -p "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/nginx
  817. echo -en "\n\e[1mBacking up nginx configuration\e[0m"
  818. sleep 0.2
  819. cp -r "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}* "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}/nginx
  820. exit_response
  821. fi
  822. if [ -f "${ENV_DIR}"/${SERVICE_NAME}.env ];then
  823. echo -en "\n\e[1mBacking up environemt file(s)\e[0m"
  824. sleep 0.2
  825. [[ -f "${ENV_DIR}"/${SERVICE_SPECIFIC_MX}mx.env ]] \
  826. && cp "${ENV_DIR}"/${SERVICE_SPECIFIC_MX}mx.env "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}
  827. cp "${ENV_DIR}"/${SERVICE_NAME}.env "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${NOW}
  828. exit_response
  829. else
  830. echo -e "\n\e[3mCould not find environment file(s) for ${PROPER_NAME}.\e[0m"
  831. fi
  832. }
  833. restore() {
  834. echo ${FUNCNAME[@]}
  835. restoring=1
  836. ## Collect the backups in the array $backups
  837. backups=( "${BASE_DIR}"/data/backup/${SERVICE_NAME}/* )
  838. # strip path from directory names
  839. backups=( "${backups[@]##*/}" )
  840. ## Enable extended globbing. This lets us use @(foo|bar) to
  841. ## match either 'foo' or 'bar'.
  842. shopt -s extglob
  843. ## Start building the string to match against.
  844. string="@(${backups[0]}"
  845. ## Add the rest of the backups to the string
  846. for((i=1;i<${#backups[@]};i++))
  847. do
  848. string+="|${backups[$i]}"
  849. done
  850. ## Close the parenthesis. $string is now @(backup1|backup2|...|backupN)
  851. string+=")"
  852. # only continue if backup directory is not empty
  853. if [[ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME} ]] \
  854. && [[ $(ls -A "${BASE_DIR}"/data/backup/${SERVICE_NAME}) ]];then
  855. echo ""
  856. echo -e "\e[4mPlease choose a backup\e[0m"
  857. ## Show the menu. This will list all backups and the string "back to previous menu"
  858. select backup in "${backups[@]}" "Back to previous menu"
  859. do
  860. case $backup in
  861. ## If the choice is one of the backups (if it matches $string)
  862. $string)
  863. ! [[ -f "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/${SERVICE_NAME}.env ]] \
  864. && echo -e "\n\e[3mCould not find ${SERVICE_NAME}.env in ${backup}\e[0m" \
  865. && return
  866. # destroy current service if found
  867. if [[ $(docker ps -q -a --filter name=^/"${SERVICE_NAME}-service-dockerbunker"$) ]];then
  868. echo -e "\n\e[3m\xe2\x86\x92 Destroying ${PROPER_NAME}\e[0m"
  869. destroy_service
  870. fi
  871. source "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/${SERVICE_NAME}.env
  872. ! [[ $(docker ps -q --filter name=^/nginx-dockerbunker$) ]] && setup_nginx
  873. echo -e "\n\e[3m\xe2\x86\x92 Restoring ${PROPER_NAME}\e[0m"
  874. for volume in ${!volumes[@]};do
  875. [[ $(docker volume ls --filter name=^${volume}$) ]] \
  876. && docker volume create $volume >/dev/null
  877. 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"
  878. echo -en "\n\e[1mDecompressing $volume\e[0m"
  879. exit_response
  880. done
  881. sleep 0.2
  882. if [ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/conf ];then
  883. ! [ -d "${CONF_DIR}"/${SERVICE_NAME} ] \
  884. && mkdir "${CONF_DIR}"/${SERVICE_NAME}
  885. echo -en "\n\e[1mRestoring configuration files\e[0m"
  886. sleep 0.2
  887. cp -r "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/conf/* "${CONF_DIR}"/${SERVICE_NAME}
  888. exit_response
  889. fi
  890. if [ -f "${BASE_DIR}"/data/backup/${SERVICE_NAME}/$backup/nginx/${SERVICE_DOMAIN}.conf ];then
  891. ! [[ -d "${CONF_DIR}"/nginx/conf.inactive.d ]] \
  892. && mkdir "${CONF_DIR}"/nginx/conf.inactive.d
  893. echo -en "\n\e[1mRestoring nginx configuration\e[0m"
  894. cp -r "${BASE_DIR}"/data/backup/${SERVICE_NAME}/$backup/nginx/${SERVICE_DOMAIN}* "${CONF_DIR}"/nginx/conf.inactive.d
  895. exit_response
  896. fi
  897. sleep 0.2
  898. if [[ ${SERVICE_DOMAIN[0]} ]] && [ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/ssl ];then
  899. ! [ -d "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]} ] \
  900. && mkdir -p "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}
  901. echo -en "\n\e[1mRestoring SSL certificate\e[0m"
  902. sleep 0.2
  903. [[ -d "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} ]] \
  904. && mkdir -p \
  905. "${CONF_DIR}"/nginx/ssl/letsencrypt/live \
  906. "${CONF_DIR}"/nginx/ssl/letsencrypt/archive \
  907. "${CONF_DIR}"/nginx/ssl/letsencrypt/renewal \
  908. && cp -r "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/ssl/letsencrypt/archive/${SERVICE_DOMAIN[0]} "${CONF_DIR}"/nginx/ssl/letsencrypt/archive \
  909. && cp -r "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} "${CONF_DIR}"/nginx/ssl/letsencrypt/live \
  910. && cp -r "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/ssl/letsencrypt/renewal/${SERVICE_DOMAIN[0]}.conf "${CONF_DIR}"/nginx/ssl/letsencrypt/renewal
  911. cp -r "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/ssl/${SERVICE_DOMAIN[0]} "${CONF_DIR}"/nginx/ssl
  912. exit_response
  913. fi
  914. if [ -f "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/${SERVICE_NAME}.env ];then
  915. echo -en "\n\e[1mRestoring environemt file(s)\e[0m"
  916. sleep 0.2
  917. [[ -f "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/${SERVICE_SPECIFIC_MX}mx.env ]] \
  918. && cp "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/${SERVICE_SPECIFIC_MX}mx.env "${ENV_DIR}"
  919. cp "${BASE_DIR}"/data/backup/${SERVICE_NAME}/${backup}/${SERVICE_NAME}.env "${ENV_DIR}"
  920. exit_response
  921. fi
  922. create_networks
  923. docker_run_all
  924. activate_nginx_conf
  925. post_setup_routine
  926. exit 0
  927. ;;
  928. "Back to previous menu")
  929. "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh
  930. ;;
  931. *)
  932. backup=""
  933. echo "Please choose a number from 1 to $((${#backups[@]}+1))";;
  934. esac
  935. done
  936. else
  937. echo -e "\n\e[1mNo ${PROPER_NAME} backup found\e[0m"
  938. echo -e "\n\e[3m\xe2\x86\x92 Checking service status"
  939. exec "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh
  940. fi
  941. }