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 ]] [[ -f $SERVICE_HOME/go-apps/bin/filtron ]]
} }
_svcpr=" |${SERVICE_USER}| " _svcpr=" ${_Yellow}|${SERVICE_USER}|${_creset} "
install_filtron() { install_filtron() {
rst_title "Install filtron in user's ~/go-apps" section 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] # usage: rst_title <header-text> [part|chapter|section]
case ${2-chapter} in case ${2-chapter} in
part) printf "\n${_BGreen}${1//?/=}\n${_BCyan}${1}${_BGreen}\n${1//?/=}${_creset}\n";; part) printf "\n${_BGreen}${1//?/=}${_creset}\n${_BCyan}${1}${_creset}\n${_BGreen}${1//?/=}${_creset}\n";;
chapter) printf "\n${_BCyan}${1}\n${_BGreen}${1//?/=}${_creset}\n";; chapter) printf "\n${_BCyan}${1}${_creset}\n${_BGreen}${1//?/=}${_creset}\n";;
section) printf "\n${_BCyan}${1}\n${_BGreen}${1//?/-}${_creset}\n";; section) printf "\n${_BCyan}${1}${_creset}\n${_BGreen}${1//?/-}${_creset}\n";;
*) *)
err_msg "invalid argument '${2}' in line $(caller)" err_msg "invalid argument '${2}' in line $(caller)"
return 42 return 42
@ -238,7 +238,7 @@ prefix_stdout () {
local prefix="${_BYellow}-->|${_creset}" local prefix="${_BYellow}-->|${_creset}"
if [[ -n $1 ]] ; then prefix="${_BYellow}$1${_creset}"; fi if [[ -n $1 ]] ; then prefix="$1"; fi
# shellcheck disable=SC2162 # shellcheck disable=SC2162
(while IFS= read line; do (while IFS= read line; do
@ -294,7 +294,8 @@ backup_file() {
# usage: backup_file /path/to/file.foo # 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}" info_msg "create backup: ${1}${stamp}"
cp -a "${1}" "${1}${stamp}" cp -a "${1}" "${1}${stamp}"
} }
@ -503,7 +504,7 @@ install_go() {
# usage: install_go "${GO_PKG_URL}" "${GO_TAR}" "${SERVICE_USER}" # 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 rst_title "Install Go in user's HOME" section
@ -1034,17 +1035,32 @@ git_clone() {
if [[ -d "${dest}" ]] ; then if [[ -d "${dest}" ]] ; then
info_msg "already cloned: $dest" 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}" cd "${dest}"
git checkout -m -B "$branch" --track "$remote/$branch" git checkout -m -B "$branch" --track "$remote/$branch"
git pull --all git pull --all
EOF EOF
else else
info_msg "clone into: $dest" 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")" mkdir -p "$(dirname "$dest")"
cd "$(dirname "$dest")" cd "$(dirname "$dest")"
git clone --branch "$branch" --origin "$remote" "$url" "$(basename "$dest")" git clone --branch "$branch" --origin "$remote" "$url" "$(basename "$dest")"
EOF EOF
fi 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_USER_ID=$(id -u "${HOST_USER}")
HOST_GROUP_ID=$(id -g "${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() { usage() {
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
@ -74,8 +80,8 @@ usage::
$(basename "$0") build [containers] $(basename "$0") build [containers]
$(basename "$0") install [searx-suite] $(basename "$0") install [searx-suite]
$(basename "$0") remove [containers|subordinate] $(basename "$0") remove [containers|subordinate]
$(basename "$0") [start|stop] [containers] $(basename "$0") [start|stop] [containers|<container-name>]
$(basename "$0") inspect [info|config] $(basename "$0") show [info|config|searx-suite]
$(basename "$0") cmd ... $(basename "$0") cmd ...
build / remove build / remove
@ -83,10 +89,11 @@ build / remove
add / remove add / remove
:subordinate: lxd permission to map ${HOST_USER}'s user/group id through :subordinate: lxd permission to map ${HOST_USER}'s user/group id through
start/stop start/stop
:containers: start/stop of all containers :containers: start/stop of all 'containers' or only <container-name>
inspect show
:info: show info of all containers :info: show info of all containers
:config: show config of all containers :config: show config of all containers
:searx-suite: show searx-suite services of all containers
cmd ... cmd ...
run commandline ... in all containers run commandline ... in all containers
install install
@ -116,22 +123,10 @@ main() {
local exit_val local exit_val
local _usage="unknown or missing $1 command $2" local _usage="unknown or missing $1 command $2"
case $1 in if [[ ! $1 == __* ]] && ! required_commands lxc; then
__install)
sudo_or_exit
case $2 in
searx-suite) install_searx_suite ;;
esac
exit
;;
*)
if ! required_commands lxc; then
lxd_info lxd_info
exit 42 exit 42
fi fi
;;
esac
case $1 in case $1 in
--source-only) ;; --source-only) ;;
-h|--help) usage; exit 0;; -h|--help) usage; exit 0;;
@ -141,20 +136,23 @@ main() {
case $2 in case $2 in
containers) build_instances ;; containers) build_instances ;;
*) usage "$_usage"; exit 42;; *) usage "$_usage"; exit 42;;
esac ;; esac
;;
remove) remove)
sudo_or_exit sudo_or_exit
case $2 in case $2 in
containers) remove_instances ;; containers) remove_instances ;;
subordinate) echo; del_subordinate_ids ;; subordinate) echo; del_subordinate_ids ;;
*) usage "$_usage"; exit 42;; *) usage "$_usage"; exit 42;;
esac ;; esac
;;
add) add)
sudo_or_exit sudo_or_exit
case $2 in case $2 in
subordinate) echo; add_subordinate_ids ;; subordinate) echo; add_subordinate_ids ;;
*) usage "$_usage"; exit 42;; *) usage "$_usage"; exit 42;;
esac ;; esac
;;
start|stop) start|stop)
sudo_or_exit sudo_or_exit
case $2 in case $2 in
@ -163,14 +161,27 @@ main() {
info_msg "lxc $1 $2" info_msg "lxc $1 $2"
lxc "$1" "$2" | prefix_stdout "[${_BBlue}${i}${_creset}] " lxc "$1" "$2" | prefix_stdout "[${_BBlue}${i}${_creset}] "
;; ;;
esac ;; esac
inspect) ;;
show)
sudo_or_exit sudo_or_exit
case $2 in case $2 in
config) lxc_cmd config show;; config) lxc_cmd config show;;
info) lxc_cmd info;; 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;; *) usage "$_usage"; exit 42;;
esac ;; esac
;;
__show)
case $2 in
searx-suite) searx_suite_info ;;
esac
;;
cmd) cmd)
sudo_or_exit sudo_or_exit
shift shift
@ -192,30 +203,55 @@ main() {
searx-suite) searx-suite)
for i in "${LOCAL_IMAGES[@]}"; do for i in "${LOCAL_IMAGES[@]}"; do
info_msg "[${_BBlue}${i}${_creset}] ${_BGreen}${LXC_REPO_ROOT}/utils/lxc.sh install $2${_creset}" 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 done
;; ;;
*) usage "$_usage"; exit 42;; *) usage "$_usage"; exit 42;;
esac ;; esac
;;
__install)
case $2 in
searx-suite) searx_suite_install ;;
esac
;;
*) *)
usage "unknown or missing command $1"; exit 42;; usage "unknown or missing command $1"; exit 42;;
esac esac
} }
install_searx_suite() { searx_suite_install() {
export FILTRON_API="0.0.0.0:4005" (
export FILTRON_LISTEN="0.0.0.0:4004" searx_suite_set_env
export MORTY_LISTEN="0.0.0.0:3000" export FORCE_TIMEOUT=0
FORCE_TIMEOUT=0 "${LXC_REPO_ROOT}/utils/searx.sh" install all "${LXC_REPO_ROOT}/utils/searx.sh" install all
FORCE_TIMEOUT=0 "${LXC_REPO_ROOT}/utils/morty.sh" install all "${LXC_REPO_ROOT}/utils/morty.sh" install all
FORCE_TIMEOUT=0 "${LXC_REPO_ROOT}/utils/filtron.sh" install all "${LXC_REPO_ROOT}/utils/filtron.sh" install all
rst_title "[$(hostname)] searx-suite installation finished" part
rst_para "IPs of the container ..." rst_title "searx-suite installation finished ($(hostname))" part
echo searx_suite_info
ip addr show | grep "inet\s*[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*"
echo 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() { build_instances() {
rst_title "Build LXC instances" rst_title "Build LXC instances"

View file

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

View file

@ -210,7 +210,7 @@ main() {
esac esac
} }
_service_prefix=" |$SERVICE_USER| " _service_prefix=" ${_Yellow}|$SERVICE_USER|${_creset} "
install_all() { install_all() {
rst_title "Install $SEARX_INSTANCE_NAME (service)" rst_title "Install $SEARX_INSTANCE_NAME (service)"
@ -537,6 +537,18 @@ EOF
uWSGI_app_available "$SEARX_UWSGI_APP" \ uWSGI_app_available "$SEARX_UWSGI_APP" \
|| err_msg "uWSGI app $SEARX_UWSGI_APP not available!" || 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 if ! service_is_available "http://${SEARX_INTERNAL_URL}"; then
err_msg "uWSGI app (service) at http://${SEARX_INTERNAL_URL} is not available!" err_msg "uWSGI app (service) at http://${SEARX_INTERNAL_URL} is not available!"
echo -e "${_Green}stop with [${_BCyan}CTRL-C${_Green}] or .." echo -e "${_Green}stop with [${_BCyan}CTRL-C${_Green}] or .."
@ -545,6 +557,9 @@ EOF
if ! service_is_available "${PUBLIC_URL}"; then if ! service_is_available "${PUBLIC_URL}"; then
warn_msg "Public service at ${PUBLIC_URL} is not available!" 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 fi
local _debug_on local _debug_on