#!/bin/sh
#
# This script is executed within the debian-installer environment when
# pre-pkgsel.d is executed, which is executed before tasksel is
# started.

set -e

. /usr/share/debconf/confmodule

log() {
    logger -t debian-edu-config-pre-pkgsel "$@"
}

error() {
    logger -t debian-edu-config-pre-pkgsel "error: $*"
}

# FIXME Rewrite function/subsystem to allow IP numbers and subnet
# information to be configured at install time.
configure_network() {
# Write a functional /target/etc/network/interfaces
    if [ -z "$PROFILE" ]; then
        PROFILE=Workstation
    fi

    # Default hostname is 'localhost'
    MY_HOSTNAME=localhost

    # Default DNS server is tjener.intern
    NAMESERVER=10.0.2.2

    DNSDOMAIN=intern
    MAILNAME=postoffice.intern

    interfaces=/target/etc/network/interfaces

    # Should it get the information from the netcfg package instead?
    eth0=dhcp
    autoeth0="auto eth0"
    eth1=dhcp
    autoeth1=

    # Hm, what if both server and workstation is choosen?  Choose the
    # server config for eth0.
    for value in `echo $PROFILE |sed 's/ /-/g' | sed 's/,-/ /g'`; do
        case $value in
           Roaming-Workstation)
                # Configure network-manager to connect to eth0 by
                # default, to be able to look up user information in
                # LDAP.
                eth0=none
                autoeth0=""
                eth1=none
                autoeth1=""
                DNSDOMAIN=
                MAILNAME=
                MY_HOSTNAME=
                eth0uuid=$(chroot /target uuid)
                mkdir -p /target/etc/NetworkManager/system-connections
                cat > /target/etc/NetworkManager/system-connections/eth0 <<EOF
[connection]
id=eth0
uuid=$eth0uuid
type=ethernet

[ipv6]
method=auto

[ipv4]
method=auto
EOF
                ;;
            Standalone)
                # Leave network configuration to network-manager on
                # Standalone
                eth0=none
                autoeth0=""
                eth1=none
                autoeth1=""
                DNSDOMAIN=
                MAILNAME=
                MY_HOSTNAME=
                ;;
            Workstation)
                # Use this unless Server also was choosen.
                if [ -z "$eth0" ] ; then
                    eth0=none
                    autoeth0=""
                    eth1=none
                    autoeth1=""
                fi
                ;;
            Main-Server)
                # Override for workstations combining as servers
                eth0=10.0.2.2:255.0.0.0:10.255.255.255:10.0.0.1
                MY_HOSTNAME=tjener
                NAMESERVER=127.0.0.1
                autoeth0="auto eth0"
                ;;
            LTSP-Server)
                # Use this unless Server also was choosen.
                if [ -z "$eth0" ] ; then
                    eth0=none
                    autoeth0=""
                fi
                eth1=192.168.0.254:255.255.255.0:192.168.0.255:none
                autoeth1="auto eth1"
                ;;
        esac
    done

    # Every host need the loopback interface
    cat > $interfaces <<EOF
# Created by debian-edu-profile during the Debian installation.
#
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback
EOF

    for interface in eth0 eth1 ; do
        eval "ifinfo=\$$interface"
        eval "ifauto=\$auto$interface"
        log "setting up network interface $interface using $ifinfo"
        case $ifinfo in
            dhcp)
                cat >> $interfaces <<EOF

$ifauto
iface $interface inet dhcp
EOF

                ;;
            [0-9]*)
                address=`echo $ifinfo | cut -d: -f1`
                netmask=`echo $ifinfo | cut -d: -f2`
                broadcast=`echo $ifinfo | cut -d: -f3`
                gateway=`echo $ifinfo | cut -d: -f4`
                cat >> $interfaces <<EOF

auto $interface
iface $interface inet static
    address $address
    netmask $netmask
    broadcast $broadcast
EOF
                if [ none != "$gateway" ] ; then
                    cat >> $interfaces <<EOF
    gateway $gateway
EOF
                fi
                if [ "$DNSDOMAIN" ] && [ "$NAMESERVER" = "127.0.0.1" ] ; then
                    cat >> $interfaces <<EOF
    dns-search $DNSDOMAIN
    dns-nameservers $NAMESERVER
EOF
                fi
                cat >> $interfaces <<EOF
# The commented lines below is to be used if a DHCP server is in use
#iface $interface inet dhcp
EOF
                ;;
            *)
                # Nothing to do?
                ;;
        esac
    done
    (
        echo "127.0.0.1       localhost.localdomain localhost"
        echo "::1             localhost       ip6-localhost ip6-loopback"
        echo "fe00::0         ip6-localnet"
        echo "ff00::0         ip6-mcastprefix"
        echo "ff02::1         ip6-allnodes"
        echo "ff02::2         ip6-allrouters"
        echo "ff02::3         ip6-allhosts"
    ) > /target/etc/hosts

    # Check whether hostname= was given on boot's /proc/cmdline prompt
    # and use that if not installing a Main-Server.
    PROC_CMDLINE_HOSTNAME=$(cat /proc/cmdline |
        sed -n -re "s/.*(^| )hostname=([^ ]+).*/\2/p" |
        tr A-Z a-z |
        tr -cd 'a-z0-9-' |
        sed -e 's/^-+//' -e 's/-+$//')
    if echo $PROFILE | grep -q Main-Server ; then
        :
    elif [ -n "${PROC_CMDLINE_HOSTNAME}" ]; then
        MY_HOSTNAME="${PROC_CMDLINE_HOSTNAME}"
    fi

    if [ ! -z "$MY_HOSTNAME" ] ; then
        echo "$MY_HOSTNAME" > /target/etc/hostname
        in-target /bin/hostname "$MY_HOSTNAME"
    fi

    # Update hostname based on reverse DNS entry of current IP or
    # generate from MAC address, unless installing main-server.
    if echo $PROFILE | grep -q Main-Server ; then
        :
    elif [ -x /target/usr/sbin/update-hostname-from-ip ] && [ -z "${PROC_CMDLINE_HOSTNAME}" ]; then
        in-target /usr/sbin/update-hostname-from-ip -m || true
    fi

    # Avoid hardcoding entries on the clients, to make sure IP address
    # range can be changed on the clients by changing DHCP
    # configuration on the server.
    if [ "tjener" = "$MY_HOSTNAME" ] ; then
        (
            echo
            echo "10.0.2.2        ${MY_HOSTNAME}.${DNSDOMAIN} ${MY_HOSTNAME}"
        ) >> /target/etc/hosts
    fi

    # Set /etc/mailname if it is missing
    if [ "$MAILNAME" ] && [ ! -f /target/etc/mailname ] ; then
        echo "$MAILNAME" > /target/etc/mailname
    fi

    # Make sure that the interfaces are there for the cfengine run if
    # network isn't already configured
    if route | grep -q default ; then
        log "Not restarting network, as it seem to be up already."
    else
        log "Restarting network to prepare for cfengine run."
        # Redirecting fd 3 as a workaround for skolelinux bug #1229.
        # make sure the redirecting happen inside the chroot, as
        # in-target need to talk to debconf.
        in-target /bin/sh -c "/etc/init.d/networking start 3> /dev/null" || true
        touch /tmp/debian-edu-nonetwork
    fi
}

# Make sure required information is available after user-setup run its
# finish-install hook.
set_kerberos_ldap_passwords() {
    if db_get passwd/root-password-crypted && [ "$RET" ] ; then
        log "No clear text root password, unable to pass it on to Kerberos/LDAP."
    else
        log "Fetching password for Kerberos KDC and LDAP." 1>&2
        db_get passwd/root-password
        ROOTPWD="$RET"

        log "Fetching info for first user." 1>&2

        if db_get passwd/username && [ "$RET" ] ; then
            FIRSTUSERNAME="$RET"
        else
            FIRSTUSERNAME="localadmin"
        fi
        if db_get passwd/user-fullname && [ "$RET" ] ; then
            FIRSTUSERGECOS="$RET"
        else
            FIRSTUSERGECOS="LDAP initial admin user"
        fi
        if db_get passwd/user-password && [ "$RET" ] ; then
            FIRSTUSERPWD="$RET"
        else
            FIRSTUSERPWD="$ROOTPWD"
        fi

        file=/tmp/passwords-preseed
        cat > $file <<EOF
debian-edu-config debian-edu-config/kdc-password password $ROOTPWD
debian-edu-config debian-edu-config/kdc-password-again password $ROOTPWD
debian-edu-config debian-edu-config/ldap-password password $ROOTPWD
debian-edu-config debian-edu-config/ldap-password-again password $ROOTPWD
debian-edu-config debian-edu-config/first-user-name string $FIRSTUSERNAME
debian-edu-config debian-edu-config/first-user-fullname string $FIRSTUSERGECOS
debian-edu-config debian-edu-config/first-user-password password $FIRSTUSERPWD
EOF
        # Pass user and password information into the target
        cat $file | LANG=C chroot /target debconf-set-selections || \
            error "Failed to load preseed values from $file."
        rm $file
    fi
}

# Work around grub bug #712907 (see also bug #763580) by preseeding
# grub-installer/choose_device to the disk used by /target/boot
# This fix it for the most common case.
# FIXME remember to remove this code when the bug is fixed
workaround_grub_issue() {
    log "checking if grub workaround for bug #712907 should be activated."
    bootdev=$(grep /target/boot /proc/mounts | cut -d" " -f1)
    grubdev=$(echo $bootdev | sed -rn 's/^(\/dev\/.*d.)[0-9].*$/\1/p')

    # Only override if it is set to manual or do not have a value,
    # otherwise we assume someone is preseeding it to the value they
    # want.
    db_get grub-installer/choose_bootdev || true
    if [ "$RET" ] && [ "manual" != "$RET" ]; then
        log "not overriding grub-installer/choose_bootdev to $grubdev, its value was '$RET'"
        return
    fi

    case "$bootdev" in
        /dev/sd*|/dev/vd*|/dev/hd*|/dev/xvd*)
            log "overriding grub-installer/choose_bootdev, setting it to $grubdev"
            db_set grub-installer/choose_bootdev "$grubdev" || true
            ;;
    esac
}

workaround_grub_issue

db_get debian-edu-install/profile
PROFILE="$RET"

# Modify tasksel tests so the normal Debian desktop profiles are not
# installed.
in-target /usr/lib/education-tasks/edu-tasksel-setup setup

edu-etcvcs commit

# Configure network also on DVDs to make sure cfengine find a working
# network.
configure_network

edu-etcvcs commit

if echo "$PROFILE" | grep -q Main-Server ; then
        set_kerberos_ldap_passwords
fi

for p in $(echo $PROFILE | tr , " ") ; do
    case $p in
        # Only do this for the networked tasks, not for standalone
        Main-Server|Workstation|Roaming-Workstation|LTSP-Server|Minimal)
            in-target /usr/share/debian-edu-config/tools/preseed-ldap-kerberos
            in-target /usr/share/debian-edu-config/tools/preseed-sitesummary

            # Tell user-setup to not create a user, needed on
            # Main-Server to be able to create the user in LDAP.
            db_set passwd/make-user boolean false
            ;;
    esac
done
