searx.sh 27 KB

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