#!/bin/bash
# Copyright (C) 2017
#
# This file is part of cloud. It is used to assist with the following features:
# 1. config_set_passwords
# 2. config_ssh_pub_key
# 3. config_network

RETVAL=0

cdrom_label="config-2"
cloud_init="/usr/bin/cloud-init"
last_action_dir="/usr/local/qcloud/action/"
eject_flag_file="/var/lib/cloud/instance/auto_inject_cdrom.conf"
finished_flag_file="/var/lib/cloud/instance/init_finished.conf"
downsr_script="/usr/local/qcloud/qemudvd/downsr.sh"


log_output() {
    echo "[`date "+%Y-%m-%d %H:%M:%S"`]:${1}"
}

# for cdrom operation start
eject_cdrom() {
    if [ ! -f "${eject_flag_file}" ]; then
        # flag file not existing, skip eject
        log_output "eject flag not existing, skip ejection"
        return 0
    fi
    if [ ! -f "${finished_flag_file}" ]; then
        # flag file not existing, skip eject
        log_output "finished flag not existing, skip ejection"
        return 0
    fi
    if [ ! -f "/var/lib/cloud/instance/sem/config_scripts_user" ]; then
        # not execute scripts_user
        log_output "scripts_user flag not existing, skip ejection"
        return 0
    fi

    log_output "waiting storage sync"
    sync

    log_output "ejecting cdrom"
    dev=$(blkid -tLABEL=$cdrom_label -odevice)
    if [ ! -e "$dev" ]; then
        log_output "cdrom not existing, skip ejection"
        return 0
    fi

    dev_name=${dev##*/}
    bd_path=`readlink /sys/block/$dev_name/device`
    bd_addr=${bd_path##*/}
    echo "$bd_addr" > /sys/block/$dev_name/device/driver/unbind
}

downsr_clear() {
    log_output "clear downsr script"
    if [ -f "${downsr_script}" ]; then
        # check if need backup
        if [ ! -f "${downsr_script}.backup" ]; then
            # backup
            cp "${downsr_script}" "${downsr_script}.backup"
            # empty script
            echo "" > "${downsr_script}"
        fi
    fi
    # create flag file
    touch "${eject_flag_file}"
}

downsr_rollback() {
    # check if need rollback
    log_output "rollback downsr script"
    if [ -f "${downsr_script}.backup" ]; then
        mv "${downsr_script}.backup" "${downsr_script}"
    fi
    # remove flag file
    rm -f "${eject_flag_file}"
}

downsr_auto() {
  grep -q "downsr_rollback" "${1}/openstack/latest/vendor_data.json"
  if [ $? -eq 0 ]; then
      downsr_rollback
  else
      # check if need clear
      grep -q "downsr_clear" "${1}/openstack/latest/vendor_data.json"
      if [ $? -eq 0 ]; then
          downsr_clear
      fi
  fi
}

# support argument
if [ $# -eq 1 ] ; then
    case "$1" in
        eject_cdrom)
            eject_cdrom
            exit 0
            ;;
        downsr_clear)
            downsr_clear
            exit 0
            ;;
        downsr_rollback)
            downsr_rollback
            exit 0
            ;;
    esac
fi
# for cdrom operation end

_exit() {
    umount $mount_dir
    rm -rf $mount_dir
    rm -rf /run/cloud-init/.instance-id

    # eject cdrom
    eject_cdrom

    exit $RETVAL
}

config_set_passwords() {
    log_output "config_set_passwords, begin"
    rm -rf /var/lib/cloud/instance/sem/config_set_passwords
    $cloud_init single --n set-passwords
    RETVAL=$?
    log_output "config_set_passwords return value ${RETVAL}, end"
    return $RETVAL
}

config_set_hostname() {
    log_output "config_set_hostname, begin"
    rm -rf /var/lib/cloud/instance/sem/config_set_hostname
    $cloud_init single --n set_hostname
    hostnamectl --transient set-hostname $hostname &
    hostnamectl --static set-hostname $hostname &
    hostnamectl --pretty set-hostname $hostname &
    RETVAL=$?
    log_output "config_set_hostname return value ${RETVAL}, end"
    return $RETVAL
}

config_set_hosts() {
    log_output "config_set_hosts, begin"
    hosts="127.0.0.1 localhost localhost.localdomain $hostname"
    sed -i "/^127.0.0.1/d" /etc/hosts
    RETVAL=$?
    echo $hosts >> /etc/hosts
    log_output "config_set_hosts return value ${RETVAL}, end"
    return $RETVAL
}

config_network_dhcp() {
    log_output "config_network(dhcp), begin"
    if [ "$reserve_hosts" == "false" ]; then
        config_set_hosts
        config_set_hostname
    fi
    ifdown $network_device
    ifup $network_device
}

config_network_static() {
    log_output "config_network(static), begin"
    ifconfig $network_device $ip_addr netmask $netmask
    ifdown $network_device
    if [ "$reserve_hosts" == "false" ]; then
        config_set_hosts
        config_set_hostname
    fi

    rm -f /var/lib/cloud/instance/sem/config_resolv_conf
    $cloud_init single -n resolv_conf
    RETVAL=$?
    log_output "config_network_static resolv_conf return value ${RETVAL}, end"

    rm -f /var/lib/cloud/instance/sem/config_write_files
    $cloud_init single -n write-files
    RETVAL=$?
    ifup $network_device
    log_output "config_network_static write-files return value ${RETVAL}, end"
}

install_agent() {
    log_output "install_agent, begin"
    cp -r "$mount_dir/qcloud_init/" /
    agent_file="/qcloud_init/install_${agent_name}.sh"
    if [ ! -f "$agent_file" ]
    then
        log_output "$agent_file not exits."
    else
        bash "$agent_file"
    fi

    RETVAL=$?
    rm -rf /qcloud_init/
    log_output "install_agent return value ${RETVAL}, end"
}

config_network() {
    rm -f /var/lib/cloud/data/instance-id
    $cloud_init init --local
    RETVAL=$?

    if [ "$net_boot_type" == "static" ]; then
        config_network_static
    else
        config_network_dhcp
    fi

    log_output "config_network return value ${RETVAL}, end"
}

config_users_groups() {
    log_output "config_users_groups, begin"
    rm -rf /var/lib/cloud/instance/sem/config_users_groups
    $cloud_init single --n users-groups
    RETVAL=$?
    log_output "config_users_groups return value ${RETVAL}, end"
    return $RETVAL
}

config_ssh_pub_key() {
    log_output "config_ssh_pub_key, begin"
    if [ "$username" == "root" ]; then
        ssh_key_file='/root/.ssh/authorized_keys'
    else
        ssh_key_file=/home/${username}/.ssh/authorized_keys
    fi
    rm -f $ssh_key_file
    config_users_groups
    config_set_passwords
    RETVAL=$?
    log_output "config_ssh_pub_key return value ${RETVAL}, end"
    return $RETVAL
}

load_action_conf() {
    dev=$(blkid -tLABEL=$cdrom_label -odevice)
    mount_dir=$(mktemp -d /tmp/tmp.XXXXXX)
    action_file="${mount_dir}""${qcloud_action_file}"
    mount $dev $mount_dir
    if [ -f $action_file ]; then
        . $action_file
        RETVAL=0
    else
        RETVAL=1
    fi
    umount $mount_dir
    rm -rf $mount_dir
    return $RETVAL
}

rm -rf /run/cloud-init/.instance-id
dev=$(blkid -tLABEL=$cdrom_label -odevice)
if [ -z '$dev' ]; then
    dev='/dev/sr0'
fi
mount_dir=$(mktemp -d /tmp/tmp.XXXXXX)
mount $dev $mount_dir

# check if need rollback or clear
downsr_auto "${mount_dir}"


qcloud_action_dir=${mount_dir}/qcloud_action
for action_conf in ${qcloud_action_dir}/*.conf
do
    if [ `basename $action_conf` == "os.conf" ]; then
        continue
    fi
    . $action_conf
    if [ $? -ne 0 ] ; then
        log_output "load ${action_conf} failed."
        continue
    fi
    last_action_file=${last_action_dir}/$action
    last_action_timestamp=`cat $last_action_file`
    current_action_timestamp=$timestamp
    if [ "$last_action_timestamp" == "$current_action_timestamp" ];then
        continue
    fi

    case "$action" in
        config_set_passwords)
            config_set_passwords
            RETVAL=$?
            ;;
        config_ssh_pub_key)
            config_ssh_pub_key
            RETVAL=$?
            ;;
        config_network)
            config_network
            RETVAL=$?
            ;;
        install_agent)
            install_agent
            RETVAL=$?
            ;;
        config_set_hostname)
            config_set_hostname
            RETVAL=$?
            ;;
        *)
            log_output "${action} not found."
            RETVAL=3
            ;;
    esac

    if [ $RETVAL -eq 0 ] ; then
        mkdir -p $last_action_dir
        echo $current_action_timestamp > $last_action_file
    fi
done

_exit
