You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
6.7 KiB
195 lines
6.7 KiB
#!/bin/bash
|
|
|
|
function check_container_missing() {
|
|
if container_exists "$CONTAINER"; then
|
|
echoerr "$CONTAINER already created!"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
function usage() {
|
|
echo 'USAGE with options:'
|
|
echo -e "\t\tlxc-miaou-create <CONTAINER_NAME> -o sameuser[,nesting,ssh]"
|
|
}
|
|
|
|
function check() {
|
|
check_container_missing || return 1
|
|
return 0
|
|
}
|
|
|
|
function set_options() {
|
|
declare -a options=("$@")
|
|
length=${#options[@]}
|
|
if [[ "$length" -ne 0 ]]; then
|
|
if [[ "$length" -ne 2 ]]; then
|
|
echoerr "unrecognized options: $@" && usage && exit 30
|
|
else
|
|
prefix="${options[0]}"
|
|
option="${options[1]}"
|
|
if [[ "$prefix" == '-o' ]]; then
|
|
IFS=',' read -r -a options <<<"$option"
|
|
for i in ${options[@]}; do
|
|
case "$i" in
|
|
sameuser) OPTION_SAMEUSER=true ;;
|
|
nesting) OPTION_NESTING=true ;;
|
|
ssh) OPTION_SSH=true ;;
|
|
*) echoerr "unrecognized options: $@" && usage && exit 32 ;;
|
|
esac
|
|
done
|
|
# echo "OPTION_SAMEUSER=$OPTION_SAMEUSER, OPTION_NESTING=$OPTION_NESTING, OPTION_SSH=$OPTION_SSH"
|
|
else
|
|
echoerr "unrecognized options prefix: $prefix" && usage && exit 31
|
|
fi
|
|
fi
|
|
shift
|
|
fi
|
|
}
|
|
|
|
function create() {
|
|
local PREFIX="miaou:create"
|
|
|
|
if [[ "$OPTION_SAMEUSER" == true ]]; then
|
|
miaou_user=$(whoami)
|
|
fi
|
|
|
|
echo -n "creating new container <$CONTAINER> based on image <$CONTAINER_RELEASE>... "
|
|
bridge_gw=$(lxc network get lxdbr0 ipv4.address | cut -d'/' -f1)
|
|
packages=(git file bc bash-completion)
|
|
[[ "$OPTION_SSH" == true ]] && packages+=(openssh-server)
|
|
packages_string=$(join ', ' "${packages[@]}")
|
|
|
|
timezone=$(cat /etc/timezone)
|
|
debian_repo=$(cat /etc/apt/sources.list | head -n1 | cut -d '/' -f3)
|
|
|
|
user_data="$(
|
|
cat <<EOF
|
|
#cloud-config
|
|
timezone: '$timezone'
|
|
apt:
|
|
preserve_sources_list: false
|
|
conf: |
|
|
Acquire::Retries "60";
|
|
DPkg::Lock::Timeout "60";
|
|
primary:
|
|
- arches: [default]
|
|
uri: http://$debian_repo/debian
|
|
security:
|
|
- arches: [default]
|
|
uri: http://$debian_repo/debian-security
|
|
sources_list: |
|
|
# generated by miaou
|
|
deb \$PRIMARY \$RELEASE main
|
|
deb \$PRIMARY \$RELEASE-updates main
|
|
deb \$SECURITY \$RELEASE-security main
|
|
package_update: true
|
|
package_upgrade: true
|
|
package_reboot_if_required: true
|
|
packages: [ $packages_string ]
|
|
write_files:
|
|
- path: /etc/sudoers.d/10-add_TOOLBOX_to_secure_path
|
|
content: >
|
|
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/TOOLBOX"
|
|
runcmd:
|
|
- [ systemctl, mask, systemd-hostnamed.service ]
|
|
- [ systemctl, disable, e2scrub_reap.service ]
|
|
- [ systemctl, disable, systemd-resolved.service, --now ]
|
|
- [ systemctl, reset-failed ]
|
|
- [ rm, /etc/resolv.conf]
|
|
- [ rm, /etc/sudoers.d/90-cloud-init-users]
|
|
- "echo nameserver $bridge_gw > /etc/resolv.conf"
|
|
final_message: "Container from datasource \$datasource is finally up, after \$UPTIME seconds"
|
|
EOF
|
|
)"
|
|
|
|
lxc init local:debian/$CONTAINER_RELEASE/cloud "$CONTAINER" --config user.user-data="$user_data" -q
|
|
|
|
# allow directory `SHARED` to be read-write mounted
|
|
lxc config set "$CONTAINER" raw.idmap "both $(id -u) 0" -q
|
|
mkdir -p "$HOME/LXD/SHARED/$CONTAINER"
|
|
|
|
lxc config device add "$CONTAINER" SHARED disk source="$HOME/LXD/SHARED/$CONTAINER" path=/mnt/SHARED -q
|
|
lxc config device add "$CONTAINER" TOOLBOX disk source=/TOOLBOX path=/TOOLBOX readonly=true -q
|
|
lxc config device add "$CONTAINER" MIAOU_BASH disk source=$(realpath /opt/miaou-bash) path=/opt/miaou-bash readonly=true -q
|
|
|
|
# environment variables
|
|
lxc config set "$CONTAINER" environment.PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/miaou-bash/tools:/TOOLBOX -q
|
|
lxc config set "$CONTAINER" environment.container lxc -q
|
|
|
|
if [[ "$OPTION_NESTING" == true ]]; then
|
|
lxc config set "$CONTAINER" security.nesting true -q
|
|
lxc config device add "$CONTAINER" miaou disk source=/opt/miaou path=/opt/miaou readonly=true -q
|
|
fi
|
|
|
|
lxc start "$CONTAINER" -q
|
|
|
|
# initializing miaou-bash
|
|
lxc exec "$CONTAINER" -- /opt/miaou-bash/init.sh
|
|
|
|
# default configuration files (btm,)
|
|
lxc exec "$CONTAINER" -- mkdir -p /root/.config/bottom
|
|
lxc file push "$MIAOU_BASEDIR/templates/bottom/bottom.toml" "$CONTAINER/root/.config/bottom/bottom.toml" -q
|
|
|
|
# purge cloud-init after success
|
|
attempt=0
|
|
max_attempt=10
|
|
delay=0.2
|
|
while ! lxc exec "$CONTAINER" -- bash -c 'systemd-run -q -p After=cloud-final.service -p Type=oneshot --no-block bash -c "\
|
|
cloud-init status --wait &&\
|
|
cp /var/lib/cloud/data/status.json /root/cloud-status.json &&\
|
|
systemctl stop cloud-{config,final,init-local,init}.service &&\
|
|
systemctl disable cloud-{config,final,init-local,init}.service &&\
|
|
systemctl stop cloud-config.target cloud-init.target &&\
|
|
apt-get purge -y cloud-init &&\
|
|
rm -rf /var/lib/cloud && \
|
|
userdel -rf debian \
|
|
" 2>/dev/null '; do
|
|
attempt=$((attempt++))
|
|
if [[ $attempt -gt $max_attempt ]]; then
|
|
echoerr "systemd unavailable after $(bc <<<"$max_attempt * $delay") seconds"
|
|
exit 1
|
|
else
|
|
sleep $delay
|
|
fi
|
|
done
|
|
|
|
if [[ "$OPTION_SAMEUSER" == true ]]; then
|
|
if ! lxc exec "$CONTAINER" -- grep "$miaou_user" /etc/passwd; then
|
|
lxc exec "$CONTAINER" -- useradd -ms /bin/bash -G sudo "$miaou_user"
|
|
fi
|
|
if ! lxc exec "$CONTAINER" -- passwd -S "$miaou_user" | cut -d ' ' -f2 | grep -q ^P; then
|
|
shadow_passwd=$(load_yaml_from_expanded credential.shadow)
|
|
shadow_remainder=$(lxc exec "$CONTAINER" -- bash -c "grep $miaou_user /etc/shadow | cut -d':' -f3-")
|
|
lxc exec "$CONTAINER" -- /opt/miaou-bash/tools/append_or_replace "^$miaou_user:.*:" "$miaou_user:$shadow_passwd:$shadow_remainder" /etc/shadow >/dev/null
|
|
fi
|
|
fi
|
|
|
|
if [[ "$OPTION_SSH" == true && "$OPTION_SAMEUSER" == true ]]; then
|
|
#FIXME: can be fatser due to openssh-server already installed from cloud-init
|
|
lxc-miaou-enable-ssh "$CONTAINER" >/dev/null
|
|
fi
|
|
|
|
PREFIX="" echoinfo OK
|
|
|
|
echo "hint: \`lxc login $CONTAINER [--env user=<USER>]\`"
|
|
[[ "$OPTION_SAMEUSER" == true ]] && echo "hint: \`lxc sameuser $CONTAINER\`"
|
|
|
|
true
|
|
}
|
|
|
|
## MAIN
|
|
. "$MIAOU_BASEDIR/lib/init.sh"
|
|
OPTION_SAMEUSER=false
|
|
OPTION_NESTING=false
|
|
OPTION_SSH=false
|
|
PREFIX="miaou"
|
|
|
|
arg1_required "$@" || (usage && exit 1)
|
|
readonly CONTAINER=$1
|
|
readonly CONTAINER_RELEASE="bookworm"
|
|
|
|
shift
|
|
set_options "$@"
|
|
readonly FULL_OPTIONS="$@"
|
|
|
|
check
|
|
create
|