searx.sh 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883
  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=SC2001
  5. # shellcheck source=utils/lib.sh
  6. source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
  7. # shellcheck source=utils/brand.env
  8. source "${REPO_ROOT}/utils/brand.env"
  9. source_dot_config
  10. source "${REPO_ROOT}/utils/lxc-searx.env"
  11. in_container && lxc_set_suite_env
  12. # ----------------------------------------------------------------------------
  13. # config
  14. # ----------------------------------------------------------------------------
  15. PUBLIC_URL="${PUBLIC_URL:-http://$(uname -n)/searx}"
  16. SEARX_INTERNAL_HTTP="${SEARX_INTERNAL_HTTP:-127.0.0.1:8888}"
  17. SEARX_URL_PATH="${SEARX_URL_PATH:-$(echo "${PUBLIC_URL}" \
  18. | sed -e 's,^.*://[^/]*\(/.*\),\1,g')}"
  19. [[ "${SEARX_URL_PATH}" == "${PUBLIC_URL}" ]] && SEARX_URL_PATH=/
  20. SEARX_INSTANCE_NAME="${SEARX_INSTANCE_NAME:-searx@$(echo "$PUBLIC_URL" \
  21. | sed -e 's,^.*://\([^\:/]*\).*,\1,g') }"
  22. SERVICE_NAME="searx"
  23. SERVICE_USER="${SERVICE_USER:-${SERVICE_NAME}}"
  24. SERVICE_HOME_BASE="${SERVICE_HOME_BASE:-/usr/local}"
  25. SERVICE_HOME="${SERVICE_HOME_BASE}/${SERVICE_USER}"
  26. # shellcheck disable=SC2034
  27. SERVICE_GROUP="${SERVICE_USER}"
  28. GIT_BRANCH="${GIT_BRANCH:-master}"
  29. SEARX_PYENV="${SERVICE_HOME}/searx-pyenv"
  30. SEARX_SRC="${SERVICE_HOME}/searx-src"
  31. SEARX_SETTINGS_PATH="/etc/searx/settings.yml"
  32. SEARX_UWSGI_APP="searx.ini"
  33. # shellcheck disable=SC2034
  34. SEARX_UWSGI_SOCKET="/run/uwsgi/app/searx/socket"
  35. # apt packages
  36. SEARX_PACKAGES_debian="\
  37. virtualenv python3-dev python3-babel python3-venv
  38. uwsgi uwsgi-plugin-python3
  39. git build-essential libxslt-dev zlib1g-dev libffi-dev libssl-dev
  40. shellcheck"
  41. BUILD_PACKAGES_debian="\
  42. firefox graphviz imagemagick texlive-xetex librsvg2-bin
  43. texlive-latex-recommended texlive-extra-utils ttf-dejavu
  44. latexmk"
  45. # pacman packages
  46. SEARX_PACKAGES_arch="\
  47. python-virtualenv python python-pip python-lxml python-babel
  48. uwsgi uwsgi-plugin-python
  49. git base-devel libxml2
  50. shellcheck"
  51. BUILD_PACKAGES_arch="\
  52. firefox graphviz imagemagick texlive-bin extra/librsvg
  53. texlive-core texlive-latexextra ttf-dejavu"
  54. # dnf packages
  55. SEARX_PACKAGES_fedora="\
  56. virtualenv python python-pip python-lxml python-babel
  57. uwsgi uwsgi-plugin-python3
  58. git @development-tools libxml2
  59. ShellCheck"
  60. BUILD_PACKAGES_fedora="\
  61. firefox graphviz graphviz-gd ImageMagick librsvg2-tools
  62. texlive-xetex-bin texlive-collection-fontsrecommended
  63. texlive-collection-latex dejavu-sans-fonts dejavu-serif-fonts
  64. dejavu-sans-mono-fonts"
  65. case $DIST_ID-$DIST_VERS in
  66. ubuntu-16.04|ubuntu-18.04)
  67. SEARX_PACKAGES="${SEARX_PACKAGES_debian}"
  68. BUILD_PACKAGES="${BUILD_PACKAGES_debian}"
  69. APACHE_PACKAGES="$APACHE_PACKAGES libapache2-mod-proxy-uwsgi"
  70. ;;
  71. ubuntu-20.04)
  72. # https://askubuntu.com/a/1224710
  73. SEARX_PACKAGES="${SEARX_PACKAGES_debian} python-is-python3"
  74. BUILD_PACKAGES="${BUILD_PACKAGES_debian}"
  75. ;;
  76. ubuntu-*|debian-*)
  77. SEARX_PACKAGES="${SEARX_PACKAGES_debian}"
  78. BUILD_PACKAGES="${BUILD_PACKAGES_debian}"
  79. ;;
  80. arch-*)
  81. SEARX_PACKAGES="${SEARX_PACKAGES_arch}"
  82. BUILD_PACKAGES="${BUILD_PACKAGES_arch}"
  83. ;;
  84. fedora-*)
  85. SEARX_PACKAGES="${SEARX_PACKAGES_fedora}"
  86. BUILD_PACKAGES="${BUILD_PACKAGES_fedora}"
  87. ;;
  88. esac
  89. # Apache Settings
  90. APACHE_SEARX_SITE="searx.conf"
  91. # shellcheck disable=SC2034
  92. CONFIG_FILES=(
  93. "${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP}"
  94. )
  95. # shellcheck disable=SC2034
  96. CONFIG_BACKUP_ENCRYPTED=(
  97. "${SEARX_SETTINGS_PATH}"
  98. )
  99. # ----------------------------------------------------------------------------
  100. usage() {
  101. # ----------------------------------------------------------------------------
  102. # shellcheck disable=SC1117
  103. cat <<EOF
  104. usage::
  105. $(basename "$0") shell
  106. $(basename "$0") install [all|user|searx-src|pyenv|uwsgi|packages|buildhost]
  107. $(basename "$0") update [searx]
  108. $(basename "$0") remove [all|user|pyenv|searx-src]
  109. $(basename "$0") activate [service]
  110. $(basename "$0") deactivate [service]
  111. $(basename "$0") inspect [service]
  112. $(basename "$0") option [debug-[on|off]|image-proxy-[on|off]|result-proxy <url> <key>]
  113. $(basename "$0") apache [install|remove]
  114. shell
  115. start interactive shell from user ${SERVICE_USER}
  116. install / remove
  117. :all: complete (de-) installation of searx service
  118. :user: add/remove service user '$SERVICE_USER' ($SERVICE_HOME)
  119. :searx-src: clone $GIT_URL
  120. :pyenv: create/remove virtualenv (python) in $SEARX_PYENV
  121. :uwsgi: install searx uWSGI application
  122. :settings: reinstall settings from ${REPO_ROOT}/searx/settings.yml
  123. :packages: install needed packages from OS package manager
  124. :buildhost: install packages from OS package manager needed by buildhosts
  125. update searx
  126. Update searx installation ($SERVICE_HOME)
  127. activate service
  128. activate and start service daemon (systemd unit)
  129. deactivate service
  130. stop and deactivate service daemon (systemd unit)
  131. inspect service
  132. run some small tests and inspect service's status and log
  133. option
  134. set one of the available options
  135. apache
  136. :install: apache site with the searx uwsgi app
  137. :remove: apache site ${APACHE_FILTRON_SITE}
  138. searx settings: ${SEARX_SETTINGS_PATH}
  139. If needed, set PUBLIC_URL of your WEB service in the '${DOT_CONFIG#"$REPO_ROOT/"}' file::
  140. PUBLIC_URL : ${PUBLIC_URL}
  141. SEARX_INSTANCE_NAME : ${SEARX_INSTANCE_NAME}
  142. SERVICE_USER : ${SERVICE_USER}
  143. SEARX_INTERNAL_HTTP : http://${SEARX_INTERNAL_HTTP}
  144. EOF
  145. if in_container; then
  146. # searx is listening on 127.0.0.1 and not available from outside container
  147. # in containers the service is listening on 0.0.0.0 (see lxc-searx.env)
  148. echo -e "${_BBlack}HINT:${_creset} searx only listen on loopback device" \
  149. "${_BBlack}inside${_creset} the container."
  150. for ip in $(global_IPs) ; do
  151. if [[ $ip =~ .*:.* ]]; then
  152. echo " container (IPv6): [${ip#*|}]"
  153. else
  154. # IPv4:
  155. echo " container (IPv4): ${ip#*|}"
  156. fi
  157. done
  158. fi
  159. [[ -n ${1} ]] && err_msg "$1"
  160. }
  161. main() {
  162. required_commands \
  163. sudo systemctl install git wget curl \
  164. || exit
  165. local _usage="unknown or missing $1 command $2"
  166. case $1 in
  167. --getenv) var="$2"; echo "${!var}"; exit 0;;
  168. -h|--help) usage; exit 0;;
  169. shell)
  170. sudo_or_exit
  171. interactive_shell "${SERVICE_USER}"
  172. ;;
  173. inspect)
  174. case $2 in
  175. service)
  176. sudo_or_exit
  177. inspect_service
  178. ;;
  179. *) usage "$_usage"; exit 42;;
  180. esac ;;
  181. install)
  182. rst_title "$SEARX_INSTANCE_NAME" part
  183. sudo_or_exit
  184. case $2 in
  185. all) install_all ;;
  186. user) assert_user ;;
  187. pyenv) create_pyenv ;;
  188. searx-src) clone_searx ;;
  189. settings) install_settings ;;
  190. uwsgi)
  191. install_searx_uwsgi
  192. if ! service_is_available "http://${SEARX_INTERNAL_HTTP}"; then
  193. err_msg "URL http://${SEARX_INTERNAL_HTTP} not available, check searx & uwsgi setup!"
  194. fi
  195. ;;
  196. packages)
  197. pkg_install "$SEARX_PACKAGES"
  198. ;;
  199. buildhost)
  200. pkg_install "$SEARX_PACKAGES"
  201. pkg_install "$BUILD_PACKAGES"
  202. ;;
  203. *) usage "$_usage"; exit 42;;
  204. esac ;;
  205. update)
  206. sudo_or_exit
  207. case $2 in
  208. searx) update_searx;;
  209. *) usage "$_usage"; exit 42;;
  210. esac ;;
  211. remove)
  212. sudo_or_exit
  213. case $2 in
  214. all) remove_all;;
  215. user) drop_service_account "${SERVICE_USER}";;
  216. pyenv) remove_pyenv ;;
  217. searx-src) remove_searx ;;
  218. *) usage "$_usage"; exit 42;;
  219. esac ;;
  220. activate)
  221. sudo_or_exit
  222. case $2 in
  223. service)
  224. activate_service ;;
  225. *) usage "$_usage"; exit 42;;
  226. esac ;;
  227. deactivate)
  228. sudo_or_exit
  229. case $2 in
  230. service) deactivate_service ;;
  231. *) usage "$_usage"; exit 42;;
  232. esac ;;
  233. option)
  234. sudo_or_exit
  235. case $2 in
  236. debug-on) echo; enable_debug ;;
  237. debug-off) echo; disable_debug ;;
  238. result-proxy) set_result_proxy "$3" "$4" ;;
  239. image-proxy-on) enable_image_proxy ;;
  240. image-proxy-off) disable_image_proxy ;;
  241. *) usage "$_usage"; exit 42;;
  242. esac ;;
  243. apache)
  244. sudo_or_exit
  245. case $2 in
  246. install) install_apache_site ;;
  247. remove) remove_apache_site ;;
  248. *) usage "$_usage"; exit 42;;
  249. esac ;;
  250. doc) rst-doc;;
  251. *) usage "unknown or missing command $1"; exit 42;;
  252. esac
  253. }
  254. _service_prefix=" ${_Yellow}|$SERVICE_USER|${_creset} "
  255. install_all() {
  256. rst_title "Install $SEARX_INSTANCE_NAME (service)"
  257. pkg_install "$SEARX_PACKAGES"
  258. wait_key
  259. assert_user
  260. wait_key
  261. clone_searx
  262. wait_key
  263. create_pyenv
  264. wait_key
  265. install_settings
  266. wait_key
  267. test_local_searx
  268. wait_key
  269. install_searx_uwsgi
  270. if ! service_is_available "http://${SEARX_INTERNAL_HTTP}"; then
  271. err_msg "URL http://${SEARX_INTERNAL_HTTP} not available, check searx & uwsgi setup!"
  272. fi
  273. if ask_yn "Do you want to inspect the installation?" Ny; then
  274. inspect_service
  275. fi
  276. }
  277. update_searx() {
  278. rst_title "Update searx instance"
  279. echo
  280. tee_stderr 0.3 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
  281. cd ${SEARX_SRC}
  282. git checkout -B "$GIT_BRANCH"
  283. git pull
  284. pip install -U pip
  285. pip install -U setuptools
  286. pip install -U wheel
  287. pip install -U -e .
  288. EOF
  289. install_settings
  290. uWSGI_restart "$SEARX_UWSGI_APP"
  291. }
  292. remove_all() {
  293. rst_title "De-Install $SEARX_INSTANCE_NAME (service)"
  294. rst_para "\
  295. It goes without saying that this script can only be used to remove
  296. installations that were installed with this script."
  297. if ! ask_yn "Do you really want to deinstall $SEARX_INSTANCE_NAME?"; then
  298. return
  299. fi
  300. remove_searx_uwsgi
  301. drop_service_account "${SERVICE_USER}"
  302. remove_settings
  303. wait_key
  304. if service_is_available "${PUBLIC_URL}"; then
  305. MSG="** Don't forgett to remove your public site! (${PUBLIC_URL}) **" wait_key 10
  306. fi
  307. }
  308. assert_user() {
  309. rst_title "user $SERVICE_USER" section
  310. echo
  311. tee_stderr 1 <<EOF | bash | prefix_stdout
  312. useradd --shell /bin/bash --system \
  313. --home-dir "$SERVICE_HOME" \
  314. --comment 'Privacy-respecting metasearch engine' $SERVICE_USER
  315. mkdir "$SERVICE_HOME"
  316. chown -R "$SERVICE_GROUP:$SERVICE_GROUP" "$SERVICE_HOME"
  317. groups $SERVICE_USER
  318. EOF
  319. #SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME)"
  320. #export SERVICE_HOME
  321. #echo "export SERVICE_HOME=$SERVICE_HOME"
  322. }
  323. clone_is_available() {
  324. [[ -f "$SEARX_SRC/.git/config" ]]
  325. }
  326. # shellcheck disable=SC2164
  327. clone_searx() {
  328. rst_title "Clone searx sources" section
  329. echo
  330. if ! sudo -i -u "$SERVICE_USER" ls -d "$REPO_ROOT" > /dev/null; then
  331. die 42 "user '$SERVICE_USER' missed read permission: $REPO_ROOT"
  332. fi
  333. SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME 2>/dev/null)"
  334. if [[ ! "${SERVICE_HOME}" ]]; then
  335. err_msg "to clone searx sources, user $SERVICE_USER hast to be created first"
  336. return 42
  337. fi
  338. export SERVICE_HOME
  339. git_clone "$REPO_ROOT" "$SEARX_SRC" \
  340. "$GIT_BRANCH" "$SERVICE_USER"
  341. pushd "${SEARX_SRC}" > /dev/null
  342. tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
  343. cd "${SEARX_SRC}"
  344. git remote set-url origin ${GIT_URL}
  345. git config user.email "$ADMIN_EMAIL"
  346. git config user.name "$ADMIN_NAME"
  347. git config --list
  348. EOF
  349. popd > /dev/null
  350. }
  351. install_settings() {
  352. rst_title "${SEARX_SETTINGS_PATH}" section
  353. if ! clone_is_available; then
  354. err_msg "you have to install searx first"
  355. exit 42
  356. fi
  357. mkdir -p "$(dirname ${SEARX_SETTINGS_PATH})"
  358. if [[ ! -f ${SEARX_SETTINGS_PATH} ]]; then
  359. info_msg "install settings ${REPO_ROOT}/searx/settings.yml"
  360. info_msg " --> ${SEARX_SETTINGS_PATH}"
  361. cp "${REPO_ROOT}/searx/settings.yml" "${SEARX_SETTINGS_PATH}"
  362. configure_searx
  363. return
  364. fi
  365. rst_para "Diff between origin's setting file (+) and current (-):"
  366. echo
  367. $DIFF_CMD "${SEARX_SETTINGS_PATH}" "${SEARX_SRC}/searx/settings.yml"
  368. local action
  369. choose_one action "What should happen to the settings file? " \
  370. "keep configuration unchanged" \
  371. "use origin settings" \
  372. "start interactiv shell"
  373. case $action in
  374. "keep configuration unchanged")
  375. info_msg "leave settings file unchanged"
  376. ;;
  377. "use origin settings")
  378. backup_file "${SEARX_SETTINGS_PATH}"
  379. info_msg "install origin settings"
  380. cp "${SEARX_SRC}/searx/settings.yml" "${SEARX_SETTINGS_PATH}"
  381. ;;
  382. "start interactiv shell")
  383. backup_file "${SEARX_SETTINGS_PATH}"
  384. echo -e "// exit with [${_BCyan}CTRL-D${_creset}]"
  385. sudo -H -i
  386. rst_para 'Diff between new setting file (-) and current (+):'
  387. echo
  388. $DIFF_CMD "${SEARX_SRC}/searx/settings.yml" "${SEARX_SETTINGS_PATH}"
  389. wait_key
  390. ;;
  391. esac
  392. }
  393. remove_settings() {
  394. rst_title "remove searx settings" section
  395. echo
  396. info_msg "delete ${SEARX_SETTINGS_PATH}"
  397. rm -f "${SEARX_SETTINGS_PATH}"
  398. }
  399. remove_searx() {
  400. rst_title "Drop searx sources" section
  401. if ask_yn "Do you really want to drop searx sources ($SEARX_SRC)?"; then
  402. rm -rf "$SEARX_SRC"
  403. else
  404. rst_para "Leave searx sources unchanged."
  405. fi
  406. }
  407. pyenv_is_available() {
  408. [[ -f "${SEARX_PYENV}/bin/activate" ]]
  409. }
  410. create_pyenv() {
  411. rst_title "Create virtualenv (python)" section
  412. echo
  413. if [[ ! -f "${SEARX_SRC}/manage.sh" ]]; then
  414. err_msg "to create pyenv for searx, searx has to be cloned first"
  415. return 42
  416. fi
  417. info_msg "create pyenv in ${SEARX_PYENV}"
  418. tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
  419. rm -rf "${SEARX_PYENV}"
  420. python3 -m venv "${SEARX_PYENV}"
  421. grep -qFs -- 'source ${SEARX_PYENV}/bin/activate' ~/.profile \
  422. || echo 'source ${SEARX_PYENV}/bin/activate' >> ~/.profile
  423. EOF
  424. info_msg "inspect python's virtual environment"
  425. tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
  426. command -v python && python --version
  427. EOF
  428. wait_key
  429. info_msg "install needed python packages"
  430. tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
  431. pip install -U pip
  432. pip install -U setuptools
  433. pip install -U wheel
  434. pip install -U -e .
  435. cd ${SEARX_SRC}
  436. pip install -e .
  437. EOF
  438. }
  439. remove_pyenv() {
  440. rst_title "Remove virtualenv (python)" section
  441. if ! ask_yn "Do you really want to drop ${SEARX_PYENV} ?"; then
  442. return
  443. fi
  444. info_msg "remove pyenv activation from ~/.profile"
  445. tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
  446. grep -v 'source ${SEARX_PYENV}/bin/activate' ~/.profile > ~/.profile.##
  447. mv ~/.profile.## ~/.profile
  448. EOF
  449. rm -rf "${SEARX_PYENV}"
  450. }
  451. configure_searx() {
  452. rst_title "Configure searx" section
  453. rst_para "Setup searx config located at $SEARX_SETTINGS_PATH"
  454. echo
  455. tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
  456. cd ${SEARX_SRC}
  457. sed -i -e "s/ultrasecretkey/$(openssl rand -hex 16)/g" "$SEARX_SETTINGS_PATH"
  458. sed -i -e "s/{instance_name}/${SEARX_INSTANCE_NAME}/g" "$SEARX_SETTINGS_PATH"
  459. EOF
  460. }
  461. test_local_searx() {
  462. rst_title "Testing searx instance localy" section
  463. echo
  464. if service_is_available "http://${SEARX_INTERNAL_HTTP}" &>/dev/null; then
  465. err_msg "URL/port http://${SEARX_INTERNAL_HTTP} is already in use, you"
  466. err_msg "should stop that service before starting local tests!"
  467. if ! ask_yn "Continue with local tests?"; then
  468. return
  469. fi
  470. fi
  471. sed -i -e "s/debug : False/debug : True/g" "$SEARX_SETTINGS_PATH"
  472. tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
  473. export SEARX_SETTINGS_PATH="${SEARX_SETTINGS_PATH}"
  474. cd ${SEARX_SRC}
  475. timeout 10 python searx/webapp.py &
  476. sleep 3
  477. curl --location --verbose --head --insecure $SEARX_INTERNAL_HTTP
  478. EOF
  479. sed -i -e "s/debug : True/debug : False/g" "$SEARX_SETTINGS_PATH"
  480. }
  481. install_searx_uwsgi() {
  482. rst_title "Install searx's uWSGI app (searx.ini)" section
  483. echo
  484. install_uwsgi
  485. uWSGI_install_app "$SEARX_UWSGI_APP"
  486. }
  487. remove_searx_uwsgi() {
  488. rst_title "Remove searx's uWSGI app (searx.ini)" section
  489. echo
  490. uWSGI_remove_app "$SEARX_UWSGI_APP"
  491. }
  492. activate_service() {
  493. rst_title "Activate $SEARX_INSTANCE_NAME (service)" section
  494. echo
  495. uWSGI_enable_app "$SEARX_UWSGI_APP"
  496. uWSGI_restart "$SEARX_UWSGI_APP"
  497. }
  498. deactivate_service() {
  499. rst_title "De-Activate $SEARX_INSTANCE_NAME (service)" section
  500. echo
  501. uWSGI_disable_app "$SEARX_UWSGI_APP"
  502. uWSGI_restart "$SEARX_UWSGI_APP"
  503. }
  504. enable_image_proxy() {
  505. info_msg "try to enable image_proxy ..."
  506. tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
  507. cd ${SEARX_SRC}
  508. sed -i -e "s/image_proxy : False/image_proxy : True/g" "$SEARX_SETTINGS_PATH"
  509. EOF
  510. uWSGI_restart "$SEARX_UWSGI_APP"
  511. }
  512. disable_image_proxy() {
  513. info_msg "try to enable image_proxy ..."
  514. tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
  515. cd ${SEARX_SRC}
  516. sed -i -e "s/image_proxy : True/image_proxy : False/g" "$SEARX_SETTINGS_PATH"
  517. EOF
  518. uWSGI_restart "$SEARX_UWSGI_APP"
  519. }
  520. enable_debug() {
  521. warn_msg "Do not enable debug in production enviroments!!"
  522. info_msg "try to enable debug mode ..."
  523. tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
  524. cd ${SEARX_SRC}
  525. sed -i -e "s/debug : False/debug : True/g" "$SEARX_SETTINGS_PATH"
  526. EOF
  527. uWSGI_restart "$SEARX_UWSGI_APP"
  528. }
  529. disable_debug() {
  530. info_msg "try to disable debug mode ..."
  531. tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
  532. cd ${SEARX_SRC}
  533. sed -i -e "s/debug : True/debug : False/g" "$SEARX_SETTINGS_PATH"
  534. EOF
  535. uWSGI_restart "$SEARX_UWSGI_APP"
  536. }
  537. set_result_proxy() {
  538. # usage: set_result_proxy <URL> [<key>]
  539. info_msg "try to set result proxy: '$1' ($2)"
  540. cp "${SEARX_SETTINGS_PATH}" "${SEARX_SETTINGS_PATH}.bak"
  541. _set_result_proxy "$1" "$2" > "${SEARX_SETTINGS_PATH}"
  542. }
  543. _set_result_proxy() {
  544. local line
  545. local stage=0
  546. local url=" url: $1"
  547. local key=" key: !!binary \"$2\""
  548. if [[ -z $2 ]]; then
  549. key=
  550. fi
  551. while IFS= read -r line
  552. do
  553. if [[ $stage = 0 ]] || [[ $stage = 2 ]] ; then
  554. if [[ $line =~ ^[[:space:]]*#*[[:space:]]*result_proxy[[:space:]]*:[[:space:]]*$ ]]; then
  555. if [[ $stage = 0 ]]; then
  556. stage=1
  557. echo "result_proxy:"
  558. continue
  559. elif [[ $stage = 2 ]]; then
  560. continue
  561. fi
  562. fi
  563. fi
  564. if [[ $stage = 1 ]] || [[ $stage = 2 ]] ; then
  565. if [[ $line =~ ^[[:space:]]*#*[[:space:]]*url[[:space:]]*:[[:space:]] ]]; then
  566. [[ $stage = 1 ]] && echo "$url"
  567. continue
  568. elif [[ $line =~ ^[[:space:]]*#*[[:space:]]*key[[:space:]]*:[[:space:]] ]]; then
  569. [[ $stage = 1 ]] && [[ -n $key ]] && echo "$key"
  570. continue
  571. elif [[ $line =~ ^[[:space:]]*$ ]]; then
  572. stage=2
  573. fi
  574. fi
  575. echo "$line"
  576. done < "${SEARX_SETTINGS_PATH}.bak"
  577. }
  578. function has_substring() {
  579. [[ "$1" != "${2/$1/}" ]]
  580. }
  581. inspect_service() {
  582. rst_title "service status & log"
  583. cat <<EOF
  584. sourced ${DOT_CONFIG#"$REPO_ROOT/"} :
  585. PUBLIC_URL : ${PUBLIC_URL}
  586. SEARX_URL_PATH : ${SEARX_URL_PATH}
  587. SEARX_INSTANCE_NAME : ${SEARX_INSTANCE_NAME}
  588. SEARX_INTERNAL_HTTP : ${SEARX_INTERNAL_HTTP}
  589. EOF
  590. if service_account_is_available "$SERVICE_USER"; then
  591. info_msg "Service account $SERVICE_USER exists."
  592. else
  593. err_msg "Service account $SERVICE_USER does not exists!"
  594. fi
  595. if pyenv_is_available; then
  596. info_msg "~$SERVICE_USER: python environment is available."
  597. else
  598. err_msg "~$SERVICE_USER: python environment is not available!"
  599. fi
  600. if clone_is_available; then
  601. info_msg "~$SERVICE_USER: Searx software is installed."
  602. else
  603. err_msg "~$SERVICE_USER: Missing searx software!"
  604. fi
  605. if uWSGI_app_enabled "$SEARX_UWSGI_APP"; then
  606. info_msg "uWSGI app $SEARX_UWSGI_APP is enabled."
  607. else
  608. err_msg "uWSGI app $SEARX_UWSGI_APP not enabled!"
  609. fi
  610. uWSGI_app_available "$SEARX_UWSGI_APP" \
  611. || err_msg "uWSGI app $SEARX_UWSGI_APP not available!"
  612. if in_container; then
  613. lxc_suite_info
  614. else
  615. info_msg "public URL --> ${PUBLIC_URL}"
  616. info_msg "internal URL --> http://${SEARX_INTERNAL_HTTP}"
  617. fi
  618. if ! service_is_available "http://${SEARX_INTERNAL_HTTP}"; then
  619. err_msg "uWSGI app (service) at http://${SEARX_INTERNAL_HTTP} is not available!"
  620. MSG="${_Green}[${_BCyan}CTRL-C${_Green}] to stop or [${_BCyan}KEY${_Green}] to continue"\
  621. wait_key
  622. fi
  623. if ! service_is_available "${PUBLIC_URL}"; then
  624. warn_msg "Public service at ${PUBLIC_URL} is not available!"
  625. if ! in_container; then
  626. warn_msg "Check if public name is correct and routed or use the public IP from above."
  627. fi
  628. fi
  629. local _debug_on
  630. if ask_yn "Enable searx debug mode?"; then
  631. enable_debug
  632. _debug_on=1
  633. fi
  634. echo
  635. case $DIST_ID-$DIST_VERS in
  636. ubuntu-*|debian-*)
  637. systemctl --no-pager -l status "${SERVICE_NAME}"
  638. ;;
  639. arch-*)
  640. systemctl --no-pager -l status "uwsgi@${SERVICE_NAME%.*}"
  641. ;;
  642. fedora-*)
  643. systemctl --no-pager -l status uwsgi
  644. ;;
  645. esac
  646. # shellcheck disable=SC2059
  647. printf "// use ${_BCyan}CTRL-C${_creset} to stop monitoring the log"
  648. read -r -s -n1 -t 5
  649. echo
  650. while true; do
  651. trap break 2
  652. case $DIST_ID-$DIST_VERS in
  653. ubuntu-*|debian-*) tail -f /var/log/uwsgi/app/searx.log ;;
  654. arch-*) journalctl -f -u "uwsgi@${SERVICE_NAME%.*}" ;;
  655. fedora-*) journalctl -f -u uwsgi ;;
  656. esac
  657. done
  658. if [[ $_debug_on == 1 ]]; then
  659. disable_debug
  660. fi
  661. return 0
  662. }
  663. install_apache_site() {
  664. rst_title "Install Apache site $APACHE_SEARX_SITE"
  665. rst_para "\
  666. This installs the searx uwsgi app as apache site. If your server is public to
  667. the internet, you should instead use a reverse proxy (filtron) to block
  668. excessively bot queries."
  669. ! apache_is_installed && err_msg "Apache is not installed."
  670. if ! ask_yn "Do you really want to continue?" Yn; then
  671. return
  672. else
  673. install_apache
  674. fi
  675. apache_install_site --variant=uwsgi "${APACHE_SEARX_SITE}"
  676. rst_title "Install searx's uWSGI app (searx.ini)" section
  677. echo
  678. uWSGI_install_app --variant=socket "$SEARX_UWSGI_APP"
  679. if ! service_is_available "${PUBLIC_URL}"; then
  680. err_msg "Public service at ${PUBLIC_URL} is not available!"
  681. fi
  682. }
  683. remove_apache_site() {
  684. rst_title "Remove Apache site ${APACHE_SEARX_SITE}"
  685. rst_para "\
  686. This removes apache site ${APACHE_SEARX_SITE}."
  687. ! apache_is_installed && err_msg "Apache is not installed."
  688. if ! ask_yn "Do you really want to continue?" Yn; then
  689. return
  690. fi
  691. apache_remove_site "${APACHE_SEARX_SITE}"
  692. rst_title "Remove searx's uWSGI app (searx.ini)" section
  693. echo
  694. uWSGI_remove_app "$SEARX_UWSGI_APP"
  695. }
  696. rst-doc() {
  697. local debian="${SEARX_PACKAGES_debian}"
  698. local arch="${SEARX_PACKAGES_arch}"
  699. local fedora="${SEARX_PACKAGES_fedora}"
  700. local debian_build="${BUILD_PACKAGES_debian}"
  701. local arch_build="${BUILD_PACKAGES_arch}"
  702. local fedora_build="${BUILD_PACKAGES_fedora}"
  703. debian="$(echo "${debian}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
  704. arch="$(echo "${arch}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
  705. fedora="$(echo "${fedora}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
  706. debian_build="$(echo "${debian_build}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
  707. arch_build="$(echo "${arch_build}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
  708. fedora_build="$(echo "${fedora_build}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
  709. eval "echo \"$(< "${REPO_ROOT}/docs/build-templates/searx.rst")\""
  710. # I use ubuntu-20.04 here to demonstrate that versions are also suported,
  711. # normaly debian-* and ubuntu-* are most the same.
  712. for DIST_NAME in ubuntu-20.04 arch fedora; do
  713. (
  714. DIST_ID=${DIST_NAME%-*}
  715. DIST_VERS=${DIST_NAME#*-}
  716. [[ $DIST_VERS =~ $DIST_ID ]] && DIST_VERS=
  717. uWSGI_distro_setup
  718. echo -e "\n.. START searx uwsgi-description $DIST_NAME"
  719. case $DIST_ID-$DIST_VERS in
  720. ubuntu-*|debian-*) cat <<EOF
  721. .. code:: bash
  722. # init.d --> /usr/share/doc/uwsgi/README.Debian.gz
  723. # For uWSGI debian uses the LSB init process, this might be changed
  724. # one day, see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=833067
  725. create ${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP}
  726. enable: sudo -H ln -s ${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP} ${uWSGI_APPS_ENABLED}/
  727. start: sudo -H service uwsgi start ${SEARX_UWSGI_APP%.*}
  728. restart: sudo -H service uwsgi restart ${SEARX_UWSGI_APP%.*}
  729. stop: sudo -H service uwsgi stop ${SEARX_UWSGI_APP%.*}
  730. disable: sudo -H rm ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
  731. EOF
  732. ;;
  733. arch-*) cat <<EOF
  734. .. code:: bash
  735. # systemd --> /usr/lib/systemd/system/uwsgi@.service
  736. # For uWSGI archlinux uses systemd template units, see
  737. # - http://0pointer.de/blog/projects/instances.html
  738. # - https://uwsgi-docs.readthedocs.io/en/latest/Systemd.html#one-service-per-app-in-systemd
  739. create: ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
  740. enable: sudo -H systemctl enable uwsgi@${SEARX_UWSGI_APP%.*}
  741. start: sudo -H systemctl start uwsgi@${SEARX_UWSGI_APP%.*}
  742. restart: sudo -H systemctl restart uwsgi@${SEARX_UWSGI_APP%.*}
  743. stop: sudo -H systemctl stop uwsgi@${SEARX_UWSGI_APP%.*}
  744. disable: sudo -H systemctl disable uwsgi@${SEARX_UWSGI_APP%.*}
  745. EOF
  746. ;;
  747. fedora-*) cat <<EOF
  748. .. code:: bash
  749. # systemd --> /usr/lib/systemd/system/uwsgi.service
  750. # The unit file starts uWSGI in emperor mode (/etc/uwsgi.ini), see
  751. # - https://uwsgi-docs.readthedocs.io/en/latest/Emperor.html
  752. create: ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
  753. restart: sudo -H touch ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
  754. disable: sudo -H rm ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
  755. EOF
  756. ;;
  757. esac
  758. echo -e ".. END searx uwsgi-description $DIST_NAME"
  759. echo -e "\n.. START searx uwsgi-appini $DIST_NAME"
  760. echo ".. code:: bash"
  761. echo
  762. eval "echo \"$(< "${TEMPLATES}/${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP}")\"" | prefix_stdout " "
  763. echo -e "\n.. END searx uwsgi-appini $DIST_NAME"
  764. )
  765. done
  766. }
  767. # ----------------------------------------------------------------------------
  768. main "$@"
  769. # ----------------------------------------------------------------------------