menu_functions.sh 36 KB

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