searx.sh 29 KB

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