#
# Set up extra packages and diskless workstation.  Partly based on
# ltsp-make-client originally created by Finn-Arne Johansen.
#
info() {
    echo "info: $@"
}

warning() {
    echo "warning: $@"
}

error() {
    echo "error: $@"
}

in_target() {
    chroot $ROOT "$@"
}

# Clean up changes done to the tasksel behaviour earlier and go back
# to the default behavior.
diverts_remove() {
    for test in desktop ; do
        if [ -f $ROOT/usr/lib/tasksel/tests/$test.edu ] ; then
            rm $ROOT/usr/lib/tasksel/tests/$test
            in_target dpkg-divert --package debian-edu-install --rename --quiet \
                --remove /usr/lib/tasksel/tests/$test
            rm $ROOT/usr/lib/tasksel/tests/$test.edu
        fi
    done
}

# Modify tasksel desktop test so the normal Debian desktop profiles
# are not installed. Use dpkg-divert to to switch to our version while
# tasksel runs.
diverts_insert() {
    file=/usr/lib/tasksel/tests/desktop
    sed -e 's/if desktop_hardware/# Do not install a desktop - added by debian-edu-install\nunmark\n\n&/' \
        <$ROOT$file >$ROOT$file.edu
    in_target dpkg-divert --package debian-edu-install --rename --quiet --add $file
    ln -s ./desktop.edu $ROOT$file
}

disable_cronjob() {
    for jobname in $@ ; do
        for crondir in /etc/cron.d /etc/cron.daily /etc/cron.hourly \
            /etc/cron.monthly /etc/cron.weekly ; do
            job="$ROOT$crondir/$jobname"
            if [ -f "$job" ] ; then
                mv "$job" "${job}~disabled"
            fi
        done
    done
}

append_if_missing() {
    file="$1"
    pattern="$2"
    if [ -f "$file" ] && grep -q "$pattern" "$file" ; then
        :
    else
        (
            if [ -f "$file" ] ; then cat "$file" ; fi
            cat -
        ) > "$file.new" && mv "$file.new" "$file"
    fi
}

etcvcs_commit() {
    msg="$1"
    if [ -x $ROOT/usr/bin/etckeeper ] ; then
	in_target etckeeper commit "$msg" || true
    fi
    if [ -x /usr/bin/etckeeper ] ; then
	etckeeper commit "$msg" || true
    fi
}

# Setting up a diskless workstation, using three parts/functions to
# get more steps on the progress bar shown by d-i.
install_diskless_workstation() {
    etcvcs_commit "Before diskless workstation is set up"

    # Add Edu config with language and profile.
    mkdir -p $ROOT/etc/debian-edu
    sed 's/^PROFILE=\".*/PROFILE=\"Workstation\"/' \
        < /etc/debian-edu/config > $ROOT/etc/debian-edu/config

    # Install the installation package to load preseeding values based
    # on the /etc/debian-edu/config PROFILE
    in_target apt-get install -y -q debian-edu-install

    # Add preseeding values, without the popularity-contest settings
    # to avoid several hosts reporting with the same popcon ID.
    (
        debconf-get-selections | egrep "^locales"
    ) | in_target debconf-set-selections

    # Set same default-wordlist and default-ispell as on the server side
    (
        debconf-get-selections | egrep "^dictionaries-common" | grep default-wordlist
    ) | in_target debconf-set-selections

    (
        debconf-get-selections | egrep "^dictionaries-common" | grep default-ispell
    ) | in_target debconf-set-selections

    if [ -f /etc/locale.gen -a ! -f $ROOT/locale.gen ] ; then
        cp /etc/locale.gen $ROOT/etc/locale.gen
    fi

    if [ -f /etc/environment -a ! -f $ROOT/etc/environment ] ; then
        cp /etc/environment $ROOT/etc/environment
    fi

    # set the timezone
    cp -d /etc/localtime $ROOT/etc
    cp -d /etc/timezone $ROOT/etc

    # Pass on the current desktop setting and the profile we
    # want to install
    (
        debconf-get-selections | grep tasksel/desktop
        echo debian-edu-install debian-edu-install/profile multiselect Workstation
    ) | in_target debconf-set-selections

    # Do not dynamically detect on Main-Server, because in this
    # setting it is not possible for a workstation to get its settings
    # from the Main-Server.
    if grep '^PROFILE=\".*Main-Server.*\"' /etc/debian-edu/config ; then
        ldapserver=$(debian-edu-ldapserver -f)
        ldapbase=$(debian-edu-ldapserver -f -s $ldapserver -b)
        # Tell nslcd to use FQDN for LDAP server to get SSL cert check working
        echo nslcd nslcd/ldap-uris string "ldap://$ldapserver" | \
            in_target debconf-set-selections || \
            error "Failed to load preseed 'nslcd/ldap-uris'"

    else
        # Preseed Kerberos and LDAP stuff before installing packages.
        in_target /usr/share/debian-edu-config/tools/preseed-ldap-kerberos
        # Preseed Sitesummary too
        in_target /usr/share/debian-edu-config/tools/preseed-sitesummary
    fi
}

after_install_diskless_workstation() {
    # Fetch current default locale to make tasksel pick the correct
    # language specific tasks.
    if [ -e /etc/default/locale ] ; then
	. /etc/default/locale
    fi

    # Workaround for sudo refusing to be replaced by sudo-ldap when no
    # root password is set (#586887).
    SUDO_FORCE_REMOVE=yes
    export SUDO_FORCE_REMOVE

    info "installing packages the same way tasksel do it"

    # Query tasksel for its apt-get command, and use it directly to
    # get output from the process.
    diverts_insert
    cmd="$(LANG=$LANG in_target tasksel -t --new-install | sed 's/debconf-apt-progress -- //')"
    info "cmd: $cmd"
    if in_target $cmd ; then
        diverts_remove
    else
        diverts_remove
        return 1
    fi
}

finalization_diskless_workstation() {
    local CANDIDATE=""
    local PURGE=""
    # Get rid of lvm2, as it causes the shutdown to hang.
    CANDIDATE="lvm2"

    # Get rid of munin-node which we do not want on diskless workstations
    CANDIDATE="$CANDIDATE munin-node"

    # LTSP take care of updating resolv.conf, no need to have
    # resolvconf try to do the same.
    CANDIDATE="$CANDIDATE resolvconf"

    # No dynamic network configuration on diskless clients.
    CANDIDATE="$CANDIDATE network-manager wpasupplicant network-manager-openvpn network-manager-pptp network-manager-vpnc"

    # No VPN nor serial network either
    CANDIDATE="$CANDIDATE ppp"

    # No modem either
    CANDIDATE="$CANDIDATE modemmanager"

    # cups isn't needed for LTSP clients to be able to print.
    CANDIDATE="$CANDIDATE cups"

    # Missing unique ID on the clients, so no use keeping it around
    CANDIDATE="$CANDIDATE popularity-contest"

    # Probably not very useful without a disk
    CANDIDATE="$CANDIDATE hdparm hddtemp"

    # Match only installed packages to avoid breaking the installation.
    for p in $(echo $CANDIDATE) ; do
        if in_target dpkg -l $p 2>/dev/null | tail -1 | grep -q  ^ii ; then
            PURGE="$PURGE $p"
        fi
    done

    # purge them alltogether
    in_target apt-get -y purge $PURGE

    # Remove dependencies pulled in by removed packages
    in_target apt-get -y --purge autoremove

    # Disable the cron jobs that should not be running on a diskless
    # workstation (in addition to LTSP default disabled ones).
    # Keep rwhod, shutdown-at-night and sitesummary-client.
    disable_cronjob \
        bsdmainutils \
        desktop-profiles \
        etckeeper \
        killer \
        ntp

    # Make sure ifupdown knows about loopback
    cat <<'EOF' | append_if_missing $ROOT/etc/network/interfaces \
    "iface lo inet loopback"
# The loopback network interface
auto lo
iface lo inet loopback
    dns-search intern
EOF

    # Create /skole, since the chroot will be read-only
    mkdir -p $ROOT/skole

    etcvcs_commit "Before cfengine is executed"

    # Make sure Debian::Edu find the correct LDAP server when
    # autodetection do not work.
    if grep '^PROFILE=\".*Main-Server.*\"' /etc/debian-edu/config ; then
        cat >> $ROOT/etc/ldap/ldap.conf <<EOF
HOST $ldapserver
BASE $ldapbase
EOF
    fi

    # Setup Cfengine3 and apply configuration inside the LTSP chroot.
    in_target /usr/share/debian-edu-config/tools/setup-cfengine3
    in_target /bin/sh -c "cf-agent -D installation 2>&1 | tee /var/log/cfengine3/edu-ltsp-install.log"

    etcvcs_commit "After cfengine is executed"

    # it is nice to have a running ssh for the admin
    rm -f $ROOT/etc/ssh/sshd_not_to_be_run

    etcvcs_commit "After diskless workstation is set up"
}

case "$MODE" in
    commandline)
        add_option "no-diskless-edu-workstation" "$(eval_gettext "do not install debian-edu diskless workstation environment")" "advanced" "false"
        option_diskless_edu_workstation_value=true
        ;;
    configure)
        if [ -n "$option_no_diskless_edu_workstation_value" ]; then
            option_diskless_edu_workstation_value=""
        fi
        # education-thin-client should contain all dependencies needed
        DEBCONF_SEEDS="$DEBCONF_SEEDS /usr/lib/debian-edu-install/defaults.ltsp-chroot"
        LATE_PACKAGES="$LATE_PACKAGES education-thin-client openbsd-inetd"
        if [ -n "$option_diskless_edu_workstation_value" ]; then
            # Be backwards compatible with ltsp-make-client, and allow
            # the diskless workstation setup to be disabled during
            # installation.
            if grep -wq edu-skip-ltsp-make-client /proc/cmdline ; then
                info "Found edu-skip-ltsp-make-client in /proc/cmdline"
                info "Not generating diskless workstation."
                option_diskless_edu_workstation_value=""
            else
                # Try to get the sudo package we want without having
                # to first install sudo and then try to switch to
                # sudo-ldap (which fail due to #586887).
                EARLY_PACKAGES="$EARLY_PACKAGES sudo-ldap"

                LATE_PACKAGES="$LATE_PACKAGES education-tasks"
            fi
        fi
        ;;
    install)
        if [ -n "$option_diskless_edu_workstation_value" ]; then
            if [ "true" = "$LTSP_CDROM_INSTALL" ]; then
                # Our CDs and DVDs are unsigned, so we can not check
                # authentication when using them.  These options
                # should work with apt and aptitude.  Need to do this
                # as well as the --allow-unauthenticated option above,
                # to make sure aptitude work for installing diskless
                # workstation packages.
                (
                    echo 'APT::Get::AllowUnauthenticated "true";'
                    echo 'APT::Authentication::TrustCDROM "true";'
                    echo 'APT::Cmdline::ignore-trust-violations "true";'
                ) >> $ROOT/etc/apt/apt.conf.d/90ltsp-build-client
            fi

            # Bind-mount /var/cache/apt/archives/ on
            # $target/var/cache/apt/archives/, to avoid having to
            # download packages twice.
            chroot_mount /var/cache/apt/archives /var/cache/apt/archives --bind
        fi

        # Try to speed up installation by dropping some fsync() calls
        # in dpkg.  This is the same d-i is doing on first time
        # installations.
        cat > $ROOT/etc/dpkg/dpkg.cfg.d/force-unsafe-io <<EOF
force-unsafe-io
EOF
        ;;
    finalization)
        # Run final setup in finalization step and not in
        # after-install to make sure boot system modifications are
        # done after the ones done in LTSP by default.
        if [ -n "$option_diskless_edu_workstation_value" ]; then
            install_diskless_workstation
            after_install_diskless_workstation
            finalization_diskless_workstation
            if [ "true" = "$LTSP_CDROM_INSTALL" ]; then
                rm -f $ROOT/etc/apt/apt.conf.d/90ltsp-build-client
            fi
        fi

        # Remove dpkg optimization after setup_diskless_workstation,
        # to ensure it have effect while most packages are installed.
        rm $ROOT/etc/dpkg/dpkg.cfg.d/force-unsafe-io
        ;;
esac
