searx.sh 29 KB

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