searxng/utils/searx.sh

513 lines
14 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# -*- coding: utf-8; mode: sh indent-tabs-mode: nil -*-
# shellcheck disable=SC2119
# shellcheck source=utils/lib.sh
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
# ----------------------------------------------------------------------------
# config
# ----------------------------------------------------------------------------
SERVICE_NAME="searx"
SERVICE_USER="${SERVICE_NAME}"
# shellcheck disable=SC2034
SERVICE_GROUP="${SERVICE_USER}"
SERVICE_HOME="/home/${SERVICE_USER}"
SEARX_URL="127.0.0.1:8888"
SEARX_GIT_URL="https://github.com/asciimoo/searx.git"
SEARX_GIT_BRANCH="master"
# FIXME: Arch Linux & RHEL should be added
SEARX_APT_PACKAGES="\
libapache2-mod-uwsgi uwsgi uwsgi-plugin-python3 \
git build-essential libxslt-dev python3-dev python3-babel zlib1g-dev \
libffi-dev libssl-dev"
SEARX_PYENV="${SERVICE_HOME}/searx-pyenv"
SEARX_SRC="${SERVICE_HOME}/searx-src"
SEARX_SETTINGS="${SEARX_SRC}/searx/settings.yml"
SEARX_INSTANCE_NAME="${SEARX_INSTANCE_NAME:-searx@$(uname -n)}"
SEARX_UWSGI_APP="searx.ini"
SEARX_UWSGI_SOCKET="/run/uwsgi/app/searx/socket"
# Apache Settings
SEARX_APACHE_URL="/searx"
SEARX_APACHE_SITE="searx.conf"
# shellcheck disable=SC2034
CONFIG_FILES=(
"${uWSGI_SETUP}/apps-available/${SEARX_UWSGI_APP}"
)
# shellcheck disable=SC2034
CONFIG_BACKUP_ENCRYPTED=(
"${SEARX_SETTINGS}"
)
# ----------------------------------------------------------------------------
usage() {
# ----------------------------------------------------------------------------
# shellcheck disable=SC1117
cat <<EOF
usage:
$(basename "$0") shell
$(basename "$0") install [all|user|pyenv|searx-src|apache]
$(basename "$0") update [searx]
$(basename "$0") remove [all|user|pyenv|searx-src]
$(basename "$0") activate [service]
$(basename "$0") deactivate [service]
$(basename "$0") show [service]
$(basename "$0") option [debug-on|debug-off]
shell
start interactive shell from user ${SERVICE_USER}
install / remove
all: complete (de-) installation of searx service
user: add/remove service user '$SERVICE_USER' at $SERVICE_HOME
searx-src: clone $SEARX_GIT_URL
pyenv: create/remove virtualenv (python) in $SEARX_PYENV
apache: install apache site for searx-uwsgi app
update searx
Update searx installation of user ${SERVICE_USER}
activate
activate and start service daemon (systemd unit)
deactivate service
stop and deactivate service daemon (systemd unit)
show service
run some small tests and show service's status and log
option
set one of te available options
EOF
[ ! -z ${1+x} ] && echo -e "$1"
}
main() {
rst_title "$SERVICE_NAME" part
local _usage="ERROR: unknown or missing $1 command $2"
case $1 in
--source-only) ;;
-h|--help) usage; exit 0;;
shell)
sudo_or_exit
interactive_shell
;;
show)
case $2 in
service)
sudo_or_exit
show_service
;;
*) usage "$_usage"; exit 42;;
esac ;;
install)
sudo_or_exit
case $2 in
all) install_all ;;
user) assert_user ;;
pyenv) create_pyenv ;;
searx-src) clone_searx ;;
apache) install_apache_site ;;
*) usage "$_usage"; exit 42;;
esac ;;
update)
sudo_or_exit
case $2 in
searx) update_searx;;
*) usage "$_usage"; exit 42;;
esac ;;
remove)
sudo_or_exit
case $2 in
all) remove_all;;
user) remove_user ;;
pyenv) remove_pyenv ;;
searx-src) remove_searx ;;
*) usage "$_usage"; exit 42;;
esac ;;
activate)
sudo_or_exit
case $2 in
service)
activate_service; uWSGI_restart ;;
*) usage "$_usage"; exit 42;;
esac ;;
deactivate)
sudo_or_exit
case $2 in
service) deactivate_service; uWSGI_restart ;;
*) usage "$_usage"; exit 42;;
esac ;;
option)
sudo_or_exit
case $2 in
debug-on) echo; enable_debug ;;
debug-off) echo; disable_debug ;;
*) usage "$_usage"; exit 42;;
esac ;;
*) usage "ERROR: unknown or missing command $1"; exit 42;;
esac
}
_service_prefix=" |$SERVICE_USER| "
install_all() {
rst_title "Install $SERVICE_NAME (service)"
pkg_install "$SEARX_APT_PACKAGES"
wait_key
assert_user
wait_key
clone_searx
wait_key
create_pyenv
wait_key
configure_searx
wait_key
test_local_searx
wait_key
install_searx_uwsgi
if service_is_available; then
info_msg "URL http://$SEARX_URL is available."
else
err_msg "URL http://$SEARX_URL not available, check searx & uwsgi setup!"
fi
}
update_searx() {
rst_title "Update searx instance"
echo
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
cd ${SEARX_SRC}
cp -f ${SEARX_SETTINGS} ${SEARX_SETTINGS}.backup
git stash push -m "BACKUP -- 'update server' at ($(date))"
git checkout -b $SEARX_GIT_BRANCH" --track "$SEARX_GIT_BRANCH"
git pull "$SEARX_GIT_BRANCH"
${SEARX_SRC}/manage.sh update_packages
EOF
configure_searx
rst_title "${SEARX_SETTINGS}" section
rstBlock 'Diff between new setting file (<) and backup (>):'
echo
diff "$SEARX_SETTINGS}" "${SEARX_SETTINGS}.backup"
local action
choose_one action "What should happen to the settings file? " \
"keep new configuration" \
"revert to the old configuration (backup file)" \
"start interactiv shell"
case $action in
"keep new configuration")
info_msg "continue using new settings file"
;;
"revert to the old configuration (backup file)")
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
cp -f ${SEARX_SETTINGS}.backup ${SEARX_SETTINGS}
EOF
;;
"start interactiv shell")
interactive_shell
;;
esac
chown "${SERVICE_USER}:${SERVICE_USER}" "${SEARX_SETTINGS}"
# shellcheck disable=SC2016
rst_para 'Diff between local modified settings (<) and $SEARX_GIT_BRANCH branch (>):'
echo
git_diff
wait_key
uWSGI_restart
}
remove_all() {
rst_title "De-Install $SERVICE_NAME (service)"
rst_para "\
It goes without saying that this script can only be used to remove
installations that were installed with this script."
if ! ask_yn "Do you really want to deinstall $SERVICE_NAME?"; then
return
fi
remove_searx_uwsgi
wait_key
remove_user
}
user_is_available() {
sudo -i -u "$SERVICE_USER" echo \$HOME &>/dev/null
}
assert_user() {
rst_title "user $SERVICE_USER" section
echo
tee_stderr 1 <<EOF | bash | prefix_stdout
sudo -H adduser --shell /bin/bash --system --home "$SERVICE_HOME" \
--disabled-password --group --gecos 'searx' $SERVICE_USER
sudo -H usermod -a -G shadow $SERVICE_USER
groups $SERVICE_USER
EOF
#SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME)"
#export SERVICE_HOME
#echo "export SERVICE_HOME=$SERVICE_HOME"
}
remove_user() {
rst_title "Drop $SERVICE_USER HOME" section
if ask_yn "Do you really want to drop $SERVICE_USER home folder?"; then
userdel -r -f "$SERVICE_USER" 2>&1 | prefix_stdout
else
rst_para "Leave HOME folder $(du -sh "$SERVICE_HOME") unchanged."
fi
}
clone_is_available() {
[[ -f "$SEARX_SETTINGS" ]]
}
# shellcheck disable=SC2164
clone_searx() {
rst_title "Clone searx sources" section
echo
SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME 2>/dev/null)"
if [[ ! "${SERVICE_HOME}" ]]; then
err_msg "to clone searx sources, user $SERVICE_USER hast to be created first"
return 42
fi
export SERVICE_HOME
git_clone "$SEARX_GIT_URL" "$SEARX_SRC" \
"$SEARX_GIT_BRANCH" "$SERVICE_USER"
pushd "${SEARX_SRC}" > /dev/null
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
cd "${SEARX_SRC}"
git config user.email "$ADMIN_EMAIL"
git config user.name "$ADMIN_NAME"
git config --list
EOF
popd > /dev/null
}
remove_searx() {
rst_title "Drop searx sources" section
if ask_yn "Do you really want to drop searx sources ($SEARX_SRC)?"; then
rm -rf "$SEARX_SRC"
else
rst_para "Leave searx sources unchanged."
fi
}
pyenv_is_available() {
[[ -f "${SEARX_PYENV}/bin/activate" ]]
}
create_pyenv() {
rst_title "Create virtualenv (python)" section
echo
if [[ ! -f "${SEARX_SRC}/manage.sh" ]]; then
err_msg "to create pyenv for searx, searx has to be cloned first"
return 42
fi
info_msg "create pyenv in ${SEARX_PYENV}"
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
rm -rf "${SEARX_PYENV}"
python3 -m venv "${SEARX_PYENV}"
grep -qFs -- 'source ${SEARX_PYENV}/bin/activate' ~/.profile \
|| echo 'source ${SEARX_PYENV}/bin/activate' >> ~/.profile
EOF
info_msg "inspect python's virtual environment"
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
command -v python && python --version
EOF
wait_key
info_msg "install needed python packages"
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
${SEARX_SRC}/manage.sh update_packages
EOF
}
remove_pyenv() {
rst_title "Remove virtualenv (python)" section
if ! ask_yn "Do you really want to drop ${SEARX_PYENV} ?"; then
return
fi
info_msg "remove pyenv activation from ~/.profile"
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
grep -v 'source ${SEARX_PYENV}/bin/activate' ~/.profile > ~/.profile.##
mv ~/.profile.## ~/.profile
EOF
rm -rf "${SEARX_PYENV}"
}
configure_searx() {
rst_title "Configure searx" section
rst_para "Setup searx config located at $SEARX_SETTINGS"
echo
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
cd ${SEARX_SRC}
sed -i -e "s/ultrasecretkey/$(openssl rand -hex 16)/g" "$SEARX_SETTINGS"
sed -i -e "s/{instance_name}/${SEARX_INSTANCE_NAME}/g" "$SEARX_SETTINGS"
EOF
}
test_local_searx() {
rst_title "Testing searx instance localy" section
echo
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
cd ${SEARX_SRC}
sed -i -e "s/debug : False/debug : True/g" "$SEARX_SETTINGS"
timeout 5 python3 searx/webapp.py &
sleep 1
curl --location --verbose --head --insecure $SEARX_URL
sed -i -e "s/debug : True/debug : False/g" "$SEARX_SETTINGS"
EOF
}
install_searx_uwsgi() {
rst_title "Install searx's uWSGI app (searx.ini)" section
echo
uWSGI_install_app "$SEARX_UWSGI_APP"
}
remove_searx_uwsgi() {
rst_title "Remove searx's uWSGI app (searx.ini)" section
echo
uWSGI_remove_app "$SEARX_UWSGI_APP"
}
activate_service() {
rst_title "Activate $SERVICE_NAME (service)" section
echo
uWSGI_enable_app "$SEARX_UWSGI_APP"
}
deactivate_service() {
rst_title "De-Activate $SERVICE_NAME (service)" section
echo
uWSGI_disable_app "$SEARX_UWSGI_APP"
}
interactive_shell() {
echo "// exit with CTRL-D"
sudo -H -u "${SERVICE_USER}" -i
}
git_diff() {
sudo -H -u "${SERVICE_USER}" -i <<EOF
cd ${SEARX_REPO_FOLDER}
git --no-pager diff
EOF
}
service_is_available() {
curl --insecure "http://$SEARX_URL" &>/dev/null
}
enable_debug() {
info_msg "try to enable debug mode ..."
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
cd ${SEARX_SRC}
sed -i -e "s/debug : False/debug : True/g" "$SEARX_SETTINGS"
EOF
uWSGI_restart
}
disable_debug() {
info_msg "try to disable debug mode ..."
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
cd ${SEARX_SRC}
sed -i -e "s/debug : True/debug : False/g" "$SEARX_SETTINGS"
EOF
uWSGI_restart
}
show_service() {
rst_title "service status & log"
echo
apache_is_installed && info_msg "Apache is installed."
if user_is_available; then
info_msg "service account $SERVICE_USER available."
else
err_msg "service account $SERVICE_USER not available!"
fi
if service_is_available; then
info_msg "URL http://$SEARX_URL is available."
else
err_msg "URL http://$SEARX_URL not available!"
fi
if pyenv_is_available; then
info_msg "${SEARX_PYENV}/bin/activate is available."
else
err_msg "${SEARX_PYENV}/bin/activate not available!"
fi
if clone_is_available; then
info_msg "Searx software is installed."
else
err_msg "Missing searx software!"
fi
uWSGI_app_available "$SEARX_UWSGI_APP" \
|| err_msg "uWSGI app $SEARX_UWSGI_APP not available!"
if uWSGI_app_enabled "$SEARX_UWSGI_APP"; then
info_msg "uWSGI app $SEARX_UWSGI_APP is enabled."
else
err_msg "uWSGI app $SEARX_UWSGI_APP not enabled!"
fi
local _debug_on
if ask_yn "Enable searx debug mode?"; then
enable_debug
_debug_on=1
fi
echo
systemctl --no-pager -l status uwsgi.service
echo
read -r -s -n1 -t 2 -p "// use CTRL-C to stop monitoring the log"
echo
while true; do
trap break 2
#journalctl -f -u uwsgi.service
tail -f /var/log/uwsgi/app/searx.log
done
if [[ $_debug_on == 1 ]]; then
disable_debug
fi
return 0
}
install_apache_site() {
rst_title "Install Apache site $SEARX_APACHE_SITE"
rst_para "\
This installs the searx uwsgi app as apache site. If your server ist public to
the internet you should instead use a reverse proxy (filtron) to block
excessively bot queries."
! apache_is_installed && err_msg "Apache is not installed."
if ! ask_yn "Do you really want to install apache site for searx-uwsgi?"; then
return
fi
echo
apache_install_site --variant=uwsgi "${SEARX_APACHE_SITE}"
}
# ----------------------------------------------------------------------------
main "$@"
# ----------------------------------------------------------------------------