menu_functions.sh 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  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. while [[ -z ${RUNNING} ]];do
  16. echo -e "\n\e[3m$container container missing\e[0m\n" \
  17. && prompt_confirm "Re-run container?" \
  18. && docker_run ${container//-/_}
  19. RUNNING=$(docker ps -a -q --filter name=^/${container}$)
  20. done
  21. done
  22. fi
  23. if [[ $RUNNING ]];then
  24. menu=( "Reconfigure service" "Reinstall service" "Upgrade Image(s)" "Destroy \"${PROPER_NAME}\"" "$exitmenu" )
  25. add_ssl_menuentry menu 2
  26. if elementInArray "${PROPER_NAME}" "${STOPPED_SERVICES}";then
  27. insert menu "Start container(s)" 3
  28. else
  29. insert menu "Restart container(s)" 3
  30. insert menu "Stop container(s)" 4
  31. fi
  32. elif [[ $RUNNING == "false" ]];then
  33. menu=( "Reconfigure service" "Reinstall service" "Start container(s)" "Destroy \"${PROPER_NAME}\"" "$exitmenu" )
  34. add_ssl_menuentry menu 2
  35. else
  36. if ! elementInArray "${PROPER_NAME}" "${CONFIGURED_SERVICES[@]}" \
  37. && ! elementInArray "${PROPER_NAME}" "${INSTALLED_SERVICES[@]}" \
  38. && [[ ! -f "${ENV_DIR}/${SERVICE_NAME}.env" ]];then
  39. [[ ${STATIC} \
  40. && $(ls -A "${ENV_DIR}"/static) ]] \
  41. && menu=( "Configure Site" "Manage Sites" "$exitmenu" ) \
  42. || menu=( "Configure Site" "$exitmenu" )
  43. elif ! elementInArray "${PROPER_NAME}" "${CONFIGURED_SERVICES[@]}" \
  44. && ! elementInArray "${PROPER_NAME}" "${INSTALLED_SERVICES[@]}";then
  45. menu=( "Destroy \"${PROPER_NAME}\"" "$exitmenu" )
  46. error="Environment file found but ${PROPER_NAME} is not marked as configured or installed. Please destroy first!"
  47. elif elementInArray "${PROPER_NAME}" "${CONFIGURED_SERVICES[@]}" \
  48. && [[ ! -f "${ENV_DIR}/${SERVICE_NAME}.env" ]];then
  49. error="Service marked as configured, but configuration file is missing. Please destroy first."
  50. menu=( "Destroy \"${PROPER_NAME}\"" "$exitmenu" )
  51. elif elementInArray "${PROPER_NAME}" "${CONFIGURED_SERVICES[@]}" \
  52. && [[ -f "${ENV_DIR}/${SERVICE_NAME}.env" ]];then
  53. menu=( "Reconfigure service" "Setup service" "Destroy \"${PROPER_NAME}\"" "$exitmenu" )
  54. fi
  55. fi
  56. echo ""
  57. echo -e "\e[4m${PROPER_NAME}\e[0m"
  58. if [[ $error ]];then
  59. echo -e "\n\e[3m$error\e[0m\n"
  60. fi
  61. select choice in "${menu[@]}"
  62. do
  63. case $choice in
  64. "Configure Site")
  65. echo -e "\n\e[3m\xe2\x86\x92 Configure ${PROPER_NAME}\e[0m\n"
  66. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh configure
  67. say_done
  68. sleep 0.2
  69. break
  70. ;;
  71. "Configure service")
  72. echo -e "\n\e[3m\xe2\x86\x92 Configure ${PROPER_NAME}\e[0m\n"
  73. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh configure
  74. sleep 0.2
  75. break
  76. ;;
  77. "Manage Sites")
  78. echo -e "\n\e[3m\xe2\x86\x92 Manage sites\e[0m"
  79. static_menu
  80. sleep 0.2
  81. break
  82. ;;
  83. "Reconfigure service")
  84. echo -e "\n\e[3m\xe2\x86\x92 Reconfigure ${PROPER_NAME}\e[0m"
  85. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh reconfigure
  86. break
  87. ;;
  88. "Setup service")
  89. # Set up nginx container if not yet present
  90. setup_nginx
  91. echo -e "\n\e[3m\xe2\x86\x92 Setup ${PROPER_NAME}\e[0m"
  92. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh setup
  93. sleep 0.2
  94. break
  95. ;;
  96. "Reinstall service")
  97. echo -e "\n\e[3m\xe2\x86\x92 Reinstall ${PROPER_NAME}\e[0m"
  98. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh reinstall
  99. say_done
  100. sleep 0.2
  101. break
  102. ;;
  103. "Upgrade Image(s)")
  104. echo -e "\n\e[3m\xe2\x86\x92 Upgrade ${PROPER_NAME} images\e[0m"
  105. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh upgrade
  106. say_done
  107. sleep 0.2
  108. break
  109. ;;
  110. "Generate self-signed certificate")
  111. generate_certificate
  112. restart_nginx
  113. say_done
  114. sleep 0.2
  115. break
  116. ;;
  117. "Obtain Let's Encrypt certificate")
  118. get_le_cert
  119. say_done
  120. sleep 0.2
  121. exit
  122. ;;
  123. "Renew Let's Encrypt certificate")
  124. get_le_cert renew
  125. say_done
  126. sleep 0.2
  127. exit
  128. ;;
  129. "Restart container(s)")
  130. echo -e "\n\e[3m\xe2\x86\x92 Restart ${PROPER_NAME} Containers\e[0m"
  131. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh restart_containers
  132. say_done
  133. sleep 0.2
  134. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh
  135. break
  136. ;;
  137. "Start container(s)")
  138. echo -e "\n\e[3m\xe2\x86\x92 Start ${PROPER_NAME} Containers\e[0m"
  139. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh start_containers
  140. say_done
  141. sleep 0.2
  142. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh
  143. break
  144. ;;
  145. "Stop container(s)")
  146. echo -e "\n\e[3m\xe2\x86\x92 Stop ${PROPER_NAME} Containers\e[0m"
  147. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh stop_containers
  148. say_done
  149. sleep 0.2
  150. ${SERVICES_DIR}/${SERVICE_NAME}/${SERVICE_NAME}.sh
  151. break
  152. ;;
  153. "Destroy \"${PROPER_NAME}\"")
  154. echo -e "\n\e[3m\xe2\x86\x92 Destroy ${PROPER_NAME}\e[0m"
  155. echo ""
  156. echo "The following will be removed:"
  157. echo ""
  158. for container in ${containers[@]};do
  159. [[ $(docker ps -a -q --filter name=^/${container}$) ]] \
  160. && containers_found+=( $container )
  161. done
  162. [[ ${containers_found[0]} ]] \
  163. && echo "- ${PROPER_NAME} container(s)"
  164. for volume in ${volumes[@]};do
  165. [[ $(docker volume ls -q --filter name=^${volume}$) ]] \
  166. && volumes_found+=( $volume )
  167. done
  168. [[ ${volumes_found[0]} ]] && echo "- ${PROPER_NAME} volume(s)"
  169. [[ -f "${ENV_DIR}"/static/${SERVICE_DOMAIN[0]}.env \
  170. || -f "${ENV_DIR}"/${SERVICE_NAME}.env ]] \
  171. && echo "- ${PROPER_NAME} environment file(s)"
  172. [[ -f "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf \
  173. || -f "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf ]] \
  174. && echo "- nginx configuration of ${SERVICE_DOMAIN[0]}"
  175. [[ ${SERVICE_DOMAIN[0]} && -d "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]} ]] \
  176. && echo "- self-signed certificate for ${SERVICE_DOMAIN[0]}"
  177. echo ""
  178. prompt_confirm "Continue?" && prompt_confirm "Are you sure?" && . "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh destroy_service
  179. say_done
  180. sleep 0.2
  181. ${BASE_DIR}/dockerbunker.sh
  182. ;;
  183. "$exitmenu")
  184. exit 0
  185. ;;
  186. *)
  187. echo "Invalid option."
  188. ;;
  189. esac
  190. done
  191. }
  192. get_le_cert() {
  193. if ! [[ $1 == "renew" ]];then
  194. echo -e "\n\e[3m\xe2\x86\x92 Obtain Let's Encrypt certificate\e[0m"
  195. [[ -z ${LE_EMAIL} ]] && get_le_email
  196. if [[ ${STATIC} ]];then
  197. sed -i "s/SSL_CHOICE=.*/SSL_CHOICE=le/" "${ENV_DIR}"/static/${SERVICE_DOMAIN[0]}.env
  198. sed -i "s/LE_EMAIL=.*/LE_EMAIL="${LE_EMAIL}"/" "${ENV_DIR}"/static/${SERVICE_DOMAIN[0]}.env
  199. else
  200. sed -i "s/SSL_CHOICE=.*/SSL_CHOICE=le/" "${SERVICE_ENV}"
  201. sed -i "s/LE_EMAIL=.*/LE_EMAIL="${LE_EMAIL}"/" "${SERVICE_ENV}"
  202. fi
  203. elementInArray "${PROPER_NAME}" "${STOPPED_SERVICES[@]}" && "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh start_containers
  204. if [[ ${SERVICE_DOMAIN[0]} && -d "${CONF_DIR}"/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} && ! -L "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/cert.pem ]];then
  205. # Back up self-signed certificate
  206. mv "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/cert.{pem,pem.backup}
  207. mv "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/key.{pem,pem.backup}
  208. # Symlink letsencrypt certificate
  209. ln -sf "/etc/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]}/fullchain.pem" "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/cert.pem
  210. ln -sf "/etc/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]}/privkey.pem" "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/key.pem
  211. restart_nginx
  212. else
  213. letsencrypt issue
  214. fi
  215. else
  216. echo -e "\n\e[3m\xe2\x86\x92 Renew Let's Encrypt certificate\e[0m"
  217. export prevent_nginx_restart=1
  218. [[ -z ${STATIC} ]] && "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh start_containers
  219. bash "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh letsencrypt issue
  220. fi
  221. }
  222. # start/stop/restart nginx container
  223. restart_nginx() {
  224. echo -en "\n\e[1mRestarting nginx container\e[0m"
  225. docker exec -it nginx-dockerbunker nginx -t >/dev/null \
  226. && docker restart ${NGINX_CONTAINER} >/dev/null
  227. exit_response
  228. if [[ $? == 1 ]];then
  229. echo ""
  230. docker exec -it nginx-dockerbunker nginx -t
  231. echo -e "\n\e[3m\xe2\x86\x92 \e[3m\`nginx -t\` failed. Trying to add missing containers to dockerbunker-network.\e[0m"
  232. for container in ${CONTAINERS_IN_DOCKERBUNKER_NETWORK[@]};do
  233. connect_containers_to_network ${container}
  234. done
  235. echo -en "\n\e[1mRestarting nginx container\e[0m"
  236. docker exec -it nginx-dockerbunker nginx -t >/dev/null \
  237. && docker restart ${NGINX_CONTAINER} >/dev/null
  238. exit_response
  239. if [[ $? == 1 ]];then
  240. echo ""
  241. docker exec -it nginx-dockerbunker nginx -t
  242. echo -e "\n\`nginx -t\` failed again. Please resolve issue and try again."
  243. fi
  244. fi
  245. }
  246. start_nginx() {
  247. echo -en "\n\e[1mStarting nginx container\e[0m"
  248. docker start ${NGINX_CONTAINER} >/dev/null
  249. exit_response
  250. }
  251. stop_nginx() {
  252. echo -en "\n\e[1mStopping nginx container\e[0m"
  253. docker stop ${NGINX_CONTAINER} >/dev/null
  254. exit_response
  255. }
  256. # all functions starting/stopping/restarting containers of individual services. This is offered in every service specific menu.
  257. deactivate_nginx_conf() {
  258. if [[ ${SERVICE_NAME} == "nginx" ]] \
  259. || [[ -f "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf ]] \
  260. || elementInArray "${PROPER_NAME}" "${STOPPED_SERVICES[@]}" \
  261. || [[ ${FUNCNAME[2]} == "destroy_service" ]];then \
  262. return
  263. fi
  264. ! [[ -f "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf ]] \
  265. && [[ -z $reconfigure ]] \
  266. && 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" \
  267. && return
  268. ! [[ -d "${CONF_DIR}"/nginx/conf.inactive.d ]] \
  269. && mkdir "${CONF_DIR}"/nginx/conf.inactive.d
  270. if [[ -f "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf ]];then
  271. echo -en "\n\e[1mDeactivating nginx configuration\e[0m"
  272. [[ -d "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]} ]] \
  273. && mv "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]} "${CONF_DIR}"/nginx/conf.inactive.d/
  274. mv "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf "${CONF_DIR}"/nginx/conf.inactive.d/
  275. exit_response
  276. fi
  277. if ! elementInArray "${PROPER_NAME}" "${STOPPED_SERVICES[@]}";then
  278. STOPPED_SERVICES+=( "${PROPER_NAME}" )
  279. sed -i '/STOPPED_SERVICES/d' "${ENV_DIR}"/dockerbunker.env
  280. declare -p STOPPED_SERVICES >> "${ENV_DIR}"/dockerbunker.env
  281. fi
  282. [[ -z $prevent_nginx_restart ]] && restart_nginx
  283. }
  284. activate_nginx_conf() {
  285. [[ ${SERVICE_NAME} == "nginx" ]] && return
  286. [[ ${FUNCNAME[1]} != "setup" ]] \
  287. && elementInArray "${PROPER_NAME}" "${STOPPED_SERVICES[@]}" \
  288. && ! [[ -f "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf ]] \
  289. && 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" \
  290. && return
  291. # activate nginx config
  292. [[ -d "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]} ]] \
  293. && mv "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]} "${CONF_DIR}"/nginx/conf.d/
  294. [[ -f "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf ]] \
  295. && mv "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf "${CONF_DIR}"/nginx/conf.d/
  296. }
  297. start_containers() {
  298. RUNNING=$(docker inspect --format="{{.State.Running}}" ${NGINX_CONTAINER} 2> /dev/null)
  299. [[ $RUNNING == "false" ]] || [[ -z $RUNNING ]] && bash -c "${SERVICES_DIR}"/nginx/nginx.sh setup
  300. echo -e "\n\e[1mStarting containers\e[0m"
  301. for container in "${containers[@]}";do
  302. [[ $(docker ps -q --filter "status=exited" --filter name=^/${container}$) ]] \
  303. && echo -en "- $container" \
  304. && docker start $container >/dev/null 2>&1 \
  305. && exit_response
  306. done
  307. [[ $? == 1 ]] && echo " Nothing to do. Please configure & setup ${PROPER_NAME} first."
  308. remove_from_STOPPED_SERVICES
  309. activate_nginx_conf
  310. [[ -z $prevent_nginx_restart ]] && restart_nginx
  311. }
  312. stop_containers() {
  313. deactivate_nginx_conf
  314. echo -e "\n\e[1mStopping containers\e[0m"
  315. for container in "${containers[@]}";do
  316. [[ $(docker ps -q --filter name=^/${container}$) ]] \
  317. && echo -en "- $container" \
  318. && docker stop $container >/dev/null 2>&1 \
  319. && exit_response \
  320. || echo "- $container (not running)"
  321. done
  322. }
  323. remove_containers() {
  324. for container in ${containers[@]};do
  325. [[ $(docker ps -a -q --filter name=^/${container}$) ]] \
  326. && containers_found+=( $container )
  327. done
  328. if [[ -z ${containers_found[0]} ]];then
  329. echo -e "\n\e[1mRemoving containers\e[0m"
  330. for container in "${containers[@]}";do
  331. [[ $(docker ps -q --filter "status=exited" --filter name=^/${container}$) || $(docker ps -q --filter "status=restarting" --filter name=^/${container}$) ]] \
  332. && echo -en "- $container" \
  333. && docker rm -f $container >/dev/null 2>&1 \
  334. && exit_response \
  335. || echo "- $container (not found)"
  336. done
  337. elif [[ ${#containers_found[@]} > 0 ]];then
  338. echo -e "\n\e[1mRemoving containers\e[0m"
  339. for container in "${containers[@]}";do
  340. echo -en "- $container"
  341. docker rm -f $container >/dev/null 2>&1
  342. exit_response
  343. done
  344. else
  345. return
  346. fi
  347. }
  348. remove_volumes() {
  349. if [[ ${volumes[0]} && $remove_volumes ]] || [[ $destroy_all ]];then
  350. echo -e "\n\e[1mRemoving volumes\e[0m"
  351. for volume in "${volumes[@]}";do
  352. [[ $(docker volume ls -q --filter name=^${volume}$) ]] \
  353. && echo -en "- $volume" \
  354. && docker volume rm $volume >/dev/null \
  355. && exit_response \
  356. || echo "- $volume (not found)"
  357. done
  358. fi
  359. }
  360. remove_networks() {
  361. if [[ ${networks[0]} ]];then
  362. echo -e "\n\e[1mRemoving networks\e[0m"
  363. for network in "${networks[@]}";do
  364. [[ $(docker network ls -q --filter name=^${network}$) ]] \
  365. && echo -en "- $network" \
  366. && docker network rm $network >/dev/null \
  367. && exit_response \
  368. || echo "- $network (not found)"
  369. done
  370. fi
  371. }
  372. restart_containers() {
  373. echo -e "\n\e[1mRestarting containers\e[0m"
  374. [[ $(docker ps -a -q --filter name=^/${NGINX_CONTAINER}$ 2> /dev/null) ]] \
  375. || bash -c "${SERVICES_DIR}"/nginx/nginx.sh setup
  376. for container in "${containers[@]}";do
  377. [[ $(docker ps -q --filter name=^/${container}$) ]] && ( echo -en "- $container";docker restart $container >/dev/null 2>&1;exit_response )
  378. done
  379. [[ $? == 1 ]] && echo " Nothing to do. Please configure & setup ${PROPER_NAME} first."
  380. [[ -z $prevent_nginx_restart ]] && restart_nginx
  381. }
  382. remove_images() {
  383. if [[ ${IMAGES[0]} ]];then
  384. prompt_confirm "Remove all images?"
  385. if [[ $? == 0 ]];then
  386. echo -e "\n\e[1mRemoving images\e[0m"
  387. for image in "${IMAGES[@]}";do
  388. if ! [[ $(docker container ls | awk '{print $2}' | grep "\<${image}\>") ]];then
  389. echo -en "- $image"
  390. docker rmi $image >/dev/null
  391. exit_response
  392. fi
  393. done
  394. fi
  395. fi
  396. }
  397. remove_service_conf() {
  398. [[ -d "${CONF_DIR}/${SERVICE_NAME}" ]] \
  399. && rm -r "${CONF_DIR}/${SERVICE_NAME}/*" \
  400. }
  401. remove_environment_files() {
  402. [[ -f "${ENV_DIR}/${SERVICE_NAME}.env" ]] \
  403. && echo -en "\n\e[1mRemoving ${SERVICE_NAME}.env\e[0m" \
  404. && rm "${ENV_DIR}/${SERVICE_NAME}.env" \
  405. && exit_response
  406. [[ ${SERVICE_SPECIFIC_MX} ]] && [[ -f "${ENV_DIR}/${SERVICE_SPECIFIC_MX}mx.env" ]] \
  407. && rm "${ENV_DIR}/${SERVICE_SPECIFIC_MX}mx.env"
  408. [[ ${STATIC} && -f "${ENV_DIR}/static/${SERVICE_DOMAIN[0]}.env" ]] \
  409. && echo -en "\n\e[1mRemoving ${SERVICE_DOMAIN[0]}.env\e[0m" \
  410. && rm "${ENV_DIR}/static/${SERVICE_DOMAIN[0]}.env" \
  411. && exit_response
  412. }
  413. remove_ssl_certificate() {
  414. if [[ ${SERVICE_DOMAIN[0]} ]] && [[ -d "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]} ]];then
  415. echo -en "\n\e[1mRemoving SSL Certificate\e[0m"
  416. rm -r "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}
  417. exit_response
  418. fi
  419. }
  420. destroy_service() {
  421. export remove_volumes=1
  422. if [[ -z ${STATIC} ]];then
  423. disconnect_from_dockerbunker_network
  424. stop_containers
  425. remove_containers
  426. remove_volumes
  427. remove_networks
  428. remove_images
  429. echo -en "\n\e[1mRemoving ${PROPER_NAME} from dockerbunker.env\e[0m"
  430. remove_from_WEB_SERVICES
  431. remove_from_CONFIGURED_SERVICES
  432. remove_from_INSTALLED_SERVICES
  433. remove_from_STOPPED_SERVICES
  434. remove_from_CONTAINERS_IN_DOCKERBUNKER_NETWORK
  435. else
  436. [[ -d ${STATIC_HOME} ]] \
  437. && prompt_confirm "Remove HTML directory [${STATIC_HOME}]" \
  438. && echo -en "\n\e[1mRemoving ${STATIC_HOME}\e[0m" \
  439. && rm -r ${STATIC_HOME} >/dev/null \
  440. && exit_response
  441. echo -en "\n\e[1mRemoving "${SERVICE_DOMAIN[0]}" from dockerbunker.env\e[0m"
  442. remove_from_STATIC_SITES
  443. fi
  444. exit_response
  445. remove_nginx_conf
  446. remove_environment_files
  447. remove_service_conf
  448. remove_ssl_certificate
  449. [[ -z $destroy_all ]] \
  450. && [[ -z ${INSTALLED_SERVICES[@]} ]] \
  451. && [[ $(docker ps -q --filter name=^/${NGINX_CONTAINER}) ]] \
  452. && echo -e "\nNo remaining services running.\n" \
  453. && prompt_confirm "Destroy nginx as well and completely reset dockerbunker?" \
  454. && bash "${SERVICES_DIR}"/nginx/nginx.sh destroy_service \
  455. && return
  456. [[ -z $prevent_nginx_restart ]] \
  457. && [[ ${SERVICE_NAME} != "nginx" ]] \
  458. && restart_nginx
  459. }
  460. # minimal setup routine. if more is needed add custom setup() in data/services/${SERVICE_NAME}/${SERVICE_NAME}.sh
  461. setup() {
  462. initial_setup_routine
  463. SUBSTITUTE=( "\${SERVICE_DOMAIN}" )
  464. basic_nginx
  465. docker_run_all
  466. post_setup_routine
  467. }
  468. # minimal upgrade routine. if more is needed add custom upgrade() in data/services/${SERVICE_NAME}/${SERVICE_NAME}.sh
  469. upgrade() {
  470. pull_and_compare
  471. stop_containers
  472. remove_containers
  473. docker_run_all
  474. delete_old_images
  475. }
  476. reinstall() {
  477. echo ""
  478. prompt_confirm "Keep volumes?" && export keep_volumes=1 || export remove_volumes=1
  479. disconnect_from_dockerbunker_network
  480. stop_containers
  481. remove_containers
  482. remove_volumes
  483. remove_networks
  484. export reinstall=1
  485. setup
  486. }
  487. remove_nginx_conf() {
  488. if [[ ${SERVICE_DOMAIN[0]} ]];then
  489. if [[ -f "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf || -f "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf ]];then
  490. echo -e "\n\e[1mRemoving nginx configuration\e[0m"
  491. echo -n "- ${SERVICE_DOMAIN[0]}.conf"
  492. [[ -d "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]} ]] \
  493. && rm -r "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]} \
  494. || true
  495. [[ -d "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]} ]] \
  496. && rm -r "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]} \
  497. || true
  498. [[ -f "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf ]] \
  499. && rm "${CONF_DIR}"/nginx/conf.d/${SERVICE_DOMAIN[0]}.conf \
  500. || true
  501. [[ -f "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf ]] \
  502. && rm "${CONF_DIR}"/nginx/conf.inactive.d/${SERVICE_DOMAIN[0]}.conf \
  503. || true
  504. exit_response
  505. fi
  506. fi
  507. }
  508. disconnect_from_dockerbunker_network() {
  509. for container in ${add_to_network[@]};do
  510. [[ $container && $(docker ps -q --filter name=^/${container}$) ]] \
  511. && docker network disconnect ${NETWORK} $container >/dev/null
  512. done
  513. }
  514. reconfigure() {
  515. reconfigure=1
  516. if [[ $safe_to_keep_volumes_when_reconfiguring ]];then
  517. echo ""
  518. prompt_confirm "Keep volumes?" || remove_volumes=1
  519. else
  520. echo ""
  521. prompt_confirm "All volumes will be removed. Continue?" && remove_volumes=1 || exit 0
  522. fi
  523. disconnect_from_dockerbunker_network
  524. stop_containers
  525. remove_containers
  526. remove_volumes
  527. remove_networks
  528. remove_nginx_conf
  529. remove_ssl_certificate
  530. remove_environment_files
  531. remove_service_conf
  532. [[ $(grep "${PROPER_NAME}" "${ENV_DIR}/dockerbunker.env") ]] && echo -en "\n\e[1mRemoving ${PROPER_NAME} from dockerbunker.env\e[0m"
  533. remove_from_WEB_SERVICES
  534. remove_from_CONFIGURED_SERVICES
  535. remove_from_INSTALLED_SERVICES
  536. remove_from_STOPPED_SERVICES
  537. remove_from_CONTAINERS_IN_DOCKERBUNKER_NETWORK
  538. exit_response
  539. echo ""
  540. configure
  541. }
  542. # all functions that manipulate all containers
  543. start_all() {
  544. start_nginx
  545. for PROPER_NAME in "${STOPPED_SERVICES[@]}";do
  546. SERVICE_NAME="$(echo -e "${service,,}" | tr -d '[:space:]')"
  547. source "${ENV_DIR}/${SERVICE_NAME}.env"
  548. source "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh start_containers
  549. done
  550. restart_nginx
  551. }
  552. restart_all() {
  553. for service in "${INSTALLED_SERVICES[@]}";do
  554. service="$(echo -e "${service,,}" | tr -d '[:space:]')"
  555. source "${SERVICE_ENV}"
  556. source "${SERVICES_DIR}"/${service}/${service}.sh restart_containers
  557. done
  558. restart_nginx
  559. }
  560. stop_all() {
  561. for service in "${INSTALLED_SERVICES[@]}";do
  562. service="$(echo -e "${service,,}" | tr -d '[:space:]')"
  563. if ! elementInArray "$service" "${STOPPED_SERVICES[@]}";then
  564. source "${SERVICE_ENV}"
  565. source "${SERVICES_DIR}"/${service}/${service}.sh stop_containers
  566. fi
  567. done
  568. stop_nginx
  569. export prevent_nginx_restart=1
  570. }
  571. destroy_all() {
  572. # destroy_service() is calling restart_nginx, we don't want this happening after each service is destroyed
  573. export prevent_nginx_restart=1
  574. export destroy_all=1
  575. all_services=( "${INSTALLED_SERVICES[@]}" "${CONFIGURED_SERVICES[@]}" "nginx" )
  576. echo -e "\nDestroying ${all_services[@]}\n"
  577. printf "The following Services will be removed: \
  578. $(for i in "${all_services[@]}";do \
  579. if [[ "$i" == ${all_services[-1]} ]];then \
  580. (printf "\"\e[33m%s\e[0m\" " "$i" )
  581. else
  582. (printf "\"\e[33m%s\e[0m\", " "$i" )
  583. fi
  584. done) \n"
  585. prompt_confirm "Are you sure?"
  586. [[ $? == 1 ]] && echo "Exiting..." && exit 0
  587. for service in "${all_services[@]}";do
  588. SERVICE_NAME="$(echo -e "${service,,}" | tr -d '[:space:]')"
  589. echo -e "\n\e[3m\xe2\x86\x92 Destroying $service\e[0m"
  590. [[ -f "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh ]] \
  591. && "${SERVICES_DIR}"/${SERVICE_NAME}/${SERVICE_NAME}.sh destroy_service
  592. done
  593. [[ $(ls -A "${CONF_DIR}"/nginx/conf.inactive.d) ]] \
  594. && rm -r "${CONF_DIR}"/nginx/conf.inactive.d/*
  595. [[ $(ls -A "${CONF_DIR}"/nginx/conf.d) ]] \
  596. && rm -r "${CONF_DIR}"/nginx/conf.d/*
  597. for cert_dir in $(ls "${CONF_DIR}"/nginx/ssl/);do
  598. [[ $cert_dir != "letsencrypt" ]] \
  599. && rm -r "${CONF_DIR}"/nginx/ssl/$cert_dir
  600. done
  601. [[ $(ls -A "${ENV_DIR}"/static) ]] \
  602. && rm "${ENV_DIR}"/static/*
  603. }
  604. add_ssl_menuentry() {
  605. if [[ $SSL_CHOICE == "le" ]] && [[ -d "${CONF_DIR}"/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} ]];then
  606. # in this case le cert has been obtained previously and everything is as expected
  607. insert $1 "Renew Let's Encrypt certificate" $2
  608. elif ! [[ -d "${CONF_DIR}"/nginx/ssl/letsencrypt/live/${SERVICE_DOMAIN[0]} ]] && [[ -L "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/cert.pem ]];then
  609. # 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
  610. insert $1 "Generate self-signed certificate" $2
  611. insert $1 "Obtain Let's Encrypt certificate" $2
  612. elif [[ -f "${CONF_DIR}"/nginx/ssl/${SERVICE_DOMAIN[0]}/cert.pem ]];then
  613. # 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)
  614. insert $1 "Obtain Let's Encrypt certificate" $2
  615. else
  616. # not sure when this should be the case, but if it does happen, bot options are available
  617. insert $1 "Generate self-signed certificate" $2
  618. insert $1 "Obtain Let's Encrypt certificate" $2
  619. fi
  620. }
  621. static_menu() {
  622. [[ -z ${STATIC_SITES[0]} ]] \
  623. && echo -e "\n\e[1mNo existing sites found\e[0m\n" \
  624. && return
  625. # Display all static sites in a menu
  626. # Option menu from directory listing, based on terdon's answer in https://askubuntu.com/a/682146
  627. ## Collect all sites in the array $staticsites
  628. staticsites=( "${BASE_DIR}"/data/env/static/* )
  629. # strip path from directory names
  630. staticsites=( "${staticsites[@]##*/}" )
  631. staticsites=( "${staticsites[@]%.*}" )
  632. ## Enable extended globbing. This lets us use @(foo|bar) to
  633. ## match either 'foo' or 'bar'.
  634. shopt -s extglob
  635. ## Start building the string to match against.
  636. string="@(${staticsites[0]}"
  637. ## Add the rest of the site names to the string
  638. for((i=1;i<${#staticsites[@]};i++))
  639. do
  640. string+="|${staticsites[$i]}"
  641. done
  642. ## Close the parenthesis. $string is now @(site1|site2|...|siteN)
  643. string+=")"
  644. echo ""
  645. ## Show the menu. This will list all Static Sites that have an active environment file
  646. select static in "${staticsites[@]}" "$returntopreviousmenu"
  647. do
  648. case $static in
  649. $string)
  650. if [[ -f "${BASE_DIR}"/data/env/static/${static}.env ]];then
  651. source "${BASE_DIR}"/data/env/static/${static}.env
  652. else
  653. echo "No environment file found for $static. Exiting."
  654. exit 1
  655. fi
  656. echo ""
  657. static_choices=( "Remove site" "$returntopreviousmenu" )
  658. add_ssl_menuentry static_choices 1
  659. select static_choice in "${static_choices[@]}"
  660. do
  661. case $static_choice in
  662. "Remove site")
  663. echo -e "\n\e[4mRemove site\e[0m"
  664. prompt_confirm "Remove $static" && prompt_confirm "Are you sure?" && destroy_service
  665. say_done
  666. sleep 0.2
  667. break
  668. ;;
  669. "Generate self-signed certificate")
  670. generate_certificate
  671. restart_nginx
  672. say_done
  673. sleep 0.2
  674. break
  675. ;;
  676. "Obtain Let's Encrypt certificate")
  677. get_le_cert
  678. say_done
  679. sleep 0.2
  680. break
  681. ;;
  682. "Renew Let's Encrypt certificate")
  683. get_le_cert renew
  684. say_done
  685. sleep 0.2
  686. break
  687. ;;
  688. "$returntopreviousmenu")
  689. static_menu
  690. ;;
  691. *)
  692. echo "Invalid option."
  693. ;;
  694. esac
  695. done
  696. break;
  697. ;;
  698. "$returntopreviousmenu")
  699. exec "${SERVICES_DIR}"/statichtmlsite/statichtmlsite.sh options_menu;;
  700. *)
  701. static=""
  702. echo "Please choose a number from 1 to $((${#staticsites[@]}+1))";;
  703. esac
  704. done
  705. }