
Baremetal PXE driver should read deploy_kernel_id & deploy_ramdisk_id from the 'baremetal:' namespace within instance_type['extra_specs'] so that it doesn't conflict with ComputeCapabilitiesFilter any more. This allows nova-compute to use ComputeCapabilitiesFilter with baremetal again. For this filter to properly match the baremetal ndoe's RAM, we need to tune two other Nova options for physical hardware. Fixes bug 1129485. Change-Id: I0aa1b0fef8ac59a06217577af8c747437d2d6bf5
437 lines
15 KiB
Plaintext
437 lines
15 KiB
Plaintext
# 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
|