@@ -9,6 +9,9 @@ source_dot_config
99# ----------------------------------------------------------------------------
1010# config
1111# ----------------------------------------------------------------------------
12+#
13+# read also:
14+# - https://lxd.readthedocs.io/en/latest/
1215
1316# name of https://images.linuxcontainers.org
1417LINUXCONTAINERS_ORG_NAME="${LINUXCONTAINERS_ORG_NAME:-images}"
@@ -17,10 +20,11 @@ HOST_PREFIX="${HOST_PREFIX:-searx}"
1720TEST_IMAGES=(
1821 "$LINUXCONTAINERS_ORG_NAME:ubuntu/18.04" "ubu1804"
1922 "$LINUXCONTAINERS_ORG_NAME:ubuntu/19.04" "ubu1904"
20− "$LINUXCONTAINERS_ORG_NAME:archlinux" "archlinux"
23+
24+ # TODO: installation of searx & filtron not yet implemented ..
25+ #
26+ #"$LINUXCONTAINERS_ORG_NAME:archlinux" "archlinux"
2127 #"$LINUXCONTAINERS_ORG_NAME:fedora/31" "fedora31"
22− #"ubuntu-minimal:18.04" "ubu1804"
23− #"ubuntu-minimal:19.10" "ubu1910"
2428)
2529
2630REMOTE_IMAGES=()
@@ -31,6 +35,10 @@ for ((i=0; i<${#TEST_IMAGES[@]}; i+=2)); do
3135 LOCAL_IMAGES=("${LOCAL_IMAGES[@]}" "${TEST_IMAGES[i+1]}")
3236done
3337
38+HOST_USER="${SUDO_USER:-$USER}"
39+HOST_USER_ID=$(id -u "${HOST_USER}")
40+HOST_GROUP_ID=$(id -g "${HOST_USER}")
41+
3442# ----------------------------------------------------------------------------
3543usage() {
3644# ----------------------------------------------------------------------------
@@ -39,13 +47,25 @@ usage() {
3947
4048usage::
4149
42− $(basename "$0") build [hosts]
43− $(basename "$0") delete [hosts]
50+ $(basename "$0") build [containers]
51+ $(basename "$0") delete [containers|subordinate]
52+ $(basename "$0") [start|stop] [containers]
53+ $(basename "$0") inspect [info|config]
54+ $(basename "$0") cmd ...
4455
4556build / delete
46− build and/or delete all LXC hosts
57+ :containers: build and delete all LXC containers
58+add / delete
59+ :subordinate: lxd permission to map ${HOST_USER}'s user/group id through
60+start/stop
61+ :containers: start/stop of all containers
62+inspect
63+ :info: show info of all containers
64+ :config: show config of all containers
65+cmd ...
66+ run commandline ... in all containers
4767
48−all LXC hosts:
68+all LXC containers:
4969 ${LOCAL_IMAGES[@]}
5070
5171EOF
@@ -53,7 +73,6 @@ EOF
5373}
5474
5575main() {
56− rst_title "LXC tooling box" part
5776
5877 required_commands lxc || exit
5978
@@ -66,15 +85,43 @@ main() {
6685 build)
6786 sudo_or_exit
6887 case $2 in
69− hosts) build_instances ;;
88+ containers) build_instances ;;
7089 *) usage "$_usage"; exit 42;;
7190 esac ;;
7291 delete)
7392 sudo_or_exit
7493 case $2 in
75− hosts) delete_instances ;;
94+ containers) delete_instances ;;
95+ subordinate) echo; del_subordinate_ids ;;
96+ *) usage "$_usage"; exit 42;;
97+ esac ;;
98+ add)
99+ sudo_or_exit
100+ case $2 in
101+ subordinate) echo; add_subordinate_ids ;;
102+ *) usage "$_usage"; exit 42;;
103+ esac ;;
104+ start|stop)
105+ sudo_or_exit
106+ case $2 in
107+ containers) lxc_cmd "$1" ;;
76108 *) usage "$_usage"; exit 42;;
77109 esac ;;
110+ inspect)
111+ sudo_or_exit
112+ case $2 in
113+ config) lxc_cmd config show;;
114+ info) lxc_cmd info;;
115+ *) usage "$_usage"; exit 42;;
116+ esac ;;
117+ cmd)
118+ sudo_or_exit
119+ shift
120+ for i in "${LOCAL_IMAGES[@]}"; do
121+ info_msg "lxc exec ${_BBlue}${HOST_PREFIX}-${i}${_creset} -- ${_BGreen}${*}${_creset}"
122+ lxc exec "${HOST_PREFIX}-${i}" -- "$@"
123+ done
124+ ;;
78125 *)
79126 usage "unknown or missing command $1"; exit 42;;
80127 esac
@@ -83,19 +130,25 @@ main() {
83130build_instances() {
84131 rst_title "Build LXC instances"
85132 lxc_copy_images_localy
133+ #lxc image list local: && wait_key
86134 lxc_init_containers
87−
88− err_msg "WIP / sorry, not implemented yet :o"
135+ lxc_config_containers
136+ lxc list "$HOST_PREFIX"
89137}
90138
91139delete_instances() {
92140 rst_title "Delete LXC instances"
93− echo -en "\\nLXC hosts(s)::\\n\\n ${LOCAL_IMAGES[*]}\\n" | $FMT
141+ echo -en "\\nLXC containers(s)::\\n\\n ${LOCAL_IMAGES[*]}\\n" | $FMT
94142 if ask_yn "Do you really want to delete all images"; then
95143 lxc_delete_containers
96144 fi
145+ # lxc list "$HOST_PREFIX"
146+ # lxc image list local: && wait_key
97147}
98148
149+# images
150+# ------
151+
99152lxc_copy_images_localy() {
100153 echo
101154 for ((i=0; i<${#TEST_IMAGES[@]}; i+=2)); do
@@ -107,7 +160,6 @@ lxc_copy_images_localy() {
107160 --alias "${TEST_IMAGES[i+1]}" prefix_stdout
108161 fi
109162 done
110− #lxc image list local:
111163}
112164
113165lxc_delete_images_localy() {
@@ -119,6 +171,17 @@ lxc_delete_images_localy() {
119171 #lxc image list local:
120172}
121173
174+# container
175+# ---------
176+
177+lxc_cmd() {
178+ echo
179+ for i in "${LOCAL_IMAGES[@]}"; do
180+ info_msg "lxc $* $HOST_PREFIX-$i"
181+ lxc "$@" "$HOST_PREFIX-$i"
182+ done
183+}
184+
122185lxc_init_containers() {
123186 echo
124187 for i in "${LOCAL_IMAGES[@]}"; do
@@ -129,7 +192,25 @@ lxc_init_containers() {
129192 lxc init "local:$i" "$HOST_PREFIX-$i"
130193 fi
131194 done
132− #lxc list "$HOST_PREFIX"
195+}
196+
197+lxc_config_containers() {
198+ echo
199+ for i in "${LOCAL_IMAGES[@]}"; do
200+
201+ info_msg "map uid/gid from host to conatiner: $HOST_PREFIX-$i"
202+ # https://lxd.readthedocs.io/en/latest/userns-idmap/#custom-idmaps
203+ echo -e -n "uid $HOST_USER_ID 1000\\ngid $HOST_GROUP_ID 1000"\
204+ | lxc config set "$HOST_PREFIX-$i" raw.idmap -
205+
206+ info_msg "share ${REPO_ROOT} (repo_share) from HOST into container: $HOST_PREFIX-$i"
207+ # https://lxd.readthedocs.io/en/latest/instances/#type-disk
208+ lxc config device add "$HOST_PREFIX-$i" repo_share disk \
209+ source="${REPO_ROOT}" \
210+ path="/share/$(basename "${REPO_ROOT}")"
211+
212+ # lxc config show "$HOST_PREFIX-$i" && wait_key
213+ done
133214}
134215
135216lxc_delete_containers() {
@@ -143,7 +224,46 @@ lxc_delete_containers() {
143224 warn_msg "instance '$HOST_PREFIX-$i' does not exist / can't delete :o"
144225 fi
145226 done
146− #lxc list "$HOST_PREFIX"
227+}
228+
229+# subordinates
230+# ------------
231+#
232+# see man: subgid(5), subuid(5), https://lxd.readthedocs.io/en/latest/userns-idmap
233+#
234+# E.g. in the HOST you have uid=1001(user) and/or gid=1001(user) ::
235+#
236+# root:1001:1
237+#
238+# in the CONTAINER::
239+#
240+# config:
241+# raw.idmap: |
242+# uid 1001 1000
243+# gid 1001 1000
244+
245+add_subordinate_ids() {
246+ if grep "root:${HOST_USER_ID}:1" /etc/subuid -qs; then
247+ info_msg "lxd already has permission to map ${HOST_USER_ID}'s user/group id through"
248+ else
249+ info_msg "add lxd permission to map ${HOST_USER_ID}'s user/group id through"
250+ usermod --add-subuids "${HOST_USER_ID}-${HOST_USER_ID}" \
251+ --add-subgids "${HOST_GROUP_ID}-${HOST_GROUP_ID}" root
252+ fi
253+}
254+
255+del_subordinate_ids() {
256+ local out
257+ if grep "root:${HOST_USER_ID}:1" /etc/subuid -qs; then
258+ # TODO: root user is always in use by process 1, how can we remove subordinates?
259+ info_msg "remove lxd permission to map ${HOST_USER_ID}'s user/group id through"
260+ out=$(usermod --del-subuids "${HOST_USER_ID}-${HOST_USER_ID}" --del-subgids "${HOST_GROUP_ID}-${HOST_GROUP_ID}" root 2>&1)
261+ if [ ! -z $? ]; then
262+ err_msg "$out"
263+ fi
264+ else
265+ info_msg "lxd does not have permission to map ${HOST_USER_ID}'s user/group id through"
266+ fi
147267}
148268
149269