@@ -76,16 +76,17 @@ usage() {
7676
7777usage::
7878
79− $_cmd build [containers]
79+ $_cmd build [containers|<name>]
8080 $_cmd copy [images]
8181 $_cmd remove [containers|<name>|images]
8282 $_cmd [start|stop] [containers|<name>]
83− $_cmd show [info|config|suite|images]
83+ $_cmd show [images|suite|info|config [<name>]]
8484 $_cmd cmd [--|<name>] '...'
8585 $_cmd install [suite|base]
8686
8787build
88− :containers: build, launch and 'install basic' packages on 'containers'
88+ :containers: build, launch all containers and 'install base' packages
89+ :<name>: build, launch container <name> and 'install base' packages
8990copy:
9091 :images: copy remote images of the suite into local storage
9192remove
@@ -93,10 +94,10 @@ remove
9394 :images: delete local images of the suite
9495start/stop
9596 :containers: start/stop all 'containers' from the suite
96− :<name>: start/stop conatiner <name> from suite
97+ :<name>: start/stop container <name> from suite
9798show
98− :info: show info of all the containers from LXC suite
99− :config: show config of all the containers from the LXC suite
99+ :info: show info of all (or <name>) containers from LXC suite
100+ :config: show config of all (or <name>) containers from the LXC suite
100101 :suite: show services of all the containers from the LXC suite
101102 :images: show information of local images
102103cmd
@@ -162,7 +163,8 @@ main() {
162163 build)
163164 sudo_or_exit
164165 case $2 in
165− ''|containers) build_instances ;;
166+ ${LXC_HOST_PREFIX}-*) build_container "$2" ;;
167+ ''|containers) build_all_containers ;;
166168 *) usage "$_usage"; exit 42;;
167169 esac
168170 ;;
@@ -175,11 +177,11 @@ main() {
175177 remove)
176178 sudo_or_exit
177179 case $2 in
178− ''|containers) remove_instances ;;
180+ ''|containers) remove_containers ;;
179181 images) lxc_delete_images_localy ;;
180182 ${LXC_HOST_PREFIX}-*)
181183 ! lxc_exists "$2" && usage_containers "unknown container: $2" && exit 42
182− if ask_yn "Do you really want to delete conatiner $2"; then
184+ if ask_yn "Do you really want to delete container $2"; then
183185 lxc_delete_container "$2"
184186 fi
185187 ;;
@@ -201,19 +203,41 @@ main() {
201203 show)
202204 sudo_or_exit
203205 case $2 in
204− suite) show_suite ;;
206+ suite)
207+ case $3 in
208+ ${LXC_HOST_PREFIX}-*)
209+ lxc exec -t "$3" -- "${LXC_REPO_ROOT}/utils/lxc.sh" __show suite \
210+ | prefix_stdout "[${_BBlue}$3${_creset}] "
211+ ;;
212+ *) show_suite;;
213+ esac
214+ ;;
205215 images) show_images ;;
206216 config)
207− rst_title "container configurations"
208− echo
209− lxc list "$LXC_HOST_PREFIX-"
210− echo
211− lxc_cmd config show
217+ case $3 in
218+ ${LXC_HOST_PREFIX}-*)
219+ lxc config show "$3" | prefix_stdout "[${_BBlue}${3}${_creset}] "
220+ ;;
221+ *)
222+ rst_title "container configurations"
223+ echo
224+ lxc list "$LXC_HOST_PREFIX-"
225+ echo
226+ lxc_cmd config show
227+ ;;
228+ esac
212229 ;;
213230 info)
214− rst_title "container info"
215− echo
216− lxc_cmd info
231+ case $3 in
232+ ${LXC_HOST_PREFIX}-*)
233+ lxc info "$3" | prefix_stdout "[${_BBlue}${3}${_creset}] "
234+ ;;
235+ *)
236+ rst_title "container info"
237+ echo
238+ lxc_cmd info
239+ ;;
240+ esac
217241 ;;
218242 *) usage "$_usage"; exit 42;;
219243 esac
@@ -265,28 +289,69 @@ main() {
265289}
266290
267291
268−build_instances() {
269− rst_title "Build LXC instances"
292+build_all_containers() {
293+ rst_title "Build all LXC containers of suite"
294+ usage_containers
270295 lxc_copy_images_localy
271296 echo
272297 rst_title "build containers" section
273298 echo
274− lxc_init_containers
275− lxc_config_containers
276− lxc_boilerplate_containers
299+ lxc_init_all_containers
300+ lxc_config_all_containers
301+ lxc_boilerplate_all_containers
302+ rst_title "install LXC base packages" section
277303 echo
278304 lxc_exec "${LXC_REPO_ROOT}/utils/lxc.sh" __install base
279305 echo
280306 lxc list "$LXC_HOST_PREFIX"
281307}
282308
283−remove_instances() {
284− rst_title "Remove LXC instances"
309+build_container() {
310+ rst_title "Build container $1"
311+
312+ local remote_image
313+ local container
314+ local image
315+ local boilerplate_script
316+
317+ for ((i=0; i<${#LXC_SUITE[@]}; i+=2)); do
318+ if [ "${LXC_HOST_PREFIX}-${LXC_SUITE[i+1]}" = "$1" ]; then
319+ remote_image="${LXC_SUITE[i]}"
320+ container="${LXC_HOST_PREFIX}-${LXC_SUITE[i+1]}"
321+ image="${LXC_SUITE[i+1]}"
322+ boilerplate_script="${image}_boilerplate"
323+ boilerplate_script="${!boilerplate_script}"
324+ break
325+ fi
326+ done
327+ echo
328+ if [ -z "$container" ]; then
329+ err_msg "container $1 unknown"
330+ usage_containers
331+ return 42
332+ fi
333+ lxc_image_copy "${remote_image}" "${image}"
334+ rst_title "init container" section
335+ lxc_init_container "${image}" "${container}"
336+ rst_title "configure container" section
337+ lxc_config_container "${container}"
338+ rst_title "run LXC boilerplate scripts" section
339+ lxc_install_boilerplate "${container}" "$boilerplate_script"
340+ echo
341+ rst_title "install LXC base packages" section
342+ lxc_exec_cmd "${container}" "${LXC_REPO_ROOT}/utils/lxc.sh" __install base \
343+ | prefix_stdout "[${_BBlue}${container}${_creset}] "
344+ echo
345+ lxc list "$container"
346+}
347+
348+remove_containers() {
349+ rst_title "Remove all LXC containers of suite"
285350 rst_para "existing containers matching ${_BGreen}$LXC_HOST_PREFIX-*${_creset}"
286351 echo
287352 lxc list "$LXC_HOST_PREFIX-"
288353 echo -en "\\n${_BRed}LXC containers to delete::${_creset}\\n\\n ${CONTAINERS[*]}\\n" | $FMT
289− if ask_yn "Do you really want to delete these conatiners"; then
354+ if ask_yn "Do you really want to delete these containers"; then
290355 for i in "${CONTAINERS[@]}"; do
291356 lxc_delete_container "$i"
292357 done
@@ -302,13 +367,7 @@ lxc_copy_images_localy() {
302367 rst_title "copy images" section
303368 echo
304369 for ((i=0; i<${#LXC_SUITE[@]}; i+=2)); do
305− if lxc_image_exists "local:${LXC_SUITE[i+1]}"; then
306− info_msg "image ${LXC_SUITE[i]} already copied --> ${LXC_SUITE[i+1]}"
307− else
308− info_msg "copy image locally ${LXC_SUITE[i]} --> ${LXC_SUITE[i+1]}"
309− lxc image copy "${LXC_SUITE[i]}" local: \
310− --alias "${LXC_SUITE[i+1]}" | prefix_stdout
311− fi
370+ lxc_image_copy "${LXC_SUITE[i]}" "${LXC_SUITE[i+1]}"
312371 done
313372 # lxc image list local: && wait_key
314373}
@@ -408,81 +467,90 @@ lxc_exec() {
408467 done
409468}
410469
411−lxc_init_containers() {
470+lxc_init_all_containers() {
471+ rst_title "init all containers" section
412472
413473 local image_name
414474 local container_name
415475
416476 for ((i=0; i<${#LXC_SUITE[@]}; i+=2)); do
417−
418− image_name="${LXC_SUITE[i+1]}"
419− container_name="${LXC_HOST_PREFIX}-${image_name}"
420−
421− if lxc info "${container_name}" &>/dev/null; then
422− info_msg "container '${container_name}' already exists"
423− else
424− info_msg "create conatiner instance: ${container_name}"
425− lxc init "local:${image_name}" "${container_name}"
426− fi
477+ lxc_init_container "${LXC_SUITE[i+1]}" "${LXC_HOST_PREFIX}-${image_name}"
427478 done
428479}
429480
430−lxc_config_containers() {
481+lxc_config_all_containers() {
482+ rst_title "configure all containers" section
483+
431484 for i in "${CONTAINERS[@]}"; do
432− info_msg "[${_BBlue}${i}${_creset}] configure container ..."
433−
434− info_msg "[${_BBlue}${i}${_creset}] map uid/gid from host to container"
435− # https://lxd.readthedocs.io/en/latest/userns-idmap/#custom-idmaps
436− echo -e -n "uid $HOST_USER_ID 0\\ngid $HOST_GROUP_ID 0"\
437− | lxc config set "$i" raw.idmap -
438−
439− info_msg "[${_BBlue}${i}${_creset}] share ${REPO_ROOT} (repo_share) from HOST into container"
440− # https://lxd.readthedocs.io/en/latest/instances/#type-disk
441− lxc config device add "$i" repo_share disk \
442− source="${REPO_ROOT}" \
443− path="${LXC_REPO_ROOT}" &>/dev/null
444− # lxc config show "$i" && wait_key
485+ lxc_config_container "${i}"
445486 done
446487}
447488
448−lxc_boilerplate_containers() {
489+lxc_config_container() {
490+ info_msg "[${_BBlue}$1${_creset}] configure container ..."
491+
492+ info_msg "[${_BBlue}$1${_creset}] map uid/gid from host to container"
493+ # https://lxd.readthedocs.io/en/latest/userns-idmap/#custom-idmaps
494+ echo -e -n "uid $HOST_USER_ID 0\\ngid $HOST_GROUP_ID 0"\
495+ | lxc config set "$1" raw.idmap -
496+
497+ info_msg "[${_BBlue}$1${_creset}] share ${REPO_ROOT} (repo_share) from HOST into container"
498+ # https://lxd.readthedocs.io/en/latest/instances/#type-disk
499+ lxc config device add "$1" repo_share disk \
500+ source="${REPO_ROOT}" \
501+ path="${LXC_REPO_ROOT}" &>/dev/null
502+ # lxc config show "$1" && wait_key
503+}
504+
505+lxc_boilerplate_all_containers() {
506+ rst_title "run LXC boilerplate scripts" section
449507
450− local image_name
451− local container_name
452508 local boilerplate_script
509+ local image_name
453510
454511 for ((i=0; i<${#LXC_SUITE[@]}; i+=2)); do
455512
456513 image_name="${LXC_SUITE[i+1]}"
457− container_name="${LXC_HOST_PREFIX}-${image_name}"
458514 boilerplate_script="${image_name}_boilerplate"
459515 boilerplate_script="${!boilerplate_script}"
460516
461− info_msg "[${_BBlue}${container_name}${_creset}] init .."
462− if lxc start -q "${container_name}" &>/dev/null; then
463− sleep 5 # guest needs some time to come up and get an IP
517+ lxc_install_boilerplate "${LXC_HOST_PREFIX}-${image_name}" "$boilerplate_script"
518+
519+ if [[ -z "${boilerplate_script}" ]]; then
520+ err_msg "[${_BBlue}${container_name}${_creset}] no boilerplate for image '${image_name}'"
464521 fi
465− lxc_init_container "${container_name}"
466− info_msg "[${_BBlue}${container_name}${_creset}] install /.lxcenv.mk .."
467− cat <<EOF | lxc exec "${container_name}" -- bash | prefix_stdout "[${_BBlue}${container_name}${_creset}] "
522+ done
523+}
524+
525+lxc_install_boilerplate() {
526+
527+ # usage: lxc_install_boilerplate <container-name> <string: shell commands ..>
528+ #
529+ # usage: lxc_install_boilerplate searx-archlinux "${archlinux_boilerplate}"
530+
531+ local container_name="$1"
532+ local boilerplate_script="$2"
533+
534+ info_msg "[${_BBlue}${container_name}${_creset}] init .."
535+ if lxc start -q "${container_name}" &>/dev/null; then
536+ sleep 5 # guest needs some time to come up and get an IP
537+ fi
538+ info_msg "[${_BBlue}${container_name}${_creset}] install /.lxcenv.mk .."
539+ cat <<EOF | lxc exec "${container_name}" -- bash | prefix_stdout "[${_BBlue}${container_name}${_creset}] "
468540rm -f "/.lxcenv.mk"
469541ln -s "${LXC_REPO_ROOT}/utils/makefile.lxc" "/.lxcenv.mk"
470542ls -l "/.lxcenv.mk"
471543EOF
472544
473− info_msg "[${_BBlue}${container_name}${_creset}] install boilerplate .."
474− if lxc start -q "${container_name}" &>/dev/null; then
475− sleep 5 # guest needs some time to come up and get an IP
476− fi
477− if [[ -n "${boilerplate_script}" ]]; then
478− echo "${boilerplate_script}" \
479− | lxc exec "${container_name}" -- bash \
480− | prefix_stdout "[${_BBlue}${container_name}${_creset}] "
481− else
482− err_msg "[${_BBlue}${container_name}${_creset}] no boilerplate for image '${image_name}'"
483− fi
484−
485− done
545+ info_msg "[${_BBlue}${container_name}${_creset}] run LXC boilerplate scripts .."
546+ if lxc start -q "${container_name}" &>/dev/null; then
547+ sleep 5 # guest needs some time to come up and get an IP
548+ fi
549+ if [[ -n "${boilerplate_script}" ]]; then
550+ echo "${boilerplate_script}" \
551+ | lxc exec "${container_name}" -- bash \
552+ | prefix_stdout "[${_BBlue}${container_name}${_creset}] "
553+ fi
486554}
487555
488556