instack-undercloud/scripts/instack-ironic-deployment
Ben Nemec b0a94a9249 Disable localboot
This requires a patched version of diskimage-builder, and right now
we have an ugly version wedge in delorean that prevents us from
using it.  In order to unblock all of the other work going on,
disable localboot until we can resolve the delorean issue.

Change-Id: I57a9e8ac6614c6097831f60372fe754fb2fcbf8a
2015-03-26 12:34:04 -05:00

391 lines
13 KiB
Bash
Executable File

#!/bin/bash
set -eu
set -o pipefail
SCRIPT_NAME=$(basename $0)
OS_AUTH_URL=${OS_AUTH_URL:-""}
if [ -z "$OS_AUTH_URL" ]; then
echo "You must source a stackrc file for the Undercloud."
exit 1
fi
function show_options () {
echo "Usage: $SCRIPT_NAME [options]"
echo
echo "Deploys instances via Ironic in preparation for an Overcloud deployment."
echo
echo "Options:"
echo " --register-nodes -- register nodes from a nodes json file"
echo " --nodes-json -- nodes json file containing node data"
echo " for registration."
echo " Default: nodes.json in the current directory"
echo " --discover-nodes -- Perform discovery of registered nodes."
echo " Powers on registered nodes to complete"
echo " the discovery process."
echo " --configure-bios -- Configure BIOS settings of "
echo " registered nodes."
echo " --configure-root-raid-volume -- Configure RAID volumes of registered"
echo " nodes."
echo " --configure-nonroot-raid-volumes -- Configure RAID volumes of registered"
echo " nodes."
echo " --setup-flavors -- Setup Nova flavors to match discovered"
echo " profiles"
echo " --show-profile -- Show matching profile of nodes"
echo " --deploy-nodes -- Deploy nodes"
echo " --check-ssh -- Check the root ssh connection to each"
echo " deployed node."
echo " --delete-stack -- Wait until the stack has deleted."
echo " --delete-nodes -- Delete all nodes."
echo " -x -- enable tracing"
echo " --help, -h -- Print this help message."
echo
exit $1
}
TEMP=$(getopt -o ,h -l,register-nodes,nodes-json:,discover-nodes,configure-bios,configure-root-raid-volume,configure-nonroot-raid-volumes,deploy-nodes,help,setup-flavors,show-profile,check-ssh,delete-stack,delete-nodes,config-tools-provision -o,x,h -n $SCRIPT_NAME -- "$@")
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
REGISTER_NODES=
NODES_JSON=
DISCOVER_NODES=
CONFIGURE_BIOS=
CONFIGURE_RAID_ROOT_VOLUMES=
CONFIGURE_RAID_NONROOT_VOLUMES=
DEPLOY_NODES=
SETUP_FLAVORS=
SHOW_PROFILE=
CHECK_SSH=
DELETE_STACK=
DELETE_NODES=
STDERR=/dev/null
# NOTE(bnemec): Can be removed once Ironic is updated to fix the
# novaclient.v1_1 deprecation warning
export PYTHONWARNINGS="ignore"
DEPLOY_NAME=${DEPLOY_NAME:-"ironic-discover"}
IRONIC=$(keystone endpoint-get --service baremetal | grep publicURL | awk '{ print $4; }')
IRONIC=${IRONIC%/}
while true ; do
case "$1" in
--register-nodes) REGISTER_NODES="1"; shift 1;;
--nodes-json) NODES_JSON="$2"; shift 2;;
--discover-nodes) DISCOVER_NODES="1"; shift 1;;
--configure-bios) CONFIGURE_BIOS="1"; shift 1;;
--configure-root-raid-volume) CONFIGURE_RAID_ROOT_VOLUMES="1"; shift 1;;
--configure-nonroot-raid-volumes) CONFIGURE_RAID_NONROOT_VOLUMES="1"; shift 1;;
--show-profile) SHOW_PROFILE="1"; shift 1;;
--deploy-nodes) DEPLOY_NODES="1"; shift 1;;
--setup-flavors) SETUP_FLAVORS="1"; shift 1;;
--check-ssh) CHECK_SSH="1"; shift 1;;
--delete-stack) DELETE_STACK="1"; shift 1;;
--delete-nodes) DELETE_NODES="1"; shift 1;;
-x) set -x; STDERR=/dev/stderr; shift 1;;
-h | --help) show_options 0;;
--) shift ; break ;;
*) echo "Error: unsupported option $1." ; exit 1 ;;
esac
done
function register_nodes {
NODES_JSON=${NODES_JSON:-"nodes.json"}
NULL_STATS=${NULL_STATS:-0}
tmp_json=$NODES_JSON
if [ "$NULL_STATS" = "1" ]; then
tmp_json=$(mktemp)
jq '.nodes[].memory=null | .nodes[].disk=null | .nodes[].arch=null | .nodes[].cpu=null' $NODES_JSON > $tmp_json
fi
echo " Registering nodes from $NODES_JSON"
register-nodes --service-host undercloud --nodes <(jq '.nodes' $tmp_json) 1>/dev/null
if [ "$NULL_STATS" = "1" ]; then
rm -f $tmp_json
fi
deploy_kernel_id=$(glance image-show bm-deploy-kernel | awk ' / id / {print $4}')
deploy_ramdisk_id=$(glance image-show bm-deploy-ramdisk | awk ' / id / {print $4}')
# Add the local boot capability and deploy_{kernel, ramdisk} parameters
node_list=$(ironic node-list --limit 0)
node_ids=$(echo "$node_list" | tail -n +4 | head -n -1 | awk -F "| " '{print $2}')
for node_id in $node_ids; do
ironic node-update $node_id add properties/capabilities="boot_option:local" driver_info/deploy_ramdisk=$deploy_ramdisk_id driver_info/deploy_kernel=$deploy_kernel_id 1> /dev/null
done
echo " Nodes registered."
echo
echo "$node_list"
echo
}
function discover_nodes {
echo " Discovering nodes."
node_ids=$(ironic node-list | tail -n +4 | head -n -1 | awk -F "| " '{print $2}')
for node_id in $node_ids; do
echo -n " Sending node ID $node_id to discoverd for discovery ... "
openstack baremetal introspection start $node_id
# tftpd chokes when serving 4 or more clients. Seeing less than 3Mb/s
# throughput. As a workaround, sleep for some time in between sending
# each node to discovery to give each node enough time to download the
# kernel/ramdisk before the next node is powered on.
sleep 15
echo "DONE."
done
echo " Polling discoverd for discovery results ... "
for node_id in $node_ids; do
echo -n " Result for node $node_id is ... "
while true; do
finished=$(openstack baremetal introspection status $node_id -f value -c finished)
if [ "$finished" = "True" ]; then
error=$(openstack baremetal introspection status $node_id -f value -c error)
if [ "$error" = "None" ]; then
echo "DISCOVERED."
else
echo "ERROR: $error"
fi
break
fi
sleep 15
done
done
echo
}
function configure_bios {
echo " Configuring BIOS."
node_ids=$(ironic node-list | tail -n +4 | head -n -1 | awk -F "| " '{print $2}')
for node_id in $node_ids; do
driver=$(ironic node-show $node_id | grep 'driver[ \t]' | awk -F "|" '{print $3}' | xargs)
if [ "$driver" == "pxe_drac" ]; then
echo -n " Configuring BIOS for node ID $node_id ... "
ironic node-vendor-passthru $node_id --http_method POST configure_bios_settings
echo "DONE. You might need to reboot the machine to apply the changes."
fi
done
echo
}
function configure_raid_volumes {
create_root_volume=$1
create_nonroot_volumes=$2
echo " Configuring RAID volumes."
node_ids=$(ironic node-list | tail -n +4 | head -n -1 | awk -F "| " '{print $2}')
for node_id in $node_ids; do
driver=$(ironic node-show $node_id | grep 'driver[ \t]' | awk -F "|" '{print $3}' | xargs)
if [ "$driver" == "pxe_drac" ]; then
echo -n " Configuring RAID volumes for node ID $node_id ... "
ironic node-vendor-passthru $node_id --http_method POST prepare_for_ready_state
ironic node-vendor-passthru $node_id --http_method POST create_raid_configuration \
create_root_volume=$create_root_volume \
create_nonroot_volumes=$create_nonroot_volumes
echo "DONE."
fi
done
echo
wait_for_drac_config_jobs
}
function wait_for_drac_config_jobs {
echo " Waiting for DRAC config jobs to finish ... "
node_ids=$(ironic node-list | tail -n +4 | head -n -1 | awk -F "| " '{print $2}')
for node_id in $node_ids; do
driver=$(ironic node-show $node_id | grep 'driver[ \t]' | awk -F "|" '{print $3}' | xargs)
if [ "$driver" == "pxe_drac" ]; then
echo -n " Waiting for node $node_id ... "
while true; do
jobs=$(ironic node-vendor-passthru $node_id --http_method GET list_unfinished_jobs)
if [[ $jobs == *"'unfinished_jobs': []"* ]]; then
break
fi
sleep 30
done
echo "DONE."
fi
done
echo
}
function wait_for_ssh {
echo " Waiting for ssh as root to be enabled ... "
echo
ips=$(nova list | tail -n +4 | head -n -1 | awk '{print $12}' | cut -d= -f2)
for ip in $ips; do
echo -n " checking $ip ... "
tripleo wait_for 300 1 ssh -o "PasswordAuthentication=no" -o "StrictHostKeyChecking=no" root@$ip ls
echo "DONE."
done
echo
}
function deploy_nodes {
wait_for_hypervisor_stats
DEPLOY_HEAT_TEMPLATE=${DEPLOY_HEAT_TEMPLATE:-"/usr/share/instack-undercloud/heat-templates/ironic-deployment.yaml"}
CONTROL_COUNT=${CONTROL_COUNT:-"1"}
COMPUTE_COUNT=${COMPUTE_COUNT:-"3"}
echo " Creating heat stack ... "
heat stack-create $DEPLOY_NAME -f $DEPLOY_HEAT_TEMPLATE -P "control_count=$CONTROL_COUNT" -P "compute_count=$COMPUTE_COUNT"
echo " Created."
echo
echo -n " Waiting for stack to finish ... "
echo
tripleo wait_for_stack_ready 60 10 $DEPLOY_NAME
echo "DONE."
heat stack-show $DEPLOY_NAME
heat stack-list
wait_for_ssh
echo
}
function setup_flavors {
if ! nova flavor-show baremetal_control 2>$STDERR 1>/dev/null; then
echo " Creating baremetal_control flavor ... "
nova flavor-create baremetal_control auto 2048 40 1
else
echo " baremetal_control flavor already exists."
fi
if ! nova flavor-show baremetal_compute 2>$STDERR 1>/dev/null; then
echo " Creating baremetal_compute flavor ... "
nova flavor-create baremetal_compute auto 4096 40 1
else
echo " baremetal_compute flavor already exists."
fi
echo
nova flavor-list
echo
echo " Setting baremetal_control flavor keys ... "
nova flavor-key baremetal_control set \
"cpu_arch"="x86_64" \
"profile=control"
nova flavor-show baremetal_control
echo " Setting baremetal_compute flavor keys ... "
nova flavor-key baremetal_compute set \
"cpu_arch"="x86_64" \
"profile=compute"
nova flavor-show baremetal_compute
}
function show_profile {
node_ids=$(ironic node-list | tail -n +4 | head -n -1 | awk -F "| " '{print $2}')
token=$(keystone token-get | grep ' id ' | awk '{print $4}')
echo " Querying assigned profiles ... "
echo
for node_id in $node_ids; do
echo " $node_id"
echo -n " "
curl -s -H "x-auth-token: $token" $IRONIC/v1/nodes/$node_id | jq '.properties.capabilities'
echo
done
echo
echo " DONE."
echo
}
function wait_for_hypervisor_stats {
node_ids=$(ironic node-list | tail -n +4 | head -n -1 | awk -F "| " '{print $2}')
expected_nodes=$(echo $node_ids | wc -w)
expected_memory=0
expected_vcpus=0
token=$(keystone token-get | grep ' id ' | awk '{print $4}')
echo -n " Wating for nova hypervisor stats ... "
for node_id in $node_ids; do
mem=$(curl -s -H "x-auth-token: $token" $IRONIC/v1/nodes/$node_id | jq '.properties.memory_mb | tonumber')
vcpu=$(curl -s -H "x-auth-token: $token" $IRONIC/v1/nodes/$node_id | jq '.properties.cpus | tonumber')
expected_memory=$(($expected_memory + $mem))
expected_vcpus=$(($expected_vcpus + $vcpu))
done
tripleo wait_for 180 1 wait_for_hypervisor_stats $expected_nodes $expected_memory $expected_vcpus
echo "DONE."
echo
}
function delete_stack {
heat stack-delete $DEPLOY_NAME
tripleo wait_for 90 2 ! heat stack-show $DEPLOY_NAME
}
function delete_nodes {
for n in $(ironic node-list | tail -n +4 | head -n -1 | awk '{print $2}'); do
ironic node-delete $n;
done
}
echo "Preparing for deployment..."
if [ "$REGISTER_NODES" = 1 ]; then
register_nodes
fi
if [ "$DISCOVER_NODES" = 1 ]; then
discover_nodes
fi
if [ "$CONFIGURE_BIOS" = 1 ]; then
configure_bios
fi
if [ "$CONFIGURE_RAID_ROOT_VOLUMES" = 1 ]; then
create_root_volume=true
create_nonroot_volumes=false
configure_raid_volumes $create_root_volume $create_nonroot_volumes
fi
if [ "$CONFIGURE_RAID_NONROOT_VOLUMES" = 1 ]; then
create_root_volume=false
create_nonroot_volumes=true
configure_raid_volumes $create_root_volume $create_nonroot_volumes
fi
if [ "$SETUP_FLAVORS" = 1 ]; then
setup_flavors
fi
if [ "$SHOW_PROFILE" = 1 ]; then
show_profile
fi
if [ "$CHECK_SSH" = 1 ]; then
wait_for_ssh
fi
if [ "$DELETE_STACK" = 1 ]; then
delete_stack
fi
if [ "$DELETE_NODES" = 1 ]; then
delete_nodes
fi
echo "Prepared."
if [ "$DEPLOY_NODES" = 1 ]; then
echo "Deploying..."
deploy_nodes
echo "Deployed."
fi