menu_functions.sh 36 KB

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