morty.sh 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. #!/usr/bin/env bash
  2. # -*- coding: utf-8; mode: sh indent-tabs-mode: nil -*-
  3. # SPDX-License-Identifier: AGPL-3.0-or-later
  4. # shellcheck source=utils/lib.sh
  5. source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
  6. source_dot_config
  7. # ----------------------------------------------------------------------------
  8. # config
  9. # ----------------------------------------------------------------------------
  10. PUBLIC_URL_PATH_MORTY="/morty"
  11. PUBLIC_URL_MORTY="$(dirname ${PUBLIC_URL})${PUBLIC_URL_PATH_MORTY}"
  12. MORTY_LISTEN="${MORTY_LISTEN:-127.0.0.1:3000}"
  13. MORTY_TIMEOUT=5
  14. SERVICE_NAME="morty"
  15. SERVICE_USER="${SERVICE_USER:-${SERVICE_NAME}}"
  16. SERVICE_HOME="/home/${SERVICE_USER}"
  17. SERVICE_SYSTEMD_UNIT="${SYSTEMD_UNITS}/${SERVICE_NAME}.service"
  18. # shellcheck disable=SC2034
  19. SERVICE_GROUP="${SERVICE_USER}"
  20. SERVICE_ENV_DEBUG=false
  21. GO_ENV="${SERVICE_HOME}/.go_env"
  22. GO_PKG_URL="https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz"
  23. GO_TAR=$(basename "$GO_PKG_URL")
  24. # shellcheck disable=SC2034
  25. CONFIG_FILES=()
  26. # Apache Settings
  27. APACHE_MORTY_SITE="morty.conf"
  28. # ----------------------------------------------------------------------------
  29. usage() {
  30. # ----------------------------------------------------------------------------
  31. # shellcheck disable=SC1117
  32. cat <<EOF
  33. usage::
  34. $(basename "$0") shell
  35. $(basename "$0") install [all|user]
  36. $(basename "$0") update [morty]
  37. $(basename "$0") remove [all]
  38. $(basename "$0") activate [service]
  39. $(basename "$0") deactivate [service]
  40. $(basename "$0") inspect [service]
  41. $(basename "$0") option [debug-on|debug-off]
  42. $(basename "$0") apache [install|remove]
  43. shell
  44. start interactive shell from user ${SERVICE_USER}
  45. install / remove
  46. all: complete setup of morty service
  47. user: add/remove service user '$SERVICE_USER' at $SERVICE_HOME
  48. update morty
  49. Update morty installation of user ${SERVICE_USER}
  50. activate service
  51. activate and start service daemon (systemd unit)
  52. deactivate service
  53. stop and deactivate service daemon (systemd unit)
  54. inspect service
  55. show service status and log
  56. option
  57. set one of the available options
  58. apache : ${PUBLIC_URL_MORTY}
  59. :install: apache site with a reverse proxy (ProxyPass)
  60. :remove: apache site ${APACHE_MORTY_SITE}
  61. If needed, set the environment variable MORTY_LISTEN in the
  62. ${DOT_CONFIG#"$REPO_ROOT/"} file::
  63. MORTY_LISTEN : ${MORTY_LISTEN}
  64. To activate morty in searx, add result_proxy to your settings.yml::
  65. result_proxy:
  66. url : ${PUBLIC_URL_MORTY}
  67. further read: https://asciimoo.github.io/searx/admin/morty.html
  68. EOF
  69. [ ! -z ${1+x} ] && echo -e "$1"
  70. }
  71. main() {
  72. rst_title "$SERVICE_NAME" part
  73. required_commands \
  74. dpkg apt-get install git wget curl \
  75. || exit
  76. local _usage="ERROR: unknown or missing $1 command $2"
  77. case $1 in
  78. --source-only) ;;
  79. -h|--help) usage; exit 0;;
  80. shell)
  81. sudo_or_exit
  82. interactive_shell "${SERVICE_USER}"
  83. ;;
  84. inspect)
  85. case $2 in
  86. service)
  87. sudo_or_exit
  88. inspect_service
  89. ;;
  90. *) usage "$_usage"; exit 42;;
  91. esac ;;
  92. install)
  93. sudo_or_exit
  94. case $2 in
  95. all) install_all ;;
  96. user) assert_user ;;
  97. *) usage "$_usage"; exit 42;;
  98. esac ;;
  99. update)
  100. sudo_or_exit
  101. case $2 in
  102. morty) update_morty ;;
  103. *) usage "$_usage"; exit 42;;
  104. esac ;;
  105. remove)
  106. sudo_or_exit
  107. case $2 in
  108. all) remove_all;;
  109. user) drop_service_account "${SERVICE_USER}" ;;
  110. *) usage "$_usage"; exit 42;;
  111. esac ;;
  112. activate)
  113. sudo_or_exit
  114. case $2 in
  115. service) systemd_activate_service "${SERVICE_NAME}" ;;
  116. *) usage "$_usage"; exit 42;;
  117. esac ;;
  118. deactivate)
  119. sudo_or_exit
  120. case $2 in
  121. service) systemd_deactivate_service "${SERVICE_NAME}" ;;
  122. *) usage "$_usage"; exit 42;;
  123. esac ;;
  124. apache)
  125. sudo_or_exit
  126. case $2 in
  127. install) install_apache_site ;;
  128. remove) remove_apache_site ;;
  129. *) usage "$_usage"; exit 42;;
  130. esac ;;
  131. option)
  132. sudo_or_exit
  133. case $2 in
  134. debug-on) enable_debug ;;
  135. debug-off) disable_debug ;;
  136. *) usage "$_usage"; exit 42;;
  137. esac ;;
  138. *) usage "ERROR: unknown or missing command $1"; exit 42;;
  139. esac
  140. }
  141. install_all() {
  142. rst_title "Install $SERVICE_NAME (service)"
  143. assert_user
  144. wait_key
  145. install_go "${GO_PKG_URL}" "${GO_TAR}" "${SERVICE_USER}"
  146. wait_key
  147. install_morty
  148. wait_key
  149. systemd_install_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"
  150. wait_key
  151. echo
  152. if ! service_is_available "http://${MORTY_LISTEN}" ; then
  153. err_msg "Morty does not listening on: http://${MORTY_LISTEN}"
  154. fi
  155. if ask_yn "Do you want to inspect the installation?" Yn; then
  156. inspect_service
  157. fi
  158. }
  159. remove_all() {
  160. rst_title "De-Install $SERVICE_NAME (service)"
  161. rst_para "\
  162. It goes without saying that this script can only be used to remove
  163. installations that were installed with this script."
  164. if systemd_remove_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"; then
  165. drop_service_account "${SERVICE_USER}"
  166. fi
  167. }
  168. assert_user() {
  169. rst_title "user $SERVICE_USER" section
  170. echo
  171. tee_stderr 1 <<EOF | bash | prefix_stdout
  172. sudo -H adduser --shell /bin/bash --system --home $SERVICE_HOME \
  173. --disabled-password --group --gecos 'Morty' $SERVICE_USER
  174. sudo -H usermod -a -G shadow $SERVICE_USER
  175. groups $SERVICE_USER
  176. EOF
  177. SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME)"
  178. export SERVICE_HOME
  179. echo "export SERVICE_HOME=$SERVICE_HOME"
  180. cat > "$GO_ENV" <<EOF
  181. export GOPATH=\$HOME/go-apps
  182. export PATH=\$PATH:\$HOME/local/go/bin:\$GOPATH/bin
  183. EOF
  184. echo "Environment $GO_ENV has been setup."
  185. tee_stderr <<EOF | sudo -i -u "$SERVICE_USER"
  186. grep -qFs -- 'source $GO_ENV' ~/.profile || echo 'source $GO_ENV' >> ~/.profile
  187. EOF
  188. }
  189. morty_is_installed() {
  190. [[ -f $SERVICE_HOME/go-apps/bin/morty ]]
  191. }
  192. _svcpr=" |${SERVICE_USER}| "
  193. install_morty() {
  194. rst_title "Install morty in user's ~/go-apps" section
  195. echo
  196. tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
  197. go get -v -u github.com/asciimoo/morty
  198. EOF
  199. tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
  200. cd \$GOPATH/src/github.com/asciimoo/morty
  201. go test
  202. go test -benchmem -bench .
  203. EOF
  204. }
  205. update_morty() {
  206. rst_title "Update morty" section
  207. echo
  208. tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
  209. go get -v -u github.com/asciimoo/morty
  210. EOF
  211. tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
  212. cd \$GOPATH/src/github.com/asciimoo/morty
  213. go test
  214. go test -benchmem -bench .
  215. EOF
  216. }
  217. set_service_env_debug() {
  218. # usage: set_service_env_debug [false|true]
  219. local SERVICE_ENV_DEBUG="${1:-false}"
  220. if systemd_remove_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"; then
  221. systemd_install_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"
  222. fi
  223. }
  224. inspect_service() {
  225. rst_title "service status & log"
  226. cat <<EOF
  227. sourced ${DOT_CONFIG#"$REPO_ROOT/"} :
  228. MORTY_LISTEN : ${MORTY_LISTEN}
  229. EOF
  230. if service_account_is_available "$SERVICE_USER"; then
  231. info_msg "service account $SERVICE_USER available."
  232. else
  233. err_msg "service account $SERVICE_USER not available!"
  234. fi
  235. if go_is_available "$SERVICE_USER"; then
  236. info_msg "~$SERVICE_USER: go is installed"
  237. else
  238. err_msg "~$SERVICE_USER: go is not installed"
  239. fi
  240. if morty_is_installed; then
  241. info_msg "~$SERVICE_USER: morty app is installed"
  242. else
  243. err_msg "~$SERVICE_USER: morty app is not installed!"
  244. fi
  245. if ! service_is_available "http://${MORTY_LISTEN}" ; then
  246. err_msg "Morty does not listening on: http://${MORTY_LISTEN}"
  247. echo -e "${_Green}stop with [${_BCyan}CTRL-C${_Green}] or .."
  248. wait_key
  249. fi
  250. local _debug_on
  251. if ask_yn "Enable filtron debug mode?"; then
  252. enable_debug
  253. _debug_on=1
  254. fi
  255. echo
  256. systemctl --no-pager -l status "${SERVICE_NAME}"
  257. echo
  258. # shellcheck disable=SC2059
  259. info_msg "morty URL --> http://${MORTY_LISTEN}"
  260. info_msg "public URL --> ${PUBLIC_URL_MORTY}"
  261. printf "// use ${_BCyan}CTRL-C${_creset} to stop monitoring the log"
  262. read -r -s -n1 -t 2
  263. echo
  264. while true; do
  265. trap break 2
  266. journalctl -f -u "${SERVICE_NAME}"
  267. done
  268. if [[ $_debug_on == 1 ]]; then
  269. FORCE_SELECTION=Y disable_debug
  270. fi
  271. return 0
  272. }
  273. enable_debug() {
  274. warn_msg "Do not enable debug in production enviroments!!"
  275. info_msg "Enabling debug option needs to reinstall systemd service!"
  276. set_service_env_debug true
  277. }
  278. disable_debug() {
  279. info_msg "Disabling debug option needs to reinstall systemd service!"
  280. set_service_env_debug false
  281. }
  282. install_apache_site() {
  283. rst_title "Install Apache site $APACHE_MORTY_SITE"
  284. rst_para "\
  285. This installs a reverse proxy (ProxyPass) into apache site (${APACHE_MORTY_SITE})"
  286. ! apache_is_installed && err_msg "Apache is not installed."
  287. if ! ask_yn "Do you really want to continue?"; then
  288. return
  289. fi
  290. a2enmod headers
  291. a2enmod proxy
  292. a2enmod proxy_http
  293. echo
  294. apache_install_site "${APACHE_MORTY_SITE}"
  295. info_msg "testing public url .."
  296. if ! service_is_available "${PUBLIC_URL_MORTY}"; then
  297. err_msg "Public service at ${PUBLIC_URL_MORTY} is not available!"
  298. fi
  299. }
  300. remove_apache_site() {
  301. rst_title "Remove Apache site $APACHE_MORTY_SITE"
  302. rst_para "\
  303. This removes apache site ${APACHE_MORTY_SITE}."
  304. ! apache_is_installed && err_msg "Apache is not installed."
  305. if ! ask_yn "Do you really want to continue?"; then
  306. return
  307. fi
  308. apache_remove_site "$APACHE_MORTY_SITE"
  309. }
  310. # ----------------------------------------------------------------------------
  311. main "$@"
  312. # ----------------------------------------------------------------------------