#!/bin/bash
# **** License ****
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# A copy of the GNU General Public License is available as
# `/usr/share/common-licenses/GPL' in the Debian GNU/Linux distribution
# or on the World Wide Web at `http://www.gnu.org/copyleft/gpl.html'.
# You can also obtain it by writing to the Free Software Foundation,
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
# Author:	Tom Grennan <tgrennan@vyatta.com>
# **** End License ****

. /lib/lsb/init-functions

: ${vyatta_env:=/etc/default/vyatta}
source $vyatta_env

declare progname=${0##*/}
declare action=$1; shift

declare -x BOOTFILE=$vyatta_sysconfdir/config/config.boot

# If vyos-config= boot option is present, use that file instead
for x in $(cat /proc/cmdline); do
    [[ $x = vyos-config=* ]] || continue
    VYOS_CONFIG="${x#vyos-config=}"
done

if [ ! -z "$VYOS_CONFIG" ]; then
    if [ -r "$VYOS_CONFIG" ]; then
        echo "Config selected manually: $VYOS_CONFIG"
        declare -x BOOTFILE="$VYOS_CONFIG"
    else
        echo "WARNING: Could not read selected config file, using default!"
    fi
fi

declare -a subinit
declare -a all_subinits=(
    rl-system
    firewall )

if [ $# -gt 0 ] ; then
    for s in $@ ; do
	[ -x ${vyatta_sbindir}/${s}.init ] && subinit[${#subinit}]=$s
    done
else
    for s in ${all_subinits[@]} ; do
	[ -x ${vyatta_sbindir}/${s}.init ] && subinit[${#subinit}]=$s
    done
fi

GROUP=vyattacfg

# check if bootup of this portion is disabled
disabled () {
    grep -q -w no-vyos-$1 /proc/cmdline
}

# if necessary, provide initial config
init_bootfile () {
   if [ ! -r $BOOTFILE ] ; then
	if [ -f $vyatta_sysconfdir/config.boot.default ]; then
	  cp $vyatta_sysconfdir/config.boot.default $BOOTFILE
        else
          $vyos_libexec_dir/system-versions-foot.py > $BOOTFILE
        fi

	chgrp ${GROUP} $BOOTFILE
	chmod 660 $BOOTFILE
    fi
}

# if necessary, migrate initial config
migrate_bootfile ()
{
    if [ -x $vyos_libexec_dir/run-config-migration.py ]; then
        log_progress_msg migrate
        sg ${GROUP} -c "$vyos_libexec_dir/run-config-migration.py $BOOTFILE"
    fi
}

# load the initial config
load_bootfile ()
{
    log_progress_msg configure
    (
      if [ -f /etc/default/vyatta-load-boot ]; then
        # build-specific environment for boot-time config loading
        source /etc/default/vyatta-load-boot
      fi
      if [ -x $vyos_libexec_dir/vyos-boot-config-loader.py ]; then
          sg ${GROUP} -c "$vyos_libexec_dir/vyos-boot-config-loader.py $BOOTFILE"
      else
          # if not available, fallback to earlier version
          sg ${GROUP} -c "$vyatta_sbindir/vyatta-boot-config-loader $BOOTFILE"
      fi
    )
}

# execute the pre-config script
run_preconfig_script ()
{
    if [ -x /config/scripts/vyos-preconfig-bootup.script ]; then
        /config/scripts/vyos-preconfig-bootup.script
    fi
}

# execute the post-config scripts
run_postconfig_scripts ()
{
    if [ -x /config/scripts/vyatta-postconfig-bootup.script ]; then
        /config/scripts/vyatta-postconfig-bootup.script
    fi

    if [ -x /config/scripts/vyos-postconfig-bootup.script ]; then
        /config/scripts/vyos-postconfig-bootup.script
    fi
}

run_postupgrade_script ()
{
    if [ -f /config/.upgraded ]; then
        # Run the system script
        /usr/libexec/vyos/system/post-upgrade

        # Run user scripts
        if [ -d /config/scripts/post-upgrade.d ]; then
            run-parts /config/scripts/post-upgrade.d
        fi

        rm -f /config/.upgraded
    fi
}

# 
# On image booted machines, we need to mount /boot from the image-specific
# boot directory so that kernel package installation will put the
# files in the right place.  We also have to mount /boot/grub from the
# system-wide grub directory so that tools that edit the grub.cfg
# file will find it in the expected location.
#
bind_mount_boot ()
{
	persist_path=$(/opt/vyatta/sbin/vyos-persistpath)
	if [ $? == 0 ]; then
		if [ -e $persist_path/boot ]; then
			image_name=$(cat /proc/cmdline | sed -e s+^.*vyos-union=/boot/++ | sed -e 's/ .*$//')
			
			if [ -n "$image_name" ]; then
				mount --bind $persist_path/boot/$image_name /boot
				
				if [ $? -ne 0 ]; then
					echo "Couldn't bind mount /boot"
				fi
				
				if [ ! -d /boot/grub ]; then
					mkdir /boot/grub
				fi
				
				mount --bind $persist_path/boot/grub /boot/grub
				if [ $? -ne 0 ]; then
					echo "Couldn't bind mount /boot/grub"
				fi
			fi
		fi
	fi
}

start ()
{
    log_daemon_msg "Waiting for NICs to settle down"
    # On boot time udev migth take a long time to reorder nic's, this will ensure that
    # all udev activity is completed and all nics presented at boot-time will have their
    # final name before continuing with vyos-router initialization.
    SECONDS=0
    udevadm settle
    STATUS=$?
    log_progress_msg "settled in ${SECONDS}sec."
    log_end_msg ${STATUS}
    # Fixup for FRR

    # In 5.1 master, zebra thinks existence of /var/run/netns is
    # a requirement for netns support
    mkdir -p /var/run/netns

    # chown the config dir to give all admins access
    chown -R root:frrvty /etc/frr
    chmod 775 /etc/frr

    # Since systemd doesn't work without watchfrr and watchfrr restarts
    # all daemons if just one failed, do the start manually
    /usr/lib/frr/frrinit.sh start

    log_action_begin_msg "Mounting VyOS Config"
    # ensure the vyatta_configdir supports a large number of inodes since
    # the config hierarchy is often inode-bound (instead of size).
    # impose a minimum and then scale up dynamically with the actual size
    # of the system memory.
    local tmem=$(sed -n 's/^MemTotal: \+\([0-9]\+\) kB$/\1/p' /proc/meminfo)
    local tpages
    local tmpfs_opts="nosuid,nodev,mode=775,nr_inodes=0" #automatically allocate inodes
    mount -o $tmpfs_opts -t tmpfs none ${vyatta_configdir} \
      && chgrp ${GROUP} ${vyatta_configdir}
    log_action_end_msg $?

    disabled bootfile || init_bootfile

    log_daemon_msg "Starting VyOS router"
    disabled migrate || migrate_bootfile

    run_preconfig_script

    run_postupgrade_script

    for s in ${subinit[@]} ; do
	if ! disabled $s; then 
	    log_progress_msg $s
	    if ! ${vyatta_sbindir}/${s}.init start
	    then log_failure_msg
		 exit 1
	    fi
	fi
    done

    bind_mount_boot

    disabled configure || load_bootfile
    log_end_msg $?

    telinit q
    chmod g-w,o-w /

    run_postconfig_scripts
}

stop()
{
    local -i status=0
    log_daemon_msg "Stopping VyOS router"
    for ((i=${#sub_inits[@]} - 1; i >= 0; i--)) ; do
	s=${subinit[$i]}
	log_progress_msg $s
	${vyatta_sbindir}/${s}.init stop
	let status\|=$?
    done
    log_end_msg $status
    log_action_begin_msg "Un-mounting VyOS Config"
    umount ${vyatta_configdir}
    log_action_end_msg $?

    /usr/lib/frr/frrinit.sh stop
}

case "$action" in
    start) start ;;
    stop)  stop ;;
    restart|force-reload) stop && start ;;
    *)	log_failure_msg "usage: $progname [ start|stop|restart ] [ subinit ... ]" ;
	false ;;
esac

exit $?

# Local Variables:
# mode: shell-script
# sh-indentation: 4
# End:
