Sometime your shell scripts get out of control. Sometimes you are proud of them. Sometimes….both.
I need to be able to re-add a bunch of nodes to an OpenStack cluster on a regular basis. Yes, I could do this with Ansible, but, well, Ansible is great for doing something via SSH, and this just needs to be done here and now. So shell is fine.
This started as a one liner, and got a bit bigger.
This is a utility script that I keep modifying as I need new things from it. I have not cleaned it up or anything, but I find it works OK as is and is not too big that I lose sight of what it is doing.
It reads a csv file that has the list of nodes in it. The order of fields is
name,ipmi_ip, mac1, mac2,resource-class
The second MAC address is ignored for now.
#! /usr/bin/bash #set -x check_enroll(){ ironic_host_name=$1 ironic_ipmi_address=$2 ironic_pxe_interface_mac=$3 openstack baremetal node show $ironic_host_name 2>&1 > /dev/null if [ $? -eq 0 ] then echo $ironic_host_name already exists return 0 else echo $ironic_host_name does not yet exist return 1 fi } ironic_enroll(){ ironic_host_name=$1 ironic_ipmi_address=$2 ironic_pxe_interface_mac=$3 ironic_resource_name=$4 echo "ironic_host_name: " $ironic_host_name echo "ironic ipmi interface: " $ironic_ipmi_address echo "ironic pxe interface mac address: " $ironic_pxe_interface_mac openstack baremetal node show $ironic_host_name 2>&1 > /dev/null if [ $? -eq 0 ] then echo $ironic_host_name already exists return [0] fi echo enrolling $ironic_host_name set -x openstack baremetal node create \ --driver ipmi \ --name ${ironic_host_name} \ --driver-info ipmi_username=${IPMI_USERNAME} \ --driver-info ipmi_password=${IPMI_PASSWD} \ --driver-info ipmi_address=${ironic_ipmi_address} \ --driver-info ipmi_terminal_port=8901 \ --resource-class $ironic_resource_name \ --property cpus=1 \ --property memory_mb=512 \ --property local_gb=1 \ --property cpu_arch=arm64 \ --property capabilities='boot_mode:uefi' \ --driver-info deploy_kernel=${IRONIC_DEPLOY_KERNEL} \ --driver-info deploy_ramdisk=${IRONIC_DEPLOY_INITRD} set +x # Add this to enable console # --console-interface ipmitool-socat \ # --deploy-interface iscsi \ # --deploy-interface direct \ # --raid-interface agent \ sleep 10 NODE_UUID=$(openstack baremetal node list | grep ${ironic_host_name} | awk '{print $2}' | tr '\012' ' ' | awk '{print $1}') echo "*** IRONIC NODE UUID = " ${NODE_UUID} " ***" echo "*** IRONIC Baremetal node show" ${NODE_UUID} " ***" openstack baremetal node show ${NODE_UUID} echo "*** IRONIC Baremetal node console enable" ${NODE_UUID} " ***" openstack baremetal node console enable ${NODE_UUID} echo "*** IRONIC Creating baremetal port added for node " ${NODE_UUID} " ***" openstack baremetal port create ${ironic_pxe_interface_mac} --node ${NODE_UUID} sleep 10 echo "*** IRONIC baremetal node validate " ${NODE_UUID} " ***" openstack baremetal node validate ${NODE_UUID} sleep 10 echo "*** IRONIC baremetal node manage " ${NODE_UUID} " ***" openstack baremetal node manage ${NODE_UUID} sleep 10 echo "*** IRONIC baremetal node inspect " ${NODE_UUID} " ***" openstack baremetal node inspect ${NODE_UUID} sleep 10 echo "*** IRONIC Baremetal node show" ${NODE_UUID} " ***" openstack baremetal node show ${NODE_UUID} echo "*** IRONIC Baremetal node provide" ${NODE_UUID} " ***" openstack baremetal node provide ${NODE_UUID} echo "*** IRONIC Baremetal node show" ${NODE_UUID} " ***" openstack baremetal node show ${NODE_UUID} # Show Hypervisor Stats echo "*** OpenStack Hypervisor stats show ***" openstack hypervisor stats show echo "*** OpenStack Hypervisor show " ${NODE_UUID} " ***" openstack hypervisor show ${NODE_UUID} } ipmi_check(){ ironic_host_name=$1 ironic_ipmi_address=$2 ironic_pxe_interface_mac=$3 echo ipmitool -H $ironic_ipmi_address -U $IPMI_USERNAME -I lanplus -P $IPMI_PASSWD power status ipmitool -H $ironic_ipmi_address -U $IPMI_USERNAME -I lanplus -P $IPMI_PASSWD power status } IPMI_USERNAME=ADMIN IPMI_PASSWD=`cat ipmi_passwd.txt` PROJECT_DIR=$(pwd) DEPLOY_KERNEL='ironic-deploy-kernel' DEPLOY_INITRD='ironic-deploy-initrd' IRONIC_DEPLOY_KERNEL=$( openstack image show ${DEPLOY_KERNEL} -f value -c id ) IRONIC_DEPLOY_INITRD=$( openstack image show ${DEPLOY_INITRD} -f value -c id ) echo "Ironic Deploy Kernel: " ${IRONIC_DEPLOY_KERNEL} echo "Ironic Deploy Initrd: " ${IRONIC_DEPLOY_INITRD} #input='jades.csv' #input='mystiques.csv' input='nodes.csv' while IFS= read -r line do IFS=', ' read -r -a array <<< "$line" echo Processing ${array[0]} check_enroll ${array[0]} ${array[1]} ${array[2]} if [ $? -eq 1 ] then ipmi_check ${array[0]} ${array[1]} ${array[2]} ironic_enroll ${array[0]} ${array[1]} ${array[2]} ${array[4]} fi done < "$input" |
If I were to rework this, I would unroll the loop, and perform all of the same actions first; create the nodes, then port, validate etc. That would avoid the need for the sleep commands when doing it in bulk. However, for just adding a single node, it would break things, and that is more important right now.
Here is my current nodes.csv file.
mystique01-r097,10.76.97.185,98:03:9B:AD:49:0C,98:03:9B:AD:49:0D,baremetal-mystique jade01-r097,10.76.97.173,1c:34:da:71:01:66,1c:34:da:71:01:67,baremetal-jade2 jade02-r097,10.76.97.174,1c:34:da:51:a0:8c,1c:34:da:51:a0:8d,baremetal-jade2 jade03-r097,10.76.97.175,0c:42:a1:52:1d:8c,0c:42:a1:52:1d:8d,baremetal-jade2 jade04-r097,10.76.97.176,1c:34:da:51:d6:c0,1c:34:da:51:d6:c1,baremetal-jade2 jade05-r097,10.76.97.177,98:03:9b:ad:67:20,98:03:9b:ad:67:21,baremetal-jade2 jade06-r097,10.76.97.178,1c:34:da:5a:c7:b0,1c:34:da:5a:c7:b1,baremetal-jade2 jade07-r097,10.76.97.179,98:03:9b:ad:67:38,98:03:9b:ad:67:39,baremetal-jade2 jade08-r097,10.76.97.180,1c:34:da:72:95:4e,1c:34:da:72:95:4f,baremetal-jade2 jade09-r097,10.76.97.181,b8:59:9f:c7:5c:6e,b8:59:9f:c7:5c:6f,baremetal-jade2 jade10-r097,10.76.97.182,98:03:9b:ad:7e:7c,98:03:9b:ad:7e:7d,baremetal-jade2 jade11-r097,10.76.97.183,0C:42:A1:45:3D:24,0C:42:A1:45:3D:25,baremetal-jade2 jade12-r097,10.76.97.184,B8:59:9F:AC:15:4C,B8:59:9F:AC:15:4D,baremetal-jade2 |