# vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright (c) 2012 Hewlett-Packard Development Company, L.P.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.


# This file provides devstack with the environment and utilities to
# control nova-compute's baremetal driver.
# It sets reasonable defaults to run within a single host,
# using virtual machines in place of physical hardware.
# However, by changing just a few options, devstack+baremetal can in fact
# control physical hardware resources on the same network, if you know
# the MAC address(es) and IPMI credentials.
#
# At a minimum, to enable the baremetal driver, you must set these in loclarc:
#    VIRT_DRIVER=baremetal
#    ENABLED_SERVICES="$ENABLED_SERVICES,baremetal"
#
#
# We utilize diskimage-builder to create a ramdisk, and then
# baremetal driver uses that to push a disk image onto the node(s).
#
# Below we define various defaults which control the behavior of the
# baremetal compute service, and inform it of the hardware it will contorl.
#
# Below that, various functions are defined, which are called by devstack
# in the following order:
#
#  before nova-cpu starts:
#  - prepare_baremetal_toolchain
#  - configure_baremetal_nova_dirs
#
#  after nova and glance have started:
#  - build_and_upload_baremetal_deploy_k_and_r $token
#  - create_baremetal_flavor $BM_DEPLOY_KERNEL_ID $BM_DEPLOY_RAMDISK_ID
#  - upload_baremetal_image $url $token
#  - add_baremetal_node <first_mac> <second_mac>


# Save trace setting
XTRACE=$(set +o | grep xtrace)
set +o xtrace

# Sub-driver settings
# -------------------

# sub-driver to use for kernel deployment
#  - nova.virt.baremetal.pxe.PXE
#  - nova.virt.baremetal.tilera.TILERA
BM_DRIVER=${BM_DRIVER:-nova.virt.baremetal.pxe.PXE}

# sub-driver to use for remote power management
# - nova.virt.baremetal.fake.FakePowerManager, for manual power control
# - nova.virt.baremetal.ipmi.IPMI, for remote IPMI
# - nova.virt.baremetal.tilera_pdu.Pdu, for TilePro hardware
BM_POWER_MANAGER=${BM_POWER_MANAGER:-nova.virt.baremetal.fake.FakePowerManager}


# These should be customized to your environment and hardware
# -----------------------------------------------------------

# whether to create a fake environment, eg. for devstack-gate
BM_USE_FAKE_ENV=`trueorfalse False $BM_USE_FAKE_ENV`

# Extra options to pass to bm_poseur
# change the bridge name or IP: --bridge br99 --bridge-ip 192.0.2.1
# change the virtualization type: --engine qemu
BM_POSEUR_EXTRA_OPTS=${BM_POSEUR_EXTRA_OPTS:-}

# BM_DNSMASQ_IFACE should match FLAT_NETWORK_BRIDGE
if [ "$BM_USE_FAKE_ENV" ]; then
    BM_DNSMASQ_IFACE=${BM_DNSMASQ_IFACE:-br99}
    BM_DNSMASQ_RANGE=${BM_DNSMASQ_RANGE:-192.0.2.32,192.0.2.48}
else
    BM_DNSMASQ_IFACE=${BM_DNSMASQ_IFACE:-eth0}
    # if testing on a physical network,
    # BM_DNSMASQ_RANGE must be changed to suit your network
    BM_DNSMASQ_RANGE=${BM_DNSMASQ_RANGE:-}
fi

# BM_DNSMASQ_DNS provide dns server to bootstrap clients
BM_DNSMASQ_DNS=${BM_DNSMASQ_DNS:-}

# BM_FIRST_MAC *must* be set to the MAC address of the node you will boot.
#              This is passed to dnsmasq along with the kernel/ramdisk to
#              deploy via PXE.
BM_FIRST_MAC=${BM_FIRST_MAC:-}

# BM_SECOND_MAC is only important if the host has >1 NIC.
BM_SECOND_MAC=${BM_SECOND_MAC:-}

# Hostname for the baremetal nova-compute node, if not run on this host
BM_HOSTNAME=${BM_HOSTNAME:-$(hostname -f)}

# BM_PM_* options are only necessary if BM_POWER_MANAGER=...IPMI
BM_PM_ADDR=${BM_PM_ADDR:-0.0.0.0}
BM_PM_USER=${BM_PM_USER:-user}
BM_PM_PASS=${BM_PM_PASS:-pass}

# BM_FLAVOR_* options are arbitrary and not necessarily related to physical
#             hardware capacity. These can be changed if you are testing
#             BaremetalHostManager with multiple nodes and different flavors.
BM_CPU_ARCH=${BM_CPU_ARCH:-x86_64}
BM_FLAVOR_CPU=${BM_FLAVOR_CPU:-1}
BM_FLAVOR_RAM=${BM_FLAVOR_RAM:-1024}
BM_FLAVOR_ROOT_DISK=${BM_FLAVOR_ROOT_DISK:-10}
BM_FLAVOR_EPHEMERAL_DISK=${BM_FLAVOR_EPHEMERAL_DISK:-0}
BM_FLAVOR_SWAP=${BM_FLAVOR_SWAP:-1}
BM_FLAVOR_NAME=${BM_FLAVOR_NAME:-bm.small}
BM_FLAVOR_ID=${BM_FLAVOR_ID:-11}
BM_FLAVOR_ARCH=${BM_FLAVOR_ARCH:-$BM_CPU_ARCH}


# Below this, we set some path and filenames.
# Defaults are probably sufficient.
BM_IMAGE_BUILD_DIR=${BM_IMAGE_BUILD_DIR:-$DEST/diskimage-builder}
BM_POSEUR_DIR=${BM_POSEUR_DIR:-$DEST/bm_poseur}

BM_HOST_CURRENT_KERNEL=$(uname -r)
BM_DEPLOY_RAMDISK=${BM_DEPLOY_RAMDISK:-bm-deploy-$BM_HOST_CURRENT_KERNEL-initrd}
BM_DEPLOY_KERNEL=${BM_DEPLOY_KERNEL:-bm-deploy-$BM_HOST_CURRENT_KERNEL-vmlinuz}

# If you need to add any extra flavors to the deploy ramdisk image
# eg, specific network drivers, specify them here
BM_DEPLOY_FLAVOR=${BM_DEPLOY_FLAVOR:-}

# set URL and version for google shell-in-a-box
BM_SHELL_IN_A_BOX=${BM_SHELL_IN_A_BOX:-http://shellinabox.googlecode.com/files/shellinabox-2.14.tar.gz}


# Functions
# ---------

# Check if baremetal is properly enabled
# Returns false if VIRT_DRIVER is not baremetal, or if ENABLED_SERVICES
# does not contain "baremetal"
function is_baremetal() {
    if [[ "$ENABLED_SERVICES" =~ 'baremetal' && "$VIRT_DRIVER" = 'baremetal' ]]; then
        return 0
    fi
    return 1
}

# Install diskimage-builder and shell-in-a-box
# so that we can build the deployment kernel & ramdisk
function prepare_baremetal_toolchain() {
    git_clone $BM_IMAGE_BUILD_REPO $BM_IMAGE_BUILD_DIR $BM_IMAGE_BUILD_BRANCH
    git_clone $BM_POSEUR_REPO $BM_POSEUR_DIR $BM_POSEUR_BRANCH

    local shellinabox_basename=$(basename $BM_SHELL_IN_A_BOX)
    if [[ ! -e $DEST/$shellinabox_basename ]]; then
        cd $DEST
        wget $BM_SHELL_IN_A_BOX
    fi
    if [[ ! -d $DEST/${shellinabox_basename%%.tar.gz} ]]; then
        cd $DEST
        tar xzf $shellinabox_basename
    fi
    if [[ ! $(which shellinaboxd) ]]; then
        cd $DEST/${shellinabox_basename%%.tar.gz}
        ./configure
        make
        sudo make install
    fi
}

# set up virtualized environment for devstack-gate testing
function create_fake_baremetal_env() {
    local bm_poseur="$BM_POSEUR_DIR/bm_poseur"
    # TODO(deva): add support for >1 VM
    sudo $bm_poseur $BM_POSEUR_EXTRA_OPTS create-bridge
    sudo $bm_poseur $BM_POSEUR_EXTRA_OPTS create-vm
    BM_FIRST_MAC=$(sudo $bm_poseur get-macs)

    # NOTE: there is currently a limitation in baremetal driver
    #       that requires second MAC even if it is not used.
    #       Passing a fake value allows this to work.
    # TODO(deva): remove this after driver issue is fixed.
    BM_SECOND_MAC='12:34:56:78:90:12'
}

function cleanup_fake_baremetal_env() {
    local bm_poseur="$BM_POSEUR_DIR/bm_poseur"
    sudo $bm_poseur $BM_POSEUR_EXTRA_OPTS destroy-vm
    sudo $bm_poseur $BM_POSEUR_EXTRA_OPTS destroy-bridge
}

# prepare various directories needed by baremetal hypervisor
function configure_baremetal_nova_dirs() {
    # ensure /tftpboot is prepared
    sudo mkdir -p /tftpboot
    sudo mkdir -p /tftpboot/pxelinux.cfg
    sudo cp /usr/lib/syslinux/pxelinux.0 /tftpboot/
    sudo chown -R $STACK_USER:libvirtd /tftpboot

    # ensure $NOVA_STATE_PATH/baremetal is prepared
    sudo mkdir -p $NOVA_STATE_PATH/baremetal
    sudo mkdir -p $NOVA_STATE_PATH/baremetal/console
    sudo mkdir -p $NOVA_STATE_PATH/baremetal/dnsmasq
    sudo touch $NOVA_STATE_PATH/baremetal/dnsmasq/dnsmasq-dhcp.host
    sudo chown -R $STACK_USER $NOVA_STATE_PATH/baremetal

    # ensure dnsmasq is installed but not running
    # because baremetal driver will reconfigure and restart this as needed
    is_package_installed dnsmasq || install_package dnsmasq
    stop_service dnsmasq
}

# build deploy kernel+ramdisk, then upload them to glance
# this function sets BM_DEPLOY_KERNEL_ID and BM_DEPLOY_RAMDISK_ID
function upload_baremetal_deploy() {
    token=$1

    if [ ! -e $TOP_DIR/files/$BM_DEPLOY_KERNEL -a -e /boot/vmlinuz-$BM_HOST_CURRENT_KERNEL ]; then
        sudo cp /boot/vmlinuz-$BM_HOST_CURRENT_KERNEL $TOP_DIR/files/$BM_DEPLOY_KERNEL
        sudo chmod a+r $TOP_DIR/files/$BM_DEPLOY_KERNEL
    fi
    if [ ! -e $TOP_DIR/files/$BM_DEPLOY_RAMDISK ]; then
       $BM_IMAGE_BUILD_DIR/bin/ramdisk-image-create $BM_DEPLOY_FLAVOR deploy \
           -o $TOP_DIR/files/$BM_DEPLOY_RAMDISK -k $BM_HOST_CURRENT_KERNEL
    fi

    # load them into glance
    BM_DEPLOY_KERNEL_ID=$(glance \
         --os-auth-token $token \
         --os-image-url http://$GLANCE_HOSTPORT \
         image-create \
         --name $BM_DEPLOY_KERNEL \
         --public --disk-format=aki \
         < $TOP_DIR/files/$BM_DEPLOY_KERNEL  | grep ' id ' | get_field 2)
    BM_DEPLOY_RAMDISK_ID=$(glance \
         --os-auth-token $token \
         --os-image-url http://$GLANCE_HOSTPORT \
         image-create \
         --name $BM_DEPLOY_RAMDISK \
         --public --disk-format=ari \
         < $TOP_DIR/files/$BM_DEPLOY_RAMDISK  | grep ' id ' | get_field 2)
}

# create a basic baremetal flavor, associated with deploy kernel & ramdisk
#
# Usage: create_baremetal_flavor <aki_uuid> <ari_uuid>
function create_baremetal_flavor() {
    aki=$1
    ari=$2
    nova flavor-create $BM_FLAVOR_NAME $BM_FLAVOR_ID \
            $BM_FLAVOR_RAM $BM_FLAVOR_ROOT_DISK $BM_FLAVOR_CPU
    nova flavor-key $BM_FLAVOR_NAME set \
            "cpu_arch"="$BM_FLAVOR_ARCH" \
            "baremetal:deploy_kernel_id"="$aki" \
            "baremetal:deploy_ramdisk_id"="$ari"

}

# pull run-time kernel/ramdisk out of disk image and load into glance
# note that $file is currently expected to be in qcow2 format
# Sets KERNEL_ID and RAMDISK_ID
#
# Usage: extract_and_upload_k_and_r_from_image $token $file
function extract_and_upload_k_and_r_from_image() {
    token=$1
    file=$2
    image_name=$(basename "$file" ".qcow2")

    # this call returns the file names as "$kernel,$ramdisk"
    out=$($BM_IMAGE_BUILD_DIR/bin/disk-image-get-kernel \
            -x -d $TOP_DIR/files -o bm-deploy -i $file)
    if [ $? -ne 0 ]; then
        die "Failed to get kernel and ramdisk from $file"
    fi
    XTRACE=$(set +o | grep xtrace)
    set +o xtrace
    out=$(echo "$out" | tail -1)
    $XTRACE
    OUT_KERNEL=${out%%,*}
    OUT_RAMDISK=${out##*,}

    # load them into glance
    KERNEL_ID=$(glance \
         --os-auth-token $token \
         --os-image-url http://$GLANCE_HOSTPORT \
         image-create \
         --name $image_name-kernel \
         --public --disk-format=aki \
         < $TOP_DIR/files/$OUT_KERNEL | grep ' id ' | get_field 2)
    RAMDISK_ID=$(glance \
         --os-auth-token $token \
         --os-image-url http://$GLANCE_HOSTPORT \
         image-create \
         --name $image_name-initrd \
         --public --disk-format=ari \
         < $TOP_DIR/files/$OUT_RAMDISK | grep ' id ' | get_field 2)
}


# Re-implementation of devstack's "upload_image" function
#
# Takes the same parameters, but has some peculiarities which made it
# easier to create a separate method, rather than complicate the logic
# of the existing function.
function upload_baremetal_image() {
    local image_url=$1
    local token=$2

    # Create a directory for the downloaded image tarballs.
    mkdir -p $FILES/images

    # Downloads the image (uec ami+aki style), then extracts it.
    IMAGE_FNAME=`basename "$image_url"`
    if [[ ! -f $FILES/$IMAGE_FNAME || \
        "$(stat -c "%s" $FILES/$IMAGE_FNAME)" = "0" ]]; then
        wget -c $image_url -O $FILES/$IMAGE_FNAME
        if [[ $? -ne 0 ]]; then
            echo "Not found: $image_url"
            return
        fi
    fi

    local KERNEL=""
    local RAMDISK=""
    local DISK_FORMAT=""
    local CONTAINER_FORMAT=""
    case "$IMAGE_FNAME" in
        *.tar.gz|*.tgz)
            # Extract ami and aki files
            [ "${IMAGE_FNAME%.tar.gz}" != "$IMAGE_FNAME" ] &&
                IMAGE_NAME="${IMAGE_FNAME%.tar.gz}" ||
                IMAGE_NAME="${IMAGE_FNAME%.tgz}"
            xdir="$FILES/images/$IMAGE_NAME"
            rm -Rf "$xdir";
            mkdir "$xdir"
            tar -zxf $FILES/$IMAGE_FNAME -C "$xdir"
            KERNEL=$(for f in "$xdir/"*-vmlinuz* "$xdir/"aki-*/image; do
                     [ -f "$f" ] && echo "$f" && break; done; true)
            RAMDISK=$(for f in "$xdir/"*-initrd* "$xdir/"ari-*/image; do
                     [ -f "$f" ] && echo "$f" && break; done; true)
            IMAGE=$(for f in "$xdir/"*.img "$xdir/"ami-*/image; do
                     [ -f "$f" ] && echo "$f" && break; done; true)
            if [[ -z "$IMAGE_NAME" ]]; then
                IMAGE_NAME=$(basename "$IMAGE" ".img")
            fi
            DISK_FORMAT=ami
            CONTAINER_FORMAT=ami
            ;;
        *.qcow2)
            IMAGE="$FILES/${IMAGE_FNAME}"
            IMAGE_NAME=$(basename "$IMAGE" ".qcow2")
            DISK_FORMAT=qcow2
            CONTAINER_FORMAT=bare
            ;;
        *) echo "Do not know what to do with $IMAGE_FNAME"; false;;
    esac

    if [ "$CONTAINER_FORMAT" = "bare" ]; then
        extract_and_upload_k_and_r_from_image $token $IMAGE
    elif [ "$CONTAINER_FORMAT" = "ami" ]; then
        KERNEL_ID=$(glance \
            --os-auth-token $token \
            --os-image-url http://$GLANCE_HOSTPORT \
            image-create \
            --name "$IMAGE_NAME-kernel" --public \
            --container-format aki \
            --disk-format aki < "$KERNEL" | grep ' id ' | get_field 2)
        RAMDISK_ID=$(glance \
            --os-auth-token $token \
            --os-image-url http://$GLANCE_HOSTPORT \
            image-create \
            --name "$IMAGE_NAME-ramdisk" --public \
            --container-format ari \
            --disk-format ari < "$RAMDISK" | grep ' id ' | get_field 2)
    else
       # TODO(deva): add support for other image types
       return
    fi

    glance \
       --os-auth-token $token \
       --os-image-url http://$GLANCE_HOSTPORT \
       image-create \
       --name "${IMAGE_NAME%.img}" --public \
       --container-format $CONTAINER_FORMAT \
       --disk-format $DISK_FORMAT \
       ${KERNEL_ID:+--property kernel_id=$KERNEL_ID} \
       ${RAMDISK_ID:+--property ramdisk_id=$RAMDISK_ID} < "${IMAGE}"

    # override DEFAULT_IMAGE_NAME so that tempest can find the image 
    # that we just uploaded in glance
    DEFAULT_IMAGE_NAME="${IMAGE_NAME%.img}"
}

function clear_baremetal_of_all_nodes() {
    list=$(nova baremetal-node-list | awk -F '| ' 'NR>3 {print $2}' )
    for node in $list
    do
        nova baremetal-node-delete $node
    done
}

# inform nova-baremetal about nodes, MACs, etc
# Defaults to using BM_FIRST_MAC and BM_SECOND_MAC if parameters not specified
#
# Usage: add_baremetal_node <first_mac> <second_mac>
function add_baremetal_node() {
    mac_1=${1:-$BM_FIRST_MAC}
    mac_2=${2:-$BM_SECOND_MAC}

    id=$(nova baremetal-node-create \
       --pm_address="$BM_PM_ADDR" \
       --pm_user="$BM_PM_USER" \
       --pm_password="$BM_PM_PASS" \
       "$BM_HOSTNAME" \
       "$BM_FLAVOR_CPU" \
       "$BM_FLAVOR_RAM" \
       "$BM_FLAVOR_ROOT_DISK" \
       "$mac_1" \
       | grep ' id ' | get_field 2 )
    [ $? -eq 0 ] || [ "$id" ] || die "Error adding baremetal node"
    id2=$(nova baremetal-add-interface "$id" "$mac_2" )
    [ $? -eq 0 ] || [ "$id2" ] || die "Error adding interface to barmetal node $id"
}


# Restore xtrace
$XTRACE
