#!/usr/bin/env bash set -euo pipefail usage() { cat < [container-path] Bind-mounts a host directory into an LXC container, persisting across reboots. If container-path is omitted, it mirrors host-path inside the container. Examples: lab-mount alice /mnt/nas/shared # -> /mnt/nas/shared inside lxc-alice lab-mount alice /mnt/nas/shared /data/shared # -> /data/shared inside lxc-alice lab-mount lxc-alice /mnt/nas/shared # container name directly also works To mount for ALL containers: lab-mount --all /mnt/nas/shared /data/shared EOF exit 1 } mount_into() { local CONTAINER="$1" local HOST_PATH="$2" local CONT_PATH="$3" local ROOTFS="/var/lib/lxc/${CONTAINER}/rootfs" local CONFIG="/var/lib/lxc/${CONTAINER}/config" if [[ ! -d "$ROOTFS" ]]; then echo "ERROR: container '$CONTAINER' not found" >&2 return 1 fi if [[ ! -e "$HOST_PATH" ]]; then echo "ERROR: host path '$HOST_PATH' does not exist" >&2 return 1 fi # create mountpoint inside rootfs mkdir -p "${ROOTFS}${CONT_PATH}" # check if this bind mount is already in config local ENTRY="lxc.mount.entry = ${HOST_PATH} ${CONT_PATH#/} none bind,create=dir 0 0" if grep -qF "$ENTRY" "$CONFIG" 2>/dev/null; then echo "Already configured: ${CONTAINER} ${HOST_PATH} -> ${CONT_PATH}" return 0 fi # add persistent bind mount to container config echo "$ENTRY" >> "$CONFIG" echo "Added to config: ${CONTAINER} ${HOST_PATH} -> ${CONT_PATH}" # if the container is running, also mount it live local STATE STATE=$(lxc-info -n "$CONTAINER" -sH 2>/dev/null || true) if [[ "$STATE" == "RUNNING" ]]; then # lxc-attach to mount from inside lxc-attach --clear-env -n "$CONTAINER" -- /bin/bash -c " export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin mkdir -p '${CONT_PATH}' " # note: live bind mounts into running unprivileged containers via config # may require a container restart to take effect echo "NOTE: restart the container for the mount to take effect:" echo " lxc-stop -n ${CONTAINER} && lxc-start -n ${CONTAINER}" fi } resolve_container() { local NAME="$1" # if it already starts with lxc-, use as-is if [[ "$NAME" == lxc-* ]]; then echo "$NAME" elif [[ -f "/home/${NAME}/.lxc-container" ]]; then cat "/home/${NAME}/.lxc-container" else echo "lxc-${NAME}" fi } # --- parse args --- [[ $# -lt 2 ]] && usage if [[ "$1" == "--all" ]]; then HOST_PATH="$2" CONT_PATH="${3:-$HOST_PATH}" for dir in /var/lib/lxc/lxc-*/; do CONTAINER=$(basename "$dir") mount_into "$CONTAINER" "$HOST_PATH" "$CONT_PATH" done else CONTAINER=$(resolve_container "$1") HOST_PATH="$2" CONT_PATH="${3:-$HOST_PATH}" mount_into "$CONTAINER" "$HOST_PATH" "$CONT_PATH" fi