filtron.sh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  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 disable=SC2119,SC2001
  5. # shellcheck source=utils/lib.sh
  6. source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
  7. source_dot_config
  8. # ----------------------------------------------------------------------------
  9. # config
  10. # ----------------------------------------------------------------------------
  11. FILTRON_URL_PATH="${FILTRON_URL_PATH:-$(echo "${PUBLIC_URL}" \
  12. | sed -e 's,^.*://[^/]*\(/.*\),\1,g')}"
  13. [[ "${FILTRON_URL_PATH}" == "${PUBLIC_URL}" ]] && FILTRON_URL_PATH=/
  14. FILTRON_ETC="/etc/filtron"
  15. FILTRON_RULES="$FILTRON_ETC/rules.json"
  16. FILTRON_API="127.0.0.1:4005"
  17. FILTRON_LISTEN="127.0.0.1:4004"
  18. FILTRON_TARGET="127.0.0.1:8888"
  19. SERVICE_NAME="filtron"
  20. 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. GO_ENV="${SERVICE_HOME}/.go_env"
  26. GO_PKG_URL="https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz"
  27. GO_TAR=$(basename "$GO_PKG_URL")
  28. # Apache Settings
  29. APACHE_FILTRON_SITE="searx.conf"
  30. # shellcheck disable=SC2034
  31. CONFIG_FILES=(
  32. "${FILTRON_RULES}"
  33. "${SERVICE_SYSTEMD_UNIT}"
  34. )
  35. # ----------------------------------------------------------------------------
  36. usage() {
  37. # ----------------------------------------------------------------------------
  38. # shellcheck disable=SC1117
  39. cat <<EOF
  40. usage:
  41. $(basename "$0") shell
  42. $(basename "$0") install [all|user]
  43. $(basename "$0") update [filtron]
  44. $(basename "$0") remove [all]
  45. $(basename "$0") activate [service]
  46. $(basename "$0") deactivate [service]
  47. $(basename "$0") inspect [service]
  48. $(basename "$0") apache [install|remove]
  49. shell
  50. start interactive shell from user ${SERVICE_USER}
  51. install / remove
  52. all: complete setup of filtron service
  53. user: add/remove service user '$SERVICE_USER' at $SERVICE_HOME
  54. update filtron
  55. Update filtron installation of user ${SERVICE_USER}
  56. activate service
  57. activate and start service daemon (systemd unit)
  58. deactivate service
  59. stop and deactivate service daemon (systemd unit)
  60. inspect service
  61. show service status and log
  62. apache
  63. install: apache site with a reverse proxy (ProxyPass)
  64. remove: apache site ${APACHE_FILTRON_SITE}
  65. If needed change the environment variable PUBLIC_URL of your WEB service in the
  66. ${DOT_CONFIG#"$REPO_ROOT/"} file:
  67. PUBLIC_URL : ${PUBLIC_URL}
  68. PUBLIC_HOST : ${PUBLIC_HOST}
  69. EOF
  70. [ ! -z ${1+x} ] && echo -e "$1"
  71. }
  72. main() {
  73. rst_title "$SERVICE_NAME" part
  74. required_commands \
  75. dpkg apt-get install git wget curl \
  76. || exit
  77. local _usage="ERROR: unknown or missing $1 command $2"
  78. case $1 in
  79. --source-only) ;;
  80. -h|--help) usage; exit 0;;
  81. shell)
  82. sudo_or_exit
  83. interactive_shell
  84. ;;
  85. inspect)
  86. case $2 in
  87. service)
  88. sudo_or_exit
  89. inspect_service
  90. ;;
  91. *) usage "$_usage"; exit 42;;
  92. esac ;;
  93. install)
  94. sudo_or_exit
  95. case $2 in
  96. all) install_all ;;
  97. user) assert_user ;;
  98. *) usage "$_usage"; exit 42;;
  99. esac ;;
  100. update)
  101. sudo_or_exit
  102. case $2 in
  103. filtron) update_filtron ;;
  104. *) usage "$_usage"; exit 42;;
  105. esac ;;
  106. remove)
  107. sudo_or_exit
  108. case $2 in
  109. all) remove_all;;
  110. user) remove_user ;;
  111. *) usage "$_usage"; exit 42;;
  112. esac ;;
  113. activate)
  114. sudo_or_exit
  115. case $2 in
  116. service) activate_service ;;
  117. *) usage "$_usage"; exit 42;;
  118. esac ;;
  119. deactivate)
  120. sudo_or_exit
  121. case $2 in
  122. service) deactivate_service ;;
  123. *) usage "$_usage"; exit 42;;
  124. esac ;;
  125. apache)
  126. sudo_or_exit
  127. case $2 in
  128. install) install_apache_site ;;
  129. remove) remove_apache_site ;;
  130. *) usage "$_usage"; exit 42;;
  131. esac ;;
  132. *) usage "ERROR: unknown or missing command $1"; exit 42;;
  133. esac
  134. }
  135. install_all() {
  136. rst_title "Install $SERVICE_NAME (service)"
  137. assert_user
  138. wait_key
  139. install_go
  140. wait_key
  141. install_filtron
  142. wait_key
  143. install_service
  144. wait_key
  145. echo
  146. if ! service_is_available "http://${FILTRON_LISTEN}" ; then
  147. err_msg "Filtron does not listening on: http://${FILTRON_LISTEN}"
  148. fi
  149. if apache_is_installed; then
  150. info_msg "Apache is installed on this host."
  151. if ask_yn "Do you want to install a reverse proxy (ProxyPass)" Yn; then
  152. install_apache_site
  153. fi
  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. remove_service
  165. wait_key
  166. remove_user
  167. rm -r "$FILTRON_ETC" 2>&1 | prefix_stdout
  168. if service_is_available "${PUBLIC_URL}"; then
  169. MSG="** Don't forget to remove your public site! (${PUBLIC_URL}) **" wait_key 10
  170. fi
  171. }
  172. install_service() {
  173. rst_title "Install System-D Unit ${SERVICE_NAME}.service" section
  174. echo
  175. install_template "${SERVICE_SYSTEMD_UNIT}" root root 644
  176. wait_key
  177. activate_service
  178. }
  179. remove_service() {
  180. if ! ask_yn "Do you really want to deinstall $SERVICE_NAME?"; then
  181. return
  182. fi
  183. deactivate_service
  184. rm "${SERVICE_SYSTEMD_UNIT}" 2>&1 | prefix_stdout
  185. }
  186. activate_service() {
  187. rst_title "Activate $SERVICE_NAME (service)" section
  188. echo
  189. tee_stderr <<EOF | bash 2>&1
  190. systemctl enable $SERVICE_NAME.service
  191. systemctl restart $SERVICE_NAME.service
  192. EOF
  193. tee_stderr <<EOF | bash 2>&1
  194. systemctl status --no-pager $SERVICE_NAME.service
  195. EOF
  196. }
  197. deactivate_service() {
  198. rst_title "De-Activate $SERVICE_NAME (service)" section
  199. echo
  200. tee_stderr <<EOF | bash 2>&1 | prefix_stdout
  201. systemctl stop $SERVICE_NAME.service
  202. systemctl disable $SERVICE_NAME.service
  203. EOF
  204. }
  205. user_is_available() {
  206. sudo -i -u "$SERVICE_USER" echo \$HOME &>/dev/null
  207. }
  208. assert_user() {
  209. rst_title "user $SERVICE_USER" section
  210. echo
  211. tee_stderr 1 <<EOF | bash | prefix_stdout
  212. sudo -H adduser --shell /bin/bash --system --home $SERVICE_HOME \
  213. --disabled-password --group --gecos 'Filtron' $SERVICE_USER
  214. sudo -H usermod -a -G shadow $SERVICE_USER
  215. groups $SERVICE_USER
  216. EOF
  217. SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME)"
  218. export SERVICE_HOME
  219. echo "export SERVICE_HOME=$SERVICE_HOME"
  220. cat > "$GO_ENV" <<EOF
  221. export GOPATH=\$HOME/go-apps
  222. export PATH=\$PATH:\$HOME/local/go/bin:\$GOPATH/bin
  223. EOF
  224. echo "Environment $GO_ENV has been setup."
  225. tee_stderr <<EOF | sudo -i -u $SERVICE_USER
  226. grep -qFs -- 'source $GO_ENV' ~/.profile || echo 'source $GO_ENV' >> ~/.profile
  227. EOF
  228. }
  229. remove_user() {
  230. rst_title "Drop $SERVICE_USER HOME" section
  231. if ask_yn "Do you really want to drop $SERVICE_USER home folder?"; then
  232. userdel -r -f "$SERVICE_USER" 2>&1 | prefix_stdout
  233. else
  234. rst_para "Leave HOME folder $(du -sh "$SERVICE_HOME") unchanged."
  235. fi
  236. }
  237. interactive_shell(){
  238. echo "// exit with CTRL-D"
  239. sudo -H -u ${SERVICE_USER} -i
  240. }
  241. _service_prefix=" |$SERVICE_USER| "
  242. go_is_available() {
  243. sudo -i -u "$SERVICE_USER" which go &>/dev/null
  244. }
  245. install_go() {
  246. rst_title "Install Go in user's HOME" section
  247. rst_para "download and install go binary .."
  248. cache_download "${GO_PKG_URL}" "${GO_TAR}"
  249. tee_stderr 0.1 <<EOF | sudo -i -u "$SERVICE_USER" | prefix_stdout "$_service_prefix"
  250. echo \$PATH
  251. echo \$GOPATH
  252. mkdir -p \$HOME/local
  253. rm -rf \$HOME/local/go
  254. tar -C \$HOME/local -xzf ${CACHE}/${GO_TAR}
  255. EOF
  256. sudo -i -u "$SERVICE_USER" <<EOF | prefix_stdout
  257. ! which go >/dev/null && echo "ERROR - Go Installation not found in PATH!?!"
  258. which go >/dev/null && go version && echo "congratulations -- Go installation OK :)"
  259. EOF
  260. }
  261. filtron_is_installed() {
  262. [[ -f $SERVICE_HOME/go-apps/bin/filtron ]]
  263. }
  264. install_filtron() {
  265. rst_title "Install filtron in user's ~/go-apps" section
  266. echo
  267. tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_service_prefix"
  268. go get -v -u github.com/asciimoo/filtron
  269. EOF
  270. install_template --no-eval "$FILTRON_RULES" root root 644
  271. }
  272. update_filtron() {
  273. rst_title "Update filtron" section
  274. echo
  275. tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_service_prefix"
  276. go get -v -u github.com/asciimoo/filtron
  277. EOF
  278. }
  279. inspect_service() {
  280. rst_title "service status & log"
  281. cat <<EOF
  282. sourced ${DOT_CONFIG#"$REPO_ROOT/"} :
  283. PUBLIC_URL : ${PUBLIC_URL}
  284. PUBLIC_HOST : ${PUBLIC_HOST}
  285. FILTRON_URL_PATH : ${FILTRON_URL_PATH}
  286. FILTRON_API : ${FILTRON_API}
  287. FILTRON_LISTEN : ${FILTRON_LISTEN}
  288. FILTRON_TARGET : ${FILTRON_TARGET}
  289. EOF
  290. apache_is_installed && info_msg "Apache is installed."
  291. if user_is_available; then
  292. info_msg "service account $SERVICE_USER available."
  293. else
  294. err_msg "service account $SERVICE_USER not available!"
  295. fi
  296. if go_is_available; then
  297. info_msg "~$SERVICE_USER: go is installed"
  298. else
  299. err_msg "~$SERVICE_USER: go is not installed"
  300. fi
  301. if filtron_is_installed; then
  302. info_msg "~$SERVICE_USER: filtron app is installed"
  303. else
  304. err_msg "~$SERVICE_USER: filtron app is not installed!"
  305. fi
  306. if ! service_is_available "http://${FILTRON_API}"; then
  307. err_msg "API not available at: http://${FILTRON_API}"
  308. fi
  309. if ! service_is_available "http://${FILTRON_LISTEN}" ; then
  310. err_msg "Filtron does not listening on: http://${FILTRON_LISTEN}"
  311. fi
  312. if ! service_is_available ""http://${FILTRON_TARGET}"" ; then
  313. info_msg "Filtron's target is available at: http://${FILTRON_TARGET}"
  314. fi
  315. if ! service_is_available "${PUBLIC_URL}"; then
  316. err_msg "Public service at ${PUBLIC_URL} is not available!"
  317. fi
  318. wait_key
  319. echo
  320. systemctl --no-pager -l status filtron.service
  321. echo
  322. read -r -s -n1 -t 2 -p "// use CTRL-C to stop monitoring the log"
  323. echo
  324. while true; do
  325. trap break 2
  326. journalctl -f -u filtron
  327. done
  328. return 0
  329. }
  330. install_apache_site() {
  331. rst_title "Install Apache site $APACHE_FILTRON_SITE"
  332. rst_para "\
  333. This installs a reverse proxy (ProxyPass) into apache site (${APACHE_FILTRON_SITE})"
  334. ! apache_is_installed && err_msg "Apache is not installed."
  335. if ! ask_yn "Do you really want to continue?"; then
  336. return
  337. fi
  338. a2enmod headers
  339. a2enmod proxy
  340. a2enmod proxy_http
  341. echo
  342. apache_install_site --variant=filtron "${APACHE_FILTRON_SITE}"
  343. info_msg "testing public url .."
  344. if ! service_is_available "${PUBLIC_URL}"; then
  345. err_msg "Public service at ${PUBLIC_URL} is not available!"
  346. fi
  347. }
  348. remove_apache_site() {
  349. rst_title "Remove Apache site $APACHE_FILTRON_SITE"
  350. rst_para "\
  351. This removes apache site ${APACHE_FILTRON_SITE}."
  352. ! apache_is_installed && err_msg "Apache is not installed."
  353. if ! ask_yn "Do you really want to continue?"; then
  354. return
  355. fi
  356. apache_remove_site "$APACHE_FILTRON_SITE"
  357. }
  358. # ----------------------------------------------------------------------------
  359. main "$@"
  360. # ----------------------------------------------------------------------------