on master help sign in
LXC: improved UX when working with a bunch of containers
37c135fMarkus Heiser
utils/filtron.sh+1−1
@@ -257,7 +257,7 @@ filtron_is_installed() {
257 [[ -f $SERVICE_HOME/go-apps/bin/filtron ]]
257 [[ -f $SERVICE_HOME/go-apps/bin/filtron ]]
258}
258}
259
259
260−_svcpr=" |${SERVICE_USER}| "
260+_svcpr=" ${_Yellow}|${SERVICE_USER}|${_creset} "
261
261
262install_filtron() {
262install_filtron() {
263 rst_title "Install filtron in user's ~/go-apps" section
263 rst_title "Install filtron in user's ~/go-apps" section
utils/lib.sh+24−8
@@ -117,9 +117,9 @@ rst_title() {
117 # usage: rst_title <header-text> [part|chapter|section]
117 # usage: rst_title <header-text> [part|chapter|section]
118
118
119 case ${2-chapter} in
119 case ${2-chapter} in
120− part) printf "\n${_BGreen}${1//?/=}\n${_BCyan}${1}${_BGreen}\n${1//?/=}${_creset}\n";;
120+ part) printf "\n${_BGreen}${1//?/=}${_creset}\n${_BCyan}${1}${_creset}\n${_BGreen}${1//?/=}${_creset}\n";;
121− chapter) printf "\n${_BCyan}${1}\n${_BGreen}${1//?/=}${_creset}\n";;
121+ chapter) printf "\n${_BCyan}${1}${_creset}\n${_BGreen}${1//?/=}${_creset}\n";;
122− section) printf "\n${_BCyan}${1}\n${_BGreen}${1//?/-}${_creset}\n";;
122+ section) printf "\n${_BCyan}${1}${_creset}\n${_BGreen}${1//?/-}${_creset}\n";;
123 *)
123 *)
124 err_msg "invalid argument '${2}' in line $(caller)"
124 err_msg "invalid argument '${2}' in line $(caller)"
125 return 42
125 return 42
@@ -238,7 +238,7 @@ prefix_stdout () {
238
238
239 local prefix="${_BYellow}-->|${_creset}"
239 local prefix="${_BYellow}-->|${_creset}"
240
240
241− if [[ -n $1 ]] ; then prefix="${_BYellow}$1${_creset}"; fi
241+ if [[ -n $1 ]] ; then prefix="$1"; fi
242
242
243 # shellcheck disable=SC2162
243 # shellcheck disable=SC2162
244 (while IFS= read line; do
244 (while IFS= read line; do
@@ -294,7 +294,8 @@ backup_file() {
294
294
295 # usage: backup_file /path/to/file.foo
295 # usage: backup_file /path/to/file.foo
296
296
297− local stamp=$(date +"_%Y%m%d_%H%M%S")
297+ local stamp
298+ stamp=$(date +"_%Y%m%d_%H%M%S")
298 info_msg "create backup: ${1}${stamp}"
299 info_msg "create backup: ${1}${stamp}"
299 cp -a "${1}" "${1}${stamp}"
300 cp -a "${1}" "${1}${stamp}"
300}
301}
@@ -503,7 +504,7 @@ install_go() {
503
504
504 # usage: install_go "${GO_PKG_URL}" "${GO_TAR}" "${SERVICE_USER}"
505 # usage: install_go "${GO_PKG_URL}" "${GO_TAR}" "${SERVICE_USER}"
505
506
506− local _svcpr=" |${3}| "
507+ local _svcpr=" ${_Yellow}|${3}|${_creset} "
507
508
508 rst_title "Install Go in user's HOME" section
509 rst_title "Install Go in user's HOME" section
509
510
@@ -1034,17 +1035,32 @@ git_clone() {
1034
1035
1035 if [[ -d "${dest}" ]] ; then
1036 if [[ -d "${dest}" ]] ; then
1036 info_msg "already cloned: $dest"
1037 info_msg "already cloned: $dest"
1037− tee_stderr 0.1 <<EOF | $bash_cmd 2>&1 | prefix_stdout " |$user| "
1038+ tee_stderr 0.1 <<EOF | $bash_cmd 2>&1 | prefix_stdout " ${_Yellow}|$user|${_creset} "
1038cd "${dest}"
1039cd "${dest}"
1039git checkout -m -B "$branch" --track "$remote/$branch"
1040git checkout -m -B "$branch" --track "$remote/$branch"
1040git pull --all
1041git pull --all
1041EOF
1042EOF
1042 else
1043 else
1043 info_msg "clone into: $dest"
1044 info_msg "clone into: $dest"
1044− tee_stderr 0.1 <<EOF | $bash_cmd 2>&1 | prefix_stdout " |$user| "
1045+ tee_stderr 0.1 <<EOF | $bash_cmd 2>&1 | prefix_stdout " ${_Yellow}|$user|${_creset} "
1045mkdir -p "$(dirname "$dest")"
1046mkdir -p "$(dirname "$dest")"
1046cd "$(dirname "$dest")"
1047cd "$(dirname "$dest")"
1047git clone --branch "$branch" --origin "$remote" "$url" "$(basename "$dest")"
1048git clone --branch "$branch" --origin "$remote" "$url" "$(basename "$dest")"
1048EOF
1049EOF
1049 fi
1050 fi
1050}
1051}
1052+
1053+# containers
1054+# ----------
1055+
1056+is_container() {
1057+ sudo_or_exit
1058+
1059+ # usage: is_container && echo "process running inside a LXC container"
1060+ # is_container || echo "process is not running inside a LXC container"
1061+ #
1062+ # hint: Reads init process environment, therefore root access is required!
1063+
1064+ # to be safe, take a look at the environment of process 1 (/sbin/init)
1065+ grep -qa 'container=lxc' /proc/1/environ
1066+}
utils/lxc.sh+78−42
@@ -63,6 +63,12 @@ HOST_USER="${SUDO_USER:-$USER}"
63HOST_USER_ID=$(id -u "${HOST_USER}")
63HOST_USER_ID=$(id -u "${HOST_USER}")
64HOST_GROUP_ID=$(id -g "${HOST_USER}")
64HOST_GROUP_ID=$(id -g "${HOST_USER}")
65
65
66+searx_suite_set_env() {
67+ export FILTRON_API="0.0.0.0:4005"
68+ export FILTRON_LISTEN="0.0.0.0:4004"
69+ export MORTY_LISTEN="0.0.0.0:3000"
70+}
71+
66# ----------------------------------------------------------------------------
72# ----------------------------------------------------------------------------
67usage() {
73usage() {
68# ----------------------------------------------------------------------------
74# ----------------------------------------------------------------------------
@@ -74,8 +80,8 @@ usage::
74 $(basename "$0") build [containers]
80 $(basename "$0") build [containers]
75 $(basename "$0") install [searx-suite]
81 $(basename "$0") install [searx-suite]
76 $(basename "$0") remove [containers|subordinate]
82 $(basename "$0") remove [containers|subordinate]
77− $(basename "$0") [start|stop] [containers]
83+ $(basename "$0") [start|stop] [containers|<container-name>]
78− $(basename "$0") inspect [info|config]
84+ $(basename "$0") show [info|config|searx-suite]
79 $(basename "$0") cmd ...
85 $(basename "$0") cmd ...
80
86
81build / remove
87build / remove
@@ -83,10 +89,11 @@ build / remove
83add / remove
89add / remove
84 :subordinate: lxd permission to map ${HOST_USER}'s user/group id through
90 :subordinate: lxd permission to map ${HOST_USER}'s user/group id through
85start/stop
91start/stop
86− :containers: start/stop of all containers
92+ :containers: start/stop of all 'containers' or only <container-name>
87−inspect
93+show
88− :info: show info of all containers
94+ :info: show info of all containers
89− :config: show config of all containers
95+ :config: show config of all containers
96+ :searx-suite: show searx-suite services of all containers
90cmd ...
97cmd ...
91 run commandline ... in all containers
98 run commandline ... in all containers
92install
99install
@@ -116,22 +123,10 @@ main() {
116 local exit_val
123 local exit_val
117 local _usage="unknown or missing $1 command $2"
124 local _usage="unknown or missing $1 command $2"
118
125
119− case $1 in
120− __install)
121− sudo_or_exit
122− case $2 in
123− searx-suite) install_searx_suite ;;
124− esac
125− exit
126− ;;
127− *)
128− if ! required_commands lxc; then
126+ if [[ ! $1 == __* ]] && ! required_commands lxc; then
129− lxd_info
127+ lxd_info
130− exit 42
128+ exit 42
131− fi
129+ fi
132− ;;
133− esac
134−
135 case $1 in
130 case $1 in
136 --source-only) ;;
131 --source-only) ;;
137 -h|--help) usage; exit 0;;
132 -h|--help) usage; exit 0;;
@@ -141,20 +136,23 @@ main() {
141 case $2 in
136 case $2 in
142 containers) build_instances ;;
137 containers) build_instances ;;
143 *) usage "$_usage"; exit 42;;
138 *) usage "$_usage"; exit 42;;
144− esac ;;
139+ esac
140+ ;;
145 remove)
141 remove)
146 sudo_or_exit
142 sudo_or_exit
147 case $2 in
143 case $2 in
148 containers) remove_instances ;;
144 containers) remove_instances ;;
149 subordinate) echo; del_subordinate_ids ;;
145 subordinate) echo; del_subordinate_ids ;;
150 *) usage "$_usage"; exit 42;;
146 *) usage "$_usage"; exit 42;;
151− esac ;;
147+ esac
148+ ;;
152 add)
149 add)
153 sudo_or_exit
150 sudo_or_exit
154 case $2 in
151 case $2 in
155 subordinate) echo; add_subordinate_ids ;;
152 subordinate) echo; add_subordinate_ids ;;
156 *) usage "$_usage"; exit 42;;
153 *) usage "$_usage"; exit 42;;
157− esac ;;
154+ esac
155+ ;;
158 start|stop)
156 start|stop)
159 sudo_or_exit
157 sudo_or_exit
160 case $2 in
158 case $2 in
@@ -163,14 +161,27 @@ main() {
163 info_msg "lxc $1 $2"
161 info_msg "lxc $1 $2"
164 lxc "$1" "$2" | prefix_stdout "[${_BBlue}${i}${_creset}] "
162 lxc "$1" "$2" | prefix_stdout "[${_BBlue}${i}${_creset}] "
165 ;;
163 ;;
166− esac ;;
164+ esac
167− inspect)
165+ ;;
166+ show)
168 sudo_or_exit
167 sudo_or_exit
169 case $2 in
168 case $2 in
170 config) lxc_cmd config show;;
169 config) lxc_cmd config show;;
171 info) lxc_cmd info;;
170 info) lxc_cmd info;;
171+ searx-suite)
172+ for i in "${LOCAL_IMAGES[@]}"; do
173+ info_msg "[${_BBlue}${i}${_creset}] ${_BGreen}${LXC_REPO_ROOT}/utils/lxc.sh install $2${_creset}"
174+ lxc exec -t "${i}" -- "${LXC_REPO_ROOT}/utils/lxc.sh" __show "$2" | prefix_stdout "[${i}] "
175+ done
176+ ;;
172 *) usage "$_usage"; exit 42;;
177 *) usage "$_usage"; exit 42;;
173− esac ;;
178+ esac
179+ ;;
180+ __show)
181+ case $2 in
182+ searx-suite) searx_suite_info ;;
183+ esac
184+ ;;
174 cmd)
185 cmd)
175 sudo_or_exit
186 sudo_or_exit
176 shift
187 shift
@@ -192,30 +203,55 @@ main() {
192 searx-suite)
203 searx-suite)
193 for i in "${LOCAL_IMAGES[@]}"; do
204 for i in "${LOCAL_IMAGES[@]}"; do
194 info_msg "[${_BBlue}${i}${_creset}] ${_BGreen}${LXC_REPO_ROOT}/utils/lxc.sh install $2${_creset}"
205 info_msg "[${_BBlue}${i}${_creset}] ${_BGreen}${LXC_REPO_ROOT}/utils/lxc.sh install $2${_creset}"
195− lxc exec "${i}" -- "${LXC_REPO_ROOT}/utils/lxc.sh" __install "$2"
206+ lxc exec -t "${i}" -- "${LXC_REPO_ROOT}/utils/lxc.sh" __install "$2" | prefix_stdout "[${i}] "
196 done
207 done
197 ;;
208 ;;
198 *) usage "$_usage"; exit 42;;
209 *) usage "$_usage"; exit 42;;
199− esac ;;
210+ esac
211+ ;;
212+ __install)
213+ case $2 in
214+ searx-suite) searx_suite_install ;;
215+ esac
216+ ;;
200 *)
217 *)
201 usage "unknown or missing command $1"; exit 42;;
218 usage "unknown or missing command $1"; exit 42;;
202 esac
219 esac
203}
220}
204
221
205−install_searx_suite() {
222+searx_suite_install() {
206− export FILTRON_API="0.0.0.0:4005"
223+ (
207− export FILTRON_LISTEN="0.0.0.0:4004"
224+ searx_suite_set_env
208− export MORTY_LISTEN="0.0.0.0:3000"
225+ export FORCE_TIMEOUT=0
209− FORCE_TIMEOUT=0 "${LXC_REPO_ROOT}/utils/searx.sh" install all
226+ "${LXC_REPO_ROOT}/utils/searx.sh" install all
210− FORCE_TIMEOUT=0 "${LXC_REPO_ROOT}/utils/morty.sh" install all
227+ "${LXC_REPO_ROOT}/utils/morty.sh" install all
211− FORCE_TIMEOUT=0 "${LXC_REPO_ROOT}/utils/filtron.sh" install all
228+ "${LXC_REPO_ROOT}/utils/filtron.sh" install all
229+
212− rst_title "[$(hostname)] searx-suite installation finished" part
230+ rst_title "searx-suite installation finished ($(hostname))" part
213− rst_para "IPs of the container ..."
231+ searx_suite_info
214− echo
232+ echo
215− ip addr show | grep "inet\s*[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*"
233+ )
216− echo
217}
234}
218
235
236+searx_suite_info() {
237+ (
238+ searx_suite_set_env
239+ rst_para "Services of the container $(hostname)"
240+ for ip in $(hostname -I); do
241+ echo
242+ if [[ $ip =~ .*:.* ]]; then
243+ :
244+ # IPv6: not yet implemented / tested
245+ # echo " searx (filtron) --> http://[$ip]:4004/"
246+ # echo " morty --> http://[$ip]:3000/"
247+ else
248+ # IPv4:
249+ echo " searx (filtron) --> http://$ip:4004/"
250+ echo " morty --> http://$ip:3000/"
251+ fi
252+ done
253+ )
254+}
219
255
220build_instances() {
256build_instances() {
221 rst_title "Build LXC instances"
257 rst_title "Build LXC instances"
utils/morty.sh+1−1
@@ -255,7 +255,7 @@ morty_is_installed() {
255 [[ -f $SERVICE_HOME/go-apps/bin/morty ]]
255 [[ -f $SERVICE_HOME/go-apps/bin/morty ]]
256}
256}
257
257
258−_svcpr=" |${SERVICE_USER}| "
258+_svcpr=" ${_Yellow}|${SERVICE_USER}|${_creset} "
259
259
260install_morty() {
260install_morty() {
261 rst_title "Install morty in user's ~/go-apps" section
261 rst_title "Install morty in user's ~/go-apps" section
utils/searx.sh+18−3
@@ -210,7 +210,7 @@ main() {
210 esac
210 esac
211}
211}
212
212
213−_service_prefix=" |$SERVICE_USER| "
213+_service_prefix=" ${_Yellow}|$SERVICE_USER|${_creset} "
214
214
215install_all() {
215install_all() {
216 rst_title "Install $SEARX_INSTANCE_NAME (service)"
216 rst_title "Install $SEARX_INSTANCE_NAME (service)"
@@ -352,7 +352,7 @@ install_settings() {
352 sudo -H -i
352 sudo -H -i
353 rst_para 'Diff between new setting file (-) and current (+):'
353 rst_para 'Diff between new setting file (-) and current (+):'
354 echo
354 echo
355− $DIFF_CMD "${SEARX_SRC}/searx/settings.yml" "${SEARX_SETTINGS_PATH}"
355+ $DIFF_CMD "${SEARX_SRC}/searx/settings.yml" "${SEARX_SETTINGS_PATH}"
356 wait_key
356 wait_key
357 ;;
357 ;;
358 esac
358 esac
@@ -440,7 +440,7 @@ test_local_searx() {
440 fi
440 fi
441 sed -i -e "s/debug : False/debug : True/g" "$SEARX_SETTINGS_PATH"
441 sed -i -e "s/debug : False/debug : True/g" "$SEARX_SETTINGS_PATH"
442 tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
442 tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
443−export SEARX_SETTINGS_PATH="${SEARX_SETTINGS_PATH}"
443+export SEARX_SETTINGS_PATH="${SEARX_SETTINGS_PATH}"
444cd ${SEARX_SRC}
444cd ${SEARX_SRC}
445timeout 10 python3 searx/webapp.py &
445timeout 10 python3 searx/webapp.py &
446sleep 3
446sleep 3
@@ -537,6 +537,18 @@ EOF
537 uWSGI_app_available "$SEARX_UWSGI_APP" \
537 uWSGI_app_available "$SEARX_UWSGI_APP" \
538 || err_msg "uWSGI app $SEARX_UWSGI_APP not available!"
538 || err_msg "uWSGI app $SEARX_UWSGI_APP not available!"
539
539
540+ if is_container; then
541+ warn_msg "runnning inside container ..."
542+ for ip in $(hostname -I); do
543+ if [[ $ip =~ .*:.* ]]; then
544+ info_msg " public HTTP service (IPv6) --> http://[$ip]"
545+ else
546+ info_msg " public HTTP service (IPv4) --> http://$ip"
547+ fi
548+ done
549+ warn_msg "SEARX_INTERNAL_URL not available from outside"
550+ fi
551+
540 if ! service_is_available "http://${SEARX_INTERNAL_URL}"; then
552 if ! service_is_available "http://${SEARX_INTERNAL_URL}"; then
541 err_msg "uWSGI app (service) at http://${SEARX_INTERNAL_URL} is not available!"
553 err_msg "uWSGI app (service) at http://${SEARX_INTERNAL_URL} is not available!"
542 echo -e "${_Green}stop with [${_BCyan}CTRL-C${_Green}] or .."
554 echo -e "${_Green}stop with [${_BCyan}CTRL-C${_Green}] or .."
@@ -545,6 +557,9 @@ EOF
545
557
546 if ! service_is_available "${PUBLIC_URL}"; then
558 if ! service_is_available "${PUBLIC_URL}"; then
547 warn_msg "Public service at ${PUBLIC_URL} is not available!"
559 warn_msg "Public service at ${PUBLIC_URL} is not available!"
560+ if is_container; then
561+ warn_msg "Check if public name is correct and routed or use the public IP from above."
562+ fi
548 fi
563 fi
549
564
550 local _debug_on
565 local _debug_on