#!/usr/bin/env bash # # Launch Inucs containers to work in there. # # Steps to do before first run on a new machine: # # sudo incus admin init # # then download the ubuntu image: # sudo incus launch images:ubuntu/24.04 test # # - create a managed network bridge: # incus network create incusbr0 ipv4.address=auto ipv4.nat=true ipv6.address=none # incus profile device set default eth0 network incusbr0 # # set -e if [ -z "$1" ]; then echo "Error: no container name provided." echo "Usage: box " exit 1 fi # Choose which container manager to use: MNGR="sudo incus" CONTAINER_NAME="$1" HOST_SHARE_DIR="/home/$USER/container_data/$CONTAINER_NAME" CONTAINER_SHARE_DIR="/mnt/shared" IMAGE="images:ubuntu/24.04" PROFILE_NAME=${2:-"default"} # if $2 is empty, use "default" PROFILES_FILE="$HOME/bin/box_profiles.sh" # EXPOSE_PORTS="7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010" EXPOSE_PORTS="" if [ -z "$CONTAINER_NAME" ]; then echo "error: no container name provided." echo "Usage: ./box.sh [profile_name]" exit 1 fi if [ ! -f "$PROFILES_FILE" ]; then echo "error: $PROFILES_FILE not found." exit 1 fi source "$PROFILES_FILE" if ! declare -f "profile_$PROFILE_NAME" > /dev/null; then echo "error: profile '$PROFILE_NAME' not found in $PROFILES_FILE." echo "Available profiles are:" grep -oP '(?<=profile_).*(?=\(\))' "$PROFILES_FILE" exit 1 fi echo "profile selected: [$PROFILE_NAME]" mkdir -p "$HOST_SHARE_DIR" echo "launch LXD container: $CONTAINER_NAME..." # security.nesting=true allows Docker to run inside this container $MNGR launch "$IMAGE" "$CONTAINER_NAME" -c security.nesting=true sleep 2 # wait for filesystem echo "set dns" HOST_UID=$(id -u) # map Host User to Container Root # $MNGR config set "$CONTAINER_NAME" raw.idmap "both $HOST_UID 0" # set dns to bypass host dns #$MNGR exec "$CONTAINER_NAME" -- rm -f /etc/resolv.conf #$MNGR exec "$CONTAINER_NAME" -- bash -c "echo 'nameserver 8.8.8.8' | tee /etc/resolv.conf" echo "restart container" $MNGR restart "$CONTAINER_NAME" $MNGR exec "$CONTAINER_NAME" -- true echo "configure shared directory (between container & host)" $MNGR config device add "$CONTAINER_NAME" project_storage disk \ source="$HOST_SHARE_DIR" \ path="$CONTAINER_SHARE_DIR" echo "configure port forwarding" for PORT in $EXPOSE_PORTS; do $MNGR config device add "$CONTAINER_NAME" "proxy${PORT}" proxy \ listen=tcp:0.0.0.0:${PORT} \ connect=tcp:127.0.0.1:${PORT} done $MNGR config device set $CONTAINER_NAME project_storage shift true echo "check internet" if ! $MNGR exec "$CONTAINER_NAME" -- ping -c 1 8.8.8.8 > /dev/null; then echo "error: no internet access inside the container." echo "note: check out the 'NOTE' at the top of the script for instructions." # remove container, since failed the launch $MNGR stop $CONTAINER_NAME $MNGR delete $CONTAINER_NAME exit 1 fi echo "apt update & apt install" $MNGR exec "$CONTAINER_NAME" -- bash -c " $(cat "$PROFILES_FILE") export DEBIAN_FRONTEND=noninteractive export NEEDRESTART_MODE=a # 'a' for automatic restart apt-get update && apt-get upgrade -y if declare -f profile_$PROFILE_NAME > /dev/null; then profile_$PROFILE_NAME else echo 'error: profile function $PROFILE_NAME not found.' exit 1 fi " echo "setup complete" echo "----------------------------------------------------" echo "Shared Directory (Host): $HOST_SHARE_DIR" echo "Shared Directory (Container): $CONTAINER_SHARE_DIR" echo "----------------------------------------------------" echo "To enter the container, run: $MNGR shell $CONTAINER_NAME" echo "To stop the container, run: $MNGR stop $CONTAINER_NAME" echo "To remove the container, run: $MNGR delete $CONTAINER_NAME"