searx.sh 26 KB

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