searx.sh 28 KB

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