#!/usr/bin/env bash
# Real demos for P025 "DNS Will Finally Make Sense After This".
# A private DNS "internet" of nine Ubuntu 24.04 LXD system containers on their own bridge (ce-p025, 10.53.0.0/24),
# deleted at the end:
#   root-server  10.53.0.11  BIND 9, authoritative for our own root zone "." (delegates test. to tld-server)
#   tld-server   10.53.0.12  BIND 9, authoritative for the top-level domain test. (a name reserved for testing,
#                            RFC 6761; on the internet this would be .com), delegates shop.test to ns.shop.test
#   shop-dns     10.53.0.13  BIND 9, authoritative for shop.test: Ana's DNS server (ns.shop.test)
#   resolver-1   10.53.0.21  Unbound, a recursive resolver (Ana's internet provider), root hints = our root only
#   resolver-2   10.53.0.22  Unbound, a recursive resolver (Ben's internet provider)
#   ana-laptop   10.53.0.101 uses resolver-1         ben-laptop  10.53.0.102 uses resolver-2
#   old-server   10.53.0.50  Ana's shop website, old server   new-server  10.53.0.60  the new server
# The three name servers get a 30 ms delay on their network card (tc netem), standing in for the distance to real
# name servers across the internet; the video says so. Nothing here talks to the real DNS: the resolvers only know
# our root server. Every terminal is a real interactive login shell in a pty (demo_driver.py).
#
# Needs: the LXD snap on render01, internet for the Ubuntu archive (base image only). Takes ~25 minutes: the story
# waits for real TTLs to run out. Run it detached: nohup bash demo.sh > /tmp/p025-demo.log 2>&1 &
set -euo pipefail
cd "$(dirname "$0")"
P=ce-p025
NET=ce-p025
BOXES="root-server tld-server shop-dns resolver-1 resolver-2 ana-laptop ben-laptop old-server new-server"
cleanup() {
  for b in $BOXES; do lxc delete -f $P-$b >/dev/null 2>&1 || true; done
  lxc network delete $NET >/dev/null 2>&1 || true
}
cleanup
[ -n "${KEEP:-}" ] || trap cleanup EXIT

# One base image with the DNS software installed, reused by every box (rebuilt with REBUILD=1).
if [ -n "${REBUILD:-}" ] || ! lxc image info $P-base >/dev/null 2>&1; then
  lxc image delete $P-base >/dev/null 2>&1 || true
  lxc delete -f $P-build >/dev/null 2>&1 || true
  lxc launch -q ubuntu:24.04 $P-build
  lxc exec $P-build -- cloud-init status --wait >/dev/null
  lxc exec $P-build -- bash -c 'apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq \
      bind9 bind9-dnsutils unbound curl >/dev/null && systemctl disable -q --now named unbound && cloud-init clean'
  lxc stop $P-build
  lxc publish -q $P-build --alias $P-base
  lxc delete -f $P-build
fi

lxc network create $NET ipv4.address=10.53.0.1/24 ipv4.nat=true ipv6.address=none ipv4.dhcp.ranges=10.53.0.200-10.53.0.250 >/dev/null
declare -A IP=([root-server]=10.53.0.11 [tld-server]=10.53.0.12 [shop-dns]=10.53.0.13 [resolver-1]=10.53.0.21
               [resolver-2]=10.53.0.22 [ana-laptop]=10.53.0.101 [ben-laptop]=10.53.0.102 [old-server]=10.53.0.50
               [new-server]=10.53.0.60)
for b in $BOXES; do
  lxc init -q $P-base $P-$b --network $NET
  lxc config device set $P-$b eth0 ipv4.address=${IP[$b]}
  lxc start $P-$b
done
for b in $BOXES; do
  until lxc exec $P-$b -- systemctl is-system-running 2>/dev/null | grep -qE 'running|degraded'; do sleep 1; done
  lxc exec $P-$b -- cloud-init status --wait >/dev/null || true
  lxc exec $P-$b -- hostnamectl set-hostname $b
done
python3 - "$P" <demo_driver.py
