Integration testing preparation for Ironic

Add ability to create/register qemu vms for Ironic testing purposes

Implements bp:deprecate-baremetal-driver

Change-Id: If452438fcc0ff562531b33a36cd189b235654b48
This commit is contained in:
Alexander Gordeev 2014-01-31 18:02:07 +04:00 committed by Adam Gandelman
parent 1fef36e526
commit 06fb29c661
15 changed files with 630 additions and 8 deletions

View File

@ -24,10 +24,17 @@ if is_service_enabled ir-api ir-cond; then
# Start the ironic API and ironic taskmgr components # Start the ironic API and ironic taskmgr components
echo_summary "Starting Ironic" echo_summary "Starting Ironic"
start_ironic start_ironic
if [[ "$IRONIC_BAREMETAL_BASIC_OPS" = "True" ]]; then
prepare_baremetal_basic_ops
fi
fi fi
if [[ "$1" == "unstack" ]]; then if [[ "$1" == "unstack" ]]; then
stop_ironic stop_ironic
if [[ "$IRONIC_BAREMETAL_BASIC_OPS" = "True" ]]; then
cleanup_baremetal_basic_ops
fi
fi fi
if [[ "$1" == "clean" ]]; then if [[ "$1" == "clean" ]]; then

10
files/apts/ironic Normal file
View File

@ -0,0 +1,10 @@
libguestfs0
libvirt-bin
openssh-client
openvswitch-switch
openvswitch-datapath-dkms
python-libguestfs
python-libvirt
syslinux
tftpd-hpa
xinetd

9
files/rpms/ironic Normal file
View File

@ -0,0 +1,9 @@
libguestfs
libvirt
libvirt-python
openssh-clients
openvswitch
python-libguestfs
syslinux
tftp-server
xinetd

View File

@ -140,7 +140,10 @@ BM_DEPLOY_KERNEL=${BM_DEPLOY_KERNEL:-}
# If you need to add any extra flavors to the deploy ramdisk image # If you need to add any extra flavors to the deploy ramdisk image
# eg, specific network drivers, specify them here # eg, specific network drivers, specify them here
BM_DEPLOY_FLAVOR=${BM_DEPLOY_FLAVOR:-} #
# NOTE(deva): this will be moved to lib/ironic in a future patch
# for now, set the default to a suitable value for Ironic's needs
BM_DEPLOY_FLAVOR=${BM_DEPLOY_FLAVOR:--a amd64 ubuntu deploy-ironic}
# set URL and version for google shell-in-a-box # 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} BM_SHELL_IN_A_BOX=${BM_SHELL_IN_A_BOX:-http://shellinabox.googlecode.com/files/shellinabox-2.14.tar.gz}
@ -220,7 +223,7 @@ function upload_baremetal_deploy {
BM_DEPLOY_KERNEL=bm-deploy.kernel BM_DEPLOY_KERNEL=bm-deploy.kernel
BM_DEPLOY_RAMDISK=bm-deploy.initramfs BM_DEPLOY_RAMDISK=bm-deploy.initramfs
if [ ! -e "$TOP_DIR/files/$BM_DEPLOY_KERNEL" -o ! -e "$TOP_DIR/files/$BM_DEPLOY_RAMDISK" ]; then if [ ! -e "$TOP_DIR/files/$BM_DEPLOY_KERNEL" -o ! -e "$TOP_DIR/files/$BM_DEPLOY_RAMDISK" ]; then
$BM_IMAGE_BUILD_DIR/bin/ramdisk-image-create $BM_DEPLOY_FLAVOR deploy \ $BM_IMAGE_BUILD_DIR/bin/ramdisk-image-create $BM_DEPLOY_FLAVOR \
-o $TOP_DIR/files/bm-deploy -o $TOP_DIR/files/bm-deploy
fi fi
fi fi

View File

@ -18,16 +18,19 @@
# - stop_ironic # - stop_ironic
# - cleanup_ironic # - cleanup_ironic
# Save trace setting # Save trace and pipefail settings
XTRACE=$(set +o | grep xtrace) XTRACE=$(set +o | grep xtrace)
PIPEFAIL=$(set +o | grep pipefail)
set +o xtrace set +o xtrace
set +o pipefail
# Defaults # Defaults
# -------- # --------
# Set up default directories # Set up default directories
IRONIC_DIR=$DEST/ironic IRONIC_DIR=$DEST/ironic
IRONIC_DATA_DIR=$DATA_DIR/ironic
IRONIC_STATE_PATH=/var/lib/ironic
IRONICCLIENT_DIR=$DEST/python-ironicclient IRONICCLIENT_DIR=$DEST/python-ironicclient
IRONIC_AUTH_CACHE_DIR=${IRONIC_AUTH_CACHE_DIR:-/var/cache/ironic} IRONIC_AUTH_CACHE_DIR=${IRONIC_AUTH_CACHE_DIR:-/var/cache/ironic}
IRONIC_CONF_DIR=${IRONIC_CONF_DIR:-/etc/ironic} IRONIC_CONF_DIR=${IRONIC_CONF_DIR:-/etc/ironic}
@ -35,6 +38,28 @@ IRONIC_CONF_FILE=$IRONIC_CONF_DIR/ironic.conf
IRONIC_ROOTWRAP_CONF=$IRONIC_CONF_DIR/rootwrap.conf IRONIC_ROOTWRAP_CONF=$IRONIC_CONF_DIR/rootwrap.conf
IRONIC_POLICY_JSON=$IRONIC_CONF_DIR/policy.json IRONIC_POLICY_JSON=$IRONIC_CONF_DIR/policy.json
# 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_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_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_VM_SSH_PORT=${IRONIC_VM_SSH_PORT:-2222}
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:-256}
IRONIC_VM_SPECS_DISK=${IRONIC_VM_SPECS_DISK:-10}
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}
# Support entry points installation of console scripts # Support entry points installation of console scripts
IRONIC_BIN_DIR=$(get_python_exec_prefix) IRONIC_BIN_DIR=$(get_python_exec_prefix)
@ -86,8 +111,8 @@ function configure_ironic {
iniset $IRONIC_CONF_FILE DEFAULT debug True iniset $IRONIC_CONF_FILE DEFAULT debug True
inicomment $IRONIC_CONF_FILE DEFAULT log_file inicomment $IRONIC_CONF_FILE DEFAULT log_file
iniset $IRONIC_CONF_FILE DEFAULT sql_connection `database_connection_url ironic` 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 iniset $IRONIC_CONF_FILE DEFAULT use_syslog $SYSLOG
# Configure Ironic conductor, if it was enabled. # Configure Ironic conductor, if it was enabled.
if is_service_enabled ir-cond; then if is_service_enabled ir-cond; then
configure_ironic_conductor configure_ironic_conductor
@ -97,6 +122,10 @@ function configure_ironic {
if is_service_enabled ir-api; then if is_service_enabled ir-api; then
configure_ironic_api configure_ironic_api
fi fi
if [[ "$IRONIC_BAREMETAL_BASIC_OPS" == "True" ]]; then
configure_ironic_auxiliary
fi
} }
# configure_ironic_api() - Is used by configure_ironic(). Performs # configure_ironic_api() - Is used by configure_ironic(). Performs
@ -125,6 +154,10 @@ function configure_ironic_conductor {
cp -r $IRONIC_DIR/etc/ironic/rootwrap.d $IRONIC_CONF_DIR cp -r $IRONIC_DIR/etc/ironic/rootwrap.d $IRONIC_CONF_DIR
iniset $IRONIC_CONF_FILE DEFAULT rootwrap_config $IRONIC_ROOTWRAP_CONF iniset $IRONIC_CONF_FILE DEFAULT rootwrap_config $IRONIC_ROOTWRAP_CONF
iniset $IRONIC_CONF_FILE conductor api_url http://$SERVICE_HOST:6385
iniset $IRONIC_CONF_FILE pxe tftp_server $SERVICE_HOST
iniset $IRONIC_CONF_FILE pxe tftp_root $IRONIC_TFTPBOOT_DIR
iniset $IRONIC_CONF_FILE pxe tftp_master_path $IRONIC_TFTPBOOT_DIR/master_images
} }
# create_ironic_cache_dir() - Part of the init_ironic() process # create_ironic_cache_dir() - Part of the init_ironic() process
@ -225,9 +258,233 @@ function stop_ironic {
screen -S $SCREEN_NAME -p ir-cond -X kill screen -S $SCREEN_NAME -p ir-cond -X kill
} }
function is_ironic {
if ( is_service_enabled ir-cond && is_service_enabled ir-api ); then
return 0
fi
return 1
}
# Restore xtrace function configure_ironic_dirs {
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
if is_ubuntu; then
PXEBIN=/usr/lib/syslinux/pxelinux.0
elif is_fedora; then
PXEBIN=/usr/share/syslinux/pxelinux.0
fi
if [ ! -f $PXEBIN ]; then
die $LINENO "pxelinux.0 (from SYSLINUX) not found."
fi
cp $PXEBIN $IRONIC_TFTPBOOT_DIR
mkdir -p $IRONIC_TFTPBOOT_DIR/pxelinux.cfg
}
function ironic_ensure_libvirt_group {
groups $STACK_USER | grep -q $LIBVIRT_GROUP || adduser $STACK_USER $LIBVIRT_GROUP
}
function create_bridge_and_vms {
ironic_ensure_libvirt_group
# Call libvirt setup scripts in a new shell to ensure any new group membership
sudo su $STACK_USER -c "$IRONIC_SCRIPTS_DIR/setup-network"
sudo su $STACK_USER -c "$IRONIC_SCRIPTS_DIR/create-nodes \
$IRONIC_VM_SPECS_CPU $IRONIC_VM_SPECS_RAM $IRONIC_VM_SPECS_DISK \
amd64 $IRONIC_VM_COUNT $IRONIC_VM_NETWORK_BRIDGE $IRONIC_VM_EMULATOR" >> $IRONIC_VM_MACS_CSV_FILE
}
function enroll_vms {
CHASSIS_ID=$(ironic chassis-create -d "ironic test chassis" | grep " uuid " | get_field 2)
IRONIC_NET_ID=$(neutron net-list | grep private | get_field 1)
local idx=0
# work around; need to know what netns neutron uses for private network
neutron port-create private
while read MAC; do
NODE_ID=$(ironic node-create --chassis_uuid $CHASSIS_ID --driver pxe_ssh \
-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_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME \
-p cpus=$IRONIC_VM_SPECS_CPU \
-p memory_mb=$IRONIC_VM_SPECS_RAM \
-p local_gb=$IRONIC_VM_SPECS_DISK \
-p cpu_arch=x86_64 \
| grep " uuid " | get_field 2)
ironic port-create --address $MAC --node_uuid $NODE_ID
idx=$((idx+1))
done < $IRONIC_VM_MACS_CSV_FILE
# create the nova flavor
nova flavor-create baremetal auto $IRONIC_VM_SPECS_RAM $IRONIC_VM_SPECS_DISK $IRONIC_VM_SPECS_CPU
nova flavor-key baremetal set "cpu_arch"="x86_64" "baremetal:deploy_kernel_id"="$BM_DEPLOY_KERNEL_ID" "baremetal:deploy_ramdisk_id"="$BM_DEPLOY_RAMDISK_ID"
# intentional sleep to make sure the tag has been set to port
sleep 10
TAPDEV=$(sudo ip netns exec qdhcp-${IRONIC_NET_ID} ip link list | grep tap | cut -d':' -f2 | cut -b2-)
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
}
function configure_tftpd {
# enable tftp natting for allowing connections to SERVICE_HOST's tftp server
sudo modprobe nf_conntrack_tftp
sudo modprobe nf_nat_tftp
if is_ubuntu; then
PXEBIN=/usr/lib/syslinux/pxelinux.0
elif is_fedora; then
PXEBIN=/usr/share/syslinux/pxelinux.0
fi
if [ ! -f $PXEBIN ]; then
die $LINENO "pxelinux.0 (from SYSLINUX) not found."
fi
# 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 {
# Generating ssh key pair for stack user
if [[ ! -d $IRONIC_SSH_KEY_DIR ]]; then
mkdir -p $IRONIC_SSH_KEY_DIR
fi
if [[ ! -d $HOME/.ssh ]]; then
mkdir -p $HOME/.ssh
chmod 700 $HOME/.ssh
fi
echo -e 'n\n' | ssh-keygen -q -t rsa -P '' -f $IRONIC_KEY_FILE
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_sshd {
# Ensure sshd server accepts connections from localhost only
SSH_CONFIG=/etc/ssh/sshd_config
HOST_PORT=$IRONIC_VM_SSH_ADDRESS:$IRONIC_VM_SSH_PORT
if ! sudo grep ListenAddress $SSH_CONFIG | grep $HOST_PORT; then
echo "ListenAddress $HOST_PORT" | sudo tee -a $SSH_CONFIG
fi
SSH_SERVICE_NAME=sshd
if is_ubuntu; then
SSH_SERVICE_NAME=ssh
fi
restart_service $SSH_SERVICE_NAME
# to ensure ssh service is up and running
sleep 3
ironic_ssh_check $IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME $IRONIC_VM_SSH_ADDRESS $IRONIC_VM_SSH_PORT $IRONIC_SSH_USERNAME 10
}
function configure_ironic_auxiliary {
configure_ironic_dirs
configure_ironic_ssh_keypair
configure_ironic_sshd
}
function prepare_baremetal_basic_ops {
# install diskimage-builder
git_clone $BM_IMAGE_BUILD_REPO $BM_IMAGE_BUILD_DIR $BM_IMAGE_BUILD_BRANCH
# make sure all needed service were enabled
for srv in nova glance key neutron; do
if ! is_service_enabled "$srv"; then
die $LINENO "$srv should be enabled for ironic tests"
fi
done
SCREEN_NAME=${SCREEN_NAME:-stack}
SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
# stop all nova services
stop_nova || true
# remove any nova services failure status
find $SERVICE_DIR/$SCREEN_NAME -name 'n-*.failure' -exec rm -f '{}' \;
# start them again
start_nova_api
start_nova
TOKEN=$(keystone token-get | grep ' id ' | get_field 2)
die_if_not_set $LINENO TOKEN "Keystone fail to get token"
echo_summary "Creating and uploading baremetal images for ironic"
# build and upload separate deploy kernel & ramdisk
upload_baremetal_deploy $TOKEN
create_bridge_and_vms
enroll_vms
configure_tftpd
}
function cleanup_baremetal_basic_ops {
rm -f $IRONIC_VM_MACS_CSV_FILE
if [ -f $IRONIC_KEY_FILE ]; then
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
sudo su $STACK_USER -c "$IRONIC_SCRIPTS_DIR/cleanup-nodes $IRONIC_VM_COUNT $IRONIC_VM_NETWORK_BRIDGE"
sudo rm -rf /etc/xinetd.d/tftp /etc/init/tftpd-hpa.override
restart_service xinetd
}
# Restore xtrace + pipefail
$XTRACE $XTRACE
$PIPEFAIL
# Tell emacs to use shell-script-mode # Tell emacs to use shell-script-mode
## Local variables: ## Local variables:

View File

@ -0,0 +1,75 @@
# lib/nova_plugins/hypervisor-ironic
# Configure the ironic hypervisor
# Enable with:
# VIRT_DRIVER=ironic
# Dependencies:
# ``functions`` file
# ``nova`` configuration
# install_nova_hypervisor - install any external requirements
# configure_nova_hypervisor - make configuration changes, including those to other services
# start_nova_hypervisor - start any external services
# stop_nova_hypervisor - stop any external services
# cleanup_nova_hypervisor - remove transient data and cache
# Save trace setting
MY_XTRACE=$(set +o | grep xtrace)
set +o xtrace
# Defaults
# --------
# Entry Points
# ------------
# clean_nova_hypervisor - Clean up an installation
function cleanup_nova_hypervisor {
# This function intentionally left blank
:
}
# configure_nova_hypervisor - Set config files, create data dirs, etc
function configure_nova_hypervisor {
iniset $NOVA_CONF ironic sql_connection `database_connection_url nova_bm`
LIBVIRT_FIREWALL_DRIVER=${LIBVIRT_FIREWALL_DRIVER:-"nova.virt.firewall.NoopFirewallDriver"}
iniset $NOVA_CONF DEFAULT compute_driver ironic.nova.virt.ironic.IronicDriver
iniset $NOVA_CONF DEFAULT firewall_driver $LIBVIRT_FIREWALL_DRIVER
iniset $NOVA_CONF DEFAULT scheduler_host_manager ironic.nova.scheduler.ironic_host_manager.IronicHostManager
iniset $NOVA_CONF DEFAULT ram_allocation_ratio 1.0
iniset $NOVA_CONF DEFAULT reserved_host_memory_mb 0
# ironic section
iniset $NOVA_CONF ironic admin_username admin
iniset $NOVA_CONF ironic admin_password $ADMIN_PASSWORD
iniset $NOVA_CONF ironic admin_url $KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT/v2.0
iniset $NOVA_CONF ironic admin_tenant_name demo
iniset $NOVA_CONF ironic api_endpoint http://$SERVICE_HOST:6358/v1
}
# install_nova_hypervisor() - Install external components
function install_nova_hypervisor {
# This function intentionally left blank
:
}
# start_nova_hypervisor - Start any required external services
function start_nova_hypervisor {
# This function intentionally left blank
:
}
# stop_nova_hypervisor - Stop any external services
function stop_nova_hypervisor {
# This function intentionally left blank
:
}
# Restore xtrace
$MY_XTRACE
# Local variables:
# mode: shell-script
# End:

View File

@ -267,7 +267,7 @@ DEFAULT_VIRT_DRIVER=libvirt
is_package_installed xenserver-core && DEFAULT_VIRT_DRIVER=xenserver is_package_installed xenserver-core && DEFAULT_VIRT_DRIVER=xenserver
VIRT_DRIVER=${VIRT_DRIVER:-$DEFAULT_VIRT_DRIVER} VIRT_DRIVER=${VIRT_DRIVER:-$DEFAULT_VIRT_DRIVER}
case "$VIRT_DRIVER" in case "$VIRT_DRIVER" in
libvirt) ironic|libvirt)
LIBVIRT_TYPE=${LIBVIRT_TYPE:-kvm} LIBVIRT_TYPE=${LIBVIRT_TYPE:-kvm}
if [[ "$os_VENDOR" =~ (Debian) ]]; then if [[ "$os_VENDOR" =~ (Debian) ]]; then
LIBVIRT_GROUP=libvirt LIBVIRT_GROUP=libvirt

View File

@ -55,7 +55,13 @@ export_proxy_variables
# ================ # ================
# Install package requirements # Install package requirements
install_package $(get_packages general $ENABLED_SERVICES) PACKAGES=$(get_packages general $ENABLED_SERVICES)
if is_ubuntu && echo $PACKAGES | grep -q dkms ; then
# ensure headers for the running kernel are installed for any DKMS builds
PACKAGES="$PACKAGES linux-headers-$(uname -r)"
fi
install_package $PACKAGES
if [[ -n "$SYSLOG" && "$SYSLOG" != "False" ]]; then if [[ -n "$SYSLOG" && "$SYSLOG" != "False" ]]; then
if is_ubuntu || is_fedora; then if is_ubuntu || is_fedora; then

View File

@ -0,0 +1,25 @@
#!/usr/bin/env bash
# **cleanup-nodes**
# Cleans up baremetal poseur nodes and volumes created during ironic setup
# Assumes calling user has proper libvirt group membership and access.
set -exu
LIBVIRT_STORAGE_POOL=${LIBVIRT_STORAGE_POOL:-"default"}
VM_COUNT=$1
NETWORK_BRIDGE=$2
for (( idx=0; idx<$VM_COUNT; idx++ )); do
NAME="baremetal${NETWORK_BRIDGE}_${idx}"
VOL_NAME="baremetal${NETWORK_BRIDGE}-${idx}.qcow2"
virsh list | grep -q $NAME && virsh destroy $NAME
virsh list --inactive | grep -q $NAME && virsh undefine $NAME
if virsh pool-list | grep -q $LIBVIRT_STORAGE_POOL ; then
virsh vol-list $LIBVIRT_STORAGE_POOL | grep -q $VOL_NAME &&
virsh vol-delete $VOL_NAME --pool $LIBVIRT_STORAGE_POOL
fi
done

View File

@ -0,0 +1,78 @@
#!/usr/bin/env python
import argparse
import os.path
import libvirt
templatedir = os.path.join(os.path.dirname(os.path.dirname(__file__)),
'templates')
def main():
parser = argparse.ArgumentParser(
description="Configure a kvm virtual machine for the seed image.")
parser.add_argument('--name', default='seed',
help='the name to give the machine in libvirt.')
parser.add_argument('--image',
help='Use a custom image file (must be qcow2).')
parser.add_argument('--engine', default='qemu',
help='The virtualization engine to use')
parser.add_argument('--arch', default='i686',
help='The architecture to use')
parser.add_argument('--memory', default='2097152',
help="Maximum memory for the VM in KB.")
parser.add_argument('--cpus', default='1',
help="CPU count for the VM.")
parser.add_argument('--bootdev', default='hd',
help="What boot device to use (hd/network).")
parser.add_argument('--network', default="brbm",
help='The libvirt network name to use')
parser.add_argument('--libvirt-nic-driver', default='e1000',
help='The libvirt network driver to use')
parser.add_argument('--emulator', default=None,
help='Path to emulator bin for vm template')
args = parser.parse_args()
with file(templatedir + '/vm.xml', 'rb') as f:
source_template = f.read()
params = {
'name': args.name,
'imagefile': args.image,
'engine': args.engine,
'arch': args.arch,
'memory': args.memory,
'cpus': args.cpus,
'bootdev': args.bootdev,
'network': args.network,
'emulator': args.emulator,
}
if args.emulator:
params['emulator'] = args.emulator
else:
if os.path.exists("/usr/bin/kvm"): # Debian
params['emulator'] = "/usr/bin/kvm"
elif os.path.exists("/usr/bin/qemu-kvm"): # Redhat
params['emulator'] = "/usr/bin/qemu-kvm"
nicparams = {
'nicdriver': args.libvirt_nic_driver,
'network': args.network,
}
params['bm_network'] = """
<!-- neutron friendly 'bare metal' network -->
<interface type='network'>
<source network='%(network)s'/>
<virtualport type='openvswitch'/>
<model type='%(nicdriver)s'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</interface>""" % nicparams
libvirt_template = source_template % params
conn = libvirt.open("qemu:///system")
a = conn.defineXML(libvirt_template)
print ("Created machine %s with UUID %s" % (args.name, a.UUIDString()))
if __name__ == '__main__':
main()

View File

@ -0,0 +1,68 @@
#!/usr/bin/env bash
# **create-nodes**
# Creates baremetal poseur nodes for ironic testing purposes
set -exu
# Keep track of the devstack directory
TOP_DIR=$(cd $(dirname "$0")/.. && pwd)
CPU=$1
MEM=$(( 1024 * $2 ))
# extra G to allow fuzz for partition table : flavor size and registered size
# need to be different to actual size.
DISK=$(( $3 + 1))
case $4 in
i386) ARCH='i686' ;;
amd64) ARCH='x86_64' ;;
*) echo "Unsupported arch $4!" ; exit 1 ;;
esac
TOTAL=$(($5 - 1))
BRIDGE=$6
EMULATOR=$7
LIBVIRT_NIC_DRIVER=${LIBVIRT_NIC_DRIVER:-"e1000"}
LIBVIRT_STORAGE_POOL=${LIBVIRT_STORAGE_POOL:-"default"}
if ! virsh pool-list --all | grep -q $LIBVIRT_STORAGE_POOL; then
virsh pool-define-as --name $LIBVIRT_STORAGE_POOL dir --target /var/lib/libvirt/images >&2
virsh pool-autostart $LIBVIRT_STORAGE_POOL >&2
virsh pool-start $LIBVIRT_STORAGE_POOL >&2
fi
pool_state=$(virsh pool-info $LIBVIRT_STORAGE_POOL | grep State | awk '{ print $2 }')
if [ "$pool_state" != "running" ] ; then
[ ! -d /var/lib/libvirt/images ] && sudo mkdir /var/lib/libvirt/images
virsh pool-start $LIBVIRT_STORAGE_POOL >&2
fi
PREALLOC=
if [ -f /etc/debian_version ]; then
PREALLOC="--prealloc-metadata"
fi
DOMS=""
for idx in $(seq 0 $TOTAL) ; do
NAME="baremetal${BRIDGE}_${idx}"
DOMS="$DOMS $NAME"
VOL_NAME="baremetal${BRIDGE}-${idx}.qcow2"
(virsh list --all | grep -q $NAME) && continue
virsh vol-list --pool $LIBVIRT_STORAGE_POOL | grep -q $VOL_NAME &&
virsh vol-delete $VOL_NAME --pool $LIBVIRT_STORAGE_POOL >&2
virsh vol-create-as $LIBVIRT_STORAGE_POOL ${VOL_NAME} ${DISK}G --format qcow2 $PREALLOC >&2
volume_path=$(virsh vol-path --pool $LIBVIRT_STORAGE_POOL $VOL_NAME)
# Pre-touch the VM to set +C, as it can only be set on empty files.
sudo touch "$volume_path"
sudo chattr +C "$volume_path" || true
$TOP_DIR/scripts/configure-vm --bootdev network --name $NAME --image "$volume_path" --arch $ARCH --cpus $CPU --memory $MEM --libvirt-nic-driver $LIBVIRT_NIC_DRIVER --emulator $EMULATOR --network $BRIDGE >&2
done
for dom in $DOMS ; do
# echo mac
virsh dumpxml $dom | grep "mac address" | head -1 | cut -d\' -f2
done

View File

@ -0,0 +1,24 @@
#!/usr/bin/env bash
# **setup-network**
# Setups openvswitch libvirt network suitable for
# running baremetal poseur nodes for ironic testing purposes
set -exu
# Keep track of the devstack directory
TOP_DIR=$(cd $(dirname "$0")/.. && pwd)
BRIDGE_SUFFIX=${1:-''}
BRIDGE_NAME=brbm$BRIDGE_SUFFIX
# Only add bridge if missing
(sudo ovs-vsctl list-br | grep ${BRIDGE_NAME}$) || sudo ovs-vsctl add-br ${BRIDGE_NAME}
# remove bridge before replacing it.
(virsh net-list | grep "${BRIDGE_NAME} ") && virsh net-destroy ${BRIDGE_NAME}
(virsh net-list --inactive | grep "${BRIDGE_NAME} ") && virsh net-undefine ${BRIDGE_NAME}
virsh net-define <(sed s/brbm/$BRIDGE_NAME/ $TOP_DIR/templates/brbm.xml)
virsh net-autostart ${BRIDGE_NAME}
virsh net-start ${BRIDGE_NAME}

View File

@ -0,0 +1,6 @@
<network>
<name>brbm</name>
<forward mode='bridge'/>
<bridge name='brbm'/>
<virtualport type='openvswitch'/>
</network>

View File

@ -0,0 +1,11 @@
service tftp
{
protocol = udp
port = 69
socket_type = dgram
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -v -v -v -v -v --map-file %TFTPBOOT_DIR%/map-file %TFTPBOOT_DIR%
disable = no
}

View File

@ -0,0 +1,43 @@
<domain type='%(engine)s'>
<name>%(name)s</name>
<memory unit='KiB'>%(memory)s</memory>
<vcpu>%(cpus)s</vcpu>
<os>
<type arch='%(arch)s' machine='pc-1.0'>hvm</type>
<boot dev='%(bootdev)s'/>
<bootmenu enable='no'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>%(emulator)s</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='writeback'/>
<source file='%(imagefile)s'/>
<target dev='vda' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
</disk>
<controller type='ide' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
%(network)s
%(bm_network)s
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoport='yes'/>
<video>
<model type='cirrus' vram='9216' heads='1'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
</memballoon>
</devices>
</domain>