LXC: improved UX when working with a bunch of containers

Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
Markus Heiser 2020-02-27 19:13:03 +01:00
parent af6acd3417
commit 37c135f2ce
5 changed files with 122 additions and 55 deletions

View File

@ -257,7 +257,7 @@ filtron_is_installed() {
[[ -f $SERVICE_HOME/go-apps/bin/filtron ]]
}
_svcpr=" |${SERVICE_USER}| "
_svcpr=" ${_Yellow}|${SERVICE_USER}|${_creset} "
install_filtron() {
rst_title "Install filtron in user's ~/go-apps" section

View File

@ -117,9 +117,9 @@ rst_title() {
# usage: rst_title <header-text> [part|chapter|section]
case ${2-chapter} in
part) printf "\n${_BGreen}${1//?/=}\n${_BCyan}${1}${_BGreen}\n${1//?/=}${_creset}\n";;
chapter) printf "\n${_BCyan}${1}\n${_BGreen}${1//?/=}${_creset}\n";;
section) printf "\n${_BCyan}${1}\n${_BGreen}${1//?/-}${_creset}\n";;
part) printf "\n${_BGreen}${1//?/=}${_creset}\n${_BCyan}${1}${_creset}\n${_BGreen}${1//?/=}${_creset}\n";;
chapter) printf "\n${_BCyan}${1}${_creset}\n${_BGreen}${1//?/=}${_creset}\n";;
section) printf "\n${_BCyan}${1}${_creset}\n${_BGreen}${1//?/-}${_creset}\n";;
*)
err_msg "invalid argument '${2}' in line $(caller)"
return 42
@ -238,7 +238,7 @@ prefix_stdout () {
local prefix="${_BYellow}-->|${_creset}"
if [[ -n $1 ]] ; then prefix="${_BYellow}$1${_creset}"; fi
if [[ -n $1 ]] ; then prefix="$1"; fi
# shellcheck disable=SC2162
(while IFS= read line; do
@ -294,7 +294,8 @@ backup_file() {
# usage: backup_file /path/to/file.foo
local stamp=$(date +"_%Y%m%d_%H%M%S")
local stamp
stamp=$(date +"_%Y%m%d_%H%M%S")
info_msg "create backup: ${1}${stamp}"
cp -a "${1}" "${1}${stamp}"
}
@ -503,7 +504,7 @@ install_go() {
# usage: install_go "${GO_PKG_URL}" "${GO_TAR}" "${SERVICE_USER}"
local _svcpr=" |${3}| "
local _svcpr=" ${_Yellow}|${3}|${_creset} "
rst_title "Install Go in user's HOME" section
@ -1034,17 +1035,32 @@ git_clone() {
if [[ -d "${dest}" ]] ; then
info_msg "already cloned: $dest"
tee_stderr 0.1 <<EOF | $bash_cmd 2>&1 | prefix_stdout " |$user| "
tee_stderr 0.1 <<EOF | $bash_cmd 2>&1 | prefix_stdout " ${_Yellow}|$user|${_creset} "
cd "${dest}"
git checkout -m -B "$branch" --track "$remote/$branch"
git pull --all
EOF
else
info_msg "clone into: $dest"
tee_stderr 0.1 <<EOF | $bash_cmd 2>&1 | prefix_stdout " |$user| "
tee_stderr 0.1 <<EOF | $bash_cmd 2>&1 | prefix_stdout " ${_Yellow}|$user|${_creset} "
mkdir -p "$(dirname "$dest")"
cd "$(dirname "$dest")"
git clone --branch "$branch" --origin "$remote" "$url" "$(basename "$dest")"
EOF
fi
}
# containers
# ----------
is_container() {
sudo_or_exit
# usage: is_container && echo "process running inside a LXC container"
# is_container || echo "process is not running inside a LXC container"
#
# hint: Reads init process environment, therefore root access is required!
# to be safe, take a look at the environment of process 1 (/sbin/init)
grep -qa 'container=lxc' /proc/1/environ
}

View File

@ -63,6 +63,12 @@ HOST_USER="${SUDO_USER:-$USER}"
HOST_USER_ID=$(id -u "${HOST_USER}")
HOST_GROUP_ID=$(id -g "${HOST_USER}")
searx_suite_set_env() {
export FILTRON_API="0.0.0.0:4005"
export FILTRON_LISTEN="0.0.0.0:4004"
export MORTY_LISTEN="0.0.0.0:3000"
}
# ----------------------------------------------------------------------------
usage() {
# ----------------------------------------------------------------------------
@ -74,8 +80,8 @@ usage::
$(basename "$0") build [containers]
$(basename "$0") install [searx-suite]
$(basename "$0") remove [containers|subordinate]
$(basename "$0") [start|stop] [containers]
$(basename "$0") inspect [info|config]
$(basename "$0") [start|stop] [containers|<container-name>]
$(basename "$0") show [info|config|searx-suite]
$(basename "$0") cmd ...
build / remove
@ -83,10 +89,11 @@ build / remove
add / remove
:subordinate: lxd permission to map ${HOST_USER}'s user/group id through
start/stop
:containers: start/stop of all containers
inspect
:info: show info of all containers
:config: show config of all containers
:containers: start/stop of all 'containers' or only <container-name>
show
:info: show info of all containers
:config: show config of all containers
:searx-suite: show searx-suite services of all containers
cmd ...
run commandline ... in all containers
install
@ -116,22 +123,10 @@ main() {
local exit_val
local _usage="unknown or missing $1 command $2"
case $1 in
__install)
sudo_or_exit
case $2 in
searx-suite) install_searx_suite ;;
esac
exit
;;
*)
if ! required_commands lxc; then
lxd_info
exit 42
fi
;;
esac
if [[ ! $1 == __* ]] && ! required_commands lxc; then
lxd_info
exit 42
fi
case $1 in
--source-only) ;;
-h|--help) usage; exit 0;;
@ -141,20 +136,23 @@ main() {
case $2 in
containers) build_instances ;;
*) usage "$_usage"; exit 42;;
esac ;;
esac
;;
remove)
sudo_or_exit
case $2 in
containers) remove_instances ;;
subordinate) echo; del_subordinate_ids ;;
*) usage "$_usage"; exit 42;;
esac ;;
esac
;;
add)
sudo_or_exit
case $2 in
subordinate) echo; add_subordinate_ids ;;
*) usage "$_usage"; exit 42;;
esac ;;
esac
;;
start|stop)
sudo_or_exit
case $2 in
@ -163,14 +161,27 @@ main() {
info_msg "lxc $1 $2"
lxc "$1" "$2" | prefix_stdout "[${_BBlue}${i}${_creset}] "
;;
esac ;;
inspect)
esac
;;
show)
sudo_or_exit
case $2 in
config) lxc_cmd config show;;
info) lxc_cmd info;;
searx-suite)
for i in "${LOCAL_IMAGES[@]}"; do
info_msg "[${_BBlue}${i}${_creset}] ${_BGreen}${LXC_REPO_ROOT}/utils/lxc.sh install $2${_creset}"
lxc exec -t "${i}" -- "${LXC_REPO_ROOT}/utils/lxc.sh" __show "$2" | prefix_stdout "[${i}] "
done
;;
*) usage "$_usage"; exit 42;;
esac ;;
esac
;;
__show)
case $2 in
searx-suite) searx_suite_info ;;
esac
;;
cmd)
sudo_or_exit
shift
@ -192,30 +203,55 @@ main() {
searx-suite)
for i in "${LOCAL_IMAGES[@]}"; do
info_msg "[${_BBlue}${i}${_creset}] ${_BGreen}${LXC_REPO_ROOT}/utils/lxc.sh install $2${_creset}"
lxc exec "${i}" -- "${LXC_REPO_ROOT}/utils/lxc.sh" __install "$2"
lxc exec -t "${i}" -- "${LXC_REPO_ROOT}/utils/lxc.sh" __install "$2" | prefix_stdout "[${i}] "
done
;;
*) usage "$_usage"; exit 42;;
esac ;;
esac
;;
__install)
case $2 in
searx-suite) searx_suite_install ;;
esac
;;
*)
usage "unknown or missing command $1"; exit 42;;
esac
}
install_searx_suite() {
export FILTRON_API="0.0.0.0:4005"
export FILTRON_LISTEN="0.0.0.0:4004"
export MORTY_LISTEN="0.0.0.0:3000"
FORCE_TIMEOUT=0 "${LXC_REPO_ROOT}/utils/searx.sh" install all
FORCE_TIMEOUT=0 "${LXC_REPO_ROOT}/utils/morty.sh" install all
FORCE_TIMEOUT=0 "${LXC_REPO_ROOT}/utils/filtron.sh" install all
rst_title "[$(hostname)] searx-suite installation finished" part
rst_para "IPs of the container ..."
echo
ip addr show | grep "inet\s*[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*"
echo
searx_suite_install() {
(
searx_suite_set_env
export FORCE_TIMEOUT=0
"${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 "searx-suite installation finished ($(hostname))" part
searx_suite_info
echo
)
}
searx_suite_info() {
(
searx_suite_set_env
rst_para "Services of the container $(hostname)"
for ip in $(hostname -I); do
echo
if [[ $ip =~ .*:.* ]]; then
:
# IPv6: not yet implemented / tested
# echo " searx (filtron) --> http://[$ip]:4004/"
# echo " morty --> http://[$ip]:3000/"
else
# IPv4:
echo " searx (filtron) --> http://$ip:4004/"
echo " morty --> http://$ip:3000/"
fi
done
)
}
build_instances() {
rst_title "Build LXC instances"

View File

@ -255,7 +255,7 @@ morty_is_installed() {
[[ -f $SERVICE_HOME/go-apps/bin/morty ]]
}
_svcpr=" |${SERVICE_USER}| "
_svcpr=" ${_Yellow}|${SERVICE_USER}|${_creset} "
install_morty() {
rst_title "Install morty in user's ~/go-apps" section

View File

@ -210,7 +210,7 @@ main() {
esac
}
_service_prefix=" |$SERVICE_USER| "
_service_prefix=" ${_Yellow}|$SERVICE_USER|${_creset} "
install_all() {
rst_title "Install $SEARX_INSTANCE_NAME (service)"
@ -352,7 +352,7 @@ install_settings() {
sudo -H -i
rst_para 'Diff between new setting file (-) and current (+):'
echo
$DIFF_CMD "${SEARX_SRC}/searx/settings.yml" "${SEARX_SETTINGS_PATH}"
$DIFF_CMD "${SEARX_SRC}/searx/settings.yml" "${SEARX_SETTINGS_PATH}"
wait_key
;;
esac
@ -440,7 +440,7 @@ test_local_searx() {
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}"
export SEARX_SETTINGS_PATH="${SEARX_SETTINGS_PATH}"
cd ${SEARX_SRC}
timeout 10 python3 searx/webapp.py &
sleep 3
@ -537,6 +537,18 @@ EOF
uWSGI_app_available "$SEARX_UWSGI_APP" \
|| err_msg "uWSGI app $SEARX_UWSGI_APP not available!"
if is_container; then
warn_msg "runnning inside container ..."
for ip in $(hostname -I); do
if [[ $ip =~ .*:.* ]]; then
info_msg " public HTTP service (IPv6) --> http://[$ip]"
else
info_msg " public HTTP service (IPv4) --> http://$ip"
fi
done
warn_msg "SEARX_INTERNAL_URL not available from outside"
fi
if ! service_is_available "http://${SEARX_INTERNAL_URL}"; then
err_msg "uWSGI app (service) at http://${SEARX_INTERNAL_URL} is not available!"
echo -e "${_Green}stop with [${_BCyan}CTRL-C${_Green}] or .."
@ -545,6 +557,9 @@ EOF
if ! service_is_available "${PUBLIC_URL}"; then
warn_msg "Public service at ${PUBLIC_URL} is not available!"
if is_container; then
warn_msg "Check if public name is correct and routed or use the public IP from above."
fi
fi
local _debug_on