menu_functions.sh 37 KB

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