#!/bin/bash
#
# lib/ironic
# Functions to control the configuration and operation of the **Ironic** service

# Dependencies:
#
# - ``functions`` file
# - ``DEST``, ``DATA_DIR``, ``STACK_USER`` must be defined
# - ``SERVICE_{TENANT_NAME|PASSWORD}`` must be defined
# - ``SERVICE_HOST``
# - ``KEYSTONE_TOKEN_FORMAT`` must be defined

# ``stack.sh`` calls the entry points in this order:
#
# - install_ironic
# - install_ironicclient
# - init_ironic
# - start_ironic
# - stop_ironic
# - cleanup_ironic

# Save trace and pipefail settings
XTRACE=$(set +o | grep xtrace)
PIPEFAIL=$(set +o | grep pipefail)
set +o xtrace
set +o pipefail

# Defaults
# --------

# Set up default directories
GITDIR["python-ironicclient"]=$DEST/python-ironicclient

IRONIC_DIR=$DEST/ironic
IRONIC_PYTHON_AGENT_DIR=$DEST/ironic-python-agent
IRONIC_DATA_DIR=$DATA_DIR/ironic
IRONIC_STATE_PATH=/var/lib/ironic
IRONIC_AUTH_CACHE_DIR=${IRONIC_AUTH_CACHE_DIR:-/var/cache/ironic}
IRONIC_CONF_DIR=${IRONIC_CONF_DIR:-/etc/ironic}
IRONIC_CONF_FILE=$IRONIC_CONF_DIR/ironic.conf
IRONIC_ROOTWRAP_CONF=$IRONIC_CONF_DIR/rootwrap.conf
IRONIC_POLICY_JSON=$IRONIC_CONF_DIR/policy.json

# Deploy callback timeout can be changed from its default (1800), if required.
IRONIC_CALLBACK_TIMEOUT=${IRONIC_CALLBACK_TIMEOUT:-}

# Deploy to hardware platform
IRONIC_HW_NODE_CPU=${IRONIC_HW_NODE_CPU:-1}
IRONIC_HW_NODE_RAM=${IRONIC_HW_NODE_RAM:-512}
IRONIC_HW_NODE_DISK=${IRONIC_HW_NODE_DISK:-10}
IRONIC_HW_EPHEMERAL_DISK=${IRONIC_HW_EPHEMERAL_DISK:-0}
# The file is composed of multiple lines, each line includes four field
# separated by white space: IPMI address, MAC address, IPMI username
# and IPMI password.
# An example:
#   192.168.110.107 00:1e:67:57:50:4c root otc123
IRONIC_IPMIINFO_FILE=${IRONIC_IPMIINFO_FILE:-$IRONIC_DATA_DIR/hardware_info}

# Set up defaults for functional / integration testing
IRONIC_SCRIPTS_DIR=${IRONIC_SCRIPTS_DIR:-$TOP_DIR/tools/ironic/scripts}
IRONIC_TEMPLATES_DIR=${IRONIC_TEMPLATES_DIR:-$TOP_DIR/tools/ironic/templates}
IRONIC_BAREMETAL_BASIC_OPS=$(trueorfalse False IRONIC_BAREMETAL_BASIC_OPS)
IRONIC_ENABLED_DRIVERS=${IRONIC_ENABLED_DRIVERS:-fake,pxe_ssh,pxe_ipmitool}
IRONIC_SSH_USERNAME=${IRONIC_SSH_USERNAME:-`whoami`}
IRONIC_SSH_KEY_DIR=${IRONIC_SSH_KEY_DIR:-$IRONIC_DATA_DIR/ssh_keys}
IRONIC_SSH_KEY_FILENAME=${IRONIC_SSH_KEY_FILENAME:-ironic_key}
IRONIC_KEY_FILE=${IRONIC_KEY_FILE:-$IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME}
IRONIC_SSH_VIRT_TYPE=${IRONIC_SSH_VIRT_TYPE:-virsh}
IRONIC_TFTPBOOT_DIR=${IRONIC_TFTPBOOT_DIR:-$IRONIC_DATA_DIR/tftpboot}
IRONIC_TFTPSERVER_IP=${IRONIC_TFTPSERVER_IP:-$HOST_IP}
IRONIC_VM_SSH_PORT=${IRONIC_VM_SSH_PORT:-22}
IRONIC_VM_SSH_ADDRESS=${IRONIC_VM_SSH_ADDRESS:-$HOST_IP}
IRONIC_VM_COUNT=${IRONIC_VM_COUNT:-1}
IRONIC_VM_SPECS_CPU=${IRONIC_VM_SPECS_CPU:-1}
IRONIC_VM_SPECS_RAM=${IRONIC_VM_SPECS_RAM:-512}
IRONIC_VM_SPECS_DISK=${IRONIC_VM_SPECS_DISK:-10}
IRONIC_VM_EPHEMERAL_DISK=${IRONIC_VM_EPHEMERAL_DISK:-0}
IRONIC_VM_EMULATOR=${IRONIC_VM_EMULATOR:-/usr/bin/qemu-system-x86_64}
IRONIC_VM_NETWORK_BRIDGE=${IRONIC_VM_NETWORK_BRIDGE:-brbm}
IRONIC_VM_NETWORK_RANGE=${IRONIC_VM_NETWORK_RANGE:-192.0.2.0/24}
IRONIC_VM_MACS_CSV_FILE=${IRONIC_VM_MACS_CSV_FILE:-$IRONIC_DATA_DIR/ironic_macs.csv}
IRONIC_AUTHORIZED_KEYS_FILE=${IRONIC_AUTHORIZED_KEYS_FILE:-$HOME/.ssh/authorized_keys}

# By default, baremetal VMs will console output to file.
IRONIC_VM_LOG_CONSOLE=${IRONIC_VM_LOG_CONSOLE:-True}
IRONIC_VM_LOG_DIR=${IRONIC_VM_LOG_DIR:-$IRONIC_DATA_DIR/logs/}

# Use DIB to create deploy ramdisk and kernel.
IRONIC_BUILD_DEPLOY_RAMDISK=$(trueorfalse True IRONIC_BUILD_DEPLOY_RAMDISK)
# If not use DIB, these files are used as deploy ramdisk/kernel.
# (The value must be a absolute path)
IRONIC_DEPLOY_RAMDISK=${IRONIC_DEPLOY_RAMDISK:-}
IRONIC_DEPLOY_KERNEL=${IRONIC_DEPLOY_KERNEL:-}
IRONIC_DEPLOY_ELEMENT=${IRONIC_DEPLOY_ELEMENT:-deploy-ironic}

IRONIC_AGENT_KERNEL_URL=${IRONIC_AGENT_KERNEL_URL:-http://tarballs.openstack.org/ironic-python-agent/coreos/files/coreos_production_pxe.vmlinuz}
IRONIC_AGENT_RAMDISK_URL=${IRONIC_AGENT_RAMDISK_URL:-http://tarballs.openstack.org/ironic-python-agent/coreos/files/coreos_production_pxe_image-oem.cpio.gz}

# Which deploy driver to use - valid choices right now
# are 'pxe_ssh', 'pxe_ipmitool', 'agent_ssh' and 'agent_ipmitool'.
IRONIC_DEPLOY_DRIVER=${IRONIC_DEPLOY_DRIVER:-pxe_ssh}

#TODO(agordeev): replace 'ubuntu' with host distro name getting
IRONIC_DEPLOY_FLAVOR=${IRONIC_DEPLOY_FLAVOR:-ubuntu $IRONIC_DEPLOY_ELEMENT}

# Support entry points installation of console scripts
IRONIC_BIN_DIR=$(get_python_exec_prefix)

# Ironic connection info.  Note the port must be specified.
IRONIC_SERVICE_PROTOCOL=http
IRONIC_SERVICE_PORT=${IRONIC_SERVICE_PORT:-6385}
IRONIC_HOSTPORT=${IRONIC_HOSTPORT:-$SERVICE_HOST:$IRONIC_SERVICE_PORT}

# Tell Tempest this project is present
TEMPEST_SERVICES+=,ironic

# Enable iPXE
IRONIC_IPXE_ENABLED=$(trueorfalse False IRONIC_IPXE_ENABLED)
IRONIC_HTTP_DIR=${IRONIC_HTTP_DIR:-$IRONIC_DATA_DIR/httpboot}
IRONIC_HTTP_SERVER=${IRONIC_HTTP_SERVER:-$HOST_IP}
IRONIC_HTTP_PORT=${IRONIC_HTTP_PORT:-8088}

# get_pxe_boot_file() - Get the PXE/iPXE boot file path
function get_pxe_boot_file {
    local relpath=syslinux/pxelinux.0
    if [[ "$IRONIC_IPXE_ENABLED" == "True" ]] ; then
        relpath=ipxe/undionly.kpxe
    fi

    local pxe_boot_file
    if is_ubuntu; then
        pxe_boot_file=/usr/lib/$relpath
    elif is_fedora || is_suse; then
        pxe_boot_file=/usr/share/$relpath
    fi

    echo $pxe_boot_file
}

# PXE boot image
IRONIC_PXE_BOOT_IMAGE=${IRONIC_PXE_BOOT_IMAGE:-$(get_pxe_boot_file)}


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

# Test if any Ironic services are enabled
# is_ironic_enabled
function is_ironic_enabled {
    [[ ,${ENABLED_SERVICES} =~ ,"ir-" ]] && return 0
    return 1
}

function is_ironic_hardware {
    is_ironic_enabled && [[ -n "${IRONIC_DEPLOY_DRIVER##*_ssh}" ]] && return 0
    return 1
}

function is_deployed_by_agent {
    [[ -z "${IRONIC_DEPLOY_DRIVER%%agent*}" ]] && return 0
    return 1
}

# install_ironic() - Collect source and prepare
function install_ironic {
    # make sure all needed service were enabled
    for srv in nova glance key; do
        if ! is_service_enabled "$srv"; then
            die $LINENO "$srv should be enabled for Ironic."
        fi
    done
    git_clone $IRONIC_REPO $IRONIC_DIR $IRONIC_BRANCH
    setup_develop $IRONIC_DIR

    if [[ "$IRONIC_IPXE_ENABLED" == "True" ]] ; then
        install_apache_wsgi
    fi
}

# install_ironicclient() - Collect sources and prepare
function install_ironicclient {
    if use_library_from_git "python-ironicclient"; then
        git_clone_by_name "python-ironicclient"
        setup_dev_lib "python-ironicclient"
        sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-ironicclient"]}/tools/,/etc/bash_completion.d/}ironic.bash_completion
    else
        # nothing actually "requires" ironicclient, so force instally from pypi
        pip_install python-ironicclient
    fi
}

# _cleanup_ironic_apache_wsgi() - Remove wsgi files, disable and remove apache vhost file
function _cleanup_ironic_apache_wsgi {
    sudo rm -rf $IRONIC_HTTP_DIR
    disable_apache_site ironic
    sudo rm -f $(apache_site_config_for ironic)
    restart_apache_server
}

# _config_ironic_apache_wsgi() - Set WSGI config files of Ironic
function _config_ironic_apache_wsgi {
    local ironic_apache_conf=$(apache_site_config_for ironic)
    sudo cp $FILES/apache-ironic.template $ironic_apache_conf
    sudo sed -e "
        s|%PUBLICPORT%|$IRONIC_HTTP_PORT|g;
        s|%HTTPROOT%|$IRONIC_HTTP_DIR|g;
    " -i $ironic_apache_conf
    enable_apache_site ironic
}

# cleanup_ironic() - Remove residual data files, anything left over from previous
# runs that would need to clean up.
function cleanup_ironic {
    sudo rm -rf $IRONIC_AUTH_CACHE_DIR $IRONIC_CONF_DIR
}

# configure_ironic_dirs() - Create all directories required by Ironic and
# associated services.
function configure_ironic_dirs {
    if [[ ! -d $IRONIC_CONF_DIR ]]; then
        sudo mkdir -p $IRONIC_CONF_DIR
    fi

    if [[ "$IRONIC_IPXE_ENABLED" == "True" ]] ; then
        sudo mkdir -p $IRONIC_HTTP_DIR
        sudo chown -R $STACK_USER:$LIBVIRT_GROUP $IRONIC_HTTP_DIR
    fi

    sudo mkdir -p $IRONIC_DATA_DIR
    sudo mkdir -p $IRONIC_STATE_PATH
    sudo mkdir -p $IRONIC_TFTPBOOT_DIR
    sudo chown -R $STACK_USER $IRONIC_DATA_DIR $IRONIC_STATE_PATH
    sudo chown -R $STACK_USER:$LIBVIRT_GROUP $IRONIC_TFTPBOOT_DIR
    mkdir -p $IRONIC_TFTPBOOT_DIR/pxelinux.cfg

    if [ ! -f $IRONIC_PXE_BOOT_IMAGE ]; then
        die $LINENO "PXE boot file $IRONIC_PXE_BOOT_IMAGE not found."
    fi

    cp $IRONIC_PXE_BOOT_IMAGE $IRONIC_TFTPBOOT_DIR
}

# configure_ironic() - Set config files, create data dirs, etc
function configure_ironic {
    configure_ironic_dirs
    sudo chown $STACK_USER $IRONIC_CONF_DIR

    # Copy over ironic configuration file and configure common parameters.
    cp $IRONIC_DIR/etc/ironic/ironic.conf.sample $IRONIC_CONF_FILE
    iniset $IRONIC_CONF_FILE DEFAULT debug True
    inicomment $IRONIC_CONF_FILE DEFAULT log_file
    iniset $IRONIC_CONF_FILE DEFAULT sql_connection `database_connection_url ironic`
    iniset $IRONIC_CONF_FILE DEFAULT state_path $IRONIC_STATE_PATH
    iniset $IRONIC_CONF_FILE DEFAULT use_syslog $SYSLOG
    # Configure Ironic conductor, if it was enabled.
    if is_service_enabled ir-cond; then
        configure_ironic_conductor
    fi

    # Configure Ironic API, if it was enabled.
    if is_service_enabled ir-api; then
        configure_ironic_api
    fi

    # Format logging
    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
        setup_colorized_logging $IRONIC_CONF_FILE DEFAULT
    fi

    if [[ "$IRONIC_IPXE_ENABLED" == "True" ]]; then
        _config_ironic_apache_wsgi
    fi
}

# configure_ironic_api() - Is used by configure_ironic(). Performs
# API specific configuration.
function configure_ironic_api {
    iniset $IRONIC_CONF_FILE DEFAULT auth_strategy keystone
    iniset $IRONIC_CONF_FILE DEFAULT policy_file $IRONIC_POLICY_JSON
    configure_auth_token_middleware $IRONIC_CONF_FILE ironic $IRONIC_AUTH_CACHE_DIR/api
    iniset_rpc_backend ironic $IRONIC_CONF_FILE DEFAULT
    iniset $IRONIC_CONF_FILE api port $IRONIC_SERVICE_PORT

    cp -p $IRONIC_DIR/etc/ironic/policy.json $IRONIC_POLICY_JSON
}

# configure_ironic_conductor() - Is used by configure_ironic().
# Sets conductor specific settings.
function configure_ironic_conductor {
    cp $IRONIC_DIR/etc/ironic/rootwrap.conf $IRONIC_ROOTWRAP_CONF
    cp -r $IRONIC_DIR/etc/ironic/rootwrap.d $IRONIC_CONF_DIR
    local ironic_rootwrap=$(get_rootwrap_location ironic)
    local rootwrap_isudoer_cmd="$ironic_rootwrap $IRONIC_CONF_DIR/rootwrap.conf *"

    # Set up the rootwrap sudoers for ironic
    local tempfile=`mktemp`
    echo "$STACK_USER ALL=(root) NOPASSWD: $rootwrap_isudoer_cmd" >$tempfile
    chmod 0440 $tempfile
    sudo chown root:root $tempfile
    sudo mv $tempfile /etc/sudoers.d/ironic-rootwrap

    iniset $IRONIC_CONF_FILE DEFAULT rootwrap_config $IRONIC_ROOTWRAP_CONF
    iniset $IRONIC_CONF_FILE DEFAULT enabled_drivers $IRONIC_ENABLED_DRIVERS
    iniset $IRONIC_CONF_FILE conductor api_url $IRONIC_SERVICE_PROTOCOL://$HOST_IP:$IRONIC_SERVICE_PORT
    if [[ -n "$IRONIC_CALLBACK_TIMEOUT" ]]; then
        iniset $IRONIC_CONF_FILE conductor deploy_callback_timeout $IRONIC_CALLBACK_TIMEOUT
    fi
    iniset $IRONIC_CONF_FILE pxe tftp_server $IRONIC_TFTPSERVER_IP
    iniset $IRONIC_CONF_FILE pxe tftp_root $IRONIC_TFTPBOOT_DIR
    iniset $IRONIC_CONF_FILE pxe tftp_master_path $IRONIC_TFTPBOOT_DIR/master_images
    if [[ "$IRONIC_VM_LOG_CONSOLE" == "True" ]] ; then
        iniset $IRONIC_CONF_FILE pxe pxe_append_params "nofb nomodeset vga=normal console=ttyS0"
    fi
    if is_deployed_by_agent; then
        if [[ "$SWIFT_ENABLE_TEMPURLS" == "True" ]] ; then
            iniset $IRONIC_CONF_FILE glance swift_temp_url_key $SWIFT_TEMPURL_KEY
        else
            die $LINENO "SWIFT_ENABLE_TEMPURLS must be True to use agent_ssh driver in Ironic."
        fi
        iniset $IRONIC_CONF_FILE glance swift_endpoint_url http://${HOST_IP}:${SWIFT_DEFAULT_BIND_PORT:-8080}
        iniset $IRONIC_CONF_FILE glance swift_api_version v1
        local tenant_id=$(get_or_create_project $SERVICE_TENANT_NAME)
        iniset $IRONIC_CONF_FILE glance swift_account AUTH_${tenant_id}
        iniset $IRONIC_CONF_FILE glance swift_container glance
        iniset $IRONIC_CONF_FILE glance swift_temp_url_duration 3600
        iniset $IRONIC_CONF_FILE agent heartbeat_timeout 30
        if [[ "$IRONIC_VM_LOG_CONSOLE" == "True" ]] ; then
            iniset $IRONIC_CONF_FILE agent agent_pxe_append_params "nofb nomodeset vga=normal console=ttyS0 systemd.journald.forward_to_console=yes"
        fi
    fi

    if [[ "$IRONIC_IPXE_ENABLED" == "True" ]] ; then
        local pxebin=`basename $IRONIC_PXE_BOOT_IMAGE`
        iniset $IRONIC_CONF_FILE pxe ipxe_enabled True
        iniset $IRONIC_CONF_FILE pxe pxe_config_template '\$pybasedir/drivers/modules/ipxe_config.template'
        iniset $IRONIC_CONF_FILE pxe pxe_bootfile_name $pxebin
        iniset $IRONIC_CONF_FILE pxe http_root $IRONIC_HTTP_DIR
        iniset $IRONIC_CONF_FILE pxe http_url "http://$IRONIC_HTTP_SERVER:$IRONIC_HTTP_PORT"
    fi
}

# create_ironic_cache_dir() - Part of the init_ironic() process
function create_ironic_cache_dir {
    # Create cache dir
    sudo mkdir -p $IRONIC_AUTH_CACHE_DIR/api
    sudo chown $STACK_USER $IRONIC_AUTH_CACHE_DIR/api
    rm -f $IRONIC_AUTH_CACHE_DIR/api/*
    sudo mkdir -p $IRONIC_AUTH_CACHE_DIR/registry
    sudo chown $STACK_USER $IRONIC_AUTH_CACHE_DIR/registry
    rm -f $IRONIC_AUTH_CACHE_DIR/registry/*
}

# create_ironic_accounts() - Set up common required ironic accounts

# Tenant               User       Roles
# ------------------------------------------------------------------
# service              ironic     admin        # if enabled
function create_ironic_accounts {

    # Ironic
    if [[ "$ENABLED_SERVICES" =~ "ir-api" ]]; then
        # Get ironic user if exists

        create_service_user "ironic"

        if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then

            local ironic_service=$(get_or_create_service "ironic" \
                "baremetal" "Ironic baremetal provisioning service")
            get_or_create_endpoint $ironic_service \
                "$REGION_NAME" \
                "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT" \
                "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT" \
                "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT"
        fi
    fi
}


# init_ironic() - Initialize databases, etc.
function init_ironic {
    # (Re)create  ironic database
    recreate_database ironic

    # Migrate ironic database
    $IRONIC_BIN_DIR/ironic-dbsync --config-file=$IRONIC_CONF_FILE

    create_ironic_cache_dir
}

# _ironic_bm_vm_names() - Generates list of names for baremetal VMs.
function _ironic_bm_vm_names {
    local idx
    local num_vms=$(($IRONIC_VM_COUNT - 1))
    for idx in $(seq 0 $num_vms); do
        echo "baremetal${IRONIC_VM_NETWORK_BRIDGE}_${idx}"
    done
}

# start_ironic() - Start running processes, including screen
function start_ironic {
    # Start Ironic API server, if enabled.
    if is_service_enabled ir-api; then
        start_ironic_api
    fi

    # Start Ironic conductor, if enabled.
    if is_service_enabled ir-cond; then
        start_ironic_conductor
    fi

    # Start Apache if iPXE is enabled
    if [[ "$IRONIC_IPXE_ENABLED" == "True" ]] ; then
        restart_apache_server
    fi
}

# start_ironic_api() - Used by start_ironic().
# Starts Ironic API server.
function start_ironic_api {
    run_process ir-api "$IRONIC_BIN_DIR/ironic-api --config-file=$IRONIC_CONF_FILE"
    echo "Waiting for ir-api ($IRONIC_HOSTPORT) to start..."
    if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- $IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT; do sleep 1; done"; then
        die $LINENO "ir-api did not start"
    fi
}

# start_ironic_conductor() - Used by start_ironic().
# Starts Ironic conductor.
function start_ironic_conductor {
    run_process ir-cond "$IRONIC_BIN_DIR/ironic-conductor --config-file=$IRONIC_CONF_FILE"
    # TODO(romcheg): Find a way to check whether the conductor has started.
}

# stop_ironic() - Stop running processes
function stop_ironic {
    # Kill the Ironic screen windows
    screen -S $SCREEN_NAME -p ir-api -X kill
    screen -S $SCREEN_NAME -p ir-cond -X kill

    # Cleanup the WSGI files
    if [[ "$IRONIC_IPXE_ENABLED" == "True" ]] ; then
        _cleanup_ironic_apache_wsgi
    fi
}

function create_ovs_taps {
    local ironic_net_id=$(neutron net-list | grep private | get_field 1)

    # Work around: No netns exists on host until a Neutron port is created.  We
    # need to create one in Neutron to know what netns to tap into prior to the
    # first node booting.
    local port_id=$(neutron port-create private | grep " id " | get_field 2)

    # intentional sleep to make sure the tag has been set to port
    sleep 10

    if  [[ "$Q_USE_NAMESPACE" = "True" ]]; then
        local tapdev=$(sudo ip netns exec qdhcp-${ironic_net_id} ip link list | grep " tap" | cut -d':' -f2 | cut -b2-)
    else
        local tapdev=$(sudo ip link list | grep " tap" | cut -d':' -f2 | cut -b2-)
    fi
    local tag_id=$(sudo ovs-vsctl show |grep ${tapdev} -A1 -m1 | grep tag | cut -d':' -f2 | cut -b2-)

    # make sure veth pair is not existing, otherwise delete its links
    sudo ip link show ovs-tap1 && sudo ip link delete ovs-tap1
    sudo ip link show brbm-tap1 && sudo ip link delete brbm-tap1
    # create veth pair for future interconnection between br-int and brbm
    sudo ip link add brbm-tap1 type veth peer name ovs-tap1
    sudo ip link set dev brbm-tap1 up
    sudo ip link set dev ovs-tap1 up

    sudo ovs-vsctl -- --if-exists del-port ovs-tap1 -- add-port br-int ovs-tap1 tag=$tag_id
    sudo ovs-vsctl -- --if-exists del-port brbm-tap1 -- add-port $IRONIC_VM_NETWORK_BRIDGE brbm-tap1

    # Remove the port needed only for workaround.
    neutron port-delete $port_id

    # Finally, share the fixed tenant network across all tenants.  This allows the host
    # to serve TFTP to a single network namespace via the tap device created above.
    neutron net-update $ironic_net_id --shared true
}

function create_bridge_and_vms {
    # Call libvirt setup scripts in a new shell to ensure any new group membership
    sudo su $STACK_USER -c "$IRONIC_SCRIPTS_DIR/setup-network"
    if [[ "$IRONIC_VM_LOG_CONSOLE" == "True" ]] ; then
        local log_arg="$IRONIC_VM_LOG_DIR"
    else
        local log_arg=""
    fi
    local vm_name
    for vm_name in $(_ironic_bm_vm_names); do
        sudo su $STACK_USER -c "$IRONIC_SCRIPTS_DIR/create-node $vm_name \
            $IRONIC_VM_SPECS_CPU $IRONIC_VM_SPECS_RAM $IRONIC_VM_SPECS_DISK \
            amd64 $IRONIC_VM_NETWORK_BRIDGE $IRONIC_VM_EMULATOR \
            $log_arg" >> $IRONIC_VM_MACS_CSV_FILE
    done
    create_ovs_taps
}

function wait_for_nova_resources {
    # After nodes have been enrolled, we need to wait for both ironic and
    # nova's periodic tasks to populate the resource tracker with available
    # nodes and resources. Wait up to 2 minutes for a given resource before
    # timing out.
    local resource=$1
    local expected_count=$2
    echo_summary "Waiting 2 minutes for Nova resource tracker to pick up $resource >= $expected_count"
    for i in $(seq 1 120); do
        if [ $(nova hypervisor-stats | grep " $resource " | get_field 2) -ge $expected_count ]; then
            return 0
        fi
        sleep 1
    done
    die $LINENO "Timed out waiting for Nova hypervisor-stats $resource >= $expected_count"
}

function enroll_nodes {
    local chassis_id=$(ironic chassis-create -d "ironic test chassis" | grep " uuid " | get_field 2)

    if [[ "$IRONIC_DEPLOY_DRIVER" == "pxe_ssh" ]] ; then
        local _IRONIC_DEPLOY_KERNEL_KEY=pxe_deploy_kernel
        local _IRONIC_DEPLOY_RAMDISK_KEY=pxe_deploy_ramdisk
    elif is_deployed_by_agent; then
        local _IRONIC_DEPLOY_KERNEL_KEY=deploy_kernel
        local _IRONIC_DEPLOY_RAMDISK_KEY=deploy_ramdisk
    fi

    if ! is_ironic_hardware; then
        local ironic_node_cpu=$IRONIC_VM_SPECS_CPU
        local ironic_node_ram=$IRONIC_VM_SPECS_RAM
        local ironic_node_disk=$IRONIC_VM_SPECS_DISK
        local ironic_ephemeral_disk=$IRONIC_VM_EPHEMERAL_DISK
        local ironic_hwinfo_file=$IRONIC_VM_MACS_CSV_FILE
        local node_options="\
            -i $_IRONIC_DEPLOY_KERNEL_KEY=$IRONIC_DEPLOY_KERNEL_ID \
            -i $_IRONIC_DEPLOY_RAMDISK_KEY=$IRONIC_DEPLOY_RAMDISK_ID \
            -i ssh_virt_type=$IRONIC_SSH_VIRT_TYPE \
            -i ssh_address=$IRONIC_VM_SSH_ADDRESS \
            -i ssh_port=$IRONIC_VM_SSH_PORT \
            -i ssh_username=$IRONIC_SSH_USERNAME \
            -i ssh_key_filename=$IRONIC_KEY_FILE"
    else
        local ironic_node_cpu=$IRONIC_HW_NODE_CPU
        local ironic_node_ram=$IRONIC_HW_NODE_RAM
        local ironic_node_disk=$IRONIC_HW_NODE_DISK
        local ironic_ephemeral_disk=$IRONIC_HW_EPHEMERAL_DISK
        if [[ -z "${IRONIC_DEPLOY_DRIVER##*_ipmitool}" ]]; then
            local ironic_hwinfo_file=$IRONIC_IPMIINFO_FILE
        fi
    fi

    local total_nodes=0
    local total_cpus=0
    while read hardware_info; do
        if ! is_ironic_hardware; then
            local mac_address=$hardware_info
        elif [[ -z "${IRONIC_DEPLOY_DRIVER##*_ipmitool}" ]]; then
            local ipmi_address=$(echo $hardware_info |awk  '{print $1}')
            local mac_address=$(echo $hardware_info |awk '{print $2}')
            local ironic_ipmi_username=$(echo $hardware_info |awk '{print $3}')
            local ironic_ipmi_passwd=$(echo $hardware_info |awk '{print $4}')
            # Currently we require all hardware platform have same CPU/RAM/DISK info
            # in future, this can be enhanced to support different type, and then
            # we create the bare metal flavor with minimum value
            local node_options="-i ipmi_address=$ipmi_address -i ipmi_password=$ironic_ipmi_passwd\
                -i ipmi_username=$ironic_ipmi_username"
            node_options+=" -i $_IRONIC_DEPLOY_KERNEL_KEY=$IRONIC_DEPLOY_KERNEL_ID"
            node_options+=" -i $_IRONIC_DEPLOY_RAMDISK_KEY=$IRONIC_DEPLOY_RAMDISK_ID"
        fi

        local node_id=$(ironic node-create --chassis_uuid $chassis_id \
            --driver $IRONIC_DEPLOY_DRIVER \
            -p cpus=$ironic_node_cpu\
            -p memory_mb=$ironic_node_ram\
            -p local_gb=$ironic_node_disk\
            -p cpu_arch=x86_64 \
            $node_options \
            | grep " uuid " | get_field 2)

        ironic port-create --address $mac_address --node_uuid $node_id

        total_nodes=$((total_nodes+1))
        total_cpus=$((total_cpus+$ironic_node_cpu))
    done < $ironic_hwinfo_file

    # create the nova flavor
    # NOTE(adam_g): Attempting to use an autogenerated UUID for flavor id here uncovered
    # bug (LP: #1333852) in Trove.  This can be changed to use an auto flavor id when the
    # bug is fixed in Juno.
    local adjusted_disk=$(($ironic_node_disk - $ironic_ephemeral_disk))
    nova flavor-create --ephemeral $ironic_ephemeral_disk baremetal 551 $ironic_node_ram $adjusted_disk $ironic_node_cpu

    nova flavor-key baremetal set "cpu_arch"="x86_64"

    if [ "$VIRT_DRIVER" == "ironic" ]; then
        wait_for_nova_resources "count" $total_nodes
        wait_for_nova_resources "vcpus" $total_cpus
    fi
}

function configure_iptables {
    # enable tftp natting for allowing connections to HOST_IP's tftp server
    sudo modprobe nf_conntrack_tftp
    sudo modprobe nf_nat_tftp
    # nodes boot from TFTP and callback to the API server listening on $HOST_IP
    sudo iptables -I INPUT -d $HOST_IP -p udp --dport 69 -j ACCEPT || true
    sudo iptables -I INPUT -d $HOST_IP -p tcp --dport $IRONIC_SERVICE_PORT -j ACCEPT || true
    if is_deployed_by_agent; then
        # agent ramdisk gets instance image from swift
        sudo iptables -I INPUT -d $HOST_IP -p tcp --dport ${SWIFT_DEFAULT_BIND_PORT:-8080} -j ACCEPT || true
    fi
}

function configure_tftpd {
    # stop tftpd and setup serving via xinetd
    stop_service tftpd-hpa || true
    [ -f /etc/init/tftpd-hpa.conf ] && echo "manual" | sudo tee /etc/init/tftpd-hpa.override
    sudo cp $IRONIC_TEMPLATES_DIR/tftpd-xinetd.template /etc/xinetd.d/tftp
    sudo sed -e "s|%TFTPBOOT_DIR%|$IRONIC_TFTPBOOT_DIR|g" -i /etc/xinetd.d/tftp

    # setup tftp file mapping to satisfy requests at the root (booting) and
    # /tftpboot/ sub-dir (as per deploy-ironic elements)
    echo "r ^([^/]) $IRONIC_TFTPBOOT_DIR/\1" >$IRONIC_TFTPBOOT_DIR/map-file
    echo "r ^(/tftpboot/) $IRONIC_TFTPBOOT_DIR/\2" >>$IRONIC_TFTPBOOT_DIR/map-file

    chmod -R 0755 $IRONIC_TFTPBOOT_DIR
    restart_service xinetd
}

function configure_ironic_ssh_keypair {
    if [[ ! -d $HOME/.ssh ]]; then
        mkdir -p $HOME/.ssh
        chmod 700 $HOME/.ssh
    fi
    if [[ ! -e $IRONIC_KEY_FILE ]]; then
        if [[ ! -d $(dirname $IRONIC_KEY_FILE) ]]; then
            mkdir -p $(dirname $IRONIC_KEY_FILE)
        fi
        echo -e 'n\n' | ssh-keygen -q -t rsa -P '' -f $IRONIC_KEY_FILE
    fi
    cat $IRONIC_KEY_FILE.pub | tee -a $IRONIC_AUTHORIZED_KEYS_FILE
}

function ironic_ssh_check {
    local key_file=$1
    local floating_ip=$2
    local port=$3
    local default_instance_user=$4
    local active_timeout=$5
    if ! timeout $active_timeout sh -c "while ! ssh -p $port -o StrictHostKeyChecking=no -i $key_file ${default_instance_user}@$floating_ip echo success; do sleep 1; done"; then
        die $LINENO "server didn't become ssh-able!"
    fi
}

function configure_ironic_auxiliary {
    configure_ironic_ssh_keypair
    ironic_ssh_check $IRONIC_KEY_FILE $IRONIC_VM_SSH_ADDRESS $IRONIC_VM_SSH_PORT $IRONIC_SSH_USERNAME 10
}

function build_ipa_coreos_ramdisk {
    echo "Building ironic-python-agent deploy ramdisk"
    local kernel_path=$1
    local ramdisk_path=$2
    git_clone $IRONIC_PYTHON_AGENT_REPO $IRONIC_PYTHON_AGENT_DIR $IRONIC_PYTHON_AGENT_BRANCH
    cd $IRONIC_PYTHON_AGENT_DIR
    imagebuild/coreos/build_coreos_image.sh
    cp imagebuild/coreos/UPLOAD/coreos_production_pxe_image-oem.cpio.gz $ramdisk_path
    cp imagebuild/coreos/UPLOAD/coreos_production_pxe.vmlinuz $kernel_path
    sudo rm -rf UPLOAD
    cd -
}

# build deploy kernel+ramdisk, then upload them to glance
# this function sets ``IRONIC_DEPLOY_KERNEL_ID``, ``IRONIC_DEPLOY_RAMDISK_ID``
function upload_baremetal_ironic_deploy {
    declare -g IRONIC_DEPLOY_KERNEL_ID IRONIC_DEPLOY_RAMDISK_ID
    echo_summary "Creating and uploading baremetal images for ironic"

    # install diskimage-builder
    if [[ $(type -P ramdisk-image-create) == "" ]]; then
        pip_install diskimage_builder
    fi

    if [ -z "$IRONIC_DEPLOY_KERNEL" -o -z "$IRONIC_DEPLOY_RAMDISK" ]; then
        local IRONIC_DEPLOY_KERNEL_PATH=$TOP_DIR/files/ir-deploy-$IRONIC_DEPLOY_DRIVER.kernel
        local IRONIC_DEPLOY_RAMDISK_PATH=$TOP_DIR/files/ir-deploy-$IRONIC_DEPLOY_DRIVER.initramfs
    else
        local IRONIC_DEPLOY_KERNEL_PATH=$IRONIC_DEPLOY_KERNEL
        local IRONIC_DEPLOY_RAMDISK_PATH=$IRONIC_DEPLOY_RAMDISK
    fi

    if [ ! -e "$IRONIC_DEPLOY_RAMDISK_PATH" -o ! -e "$IRONIC_DEPLOY_KERNEL_PATH" ]; then
        # files don't exist, need to build them
        if [ "$IRONIC_BUILD_DEPLOY_RAMDISK" = "True" ]; then
            # we can build them only if we're not offline
            if [ "$OFFLINE" != "True" ]; then
                if is_deployed_by_agent; then
                    build_ipa_coreos_ramdisk $IRONIC_DEPLOY_KERNEL_PATH $IRONIC_DEPLOY_RAMDISK_PATH
                else
                    ramdisk-image-create $IRONIC_DEPLOY_FLAVOR \
                        -o $TOP_DIR/files/ir-deploy-$IRONIC_DEPLOY_DRIVER
                fi
            else
                die $LINENO "Deploy kernel+ramdisk files don't exist and cannot be build in OFFLINE mode"
            fi
        else
            if is_deployed_by_agent; then
                # download the agent image tarball
                wget "$IRONIC_AGENT_KERNEL_URL" -O $IRONIC_DEPLOY_KERNEL_PATH
                wget "$IRONIC_AGENT_RAMDISK_URL" -O $IRONIC_DEPLOY_RAMDISK_PATH
            else
                die $LINENO "Deploy kernel+ramdisk files don't exist and their building was disabled explicitly by IRONIC_BUILD_DEPLOY_RAMDISK"
            fi
        fi
    fi

    local token=$(keystone token-get | grep ' id ' | get_field 2)
    die_if_not_set $LINENO token "Keystone fail to get token"

    # load them into glance
    IRONIC_DEPLOY_KERNEL_ID=$(openstack \
        --os-token $token \
        --os-url http://$GLANCE_HOSTPORT \
        image create \
        $(basename $IRONIC_DEPLOY_KERNEL_PATH) \
        --public --disk-format=aki \
        --container-format=aki \
        < $IRONIC_DEPLOY_KERNEL_PATH  | grep ' id ' | get_field 2)
    IRONIC_DEPLOY_RAMDISK_ID=$(openstack \
        --os-token $token \
        --os-url http://$GLANCE_HOSTPORT \
        image create \
        $(basename $IRONIC_DEPLOY_RAMDISK_PATH) \
        --public --disk-format=ari \
        --container-format=ari \
        < $IRONIC_DEPLOY_RAMDISK_PATH  | grep ' id ' | get_field 2)
}

function prepare_baremetal_basic_ops {
    if ! is_ironic_hardware; then
        configure_ironic_auxiliary
    fi
    upload_baremetal_ironic_deploy
    if ! is_ironic_hardware; then
        create_bridge_and_vms
    fi
    enroll_nodes
    configure_tftpd
    configure_iptables
}

function cleanup_baremetal_basic_ops {
    rm -f $IRONIC_VM_MACS_CSV_FILE
    if [ -f $IRONIC_KEY_FILE ]; then
        local key=$(cat $IRONIC_KEY_FILE.pub)
        # remove public key from authorized_keys
        grep -v "$key" $IRONIC_AUTHORIZED_KEYS_FILE > temp && mv temp $IRONIC_AUTHORIZED_KEYS_FILE
        chmod 0600 $IRONIC_AUTHORIZED_KEYS_FILE
    fi
    sudo rm -rf $IRONIC_DATA_DIR $IRONIC_STATE_PATH

    local vm_name
    for vm_name in $(_ironic_bm_vm_names); do
        sudo su $STACK_USER -c "$IRONIC_SCRIPTS_DIR/cleanup-node $vm_name $IRONIC_VM_NETWORK_BRIDGE"
    done

    sudo rm -rf /etc/xinetd.d/tftp /etc/init/tftpd-hpa.override
    restart_service xinetd
    sudo iptables -D INPUT -d $HOST_IP -p udp --dport 69 -j ACCEPT || true
    sudo iptables -D INPUT -d $HOST_IP -p tcp --dport $IRONIC_SERVICE_PORT -j ACCEPT || true
    if is_deployed_by_agent; then
        # agent ramdisk gets instance image from swift
        sudo iptables -D INPUT -d $HOST_IP -p tcp --dport ${SWIFT_DEFAULT_BIND_PORT:-8080} -j ACCEPT || true
    fi
    sudo rmmod nf_conntrack_tftp || true
    sudo rmmod nf_nat_tftp || true
}

# Restore xtrace + pipefail
$XTRACE
$PIPEFAIL

# Tell emacs to use shell-script-mode
## Local variables:
## mode: shell-script
## End:
