menu_functions.sh 36 KB

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