filtron.sh 11 KB

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