#!/bin/bash

set -e

# shellcheck disable=SC1091
. /etc/lsb-release

# shellcheck disable=SC1091
. /usr/lib/eole/ihm.sh

# shellcheck disable=SC1091
. /usr/lib/eole/utils.sh

#eolead.sh fournit CONTAINER_NAME, IP et ROOTFS
# shellcheck disable=SC1091
. /usr/lib/eole/eolead.sh

CACHE_DIR=/var/cache/lxc/${DISTRIB_CODENAME}
PARTIAL_DIR=${CACHE_DIR}/partial-amd64
SSH_EXEC="ssh -t -q -o LogLevel=ERROR -o StrictHostKeyChecking=no root@addc"

REALM=$(CreoleGet ad_domain)
SERVEUR_MAJ=$(CreoleGet serveur_maj | head -n 1)
UBUNTU_MIRROR=$(CreoleGet ubuntu_update_mirrors | head -n 1)
CONTAINER_ETH0=$(CreoleGet ad_public_address)
TIME_ZONE="$(CreoleGet time_zone)"
EOLE_PROXY_ADDRESS=$(CreoleGet proxy_client_adresse '')
EOLE_PROXY_PORT=$(CreoleGet proxy_client_port '')
APT_PROXY_RES=$(apt-config shell APT_PROXY Acquire::http::Proxy)
eval "${APT_PROXY_RES}"

# Do not use agent for connections in the container
unset SSH_AUTH_SOCK

echo
EchoBleu "Génération du conteneur $CONTAINER_NAME"

export DEBIAN_FRONTEND=noninteractive

# Use proxy from APT if not defined
if [ -z "${http_proxy}" ]
then
    if [ -n "${EOLE_PROXY_ADDRESS}" ]
    then
	export http_proxy="http://${EOLE_PROXY_ADDRESS}:${EOLE_PROXY_PORT}"
	export https_proxy="${http_proxy}"
    elif [ -n "${APT_PROXY}" ]
    then
	export http_proxy=${APT_PROXY}
	export https_proxy=${APT_PROXY}
    fi
fi

mkdir -p "${PARTIAL_DIR}"/etc/apt/apt.conf.d
#We need Apt::Pipeline and No:Cache
cp /etc/apt/apt-eole.conf "${PARTIAL_DIR}"/etc/apt/apt.conf
if [ -n "${http_proxy}" ]
then
    cat > "${PARTIAL_DIR}"/etc/apt/apt.conf.d/02eoleproxy <<EOF
Acquire::http::Proxy "${http_proxy}";
Acquire::https::Proxy "${http_proxy}";
EOF
fi

# Réseau des conteneurs en 192.0.2.0/24
cat > /etc/default/lxc-net <<EOF
USE_LXC_BRIDGE="true"
LXC_BRIDGE="br0"
LXC_ADDR="192.0.2.1"
LXC_NETMASK="255.255.255.0"
LXC_NETWORK="192.0.2.0/24"
EOF

systemctl stop lxc-net
ip link del lxcbr0 2>/dev/null || true
sed -i 's/lxc.network.link.*/lxc.network.link = br0/' /etc/lxc/default.conf
systemctl start lxc-net

# Tester si l'ip publique du conteneur est disponible sur le réseau
ADPUBLICADRESS=$(CreoleGet ad_public_address)
if /usr/bin/arping -f -c 1 -I "$(CreoleGet interface_gw)" "$ADPUBLICADRESS" >/dev/null 2>&1
then
    EchoRouge "L'IP publique du conteneur $CONTAINER_NAME n'est pas disponible $ADPUBLICADRESS"
    exit 1
fi

# Tester si l'ip publique du conteneur n'est pas déjà assignée localement
if ip addr | grep -q " $ADPUBLICADRESS/"
then
    EchoRouge "L'IP publique du conteneur $CONTAINER_NAME est déjà utilisée localement $ADPUBLICADRESS"
    exit 1
fi

# Tester si les dns des dépôts sont résolus
if ! dig "$SERVEUR_MAJ" >/dev/null 2>&1
then
    EchoBleu "Le noms de domaine du dépôt $SERVEUR_MAJ n'est pas résolu (avant création conteneur)"
    if ! dig "$UBUNTU_MIRROR" >/dev/null 2>&1
    then
        EchoRouge "Les noms de domaine des dépôts ne sont pas résolus = $SERVEUR_MAJ et $UBUNTU_MIRROR (avant création conteneur)"
        exit 1
    fi
fi

# Création du conteneur
lxc-create -n "$CONTAINER_NAME" -t ubuntu -- -r "$DISTRIB_CODENAME" -u "$DISTRIB_ID" -S ~root/.ssh/eole.pub --mirror "http://$UBUNTU_MIRROR/ubuntu" --packages bind9-dnsutils

# Workaround us keyboard set by lxc-create (#24385)
service keyboard-setup restart

echo
EchoBleu "Configuration du conteneur $CONTAINER_NAME"

# Configure keyboard
cp /etc/default/keyboard "${CONTAINER_ROOTFS}"/etc/default/keyboard

# addc container in the master timezone #24933, #35216
ZONE_FILE="/usr/share/zoneinfo/$TIME_ZONE"
if [ -f "$ZONE_FILE" ]; then
    echo "$TIME_ZONE" > "${CONTAINER_ROOTFS}"/etc/timezone
    ln -nsf "$ZONE_FILE" "${CONTAINER_ROOTFS}"/etc/localtime
else
    EchoOrange "Pas de fuseau horaire $TIME_ZONE."
fi

[ ! -f /root/.ssh/eole.pub ] && eole-ssh-keygen
mkdir -p "$CONTAINER_ROOTFS"/root/.ssh/
cp /root/.ssh/eole.pub "$CONTAINER_ROOTFS"/root/.ssh/authorized_keys
chmod -R 600 "$CONTAINER_ROOTFS"/root/.ssh/

rm -f "$CONTAINER_ROOTFS"/etc/network/interfaces

chroot "$CONTAINER_ROOTFS" apt-get purge -y resolvconf ubuntu-advantage-pro
[ -L "$CONTAINER_ROOTFS"/etc/resolv.conf ] && rm -f "$CONTAINER_ROOTFS"/etc/resolv.conf

CreoleCat -dt addc.resolv.conf
CreoleCat -dt addc.10-lxc.yaml
CreoleCat -dt addc.lxc.config

cat > "$CONTAINER_ROOTFS"/etc/nsswitch.conf <<EOF
passwd:         compat winbind
group:          compat winbind
shadow:         compat
gshadow:        files

hosts:          files dns
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

netgroup:       nis
EOF

mkdir -p "$CONTAINER_ROOTFS"/etc/eole
CreoleCat -dt samba4-vars-addc.conf

mkdir -p "$CONTAINER_ROOTFS"/usr/lib/eole
cp /usr/lib/eole/ihm.sh "$CONTAINER_ROOTFS/usr/lib/eole/ihm.sh"
cp /usr/bin/tcpcheck "$CONTAINER_ROOTFS/usr/bin/tcpcheck"
cp /usr/sbin/eole-ssh-keygen "$CONTAINER_ROOTFS/usr/sbin/eole-ssh-keygen"
sed -i 's/python$/python3/' "$CONTAINER_ROOTFS/usr/bin/tcpcheck"

ConfigureSourcesList

echo
EchoBleu "Démarrage du conteneur $CONTAINER_NAME"
lxc-start -n "$CONTAINER_NAME" -d

# attente RUNNING au sens LXC (!= systemd)
if lxc-wait -n addc -s RUNNING
then
    EchoBleu "Le conteneur $CONTAINER_NAME a démarré"
else
    if [ $? -eq 2 ]
    then
        EchoBleu "Le conteneur $CONTAINER_NAME est déjà démarré"
    else
        EchoRouge "Le conteneur $CONTAINER_NAME n'a pas démarré"
        exit 1
    fi
fi

echo "Attente Addc" >/var/log/samba/create_addc.log
try=0
max_try=10
while [ ${try} -le ${max_try} ]; do
    echo "-----------------------------------------------------" >>/var/log/samba/create_addc.log
    lxc-attach -n addc -- /bin/ps fax >>/var/log/samba/create_addc.log 2>&1 || /bin/true
    IS_RUNNING="$(lxc-attach -n addc -- /bin/systemctl is-system-running || /bin/true)"
    if [ "$IS_RUNNING" == degraded ]
    then
        EchoOrange "Conteneur addc démarré en mode dégradé !"
        EchoOrange "Les services suivants sont en état \"failed\" :"
        lxc-attach -n addc -- systemctl list-units --failed --no-pager | grep failed | xargs
        break
    fi
    if [ "$IS_RUNNING" == running ]
    then
        echo -n "Serveur démarré : "
        lxc-attach -n addc -- /bin/cat /etc/hostname
        break
    fi
    if [ "$IS_RUNNING" == maintenance ] || [ "$IS_RUNNING" == stopping ] ||
       [ "$IS_RUNNING" == unknown ] || [ ${try} -eq ${max_try} ]; then
        EchoRouge "Impossible de démarrer le conteneur : $IS_RUNNING"
        (
          echo "addc: /bin/journalctl --no-pager "
          echo "-----------------------------------------------------"
          lxc-attach -n addc -- /bin/journalctl --no-pager || /bin/true
          echo "-----------------------------------------------------"
        ) >>/var/log/samba/create_addc.log 2>&1
        exit 1
    fi
    echo "Conteneur addc en cours de démarrage : $IS_RUNNING"
    sleep 5
    try=$((try+1))
done

while [ ${try} -le ${max_try} ]; do
    if tcpcheck 1 "$CONTAINER_IP":22 >/dev/null
    then
        break
    fi
    if [ ${try} -eq ${max_try} ]; then
        EchoRouge "Impossible de contacter le conteneur via ssh"
        (
          echo "addc: /bin/journalctl --no-pager "
          echo "-----------------------------------------------------"
          lxc-attach -n addc -- /bin/journalctl --no-pager || /bin/true
          echo "-----------------------------------------------------"
        ) >>/var/log/samba/create_addc.log 2>&1
        exit 1
    fi
    echo "Conteneur addc en attente de démarrage SSH"
    sleep 5
    try=$((try+1))
done

echo
EchoBleu "Finalisation du conteneur $CONTAINER_NAME"

cat > "$CONTAINER_ROOTFS"/usr/sbin/policy-rc.d <<EOF
#!/bin/sh
exit 101
EOF
chmod a+x "$CONTAINER_ROOTFS"/usr/sbin/policy-rc.d

# Tester si les dns des dépôts sont résolus dans le conteneur
lxc-attach -n addc -- /usr/sbin/userdel -r Ubuntu 2>/dev/null
if ! lxc-attach -n addc -- dig "$SERVEUR_MAJ" >/dev/null 2>&1
then
    EchoBleu "Le nom de domaine du dépôt $SERVEUR_MAJ n'est pas résolu (dans conteneur)"
    if ! lxc-attach -n addc -- dig "$UBUNTU_MIRROR" >/dev/null 2>&1
    then
        EchoRouge "Les noms de domaine des dépôts ne sont pas résolus = $SERVEUR_MAJ et $UBUNTU_MIRROR (dans conteneur)"
        exit 1
    fi
fi

lxc-attach -n addc -- /usr/bin/apt-get update
lxc-attach -n addc --set-var DEBIAN_FRONTEND=noninteractive -- /usr/bin/apt-get install eole-ad-pkg -y
lxc-attach -n addc -- /usr/bin/apt-get clean

CreoleCat -dt ssh_config

if [ ! -f "$CONTAINER_ROOTFS"/var/lib/samba/ntp_signd ]
then
    $SSH_EXEC "install -d /var/lib/samba/ntp_signd"
    $SSH_EXEC "chown root:ntpsec /var/lib/samba/ntp_signd"
    $SSH_EXEC "chmod 0750 /var/lib/samba/ntp_signd"
fi

cat > "$CONTAINER_ROOTFS"/etc/krb5.conf <<EOF
[libdefaults]
default_realm = ${REALM^^}
dns_lookup_realm = false
dns_lookup_kdc = false

[realms]
${REALM^^} = {
kdc = $CONTAINER_ETH0
}

[domain_realms]
.${REALM} = ${REALM^^}
${REALM} = ${REALM^^}
EOF

# fichier : "$CONTAINER_ROOTFS"/etc/samba/smb.conf
CreoleCat -dt smb-addc.conf
sed -i -e "s,^\(\s*tls cafile =\).*,\1 /var/lib/samba/private/tls/ca.pem," "$CONTAINER_ROOTFS"/etc/samba/smb.conf

CreoleCat -dt ntp.conf

echo
EchoBleu "Configuration du service samba-ad-dc"
$SSH_EXEC "systemctl mask smbd"
$SSH_EXEC "systemctl mask nmbd"
$SSH_EXEC "systemctl mask winbind"
$SSH_EXEC "systemctl unmask samba-ad-dc"
$SSH_EXEC "systemctl enable samba-ad-dc"

rm "$CONTAINER_ROOTFS"/usr/sbin/policy-rc.d

$SSH_EXEC ". /usr/lib/eole/samba4.sh && . /etc/eole/samba4-vars.conf && samba_instance"

cp "$CONTAINER_ROOTFS"/etc/krb5.conf "$CONTAINER_ROOTFS"/var/lib/samba/private/krb5.conf

[ ! -e /var/log/samba-ad-dc ] && ln -ns "$CONTAINER_ROOTFS"/var/log/samba /var/log/samba-ad-dc

# clean container cache
rm -rf "${CACHE_DIR}"

echo
