forked from Icycoide/searxng
Merge branch 'master' into gigablast
This commit is contained in:
commit
4eab5cf854
68 changed files with 7299 additions and 536 deletions
|
@ -1,4 +1,5 @@
|
|||
export GIT_URL='https://github.com/asciimoo/searx'
|
||||
export GIT_BRANCH='master'
|
||||
export ISSUE_URL='https://github.com/asciimoo/searx/issues'
|
||||
export SEARX_URL='https://searx.me'
|
||||
export DOCS_URL='https://asciimoo.github.io/searx'
|
||||
|
|
561
utils/filtron.sh
Executable file
561
utils/filtron.sh
Executable file
|
@ -0,0 +1,561 @@
|
|||
#!/usr/bin/env bash
|
||||
# -*- coding: utf-8; mode: sh indent-tabs-mode: nil -*-
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# shellcheck disable=SC2119,SC2001
|
||||
|
||||
# shellcheck source=utils/lib.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
||||
# shellcheck source=utils/brand.env
|
||||
source "${REPO_ROOT}/utils/brand.env"
|
||||
source_dot_config
|
||||
source "${REPO_ROOT}/utils/lxc-searx.env"
|
||||
in_container && lxc_set_suite_env
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# config
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
PUBLIC_URL="${PUBLIC_URL:-http://$(uname -n)/searx}"
|
||||
PUBLIC_HOST="${PUBLIC_HOST:-$(echo "$PUBLIC_URL" | sed -e 's/[^/]*\/\/\([^@]*@\)\?\([^:/]*\).*/\2/')}"
|
||||
|
||||
FILTRON_URL_PATH="${FILTRON_URL_PATH:-$(echo "${PUBLIC_URL}" \
|
||||
| sed -e 's,^.*://[^/]*\(/.*\),\1,g')}"
|
||||
[[ "${FILTRON_URL_PATH}" == "${PUBLIC_URL}" ]] && FILTRON_URL_PATH=/
|
||||
|
||||
FILTRON_ETC="/etc/filtron"
|
||||
FILTRON_RULES="$FILTRON_ETC/rules.json"
|
||||
|
||||
FILTRON_API="${FILTRON_API:-127.0.0.1:4005}"
|
||||
FILTRON_LISTEN="${FILTRON_LISTEN:-127.0.0.1:4004}"
|
||||
FILTRON_TARGET="${FILTRON_TARGET:-127.0.0.1:8888}"
|
||||
|
||||
SERVICE_NAME="filtron"
|
||||
SERVICE_USER="${SERVICE_USER:-${SERVICE_NAME}}"
|
||||
SERVICE_HOME_BASE="${SERVICE_HOME_BASE:-/usr/local}"
|
||||
SERVICE_HOME="${SERVICE_HOME_BASE}/${SERVICE_USER}"
|
||||
SERVICE_SYSTEMD_UNIT="${SYSTEMD_UNITS}/${SERVICE_NAME}.service"
|
||||
# shellcheck disable=SC2034
|
||||
SERVICE_GROUP="${SERVICE_USER}"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
SERVICE_GROUP="${SERVICE_USER}"
|
||||
|
||||
GO_ENV="${SERVICE_HOME}/.go_env"
|
||||
GO_PKG_URL="https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz"
|
||||
GO_TAR=$(basename "$GO_PKG_URL")
|
||||
|
||||
APACHE_FILTRON_SITE="searx.conf"
|
||||
NGINX_FILTRON_SITE="searx.conf"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
CONFIG_FILES=(
|
||||
"${FILTRON_RULES}"
|
||||
"${SERVICE_SYSTEMD_UNIT}"
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
usage() {
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# shellcheck disable=SC1117
|
||||
cat <<EOF
|
||||
usage::
|
||||
$(basename "$0") shell
|
||||
$(basename "$0") install [all|user|rules]
|
||||
$(basename "$0") update [filtron]
|
||||
$(basename "$0") remove [all]
|
||||
$(basename "$0") activate [service]
|
||||
$(basename "$0") deactivate [service]
|
||||
$(basename "$0") inspect [service]
|
||||
$(basename "$0") option [debug-on|debug-off]
|
||||
$(basename "$0") apache [install|remove]
|
||||
$(basename "$0") nginx [install|remove]
|
||||
|
||||
shell
|
||||
start interactive shell from user ${SERVICE_USER}
|
||||
install / remove
|
||||
:all: complete setup of filtron service
|
||||
:user: add/remove service user '$SERVICE_USER' ($SERVICE_HOME)
|
||||
:rules: reinstall filtron rules $FILTRON_RULES
|
||||
update filtron
|
||||
Update filtron installation ($SERVICE_HOME)
|
||||
activate service
|
||||
activate and start service daemon (systemd unit)
|
||||
deactivate service
|
||||
stop and deactivate service daemon (systemd unit)
|
||||
inspect service
|
||||
show service status and log
|
||||
option
|
||||
set one of the available options
|
||||
apache (${PUBLIC_URL})
|
||||
:install: apache site with a reverse proxy (ProxyPass)
|
||||
:remove: apache site ${APACHE_FILTRON_SITE}
|
||||
nginx (${PUBLIC_URL})
|
||||
:install: nginx site with a reverse proxy (ProxyPass)
|
||||
:remove: nginx site ${NGINX_FILTRON_SITE}
|
||||
|
||||
filtron rules: ${FILTRON_RULES}
|
||||
|
||||
If needed, set PUBLIC_URL of your WEB service in the '${DOT_CONFIG#"$REPO_ROOT/"}' file::
|
||||
PUBLIC_URL : ${PUBLIC_URL}
|
||||
PUBLIC_HOST : ${PUBLIC_HOST}
|
||||
SERVICE_USER : ${SERVICE_USER}
|
||||
FILTRON_TARGET : ${FILTRON_TARGET}
|
||||
FILTRON_API : ${FILTRON_API}
|
||||
FILTRON_LISTEN : ${FILTRON_LISTEN}
|
||||
EOF
|
||||
if in_container; then
|
||||
# in containers the service is listening on 0.0.0.0 (see lxc-searx.env)
|
||||
for ip in $(global_IPs) ; do
|
||||
if [[ $ip =~ .*:.* ]]; then
|
||||
echo " container URL (IPv6): http://[${ip#*|}]:4005/"
|
||||
else
|
||||
# IPv4:
|
||||
echo " container URL (IPv4): http://${ip#*|}:4005/"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
[[ -n ${1} ]] && err_msg "$1"
|
||||
}
|
||||
|
||||
main() {
|
||||
required_commands \
|
||||
sudo install git wget curl \
|
||||
|| exit
|
||||
|
||||
local _usage="unknown or missing $1 command $2"
|
||||
|
||||
case $1 in
|
||||
--getenv) var="$2"; echo "${!var}"; exit 0;;
|
||||
-h|--help) usage; exit 0;;
|
||||
|
||||
shell)
|
||||
sudo_or_exit
|
||||
interactive_shell "${SERVICE_USER}"
|
||||
;;
|
||||
inspect)
|
||||
case $2 in
|
||||
service)
|
||||
sudo_or_exit
|
||||
inspect_service
|
||||
;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
install)
|
||||
rst_title "$SERVICE_NAME" part
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
all) install_all ;;
|
||||
user) assert_user ;;
|
||||
rules)
|
||||
rst_title "Re-Install filtron rules"
|
||||
echo
|
||||
install_template --no-eval "$FILTRON_RULES" root root 644
|
||||
systemd_restart_service "${SERVICE_NAME}"
|
||||
;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
update)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
filtron) update_filtron ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
remove)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
all) remove_all;;
|
||||
user) drop_service_account "${SERVICE_USER}" ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
activate)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
service) systemd_activate_service "${SERVICE_NAME}" ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
deactivate)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
service) systemd_deactivate_service "${SERVICE_NAME}" ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
apache)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
install) install_apache_site ;;
|
||||
remove) remove_apache_site ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
nginx)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
install) install_nginx_site ;;
|
||||
remove) remove_nginx_site ;;
|
||||
*) 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 ;;
|
||||
doc) rst-doc ;;
|
||||
*) usage "unknown or missing command $1"; exit 42;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_all() {
|
||||
rst_title "Install $SERVICE_NAME (service)"
|
||||
assert_user
|
||||
wait_key
|
||||
install_go "${GO_PKG_URL}" "${GO_TAR}" "${SERVICE_USER}"
|
||||
wait_key
|
||||
install_filtron
|
||||
wait_key
|
||||
systemd_install_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"
|
||||
wait_key
|
||||
echo
|
||||
if ! service_is_available "http://${FILTRON_LISTEN}" ; then
|
||||
err_msg "Filtron does not listening on: http://${FILTRON_LISTEN}"
|
||||
fi
|
||||
if apache_is_installed; then
|
||||
info_msg "Apache is installed on this host."
|
||||
if ask_yn "Do you want to install a reverse proxy (ProxyPass)" Yn; then
|
||||
install_apache_site
|
||||
fi
|
||||
elif nginx_is_installed; then
|
||||
info_msg "nginx is installed on this host."
|
||||
if ask_yn "Do you want to install a reverse proxy (ProxyPass)" Yn; then
|
||||
install_nginx_site
|
||||
fi
|
||||
fi
|
||||
if ask_yn "Do you want to inspect the installation?" Ny; then
|
||||
inspect_service
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
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 ! systemd_remove_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"; then
|
||||
return 42
|
||||
fi
|
||||
drop_service_account "${SERVICE_USER}"
|
||||
rm -r "$FILTRON_ETC" 2>&1 | prefix_stdout
|
||||
if service_is_available "${PUBLIC_URL}"; then
|
||||
MSG="** Don't forget to remove your public site! (${PUBLIC_URL}) **" wait_key 10
|
||||
fi
|
||||
}
|
||||
|
||||
assert_user() {
|
||||
rst_title "user $SERVICE_USER" section
|
||||
echo
|
||||
tee_stderr 1 <<EOF | bash | prefix_stdout
|
||||
useradd --shell /bin/bash --system \
|
||||
--home-dir "$SERVICE_HOME" \
|
||||
--comment 'Reverse HTTP proxy to filter requests' $SERVICE_USER
|
||||
mkdir "$SERVICE_HOME"
|
||||
chown -R "$SERVICE_GROUP:$SERVICE_GROUP" "$SERVICE_HOME"
|
||||
groups $SERVICE_USER
|
||||
EOF
|
||||
SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME)"
|
||||
export SERVICE_HOME
|
||||
echo "export SERVICE_HOME=$SERVICE_HOME"
|
||||
|
||||
cat > "$GO_ENV" <<EOF
|
||||
export GOPATH=\$HOME/go-apps
|
||||
export PATH=\$PATH:\$HOME/local/go/bin:\$GOPATH/bin
|
||||
EOF
|
||||
echo "Environment $GO_ENV has been setup."
|
||||
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER"
|
||||
grep -qFs -- 'source $GO_ENV' ~/.profile || echo 'source $GO_ENV' >> ~/.profile
|
||||
EOF
|
||||
}
|
||||
|
||||
filtron_is_installed() {
|
||||
[[ -f $SERVICE_HOME/go-apps/bin/filtron ]]
|
||||
}
|
||||
|
||||
_svcpr=" ${_Yellow}|${SERVICE_USER}|${_creset} "
|
||||
|
||||
install_filtron() {
|
||||
rst_title "Install filtron in user's ~/go-apps" section
|
||||
echo
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
|
||||
go get -v -u github.com/asciimoo/filtron
|
||||
EOF
|
||||
install_template --no-eval "$FILTRON_RULES" root root 644
|
||||
}
|
||||
|
||||
update_filtron() {
|
||||
rst_title "Update filtron" section
|
||||
echo
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
|
||||
go get -v -u github.com/asciimoo/filtron
|
||||
EOF
|
||||
}
|
||||
|
||||
inspect_service() {
|
||||
|
||||
rst_title "service status & log"
|
||||
|
||||
cat <<EOF
|
||||
|
||||
sourced ${DOT_CONFIG#"$REPO_ROOT/"} :
|
||||
|
||||
PUBLIC_URL : ${PUBLIC_URL}
|
||||
PUBLIC_HOST : ${PUBLIC_HOST}
|
||||
FILTRON_URL_PATH : ${FILTRON_URL_PATH}
|
||||
FILTRON_API : ${FILTRON_API}
|
||||
FILTRON_LISTEN : ${FILTRON_LISTEN}
|
||||
FILTRON_TARGET : ${FILTRON_TARGET}
|
||||
|
||||
EOF
|
||||
|
||||
if service_account_is_available "$SERVICE_USER"; then
|
||||
info_msg "service account $SERVICE_USER available."
|
||||
else
|
||||
err_msg "service account $SERVICE_USER not available!"
|
||||
fi
|
||||
if go_is_available "$SERVICE_USER"; then
|
||||
info_msg "~$SERVICE_USER: go is installed"
|
||||
else
|
||||
err_msg "~$SERVICE_USER: go is not installed"
|
||||
fi
|
||||
if filtron_is_installed; then
|
||||
info_msg "~$SERVICE_USER: filtron app is installed"
|
||||
else
|
||||
err_msg "~$SERVICE_USER: filtron app is not installed!"
|
||||
fi
|
||||
|
||||
if ! service_is_available "http://${FILTRON_API}"; then
|
||||
err_msg "API not available at: http://${FILTRON_API}"
|
||||
fi
|
||||
|
||||
if ! service_is_available "http://${FILTRON_LISTEN}" ; then
|
||||
err_msg "Filtron does not listening on: http://${FILTRON_LISTEN}"
|
||||
fi
|
||||
|
||||
if service_is_available "http://${FILTRON_TARGET}" ; then
|
||||
info_msg "Filtron's target is available at: http://${FILTRON_TARGET}"
|
||||
fi
|
||||
|
||||
if ! service_is_available "${PUBLIC_URL}"; then
|
||||
warn_msg "Public service at ${PUBLIC_URL} is not available!"
|
||||
if ! in_container; then
|
||||
warn_msg "Check if public name is correct and routed or use the public IP from above."
|
||||
fi
|
||||
fi
|
||||
|
||||
if in_container; then
|
||||
lxc_suite_info
|
||||
else
|
||||
info_msg "public URL --> ${PUBLIC_URL}"
|
||||
info_msg "internal URL --> http://${FILTRON_LISTEN}"
|
||||
fi
|
||||
|
||||
|
||||
local _debug_on
|
||||
if ask_yn "Enable filtron debug mode?"; then
|
||||
enable_debug
|
||||
_debug_on=1
|
||||
fi
|
||||
echo
|
||||
systemctl --no-pager -l status "${SERVICE_NAME}"
|
||||
echo
|
||||
|
||||
info_msg "public URL --> ${PUBLIC_URL}"
|
||||
# shellcheck disable=SC2059
|
||||
printf "// use ${_BCyan}CTRL-C${_creset} to stop monitoring the log"
|
||||
read -r -s -n1 -t 5
|
||||
echo
|
||||
while true; do
|
||||
trap break 2
|
||||
journalctl -f -u "${SERVICE_NAME}"
|
||||
done
|
||||
|
||||
if [[ $_debug_on == 1 ]]; then
|
||||
disable_debug
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
enable_debug() {
|
||||
info_msg "try to enable debug mode ..."
|
||||
python <<EOF
|
||||
import sys, json
|
||||
|
||||
debug = {
|
||||
u'name': u'debug request'
|
||||
, u'filters': []
|
||||
, u'interval': 0
|
||||
, u'limit': 0
|
||||
, u'actions': [{u'name': u'log'}]
|
||||
}
|
||||
|
||||
with open('$FILTRON_RULES') as rules:
|
||||
j = json.load(rules)
|
||||
|
||||
pos = None
|
||||
for i in range(len(j)):
|
||||
if j[i].get('name') == 'debug request':
|
||||
pos = i
|
||||
break
|
||||
if pos is not None:
|
||||
j[pos] = debug
|
||||
else:
|
||||
j.append(debug)
|
||||
with open('$FILTRON_RULES', 'w') as rules:
|
||||
json.dump(j, rules, indent=2, sort_keys=True)
|
||||
|
||||
EOF
|
||||
systemctl restart "${SERVICE_NAME}.service"
|
||||
}
|
||||
|
||||
disable_debug() {
|
||||
info_msg "try to disable debug mode ..."
|
||||
python <<EOF
|
||||
import sys, json
|
||||
with open('$FILTRON_RULES') as rules:
|
||||
j = json.load(rules)
|
||||
|
||||
pos = None
|
||||
for i in range(len(j)):
|
||||
if j[i].get('name') == 'debug request':
|
||||
pos = i
|
||||
break
|
||||
if pos is not None:
|
||||
del j[pos]
|
||||
with open('$FILTRON_RULES', 'w') as rules:
|
||||
json.dump(j, rules, indent=2, sort_keys=True)
|
||||
EOF
|
||||
systemctl restart "${SERVICE_NAME}.service"
|
||||
}
|
||||
|
||||
install_apache_site() {
|
||||
|
||||
rst_title "Install Apache site $APACHE_FILTRON_SITE"
|
||||
|
||||
rst_para "\
|
||||
This installs a reverse proxy (ProxyPass) into apache site (${APACHE_FILTRON_SITE})"
|
||||
|
||||
! apache_is_installed && info_msg "Apache is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
else
|
||||
install_apache
|
||||
fi
|
||||
|
||||
"${REPO_ROOT}/utils/searx.sh" install uwsgi
|
||||
|
||||
apache_install_site --variant=filtron "${APACHE_FILTRON_SITE}"
|
||||
|
||||
info_msg "testing public url .."
|
||||
if ! service_is_available "${PUBLIC_URL}"; then
|
||||
err_msg "Public service at ${PUBLIC_URL} is not available!"
|
||||
fi
|
||||
}
|
||||
|
||||
remove_apache_site() {
|
||||
|
||||
rst_title "Remove Apache site $APACHE_FILTRON_SITE"
|
||||
|
||||
rst_para "\
|
||||
This removes apache site ${APACHE_FILTRON_SITE}."
|
||||
|
||||
! apache_is_installed && err_msg "Apache is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
fi
|
||||
|
||||
apache_remove_site "$APACHE_FILTRON_SITE"
|
||||
|
||||
}
|
||||
|
||||
install_nginx_site() {
|
||||
|
||||
rst_title "Install nginx site $NGINX_FILTRON_SITE"
|
||||
|
||||
rst_para "\
|
||||
This installs a reverse proxy (ProxyPass) into nginx site (${NGINX_FILTRON_SITE})"
|
||||
|
||||
! nginx_is_installed && info_msg "nginx is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
else
|
||||
install_nginx
|
||||
fi
|
||||
|
||||
"${REPO_ROOT}/utils/searx.sh" install uwsgi
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
SEARX_SRC=$("${REPO_ROOT}/utils/searx.sh" --getenv SEARX_SRC)
|
||||
# shellcheck disable=SC2034
|
||||
SEARX_URL_PATH=$("${REPO_ROOT}/utils/searx.sh" --getenv SEARX_URL_PATH)
|
||||
nginx_install_app --variant=filtron "${NGINX_FILTRON_SITE}"
|
||||
|
||||
info_msg "testing public url .."
|
||||
if ! service_is_available "${PUBLIC_URL}"; then
|
||||
err_msg "Public service at ${PUBLIC_URL} is not available!"
|
||||
fi
|
||||
}
|
||||
|
||||
remove_nginx_site() {
|
||||
|
||||
rst_title "Remove nginx site $NGINX_FILTRON_SITE"
|
||||
|
||||
rst_para "\
|
||||
This removes nginx site ${NGINX_FILTRON_SITE}."
|
||||
|
||||
! nginx_is_installed && err_msg "nginx is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
fi
|
||||
|
||||
nginx_remove_site "$FILTRON_FILTRON_SITE"
|
||||
|
||||
}
|
||||
|
||||
|
||||
rst-doc() {
|
||||
|
||||
eval "echo \"$(< "${REPO_ROOT}/docs/build-templates/filtron.rst")\""
|
||||
|
||||
echo -e "\n.. START install systemd unit"
|
||||
cat <<EOF
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: systemd
|
||||
|
||||
.. code:: bash
|
||||
|
||||
EOF
|
||||
eval "echo \"$(< "${TEMPLATES}/${SERVICE_SYSTEMD_UNIT}")\"" | prefix_stdout " "
|
||||
echo -e "\n.. END install systemd unit"
|
||||
|
||||
# for DIST_NAME in ubuntu-20.04 arch fedora; do
|
||||
# (
|
||||
# DIST_ID=${DIST_NAME%-*}
|
||||
# DIST_VERS=${DIST_NAME#*-}
|
||||
# [[ $DIST_VERS =~ $DIST_ID ]] && DIST_VERS=
|
||||
# # ...
|
||||
# )
|
||||
# done
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
main "$@"
|
||||
# ----------------------------------------------------------------------------
|
1519
utils/lib.sh
Executable file
1519
utils/lib.sh
Executable file
File diff suppressed because it is too large
Load diff
95
utils/lxc-searx.env
Normal file
95
utils/lxc-searx.env
Normal file
|
@ -0,0 +1,95 @@
|
|||
# -*- coding: utf-8; mode: sh indent-tabs-mode: nil -*-
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# shellcheck shell=bash
|
||||
|
||||
# This file is a setup of a LXC suite. It is sourced from different context, do
|
||||
# not manipulate the environment directly, implement functions and manipulate
|
||||
# environment only is subshells!
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# config
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
LXC_SUITE_NAME="searx"
|
||||
lxc_set_suite_env() {
|
||||
# name of https://images.linuxcontainers.org
|
||||
export LINUXCONTAINERS_ORG_NAME="${LINUXCONTAINERS_ORG_NAME:-images}"
|
||||
export LXC_HOST_PREFIX="${LXC_SUITE_NAME:-searx}"
|
||||
export LXC_SUITE=(
|
||||
|
||||
# to disable containers, comment out lines ..
|
||||
|
||||
# end of standard support see https://wiki.ubuntu.com/Releases
|
||||
"$LINUXCONTAINERS_ORG_NAME:ubuntu/16.04" "ubu1604" # April 2021
|
||||
"$LINUXCONTAINERS_ORG_NAME:ubuntu/18.04" "ubu1804" # April 2023
|
||||
"$LINUXCONTAINERS_ORG_NAME:ubuntu/19.10" "ubu1910" # July 2020
|
||||
"$LINUXCONTAINERS_ORG_NAME:ubuntu/20.04" "ubu2004" # future (EOL 2030)
|
||||
|
||||
# EOL see https://fedoraproject.org/wiki/Releases
|
||||
"$LINUXCONTAINERS_ORG_NAME:fedora/31" "fedora31"
|
||||
|
||||
# rolling releases see https://www.archlinux.org/releng/releases/
|
||||
"$LINUXCONTAINERS_ORG_NAME:archlinux" "archlinux"
|
||||
)
|
||||
|
||||
PUBLIC_URL="${PUBLIC_URL:-http://$(uname -n)/searx}"
|
||||
if in_container; then
|
||||
# container hostnames do not have a DNS entry: use primary IP!
|
||||
PUBLIC_URL="http://$(primary_ip)/searx"
|
||||
|
||||
# make GUEST's services public to the HOST
|
||||
FILTRON_API="0.0.0.0:4005"
|
||||
FILTRON_LISTEN="0.0.0.0:4004"
|
||||
MORTY_LISTEN="0.0.0.0:3000"
|
||||
|
||||
# export LXC specific environment
|
||||
export PUBLIC_URL FILTRON_API FILTRON_LISTEN MORTY_LISTEN
|
||||
fi
|
||||
}
|
||||
|
||||
lxc_suite_install_info() {
|
||||
(
|
||||
lxc_set_suite_env
|
||||
cat <<EOF
|
||||
LXC suite: ${LXC_SUITE_NAME} --> ${PUBLIC_URL}
|
||||
suite includes searx, morty & filtron
|
||||
suite images:
|
||||
$(echo " ${LOCAL_IMAGES[*]}" | $FMT)
|
||||
suite containers:
|
||||
$(echo " ${CONTAINERS[*]}" | $FMT)
|
||||
EOF
|
||||
)
|
||||
}
|
||||
|
||||
lxc_suite_install() {
|
||||
(
|
||||
lxc_set_suite_env
|
||||
FORCE_TIMEOUT=0
|
||||
export FORCE_TIMEOUT
|
||||
"${LXC_REPO_ROOT}/utils/searx.sh" install all
|
||||
"${LXC_REPO_ROOT}/utils/morty.sh" install all
|
||||
"${LXC_REPO_ROOT}/utils/filtron.sh" install all
|
||||
|
||||
rst_title "suite installation finished ($(hostname))" part
|
||||
lxc_suite_info
|
||||
echo
|
||||
)
|
||||
}
|
||||
|
||||
lxc_suite_info() {
|
||||
(
|
||||
lxc_set_suite_env
|
||||
for ip in $(global_IPs) ; do
|
||||
if [[ $ip =~ .*:.* ]]; then
|
||||
info_msg "(${ip%|*}) IPv6: http://[${ip#*|}]"
|
||||
else
|
||||
# IPv4:
|
||||
# shellcheck disable=SC2034,SC2031
|
||||
info_msg "(${ip%|*}) filtron: http://${ip#*|}:4004/ $PUBLIC_URL"
|
||||
info_msg "(${ip%|*}) morty: http://${ip#*|}:3000/ $PUBLIC_URL_MORTY"
|
||||
info_msg "(${ip%|*}) docs-live: http://${ip#*|}:8080/"
|
||||
fi
|
||||
done
|
||||
)
|
||||
}
|
552
utils/lxc.sh
Executable file
552
utils/lxc.sh
Executable file
|
@ -0,0 +1,552 @@
|
|||
#!/usr/bin/env bash
|
||||
# -*- coding: utf-8; mode: sh indent-tabs-mode: nil -*-
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# shellcheck source=utils/lib.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
||||
source_dot_config
|
||||
|
||||
# load environment of the LXC suite
|
||||
LXC_ENV="${LXC_ENV:-${REPO_ROOT}/utils/lxc-searx.env}"
|
||||
source "$LXC_ENV"
|
||||
lxc_set_suite_env
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# config
|
||||
# ----------------------------------------------------------------------------
|
||||
#
|
||||
# read also:
|
||||
# - https://lxd.readthedocs.io/en/latest/
|
||||
|
||||
LXC_HOST_PREFIX="${LXC_HOST_PREFIX:-test}"
|
||||
|
||||
# where all folders from HOST are mounted
|
||||
LXC_SHARE_FOLDER="/share"
|
||||
LXC_REPO_ROOT="${LXC_SHARE_FOLDER}/$(basename "${REPO_ROOT}")"
|
||||
|
||||
ubu1604_boilerplate="
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -y
|
||||
apt-get upgrade -y
|
||||
apt-get install -y git curl wget
|
||||
"
|
||||
ubu1804_boilerplate="$ubu1604_boilerplate"
|
||||
ubu1904_boilerplate="$ubu1804_boilerplate"
|
||||
ubu1910_boilerplate="$ubu1904_boilerplate"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
ubu2004_boilerplate="
|
||||
$ubu1910_boilerplate
|
||||
echo 'Set disable_coredump false' >> /etc/sudo.conf
|
||||
"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
archlinux_boilerplate="
|
||||
pacman -Syu --noconfirm
|
||||
pacman -S --noconfirm inetutils git curl wget sudo
|
||||
echo 'Set disable_coredump false' >> /etc/sudo.conf
|
||||
"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
fedora31_boilerplate="
|
||||
dnf update -y
|
||||
dnf install -y git curl wget hostname
|
||||
echo 'Set disable_coredump false' >> /etc/sudo.conf
|
||||
"
|
||||
|
||||
REMOTE_IMAGES=()
|
||||
CONTAINERS=()
|
||||
LOCAL_IMAGES=()
|
||||
|
||||
for ((i=0; i<${#LXC_SUITE[@]}; i+=2)); do
|
||||
REMOTE_IMAGES=("${REMOTE_IMAGES[@]}" "${LXC_SUITE[i]}")
|
||||
CONTAINERS=("${CONTAINERS[@]}" "${LXC_HOST_PREFIX}-${LXC_SUITE[i+1]}")
|
||||
LOCAL_IMAGES=("${LOCAL_IMAGES[@]}" "${LXC_SUITE[i+1]}")
|
||||
done
|
||||
|
||||
HOST_USER="${SUDO_USER:-$USER}"
|
||||
HOST_USER_ID=$(id -u "${HOST_USER}")
|
||||
HOST_GROUP_ID=$(id -g "${HOST_USER}")
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
usage() {
|
||||
# ----------------------------------------------------------------------------
|
||||
_cmd="$(basename "$0")"
|
||||
cat <<EOF
|
||||
usage::
|
||||
$_cmd build [containers|<name>]
|
||||
$_cmd copy [images]
|
||||
$_cmd remove [containers|<name>|images]
|
||||
$_cmd [start|stop] [containers|<name>]
|
||||
$_cmd show [images|suite|info|config [<name>]]
|
||||
$_cmd cmd [--|<name>] '...'
|
||||
$_cmd install [suite|base [<name>]]
|
||||
|
||||
build
|
||||
:containers: build, launch all containers and 'install base' packages
|
||||
:<name>: build, launch container <name> and 'install base' packages
|
||||
copy:
|
||||
:images: copy remote images of the suite into local storage
|
||||
remove
|
||||
:containers: delete all 'containers' or only <container-name>
|
||||
:images: delete local images of the suite
|
||||
start/stop
|
||||
:containers: start/stop all 'containers' from the suite
|
||||
:<name>: start/stop container <name> from suite
|
||||
show
|
||||
:info: show info of all (or <name>) containers from LXC suite
|
||||
:config: show config of all (or <name>) containers from the LXC suite
|
||||
:suite: show services of all (or <name>) containers from the LXC suite
|
||||
:images: show information of local images
|
||||
cmd
|
||||
use single qoutes to evaluate in container's bash, e.g.: 'echo \$(hostname)'
|
||||
-- run command '...' in all containers of the LXC suite
|
||||
:<name>: run command '...' in container <name>
|
||||
install
|
||||
:base: prepare LXC; install basic packages
|
||||
:suite: install LXC ${LXC_SUITE_NAME} suite into all (or <name>) containers
|
||||
|
||||
EOF
|
||||
usage_containers
|
||||
[ -n "${1+x}" ] && err_msg "$1"
|
||||
}
|
||||
|
||||
usage_containers() {
|
||||
lxc_suite_install_info
|
||||
[ -n "${1+x}" ] && err_msg "$1"
|
||||
}
|
||||
|
||||
lxd_info() {
|
||||
|
||||
cat <<EOF
|
||||
|
||||
LXD is needed, to install run::
|
||||
|
||||
snap install lxd
|
||||
lxd init --auto
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
|
||||
local exit_val
|
||||
local _usage="unknown or missing $1 command $2"
|
||||
|
||||
# don't check prerequisite when in recursion
|
||||
if [[ ! $1 == __* ]]; then
|
||||
if ! in_container; then
|
||||
! required_commands lxc && lxd_info && exit 42
|
||||
fi
|
||||
[[ -z $LXC_SUITE ]] && err_msg "missing LXC_SUITE" && exit 42
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
--getenv) var="$2"; echo "${!var}"; exit 0;;
|
||||
-h|--help) usage; exit 0;;
|
||||
|
||||
build)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
${LXC_HOST_PREFIX}-*) build_container "$2" ;;
|
||||
''|--|containers) build_all_containers ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac
|
||||
;;
|
||||
copy)
|
||||
case $2 in
|
||||
''|images) lxc_copy_images_localy;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac
|
||||
;;
|
||||
remove)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
''|--|containers) remove_containers ;;
|
||||
images) lxc_delete_images_localy ;;
|
||||
${LXC_HOST_PREFIX}-*)
|
||||
! lxc_exists "$2" && warn_msg "container not yet exists: $2" && exit 0
|
||||
if ask_yn "Do you really want to delete container $2"; then
|
||||
lxc_delete_container "$2"
|
||||
fi
|
||||
;;
|
||||
*) usage "uknown or missing container <name> $2"; exit 42;;
|
||||
esac
|
||||
;;
|
||||
start|stop)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
''|--|containers) lxc_cmd "$1" ;;
|
||||
${LXC_HOST_PREFIX}-*)
|
||||
! lxc_exists "$2" && usage_containers "unknown container: $2" && exit 42
|
||||
info_msg "lxc $1 $2"
|
||||
lxc "$1" "$2" | prefix_stdout "[${_BBlue}${i}${_creset}] "
|
||||
;;
|
||||
*) usage "uknown or missing container <name> $2"; exit 42;;
|
||||
esac
|
||||
;;
|
||||
show)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
suite)
|
||||
case $3 in
|
||||
${LXC_HOST_PREFIX}-*)
|
||||
lxc exec -t "$3" -- "${LXC_REPO_ROOT}/utils/lxc.sh" __show suite \
|
||||
| prefix_stdout "[${_BBlue}$3${_creset}] "
|
||||
;;
|
||||
*) show_suite;;
|
||||
esac
|
||||
;;
|
||||
images) show_images ;;
|
||||
config)
|
||||
case $3 in
|
||||
${LXC_HOST_PREFIX}-*)
|
||||
! lxc_exists "$3" && usage_containers "unknown container: $3" && exit 42
|
||||
lxc config show "$3" | prefix_stdout "[${_BBlue}${3}${_creset}] "
|
||||
;;
|
||||
*)
|
||||
rst_title "container configurations"
|
||||
echo
|
||||
lxc list "$LXC_HOST_PREFIX-"
|
||||
echo
|
||||
lxc_cmd config show
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
info)
|
||||
case $3 in
|
||||
${LXC_HOST_PREFIX}-*)
|
||||
! lxc_exists "$3" && usage_containers "unknown container: $3" && exit 42
|
||||
lxc info "$3" | prefix_stdout "[${_BBlue}${3}${_creset}] "
|
||||
;;
|
||||
*)
|
||||
rst_title "container info"
|
||||
echo
|
||||
lxc_cmd info
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac
|
||||
;;
|
||||
__show)
|
||||
# wrapped show commands, called once in each container
|
||||
case $2 in
|
||||
suite) lxc_suite_info ;;
|
||||
esac
|
||||
;;
|
||||
cmd)
|
||||
sudo_or_exit
|
||||
shift
|
||||
case $1 in
|
||||
--) shift; lxc_exec "$@" ;;
|
||||
${LXC_HOST_PREFIX}-*)
|
||||
! lxc_exists "$1" && usage_containers "unknown container: $1" && exit 42
|
||||
local name=$1
|
||||
shift
|
||||
lxc_exec_cmd "${name}" "$@"
|
||||
;;
|
||||
*) usage_containers "unknown container: $1" && exit 42
|
||||
esac
|
||||
;;
|
||||
install)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
suite|base)
|
||||
case $3 in
|
||||
${LXC_HOST_PREFIX}-*)
|
||||
! lxc_exists "$3" && usage_containers "unknown container: $3" && exit 42
|
||||
lxc_exec_cmd "$3" "${LXC_REPO_ROOT}/utils/lxc.sh" __install "$2"
|
||||
;;
|
||||
''|--) lxc_exec "${LXC_REPO_ROOT}/utils/lxc.sh" __install "$2" ;;
|
||||
*) usage_containers "unknown container: $3" && exit 42
|
||||
esac
|
||||
;;
|
||||
*) usage "$_usage"; exit 42 ;;
|
||||
esac
|
||||
;;
|
||||
__install)
|
||||
# wrapped install commands, called once in each container
|
||||
# shellcheck disable=SC2119
|
||||
case $2 in
|
||||
suite) lxc_suite_install ;;
|
||||
base) FORCE_TIMEOUT=0 lxc_install_base_packages ;;
|
||||
esac
|
||||
;;
|
||||
doc)
|
||||
echo
|
||||
echo ".. generic utils/lxc.sh documentation"
|
||||
;;
|
||||
-*) usage "unknown option $1"; exit 42;;
|
||||
*) usage "unknown or missing command $1"; exit 42;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
build_all_containers() {
|
||||
rst_title "Build all LXC containers of suite"
|
||||
echo
|
||||
usage_containers
|
||||
lxc_copy_images_localy
|
||||
lxc_init_all_containers
|
||||
lxc_config_all_containers
|
||||
lxc_boilerplate_all_containers
|
||||
rst_title "install LXC base packages" section
|
||||
echo
|
||||
lxc_exec "${LXC_REPO_ROOT}/utils/lxc.sh" __install base
|
||||
echo
|
||||
lxc list "$LXC_HOST_PREFIX"
|
||||
}
|
||||
|
||||
build_container() {
|
||||
rst_title "Build container $1"
|
||||
|
||||
local remote_image
|
||||
local container
|
||||
local image
|
||||
local boilerplate_script
|
||||
|
||||
for ((i=0; i<${#LXC_SUITE[@]}; i+=2)); do
|
||||
if [ "${LXC_HOST_PREFIX}-${LXC_SUITE[i+1]}" = "$1" ]; then
|
||||
remote_image="${LXC_SUITE[i]}"
|
||||
container="${LXC_HOST_PREFIX}-${LXC_SUITE[i+1]}"
|
||||
image="${LXC_SUITE[i+1]}"
|
||||
boilerplate_script="${image}_boilerplate"
|
||||
boilerplate_script="${!boilerplate_script}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
echo
|
||||
if [ -z "$container" ]; then
|
||||
err_msg "container $1 unknown"
|
||||
usage_containers
|
||||
return 42
|
||||
fi
|
||||
lxc_image_copy "${remote_image}" "${image}"
|
||||
rst_title "init container" section
|
||||
lxc_init_container "${image}" "${container}"
|
||||
rst_title "configure container" section
|
||||
lxc_config_container "${container}"
|
||||
rst_title "run LXC boilerplate scripts" section
|
||||
lxc_install_boilerplate "${container}" "$boilerplate_script"
|
||||
echo
|
||||
rst_title "install LXC base packages" section
|
||||
lxc_exec_cmd "${container}" "${LXC_REPO_ROOT}/utils/lxc.sh" __install base \
|
||||
| prefix_stdout "[${_BBlue}${container}${_creset}] "
|
||||
echo
|
||||
lxc list "$container"
|
||||
}
|
||||
|
||||
remove_containers() {
|
||||
rst_title "Remove all LXC containers of suite"
|
||||
rst_para "existing containers matching ${_BGreen}$LXC_HOST_PREFIX-*${_creset}"
|
||||
echo
|
||||
lxc list "$LXC_HOST_PREFIX-"
|
||||
echo -en "\\n${_BRed}LXC containers to delete::${_creset}\\n\\n ${CONTAINERS[*]}\\n" | $FMT
|
||||
local default=Ny
|
||||
[[ $FORCE_TIMEOUT = 0 ]] && default=Yn
|
||||
if ask_yn "Do you really want to delete these containers" $default; then
|
||||
for i in "${CONTAINERS[@]}"; do
|
||||
lxc_delete_container "$i"
|
||||
done
|
||||
fi
|
||||
echo
|
||||
lxc list "$LXC_HOST_PREFIX-"
|
||||
}
|
||||
|
||||
# images
|
||||
# ------
|
||||
|
||||
lxc_copy_images_localy() {
|
||||
rst_title "copy images" section
|
||||
for ((i=0; i<${#LXC_SUITE[@]}; i+=2)); do
|
||||
lxc_image_copy "${LXC_SUITE[i]}" "${LXC_SUITE[i+1]}"
|
||||
done
|
||||
# lxc image list local: && wait_key
|
||||
}
|
||||
|
||||
lxc_delete_images_localy() {
|
||||
rst_title "Delete LXC images"
|
||||
rst_para "local existing images"
|
||||
echo
|
||||
lxc image list local:
|
||||
echo -en "\\n${_BRed}LXC images to delete::${_creset}\\n\\n ${LOCAL_IMAGES[*]}\\n"
|
||||
if ask_yn "Do you really want to delete these images"; then
|
||||
for i in "${LOCAL_IMAGES[@]}"; do
|
||||
lxc_delete_local_image "$i"
|
||||
done
|
||||
fi
|
||||
|
||||
for i in $(lxc image list --format csv | grep '^,' | sed 's/,\([^,]*\).*$/\1/'); do
|
||||
if ask_yn "Image $i has no alias, do you want to delete the image?" Yn; then
|
||||
lxc_delete_local_image "$i"
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
lxc image list local:
|
||||
}
|
||||
|
||||
show_images(){
|
||||
rst_title "local images"
|
||||
echo
|
||||
lxc image list local:
|
||||
echo -en "\\n${_Green}LXC suite images::${_creset}\\n\\n ${LOCAL_IMAGES[*]}\\n"
|
||||
wait_key
|
||||
for i in "${LOCAL_IMAGES[@]}"; do
|
||||
if lxc_image_exists "$i"; then
|
||||
info_msg "lxc image info ${_BBlue}${i}${_creset}"
|
||||
lxc image info "$i" | prefix_stdout "[${_BBlue}${i}${_creset}] "
|
||||
else
|
||||
warn_msg "image ${_BBlue}$i${_creset} does not yet exists"
|
||||
fi
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
|
||||
# container
|
||||
# ---------
|
||||
|
||||
show_suite(){
|
||||
rst_title "LXC suite ($LXC_HOST_PREFIX-*)"
|
||||
echo
|
||||
lxc list "$LXC_HOST_PREFIX-"
|
||||
echo
|
||||
for i in "${CONTAINERS[@]}"; do
|
||||
if ! lxc_exists "$i"; then
|
||||
warn_msg "container ${_BBlue}$i${_creset} does not yet exists"
|
||||
else
|
||||
lxc exec -t "${i}" -- "${LXC_REPO_ROOT}/utils/lxc.sh" __show suite \
|
||||
| prefix_stdout "[${_BBlue}${i}${_creset}] "
|
||||
echo
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
lxc_cmd() {
|
||||
for i in "${CONTAINERS[@]}"; do
|
||||
if ! lxc_exists "$i"; then
|
||||
warn_msg "container ${_BBlue}$i${_creset} does not yet exists"
|
||||
else
|
||||
info_msg "lxc $* $i"
|
||||
lxc "$@" "$i" | prefix_stdout "[${_BBlue}${i}${_creset}] "
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
lxc_exec_cmd() {
|
||||
local name="$1"
|
||||
shift
|
||||
exit_val=
|
||||
info_msg "[${_BBlue}${name}${_creset}] ${_BGreen}${*}${_creset}"
|
||||
lxc exec -t --cwd "${LXC_REPO_ROOT}" "${name}" -- bash -c "$*"
|
||||
exit_val=$?
|
||||
if [[ $exit_val -ne 0 ]]; then
|
||||
warn_msg "[${_BBlue}${name}${_creset}] exit code (${_BRed}${exit_val}${_creset}) from ${_BGreen}${*}${_creset}"
|
||||
else
|
||||
info_msg "[${_BBlue}${name}${_creset}] exit code (${exit_val}) from ${_BGreen}${*}${_creset}"
|
||||
fi
|
||||
}
|
||||
|
||||
lxc_exec() {
|
||||
for i in "${CONTAINERS[@]}"; do
|
||||
if ! lxc_exists "$i"; then
|
||||
warn_msg "container ${_BBlue}$i${_creset} does not yet exists"
|
||||
else
|
||||
lxc_exec_cmd "${i}" "$@" | prefix_stdout "[${_BBlue}${i}${_creset}] "
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
lxc_init_all_containers() {
|
||||
rst_title "init all containers" section
|
||||
|
||||
local image_name
|
||||
local container_name
|
||||
|
||||
for ((i=0; i<${#LXC_SUITE[@]}; i+=2)); do
|
||||
lxc_init_container "${LXC_SUITE[i+1]}" "${LXC_HOST_PREFIX}-${LXC_SUITE[i+1]}"
|
||||
done
|
||||
}
|
||||
|
||||
lxc_config_all_containers() {
|
||||
rst_title "configure all containers" section
|
||||
|
||||
for i in "${CONTAINERS[@]}"; do
|
||||
lxc_config_container "${i}"
|
||||
done
|
||||
}
|
||||
|
||||
lxc_config_container() {
|
||||
info_msg "[${_BBlue}$1${_creset}] configure container ..."
|
||||
|
||||
info_msg "[${_BBlue}$1${_creset}] map uid/gid from host to container"
|
||||
# https://lxd.readthedocs.io/en/latest/userns-idmap/#custom-idmaps
|
||||
echo -e -n "uid $HOST_USER_ID 0\\ngid $HOST_GROUP_ID 0"\
|
||||
| lxc config set "$1" raw.idmap -
|
||||
|
||||
info_msg "[${_BBlue}$1${_creset}] share ${REPO_ROOT} (repo_share) from HOST into container"
|
||||
# https://lxd.readthedocs.io/en/latest/instances/#type-disk
|
||||
lxc config device add "$1" repo_share disk \
|
||||
source="${REPO_ROOT}" \
|
||||
path="${LXC_REPO_ROOT}" &>/dev/null
|
||||
# lxc config show "$1" && wait_key
|
||||
}
|
||||
|
||||
lxc_boilerplate_all_containers() {
|
||||
rst_title "run LXC boilerplate scripts" section
|
||||
|
||||
local boilerplate_script
|
||||
local image_name
|
||||
|
||||
for ((i=0; i<${#LXC_SUITE[@]}; i+=2)); do
|
||||
|
||||
image_name="${LXC_SUITE[i+1]}"
|
||||
boilerplate_script="${image_name}_boilerplate"
|
||||
boilerplate_script="${!boilerplate_script}"
|
||||
|
||||
lxc_install_boilerplate "${LXC_HOST_PREFIX}-${image_name}" "$boilerplate_script"
|
||||
|
||||
if [[ -z "${boilerplate_script}" ]]; then
|
||||
err_msg "[${_BBlue}${container_name}${_creset}] no boilerplate for image '${image_name}'"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
lxc_install_boilerplate() {
|
||||
|
||||
# usage: lxc_install_boilerplate <container-name> <string: shell commands ..>
|
||||
#
|
||||
# usage: lxc_install_boilerplate searx-archlinux "${archlinux_boilerplate}"
|
||||
|
||||
local container_name="$1"
|
||||
local boilerplate_script="$2"
|
||||
|
||||
info_msg "[${_BBlue}${container_name}${_creset}] init .."
|
||||
if lxc start -q "${container_name}" &>/dev/null; then
|
||||
sleep 5 # guest needs some time to come up and get an IP
|
||||
fi
|
||||
lxc_init_container_env "${container_name}"
|
||||
info_msg "[${_BBlue}${container_name}${_creset}] install /.lxcenv.mk .."
|
||||
cat <<EOF | lxc exec "${container_name}" -- bash | prefix_stdout "[${_BBlue}${container_name}${_creset}] "
|
||||
rm -f "/.lxcenv.mk"
|
||||
ln -s "${LXC_REPO_ROOT}/utils/makefile.lxc" "/.lxcenv.mk"
|
||||
ls -l "/.lxcenv.mk"
|
||||
EOF
|
||||
|
||||
info_msg "[${_BBlue}${container_name}${_creset}] run LXC boilerplate scripts .."
|
||||
if lxc start -q "${container_name}" &>/dev/null; then
|
||||
sleep 5 # guest needs some time to come up and get an IP
|
||||
fi
|
||||
if [[ -n "${boilerplate_script}" ]]; then
|
||||
echo "${boilerplate_script}" \
|
||||
| lxc exec "${container_name}" -- bash \
|
||||
| prefix_stdout "[${_BBlue}${container_name}${_creset}] "
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
main "$@"
|
||||
# ----------------------------------------------------------------------------
|
|
@ -1,12 +1,25 @@
|
|||
# -*- coding: utf-8; mode: makefile-gmake -*-
|
||||
|
||||
ifeq (,$(wildcard /.lxcenv.mk))
|
||||
PHONY += lxc-activate lxc-purge
|
||||
lxc-activate:
|
||||
@$(MAKE) -s -f /share/searx/utils/makefile.lxc lxc-activate
|
||||
lxc-purge:
|
||||
$(Q)rm -rf ./lxc
|
||||
else
|
||||
include /.lxcenv.mk
|
||||
endif
|
||||
|
||||
ifeq (,$(wildcard /.lxcenv.mk))
|
||||
make-help:
|
||||
else
|
||||
make-help: lxc-help
|
||||
endif
|
||||
@echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
|
||||
@echo ' make V=2 [targets] 2 => give reason for rebuild of target'
|
||||
|
||||
quiet_cmd_common_clean = CLEAN $@
|
||||
cmd_common_clean = \
|
||||
rm -rf tests/build ;\
|
||||
find . -name '*.orig' -exec rm -f {} + ;\
|
||||
find . -name '*.rej' -exec rm -f {} + ;\
|
||||
find . -name '*~' -exec rm -f {} + ;\
|
||||
|
@ -126,3 +139,4 @@ echo-cmd = $(if $($(quiet)cmd_$(1)),echo '$(call escsq,$($(quiet)cmd_$(1)))$(ech
|
|||
# printing commands
|
||||
cmd = @$(echo-cmd) $(cmd_$(1))
|
||||
|
||||
.PHONY: $(PHONY)
|
||||
|
|
29
utils/makefile.lxc
Normal file
29
utils/makefile.lxc
Normal file
|
@ -0,0 +1,29 @@
|
|||
# -*- coding: utf-8; mode: makefile-gmake -*-
|
||||
#
|
||||
# LXC environment
|
||||
# ===============
|
||||
#
|
||||
# To activate/deactivate LXC makefile environment in a container, set/unset link
|
||||
# from root '/.lxcenv.mk' to *this* file::
|
||||
#
|
||||
# sudo make ./utils/makefile.lxc lxc-activate
|
||||
# sudo make ./utils/makefile.lxc lxc-deactivate
|
||||
|
||||
LXC_ENV_FOLDER=lxc/$(shell hostname)/
|
||||
|
||||
lxc-help::
|
||||
@echo 'LXC: running in container LXC_ENV_FOLDER=$(LXC_ENV_FOLDER)'
|
||||
|
||||
# If not activated, serve target 'lxc-activate' ..
|
||||
ifeq (,$(wildcard /.lxcenv.mk))
|
||||
PHONY += lxc-activate
|
||||
lxc-activate:
|
||||
ln -s "$(abspath $(lastword $(MAKEFILE_LIST)))" "/.lxcenv.mk"
|
||||
else
|
||||
# .. and if activated, serve target 'lxc-deactivate'.
|
||||
PHONY += lxc-deactivate
|
||||
lxc-deactivate:
|
||||
rm /.lxcenv.mk
|
||||
endif
|
||||
|
||||
.PHONY: $(PHONY)
|
|
@ -8,9 +8,9 @@ export PYTHONPATH := $(SITE_PYTHON):$$PYTHONPATH
|
|||
export PY_ENV PYDIST PYBUILD
|
||||
|
||||
# folder where the python distribution takes place
|
||||
PYDIST ?= ./py_dist
|
||||
PYDIST = ./$(LXC_ENV_FOLDER)dist
|
||||
# folder where the python intermediate build files take place
|
||||
PYBUILD ?= ./py_build
|
||||
PYBUILD = ./$(LXC_ENV_FOLDER)build
|
||||
# python version to use
|
||||
PY ?=3
|
||||
# $(PYTHON) points to the python interpreter from the OS! The python from the
|
||||
|
@ -30,8 +30,7 @@ PYLINT_RC ?= .pylintrc
|
|||
TEST_FOLDER ?= ./tests
|
||||
TEST ?= .
|
||||
|
||||
VTENV_OPTS = "--no-site-packages"
|
||||
PY_ENV = ./local/py$(PY)
|
||||
PY_ENV = ./$(LXC_ENV_FOLDER)local/py$(PY)
|
||||
PY_ENV_BIN = $(PY_ENV)/bin
|
||||
PY_ENV_ACT = . $(PY_ENV_BIN)/activate
|
||||
|
||||
|
@ -41,6 +40,7 @@ ifeq ($(OS),Windows_NT)
|
|||
PY_ENV_ACT = $(PY_ENV_BIN)/activate
|
||||
endif
|
||||
|
||||
VTENV_OPTS ?=
|
||||
ifeq ($(PYTHON),python)
|
||||
VIRTUALENV = virtualenv
|
||||
else
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
# -*- coding: utf-8; mode: makefile-gmake -*-
|
||||
|
||||
export DOCS_FOLDER DOCS_BUILD DOCS_DIST BOOKS_FOLDER BOOKS_DIST
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= $(PY_ENV_BIN)/sphinx-build
|
||||
SPHINX_CONF ?= conf.py
|
||||
|
||||
DOCS_FOLDER ?= docs
|
||||
DOCS_BUILD ?= build/docs
|
||||
DOCS_DIST ?= dist/docs
|
||||
DOCS_FOLDER = ./docs
|
||||
DOCS_BUILD = ./$(LXC_ENV_FOLDER)build/docs
|
||||
DOCS_DIST = ./$(LXC_ENV_FOLDER)dist/docs
|
||||
GH_PAGES ?= gh-pages
|
||||
|
||||
BOOKS_FOLDER ?= docs
|
||||
BOOKS_DIST ?= dist/books
|
||||
BOOKS_FOLDER = ./docs
|
||||
BOOKS_DIST = ./$(LXC_ENV_FOLDER)dist/books
|
||||
|
||||
ifeq ($(KBUILD_VERBOSE),1)
|
||||
SPHINX_VERBOSE = "-v"
|
||||
|
@ -54,11 +56,13 @@ docs-help:
|
|||
# requirements
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
sphinx-doc: $(PY_ENV)
|
||||
sphinx-doc-prebuilds:: $(PY_ENV)
|
||||
|
||||
sphinx-doc: sphinx-doc-prebuilds
|
||||
@echo "PYENV installing Sphinx$(SPHINXVERS)"
|
||||
$(Q)$(PY_ENV_BIN)/pip install $(PIP_VERBOSE) 'Sphinx$(SPHINXVERS)'
|
||||
|
||||
sphinx-live: $(PY_ENV)
|
||||
sphinx-live: sphinx-doc-prebuilds
|
||||
@echo "PYENV installing Sphinx$(SPHINXVERS)"
|
||||
$(Q)$(PY_ENV_BIN)/pip install $(PIP_VERBOSE) 'Sphinx$(SPHINXVERS)' sphinx-autobuild
|
||||
|
||||
|
@ -113,7 +117,7 @@ quiet_cmd_sphinx_clean = CLEAN $@
|
|||
# targets
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# build PDF of whole documentation in: $(DOCS_DIST)/pdf
|
||||
# build PDF of whole documentation in: $(DOCS_DIST)/pdf
|
||||
|
||||
PHONY += sphinx-pdf
|
||||
sphinx-pdf: sphinx-latex
|
||||
|
@ -154,7 +158,7 @@ $(BOOKS_HTML): sphinx-doc | $(BOOKS_DIST)
|
|||
-b html \
|
||||
-c $(DOCS_FOLDER) \
|
||||
-d $(DOCS_BUILD)/books/$(patsubst books/%.html,%,$@)/.doctrees \
|
||||
$(patsubst books/%.html,%,$@) \
|
||||
$(BOOKS_FOLDER)/$(patsubst books/%.html,%,$@) \
|
||||
$(BOOKS_DIST)/$(patsubst books/%.html,%,$@)
|
||||
@echo "SPHINX $@ --> file://$(abspath $(BOOKS_DIST)/$(patsubst books/%.html,%,$@))"
|
||||
|
||||
|
@ -166,7 +170,7 @@ $(BOOKS_LIVE): sphinx-live | $(BOOKS_DIST)
|
|||
-b html \
|
||||
-c $(DOCS_FOLDER) \
|
||||
-d $(DOCS_BUILD)/books/$(patsubst books/%.live,%,$@)/.doctrees \
|
||||
$(patsubst books/%.live,%,$@) \
|
||||
$(BOOKS_FOLDER)/$(patsubst books/%.live,%,$@) \
|
||||
$(BOOKS_DIST)/$(patsubst books/%.live,%,$@)
|
||||
|
||||
$(BOOKS_PDF): %.pdf : %.latex
|
||||
|
@ -182,7 +186,7 @@ $(BOOKS_LATEX): sphinx-doc | $(BOOKS_DIST)
|
|||
-b latex \
|
||||
-c $(DOCS_FOLDER) \
|
||||
-d $(DOCS_BUILD)/books/$(patsubst books/%.latex,%,$@)/.doctrees \
|
||||
$(patsubst books/%.latex,%,$@) \
|
||||
$(BOOKS_FOLDER)/$(patsubst books/%.latex,%,$@) \
|
||||
$(DOCS_BUILD)/latex/$(patsubst books/%.latex,%,$@)
|
||||
@echo "SPHINX $@ --> file://$(abspath $(DOCS_BUILD)/latex/$(patsubst books/%.latex,%,$@))"
|
||||
|
||||
|
|
546
utils/morty.sh
Executable file
546
utils/morty.sh
Executable file
|
@ -0,0 +1,546 @@
|
|||
#!/usr/bin/env bash
|
||||
# -*- coding: utf-8; mode: sh indent-tabs-mode: nil -*-
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# shellcheck source=utils/lib.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
||||
# shellcheck source=utils/brand.env
|
||||
source "${REPO_ROOT}/utils/brand.env"
|
||||
source_dot_config
|
||||
SEARX_URL="${PUBLIC_URL:-http://$(uname -n)/searx}"
|
||||
source "${REPO_ROOT}/utils/lxc-searx.env"
|
||||
in_container && lxc_set_suite_env
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# config
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
MORTY_LISTEN="${MORTY_LISTEN:-127.0.0.1:3000}"
|
||||
PUBLIC_URL_PATH_MORTY="${PUBLIC_URL_PATH_MORTY:-/morty/}"
|
||||
|
||||
PUBLIC_URL_MORTY="${PUBLIC_URL_MORTY:-$(echo "$SEARX_URL" | sed -e's,^\(.*://[^/]*\).*,\1,g')${PUBLIC_URL_PATH_MORTY}}"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
MORTY_TIMEOUT=5
|
||||
|
||||
SERVICE_NAME="morty"
|
||||
SERVICE_USER="${SERVICE_USER:-${SERVICE_NAME}}"
|
||||
SERVICE_HOME_BASE="${SERVICE_HOME_BASE:-/usr/local}"
|
||||
SERVICE_HOME="${SERVICE_HOME_BASE}/${SERVICE_USER}"
|
||||
SERVICE_SYSTEMD_UNIT="${SYSTEMD_UNITS}/${SERVICE_NAME}.service"
|
||||
# shellcheck disable=SC2034
|
||||
SERVICE_GROUP="${SERVICE_USER}"
|
||||
# shellcheck disable=SC2034
|
||||
SERVICE_ENV_DEBUG=false
|
||||
|
||||
GO_ENV="${SERVICE_HOME}/.go_env"
|
||||
GO_PKG_URL="https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz"
|
||||
GO_TAR=$(basename "$GO_PKG_URL")
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
CONFIG_FILES=()
|
||||
|
||||
# Apache Settings
|
||||
|
||||
APACHE_MORTY_SITE="morty.conf"
|
||||
NGINX_MORTY_SITE="morty.conf"
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
usage() {
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# shellcheck disable=SC1117
|
||||
cat <<EOF
|
||||
usage::
|
||||
$(basename "$0") shell
|
||||
$(basename "$0") install [all|user]
|
||||
$(basename "$0") update [morty]
|
||||
$(basename "$0") remove [all]
|
||||
$(basename "$0") activate [service]
|
||||
$(basename "$0") deactivate [service]
|
||||
$(basename "$0") inspect [service]
|
||||
$(basename "$0") option [debug-on|debug-off|new-key]
|
||||
$(basename "$0") apache [install|remove]
|
||||
$(basename "$0") nginx [install|remove]
|
||||
$(basename "$0") info [searx]
|
||||
|
||||
shell
|
||||
start interactive shell from user ${SERVICE_USER}
|
||||
install / remove
|
||||
all: complete setup of morty service
|
||||
user: add/remove service user '$SERVICE_USER' ($SERVICE_HOME)
|
||||
update morty
|
||||
Update morty installation ($SERVICE_HOME)
|
||||
activate service
|
||||
activate and start service daemon (systemd unit)
|
||||
deactivate service
|
||||
stop and deactivate service daemon (systemd unit)
|
||||
inspect service
|
||||
show service status and log
|
||||
option
|
||||
set one of the available options
|
||||
:new-key: set new morty key
|
||||
apache : ${PUBLIC_URL_MORTY}
|
||||
:install: apache site with a reverse proxy (ProxyPass)
|
||||
:remove: apache site ${APACHE_MORTY_SITE}
|
||||
nginx (${PUBLIC_URL_MORTY})
|
||||
:install: nginx site with a reverse proxy (ProxyPass)
|
||||
:remove: nginx site ${NGINX_MORTY_SITE}
|
||||
|
||||
If needed, set the environment variables in the '${DOT_CONFIG#"$REPO_ROOT/"}' file::
|
||||
PUBLIC_URL_MORTY: ${PUBLIC_URL_MORTY}
|
||||
MORTY_LISTEN: ${MORTY_LISTEN}
|
||||
SERVICE_USER: ${SERVICE_USER}
|
||||
EOF
|
||||
if in_container; then
|
||||
# in containers the service is listening on 0.0.0.0 (see lxc-searx.env)
|
||||
for ip in $(global_IPs) ; do
|
||||
if [[ $ip =~ .*:.* ]]; then
|
||||
echo " container URL (IPv6): http://[${ip#*|}]:3000/"
|
||||
else
|
||||
# IPv4:
|
||||
echo " container URL (IPv4): http://${ip#*|}:3000/"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
echo
|
||||
info_searx
|
||||
|
||||
[[ -n ${1} ]] && err_msg "$1"
|
||||
}
|
||||
|
||||
info_searx() {
|
||||
# shellcheck disable=SC1117
|
||||
cat <<EOF
|
||||
To activate result and image proxy in searx, edit settings.yml (read:
|
||||
${DOCS_URL}/admin/morty.html)::
|
||||
result_proxy:
|
||||
url : ${PUBLIC_URL_MORTY}
|
||||
server:
|
||||
image_proxy : True
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
required_commands \
|
||||
sudo install git wget curl \
|
||||
|| exit
|
||||
|
||||
local _usage="ERROR: unknown or missing $1 command $2"
|
||||
|
||||
case $1 in
|
||||
--getenv) var="$2"; echo "${!var}"; exit 0;;
|
||||
-h|--help) usage; exit 0;;
|
||||
|
||||
shell)
|
||||
sudo_or_exit
|
||||
interactive_shell "${SERVICE_USER}"
|
||||
;;
|
||||
inspect)
|
||||
case $2 in
|
||||
service)
|
||||
sudo_or_exit
|
||||
inspect_service
|
||||
;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
install)
|
||||
rst_title "$SERVICE_NAME" part
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
all) install_all ;;
|
||||
user) assert_user ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
update)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
morty) update_morty ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
remove)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
all) remove_all;;
|
||||
user) drop_service_account "${SERVICE_USER}" ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
activate)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
service) systemd_activate_service "${SERVICE_NAME}" ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
deactivate)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
service) systemd_deactivate_service "${SERVICE_NAME}" ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
apache)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
install) install_apache_site ;;
|
||||
remove) remove_apache_site ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
nginx)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
install) install_nginx_site ;;
|
||||
remove) remove_nginx_site ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
info)
|
||||
case $2 in
|
||||
searx) info_searx ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
option)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
new-key) set_new_key ;;
|
||||
debug-on) enable_debug ;;
|
||||
debug-off) disable_debug ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
doc) rst-doc ;;
|
||||
*) usage "ERROR: unknown or missing command $1"; exit 42;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_all() {
|
||||
|
||||
MORTY_KEY="$(head -c 32 /dev/urandom | base64)"
|
||||
|
||||
rst_title "Install $SERVICE_NAME (service)"
|
||||
assert_user
|
||||
wait_key
|
||||
install_go "${GO_PKG_URL}" "${GO_TAR}" "${SERVICE_USER}"
|
||||
wait_key
|
||||
install_morty
|
||||
wait_key
|
||||
systemd_install_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"
|
||||
wait_key
|
||||
if ! service_is_available "http://${MORTY_LISTEN}" ; then
|
||||
err_msg "Morty does not listening on: http://${MORTY_LISTEN}"
|
||||
fi
|
||||
if apache_is_installed; then
|
||||
info_msg "Apache is installed on this host."
|
||||
if ask_yn "Do you want to install a reverse proxy (ProxyPass)" Yn; then
|
||||
install_apache_site
|
||||
fi
|
||||
elif nginx_is_installed; then
|
||||
info_msg "nginx is installed on this host."
|
||||
if ask_yn "Do you want to install a reverse proxy (ProxyPass)" Yn; then
|
||||
install_nginx_site
|
||||
fi
|
||||
fi
|
||||
info_searx
|
||||
if ask_yn "Add image and result proxy to searx settings.yml?" Yn; then
|
||||
"${REPO_ROOT}/utils/searx.sh" option result-proxy "${PUBLIC_URL_MORTY}" "${MORTY_KEY}"
|
||||
"${REPO_ROOT}/utils/searx.sh" option image-proxy-on
|
||||
fi
|
||||
|
||||
if ask_yn "Do you want to inspect the installation?" Ny; then
|
||||
inspect_service
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
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 systemd_remove_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"; then
|
||||
drop_service_account "${SERVICE_USER}"
|
||||
fi
|
||||
}
|
||||
|
||||
assert_user() {
|
||||
rst_title "user $SERVICE_USER" section
|
||||
echo
|
||||
tee_stderr 1 <<EOF | bash | prefix_stdout
|
||||
useradd --shell /bin/bash --system \
|
||||
--home-dir "$SERVICE_HOME" \
|
||||
--comment 'Web content sanitizer proxy' $SERVICE_USER
|
||||
mkdir "$SERVICE_HOME"
|
||||
chown -R "$SERVICE_GROUP:$SERVICE_GROUP" "$SERVICE_HOME"
|
||||
groups $SERVICE_USER
|
||||
EOF
|
||||
SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME)"
|
||||
export SERVICE_HOME
|
||||
echo "export SERVICE_HOME=$SERVICE_HOME"
|
||||
|
||||
cat > "$GO_ENV" <<EOF
|
||||
export GOPATH=\$HOME/go-apps
|
||||
export PATH=\$PATH:\$HOME/local/go/bin:\$GOPATH/bin
|
||||
EOF
|
||||
echo "Environment $GO_ENV has been setup."
|
||||
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER"
|
||||
grep -qFs -- 'source $GO_ENV' ~/.profile || echo 'source $GO_ENV' >> ~/.profile
|
||||
EOF
|
||||
}
|
||||
|
||||
morty_is_installed() {
|
||||
[[ -f $SERVICE_HOME/go-apps/bin/morty ]]
|
||||
}
|
||||
|
||||
_svcpr=" ${_Yellow}|${SERVICE_USER}|${_creset} "
|
||||
|
||||
install_morty() {
|
||||
rst_title "Install morty in user's ~/go-apps" section
|
||||
echo
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
|
||||
go get -v -u github.com/asciimoo/morty
|
||||
EOF
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
|
||||
cd \$GOPATH/src/github.com/asciimoo/morty
|
||||
go test
|
||||
go test -benchmem -bench .
|
||||
EOF
|
||||
}
|
||||
|
||||
update_morty() {
|
||||
rst_title "Update morty" section
|
||||
echo
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
|
||||
go get -v -u github.com/asciimoo/morty
|
||||
EOF
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
|
||||
cd \$GOPATH/src/github.com/asciimoo/morty
|
||||
go test
|
||||
go test -benchmem -bench .
|
||||
EOF
|
||||
}
|
||||
|
||||
set_service_env_debug() {
|
||||
|
||||
# usage: set_service_env_debug [false|true]
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
local SERVICE_ENV_DEBUG="${1:-false}"
|
||||
if systemd_remove_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"; then
|
||||
systemd_install_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"
|
||||
fi
|
||||
}
|
||||
|
||||
inspect_service() {
|
||||
|
||||
rst_title "service status & log"
|
||||
|
||||
cat <<EOF
|
||||
|
||||
sourced ${DOT_CONFIG#"$REPO_ROOT/"} :
|
||||
|
||||
MORTY_LISTEN : ${MORTY_LISTEN}
|
||||
|
||||
EOF
|
||||
|
||||
if service_account_is_available "$SERVICE_USER"; then
|
||||
info_msg "service account $SERVICE_USER available."
|
||||
else
|
||||
err_msg "service account $SERVICE_USER not available!"
|
||||
fi
|
||||
if go_is_available "$SERVICE_USER"; then
|
||||
info_msg "~$SERVICE_USER: go is installed"
|
||||
else
|
||||
err_msg "~$SERVICE_USER: go is not installed"
|
||||
fi
|
||||
if morty_is_installed; then
|
||||
info_msg "~$SERVICE_USER: morty app is installed"
|
||||
else
|
||||
err_msg "~$SERVICE_USER: morty app is not installed!"
|
||||
fi
|
||||
|
||||
if ! service_is_available "http://${MORTY_LISTEN}" ; then
|
||||
err_msg "Morty does not listening on: http://${MORTY_LISTEN}"
|
||||
echo -e "${_Green}stop with [${_BCyan}CTRL-C${_Green}] or .."
|
||||
wait_key
|
||||
fi
|
||||
|
||||
if ! service_is_available "${PUBLIC_URL_MORTY}"; then
|
||||
warn_msg "Public service at ${PUBLIC_URL_MORTY} is not available!"
|
||||
if ! in_container; then
|
||||
warn_msg "Check if public name is correct and routed or use the public IP from above."
|
||||
fi
|
||||
fi
|
||||
|
||||
if in_container; then
|
||||
lxc_suite_info
|
||||
else
|
||||
info_msg "public URL --> ${PUBLIC_URL_MORTY}"
|
||||
info_msg "morty URL --> http://${MORTY_LISTEN}"
|
||||
fi
|
||||
|
||||
local _debug_on
|
||||
if ask_yn "Enable morty debug mode (needs reinstall of systemd service)?"; then
|
||||
enable_debug
|
||||
_debug_on=1
|
||||
else
|
||||
systemctl --no-pager -l status "${SERVICE_NAME}"
|
||||
fi
|
||||
echo
|
||||
|
||||
# shellcheck disable=SC2059
|
||||
printf "// use ${_BCyan}CTRL-C${_creset} to stop monitoring the log"
|
||||
read -r -s -n1 -t 5
|
||||
echo
|
||||
while true; do
|
||||
trap break 2
|
||||
journalctl -f -u "${SERVICE_NAME}"
|
||||
done
|
||||
|
||||
if [[ $_debug_on == 1 ]]; then
|
||||
FORCE_SELECTION=Y disable_debug
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
enable_debug() {
|
||||
warn_msg "Do not enable debug in production enviroments!!"
|
||||
info_msg "Enabling debug option needs to reinstall systemd service!"
|
||||
set_service_env_debug true
|
||||
}
|
||||
|
||||
disable_debug() {
|
||||
info_msg "Disabling debug option needs to reinstall systemd service!"
|
||||
set_service_env_debug false
|
||||
}
|
||||
|
||||
|
||||
set_new_key() {
|
||||
rst_title "Set morty key"
|
||||
echo
|
||||
|
||||
MORTY_KEY="$(head -c 32 /dev/urandom | base64)"
|
||||
info_msg "morty key: '${MORTY_KEY}'"
|
||||
|
||||
warn_msg "this will need to reinstall services .."
|
||||
MSG="${_Green}press any [${_BCyan}KEY${_Green}] to continue // stop with [${_BCyan}CTRL-C${_creset}]" wait_key
|
||||
|
||||
systemd_install_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"
|
||||
"${REPO_ROOT}/utils/searx.sh" option result-proxy "${PUBLIC_URL_MORTY}" "${MORTY_KEY}"
|
||||
"${REPO_ROOT}/utils/searx.sh" option image-proxy-on
|
||||
}
|
||||
|
||||
|
||||
install_apache_site() {
|
||||
|
||||
rst_title "Install Apache site $APACHE_MORTY_SITE"
|
||||
|
||||
rst_para "\
|
||||
This installs a reverse proxy (ProxyPass) into apache site (${APACHE_MORTY_SITE})"
|
||||
|
||||
! apache_is_installed && err_msg "Apache is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
else
|
||||
install_apache
|
||||
fi
|
||||
|
||||
apache_install_site "${APACHE_MORTY_SITE}"
|
||||
|
||||
info_msg "testing public url .."
|
||||
if ! service_is_available "${PUBLIC_URL_MORTY}"; then
|
||||
err_msg "Public service at ${PUBLIC_URL_MORTY} is not available!"
|
||||
fi
|
||||
}
|
||||
|
||||
remove_apache_site() {
|
||||
|
||||
rst_title "Remove Apache site $APACHE_MORTY_SITE"
|
||||
|
||||
rst_para "\
|
||||
This removes apache site ${APACHE_MORTY_SITE}."
|
||||
|
||||
! apache_is_installed && err_msg "Apache is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
fi
|
||||
|
||||
apache_remove_site "$APACHE_MORTY_SITE"
|
||||
}
|
||||
|
||||
install_nginx_site() {
|
||||
|
||||
rst_title "Install nginx site $NGINX_MORTY_SITE"
|
||||
|
||||
rst_para "\
|
||||
This installs a reverse proxy (ProxyPass) into nginx site (${NGINX_MORTY_SITE})"
|
||||
|
||||
! nginx_is_installed && err_msg "nginx is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
else
|
||||
install_nginx
|
||||
fi
|
||||
|
||||
"${REPO_ROOT}/utils/searx.sh" install uwsgi
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
SEARX_SRC=$("${REPO_ROOT}/utils/searx.sh" --getenv SEARX_SRC)
|
||||
# shellcheck disable=SC2034
|
||||
SEARX_URL_PATH=$("${REPO_ROOT}/utils/searx.sh" --getenv SEARX_URL_PATH)
|
||||
nginx_install_app "${NGINX_MORTY_SITE}"
|
||||
|
||||
info_msg "testing public url .."
|
||||
if ! service_is_available "${PUBLIC_URL_MORTY}"; then
|
||||
err_msg "Public service at ${PUBLIC_URL_MORTY} is not available!"
|
||||
fi
|
||||
}
|
||||
|
||||
remove_nginx_site() {
|
||||
|
||||
rst_title "Remove nginx site $NGINX_MORTY_SITE"
|
||||
|
||||
rst_para "\
|
||||
This removes nginx site ${NGINX_MORTY_SITE}."
|
||||
|
||||
! nginx_is_installed && err_msg "nginx is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
fi
|
||||
|
||||
nginx_remove_site "$NGINX_MORTY_SITE"
|
||||
|
||||
}
|
||||
|
||||
rst-doc() {
|
||||
|
||||
eval "echo \"$(< "${REPO_ROOT}/docs/build-templates/morty.rst")\""
|
||||
|
||||
echo -e "\n.. START install systemd unit"
|
||||
cat <<EOF
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: systemd
|
||||
|
||||
.. code:: bash
|
||||
|
||||
EOF
|
||||
eval "echo \"$(< "${TEMPLATES}/${SERVICE_SYSTEMD_UNIT}")\"" | prefix_stdout " "
|
||||
echo -e "\n.. END install systemd unit"
|
||||
|
||||
# for DIST_NAME in ubuntu-20.04 arch fedora; do
|
||||
# (
|
||||
# DIST_ID=${DIST_NAME%-*}
|
||||
# DIST_VERS=${DIST_NAME#*-}
|
||||
# [[ $DIST_VERS =~ $DIST_ID ]] && DIST_VERS=
|
||||
# # ...
|
||||
# )
|
||||
# done
|
||||
}
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
main "$@"
|
||||
# ----------------------------------------------------------------------------
|
869
utils/searx.sh
Executable file
869
utils/searx.sh
Executable file
|
@ -0,0 +1,869 @@
|
|||
#!/usr/bin/env bash
|
||||
# -*- coding: utf-8; mode: sh indent-tabs-mode: nil -*-
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# shellcheck disable=SC2001
|
||||
|
||||
# shellcheck source=utils/lib.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
||||
# shellcheck source=utils/brand.env
|
||||
source "${REPO_ROOT}/utils/brand.env"
|
||||
source_dot_config
|
||||
source "${REPO_ROOT}/utils/lxc-searx.env"
|
||||
in_container && lxc_set_suite_env
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# config
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
PUBLIC_URL="${PUBLIC_URL:-http://$(uname -n)/searx}"
|
||||
|
||||
SEARX_INTERNAL_HTTP="${SEARX_INTERNAL_HTTP:-127.0.0.1:8888}"
|
||||
|
||||
SEARX_URL_PATH="${SEARX_URL_PATH:-$(echo "${PUBLIC_URL}" \
|
||||
| sed -e 's,^.*://[^/]*\(/.*\),\1,g')}"
|
||||
[[ "${SEARX_URL_PATH}" == "${PUBLIC_URL}" ]] && SEARX_URL_PATH=/
|
||||
SEARX_INSTANCE_NAME="${SEARX_INSTANCE_NAME:-searx@$(echo "$PUBLIC_URL" \
|
||||
| sed -e 's,^.*://\([^\:/]*\).*,\1,g') }"
|
||||
|
||||
SERVICE_NAME="searx"
|
||||
SERVICE_USER="${SERVICE_USER:-${SERVICE_NAME}}"
|
||||
SERVICE_HOME_BASE="${SERVICE_HOME_BASE:-/usr/local}"
|
||||
SERVICE_HOME="${SERVICE_HOME_BASE}/${SERVICE_USER}"
|
||||
# shellcheck disable=SC2034
|
||||
SERVICE_GROUP="${SERVICE_USER}"
|
||||
|
||||
GIT_BRANCH="${GIT_BRANCH:-master}"
|
||||
SEARX_PYENV="${SERVICE_HOME}/searx-pyenv"
|
||||
SEARX_SRC="${SERVICE_HOME}/searx-src"
|
||||
SEARX_SETTINGS_PATH="/etc/searx/settings.yml"
|
||||
SEARX_UWSGI_APP="searx.ini"
|
||||
# shellcheck disable=SC2034
|
||||
SEARX_UWSGI_SOCKET="/run/uwsgi/app/searx/socket"
|
||||
|
||||
# apt packages
|
||||
SEARX_PACKAGES_debian="\
|
||||
virtualenv python3-dev python3-babel python3-venv
|
||||
uwsgi uwsgi-plugin-python3
|
||||
git build-essential libxslt-dev zlib1g-dev libffi-dev libssl-dev
|
||||
shellcheck"
|
||||
|
||||
BUILD_PACKAGES_debian="\
|
||||
firefox graphviz imagemagick texlive-xetex librsvg2-bin
|
||||
texlive-latex-recommended texlive-extra-utils ttf-dejavu
|
||||
latexmk"
|
||||
|
||||
# pacman packages
|
||||
SEARX_PACKAGES_arch="\
|
||||
python-virtualenv python python-pip python-lxml python-babel
|
||||
uwsgi uwsgi-plugin-python
|
||||
git base-devel libxml2
|
||||
shellcheck"
|
||||
|
||||
BUILD_PACKAGES_arch="\
|
||||
firefox graphviz imagemagick texlive-bin extra/librsvg
|
||||
texlive-core texlive-latexextra ttf-dejavu"
|
||||
|
||||
# dnf packages
|
||||
SEARX_PACKAGES_fedora="\
|
||||
virtualenv python python-pip python-lxml python-babel
|
||||
uwsgi uwsgi-plugin-python3
|
||||
git @development-tools libxml2
|
||||
ShellCheck"
|
||||
|
||||
BUILD_PACKAGES_fedora="\
|
||||
firefox graphviz graphviz-gd ImageMagick librsvg2-tools
|
||||
texlive-xetex-bin texlive-collection-fontsrecommended
|
||||
texlive-collection-latex dejavu-sans-fonts dejavu-serif-fonts
|
||||
dejavu-sans-mono-fonts"
|
||||
|
||||
case $DIST_ID-$DIST_VERS in
|
||||
ubuntu-16.04|ubuntu-18.04)
|
||||
SEARX_PACKAGES="${SEARX_PACKAGES_debian}"
|
||||
BUILD_PACKAGES="${BUILD_PACKAGES_debian}"
|
||||
APACHE_PACKAGES="$APACHE_PACKAGES libapache2-mod-proxy-uwsgi"
|
||||
;;
|
||||
ubuntu-20.04)
|
||||
# https://askubuntu.com/a/1224710
|
||||
SEARX_PACKAGES="${SEARX_PACKAGES_debian} python-is-python3"
|
||||
BUILD_PACKAGES="${BUILD_PACKAGES_debian}"
|
||||
;;
|
||||
ubuntu-*|debian-*)
|
||||
SEARX_PACKAGES="${SEARX_PACKAGES_debian}"
|
||||
BUILD_PACKAGES="${BUILD_PACKAGES_debian}"
|
||||
;;
|
||||
arch-*)
|
||||
SEARX_PACKAGES="${SEARX_PACKAGES_arch}"
|
||||
BUILD_PACKAGES="${BUILD_PACKAGES_arch}"
|
||||
;;
|
||||
fedora-*)
|
||||
SEARX_PACKAGES="${SEARX_PACKAGES_fedora}"
|
||||
BUILD_PACKAGES="${BUILD_PACKAGES_fedora}"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Apache Settings
|
||||
APACHE_SEARX_SITE="searx.conf"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
CONFIG_FILES=(
|
||||
"${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP}"
|
||||
)
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
CONFIG_BACKUP_ENCRYPTED=(
|
||||
"${SEARX_SETTINGS_PATH}"
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
usage() {
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# shellcheck disable=SC1117
|
||||
cat <<EOF
|
||||
usage::
|
||||
$(basename "$0") shell
|
||||
$(basename "$0") install [all|user|searx-src|pyenv|uwsgi|packages|buildhost]
|
||||
$(basename "$0") update [searx]
|
||||
$(basename "$0") remove [all|user|pyenv|searx-src]
|
||||
$(basename "$0") activate [service]
|
||||
$(basename "$0") deactivate [service]
|
||||
$(basename "$0") inspect [service]
|
||||
$(basename "$0") option [debug-[on|off]|image-proxy-[on|off]|result-proxy <url> <key>]
|
||||
$(basename "$0") apache [install|remove]
|
||||
|
||||
shell
|
||||
start interactive shell from user ${SERVICE_USER}
|
||||
install / remove
|
||||
:all: complete (de-) installation of searx service
|
||||
:user: add/remove service user '$SERVICE_USER' ($SERVICE_HOME)
|
||||
:searx-src: clone $GIT_URL
|
||||
:pyenv: create/remove virtualenv (python) in $SEARX_PYENV
|
||||
:uwsgi: install searx uWSGI application
|
||||
:settings: reinstall settings from ${REPO_ROOT}/searx/settings.yml
|
||||
:packages: install needed packages from OS package manager
|
||||
:buildhost: install packages from OS package manager needed by buildhosts
|
||||
update searx
|
||||
Update searx installation ($SERVICE_HOME)
|
||||
activate service
|
||||
activate and start service daemon (systemd unit)
|
||||
deactivate service
|
||||
stop and deactivate service daemon (systemd unit)
|
||||
inspect service
|
||||
run some small tests and inspect service's status and log
|
||||
option
|
||||
set one of the available options
|
||||
apache
|
||||
:install: apache site with the searx uwsgi app
|
||||
:remove: apache site ${APACHE_FILTRON_SITE}
|
||||
|
||||
searx settings: ${SEARX_SETTINGS_PATH}
|
||||
|
||||
If needed, set PUBLIC_URL of your WEB service in the '${DOT_CONFIG#"$REPO_ROOT/"}' file::
|
||||
PUBLIC_URL : ${PUBLIC_URL}
|
||||
SEARX_INSTANCE_NAME : ${SEARX_INSTANCE_NAME}
|
||||
SERVICE_USER : ${SERVICE_USER}
|
||||
SEARX_INTERNAL_HTTP : http://${SEARX_INTERNAL_HTTP}
|
||||
EOF
|
||||
if in_container; then
|
||||
# searx is listening on 127.0.0.1 and not available from outside container
|
||||
# in containers the service is listening on 0.0.0.0 (see lxc-searx.env)
|
||||
echo -e "${_BBlack}HINT:${_creset} searx only listen on loopback device" \
|
||||
"${_BBlack}inside${_creset} the container."
|
||||
for ip in $(global_IPs) ; do
|
||||
if [[ $ip =~ .*:.* ]]; then
|
||||
echo " container (IPv6): [${ip#*|}]"
|
||||
else
|
||||
# IPv4:
|
||||
echo " container (IPv4): ${ip#*|}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
[[ -n ${1} ]] && err_msg "$1"
|
||||
}
|
||||
|
||||
main() {
|
||||
required_commands \
|
||||
sudo systemctl install git wget curl \
|
||||
|| exit
|
||||
|
||||
local _usage="unknown or missing $1 command $2"
|
||||
|
||||
case $1 in
|
||||
--getenv) var="$2"; echo "${!var}"; exit 0;;
|
||||
-h|--help) usage; exit 0;;
|
||||
shell)
|
||||
sudo_or_exit
|
||||
interactive_shell "${SERVICE_USER}"
|
||||
;;
|
||||
inspect)
|
||||
case $2 in
|
||||
service)
|
||||
sudo_or_exit
|
||||
inspect_service
|
||||
;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
install)
|
||||
rst_title "$SEARX_INSTANCE_NAME" part
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
all) install_all ;;
|
||||
user) assert_user ;;
|
||||
pyenv) create_pyenv ;;
|
||||
searx-src) clone_searx ;;
|
||||
settings) install_settings ;;
|
||||
uwsgi)
|
||||
install_searx_uwsgi
|
||||
if ! service_is_available "http://${SEARX_INTERNAL_HTTP}"; then
|
||||
err_msg "URL http://${SEARX_INTERNAL_HTTP} not available, check searx & uwsgi setup!"
|
||||
fi
|
||||
;;
|
||||
packages)
|
||||
pkg_install "$SEARX_PACKAGES"
|
||||
;;
|
||||
buildhost)
|
||||
pkg_install "$SEARX_PACKAGES"
|
||||
pkg_install "$BUILD_PACKAGES"
|
||||
;;
|
||||
*) 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) drop_service_account "${SERVICE_USER}";;
|
||||
pyenv) remove_pyenv ;;
|
||||
searx-src) remove_searx ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
activate)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
service)
|
||||
activate_service ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
deactivate)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
service) deactivate_service ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
option)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
debug-on) echo; enable_debug ;;
|
||||
debug-off) echo; disable_debug ;;
|
||||
result-proxy) set_result_proxy "$3" "$4" ;;
|
||||
image-proxy-on) enable_image_proxy ;;
|
||||
image-proxy-off) disable_image_proxy ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
apache)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
install) install_apache_site ;;
|
||||
remove) remove_apache_site ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
doc) rst-doc;;
|
||||
*) usage "unknown or missing command $1"; exit 42;;
|
||||
esac
|
||||
}
|
||||
|
||||
_service_prefix=" ${_Yellow}|$SERVICE_USER|${_creset} "
|
||||
|
||||
install_all() {
|
||||
rst_title "Install $SEARX_INSTANCE_NAME (service)"
|
||||
pkg_install "$SEARX_PACKAGES"
|
||||
wait_key
|
||||
assert_user
|
||||
wait_key
|
||||
clone_searx
|
||||
wait_key
|
||||
create_pyenv
|
||||
wait_key
|
||||
install_settings
|
||||
wait_key
|
||||
test_local_searx
|
||||
wait_key
|
||||
install_searx_uwsgi
|
||||
if ! service_is_available "http://${SEARX_INTERNAL_HTTP}"; then
|
||||
err_msg "URL http://${SEARX_INTERNAL_HTTP} not available, check searx & uwsgi setup!"
|
||||
fi
|
||||
if ask_yn "Do you want to inspect the installation?" Ny; then
|
||||
inspect_service
|
||||
fi
|
||||
}
|
||||
|
||||
update_searx() {
|
||||
rst_title "Update searx instance"
|
||||
|
||||
echo
|
||||
tee_stderr 0.3 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
cd ${SEARX_SRC}
|
||||
git checkout -B "$GIT_BRANCH"
|
||||
git pull
|
||||
pip install -U pip
|
||||
pip install -U setuptools
|
||||
pip install -U wheel
|
||||
pip install -U -e .
|
||||
EOF
|
||||
install_settings
|
||||
uWSGI_restart "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
remove_all() {
|
||||
rst_title "De-Install $SEARX_INSTANCE_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 $SEARX_INSTANCE_NAME?"; then
|
||||
return
|
||||
fi
|
||||
remove_searx_uwsgi
|
||||
drop_service_account "${SERVICE_USER}"
|
||||
remove_settings
|
||||
wait_key
|
||||
if service_is_available "${PUBLIC_URL}"; then
|
||||
MSG="** Don't forgett to remove your public site! (${PUBLIC_URL}) **" wait_key 10
|
||||
fi
|
||||
}
|
||||
|
||||
assert_user() {
|
||||
rst_title "user $SERVICE_USER" section
|
||||
echo
|
||||
tee_stderr 1 <<EOF | bash | prefix_stdout
|
||||
useradd --shell /bin/bash --system \
|
||||
--home-dir "$SERVICE_HOME" \
|
||||
--comment 'Privacy-respecting metasearch engine' $SERVICE_USER
|
||||
mkdir "$SERVICE_HOME"
|
||||
chown -R "$SERVICE_GROUP:$SERVICE_GROUP" "$SERVICE_HOME"
|
||||
groups $SERVICE_USER
|
||||
EOF
|
||||
#SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME)"
|
||||
#export SERVICE_HOME
|
||||
#echo "export SERVICE_HOME=$SERVICE_HOME"
|
||||
}
|
||||
|
||||
clone_is_available() {
|
||||
[[ -f "$SEARX_SRC/.git/config" ]]
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2164
|
||||
clone_searx() {
|
||||
rst_title "Clone searx sources" section
|
||||
echo
|
||||
if ! sudo -i -u "$SERVICE_USER" ls -d "$REPO_ROOT" > /dev/null; then
|
||||
die 42 "user '$SERVICE_USER' missed read permission: $REPO_ROOT"
|
||||
fi
|
||||
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 "$REPO_ROOT" "$SEARX_SRC" \
|
||||
"$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 remote set-url origin ${GIT_URL}
|
||||
git config user.email "$ADMIN_EMAIL"
|
||||
git config user.name "$ADMIN_NAME"
|
||||
git config --list
|
||||
EOF
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
install_settings() {
|
||||
rst_title "${SEARX_SETTINGS_PATH}" section
|
||||
if ! clone_is_available; then
|
||||
err_msg "you have to install searx first"
|
||||
exit 42
|
||||
fi
|
||||
mkdir -p "$(dirname ${SEARX_SETTINGS_PATH})"
|
||||
|
||||
if [[ ! -f ${SEARX_SETTINGS_PATH} ]]; then
|
||||
info_msg "install settings ${REPO_ROOT}/searx/settings.yml"
|
||||
info_msg " --> ${SEARX_SETTINGS_PATH}"
|
||||
cp "${REPO_ROOT}/searx/settings.yml" "${SEARX_SETTINGS_PATH}"
|
||||
configure_searx
|
||||
return
|
||||
fi
|
||||
|
||||
rst_para "Diff between origin's setting file (+) and current (-):"
|
||||
echo
|
||||
$DIFF_CMD "${SEARX_SETTINGS_PATH}" "${SEARX_SRC}/searx/settings.yml"
|
||||
|
||||
local action
|
||||
choose_one action "What should happen to the settings file? " \
|
||||
"keep configuration unchanged" \
|
||||
"use origin settings" \
|
||||
"start interactiv shell"
|
||||
case $action in
|
||||
"keep configuration unchanged")
|
||||
info_msg "leave settings file unchanged"
|
||||
;;
|
||||
"use origin settings")
|
||||
backup_file "${SEARX_SETTINGS_PATH}"
|
||||
info_msg "install origin settings"
|
||||
cp "${SEARX_SRC}/searx/settings.yml" "${SEARX_SETTINGS_PATH}"
|
||||
;;
|
||||
"start interactiv shell")
|
||||
backup_file "${SEARX_SETTINGS_PATH}"
|
||||
echo -e "// exit with [${_BCyan}CTRL-D${_creset}]"
|
||||
sudo -H -i
|
||||
rst_para 'Diff between new setting file (-) and current (+):'
|
||||
echo
|
||||
$DIFF_CMD "${SEARX_SRC}/searx/settings.yml" "${SEARX_SETTINGS_PATH}"
|
||||
wait_key
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
remove_settings() {
|
||||
rst_title "remove searx settings" section
|
||||
echo
|
||||
info_msg "delete ${SEARX_SETTINGS_PATH}"
|
||||
rm -f "${SEARX_SETTINGS_PATH}"
|
||||
}
|
||||
|
||||
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"
|
||||
pip install -U pip
|
||||
pip install -U setuptools
|
||||
pip install -U wheel
|
||||
pip install -U -e .
|
||||
cd ${SEARX_SRC}
|
||||
pip install -e .
|
||||
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_PATH"
|
||||
echo
|
||||
tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
cd ${SEARX_SRC}
|
||||
sed -i -e "s/ultrasecretkey/$(openssl rand -hex 16)/g" "$SEARX_SETTINGS_PATH"
|
||||
sed -i -e "s/{instance_name}/${SEARX_INSTANCE_NAME}/g" "$SEARX_SETTINGS_PATH"
|
||||
EOF
|
||||
}
|
||||
|
||||
test_local_searx() {
|
||||
rst_title "Testing searx instance localy" section
|
||||
echo
|
||||
|
||||
if service_is_available "http://${SEARX_INTERNAL_HTTP}" &>/dev/null; then
|
||||
err_msg "URL/port http://${SEARX_INTERNAL_HTTP} is already in use, you"
|
||||
err_msg "should stop that service before starting local tests!"
|
||||
if ! ask_yn "Continue with local tests?"; then
|
||||
return
|
||||
fi
|
||||
fi
|
||||
sed -i -e "s/debug : False/debug : True/g" "$SEARX_SETTINGS_PATH"
|
||||
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
export SEARX_SETTINGS_PATH="${SEARX_SETTINGS_PATH}"
|
||||
cd ${SEARX_SRC}
|
||||
timeout 10 python searx/webapp.py &
|
||||
sleep 3
|
||||
curl --location --verbose --head --insecure $SEARX_INTERNAL_HTTP
|
||||
EOF
|
||||
sed -i -e "s/debug : True/debug : False/g" "$SEARX_SETTINGS_PATH"
|
||||
}
|
||||
|
||||
install_searx_uwsgi() {
|
||||
rst_title "Install searx's uWSGI app (searx.ini)" section
|
||||
echo
|
||||
install_uwsgi
|
||||
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 $SEARX_INSTANCE_NAME (service)" section
|
||||
echo
|
||||
uWSGI_enable_app "$SEARX_UWSGI_APP"
|
||||
uWSGI_restart "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
deactivate_service() {
|
||||
rst_title "De-Activate $SEARX_INSTANCE_NAME (service)" section
|
||||
echo
|
||||
uWSGI_disable_app "$SEARX_UWSGI_APP"
|
||||
uWSGI_restart "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
enable_image_proxy() {
|
||||
info_msg "try to enable image_proxy ..."
|
||||
tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
cd ${SEARX_SRC}
|
||||
sed -i -e "s/image_proxy : False/image_proxy : True/g" "$SEARX_SETTINGS_PATH"
|
||||
EOF
|
||||
uWSGI_restart "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
disable_image_proxy() {
|
||||
info_msg "try to enable image_proxy ..."
|
||||
tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
cd ${SEARX_SRC}
|
||||
sed -i -e "s/image_proxy : True/image_proxy : False/g" "$SEARX_SETTINGS_PATH"
|
||||
EOF
|
||||
uWSGI_restart "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
enable_debug() {
|
||||
warn_msg "Do not enable debug in production enviroments!!"
|
||||
info_msg "try to enable debug mode ..."
|
||||
tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
cd ${SEARX_SRC}
|
||||
sed -i -e "s/debug : False/debug : True/g" "$SEARX_SETTINGS_PATH"
|
||||
EOF
|
||||
uWSGI_restart "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
disable_debug() {
|
||||
info_msg "try to disable debug mode ..."
|
||||
tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
cd ${SEARX_SRC}
|
||||
sed -i -e "s/debug : True/debug : False/g" "$SEARX_SETTINGS_PATH"
|
||||
EOF
|
||||
uWSGI_restart "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
set_result_proxy() {
|
||||
|
||||
# usage: set_result_proxy <URL> [<key>]
|
||||
|
||||
info_msg "try to set result proxy: '$1' ($2)"
|
||||
cp "${SEARX_SETTINGS_PATH}" "${SEARX_SETTINGS_PATH}.bak"
|
||||
_set_result_proxy "$1" "$2" > "${SEARX_SETTINGS_PATH}"
|
||||
}
|
||||
|
||||
_set_result_proxy() {
|
||||
local line
|
||||
local stage=0
|
||||
local url=" url: $1"
|
||||
local key=" key: !!binary \"$2\""
|
||||
if [[ -z $2 ]]; then
|
||||
key=
|
||||
fi
|
||||
|
||||
while IFS= read -r line
|
||||
do
|
||||
if [[ $stage = 0 ]] || [[ $stage = 2 ]] ; then
|
||||
if [[ $line =~ ^[[:space:]]*#*[[:space:]]*result_proxy[[:space:]]*:[[:space:]]*$ ]]; then
|
||||
if [[ $stage = 0 ]]; then
|
||||
stage=1
|
||||
echo "result_proxy:"
|
||||
continue
|
||||
elif [[ $stage = 2 ]]; then
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [[ $stage = 1 ]] || [[ $stage = 2 ]] ; then
|
||||
if [[ $line =~ ^[[:space:]]*#*[[:space:]]*url[[:space:]]*:[[:space:]] ]]; then
|
||||
[[ $stage = 1 ]] && echo "$url"
|
||||
continue
|
||||
elif [[ $line =~ ^[[:space:]]*#*[[:space:]]*key[[:space:]]*:[[:space:]] ]]; then
|
||||
[[ $stage = 1 ]] && [[ -n $key ]] && echo "$key"
|
||||
continue
|
||||
elif [[ $line =~ ^[[:space:]]*$ ]]; then
|
||||
stage=2
|
||||
fi
|
||||
fi
|
||||
echo "$line"
|
||||
done < "${SEARX_SETTINGS_PATH}.bak"
|
||||
}
|
||||
|
||||
function has_substring() {
|
||||
[[ "$1" != "${2/$1/}" ]]
|
||||
}
|
||||
inspect_service() {
|
||||
rst_title "service status & log"
|
||||
cat <<EOF
|
||||
|
||||
sourced ${DOT_CONFIG#"$REPO_ROOT/"} :
|
||||
|
||||
PUBLIC_URL : ${PUBLIC_URL}
|
||||
SEARX_URL_PATH : ${SEARX_URL_PATH}
|
||||
SEARX_INSTANCE_NAME : ${SEARX_INSTANCE_NAME}
|
||||
SEARX_INTERNAL_HTTP : ${SEARX_INTERNAL_HTTP}
|
||||
|
||||
EOF
|
||||
|
||||
if service_account_is_available "$SERVICE_USER"; then
|
||||
info_msg "Service account $SERVICE_USER exists."
|
||||
else
|
||||
err_msg "Service account $SERVICE_USER does not exists!"
|
||||
fi
|
||||
|
||||
if pyenv_is_available; then
|
||||
info_msg "~$SERVICE_USER: python environment is available."
|
||||
else
|
||||
err_msg "~$SERVICE_USER: python environment is not available!"
|
||||
fi
|
||||
|
||||
if clone_is_available; then
|
||||
info_msg "~$SERVICE_USER: Searx software is installed."
|
||||
else
|
||||
err_msg "~$SERVICE_USER: Missing searx software!"
|
||||
fi
|
||||
|
||||
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
|
||||
|
||||
uWSGI_app_available "$SEARX_UWSGI_APP" \
|
||||
|| err_msg "uWSGI app $SEARX_UWSGI_APP not available!"
|
||||
|
||||
if in_container; then
|
||||
lxc_suite_info
|
||||
else
|
||||
info_msg "public URL --> ${PUBLIC_URL}"
|
||||
info_msg "internal URL --> http://${SEARX_INTERNAL_HTTP}"
|
||||
fi
|
||||
|
||||
if ! service_is_available "http://${SEARX_INTERNAL_HTTP}"; then
|
||||
err_msg "uWSGI app (service) at http://${SEARX_INTERNAL_HTTP} is not available!"
|
||||
MSG="${_Green}[${_BCyan}CTRL-C${_Green}] to stop or [${_BCyan}KEY${_Green}] to continue"\
|
||||
wait_key
|
||||
fi
|
||||
|
||||
if ! service_is_available "${PUBLIC_URL}"; then
|
||||
warn_msg "Public service at ${PUBLIC_URL} is not available!"
|
||||
if ! in_container; then
|
||||
warn_msg "Check if public name is correct and routed or use the public IP from above."
|
||||
fi
|
||||
fi
|
||||
|
||||
local _debug_on
|
||||
if ask_yn "Enable searx debug mode?"; then
|
||||
enable_debug
|
||||
_debug_on=1
|
||||
fi
|
||||
echo
|
||||
|
||||
case $DIST_ID-$DIST_VERS in
|
||||
ubuntu-*|debian-*)
|
||||
systemctl --no-pager -l status "${SERVICE_NAME}"
|
||||
;;
|
||||
arch-*)
|
||||
systemctl --no-pager -l status "uwsgi@${SERVICE_NAME%.*}"
|
||||
;;
|
||||
fedora-*)
|
||||
systemctl --no-pager -l status uwsgi
|
||||
;;
|
||||
esac
|
||||
|
||||
# shellcheck disable=SC2059
|
||||
printf "// use ${_BCyan}CTRL-C${_creset} to stop monitoring the log"
|
||||
read -r -s -n1 -t 5
|
||||
echo
|
||||
|
||||
while true; do
|
||||
trap break 2
|
||||
case $DIST_ID-$DIST_VERS in
|
||||
ubuntu-*|debian-*) tail -f /var/log/uwsgi/app/searx.log ;;
|
||||
arch-*) journalctl -f -u "uwsgi@${SERVICE_NAME%.*}" ;;
|
||||
fedora-*) journalctl -f -u uwsgi ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $_debug_on == 1 ]]; then
|
||||
disable_debug
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
install_apache_site() {
|
||||
rst_title "Install Apache site $APACHE_SEARX_SITE"
|
||||
|
||||
rst_para "\
|
||||
This installs the searx uwsgi app as apache site. If your server is 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 continue?" Yn; then
|
||||
return
|
||||
else
|
||||
install_apache
|
||||
fi
|
||||
|
||||
apache_install_site --variant=uwsgi "${APACHE_SEARX_SITE}"
|
||||
|
||||
rst_title "Install searx's uWSGI app (searx.ini)" section
|
||||
echo
|
||||
uWSGI_install_app --variant=socket "$SEARX_UWSGI_APP"
|
||||
|
||||
if ! service_is_available "${PUBLIC_URL}"; then
|
||||
err_msg "Public service at ${PUBLIC_URL} is not available!"
|
||||
fi
|
||||
}
|
||||
|
||||
remove_apache_site() {
|
||||
|
||||
rst_title "Remove Apache site ${APACHE_SEARX_SITE}"
|
||||
|
||||
rst_para "\
|
||||
This removes apache site ${APACHE_SEARX_SITE}."
|
||||
|
||||
! apache_is_installed && err_msg "Apache is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
fi
|
||||
|
||||
apache_remove_site "${APACHE_SEARX_SITE}"
|
||||
|
||||
rst_title "Remove searx's uWSGI app (searx.ini)" section
|
||||
echo
|
||||
uWSGI_remove_app "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
rst-doc() {
|
||||
local debian="${SEARX_PACKAGES_debian}"
|
||||
local arch="${SEARX_PACKAGES_arch}"
|
||||
local fedora="${SEARX_PACKAGES_fedora}"
|
||||
local debian_build="${BUILD_PACKAGES_debian}"
|
||||
local arch_build="${BUILD_PACKAGES_arch}"
|
||||
local fedora_build="${BUILD_PACKAGES_fedora}"
|
||||
debian="$(echo "${debian}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
|
||||
arch="$(echo "${arch}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
|
||||
fedora="$(echo "${fedora}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
|
||||
debian_build="$(echo "${debian_build}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
|
||||
arch_build="$(echo "${arch_build}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
|
||||
fedora_build="$(echo "${fedora_build}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
|
||||
|
||||
eval "echo \"$(< "${REPO_ROOT}/docs/build-templates/searx.rst")\""
|
||||
|
||||
# I use ubuntu-20.04 here to demonstrate that versions are also suported,
|
||||
# normaly debian-* and ubuntu-* are most the same.
|
||||
|
||||
for DIST_NAME in ubuntu-20.04 arch fedora; do
|
||||
(
|
||||
DIST_ID=${DIST_NAME%-*}
|
||||
DIST_VERS=${DIST_NAME#*-}
|
||||
[[ $DIST_VERS =~ $DIST_ID ]] && DIST_VERS=
|
||||
uWSGI_distro_setup
|
||||
|
||||
echo -e "\n.. START searx uwsgi-description $DIST_NAME"
|
||||
|
||||
case $DIST_ID-$DIST_VERS in
|
||||
ubuntu-*|debian-*) cat <<EOF
|
||||
# init.d --> /usr/share/doc/uwsgi/README.Debian.gz
|
||||
# For uWSGI debian uses the LSB init process, this might be changed
|
||||
# one day, see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=833067
|
||||
|
||||
create ${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP}
|
||||
enable: sudo -H ln -s ${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP} ${uWSGI_APPS_ENABLED}/
|
||||
start: sudo -H service uwsgi start ${SEARX_UWSGI_APP%.*}
|
||||
restart: sudo -H service uwsgi restart ${SEARX_UWSGI_APP%.*}
|
||||
stop: sudo -H service uwsgi stop ${SEARX_UWSGI_APP%.*}
|
||||
disable: sudo -H rm ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
|
||||
EOF
|
||||
;;
|
||||
arch-*) cat <<EOF
|
||||
# systemd --> /usr/lib/systemd/system/uwsgi@.service
|
||||
# For uWSGI archlinux uses systemd template units, see
|
||||
# - http://0pointer.de/blog/projects/instances.html
|
||||
# - https://uwsgi-docs.readthedocs.io/en/latest/Systemd.html#one-service-per-app-in-systemd
|
||||
|
||||
create: ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
|
||||
enable: sudo -H systemctl enable uwsgi@${SEARX_UWSGI_APP%.*}
|
||||
start: sudo -H systemctl start uwsgi@${SEARX_UWSGI_APP%.*}
|
||||
restart: sudo -H systemctl restart uwsgi@${SEARX_UWSGI_APP%.*}
|
||||
stop: sudo -H systemctl stop uwsgi@${SEARX_UWSGI_APP%.*}
|
||||
disable: sudo -H systemctl disable uwsgi@${SEARX_UWSGI_APP%.*}
|
||||
EOF
|
||||
;;
|
||||
fedora-*) cat <<EOF
|
||||
# systemd --> /usr/lib/systemd/system/uwsgi.service
|
||||
# The unit file starts uWSGI in emperor mode (/etc/uwsgi.ini), see
|
||||
# - https://uwsgi-docs.readthedocs.io/en/latest/Emperor.html
|
||||
|
||||
create: ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
|
||||
restart: sudo -H touch ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
|
||||
disable: sudo -H rm ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
echo -e ".. END searx uwsgi-description $DIST_NAME"
|
||||
|
||||
echo -e "\n.. START searx uwsgi-appini $DIST_NAME"
|
||||
eval "echo \"$(< "${TEMPLATES}/${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP}")\""
|
||||
echo -e "\n.. END searx uwsgi-appini $DIST_NAME"
|
||||
|
||||
)
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
main "$@"
|
||||
# ----------------------------------------------------------------------------
|
48
utils/site-python/sphinx_build_tools.py
Normal file
48
utils/site-python/sphinx_build_tools.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
# -*- coding: utf-8; mode: python -*-
|
||||
"""Implement some sphinx-build tools.
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from sphinx.util.pycompat import execfile_
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def load_sphinx_config(namespace):
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
u"""Load an additional configuration file into *namespace*.
|
||||
|
||||
The name of the configuration file is taken from the environment
|
||||
``SPHINX_CONF``. The external configuration file extends (or overwrites) the
|
||||
configuration values from the origin ``conf.py``. With this you are able to
|
||||
maintain *build themes*. To your docs/conf.py add::
|
||||
|
||||
from sphinx_build_tools import load_sphinx_config
|
||||
...
|
||||
|
||||
# Since loadConfig overwrites settings from the global namespace, it has to be
|
||||
# the last statement in the conf.py file
|
||||
|
||||
load_sphinx_config(globals())
|
||||
|
||||
"""
|
||||
|
||||
config_file = os.environ.get("SPHINX_CONF", None)
|
||||
if (config_file is not None
|
||||
and os.path.normpath(namespace["__file__"]) != os.path.normpath(config_file) ):
|
||||
config_file = os.path.abspath(config_file)
|
||||
|
||||
if os.path.isfile(config_file):
|
||||
sys.stdout.write(
|
||||
"load additional sphinx-config: %s\n"
|
||||
% config_file)
|
||||
config = namespace.copy()
|
||||
config['__file__'] = config_file
|
||||
execfile_(config_file, config)
|
||||
del config['__file__']
|
||||
namespace.update(config)
|
||||
else:
|
||||
sys.stderr.write(
|
||||
"WARNING: additional sphinx-config not found: %s\n"
|
||||
% config_file)
|
1
utils/templates/etc/apache2
Symbolic link
1
utils/templates/etc/apache2
Symbolic link
|
@ -0,0 +1 @@
|
|||
httpd
|
129
utils/templates/etc/filtron/rules.json
Normal file
129
utils/templates/etc/filtron/rules.json
Normal file
|
@ -0,0 +1,129 @@
|
|||
[
|
||||
{
|
||||
"name": "roboagent limit",
|
||||
"filters": [
|
||||
"Header:User-Agent=(curl|cURL|Wget|python-requests|Scrapy|FeedFetcher|Go-http-client|Ruby|UniversalFeedParser)"
|
||||
],
|
||||
"limit": 0,
|
||||
"stop": true,
|
||||
"actions": [
|
||||
{ "name": "log"},
|
||||
{ "name": "block",
|
||||
"params": {
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "botlimit",
|
||||
"filters": [
|
||||
"Header:User-Agent=(Googlebot|bingbot|Baiduspider|yacybot|YandexMobileBot|YandexBot|Yahoo! Slurp|MJ12bot|AhrefsBot|archive.org_bot|msnbot|MJ12bot|SeznamBot|linkdexbot|Netvibes|SMTBot|zgrab|James BOT)"
|
||||
],
|
||||
"limit": 0,
|
||||
"stop": true,
|
||||
"actions": [
|
||||
{ "name": "log"},
|
||||
{ "name": "block",
|
||||
"params": {
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "suspiciously frequent IP",
|
||||
"filters": [],
|
||||
"interval": 600,
|
||||
"limit": 30,
|
||||
"aggregations": [
|
||||
"Header:X-Forwarded-For"
|
||||
],
|
||||
"actions":[
|
||||
{"name":"log"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "search request",
|
||||
"filters": [
|
||||
"Param:q",
|
||||
"Path=^(/|/search)$"
|
||||
],
|
||||
"interval": 61,
|
||||
"limit": 999,
|
||||
"subrules": [
|
||||
{
|
||||
"name": "missing Accept-Language",
|
||||
"filters": ["!Header:Accept-Language"],
|
||||
"limit": 0,
|
||||
"stop": true,
|
||||
"actions": [
|
||||
{"name":"log"},
|
||||
{"name": "block",
|
||||
"params": {"message": "Rate limit exceeded"}}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "suspiciously Connection=close header",
|
||||
"filters": ["Header:Connection=close"],
|
||||
"limit": 0,
|
||||
"stop": true,
|
||||
"actions": [
|
||||
{"name":"log"},
|
||||
{"name": "block",
|
||||
"params": {"message": "Rate limit exceeded"}}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "IP limit",
|
||||
"interval": 61,
|
||||
"limit": 9,
|
||||
"stop": true,
|
||||
"aggregations": [
|
||||
"Header:X-Forwarded-For"
|
||||
],
|
||||
"actions": [
|
||||
{ "name": "log"},
|
||||
{ "name": "block",
|
||||
"params": {
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rss/json limit",
|
||||
"filters": [
|
||||
"Param:format=(csv|json|rss)"
|
||||
],
|
||||
"interval": 121,
|
||||
"limit": 2,
|
||||
"stop": true,
|
||||
"actions": [
|
||||
{ "name": "log"},
|
||||
{ "name": "block",
|
||||
"params": {
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "useragent limit",
|
||||
"interval": 61,
|
||||
"limit": 199,
|
||||
"aggregations": [
|
||||
"Header:User-Agent"
|
||||
],
|
||||
"actions": [
|
||||
{ "name": "log"},
|
||||
{ "name": "block",
|
||||
"params": {
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
28
utils/templates/etc/httpd/sites-available/morty.conf
Normal file
28
utils/templates/etc/httpd/sites-available/morty.conf
Normal file
|
@ -0,0 +1,28 @@
|
|||
# -*- coding: utf-8; mode: apache -*-
|
||||
|
||||
LoadModule headers_module ${APACHE_MODULES}/mod_headers.so
|
||||
LoadModule proxy_module ${APACHE_MODULES}/mod_proxy.so
|
||||
LoadModule proxy_http_module ${APACHE_MODULES}/mod_proxy_http.so
|
||||
#LoadModule setenvif_module ${APACHE_MODULES}/mod_setenvif.so
|
||||
|
||||
# SetEnvIf Request_URI "${PUBLIC_URL_PATH_MORTY}" dontlog
|
||||
# CustomLog /dev/null combined env=dontlog
|
||||
|
||||
<Location ${PUBLIC_URL_PATH_MORTY} >
|
||||
|
||||
<IfModule mod_security2.c>
|
||||
SecRuleEngine Off
|
||||
</IfModule>
|
||||
|
||||
Require all granted
|
||||
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
#Allow from fd00::/8 192.168.0.0/16 fe80::/10 127.0.0.0/8 ::1
|
||||
Allow from all
|
||||
|
||||
ProxyPreserveHost On
|
||||
ProxyPass http://${MORTY_LISTEN}
|
||||
RequestHeader set X-Script-Name ${PUBLIC_URL_PATH_MORTY}
|
||||
|
||||
</Location>
|
33
utils/templates/etc/httpd/sites-available/searx.conf:filtron
Normal file
33
utils/templates/etc/httpd/sites-available/searx.conf:filtron
Normal file
|
@ -0,0 +1,33 @@
|
|||
# -*- coding: utf-8; mode: apache -*-
|
||||
|
||||
LoadModule headers_module ${APACHE_MODULES}/mod_headers.so
|
||||
LoadModule proxy_module ${APACHE_MODULES}/mod_proxy.so
|
||||
LoadModule proxy_http_module ${APACHE_MODULES}/mod_proxy_http.so
|
||||
#LoadModule setenvif_module ${APACHE_MODULES}/mod_setenvif.so
|
||||
|
||||
# SetEnvIf Request_URI "${FILTRON_URL_PATH}" dontlog
|
||||
# CustomLog /dev/null combined env=dontlog
|
||||
|
||||
# SecRuleRemoveById 981054
|
||||
# SecRuleRemoveById 981059
|
||||
# SecRuleRemoveById 981060
|
||||
# SecRuleRemoveById 950907
|
||||
|
||||
<Location ${FILTRON_URL_PATH} >
|
||||
|
||||
<IfModule mod_security2.c>
|
||||
SecRuleEngine Off
|
||||
</IfModule>
|
||||
|
||||
Require all granted
|
||||
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
#Allow from fd00::/8 192.168.0.0/16 fe80::/10 127.0.0.0/8 ::1
|
||||
Allow from all
|
||||
|
||||
ProxyPreserveHost On
|
||||
ProxyPass http://${FILTRON_LISTEN}
|
||||
RequestHeader set X-Script-Name ${FILTRON_URL_PATH}
|
||||
|
||||
</Location>
|
27
utils/templates/etc/httpd/sites-available/searx.conf:uwsgi
Normal file
27
utils/templates/etc/httpd/sites-available/searx.conf:uwsgi
Normal file
|
@ -0,0 +1,27 @@
|
|||
# -*- coding: utf-8; mode: apache -*-
|
||||
|
||||
LoadModule headers_module ${APACHE_MODULES}/mod_headers.so
|
||||
LoadModule proxy_module ${APACHE_MODULES}/mod_proxy.so
|
||||
LoadModule proxy_uwsgi_module ${APACHE_MODULES}/mod_proxy_uwsgi.so
|
||||
# LoadModule setenvif_module ${APACHE_MODULES}/mod_setenvif.so
|
||||
|
||||
# SetEnvIf Request_URI "${SEARX_URL_PATH}" dontlog
|
||||
# CustomLog /dev/null combined env=dontlog
|
||||
|
||||
<Location ${SEARX_URL_PATH}>
|
||||
|
||||
<IfModule mod_security2.c>
|
||||
SecRuleEngine Off
|
||||
</IfModule>
|
||||
|
||||
Require all granted
|
||||
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
# Allow from fd00::/8 192.168.0.0/16 fe80::/10 127.0.0.0/8 ::1
|
||||
Allow from all
|
||||
|
||||
ProxyPreserveHost On
|
||||
ProxyPass unix:${SEARX_UWSGI_SOCKET}|uwsgi://uwsgi-uds-searx/
|
||||
|
||||
</Location>
|
11
utils/templates/etc/nginx/default.apps-available/morty.conf
Normal file
11
utils/templates/etc/nginx/default.apps-available/morty.conf
Normal file
|
@ -0,0 +1,11 @@
|
|||
# https://example.org/morty
|
||||
|
||||
location /morty {
|
||||
proxy_pass http://127.0.0.1:3000/;
|
||||
|
||||
proxy_set_header Host \$http_host;
|
||||
proxy_set_header Connection \$http_connection;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Scheme \$scheme;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
# https://example.org/searx
|
||||
|
||||
location ${SEARX_URL_PATH} {
|
||||
proxy_pass http://127.0.0.1:4004/;
|
||||
|
||||
proxy_set_header Host \$http_host;
|
||||
proxy_set_header Connection \$http_connection;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Scheme \$scheme;
|
||||
proxy_set_header X-Script-Name ${SEARX_URL_PATH};
|
||||
}
|
||||
|
||||
location ${SEARX_URL_PATH}/static {
|
||||
alias ${SEARX_SRC}/searx/static;
|
||||
}
|
80
utils/templates/etc/uwsgi/apps-archlinux/searx.ini
Normal file
80
utils/templates/etc/uwsgi/apps-archlinux/searx.ini
Normal file
|
@ -0,0 +1,80 @@
|
|||
[uwsgi]
|
||||
|
||||
# uWSGI core
|
||||
# ----------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#uwsgi-core
|
||||
|
||||
# Who will run the code
|
||||
uid = ${SERVICE_USER}
|
||||
gid = ${SERVICE_GROUP}
|
||||
|
||||
# chdir to specified directory before apps loading
|
||||
chdir = ${SEARX_SRC}/searx
|
||||
|
||||
# searx configuration (settings.yml)
|
||||
env = SEARX_SETTINGS_PATH=${SEARX_SETTINGS_PATH}
|
||||
|
||||
# disable logging for privacy
|
||||
logger = systemd
|
||||
disable-logging = true
|
||||
|
||||
# The right granted on the created socket
|
||||
chmod-socket = 666
|
||||
|
||||
# Plugin to use and interpretor config
|
||||
single-interpreter = true
|
||||
|
||||
# enable master process
|
||||
master = true
|
||||
|
||||
# load apps in each worker instead of the master
|
||||
lazy-apps = true
|
||||
|
||||
# load uWSGI plugins
|
||||
plugin = python
|
||||
|
||||
# By default the Python plugin does not initialize the GIL. This means your
|
||||
# app-generated threads will not run. If you need threads, remember to enable
|
||||
# them with enable-threads. Running uWSGI in multithreading mode (with the
|
||||
# threads options) will automatically enable threading support. This *strange*
|
||||
# default behaviour is for performance reasons.
|
||||
enable-threads = true
|
||||
|
||||
|
||||
# plugin: python
|
||||
# --------------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-python
|
||||
|
||||
# load a WSGI module
|
||||
module = searx.webapp
|
||||
|
||||
# set PYTHONHOME/virtualenv
|
||||
virtualenv = ${SEARX_PYENV}
|
||||
|
||||
# add directory (or glob) to pythonpath
|
||||
pythonpath = ${SEARX_SRC}
|
||||
|
||||
|
||||
# speak to upstream
|
||||
# -----------------
|
||||
#
|
||||
# Activate the 'http' configuration for filtron or activate the 'socket'
|
||||
# configuration if you setup your HTTP server to use uWSGI protocol via sockets.
|
||||
|
||||
# using IP:
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-http
|
||||
# Native HTTP support: https://uwsgi-docs.readthedocs.io/en/latest/HTTP.html
|
||||
|
||||
http = ${SEARX_INTERNAL_HTTP}
|
||||
|
||||
# using unix-sockets:
|
||||
#
|
||||
# On some distributions you need to create the app folder for the sockets::
|
||||
#
|
||||
# mkdir -p /run/uwsgi/app/searx
|
||||
# chown -R ${SERVICE_USER}:${SERVICE_GROUP} /run/uwsgi/app/searx
|
||||
#
|
||||
# socket = /run/uwsgi/app/searx/socket
|
80
utils/templates/etc/uwsgi/apps-archlinux/searx.ini:socket
Normal file
80
utils/templates/etc/uwsgi/apps-archlinux/searx.ini:socket
Normal file
|
@ -0,0 +1,80 @@
|
|||
[uwsgi]
|
||||
|
||||
# uWSGI core
|
||||
# ----------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#uwsgi-core
|
||||
|
||||
# Who will run the code
|
||||
uid = ${SERVICE_USER}
|
||||
gid = ${SERVICE_GROUP}
|
||||
|
||||
# chdir to specified directory before apps loading
|
||||
chdir = ${SEARX_SRC}/searx
|
||||
|
||||
# searx configuration (settings.yml)
|
||||
env = SEARX_SETTINGS_PATH=${SEARX_SETTINGS_PATH}
|
||||
|
||||
# disable logging for privacy
|
||||
logger = systemd
|
||||
disable-logging = true
|
||||
|
||||
# The right granted on the created socket
|
||||
chmod-socket = 666
|
||||
|
||||
# Plugin to use and interpretor config
|
||||
single-interpreter = true
|
||||
|
||||
# enable master process
|
||||
master = true
|
||||
|
||||
# load apps in each worker instead of the master
|
||||
lazy-apps = true
|
||||
|
||||
# load uWSGI plugins
|
||||
plugin = python
|
||||
|
||||
# By default the Python plugin does not initialize the GIL. This means your
|
||||
# app-generated threads will not run. If you need threads, remember to enable
|
||||
# them with enable-threads. Running uWSGI in multithreading mode (with the
|
||||
# threads options) will automatically enable threading support. This *strange*
|
||||
# default behaviour is for performance reasons.
|
||||
enable-threads = true
|
||||
|
||||
|
||||
# plugin: python
|
||||
# --------------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-python
|
||||
|
||||
# load a WSGI module
|
||||
module = searx.webapp
|
||||
|
||||
# set PYTHONHOME/virtualenv
|
||||
virtualenv = ${SEARX_PYENV}
|
||||
|
||||
# add directory (or glob) to pythonpath
|
||||
pythonpath = ${SEARX_SRC}
|
||||
|
||||
|
||||
# speak to upstream
|
||||
# -----------------
|
||||
#
|
||||
# Activate the 'http' configuration for filtron or activate the 'socket'
|
||||
# configuration if you setup your HTTP server to use uWSGI protocol via sockets.
|
||||
|
||||
# using IP:
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-http
|
||||
# Native HTTP support: https://uwsgi-docs.readthedocs.io/en/latest/HTTP.html
|
||||
|
||||
# http = ${SEARX_INTERNAL_HTTP}
|
||||
|
||||
# using unix-sockets:
|
||||
#
|
||||
# On some distributions you need to create the app folder for the sockets::
|
||||
#
|
||||
# mkdir -p /run/uwsgi/app/searx
|
||||
# chown -R ${SERVICE_USER}:${SERVICE_GROUP} /run/uwsgi/app/searx
|
||||
#
|
||||
socket = /run/uwsgi/app/searx/socket
|
79
utils/templates/etc/uwsgi/apps-available/searx.ini
Normal file
79
utils/templates/etc/uwsgi/apps-available/searx.ini
Normal file
|
@ -0,0 +1,79 @@
|
|||
[uwsgi]
|
||||
|
||||
# uWSGI core
|
||||
# ----------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#uwsgi-core
|
||||
|
||||
# Who will run the code
|
||||
uid = ${SERVICE_USER}
|
||||
gid = ${SERVICE_GROUP}
|
||||
|
||||
# chdir to specified directory before apps loading
|
||||
chdir = ${SEARX_SRC}/searx
|
||||
|
||||
# searx configuration (settings.yml)
|
||||
env = SEARX_SETTINGS_PATH=${SEARX_SETTINGS_PATH}
|
||||
|
||||
# disable logging for privacy
|
||||
disable-logging = true
|
||||
|
||||
# The right granted on the created socket
|
||||
chmod-socket = 666
|
||||
|
||||
# Plugin to use and interpretor config
|
||||
single-interpreter = true
|
||||
|
||||
# enable master process
|
||||
master = true
|
||||
|
||||
# load apps in each worker instead of the master
|
||||
lazy-apps = true
|
||||
|
||||
# load uWSGI plugins
|
||||
plugin = python3,http
|
||||
|
||||
# By default the Python plugin does not initialize the GIL. This means your
|
||||
# app-generated threads will not run. If you need threads, remember to enable
|
||||
# them with enable-threads. Running uWSGI in multithreading mode (with the
|
||||
# threads options) will automatically enable threading support. This *strange*
|
||||
# default behaviour is for performance reasons.
|
||||
enable-threads = true
|
||||
|
||||
|
||||
# plugin: python
|
||||
# --------------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-python
|
||||
|
||||
# load a WSGI module
|
||||
module = searx.webapp
|
||||
|
||||
# set PYTHONHOME/virtualenv
|
||||
virtualenv = ${SEARX_PYENV}
|
||||
|
||||
# add directory (or glob) to pythonpath
|
||||
pythonpath = ${SEARX_SRC}
|
||||
|
||||
|
||||
# speak to upstream
|
||||
# -----------------
|
||||
#
|
||||
# Activate the 'http' configuration for filtron or activate the 'socket'
|
||||
# configuration if you setup your HTTP server to use uWSGI protocol via sockets.
|
||||
|
||||
# using IP:
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-http
|
||||
# Native HTTP support: https://uwsgi-docs.readthedocs.io/en/latest/HTTP.html
|
||||
|
||||
http = ${SEARX_INTERNAL_HTTP}
|
||||
|
||||
# using unix-sockets:
|
||||
#
|
||||
# On some distributions you need to create the app folder for the sockets::
|
||||
#
|
||||
# mkdir -p /run/uwsgi/app/searx
|
||||
# chmod -R ${SERVICE_USER}:${SERVICE_GROUP} /run/uwsgi/app/searx
|
||||
#
|
||||
# socket = /run/uwsgi/app/searx/socket
|
79
utils/templates/etc/uwsgi/apps-available/searx.ini:socket
Normal file
79
utils/templates/etc/uwsgi/apps-available/searx.ini:socket
Normal file
|
@ -0,0 +1,79 @@
|
|||
[uwsgi]
|
||||
|
||||
# uWSGI core
|
||||
# ----------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#uwsgi-core
|
||||
|
||||
# Who will run the code
|
||||
uid = ${SERVICE_USER}
|
||||
gid = ${SERVICE_GROUP}
|
||||
|
||||
# chdir to specified directory before apps loading
|
||||
chdir = ${SEARX_SRC}/searx
|
||||
|
||||
# searx configuration (settings.yml)
|
||||
env = SEARX_SETTINGS_PATH=${SEARX_SETTINGS_PATH}
|
||||
|
||||
# disable logging for privacy
|
||||
disable-logging = true
|
||||
|
||||
# The right granted on the created socket
|
||||
chmod-socket = 666
|
||||
|
||||
# Plugin to use and interpretor config
|
||||
single-interpreter = true
|
||||
|
||||
# enable master process
|
||||
master = true
|
||||
|
||||
# load apps in each worker instead of the master
|
||||
lazy-apps = true
|
||||
|
||||
# load uWSGI plugins
|
||||
plugin = python3,http
|
||||
|
||||
# By default the Python plugin does not initialize the GIL. This means your
|
||||
# app-generated threads will not run. If you need threads, remember to enable
|
||||
# them with enable-threads. Running uWSGI in multithreading mode (with the
|
||||
# threads options) will automatically enable threading support. This *strange*
|
||||
# default behaviour is for performance reasons.
|
||||
enable-threads = true
|
||||
|
||||
|
||||
# plugin: python
|
||||
# --------------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-python
|
||||
|
||||
# load a WSGI module
|
||||
module = searx.webapp
|
||||
|
||||
# set PYTHONHOME/virtualenv
|
||||
virtualenv = ${SEARX_PYENV}
|
||||
|
||||
# add directory (or glob) to pythonpath
|
||||
pythonpath = ${SEARX_SRC}
|
||||
|
||||
|
||||
# speak to upstream
|
||||
# -----------------
|
||||
#
|
||||
# Activate the 'http' configuration for filtron or activate the 'socket'
|
||||
# configuration if you setup your HTTP server to use uWSGI protocol via sockets.
|
||||
|
||||
# using IP:
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-http
|
||||
# Native HTTP support: https://uwsgi-docs.readthedocs.io/en/latest/HTTP.html
|
||||
|
||||
# http = ${SEARX_INTERNAL_HTTP}
|
||||
|
||||
# using unix-sockets:
|
||||
#
|
||||
# On some distributions you need to create the app folder for the sockets::
|
||||
#
|
||||
# mkdir -p /run/uwsgi/app/searx
|
||||
# chown -R ${SERVICE_USER}:${SERVICE_GROUP} /run/uwsgi/app/searx
|
||||
#
|
||||
socket = /run/uwsgi/app/searx/socket
|
29
utils/templates/lib/systemd/system/filtron.service
Normal file
29
utils/templates/lib/systemd/system/filtron.service
Normal file
|
@ -0,0 +1,29 @@
|
|||
[Unit]
|
||||
|
||||
Description=${SERVICE_NAME}
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
|
||||
Type=simple
|
||||
User=${SERVICE_USER}
|
||||
Group=${SERVICE_GROUP}
|
||||
WorkingDirectory=${SERVICE_HOME}
|
||||
ExecStart=${SERVICE_HOME}/go-apps/bin/filtron -api '${FILTRON_API}' -listen '${FILTRON_LISTEN}' -rules '${FILTRON_RULES}' -target '${FILTRON_TARGET}'
|
||||
|
||||
Restart=always
|
||||
Environment=USER=${SERVICE_USER} HOME=${SERVICE_HOME}
|
||||
|
||||
# Some distributions may not support these hardening directives. If you cannot
|
||||
# start the service due to an unknown option, comment out the ones not supported
|
||||
# by your version of systemd.
|
||||
|
||||
ProtectSystem=full
|
||||
PrivateDevices=yes
|
||||
PrivateTmp=yes
|
||||
NoNewPrivileges=true
|
||||
|
||||
[Install]
|
||||
|
||||
WantedBy=multi-user.target
|
29
utils/templates/lib/systemd/system/morty.service
Normal file
29
utils/templates/lib/systemd/system/morty.service
Normal file
|
@ -0,0 +1,29 @@
|
|||
[Unit]
|
||||
|
||||
Description=${SERVICE_NAME}
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
|
||||
Type=simple
|
||||
User=${SERVICE_USER}
|
||||
Group=${SERVICE_GROUP}
|
||||
WorkingDirectory=${SERVICE_HOME}
|
||||
ExecStart=${SERVICE_HOME}/go-apps/bin/morty -key '${MORTY_KEY}' -listen '${MORTY_LISTEN}' -timeout ${MORTY_TIMEOUT}
|
||||
|
||||
Restart=always
|
||||
Environment=USER=${SERVICE_USER} HOME=${SERVICE_HOME} DEBUG=${SERVICE_ENV_DEBUG}
|
||||
|
||||
# Some distributions may not support these hardening directives. If you cannot
|
||||
# start the service due to an unknown option, comment out the ones not supported
|
||||
# by your version of systemd.
|
||||
|
||||
ProtectSystem=full
|
||||
PrivateDevices=yes
|
||||
PrivateTmp=yes
|
||||
NoNewPrivileges=true
|
||||
|
||||
[Install]
|
||||
|
||||
WantedBy=multi-user.target
|
Loading…
Add table
Add a link
Reference in a new issue