searx.sh 28 KB

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