Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b2b3255 authored by Markus Heiser's avatar Markus Heiser
Browse files

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

parent e6bf2038
Loading
Loading
Loading
Loading
+136 −16
Original line number Diff line number Diff line
@@ -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
}