searx.sh 27 KB

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