moar scripts
This commit is contained in:
@@ -0,0 +1,87 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: lab-addkey <user> <keyfile|key-string>
|
||||||
|
|
||||||
|
Appends an SSH public key to both:
|
||||||
|
- the host user's ~/.ssh/authorized_keys
|
||||||
|
- the container's /root/.ssh/authorized_keys
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
lab-addkey alice /tmp/alice-laptop.pub
|
||||||
|
lab-addkey alice "ssh-ed25519 AAAA... user@host"
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ $# -lt 2 ]] && usage
|
||||||
|
|
||||||
|
USER="$1"
|
||||||
|
KEY_INPUT="$2"
|
||||||
|
|
||||||
|
# resolve key content
|
||||||
|
if [[ -f "$KEY_INPUT" ]]; then
|
||||||
|
KEY=$(cat "$KEY_INPUT")
|
||||||
|
else
|
||||||
|
KEY="$KEY_INPUT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# basic sanity check
|
||||||
|
if [[ ! "$KEY" =~ ^ssh- ]] && [[ ! "$KEY" =~ ^ecdsa- ]]; then
|
||||||
|
echo "ERROR: doesn't look like a valid SSH public key" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# resolve container
|
||||||
|
if [[ -f "/home/${USER}/.lxc-container" ]]; then
|
||||||
|
CONTAINER=$(cat "/home/${USER}/.lxc-container")
|
||||||
|
else
|
||||||
|
echo "ERROR: no container found for user '${USER}'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- add to host user ---
|
||||||
|
HOST_AUTHKEYS="/home/${USER}/.ssh/authorized_keys"
|
||||||
|
mkdir -p "/home/${USER}/.ssh"
|
||||||
|
if grep -qF "$KEY" "$HOST_AUTHKEYS" 2>/dev/null; then
|
||||||
|
echo "Key already present on host for ${USER}"
|
||||||
|
else
|
||||||
|
echo "$KEY" >> "$HOST_AUTHKEYS"
|
||||||
|
chown "${USER}:" "$HOST_AUTHKEYS"
|
||||||
|
chmod 600 "$HOST_AUTHKEYS"
|
||||||
|
echo "Added key to host: ${HOST_AUTHKEYS}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- add to container ---
|
||||||
|
STATE=$(lxc-info -n "$CONTAINER" -sH 2>/dev/null || true)
|
||||||
|
if [[ "$STATE" == "RUNNING" ]]; then
|
||||||
|
echo "$KEY" | 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 /root/.ssh && chmod 700 /root/.ssh
|
||||||
|
KEY=\$(cat)
|
||||||
|
if grep -qF \"\$KEY\" /root/.ssh/authorized_keys 2>/dev/null; then
|
||||||
|
echo 'Key already present in container'
|
||||||
|
else
|
||||||
|
echo \"\$KEY\" >> /root/.ssh/authorized_keys
|
||||||
|
chmod 600 /root/.ssh/authorized_keys
|
||||||
|
echo 'Added key to container'
|
||||||
|
fi
|
||||||
|
"
|
||||||
|
else
|
||||||
|
# container stopped — write directly into rootfs
|
||||||
|
ROOTFS="/var/lib/lxc/${CONTAINER}/rootfs"
|
||||||
|
CONT_AUTHKEYS="${ROOTFS}/root/.ssh/authorized_keys"
|
||||||
|
mkdir -p "${ROOTFS}/root/.ssh"
|
||||||
|
chmod 700 "${ROOTFS}/root/.ssh"
|
||||||
|
if grep -qF "$KEY" "$CONT_AUTHKEYS" 2>/dev/null; then
|
||||||
|
echo "Key already present in container rootfs"
|
||||||
|
else
|
||||||
|
echo "$KEY" >> "$CONT_AUTHKEYS"
|
||||||
|
chmod 600 "$CONT_AUTHKEYS"
|
||||||
|
echo "Added key to container rootfs: ${CONT_AUTHKEYS}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Done."
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: lab-mount <container|user> <host-path> [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
|
||||||
Reference in New Issue
Block a user