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