Browse Source

LXC: tooling box - add HOST shares and commandline to containers (WIP)

Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
Markus Heiser 5 years ago
parent
commit
0b2b325552
1 changed files with 136 additions and 16 deletions
  1. 136 16
      utils/lxc.sh

+ 136 - 16
utils/lxc.sh

@@ -9,6 +9,9 @@ source_dot_config
 # ----------------------------------------------------------------------------
 # config
 # ----------------------------------------------------------------------------
+#
+# read also:
+# - https://lxd.readthedocs.io/en/latest/
 
 # name of https://images.linuxcontainers.org
 LINUXCONTAINERS_ORG_NAME="${LINUXCONTAINERS_ORG_NAME:-images}"
@@ -17,10 +20,11 @@ HOST_PREFIX="${HOST_PREFIX:-searx}"
 TEST_IMAGES=(
     "$LINUXCONTAINERS_ORG_NAME:ubuntu/18.04"  "ubu1804"
     "$LINUXCONTAINERS_ORG_NAME:ubuntu/19.04"  "ubu1904"
-    "$LINUXCONTAINERS_ORG_NAME:archlinux"     "archlinux"
+
+    # TODO: installation of searx & filtron not yet implemented ..
+    #
+    #"$LINUXCONTAINERS_ORG_NAME:archlinux"     "archlinux"
     #"$LINUXCONTAINERS_ORG_NAME:fedora/31"     "fedora31"
-    #"ubuntu-minimal:18.04"  "ubu1804"
-    #"ubuntu-minimal:19.10"  "ubu1910"
 )
 
 REMOTE_IMAGES=()
@@ -31,6 +35,10 @@ for ((i=0; i<${#TEST_IMAGES[@]}; i+=2)); do
     LOCAL_IMAGES=("${LOCAL_IMAGES[@]}" "${TEST_IMAGES[i+1]}")
 done
 
+HOST_USER="${SUDO_USER:-$USER}"
+HOST_USER_ID=$(id -u "${HOST_USER}")
+HOST_GROUP_ID=$(id -g "${HOST_USER}")
+
 # ----------------------------------------------------------------------------
 usage() {
 # ----------------------------------------------------------------------------
@@ -39,13 +47,25 @@ usage() {
 
 usage::
 
-  $(basename "$0") build [hosts]
-  $(basename "$0") delete [hosts]
+  $(basename "$0") build        [containers]
+  $(basename "$0") delete       [containers|subordinate]
+  $(basename "$0") [start|stop] [containers]
+  $(basename "$0") inspect      [info|config]
+  $(basename "$0") cmd          ...
 
 build / delete
-  build and/or delete all LXC hosts
+  :containers:   build and delete all LXC containers
+add / delete
+  :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
+cmd ...
+  run commandline ... in all containers
 
-all LXC hosts:
+all LXC containers:
   ${LOCAL_IMAGES[@]}
 
 EOF
@@ -53,7 +73,6 @@ EOF
 }
 
 main() {
-    rst_title "LXC tooling box" part
 
     required_commands lxc || exit
 
@@ -66,15 +85,43 @@ main() {
         build)
             sudo_or_exit
             case $2 in
-                hosts) build_instances ;;
+                containers) build_instances ;;
                 *) usage "$_usage"; exit 42;;
             esac ;;
         delete)
             sudo_or_exit
             case $2 in
-                hosts) delete_instances ;;
+                containers) delete_instances ;;
+                subordinate) echo; del_subordinate_ids ;;
+                *) usage "$_usage"; exit 42;;
+            esac ;;
+        add)
+            sudo_or_exit
+            case $2 in
+                subordinate) echo; add_subordinate_ids ;;
+                *) usage "$_usage"; exit 42;;
+            esac ;;
+        start|stop)
+            sudo_or_exit
+            case $2 in
+                containers)  lxc_cmd "$1" ;;
                 *) usage "$_usage"; exit 42;;
             esac ;;
+        inspect)
+            sudo_or_exit
+            case $2 in
+                config) lxc_cmd config show;;
+                info) lxc_cmd info;;
+                *) usage "$_usage"; exit 42;;
+            esac ;;
+        cmd)
+            sudo_or_exit
+            shift
+            for i in "${LOCAL_IMAGES[@]}"; do
+                info_msg "lxc exec ${_BBlue}${HOST_PREFIX}-${i}${_creset} -- ${_BGreen}${*}${_creset}"
+                lxc exec "${HOST_PREFIX}-${i}" -- "$@"
+            done
+            ;;
         *)
             usage "unknown or missing command $1"; exit 42;;
     esac
@@ -83,19 +130,25 @@ main() {
 build_instances() {
     rst_title "Build LXC instances"
     lxc_copy_images_localy
+    #lxc image list local: && wait_key
     lxc_init_containers
-
-    err_msg "WIP / sorry, not implemented yet :o"
+    lxc_config_containers
+    lxc list "$HOST_PREFIX"
 }
 
 delete_instances() {
     rst_title "Delete LXC instances"
-    echo -en "\\nLXC hosts(s)::\\n\\n  ${LOCAL_IMAGES[*]}\\n" | $FMT
+    echo -en "\\nLXC containers(s)::\\n\\n  ${LOCAL_IMAGES[*]}\\n" | $FMT
     if ask_yn "Do you really want to delete all images"; then
         lxc_delete_containers
     fi
+    # lxc list "$HOST_PREFIX"
+    # lxc image list local: && wait_key
 }
 
+# images
+# ------
+
 lxc_copy_images_localy() {
     echo
     for ((i=0; i<${#TEST_IMAGES[@]}; i+=2)); do
@@ -107,7 +160,6 @@ lxc_copy_images_localy() {
                 --alias  "${TEST_IMAGES[i+1]}" prefix_stdout
         fi
     done
-    #lxc image list local:
 }
 
 lxc_delete_images_localy() {
@@ -119,6 +171,17 @@ lxc_delete_images_localy() {
     #lxc image list local:
 }
 
+# container
+# ---------
+
+lxc_cmd() {
+    echo
+    for i in "${LOCAL_IMAGES[@]}"; do
+        info_msg "lxc $* $HOST_PREFIX-$i"
+        lxc "$@" "$HOST_PREFIX-$i"
+    done
+}
+
 lxc_init_containers() {
     echo
     for i in "${LOCAL_IMAGES[@]}"; do
@@ -129,7 +192,25 @@ lxc_init_containers() {
             lxc init "local:$i" "$HOST_PREFIX-$i"
         fi
     done
-    #lxc list "$HOST_PREFIX"
+}
+
+lxc_config_containers() {
+    echo
+    for i in "${LOCAL_IMAGES[@]}"; do
+
+        info_msg "map uid/gid from host to conatiner: $HOST_PREFIX-$i"
+        # https://lxd.readthedocs.io/en/latest/userns-idmap/#custom-idmaps
+        echo -e -n "uid $HOST_USER_ID 1000\\ngid $HOST_GROUP_ID 1000"\
+            | lxc config set "$HOST_PREFIX-$i" raw.idmap -
+
+        info_msg "share ${REPO_ROOT} (repo_share) from HOST into container: $HOST_PREFIX-$i"
+        # https://lxd.readthedocs.io/en/latest/instances/#type-disk
+        lxc config device add "$HOST_PREFIX-$i" repo_share disk \
+            source="${REPO_ROOT}" \
+            path="/share/$(basename "${REPO_ROOT}")"
+
+        # lxc config show "$HOST_PREFIX-$i" && wait_key
+    done
 }
 
 lxc_delete_containers() {
@@ -143,7 +224,46 @@ lxc_delete_containers() {
             warn_msg "instance '$HOST_PREFIX-$i' does not exist / can't delete :o"
         fi
     done
-    #lxc list "$HOST_PREFIX"
+}
+
+# subordinates
+# ------------
+#
+# see man: subgid(5), subuid(5), https://lxd.readthedocs.io/en/latest/userns-idmap
+#
+# E.g. in the HOST you have uid=1001(user) and/or gid=1001(user) ::
+#
+#   root:1001:1
+#
+# in the CONTAINER::
+#
+#   config:
+#     raw.idmap: |
+#       uid 1001 1000
+#       gid 1001 1000
+
+add_subordinate_ids() {
+    if  grep "root:${HOST_USER_ID}:1" /etc/subuid -qs; then
+        info_msg "lxd already has permission to map ${HOST_USER_ID}'s user/group id through"
+    else
+        info_msg "add lxd permission to map ${HOST_USER_ID}'s user/group id through"
+        usermod --add-subuids "${HOST_USER_ID}-${HOST_USER_ID}" \
+                --add-subgids "${HOST_GROUP_ID}-${HOST_GROUP_ID}" root
+    fi
+}
+
+del_subordinate_ids() {
+    local out
+    if  grep "root:${HOST_USER_ID}:1" /etc/subuid -qs; then
+        # TODO: root user is always in use by process 1, how can we remove subordinates?
+        info_msg "remove lxd permission to map ${HOST_USER_ID}'s user/group id through"
+        out=$(usermod --del-subuids "${HOST_USER_ID}-${HOST_USER_ID}" --del-subgids "${HOST_GROUP_ID}-${HOST_GROUP_ID}" root 2>&1)
+        if [ ! -z $? ]; then
+            err_msg "$out"
+        fi
+    else
+        info_msg "lxd does not have permission to map ${HOST_USER_ID}'s user/group id through"
+    fi
 }