Subdirectory 'deployment' relocated to own repo

Remove "deployment/", which is now in its own repo,
starlingx/virtual-deployment.

Story: 2010807
Task: 48291

Signed-off-by: Davlet Panech <davlet.panech@windriver.com>
Change-Id: I267e7b58e8a3b3c69c6a7122dbba5ab314275261
This commit is contained in:
Davlet Panech 2023-06-26 14:14:23 -04:00
parent abe1f6f285
commit 2d8c9bb317
47 changed files with 0 additions and 12460 deletions

View File

@ -1,118 +0,0 @@
StarlingX Deployment in Virtualized Environments
================================================
A StarlingX system can be installed in a variety of platforms with the following
deployment options:
- Standard Controller
- Dedicated Storage
- Controller Storage
- All-in-one
- Duplex
- Simplex
Deployment options uses a variety of configurations based on 3 node identities:
- Controller
- Storage
- Compute
Standard Controller :: Dedicated Storage
----------------------------------------
The software installation workflow for an initial Ceph-backed block
storage on dedicated storage nodes is:
- Controller-0 Installation and Provisioning
- Controller-1 / Compute Host / Storage Host Installation
- Controller-1 Provisioning
- Provider Network Configuration
- Compute Host Provisioning
- Storage Host Provisioning
Standard Controller :: Controller Storage
-----------------------------------------
The software installation workflow for an initial LVM-backed block
storage on controller nodes is:
- Controller-0 Installation
- Controller-0 and System Provisioning
- Controller-1 / Compute Host Installation
- Controller-1 Provisioning
- Compute Host Provisioning
All-in-one :: Duplex
--------------------
The software installation workflow for two combined controller / compute
nodes is:
- Controller-0 Installation and Provisioning
- Controller-1 Installation and Provisioning
All-in-one :: Simplex
---------------------
The software installation workflow for a single combined controller / compute
node is:
- Controller-0 Installation and Provisioning
Virtualization Environments
---------------------------
The available virtualization products where StarlingX has been deployed
are:
- VirtualBox
- Libvirt/QEMU
Directory: libvirt
~~~~~~~~~~~~~~~~~~
Deployment under Libvirt/QEMU uses a set of xml files to define the node
identity:
- Controller All-in-one
- Controller
- Compute
- Storage
These nodes are used to create the virtual machines and the network interfaces
to setup the StarlingX system:
- Setup Simplex
- 1 Controller
- Setup Duplex
- 2 Controllers
- Setup Controller Storage
- 2 Controllers
- 2 Computes
- Setup Dedicated Storage
- 2 Controllers
- 2 Computes
- 2 Storages
Directory: virtualbox
~~~~~~~~~~~~~~~~~~~~~
Deployment under VirtualBox uses a set of configuration files to define the
StarlingX system:
- All-in-one Configuration
- Standard Controller Configuration
These configurations files are used to create the virtual machines and the
network interfaces from a single script:
- Setup VM
Directory: provision
~~~~~~~~~~~~~~~~~~~~
A set of scripts are provided to automate the provisioning of data interfaces and
local storage resources for the compute function for StarlingX Duplex or Simplex.

View File

@ -1,74 +0,0 @@
StarlingX Deployment on Libvirt
===============================
This is a quick reference for deploying StarlingX on libvirt/qemu systems.
It assumes you have a working libvirt/qemu installation for a non-root user
and that your user has NOPASSWD sudo permissions.
Refer also to pages "Installation Guide" on the StarlingX Documentation:
https://docs.starlingx.io/installation_guide/index.html
Overview
--------
We create 4 bridges to use for the STX cloud. This is done in an initial step
separate from the VM management.
Depending on which basic configuration is chosen, we create a number of VMs
for one or more controllers and storage nodes.
These scripts are configured using environment variables that all have built-in
defaults. On shared systems you probably do not want to use the defaults.
The simplest way to handle this is to keep an rc file that can be sourced into
an interactive shell that configures everything. Here's an example::
export CONTROLLER=madcloud
export WORKER=madnode
export BRIDGE_INTERFACE=madbr
export EXTERNAL_NETWORK=172.30.20.0/24
export EXTERNAL_IP=172.30.20.1/24
There is also a script ``cleanup_network.sh`` that will remove networking
configuration from libvirt.
Networking
----------
Configure the bridges using ``setup_network.sh`` before doing anything else. It
will create 4 bridges named ``stxbr1``, ``stxbr2``, ``stxbr3`` and ``stxbr4``.
Set the BRIDGE_INTERFACE environment variable if you need to change stxbr to
something unique.
The ``destroy_network.sh`` script does the reverse, and should not be used lightly.
It should also only be used after all of the VMs created below have been destroyed.
Controllers
-----------
There is one script for creating the controllers: ``setup_configuration.sh``. It
builds different StarlingX cloud configurations:
- simplex
- duplex
- controllerstorage
- dedicatedstorage
You need an StarlingX ISO file for the installation. The script takes the
configuration name with the ``-c`` option and the ISO file name with the
``-i`` option::
./setup_configuration.sh -c simplex -i stx-2018-08-28-93.iso
And the setup will begin. The script create one or more VMs and start the boot
of the first controller, named oddly enough ``controller-0``. If you have Xwindows
available you will get virt-manager running.
If not, Ctrl-C out of that attempt if it doesn't return to a shell prompt.
Then connect to the serial console::
virsh console controller-0
Continue the usual StarlingX installation from this point forward.
Tear down the VMs giving the configuration name with the ``-c`` option::
>-------./destroy_configuration.sh -c simplex

View File

@ -1,21 +0,0 @@
#!/usr/bin/env bash
#
# cleanup_network.sh - Cleans up network interfaces - not safe to run blindly!
SCRIPT_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}" )" )"
source ${SCRIPT_DIR}/functions.sh
NETWORK_DEFAULT=${NETWORK_DEFAULT:-default}
BRIDGE_INTERFACE=${BRIDGE_INTERFACE=stxbr0}
if virsh net-list --name | grep ${NETWORK_DEFAULT} ; then
sudo virsh net-destroy ${NETWORK_DEFAULT}
sudo virsh net-undefine ${NETWORK_DEFAULT}
delete_xml /etc/libvirt/qemu/networks/autostart/${NETWORK_DEFAULT}.xml
fi
if [ -d "/sys/class/net/${BRIDGE_INTERFACE}" ]; then
sudo ifconfig ${BRIDGE_INTERFACE} down || true
sudo brctl delbr ${BRIDGE_INTERFACE} || true
fi

View File

@ -1,103 +0,0 @@
<domain type='kvm' id='164'>
<name>NAME</name>
<memory unit='KiB'>16777216</memory>
<currentMemory unit='KiB'>16777216</currentMemory>
<vcpu placement='static'>4</vcpu>
<resource>
<partition>/machine</partition>
</resource>
<os>
<type arch='x86_64' machine='pc-q35-xenial'>hvm</type>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<cpu match='exact'>
<model fallback='forbid'>Nehalem</model>
<topology sockets='1' cores='4' threads='1'/>
<feature policy='optional' name='vmx'/>
<feature policy='optional' name='svm'/>
</cpu>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='DISK0'/>
<backingStore/>
<target dev='sda' bus='sata'/>
<boot order='1'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='DISK1'/>
<backingStore/>
<target dev='sdb' bus='sata'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<source file='ISO'/>
<backingStore/>
<target dev='sdc' bus='sata'/>
<readonly/>
<boot order='2'/>
</disk>
<interface type='bridge'>
<source bridge='%BR1%'/>
<target dev='vnet0'/>
<model type='e1000'/>
<alias name='net0'/>
</interface>
<interface type='bridge'>
<source bridge='%BR2%'/>
<target dev='vnet1'/>
<model type='e1000'/>
<boot order='3'/>
<alias name='net1'/>
</interface>
<interface type='bridge'>
<source bridge='%BR3%'/>
<target dev='vnet2'/>
<model type='virtio'/>
<alias name='net2'/>
</interface>
<interface type='bridge'>
<source bridge='%BR4%'/>
<target dev='vnet3'/>
<model type='virtio'/>
<alias name='net3'/>
</interface>
<serial type='pty'>
<source path='/dev/pts/8'/>
<target port='0'/>
<alias name='serial0'/>
</serial>
<console type='pty' tty='/dev/pts/8'>
<source path='/dev/pts/8'/>
<target type='serial' port='0'/>
<alias name='serial0'/>
</console>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<graphics type='vnc' port='5900' autoport='yes' listen='127.0.0.1' keymap='en-us'>
<listen type='address' address='127.0.0.1'/>
</graphics>
<video>
<model type='cirrus' vram='16384' heads='1'/>
<alias name='video0'/>
</video>
<memballoon model='virtio'>
<alias name='balloon0'/>
</memballoon>
</devices>
<seclabel type='dynamic' model='apparmor' relabel='yes'>
<label>libvirt-6afab2ba-0ed0-45cb-b1bd-985e211a48de</label>
<imagelabel>libvirt-6afab2ba-0ed0-45cb-b1bd-985e211a48de</imagelabel>
</seclabel>
</domain>

View File

@ -1,109 +0,0 @@
<domain type='kvm' id='164'>
<name>NAME</name>
<memory unit='GiB'>18</memory>
<currentMemory unit='GiB'>18</currentMemory>
<vcpu placement='static'>6</vcpu>
<resource>
<partition>/machine</partition>
</resource>
<os>
<type arch='x86_64' machine='pc-q35-xenial'>hvm</type>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<cpu match='exact'>
<model fallback='forbid'>Nehalem</model>
<topology sockets='1' cores='6' threads='1'/>
<feature policy='optional' name='vmx'/>
<feature policy='optional' name='svm'/>
</cpu>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='DISK0'/>
<backingStore/>
<target dev='sda' bus='sata'/>
<boot order='1'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='DISK1'/>
<backingStore/>
<target dev='sdb' bus='sata'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='DISK2'/>
<backingStore/>
<target dev='sdc' bus='sata'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<source file='ISO'/>
<backingStore/>
<target dev='sdd' bus='sata'/>
<readonly/>
<boot order='2'/>
</disk>
<interface type='bridge'>
<source bridge='%BR1%'/>
<target dev='vnet0'/>
<model type='e1000'/>
<alias name='net0'/>
</interface>
<interface type='bridge'>
<source bridge='%BR2%'/>
<target dev='vnet1'/>
<model type='e1000'/>
<boot order='3'/>
<alias name='net1'/>
</interface>
<interface type='bridge'>
<source bridge='%BR3%'/>
<target dev='vnet2'/>
<model type='virtio'/>
<alias name='net2'/>
</interface>
<interface type='bridge'>
<source bridge='%BR4%'/>
<target dev='vnet3'/>
<model type='virtio'/>
<alias name='net3'/>
</interface>
<serial type='pty'>
<source path='/dev/pts/8'/>
<target port='0'/>
<alias name='serial0'/>
</serial>
<console type='pty' tty='/dev/pts/8'>
<source path='/dev/pts/8'/>
<target type='serial' port='0'/>
<alias name='serial0'/>
</console>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<graphics type='vnc' port='5900' autoport='yes' listen='127.0.0.1' keymap='en-us'>
<listen type='address' address='127.0.0.1'/>
</graphics>
<video>
<model type='cirrus' vram='16384' heads='1'/>
<alias name='video0'/>
</video>
<memballoon model='virtio'>
<alias name='balloon0'/>
</memballoon>
</devices>
<seclabel type='dynamic' model='apparmor' relabel='yes'>
<label>libvirt-6afab2ba-0ed0-45cb-b1bd-985e211a48de</label>
<imagelabel>libvirt-6afab2ba-0ed0-45cb-b1bd-985e211a48de</imagelabel>
</seclabel>
</domain>

View File

@ -1,54 +0,0 @@
#!/usr/bin/env bash
#
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2019 Intel Corporation
#
SCRIPT_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}" )" )"
source ${SCRIPT_DIR}/functions.sh
while getopts "c:" o; do
case "${o}" in
c)
CONFIGURATION=${OPTARG}
;;
*)
usage_destroy
exit 1
;;
esac
done
shift $((OPTIND-1))
if [[ -z ${CONFIGURATION} ]]; then
usage_destroy
exit -1
fi
configuration_check ${CONFIGURATION}
CONFIGURATION=${CONFIGURATION:-simplex}
CONTROLLER=${CONTROLLER:-controller}
DOMAIN_DIRECTORY=vms
destroy_controller ${CONFIGURATION} ${CONTROLLER}
if ([ "$CONFIGURATION" == "controllerstorage" ] || [ "$CONFIGURATION" == "dedicatedstorage" ]); then
WORKER=${WORKER:-worker}
WORKER_NODES_NUMBER=${WORKER_NODES_NUMBER:-1}
for ((i=0; i<=$WORKER_NODES_NUMBER; i++)); do
WORKER_NODE=${CONFIGURATION}-${WORKER}-${i}
destroy_node "worker" $WORKER_NODE
done
fi
if ([ "$CONFIGURATION" == "dedicatedstorage" ]); then
STORAGE=${STORAGE:-storage}
STORAGE_NODES_NUMBER=${STORAGE_NODES_NUMBER:-1}
for ((i=0; i<=$STORAGE_NODES_NUMBER; i++)); do
STORAGE_NODE=${CONFIGURATION}-${STORAGE}-${i}
destroy_node "storage" ${STORAGE_NODE}
done
fi

View File

@ -1,13 +0,0 @@
#!/usr/bin/env bash
BRIDGE_INTERFACE=${BRIDGE_INTERFACE:-stxbr}
EXTERNAL_NETWORK=${EXTERNAL_NETWORK:-10.10.10.0/24}
EXTERNAL_IP=${EXTERNAL_IP:-10.10.10.1/24}
for i in {1..4}; do
BRIDGE_INTERFACE_NAME=${BRIDGE_INTERFACE}$i
if [ -d "/sys/class/net/${BRIDGE_INTERFACE_NAME}" ]; then
sudo ip link set dev ${BRIDGE_INTERFACE_NAME} down
sudo ip link delete dev ${BRIDGE_INTERFACE_NAME}
fi
done

View File

@ -1,190 +0,0 @@
#!/usr/bin/env bash
usage() {
echo "$0 [-h] [-c <configuration>] [-i <iso image>]"
echo ""
echo "Options:"
echo " -c: Configuration: simplex, duplex, controllerstorage, dedicatedstorage"
echo " -i: StarlingX ISO image"
echo ""
}
usage_destroy() {
echo "$0 [-h] [-c <configuration>]"
echo ""
echo "Options:"
echo " -c: Configuration: simplex, duplex, controllerstorage, dedicatedstorage"
echo ""
}
iso_image_check() {
local ISOIMAGE=$1
if ! file ${ISOIMAGE} | grep "DOS/MBR" > /dev/null; then
echo "$ISOIMAGE is not an ISO type"
exit -1
fi
}
configuration_check() {
local CONFIGURATION=$1
if [ $CONFIGURATION != "simplex" ] && [ $CONFIGURATION != "duplex" ] && [ $CONFIGURATION != "controllerstorage" ] && [ $CONFIGURATION != "dedicatedstorage" ]; then
echo "Please check your configuration name, available configurations:"
echo "simplex, duplex, controllerstorage, dedicatedstorage"
exit 1
fi
}
# delete a node's disk file in a safe way
delete_disk() {
local fpath="$1"
if [ ! -f "$fpath" ]; then
echo "file to delete is not a regular file: $fpath" >&2
return 1
fi
file -b "$fpath" | grep -q "^QEMU QCOW Image (v3),"
if [ $? -ne 0 ]; then
echo "file to delete is not QEMU QCOW Image (v3): $fpath" >&2
return 1
fi
sudo rm "$fpath"
}
# delete an xml file in a safe way
delete_xml() {
local fpath="$1"
if [ ! -f "$fpath" ]; then
echo "file to delete is not a regular file: $fpath" >&2
return 1
fi
file -b "$fpath" | grep -q "^ASCII text$"
if [ $? -ne 0 ]; then
echo "file to delete is not ASCII text: $fpath" >&2
return 1
fi
sudo rm "$fpath"
}
# Create a Controller node
create_controller() {
local CONFIGURATION=$1
local CONTROLLER=$2
local BRIDGE_INTERFACE=$3
local ISOIMAGE=$4
local DOMAIN_FILE
if ([ "$CONFIGURATION" == "simplex" ]); then
CONTROLLER_NODE_NUMBER=0
else
CONTROLLER_NODE_NUMBER=1
fi
for ((i=0; i<=$CONTROLLER_NODE_NUMBER; i++)); do
CONTROLLER_NODE=${CONFIGURATION}-${CONTROLLER}-${i}
DOMAIN_FILE=${DOMAIN_DIRECTORY}/${CONTROLLER_NODE}.xml
if ([ "$CONFIGURATION" == "simplex" ] || [ "$CONFIGURATION" == "duplex" ]); then
DISK_0_SIZE=600
cp controller_allinone.xml ${DOMAIN_FILE}
else
DISK_0_SIZE=250
cp controller.xml ${DOMAIN_FILE}
fi
sed -i -e "
s,NAME,${CONTROLLER_NODE},
s,DISK0,/var/lib/libvirt/images/${CONTROLLER_NODE}-0.img,
s,DISK1,/var/lib/libvirt/images/${CONTROLLER_NODE}-1.img,
s,%BR1%,${BRIDGE_INTERFACE}1,
s,%BR2%,${BRIDGE_INTERFACE}2,
s,%BR3%,${BRIDGE_INTERFACE}3,
s,%BR4%,${BRIDGE_INTERFACE}4,
" ${DOMAIN_FILE}
sudo qemu-img create -f qcow2 /var/lib/libvirt/images/${CONTROLLER_NODE}-0.img ${DISK_0_SIZE}G
sudo qemu-img create -f qcow2 /var/lib/libvirt/images/${CONTROLLER_NODE}-1.img 200G
if ([ "$CONFIGURATION" == "simplex" ] || [ "$CONFIGURATION" == "duplex" ]); then
sed -i -e "
s,DISK2,/var/lib/libvirt/images/${CONTROLLER_NODE}-2.img,
" ${DOMAIN_FILE}
sudo qemu-img create -f qcow2 /var/lib/libvirt/images/${CONTROLLER_NODE}-2.img 200G
fi
if [ $i -eq 0 ]; then
sed -i -e "s,ISO,${ISOIMAGE}," ${DOMAIN_FILE}
else
sed -i -e "s,ISO,," ${DOMAIN_FILE}
fi
sudo virsh define ${DOMAIN_FILE}
if [ $i -eq 0 ]; then
sudo virsh start ${CONTROLLER_NODE}
fi
done
}
# Delete a Controller node
destroy_controller() {
local CONFIGURATION=$1
local CONTROLLER=$2
if ([ "$CONFIGURATION" == "simplex" ]); then
CONTROLLER_NODE_NUMBER=0
else
CONTROLLER_NODE_NUMBER=1
fi
for ((i=0; i<=$CONTROLLER_NODE_NUMBER; i++)); do
CONTROLLER_NODE=${CONFIGURATION}-${CONTROLLER}-${i}
DOMAIN_FILE=$DOMAIN_DIRECTORY/$CONTROLLER_NODE.xml
if virsh list --all --name | grep ${CONTROLLER_NODE}; then
STATUS=$(virsh list --all | grep ${CONTROLLER_NODE} | awk '{ print $3}')
if ([ "$STATUS" == "running" ])
then
sudo virsh destroy ${CONTROLLER_NODE}
fi
sudo virsh undefine ${CONTROLLER_NODE}
delete_disk /var/lib/libvirt/images/${CONTROLLER_NODE}-0.img
delete_disk /var/lib/libvirt/images/${CONTROLLER_NODE}-1.img
if ([ "$CONFIGURATION" == "simplex" ] || [ "$CONFIGURATION" == "duplex" ]); then
delete_disk /var/lib/libvirt/images/${CONTROLLER_NODE}-2.img
fi
[ -e ${DOMAIN_FILE} ] && delete_xml ${DOMAIN_FILE}
fi
done
}
# Create a Node
create_node() {
local IDENTITY=$1
local NODE=$2
local BRIDGE_INTERFACE=$3
local DOMAIN_FILE=${DOMAIN_DIRECTORY}/${NODE}.xml
sudo qemu-img create -f qcow2 /var/lib/libvirt/images/${NODE}-0.img 200G
sudo qemu-img create -f qcow2 /var/lib/libvirt/images/${NODE}-1.img 200G
cp ${IDENTITY}.xml ${DOMAIN_FILE}
sed -i -e "
s,NAME,${NODE},;
s,DISK0,/var/lib/libvirt/images/${NODE}-0.img,;
s,DISK1,/var/lib/libvirt/images/${NODE}-1.img,
s,%BR1%,${BRIDGE_INTERFACE}1,
s,%BR2%,${BRIDGE_INTERFACE}2,
s,%BR3%,${BRIDGE_INTERFACE}3,
s,%BR4%,${BRIDGE_INTERFACE}4,
" ${DOMAIN_FILE}
sudo virsh define ${DOMAIN_FILE}
}
# Delete a Node
destroy_node() {
local IDENTITY=$1
local NODE=$2
local DOMAIN_FILE=$DOMAIN_DIRECTORY/$NODE.xml
if virsh list --all --name | grep ${NODE}; then
STATUS=$(virsh list --all | grep ${NODE} | awk '{ print $3}')
if ([ "$STATUS" == "running" ])
then
sudo virsh destroy ${NODE}
fi
sudo virsh undefine ${NODE}
delete_disk /var/lib/libvirt/images/${NODE}-0.img
delete_disk /var/lib/libvirt/images/${NODE}-1.img
[ -e ${DOMAIN_FILE} ] && delete_xml ${DOMAIN_FILE}
fi
}

View File

@ -1,17 +0,0 @@
#!/usr/bin/env bash
#
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2019 Intel Corporation
#
# install_packages.sh - install required packages
sudo apt-get install virt-manager libvirt-bin qemu-system apparmor -y
cat << EOF | sudo tee /etc/libvirt/qemu.conf
user = "root"
group = "root"
EOF
sudo service libvirt-bin restart

View File

@ -1,64 +0,0 @@
#!/usr/bin/env bash
#
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2019 Intel Corporation
#
SCRIPT_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}" )" )"
source ${SCRIPT_DIR}/functions.sh
while getopts "c:i:" o; do
case "${o}" in
c)
CONFIGURATION="$OPTARG"
;;
i)
ISOIMAGE=$(readlink -f "$OPTARG")
;;
*)
usage
exit 1
;;
esac
done
shift $((OPTIND-1))
if [[ -z ${CONFIGURATION} ]] || [[ -z "${ISOIMAGE}" ]]; then
usage
exit -1
fi
iso_image_check ${ISOIMAGE}
configuration_check ${CONFIGURATION}
CONFIGURATION=${CONFIGURATION:-simplex}
BRIDGE_INTERFACE=${BRIDGE_INTERFACE:-stxbr}
CONTROLLER=${CONTROLLER:-controller}
WORKER=${WORKER:-worker}
WORKER_NODES_NUMBER=${WORKER_NODES_NUMBER:-1}
STORAGE=${STORAGE:-storage}
STORAGE_NODES_NUMBER=${STORAGE_NODES_NUMBER:-1}
DOMAIN_DIRECTORY=vms
bash ${SCRIPT_DIR}/destroy_configuration.sh -c $CONFIGURATION
[ ! -d ${DOMAIN_DIRECTORY} ] && mkdir ${DOMAIN_DIRECTORY}
create_controller $CONFIGURATION $CONTROLLER $BRIDGE_INTERFACE $ISOIMAGE
if ([ "$CONFIGURATION" == "controllerstorage" ] || [ "$CONFIGURATION" == "dedicatedstorage" ]); then
for ((i=0; i<=$WORKER_NODES_NUMBER; i++)); do
WORKER_NODE=${CONFIGURATION}-${WORKER}-${i}
create_node "worker" ${WORKER_NODE} ${BRIDGE_INTERFACE}
done
fi
if ([ "$CONFIGURATION" == "dedicatedstorage" ]); then
for ((i=0; i<=$STORAGE_NODES_NUMBER; i++)); do
STORAGE_NODE=${CONFIGURATION}-${STORAGE}-${i}
create_node "storage" ${STORAGE_NODE} ${BRIDGE_INTERFACE}
done
fi
sudo virt-manager

View File

@ -1,39 +0,0 @@
#!/usr/bin/env bash
usage() {
echo "$0 [-h]"
echo ""
echo "Options:"
# echo " -i: StarlingX ISO image"
echo ""
}
while getopts "i:" o; do
case "${o}" in
*)
usage
exit 1
;;
esac
done
shift $((OPTIND-1))
BRIDGE_INTERFACE=${BRIDGE_INTERFACE:-stxbr}
EXTERNAL_NETWORK=${EXTERNAL_NETWORK:-10.10.10.0/24}
EXTERNAL_IP=${EXTERNAL_IP:-10.10.10.1/24}
if [[ -r /sys/class/net/${BRIDGE_INTERFACE}1 ]]; then
echo "${BRIDGE_INTERFACE}1 exists, cowardly refusing to overwrite it, exiting..."
exit 1
fi
for i in {1..4}; do
sudo ip link add ${BRIDGE_INTERFACE}$i type bridge
done
sudo ip addr add $EXTERNAL_IP dev ${BRIDGE_INTERFACE}1
sudo ip link set ${BRIDGE_INTERFACE}1 up
sudo ip link set ${BRIDGE_INTERFACE}2 up
sudo ip link set ${BRIDGE_INTERFACE}3 up
sudo ip link set ${BRIDGE_INTERFACE}4 up
sudo iptables -t nat -A POSTROUTING -s $EXTERNAL_NETWORK -j MASQUERADE

View File

@ -1,95 +0,0 @@
<domain type='kvm' id='187'>
<name>NAME</name>
<memory unit='KiB'>16777216</memory>
<currentMemory unit='KiB'>16777216</currentMemory>
<vcpu placement='static'>4</vcpu>
<resource>
<partition>/machine</partition>
</resource>
<os>
<type arch='x86_64' machine='pc-q35-xenial'>hvm</type>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<cpu match='exact'>
<model fallback='forbid'>Nehalem</model>
<topology sockets='1' cores='4' threads='1'/>
<feature policy='require' name='vmx'/>
<feature policy='optional' name='svm'/>
</cpu>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='DISK0'/>
<backingStore/>
<target dev='sda' bus='sata'/>
<boot order='1'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='DISK1'/>
<backingStore/>
<target dev='sdb' bus='sata'/>
</disk>
<interface type='bridge'>
<source bridge='%BR1%'/>
<target dev='vnet8'/>
<model type='e1000'/>
<alias name='net0'/>
</interface>
<interface type='bridge'>
<source bridge='%BR2%'/>
<target dev='vnet9'/>
<model type='e1000'/>
<boot order='2'/>
<alias name='net1'/>
</interface>
<interface type='bridge'>
<source bridge='%BR3%'/>
<target dev='vnet10'/>
<model type='virtio'/>
<alias name='net2'/>
</interface>
<interface type='bridge'>
<source bridge='%BR4%'/>
<target dev='vnet11'/>
<model type='virtio'/>
<alias name='net3'/>
</interface>
<serial type='pty'>
<source path='/dev/pts/12'/>
<target port='0'/>
<alias name='serial0'/>
</serial>
<console type='pty' tty='/dev/pts/12'>
<source path='/dev/pts/12'/>
<target type='serial' port='0'/>
<alias name='serial0'/>
</console>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<graphics type='vnc' port='5903' autoport='yes' listen='127.0.0.1'
keymap='en-us'>
<listen type='address' address='127.0.0.1'/>
</graphics>
<video>
<model type='cirrus' vram='16384' heads='1'/>
<alias name='video0'/>
</video>
<memballoon model='virtio'>
<alias name='balloon0'/>
</memballoon>
</devices>
<seclabel type='dynamic' model='apparmor' relabel='yes'>
<label>libvirt-608ab5c8-8d11-4bdd-885f-f8b5fee12ff0</label>
<imagelabel>libvirt-608ab5c8-8d11-4bdd-885f-f8b5fee12ff0</imagelabel>
</seclabel>
</domain>

View File

@ -1,94 +0,0 @@
<domain type='kvm' id='187'>
<name>NAME</name>
<memory unit='KiB'>16777216</memory>
<currentMemory unit='KiB'>16777216</currentMemory>
<vcpu placement='static'>4</vcpu>
<resource>
<partition>/machine</partition>
</resource>
<os>
<type arch='x86_64' machine='pc-q35-xenial'>hvm</type>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<cpu match='exact'>
<model fallback='forbid'>Nehalem</model>
<topology sockets='1' cores='4' threads='1'/>
<feature policy='require' name='vmx'/>
<feature policy='optional' name='svm'/>
</cpu>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='DISK0'/>
<backingStore/>
<target dev='sda' bus='sata'/>
<boot order='1'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='DISK1'/>
<backingStore/>
<target dev='sdb' bus='sata'/>
</disk>
<interface type='bridge'>
<source bridge='%BR1%'/>
<target dev='vnet8'/>
<model type='e1000'/>
<alias name='net0'/>
</interface>
<interface type='bridge'>
<source bridge='%BR2%'/>
<target dev='vnet9'/>
<model type='e1000'/>
<boot order='2'/>
<alias name='net1'/>
</interface>
<interface type='bridge'>
<source bridge='%BR3%'/>
<target dev='vnet10'/>
<model type='virtio'/>
<alias name='net2'/>
</interface>
<interface type='bridge'>
<source bridge='%BR4%'/>
<target dev='vnet11'/>
<model type='virtio'/>
<alias name='net3'/>
</interface>
<serial type='pty'>
<source path='/dev/pts/12'/>
<target port='0'/>
<alias name='serial0'/>
</serial>
<console type='pty' tty='/dev/pts/12'>
<source path='/dev/pts/12'/>
<target type='serial' port='0'/>
<alias name='serial0'/>
</console>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<graphics type='vnc' port='5903' autoport='yes' listen='127.0.0.1' keymap='en-us'>
<listen type='address' address='127.0.0.1'/>
</graphics>
<video>
<model type='cirrus' vram='16384' heads='1'/>
<alias name='video0'/>
</video>
<memballoon model='virtio'>
<alias name='balloon0'/>
</memballoon>
</devices>
<seclabel type='dynamic' model='apparmor' relabel='yes'>
<label>libvirt-608ab5c8-8d11-4bdd-885f-f8b5fee12ff0</label>
<imagelabel>libvirt-608ab5c8-8d11-4bdd-885f-f8b5fee12ff0</imagelabel>
</seclabel>
</domain>

View File

@ -1,122 +0,0 @@
#!/usr/bin/env bash
## To be run AFTER "sudo config_controller --config-file TiS_config.ini_vb_simplex"
source /etc/nova/openrc
system license-install license.lic
system host-disk-list controller-0
NODE=controller-0
DEVICE=/dev/sdb
SIZE=$(echo $(system host-disk-list $NODE | grep $DEVICE | awk '{print $12}') | awk -F"." '{print $1}')
DISK=$(system host-disk-list $NODE | grep $DEVICE | awk '{print $2}')
# Create a partition for Cinder
system host-disk-partition-add $NODE $DISK $SIZE -t lvm_phys_vol
# Create the Volume Group
system host-lvg-add $NODE cinder-volumes
# Wait for partition to be created
while true; do
system host-disk-partition-list $NODE --nowrap | grep $DEVICE | grep Ready;
if [ $? -eq 0 ]; then
break;
fi;
sleep 1;
echo "Waiting for Disk Partition for $DEVICE:$NODE"
done
PARTITION=$(system host-disk-partition-list $NODE --disk $DISK --nowrap | grep part1 | awk '{print $2}')
# Create the PV
sleep 1
system host-pv-add $NODE cinder-volumes $PARTITION
sleep 1
#Enable LVM Backend.
system storage-backend-add lvm -s cinder --confirmed
#Wait for backend to be configured:
echo " This can take a few minutes..."
while true; do
system storage-backend-list | grep lvm | grep configured;
if [ $? -eq 0 ]; then
break;
else sleep 10;
fi;
echo "Waiting for backend to be configured"
done
system storage-backend-list
# Add provider networks and assign segmentation ranges
PHYSNET0='providernet-a'
PHYSNET1='providernet-b'
neutron providernet-create ${PHYSNET0} --type vlan
neutron providernet-create ${PHYSNET1} --type vlan
neutron providernet-range-create ${PHYSNET0} --name ${PHYSNET0}-a --range 400-499
neutron providernet-range-create ${PHYSNET0} --name ${PHYSNET0}-b --range 10-10 --shared
neutron providernet-range-create ${PHYSNET1} --name ${PHYSNET1}-a --range 500-599
# Create data interfaces
DATA0IF=eth1000
DATA1IF=eth1001
COMPUTE='controller-0'
system host-list --nowrap &> /dev/null && NOWRAP="--nowrap"
SPL=/tmp/tmp-system-port-list
SPIL=/tmp/tmp-system-host-if-list
system host-port-list ${COMPUTE} $NOWRAP > ${SPL}
system host-if-list -a ${COMPUTE} $NOWRAP > ${SPIL}
DATA0PCIADDR=$(cat $SPL | grep $DATA0IF |awk '{print $8}')
DATA1PCIADDR=$(cat $SPL | grep $DATA1IF |awk '{print $8}')
DATA0PORTUUID=$(cat $SPL | grep ${DATA0PCIADDR} | awk '{print $2}')
DATA1PORTUUID=$(cat $SPL | grep ${DATA1PCIADDR} | awk '{print $2}')
DATA0PORTNAME=$(cat $SPL | grep ${DATA0PCIADDR} | awk '{print $4}')
DATA1PORTNAME=$(cat $SPL | grep ${DATA1PCIADDR} | awk '{print $4}')
DATA0IFUUID=$(cat $SPIL | awk -v DATA0PORTNAME=$DATA0PORTNAME '($12 ~ DATA0PORTNAME) {print $2}')
DATA1IFUUID=$(cat $SPIL | awk -v DATA1PORTNAME=$DATA1PORTNAME '($12 ~ DATA1PORTNAME) {print $2}')
system host-if-modify -m 1500 -n data0 -p ${PHYSNET0} -nt data ${COMPUTE} ${DATA0IFUUID}
system host-if-modify -m 1500 -n data1 -p ${PHYSNET1} -nt data ${COMPUTE} ${DATA1IFUUID}
# Add nova local backend
system host-lvg-add ${COMPUTE} nova-local
ROOT_DISK=$(system host-show ${COMPUTE} | grep rootfs | awk '{print $4}')
ROOT_DISK_UUID=$(system host-disk-list ${COMPUTE} --nowrap | grep ${ROOT_DISK} | awk '{print $2}')
ROOT_DISK_SIZE=$(system host-disk-list ${COMPUTE} --nowrap | grep ${ROOT_DISK} | awk '{print $12}')
PARTITION_SIZE=$(echo ${ROOT_SIZE}/2|bc)
CGTS_PARTITION=$(system host-disk-partition-add -t lvm_phys_vol ${COMPUTE} ${ROOT_DISK_UUID} ${PARTITION_SIZE})
while true; do
system host-disk-partition-list ${COMPUTE} | grep /dev/sda5 | grep Ready
if [ $? -eq 0 ]; then
break;
else sleep 2;
fi;
echo "Waiting to add disk partition"
done
system host-disk-partition-list ${COMPUTE}
CGTS_PARTITION_UUID=$(echo ${CGTS_PARTITION} | grep -ow "| uuid | [a-z0-9\-]* |" | awk '{print $4}')
sleep 1
system host-pv-add ${COMPUTE} cgts-vg ${CGTS_PARTITION_UUID}
sleep 1
NOVA_PARTITION=$(system host-disk-partition-add -t lvm_phys_vol ${COMPUTE} ${ROOT_DISK_UUID} ${PARTITION_SIZE})
while true; do
system host-disk-partition-list ${COMPUTE} | grep /dev/sda6 | grep Ready
if [ $? -eq 0 ]; then
break;
else sleep 2;
fi;
echo "Waiting to add disk partition"
done
system host-disk-partition-list ${COMPUTE}
NOVA_PARTITION_UUID=$(echo ${NOVA_PARTITION} | grep -ow "| uuid | [a-z0-9\-]* |" | awk '{print $4}')
system host-pv-add ${COMPUTE} nova-local ${NOVA_PARTITION_UUID}
sleep 1
system host-lvg-modify -b image -s 10240 ${COMPUTE} nova-local
sleep 10
### This will result in a reboot.
system host-unlock controller-0
echo " Watch CONSOLE to see progress. You will see things like "
echo " Applying manifest 127.168.204.3_patching.pp..."
echo " [DONE]"
echo " Tailing /var/log/platform.log until reboot..."
tail -f /var/log/platform.log

View File

@ -1,56 +0,0 @@
#!/usr/bin/env bash
## To be run AFTER "provision_simplexR5_stage1.sh" and a reboot cycle
source /etc/nova/openrc
# Create tenant networks and routers
echo "Setting up tenant networks"
ADMINID=`openstack project list | grep admin | awk '{print $2}'`
PHYSNET0='providernet-a'
PHYSNET1='providernet-b'
PUBLICNET='public-net0'
PRIVATENET='private-net0'
INTERNALNET='internal-net0'
EXTERNALNET='external-net0'
PUBLICSUBNET='public-subnet0'
PRIVATESUBNET='private-subnet0'
INTERNALSUBNET='internal-subnet0'
EXTERNALSUBNET='external-subnet0'
PUBLICROUTER='public-router0'
PRIVATEROUTER='private-router0'
neutron net-create --tenant-id ${ADMINID} --provider:network_type=vlan --provider:physical_network=${PHYSNET0} --provider:segmentation_id=10 --router:external ${EXTERNALNET}
neutron net-create --tenant-id ${ADMINID} --provider:network_type=vlan --provider:physical_network=${PHYSNET0} --provider:segmentation_id=400 ${PUBLICNET}
neutron net-create --tenant-id ${ADMINID} --provider:network_type=vlan --provider:physical_network=${PHYSNET1} --provider:segmentation_id=500 ${PRIVATENET}
neutron net-create --tenant-id ${ADMINID} ${INTERNALNET}
PUBLICNETID=`neutron net-list | grep ${PUBLICNET} | awk '{print $2}'`
PRIVATENETID=`neutron net-list | grep ${PRIVATENET} | awk '{print $2}'`
INTERNALNETID=`neutron net-list | grep ${INTERNALNET} | awk '{print $2}'`
EXTERNALNETID=`neutron net-list | grep ${EXTERNALNET} | awk '{print $2}'`
neutron subnet-create --tenant-id ${ADMINID} --name ${PUBLICSUBNET} ${PUBLICNET} 192.168.101.0/24
neutron subnet-create --tenant-id ${ADMINID} --name ${PRIVATESUBNET} ${PRIVATENET} 192.168.201.0/24
neutron subnet-create --tenant-id ${ADMINID} --name ${INTERNALSUBNET} --no-gateway ${INTERNALNET} 10.10.0.0/24
neutron subnet-create --tenant-id ${ADMINID} --name ${EXTERNALSUBNET} --gateway 192.168.1.1 --disable-dhcp ${EXTERNALNET} 192.168.1.0/24
echo "Setting up tenant routers"
neutron router-create ${PUBLICROUTER}
neutron router-create ${PRIVATEROUTER}
PRIVATEROUTERID=`neutron router-list | grep ${PRIVATEROUTER} | awk '{print $2}'`
PUBLICROUTERID=`neutron router-list | grep ${PUBLICROUTER} | awk '{print $2}'`
neutron router-gateway-set --disable-snat ${PUBLICROUTERID} ${EXTERNALNETID}
neutron router-gateway-set --disable-snat ${PRIVATEROUTERID} ${EXTERNALNETID}
neutron router-interface-add ${PUBLICROUTER} ${PUBLICSUBNET}
neutron router-interface-add ${PRIVATEROUTER} ${PRIVATESUBNET}
# Create a flavor
echo "Making a flavour"
nova flavor-create s.p1 auto 512 1 1
nova flavor-key s.p1 set hw:cpu_policy=dedicated
nova flavor-key s.p1 set hw:mem_page_size=2048
# Import an image
# due to dns/proxy, just use host and horizon
echo "use Horizon to upload an image. cirros is a good small one"
echo "http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img"

View File

@ -1,26 +0,0 @@
# Virtual machine prefix name
VM_PREFIX_NAME=$(whoami)-simplex-
# Number of controller nodes
TIC_CONTROLLER_NUM=1
# Number of compute nodes
TIC_COMPUTE_NUM=0
# vCPU
TIC_CONTROLLER_CPUS="8"
# Memory size, in MB
TIC_CONTROLLER_MEM="24576"
# Disk1 size, in 1 MB units
TIC_CONTROLLER_DISK1="600000"
# Disk2 size, in 1 MB units
TIC_CONTROLLER_DISK2="16240"
# Disk2 size, in 1 MB units
TIC_CONTROLLER_DISK3="16240"
# First port for VRDE
# This is for a Virtualbox Remote Display Port
# https://www.virtualbox.org/manual/ch07.html#vrde
TIC_VDEPORT_START=1$(id -u)
# Install image
TIC_INSTALL_ISO="$PWD/bootimage.iso"

View File

@ -1,404 +0,0 @@
#!/usr/bin/python3
#
# SPDX-License-Identifier: Apache-2.0
#
"""
Parser to handle command line arguments
"""
import argparse
import getpass
def handle_args():
"""
Handle arguments supplied to the command line
"""
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
"""
**************************************
* Setup type & install configuration *
**************************************
"""
parser.add_argument("--setup-type", help=
"""
Type of setup:
AIO-SX
AIO-DX
STANDARD
STORAGE
""",
choices=['AIO-SX', 'AIO-DX', 'STANDARD', 'STORAGE'],
type=str)
parser.add_argument("--controllers", help=
"""
Number of controllers:
1 - single controller
2 - two controllers
""",
choices=[1, 2],
type=int,
default=2)
parser.add_argument("--workers", help=
"""
Number of workers:
1 - single worker
2 - two workers
etc.
""",
type=int,
default=2)
parser.add_argument("--storages", help=
"""
Number of storage nodes:
1 - single storage node
2 - two storage nodes
etc.\n
""",
type=int,
default=2)
parser.add_argument("--from-stage", help=
"""
Start stage.
For a list of stages run --list-stages
\n
""",
type=str)
parser.add_argument("--to-stage", help=
"""
End stage.
For a list of stages run --list-stages
\n
""",
type=str)
parser.add_argument("--custom-stages", help=
"""
Custom, comma separated list of stages.
For a list of stages run --list-stages
\n
""",
type=str,
default=None)
"""
******************************************
* Config folders and files configuration *
******************************************
"""
parser.add_argument("--iso-location", help=
"""
Location of ISO including the filename:
/folk/myousaf/bootimage.ISO
""",
type=str)
parser.add_argument("--config-files-dir", help=
"""
Directory with config files, scripts, images (i.e.
lab_setup.sh, lab_setup.conf, ...) that are needed
for the install. All files at this location are
transfered to controller-0 in /home/sysadmin. You
can add you own scripts that you need to be
present on the controller. Caution: rsync will
follow links and will fail if links are broken!
Use --config-files-dir-dont-follow-links
instead. Also, you can use both options for
different folders.
""",
type=str)
parser.add_argument("--config-files-dir-dont-follow-links", help=
"""
Same as --config-files-dir but keep symbolic link as is.
""",
type=str)
parser.add_argument("--config-controller-ini", help=
"""
Path to the local config_controller .ini. This
file is transferred to the controller. NOTE: OAM
configuration in this ini is updated dynamically
based on networking related args.
(e.g. stx_config.ini_centos,
~/stx_config.ini_centos, /home/myousaf ...).
""",
type=str)
parser.add_argument("--ansible-controller-config", help=
"""
Path to a local YAML file to be copied as localhost.yml
to the home directory of the controller-0.
""",
type=str)
parser.add_argument("--vbox-home-dir", help=
"""
This is the folder where vbox disks will be
placed. e.g. /home or /folk/cgts/users
The disks will be in /home/wzhou/vbox_disks/ or
/folk/cgts/users/wzhou/vbox_disks/
""",
type=str, default='/home')
parser.add_argument("--lab-setup-conf", help=
"""
Path to the config file to use
""",
action='append')
"""
**************************************
* Disk number and size configuration *
**************************************
"""
parser.add_argument("--controller-disks", help=
"""
Select the number of disks for a controller VM. default is 3
""",
type=int, default=3, choices=[1, 2, 3, 4, 5, 6, 7])
parser.add_argument("--storage-disks", help=
"""
Select the number of disks for storage VM. default is 3
""",
type=int, default=3, choices=[1, 2, 3, 4, 5, 6, 7])
parser.add_argument("--worker-disks", help=
"""
Select the number of disks for a worker VM. default is 2
""",
type=int, default=2, choices=[1, 2, 3, 4, 5, 6, 7])
parser.add_argument("--controller-disk-sizes", help=
"""
Configure size in MiB of controller disks as a comma separated list.
""",
type=str)
parser.add_argument("--storage-disk-sizes", help=
"""
Configure size in MiB of storage disks as a comma separated list.
""",
type=str)
parser.add_argument("--worker-disk-sizes", help=
"""
Configure size in MiB of worker disks as a comma separated list.
""",
type=str)
"""
**************
* Networking *
**************
"""
parser.add_argument("--vboxnet-name", help=
"""
Which host only network to use for setup.
""",
type=str)
parser.add_argument("--vboxnet-ip", help=
"""
The IP address of the host only adapter as it
is configured on the host (i.e. gateway). This is also used to
update GATEWAY_IP in [OAM_NETWORK] of config_controller config file.
""",
type=str)
parser.add_argument("--add-nat-interface", help=
"""
Add a new NAT interface to hosts.
""",
action='store_true')
parser.add_argument("--controller-floating-ip", help=
"""
OAM floating IP.
""",
type=str)
parser.add_argument("--controller0-ip", help=
"""
OAM IP of controller-0. This is also used to
update IP_ADDRESS in [OAM_NETWORK] of
config_controller config file of an AIO SX setup.
This should not be the floating IP.
""",
type=str)
parser.add_argument("--controller1-ip", help=
"""
OAM IP of controller-1.
This should not be the floating IP.
""",
type=str)
parser.add_argument("--vboxnet-type", help=
"""
Type of vbox network, either hostonly on nat
""",
choices=['hostonly', 'nat'],
type=str,
default='hostonly')
parser.add_argument("--nat-controller-floating-local-ssh-port", help=
"""
When oam network is configured as 'nat' a port on
the vbox host is used for connecting to ssh on
floating controller. No default value is
configured. This is mandatory if --vboxnet-type is
'nat' for non AIO-SX deployments.
""",
type=str)
parser.add_argument("--nat-controller0-local-ssh-port", help=
"""
When oam network is configured as 'nat' a port on
the vbox host is used for connecting to ssh on
controller-0. This is mandatory if --vboxnet-type
is 'nat'. No default value is configured.
""",
type=str)
parser.add_argument("--nat-controller1-local-ssh-port", help=
"""
When oam network is configured as 'nat' a port on
the vbox host is used for connecting to ssh on
controller-1. No default value is configued. This
is mandatory if --vboxnet-type is 'nat' for non
AIO-SX deployments or if second controller is
installed.
""",
type=str)
parser.add_argument("--ini-oam-cidr", help=
"""
The IP network and mask for the oam net, used to
update CIDR value in [OAM_NETWORK] of
config_controller config file. Default is
10.10.10.0/24
""",
type=str)
parser.add_argument("--ini-oam-ip-start-address", help=
"""
The start for the oam net allocation, used to
update IP_START_ADDRESS value in [OAM_NETWORK] of
config_controller config file. Not needed for AIO
SX setups.
""",
type=str)
parser.add_argument("--ini-oam-ip-end-address", help=
"""
The end for the oam net allocation, used to update
IP_END_ADDRESS value in [OAM_NETWORK] of
config_controller config file. Not needed for AIO
SX setups.
""",
type=str)
"""
******************
* Custom scripts *
******************
"""
parser.add_argument("--script1", help=
"""
Name of an executable script file plus options.
Has to be present in --config-files-dir.
It will be transfered to host in rsync-config
stage and executed as part of custom-script1
stage.
Example: --script1 'scripts/k8s_pv_cfg.sh,50,ssh,user'
Contains a comma separated value of:
<script_name>,<timeout>,<serial or ssh>,<user/root> Where:
script_name = name of the script, either .sh or .py;
timeout = how much to wait, in seconds, before considering failure;
serial/ssh = executed on the serial console;
user/root = as a user or as root (sudo <script_name);
Script executes successfully if return code is 0. Anything else
is considered error and further execution is aborted.
""",
default=None,
type=str)
parser.add_argument("--script2", help=
"""
See --script1
""",
default=None,
type=str)
parser.add_argument("--script3", help=
"""
See --script1
""",
default=None,
type=str)
parser.add_argument("--script4", help=
"""
See --script1
""",
default=None,
type=str)
parser.add_argument("--script5", help=
"""
See --script1
""",
default=None,
type=str)
"""
**************************************
* Other *
**************************************
"""
parser.add_argument("--list-stages", help=
"""
List stages that can be used by autoinstaller.
""",
action='store_true')
parser.add_argument("--logpath", help=
"""
Base directory to store logs.
""",
type=str)
parser.add_argument("--force-delete-lab", help=
"""
Don't ask for confirmation when deleting a lab.
""",
action='store_true')
parser.add_argument("--snapshot", help=
"""
Take snapshot at different stages when the lab is installed.
E.g. before and after config_controller, before and after lab_setup.
""",
action='store_true')
parser.add_argument("--securityprofile", help=
"""
Security profile to use:
standard
extended
Standard is the default
""",
type=str, choices=['standard', 'extended'],
default='standard')
parser.add_argument("--lowlatency", help=
"""
Whether to install an AIO system as low latency.
""",
action='store_true')
parser.add_argument("--install-mode", help=
"""
Lab will be installed using the mode specified. Serial mode by default
""",
type=str, choices=['serial', 'graphical'], default='serial')
parser.add_argument("--username", help=
"""
Username. default is 'sysadmin'
""",
type=str)
parser.add_argument("--password", help=
"""
Password. default is 'Li69nux*'
""",
type=str)
parser.add_argument("--labname", help=
"""
The name of the lab to be created.
""",
type=str)
parser.add_argument("--userid", help=
"""
Unique user id to differentiate vbox machine
unique names such as interface names or serial
ports even if setups have the same names for
different users. Default is your username on this
machine.
""",
type=str,
default=getpass.getuser())
parser.add_argument("--hostiocache", help=
"""
Turn on host i/o caching
""",
action='store_true')
return parser

View File

@ -1,175 +0,0 @@
# Pybox
This automated installer provides you with an easy way to install
StarlingX in many different configuration options. The following
acronyms are important to understand:
- `AIO` stands for All-In-One, and it means that a single host might
be responsible for more than one role.
- `SX` stands for Simplex, and it means there's only one controller node
that the whole installation depends on.
- `DX` stands for Duplex, and it means that 2 or more controllers will
be arranged in a high-availability setup.
The configurations available from this script, via the `--setup-type`
parameter, are:
- `AIO-SX` or "All-In-One Simplex" will set up one single VM that will be both
a controller and a worker nodes.
- `AIO-DX` or "All-In-One Duplex" will set up two controller VMs with one of
them also being a worker.
- `Standard` and `Storage` setups are currently under review.
Overall Design of the Code
--------------------------
The main concepts of the autoinstaller are stages and chains. A stage
is an atomic set of actions taken by the autoinstaller. A chain is a set
of stages executed in a specific order. Stages can be executed
independently and repeated as many times the user needs. Chains can be
configured with the desired stages by the user. Or, the user can select a
specific chain from the available ones.
Example stages:
- create-lab # Create VMs in vbox: controller-0, controller-1...
- install-controller-0 # Install controller-0 from --iso-location
- config-controller # Run config controller using the
- config-controller-ini updated based on --ini-* options.
- rsync-config # Rsync all files from --config-files-dir and
--config-files-dir* to /home/sysadmin.
- lab-setup1 # Run lab_setup with one or more --lab-setup-conf
files from controller-0.
- unlock-controller-0 # Unlock controller-0 and wait for it to reboot.
- lab-setup2 # Run lab_setup with one or more --lab-setup-conf
files from controller-0.
Example chains: [create-lab, install-controller-0, config-controller,
rsync-config, lab-setup1, unlock-controller-0, lab-setup2]. This chain
will install an AIO-SX.
The autoinstaller has a predefined set of chains. The user can select from
these chains and choose from which stage to which stage to do the install.
For example, if the user already executed config_controller, they can choose
to continue from rsync-config to lab-setup2.
The user can also create a custom set of chains, as he sees fit by
specifying them in the desired order. This allows better customization of
the install process. For example, the user might want to execute his own
script after config_controller. In this case, he will have to specify a
chain like this: [create-lab, install-controller-0, config-controller,
rsync-config, custom-script1, lab-setup1, unlock-controller-0, lab-setup2]
The installer supports creating virtualbox snapshots after each stage so
the user does not need to reinstall from scratch. The user can restore the
snapshot of the previous stage, whether to retry or fix the issue
manually, then continue the process.
## List of Features
Basic:
- Multi-user, and multiple lab installs can run at the same time.
- Uses config_controller ini and lab_setup.sh script to drive the
configuration [therefore their requirements have to be met prior to
execution].
- Specify setup (lab) name - this will group all nodes related to
this lab in a virtual box group
- Setup type - specify what you want to install (SX,DX,Standard,
Storage)
- Specify start and end stages or a custom list of stages
- Specify your custom ISO, config_controller ini file locations
- Updates config_controller ini automatically with your custom OAM
networking options so that you don't need to update the ini file for
each setup
- Rsync entire content from a couple of folders on your disk
directly on the controller /home/wrsroot thus allowing you easy access
to your scripts and files
- Take snapshots after each stage
Configuration:
- Specify the number of nodes you want for your setup (one or two controllers,
x storages, y workers)
- Specify the number of disks attached to each node. They use the
default sizes configured) or you can explicitly specify the sizes of the
disks
- Use either 'hostonly' adapter or 'NAT' interface with automated
port forwarding for SSH ports.
Advanced chains:
- Specify custom chain using any of the existing stages
- Ability to run your own custom scripts during the install process
- Ability to define what scripts are executed during custom script
stages, their timeout, are executed over ssh or serial, are executed as
normal user or as root.
Other features
- Log files per lab and date.
- Enable hostiocache option for virtualbox VMs storage controllers
to speed up install
- Basic support for Kubernetes (AIO-SX installable through a custom
chain)
- Support to install lowlatency and securityprofile
## Installation and Usage
This section covers a basic functioning example of the **All-In-One Simplex
(AIO-SX) installation**, which creates one VM that will work as both a
Controller and a Worker. A NAT Network between the host and the Virtual Machine
will be configured and used.
>_NOTE_: the following steps assume you're on a Debian-based Linux box.
1. Install dependencies:
```shell
sudo apt install virtualbox socat git rsync sshpass openssh-client python3-pip python3-venv
```
2. Create a NAT Network with the `VBoxManage` CLI that is installed with VirtualBox:
```shell
VBoxManage natnetwork add --netname NatNetwork --network 10.10.10.0/24 --dhcp off --ipv6 on
VBoxManage natnetwork modify --netname NatNetwork --port-forward-4 http-8080:tcp:[]:8080:[10.10.10.3]:8080
```
3. Checkout the repository, and set up Python's Virtual Environment with:
```shell
git clone https://opendev.org/starlingx/tools.git
cd tools/deployment/virtualbox/pybox
python3 -m venv venv
source ./venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
```
4. Grab the latest ISO (this script was last tested with version 8.0.0):
```shell
wget https://mirror.starlingx.cengn.ca/mirror/starlingx/release/latest_release/debian/monolithic/outputs/iso/starlingx-intel-x86-64-cd.iso \
-O $HOME/Downloads/stx-8.iso
```
5. Now you're ready to run the script. From the `/deployment/virtualbox/pybox`
folder, do:
```shell
python3 ./install_vbox.py --setup-type AIO-SX \
--iso-location "$HOME/Downloads/stx-8.iso" \
--labname StarlingX --install-mode serial \
--config-files-dir ./configs/aio-sx/ \
--config-controller-ini ./configs/aio-sx/stx_config.ini_centos \
--ansible-controller-config ./configs/aio-sx/localhost.yml \
--vboxnet-type nat \
--vboxnet-name NatNetwork \
--nat-controller0-local-ssh-port 3122 \
--controller0-ip 10.10.10.3 \
--ini-oam-cidr '10.10.10.0/24' \
--snapshot
```
The script takes a while to do all the things (from creating a VM and
installing an OS in it to configuring StarlingX). Several restarts might
occur, and you might see a VirtualBox with a prompt. You don't need to type
anything. While the installation script is running it will take care of
everything for you.

View File

@ -1,67 +0,0 @@
VSWITCH_TYPE="ovs-dpdk"
## Lab specific configuration
SYSTEM_NAME="vbox"
MGMTSUBNETS=("192.168.151.0/27,192.168.151.32/27,192.168.151.64/27", "192.168.251.0/27,192.168.251.32/27,192.168.251.64/27")
MGMTDVR=("no" "no")
EXTERNALGWIP="192.168.51.1"
EXTERNALCIDR="192.168.51.0/24"
DATAMTU=1500
INFRAMTU=9000
MGMTMTU=1500
NAMESERVERS=("8.8.8.8,4.4.4.4")
NTPSERVERS=("0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org")
CINDER_BACKENDS="ceph"
GLANCE_BACKENDS="ceph"
WHEN_TO_CONFIG_CEPH="early"
CEPH_TIER_DEFAULT="storage"
CONTROLLER0_OSD_DEVICES="/dev/disk/by-path/pci-0000:00:0d.0-ata-2.0|${CEPH_TIER_DEFAULT}"
## Provider network overrides
PROVIDERNETS="vlan|data0|${DATAMTU}|10-10|shared \
vlan|data0|${DATAMTU}|700-733|shared \
vlan|data0|${DATAMTU}|734-766|tenant1 \
vlan|data1|${DATAMTU}|767-799|tenant2"
## Manual tenant network assignments
EXTERNALPNET="vlan|data0|10"
INTERNALPNET="vlan|data0"
## Interface overrides
DATA_INTERFACES="ethernet|eth1000|${DATAMTU}|data0 \
ethernet|eth1001|${DATAMTU}|data1"
OAM_INTERFACES="ethernet|enp0s3|1500|none"
## IP address pools to support VXLAN provider networks. Each compute node will
## get an address allocated from within the specified pools
##
VLAN11_IPPOOLS="vlan11v4|192.168.59.0|24|random|192.168.59.239-192.168.59.239 vlan11v6|fd00:0:0:b::|64|sequential|fd00:0:0:b::ee-fd00:0:0:b::ee"
## Networking test mode
NETWORKING_TYPE="layer3"
## Network and VM instance parameters
VIRTIOAPPS=1
## Maximum number of networks physically possible in this lab
MAXNETWORKS=20
## Maximum number of VLANs per internal network
MAXVLANS=4
## Profile testing in this lab
TEST_PROFILES="no"
## Partitions.
CONTROLLER0_PARTITIONS="/dev/disk/by-path/pci-0000:00:0d.0-ata-1.0,[10,10]"
## Devices to extend cgts-vg
CONTROLLER0_CGTS_STORAGE="/dev/disk/by-path/pci-0000:00:0d.0-ata-1.0-part5"
## Local Storage override for this lab based on disks available
CONTROLLER0_LOCAL_STORAGE="local_image|/dev/disk/by-path/pci-0000:00:0d.0-ata-3.0|fixed|5"
## Kubernetes
K8S_ENABLED="yes"

File diff suppressed because it is too large Load Diff

View File

@ -1,65 +0,0 @@
#!/bin/bash
## This file makes the necessary configuration for the unlock of the Controller-0
GROUPNO=0
DATE_FORMAT="%Y-%m-%d %T"
LOG_FILE=${LOG_FILE:-"${HOME}/lab_setup_1.group${GROUPNO}.log"}
VERBOSE_LEVEL=0
OPENRC=/etc/platform/openrc
source ${OPENRC}
function info {
local MSG="$1"
echo ${MSG}
echo $(date +"${DATE_FORMAT}") ${MSG} >> ${LOG_FILE}
}
function log_command {
local CMD=$1
local MSG="[${OS_USERNAME}@${OS_PROJECT_NAME}]> RUNNING: ${CMD}"
set +e
if [ ${VERBOSE_LEVEL} -gt 0 ]; then
echo ${MSG}
fi
echo $(date +"${DATE_FORMAT}") ${MSG} >> ${LOG_FILE}
if [ ${VERBOSE_LEVEL} -gt 1 ]; then
eval ${CMD} 2>&1 | tee -a ${LOG_FILE}
RET=${PIPESTATUS[0]}
else
eval ${CMD} &>> ${LOG_FILE}
RET=$?
fi
if [ ${RET} -ne 0 ]; then
info "COMMAND FAILED (rc=${RET}): ${CMD}"
info "==========================="
info "Check \"${LOG_FILE}\" for more details, fix the issues and"
info "re-run the failed command manually."
exit 1
fi
set -e
return ${RET}
}
## Set OAM interface
function configure_OAM_interface {
#Set OAM_IF variable
log_command "OAM_IF=enp0s3"
#Associate OAM_IF with Controller-0
log_command "system host-if-modify controller-0 $OAM_IF -c platform"
log_command "system interface-network-assign controller-0 $OAM_IF oam"
return 0
}
configure_OAM_interface

View File

@ -1,13 +0,0 @@
system_mode: simplex
dns_servers:
- 1.1.1.1
- 8.8.8.8
external_oam_subnet: 10.10.10.0/24
external_oam_gateway_address: 10.10.10.1
external_oam_floating_address: 10.10.10.3
admin_username: admin
admin_password: Li69nux*
ansible_become_pass: Li69nux*

View File

@ -1,19 +0,0 @@
[LOGICAL_INTERFACE_2]
LAG_INTERFACE=N
INTERFACE_MTU=1500
INTERFACE_PORTS=enp0s3
[OAM_NETWORK]
IP_ADDRESS = 10.10.10.2
CIDR=10.10.10.0/24
GATEWAY=10.10.10.1
LOGICAL_INTERFACE=LOGICAL_INTERFACE_2
[AUTHENTICATION]
ADMIN_PASSWORD=Li69nux*
[VERSION]
RELEASE = 19.01
[SYSTEM]
SYSTEM_MODE=simplex

View File

@ -1,75 +0,0 @@
[General]
controllers=2
workers=2
storage=0
aio=False
deletevms=False
useexistinglab=True
securityprofile=standard
lowlatency=False
install_mode=graphical
[PhysicalTopology]
[ControllerCEPH]
memory=8192,
cpus=2,
disks=[80000]
[ControllerLVM]
memory=8192
cpus=2
disks=[100000, 10000]
[ControllerAIO]
memory=12288,
cpus=2
disks=[24000, 40000],
[Compute]
memory=4096
cpus=3
disks=[50000, 30000]
[Storage]
memory=3072
cpus=1
disks=[50000, 10000],
[NetworkTopology]
[Controller]
1={'nic': 'hostonly', 'intnet': 'none', 'nictype': '82540EM', 'nicpromisc': 'deny', 'hostonlyadapter': 'vboxnet0'}
2={'nic': 'intnet', 'intnet': 'intnet-management', 'nictype': '82540EM', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'}
3={'nic': 'intnet', 'intnet': 'intnet-infra', 'nictype': '82540EM', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'}
[Compute]
1={'nic': 'intnet', 'intnet': 'intnet-unused', 'nictype': '82540EM', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'}
2={'nic': 'intnet', 'intnet': 'intnet-management', 'nictype': '82540EM', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'}
3={'nic': 'intnet', 'intnet': 'intnet-data1', 'nictype': 'virtio', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'}
4={'nic': 'intnet', 'intnet': 'intnet-data2', 'nictype': 'virtio', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'}
[Storage]
1={'nic': 'internal', 'intnet': 'intnet-unused', 'nictype': '82540EM', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'}
2={'nic': 'internal', 'intnet': 'intnet-management', 'nictype': '82540EM', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'}
3={'nic': 'internal', 'intnet': 'intnet-infra', 'nictype': '82540EM', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'}
[OAMHostOnlyNetwork]
ip=10.10.10.254
netmask=255.255.255.0
[Lab]
name=vbox
floating_ip=10.10.10.7
controller-0_ip=10.10.10.8
controller-1_ip=10.10.10.9
username=sysadmin
password=Li69nux*
[Serial]
uartbase=0x3F8
uartport=4
uartmode=server
uartpath=/tmp
[ISO]
isohost=localhost
isopath=/tmp/bootimage.iso

View File

@ -1,27 +0,0 @@
#!/usr/bin/python3
#
# SPDX-License-Identifier: Apache-2.0
#
import getpass
from sys import platform
import os
user = getpass.getuser()
if platform == 'win32' or platform == 'win64':
LOGPATH = 'C:\\Temp\\pybox_logs'
PORT = 10000
else:
homedir = os.environ['HOME']
LOGPATH = '{}/vbox_installer_logs'.format(homedir)
class Lab:
VBOX = {
'floating_ip': '10.10.10.7',
'controller-0_ip': '10.10.10.8',
'controller-1_ip': '10.10.10.9',
'username': 'sysadmin',
'password': 'Li69nux*',
}

View File

@ -1,78 +0,0 @@
#!/usr/bin/python3
#
# SPDX-License-Identifier: Apache-2.0
#
from sys import platform
class Subnets:
IPV4 = {
'mgmt_subnet': '192.168.204.0/24',
'infra_subnet': '192.168.205.0/24',
'oam_subnet': '10.10.10.0/24'
}
IPV6 = {
'mgmt_subnet': 'aefd::/64',
'infra_subnet': 'aced::/64',
'oam_subnet': 'abcd::/64'
}
class NICs:
if platform == 'win32' or platform == 'win64':
CONTROLLER = {
'node_type': 'controller',
'1': {'nic': 'hostonly', 'intnet': '', 'nictype': '82540EM', 'nicpromisc': 'deny', 'hostonlyadapter': 'VirtualBox Host-Only Ethernet Adapter'},
'2': {'nic': 'intnet', 'intnet': 'intnet-management', 'nictype': '82540EM', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'},
'3': {'nic': 'intnet', 'intnet': 'intnet-data1', 'nictype': 'virtio', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'},
'4': {'nic': 'intnet', 'intnet': 'intnet-data2', 'nictype': 'virtio', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'},
}
else:
CONTROLLER = {
'node_type': 'controller',
'1': {'nic': 'hostonly', 'intnet': '', 'nictype': '82540EM', 'nicpromisc': 'deny', 'hostonlyadapter': 'vboxnet0'},
'2': {'nic': 'intnet', 'intnet': 'intnet-management', 'nictype': '82540EM', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'},
'3': {'nic': 'intnet', 'intnet': 'intnet-data1', 'nictype': 'virtio', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'},
'4': {'nic': 'intnet', 'intnet': 'intnet-data2', 'nictype': 'virtio', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'},
}
COMPUTE = {
'node_type': 'compute',
'1': {'nic': 'intnet', 'intnet': 'intnet-unused1', 'nictype': '82540EM', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'},
'2': {'nic': 'intnet', 'intnet': 'intnet-management', 'nictype': '82540EM', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'},
'3': {'nic': 'intnet', 'intnet': 'intnet-data1', 'nictype': 'virtio', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'},
'4': {'nic': 'intnet', 'intnet': 'intnet-data2', 'nictype': 'virtio', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'},
}
STORAGE = {
'node_type': 'storage',
'1': {'nic': 'intnet', 'intnet': 'intnet-unused', 'nictype': '82540EM', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'},
'2': {'nic': 'intnet', 'intnet': 'intnet-management', 'nictype': '82540EM', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'},
'3': {'nic': 'intnet', 'intnet': 'intnet-infra', 'nictype': '82540EM', 'nicpromisc': 'allow-all', 'hostonlyadapter': 'none'},
}
class OAM:
OAM = {
'ip': '10.10.10.254',
'netmask': '255.255.255.0',
}
class Serial:
if platform == 'win32' or platform == 'win64':
SERIAL = {
'uartbase': '0x3F8',
'uartport': '4',
'uartmode': 'tcpserver',
'uartpath': '10000'
}
else:
SERIAL = {
'uartbase': '0x3F8',
'uartport': '4',
'uartmode': 'server',
'uartpath': '/tmp/'
}

View File

@ -1,79 +0,0 @@
#!/usr/bin/python3
#
# SPDX-License-Identifier: Apache-2.0
#
class Nodes:
CONTROLLER_CEPH = {
'node_type': 'controller-STORAGE',
'memory': 12288,
'cpus': 5,
'disks': {
1:[240000],
2:[240000, 10000],
3:[240000, 10000, 10000],
4:[240000, 10000, 10000, 10000],
5:[240000, 10000, 10000, 10000, 10000],
6:[240000, 10000, 10000, 10000, 10000, 10000],
7:[240000, 10000, 10000, 10000, 10000, 10000, 10000]
}
}
CONTROLLER_LVM = {
'node_type': 'controller-STANDARD',
'memory': 12288,
'cpus': 5,
'disks': {
1:[240000],
2:[240000, 10000],
3:[240000, 10000, 10000],
4:[240000, 10000, 10000, 10000],
5:[240000, 10000, 10000, 10000, 10000],
6:[240000, 10000, 10000, 10000, 10000, 10000],
7:[240000, 10000, 10000, 10000, 10000, 10000, 10000]
}
}
CONTROLLER_AIO = {
'node_type': 'controller-AIO',
'memory': 20000,
'cpus': 8,
'disks': {
1:[240000],
2:[240000, 10000],
3:[240000, 10000, 10000],
4:[240000, 10000, 10000, 10000],
5:[240000, 10000, 10000, 10000, 10000],
6:[240000, 10000, 10000, 10000, 10000, 10000],
7:[240000, 10000, 10000, 10000, 10000, 10000, 10000]
}
}
COMPUTE = {
'node_type': 'compute',
'memory': 4096,
'cpus': 3,
'disks': {
1:[50000],
2:[50000, 10000],
3:[50000, 10000, 10000],
4:[50000, 10000, 10000, 10000],
5:[50000, 10000, 10000, 10000, 10000],
6:[50000, 10000, 10000, 10000, 10000, 10000],
7:[50000, 10000, 10000, 10000, 10000, 10000, 10000]
}
}
STORAGE = {
'node_type': 'storage',
'memory': 3072,
'cpus': 3,
'disks': {
1:[50000],
2:[50000, 10000],
3:[50000, 10000, 10000],
4:[50000, 10000, 10000, 10000],
5:[50000, 10000, 10000, 10000, 10000]
}
}

View File

@ -1,15 +0,0 @@
#!/usr/bin/python3
#
# SPDX-License-Identifier: Apache-2.0
#
class HostTimeout:
CONTROLLER_UNLOCK = 3600+1800
REBOOT = 900
INSTALL = 3600
LAB_INSTALL = 3600
HOST_INSTALL = 3600
LAB_CONFIG = 5400
INSTALL_PATCHES = 900
NETWORKING_OPERATIONAL = 60

View File

@ -1,160 +0,0 @@
#!/usr/bin/python3
#
# SPDX-License-Identifier: Apache-2.0
#
import time
import streamexpect
from consts.timeout import HostTimeout
from utils import serial
from utils.install_log import LOG
def unlock_host(stream, hostname):
"""
Unlocks given host
Args:
stream(stream): Stream to active controller
hostname(str): Name of host to unlock
Steps:
- Check that host is locked
- Unlock host
"""
LOG.info("#### Unlock %s", hostname)
serial.send_bytes(stream, "system host-list | grep {}".format(hostname), expect_prompt=False)
try:
serial.expect_bytes(stream, "locked")
except streamexpect.ExpectTimeout:
LOG.info("Host %s not locked", hostname)
return 1
serial.send_bytes(stream, "system host-unlock {}".format(hostname), expect_prompt=False)
LOG.info("Unlocking %s", hostname)
def lock_host(stream, hostname):
"""
Locks the specified host.
Args:
stream(stream): Stream to controller-0
hostname(str): Name of host to lock
Steps:
- Check that host is unlocked
- Lock host
"""
LOG.info("Lock %s", hostname)
serial.send_bytes(stream, "system host-list |grep {}".format(hostname), expect_prompt=False)
try:
serial.expect_bytes(stream, "unlocked")
except streamexpect.ExpectTimeout:
LOG.info("Host %s not unlocked", hostname)
return 1
serial.send_bytes(stream, "system host-lock {}".format(hostname), expect_prompt="keystone")
LOG.info("Locking %s", hostname)
def reboot_host(stream, hostname):
"""
Reboots host specified
Args:
stream():
hostname(str): Host to reboot
"""
LOG.info("Rebooting %s", hostname)
serial.send_bytes(stream, "system host-reboot {}".format(hostname), expect_prompt=False)
serial.expect_bytes(stream, "rebooting", HostTimeout.REBOOT)
def install_host(stream, hostname, host_type, host_id):
"""
Initiates install of specified host. Requires controller-0 to be installed already.
Args:
stream(stream): Stream to cont0
hostname(str): Name of host
host_type(str): Type of host being installed e.g. 'storage' or 'compute'
host_id(int): id to identify host
"""
time.sleep(10)
LOG.info("Installing %s with id %s", hostname, host_id)
if host_type is 'controller':
serial.send_bytes(stream,
"system host-update {} personality=controller".format(host_id),
expect_prompt=False)
elif host_type is 'storage':
serial.send_bytes(stream,
"system host-update {} personality=storage".format(host_id),
expect_prompt=False)
else:
serial.send_bytes(stream,
"system host-update {} personality=compute hostname={}".format(host_id,
hostname),
expect_prompt=False)
time.sleep(30)
def disable_logout(stream):
"""
Disables automatic logout of users.
Args:
stream(stream): stream to cont0
"""
LOG.info('Disabling automatic logout')
serial.send_bytes(stream, "export TMOUT=0")
def change_password(stream, username="sysadmin", password="Li69nux*"):
"""
changes the default password on initial login.
Args:
stream(stream): stream to cont0
"""
LOG.info('Changing password to Li69nux*')
serial.send_bytes(stream, username, expect_prompt=False)
serial.expect_bytes(stream, "Password:")
serial.send_bytes(stream, username, expect_prompt=False)
serial.expect_bytes(stream, "Current password:")
serial.send_bytes(stream, username, expect_prompt=False)
serial.expect_bytes(stream, "New password:")
serial.send_bytes(stream, password, expect_prompt=False)
serial.expect_bytes(stream, "Retype new password")
serial.send_bytes(stream, password)
def login(stream, timeout=600, username="sysadmin", password="Li69nux*"):
"""
Logs into controller-0.
Args:
stream(stream): stream to cont0
timeout(int): Time before login fails in seconds.
"""
serial.send_bytes(stream, "\n", expect_prompt=False)
rc = serial.expect_bytes(stream, "ogin:", fail_ok=True, timeout=timeout)
if rc != 0:
serial.send_bytes(stream, "\n", expect_prompt=False)
if serial.expect_bytes(stream, "~$", timeout=10, fail_ok=True) == -1:
serial.send_bytes(stream, '\n', expect_prompt=False)
serial.expect_bytes(stream, "keystone", timeout=10)
else:
serial.send_bytes(stream, username, expect_prompt=False)
serial.expect_bytes(stream, "assword:")
serial.send_bytes(stream, password)
disable_logout(stream)
def logout(stream):
"""
Logs out of controller-0.
Args:
stream(stream): stream to cont0
"""
serial.send_bytes(stream, "exit", expect_prompt=False)
time.sleep(5)
def check_password(stream, password="Li69nux*"):
ret = serial.expect_bytes(stream, 'assword', fail_ok=True, timeout=5)
if ret == 0:
serial.send_bytes(stream, password, expect_prompt=False)

View File

@ -1,54 +0,0 @@
#!/usr/bin/python3
#
# SPDX-License-Identifier: Apache-2.0
#
"""
Contains helper functions that will configure basic system settings.
"""
from consts.timeout import HostTimeout
from helper import host_helper
from utils import serial
from utils.install_log import LOG
def update_platform_cpus(stream, hostname, cpu_num=5):
"""
Update platform CPU allocation.
"""
LOG.info("Allocating %s CPUs for use by the %s platform.", cpu_num, hostname)
serial.send_bytes(stream, "\nsource /etc/platform/openrc; system host-cpu-modify "
"{} -f platform -p0 {}".format(hostname, cpu_num,
prompt='keystone', timeout=300))
def set_dns(stream, dns_ip):
"""
Perform DNS configuration on the system.
"""
LOG.info("Configuring DNS to %s.", dns_ip)
serial.send_bytes(stream, "source /etc/platform/openrc; system dns-modify "
"nameservers={}".format(dns_ip), prompt='keystone')
def config_controller(stream, config_file=None, password='Li69nux*'):
"""
Configure controller-0 using optional arguments
"""
args = ''
if config_file:
args += '--config-file ' + config_file + ' '
# serial.send_bytes(stream, f'sudo config_controller {args}', expect_prompt=False)
serial.send_bytes(stream, 'ansible-playbook /usr/share/ansible/stx-ansible/playbooks/bootstrap.yml', expect_prompt=False)
host_helper.check_password(stream, password=password)
ret = serial.expect_bytes(stream, "~$",
timeout=HostTimeout.LAB_CONFIG)
if ret != 0:
LOG.info("Configuration failed. Exiting installer.")
raise Exception("Configcontroller failed")

View File

@ -1,490 +0,0 @@
#!/usr/bin/python3
#
# SPDX-License-Identifier: Apache-2.0
#
import os
import subprocess
import re
import getpass
import time
from sys import platform
from consts import env
from utils.install_log import LOG
def vboxmanage_version():
"""
Return version of vbox.
"""
version = subprocess.check_output(['vboxmanage', '--version'], stderr=subprocess.STDOUT)
return version
def vboxmanage_extpack(action="install"):
"""
This allows you to install, uninstall the vbox extensions"
"""
output = vboxmanage_version()
version = re.match(b'(.*)r', output)
version_path = version.group(1).decode('utf-8')
LOG.info("Downloading extension pack")
filename = 'Oracle_VM_VirtualBox_Extension_Pack-{}.vbox-extpack'.format(version_path)
cmd = 'http://download.virtualbox.org/virtualbox/{}/{}'.format(version_path, filename)
result = subprocess.check_output(['wget', cmd, '-P', '/tmp'], stderr=subprocess.STDOUT)
LOG.info(result)
LOG.info("Installing extension pack")
result = subprocess.check_output(['vboxmanage', 'extpack', 'install', '/tmp/' + filename,
'--replace'], stderr=subprocess.STDOUT)
LOG.info(result)
def get_all_vms(labname, option="vms"):
initial_node_list = []
vm_list = vboxmanage_list(option)
labname.encode('utf-8')
# Reduce the number of VMs we query
for item in vm_list:
if labname.encode('utf-8') in item and (b'controller-' in item or \
b'compute-' in item or b'storage-' in item):
initial_node_list.append(item.decode('utf-8'))
# Filter by group
node_list = []
group = bytearray('"/{}"'.format(labname), 'utf-8')
for item in initial_node_list:
info = vboxmanage_showinfo(item).splitlines()
for line in info:
try:
k, v = line.split(b'=')
except ValueError:
continue
if k == b'groups' and v == group:
node_list.append(item)
return node_list
def take_snapshot(labname, snapshot_name, socks=None):
vms = get_all_vms(labname, option="vms")
runningvms = get_all_vms(labname, option="runningvms")
LOG.info("#### Taking snapshot %s of lab %s", snapshot_name, labname)
LOG.info("VMs in lab %s: %s", labname, vms)
LOG.info("VMs running in lab %s: %s", labname, runningvms)
hosts = len(vms)
# Pause running VMs to take snapshot
if len(runningvms) > 1:
for node in runningvms:
newpid = os.fork()
if newpid == 0:
vboxmanage_controlvms([node], "pause")
os._exit(0)
for node in vms:
os.waitpid(0, 0)
time.sleep(2)
if hosts != 0:
vboxmanage_takesnapshot(vms, snapshot_name)
# Resume VMs after snapshot was taken
if len(runningvms) > 1:
for node in runningvms:
newpid = os.fork()
if newpid == 0:
vboxmanage_controlvms([node], "resume")
os._exit(0)
for node in runningvms:
os.waitpid(0, 0)
time.sleep(10) # Wait for VM serial port to stabilize, otherwise it may refuse to connect
if runningvms:
new_vms = get_all_vms(labname, option="runningvms")
retry = 0
while retry < 20:
LOG.info("Waiting for VMs to come up running after taking snapshot..."
"Up VMs are %s ", new_vms)
if len(runningvms) < len(new_vms):
time.sleep(1)
new_vms = get_all_vms(labname, option="runningvms")
retry += 1
else:
LOG.info("All VMs %s are up running after taking snapshot...", vms)
break
def restore_snapshot(node_list, name):
LOG.info("Restore snapshot of %s for hosts %s", name, node_list)
if len(node_list) != 0:
vboxmanage_controlvms(node_list, "poweroff")
time.sleep(5)
if len(node_list) != 0:
for host in node_list:
vboxmanage_restoresnapshot(host, name)
time.sleep(5)
for host in node_list:
if "controller-0" not in host:
vboxmanage_startvm(host)
time.sleep(10)
for host in node_list:
if "controller-0" in host:
vboxmanage_startvm(host)
time.sleep(10)
def vboxmanage_list(option="vms"):
"""
This returns a list of vm names.
"""
result = subprocess.check_output(['vboxmanage', 'list', option], stderr=subprocess.STDOUT)
vms_list = []
for item in result.splitlines():
vm_name = re.match(b'"(.*?)"', item)
vms_list.append(vm_name.group(1))
return vms_list
def vboxmanage_showinfo(host):
"""
This returns info about the host
"""
if not isinstance(host, str):
host.decode('utf-8')
result = subprocess.check_output(['vboxmanage', 'showvminfo', host, '--machinereadable'],
stderr=subprocess.STDOUT)
return result
def vboxmanage_createvm(hostname, labname):
"""
This creates a VM with the specified name.
"""
assert hostname, "Hostname is required"
assert labname, "Labname is required"
group = "/" + labname
LOG.info("Creating VM %s", hostname)
result = subprocess.check_output(['vboxmanage', 'createvm', '--name', hostname, '--register',
'--ostype', 'Linux_64', '--groups', group],
stderr=subprocess.STDOUT)
def vboxmanage_deletevms(hosts=None):
"""
Deletes a list of VMs
"""
assert hosts, "A list of hostname(s) is required"
if len(hosts) != 0:
for hostname in hosts:
LOG.info("Deleting VM %s", hostname)
result = subprocess.check_output(['vboxmanage', 'unregistervm', hostname, '--delete'],
stderr=subprocess.STDOUT)
time.sleep(10)
# in case medium is still present after delete
vboxmanage_deletemedium(hostname)
vms_list = vboxmanage_list("vms")
for items in hosts:
assert items not in vms_list, "The following vms are unexpectedly" \
"present {}".format(vms_list)
def vboxmanage_hostonlyifcreate(name="vboxnet0", ip=None, netmask=None):
"""
This creates a hostonly network for systems to communicate.
"""
assert name, "Must provide network name"
assert ip, "Must provide an OAM IP"
assert netmask, "Must provide an OAM Netmask"
LOG.info("Creating Host-only Network")
result = subprocess.check_output(['vboxmanage', 'hostonlyif', 'create'],
stderr=subprocess.STDOUT)
LOG.info("Provisioning %s with IP %s and Netmask %s", name, ip, netmask)
result = subprocess.check_output(['vboxmanage', 'hostonlyif', 'ipconfig', name, '--ip',
ip, '--netmask', netmask], stderr=subprocess.STDOUT)
def vboxmanage_hostonlyifdelete(name="vboxnet0"):
"""
Deletes hostonly network. This is used as a work around for creating too many hostonlyifs.
"""
assert name, "Must provide network name"
LOG.info("Removing Host-only Network")
result = subprocess.check_output(['vboxmanage', 'hostonlyif', 'remove', name],
stderr=subprocess.STDOUT)
def vboxmanage_modifyvm(hostname=None, cpus=None, memory=None, nic=None,
nictype=None, nicpromisc=None, nicnum=None,
intnet=None, hostonlyadapter=None,
natnetwork=None, uartbase=None, uartport=None,
uartmode=None, uartpath=None, nicbootprio2=1, prefix=""):
"""
This modifies a VM with a specified name.
"""
assert hostname, "Hostname is required"
# Add more semantic checks
cmd = ['vboxmanage', 'modifyvm', hostname]
if cpus:
cmd.extend(['--cpus', cpus])
if memory:
cmd.extend(['--memory', memory])
if nic and nictype and nicpromisc and nicnum:
cmd.extend(['--nic{}'.format(nicnum), nic])
cmd.extend(['--nictype{}'.format(nicnum), nictype])
cmd.extend(['--nicpromisc{}'.format(nicnum), nicpromisc])
if intnet:
if prefix:
intnet = "{}-{}".format(prefix, intnet)
else:
intnet = "{}".format(intnet)
cmd.extend(['--intnet{}'.format(nicnum), intnet])
if hostonlyadapter:
cmd.extend(['--hostonlyadapter{}'.format(nicnum), hostonlyadapter])
if natnetwork:
cmd.extend(['--nat-network{}'.format(nicnum), natnetwork])
elif nicnum and nictype == 'nat':
cmd.extend(['--nic{}'.format(nicnum), 'nat'])
if uartbase and uartport and uartmode and uartpath:
cmd.extend(['--uart1'])
cmd.extend(['{}'.format(uartbase)])
cmd.extend(['{}'.format(uartport)])
cmd.extend(['--uartmode1'])
cmd.extend(['{}'.format(uartmode)])
if platform == 'win32' or platform == 'win64':
cmd.extend(['{}'.format(env.PORT)])
env.PORT += 1
else:
if prefix:
prefix = "{}_".format(prefix)
if 'controller-0' in hostname:
cmd.extend(['{}{}{}_serial'.format(uartpath, prefix, hostname)])
else:
cmd.extend(['{}{}{}'.format(uartpath, prefix, hostname)])
if nicbootprio2:
cmd.extend(['--nicbootprio2'])
cmd.extend(['{}'.format(nicbootprio2)])
cmd.extend(['--boot4'])
cmd.extend(['net'])
LOG.info(cmd)
LOG.info("Updating VM %s configuration", hostname)
result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
def vboxmanage_port_forward(hostname, network, local_port, guest_port, guest_ip):
# VBoxManage natnetwork modify --netname natnet1 --port-forward-4
# "ssh:tcp:[]:1022:[192.168.15.5]:22"
rule_name = "{}-{}".format(hostname, guest_port)
# Delete previous entry, if any
LOG.info("Removing previous forwarding rule '%s' from NAT network '%s'", rule_name, network)
cmd = ['vboxmanage', 'natnetwork', 'modify', '--netname', network,
'--port-forward-4', 'delete', rule_name]
try:
result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError:
pass
# Add new rule
rule = "{}:tcp:[]:{}:[{}]:{}".format(rule_name, local_port, guest_ip, guest_port)
LOG.info("Updating port-forwarding rule to: %s", rule)
cmd = ['vboxmanage', 'natnetwork', 'modify', '--netname', network, '--port-forward-4', rule]
result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
def vboxmanage_storagectl(hostname=None, storectl="sata", hostiocache="off"):
"""
This creates a storage controller on the host.
"""
assert hostname, "Hostname is required"
assert storectl, "Type of storage controller is required"
LOG.info("Creating %s storage controller on VM %s", storectl, hostname)
result = subprocess.check_output(['vboxmanage', 'storagectl',
hostname, '--name', storectl,
'--add', storectl, '--hostiocache',
hostiocache], stderr=subprocess.STDOUT)
def vboxmanage_storageattach(hostname=None, storectl="sata",
storetype="hdd", disk=None, port_num="0", device_num="0"):
"""
This attaches a disk to a controller.
"""
assert hostname, "Hostname is required"
assert disk, "Disk name is required"
assert storectl, "Name of storage controller is required"
assert storetype, "Type of storage controller is required"
LOG.info("Attaching %s storage to storage controller %s on VM %s",
storetype, storectl, hostname)
result = subprocess.check_output(['vboxmanage', 'storageattach',
hostname, '--storagectl', storectl,
'--medium', disk, '--type',
storetype, '--port', port_num,
'--device', device_num], stderr=subprocess.STDOUT)
return result
def vboxmanage_deletemedium(hostname, vbox_home_dir='/home'):
assert hostname, "Hostname is required"
if platform == 'win32' or platform == 'win64':
return
username = getpass.getuser()
vbox_home_dir = "{}/{}/vbox_disks/".format(vbox_home_dir, username)
disk_list = [f for f in os.listdir(vbox_home_dir) if
os.path.isfile(os.path.join(vbox_home_dir, f)) and hostname in f]
LOG.info("Disk mediums to delete: %s", disk_list)
for disk in disk_list:
LOG.info("Disconnecting disk %s from vbox.", disk)
try:
result = subprocess.check_output(['vboxmanage', 'closemedium', 'disk',
"{}{}".format(vbox_home_dir, disk), '--delete'],
stderr=subprocess.STDOUT)
LOG.info(result)
except subprocess.CalledProcessError as e:
# Continue if failures, disk may not be present
LOG.info("Error disconnecting disk, continuing. "
"Details: stdout: %s stderr: %s", e.stdout, e.stderr)
LOG.info("Removing backing file %s", disk)
try:
os.remove("{}{}".format(vbox_home_dir, disk))
except:
pass
def vboxmanage_createmedium(hostname=None, disk_list=None, vbox_home_dir='/home'):
"""
This creates the required disks.
"""
assert hostname, "Hostname is required"
assert disk_list, "A list of disk sizes is required"
username = getpass.getuser()
device_num = 0
port_num = 0
disk_count = 1
for disk in disk_list:
if platform == 'win32' or platform == 'win64':
file_name = "C:\\Users\\" + username + "\\vbox_disks\\" + \
hostname + "_disk_{}".format(disk_count)
else:
file_name = vbox_home_dir + '/' + username + "/vbox_disks/" \
+ hostname + "_disk_{}".format(disk_count)
LOG.info("Creating disk %s of size %s on VM %s on device %s port %s",
file_name, disk, hostname, device_num, port_num)
try:
result = subprocess.check_output(['vboxmanage', 'createmedium',
'disk', '--size', str(disk),
'--filename', file_name,
'--format', 'vdi',
'--variant', 'standard'],
stderr=subprocess.STDOUT)
LOG.info(result)
except subprocess.CalledProcessError as e:
LOG.info("Error stdout: %s stderr: %s", e.stdout, e.stderr)
raise
vboxmanage_storageattach(hostname, "sata", "hdd", file_name + \
".vdi", str(port_num), str(device_num))
disk_count += 1
port_num += 1
time.sleep(5)
def vboxmanage_startvm(hostname=None, force=False):
"""
This allows you to power on a VM.
"""
assert hostname, "Hostname is required"
if not force:
LOG.info("Check if VM is running")
running_vms = vboxmanage_list(option="runningvms")
else:
running_vms = []
if hostname.encode('utf-8') in running_vms:
LOG.info("Host %s is already started", hostname)
else:
LOG.info("Powering on VM %s", hostname)
result = subprocess.check_output(['vboxmanage', 'startvm',
hostname], stderr=subprocess.STDOUT)
LOG.info(result)
# Wait for VM to start
tmout = 20
while tmout:
tmout -= 1
running_vms = vboxmanage_list(option="runningvms")
if hostname.encode('utf-8') in running_vms:
break
time.sleep(1)
else:
raise "Failed to start VM: {}".format(hostname)
LOG.info("VM '%s' started.", hostname)
def vboxmanage_controlvms(hosts=None, action=None):
"""
This allows you to control a VM, e.g. pause, resume, etc.
"""
assert hosts, "Hostname is required"
assert action, "Need to provide an action to execute"
for host in hosts:
LOG.info("Executing %s action on VM %s", action, host)
result = subprocess.call(["vboxmanage", "controlvm", host,
action], stderr=subprocess.STDOUT)
time.sleep(1)
def vboxmanage_takesnapshot(hosts=None, name=None):
"""
This allows you to take snapshot of VMs.
"""
assert hosts, "Hostname is required"
assert name, "Need to provide a name for the snapshot"
for host in hosts:
LOG.info("Taking snapshot %s on VM %s", name, host)
result = subprocess.call(["vboxmanage", "snapshot", host, "take",
name], stderr=subprocess.STDOUT)
def vboxmanage_restoresnapshot(host=None, name=None):
"""
This allows you to restore snapshot of a VM.
"""
assert host, "Hostname is required"
assert name, "Need to provide the snapshot to restore"
LOG.info("Restoring snapshot %s on VM %s", name, host)
result = subprocess.call(["vboxmanage", "snapshot", host, "restore",
name], stderr=subprocess.STDOUT)
time.sleep(10)

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +0,0 @@
configparser
paramiko
pytest
git+https://github.com/digidotcom/python-streamexpect#egg=streamexpect
pexpect

View File

@ -1,52 +0,0 @@
#!/usr/bin/python3
#
# SPDX-License-Identifier: Apache-2.0
#
import os
import datetime
import logging
from consts.env import LOGPATH
log_dir = ""
LOG = logging.getLogger()
def init_logging(lab_name, log_path=None):
global LOG, log_dir
if not log_path:
log_path = LOGPATH
lab_log_path = log_path + "/" + lab_name
# Setup log sub-directory for current run
current_time = datetime.datetime.now()
log_dir = "{}/{}_{}_{}_{}_{}_{}".format(lab_log_path,
current_time.year,
current_time.month,
current_time.day,
current_time.hour,
current_time.minute,
current_time.second)
if not os.path.exists(log_dir):
os.makedirs(log_dir)
LOG.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s: %(message)s")
log_file = "{}/install.log".format(log_dir)
handler = logging.FileHandler(log_file)
handler.setFormatter(formatter)
handler.setLevel(logging.INFO)
LOG.addHandler(handler)
handler = logging.StreamHandler()
handler.setFormatter(formatter)
LOG.addHandler(handler)
# Create symbolic link to latest logs of this lab
try:
os.unlink(lab_log_path + "/latest")
except:
pass
os.symlink(log_dir, lab_log_path + "/latest")
def get_log_dir():
return log_dir

View File

@ -1,68 +0,0 @@
#!/usr/bin/python3
#
# SPDX-License-Identifier: Apache-2.0
#
import time
from utils.install_log import LOG
STAGES = []
METRICS = {}
start = 0
def init_kpi_metrics():
global start
start = time.time()
def get_formated_time(sec):
hours = sec // 3600
sec %= 3600
minutes = sec // 60
sec %= 60
seconds = sec
if hours:
return "{:.0f}h {:.0f}m {:.2f}s".format(hours, minutes, seconds)
elif minutes:
return "{:.0f}m {:.2f}s".format(minutes, seconds)
elif seconds:
return "{:.2f}s".format(seconds)
def set_kpi_metric(metric, duration):
global METRICS, STAGES
METRICS[metric] = duration
STAGES.append(metric)
def print_kpi(metric):
if metric in STAGES:
sec = METRICS[metric]
LOG.info(" Time in stage '%s': %s ", metric, get_formated_time(sec))
elif metric == 'total' and start:
duration = time.time() - start
LOG.info(" Total time: %s", get_formated_time(duration))
def get_kpi_str(metric):
msg = ""
if metric in STAGES:
sec = METRICS[metric]
msg += (" Time in stage '{}': {} \n".format(metric, get_formated_time(sec)))
elif metric == 'total' and start:
duration = time.time() - start
msg += (" Total time: {}\n".format(get_formated_time(duration)))
return msg
def get_kpi_metrics_str():
msg = "===================== Metrics ====================\n"
for stage in STAGES:
msg += get_kpi_str(stage)
msg += get_kpi_str('total')
msg += "===============================================\n"
return msg
def print_kpi_metrics():
LOG.info("===================== Metrics ====================")
for stage in STAGES:
print_kpi(stage)
print_kpi('total')
LOG.info("==================================================")

View File

@ -1,220 +0,0 @@
#!/usr/bin/python3
#
# SPDX-License-Identifier: Apache-2.0
#
import re
import socket
from sys import platform, stdout
import time
import streamexpect
from utils.install_log import LOG
def connect(hostname, port=10000, prefix=""):
"""
Connect to local domain socket and return the socket object.
Arguments:
- Requires the hostname of target, e.g. controller-0
- Requires TCP port if using Windows
"""
if prefix:
prefix = "{}_".format(prefix)
socketname = "/tmp/{}{}".format(prefix, hostname)
if 'controller-0'in hostname:
socketname += '_serial'
LOG.info("Connecting to %s at %s", hostname, socketname)
if platform == 'win32' or platform == 'win64':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
else:
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
if platform == 'win32' or platform == 'win64':
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
sock.connect(('localhost', port))
else:
sock.connect(socketname)
except:
LOG.info("Connection failed")
pass
# disconnect(sock)
sock = None
# TODO (WEI): double check this
sock.setblocking(0)
return sock
def disconnect(sock):
"""
Disconnect a local doamin socket.
Arguments:
- Requires socket
"""
# Shutdown connection and release resources
LOG.info("Disconnecting from socket")
sock.shutdown(socket.SHUT_RDWR)
sock.close()
def get_output(stream, cmd, prompts=None, timeout=5, log=True, as_lines=True, flush=True):
#TODO: Not testested, will not work if kernel or other processes throw data on stdout or stderr
"""
Execute a command and get its output. Make sure no other command is executing.
And 'dmesg -D' was executed.
"""
POLL_PERIOD = 0.1
MAX_READ_BUFFER = 1024
data = ""
line_buf = ""
lines = []
if not prompts:
prompts = [':~$ ', ':~# ', ':/home/wrsroot# ', '(keystone_.*)]$ ', '(keystone_.*)]# ']
# Flush buffers
if flush:
try:
trash = stream.poll(1) # flush input buffers
if trash:
try:
LOG.info("Buffer has bytes before cmd execution: %s",
trash.decode('utf-8'))
except Exception:
pass
except streamexpect.ExpectTimeout:
pass
# Send command
stream.sendall("{}\n".format(cmd).encode('utf-8'))
# Get response
patterns = []
for prompt in prompts:
patterns.append(re.compile(prompt))
now = time.time()
end_time = now + float(timeout)
prev_timeout = stream.gettimeout()
stream.settimeout(POLL_PERIOD)
incoming = None
try:
while (end_time - now) >= 0:
try:
incoming = stream.recv(MAX_READ_BUFFER)
except socket.timeout:
pass
if incoming:
data += incoming
if log:
for c in incoming:
if c != '\n':
line_buf += c
else:
LOG.info(line_buf)
lines.append(line_buf)
line_buf = ""
for pattern in patterns:
if pattern.search(data):
if as_lines:
return lines
else:
return data
now = time.time()
raise streamexpect.ExpectTimeout()
finally:
stream.settimeout(prev_timeout)
def expect_bytes(stream, text, timeout=180, fail_ok=False, flush=True):
"""
Wait for user specified text from stream.
"""
time.sleep(1)
if timeout < 60:
LOG.info("Expecting text within %s seconds: %s\n", timeout, text)
else:
LOG.info("Expecting text within %s minutes: %s\n", timeout/60, text)
try:
stream.expect_bytes("{}".format(text).encode('utf-8'), timeout=timeout)
except streamexpect.ExpectTimeout:
if fail_ok:
return -1
else:
stdout.write('\n')
LOG.error("Did not find expected text")
# disconnect(stream)
raise
except Exception as e:
LOG.info("Connection failed with %s", e)
raise
stdout.write('\n')
LOG.info("Found expected text: %s", text)
time.sleep(1)
if flush:
try:
incoming = stream.poll(1) # flush input buffers
if incoming:
incoming += b'\n'
try:
LOG.info(">>> expect_bytes: Buffer has bytes!")
stdout.write(incoming.decode('utf-8')) # streamexpect hardcodes it
except Exception:
pass
except streamexpect.ExpectTimeout:
pass
return 0
def send_bytes(stream, text, fail_ok=False, expect_prompt=True,
prompt=None, timeout=180, send=True, flush=True):
"""
Send user specified text to stream.
"""
time.sleep(1)
if flush:
try:
incoming = stream.poll(1) # flush input buffers
if incoming:
incoming += b'\n'
try:
LOG.info(">>> send_bytes: Buffer has bytes!")
stdout.write(incoming.decode('utf-8')) # streamexpect hardcodes it
except Exception:
pass
except streamexpect.ExpectTimeout:
pass
LOG.info("Sending text: %s", text)
try:
if send:
stream.sendall("{}\n".format(text).encode('utf-8'))
else:
stream.sendall("{}".format(text).encode('utf-8'))
if expect_prompt:
time.sleep(1)
if prompt:
return expect_bytes(stream, prompt, timeout=timeout, fail_ok=fail_ok)
else:
rc = expect_bytes(stream, "~$", timeout=timeout, fail_ok=True)
if rc != 0:
send_bytes(stream, '\n', expect_prompt=False)
expect_bytes(stream, 'keystone', timeout=timeout)
return
except streamexpect.ExpectTimeout:
if fail_ok:
return -1
else:
LOG.error("Failed to send text, logging out.")
stream.sendall("exit".encode('utf-8'))
raise
except Exception as e:
LOG.info("Connection failed with %s.", e)
raise
return 0

View File

@ -1,116 +0,0 @@
#!/usr/bin/python3
#
# SPDX-License-Identifier: Apache-2.0
#
import getpass
import os
import time
import subprocess
import paramiko
from utils.install_log import LOG
def sftp_send(source, remote_host, remote_port, destination, username, password):
"""
Send files to remote server
"""
LOG.info("Connecting to server %s with username %s", remote_host, username)
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
## TODO(WEI): need to make this timeout handling better
retry = 0
while retry < 8:
try:
ssh_client.connect(remote_host, port=remote_port,
username=username, password=password,
look_for_keys=False, allow_agent=False)
sftp_client = ssh_client.open_sftp()
retry = 8
except Exception as e:
LOG.info("******* try again")
retry += 1
time.sleep(10)
LOG.info("Sending file from %s to %s", source, destination)
sftp_client.put(source, destination)
LOG.info("Done")
sftp_client.close()
ssh_client.close()
def send_dir(source, remote_host, remote_port, destination, username,
password, follow_links=True, clear_known_hosts=True):
# Only works from linux for now
if not source.endswith('/') or not source.endswith('\\'):
source = source + '/'
follow_links = "L" if follow_links else ""
if clear_known_hosts:
if remote_host == '127.0.0.1':
keygen_arg = "[127.0.0.1]:{}".format(remote_port)
else:
keygen_arg = remote_host
cmd = f'ssh-keygen -f "/home/{getpass.getuser()}/.ssh/known_hosts" -R {keygen_arg}'
LOG.info("CMD: %s", cmd)
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
for line in iter(process.stdout.readline, b''):
LOG.info("%s", line.decode("utf-8").strip())
process.wait()
LOG.info(f'Running rsync of dir: {source} -> {username}@{remote_host}'
f':{destination}')
cmd = (f'rsync -av{follow_links} --rsh="/usr/bin/sshpass -p {password} '
f'ssh -p {remote_port} -o StrictHostKeyChecking=no -l {username}" '
f'{source}* {username}@{remote_host}:{destination}')
LOG.info("CMD: %s", cmd)
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
for line in iter(process.stdout.readline, b''):
LOG.info("%s", line.decode("utf-8").strip())
process.wait()
if process.returncode:
raise Exception(f'Error in rsync, return code: {process.returncode}')
def send_dir_fallback(source, remote_host, destination, username, password):
"""
Send directory contents to remote server, usually controller-0
Note: does not send nested directories only files.
args:
- source: full path to directory
e.g. /localhost/loadbuild/jenkins/latest_build/
- Remote host: name of host to log into, controller-0 by default
e.g. myhost.com
- destination: where to store the file on host: /home/myuser/
"""
LOG.info("Connecting to server %s with username %s", remote_host, username)
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(remote_host, username=username, password=password, look_for_keys=False, allow_agent=False)
sftp_client = ssh_client.open_sftp()
path = ''
send_img = False
for items in os.listdir(source):
path = source+items
if os.path.isfile(path):
if items.endswith('.img'):
remote_path = destination+'images/'+items
LOG.info("Sending file from %s to %s", path, remote_path)
sftp_client.put(path, remote_path)
send_img = True
elif items.endswith('.iso'):
pass
else:
remote_path = destination+items
LOG.info("Sending file from %s to %s", path, remote_path)
sftp_client.put(path, remote_path)
LOG.info("Done")
sftp_client.close()
ssh_client.close()
if send_img:
time.sleep(10)

View File

@ -1,127 +0,0 @@
#!/bin/bash
#
# SPDX-License-Identifier: Apache-2.0
#
GROUP=$1
ACTION=$2
SNAP_NAME=$3
if [ $# -lt 2 ]; then
echo "Usage: $0 <group_name> <action> [<snap_name>]"
echo "Available cmds:"
echo " Instance actions: pause|resume|poweroff|poweron"
echo " Snapshot actions: take|delete|restore"
echo ""
echo "###### Available groups: "
groups=$(vboxmanage list groups)
for grp in $groups; do
grp_txt=${grp:2:-1}
if [ ! -z "$grp_txt" ]; then
echo "$grp_txt"
fi
done
exit 0
fi
echo "###### Params:"
echo "Group name: $GROUP"
echo "Action: $ACTION"
if [ ! -z "$SNAP_NAME" ]; then
echo "Snapshot name: $SNAP_NAME"
fi
BASIC_INST_ACTIONS="pause poweroff"
SNAP_ACTIONS="take delete restore"
get_vms_by_group () {
local group=$1
vms=$(VBoxManage list -l vms |
awk -v group="/$group" \
'/^Name:/ { name = $2; } '`
'/^Groups:/ { groups = $2; } '`
'/^UUID:/ { uuid = $2; if (groups == group) print name, uuid; }')
echo "###### VMs in group:" >&2
echo "$vms" >&2
echo "$vms"
}
if [[ "$SNAP_ACTIONS" = *"$ACTION"* ]]; then
if [ $# -lt 3 ]; then
echo "###### ERROR:"
echo "Action '$ACTION' requires a snapshot name."
fi
vms=$(get_vms_by_group "$GROUP")
echo "#### Executing action on vms"
while read -r vm; do
vm=(${vm})
echo "Executing '$ACTION' on ${vm[0]}..."
VBoxManage snapshot ${vm[1]} "${ACTION}" "${SNAP_NAME}"
done <<< "$vms"
elif [[ "$BASIC_INST_ACTIONS" = *"$ACTION"* ]]; then
vms=$(get_vms_by_group "$GROUP")
echo "#### Executing action on vms"
while read -r vm; do
vm=(${vm})
echo "Executing '$ACTION' on '${vm[0]}'..."
VBoxManage controlvm ${vm[1]} "${ACTION}"
done <<< "$vms"
wait
elif [[ "$ACTION" = "resume" ]]; then
echo "resume"
vms=$(get_vms_by_group "$GROUP")
# Getting vm's in saved state
saved_vms=""
while read -r vm; do
vmA=(${vm})
state=$(vboxmanage showvminfo ${vmA[1]} --machinereadable |
grep "VMState=")
if [[ "$state" = *"saved"* ]]; then
if [ -z "$saved_vms" ]; then
saved_vms="$vm"
else
saved_vms=$(printf '%s\n%s' "$saved_vms" "$vm")
fi
fi
done <<< "$vms"
echo "#### VMs in saved state:"
echo "$saved_vms"
# Powering on each VM
echo "#### Preparing vms for start"
if [ ! -z "$saved_vms" ]; then
while read -r vm; do
vm=(${vm})
echo "Powering on VM \"${vm[1]}\"."
(VBoxHeadless --start-paused --startvm ${vm[1]} \
--vrde config >/dev/null 2>&1) &
sleep 1
while true; do
state=$(vboxmanage showvminfo ${vm[1]} --machinereadable |
grep "VMState=")
if [[ "$state" = *"paused"* ]]; then
break
fi
done
done <<< "$saved_vms"
fi
elif [[ "$ACTION" = "poweron" ]]; then
vms=$(get_vms_by_group "$GROUP")
echo "#### Powering on vms"
while read -r vm; do
vm=(${vm})
(vboxmanage startvm ${vm[1]} --type headless) &
done <<< "$vms"
wait
elif [[ "$ACTION" = "poweroff" ]]; then
echo "poweroff"
else
echo "###### ERROR:"
echo "ERROR: Action '$ACTION' not supported"
fi

View File

@ -1,3 +0,0 @@
#!/usr/bin/env bash
socat UNIX-CONNECT:"/tmp/serial_$1" stdio,raw,echo=0,icanon=0

View File

@ -1,158 +0,0 @@
#!/usr/bin/env bash
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
CONFFILE="${1:-standard_controller.conf}"
source $SCRIPTPATH/$CONFFILE
VM_PREFIX_NAME="${VM_PREFIX_NAME:-default-}"
CONTROLLER_CPUS="${TIC_CONTROLLER_CPUS:-4}"
CONTROLLER_MEM="${TIC_CONTROLLER_MEM:-8192}"
CONTROLLER_DISK1="${TIC_CONTROLLER_DISK1:-81920}"
CONTROLLER_DISK2="${TIC_CONTROLLER_DISK2:-10240}"
CONTROLLER_DISK3="${TIC_CONTROLLER_DISK3:-4096}"
ISO="${TIC_INSTALL_ISO:-$SCRIPTPATH/bootimage.iso}"
HOSTADD_SCRIPT="$SCRIPTPATH/add_host.sh"
declare -a CREATED_VMS
machine_folder=`VBoxManage list systemproperties | grep "Default machine folder:" | cut -d : -f 2 | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'`
# VRDE port for 1st VM
vrdeport="${TIC_VDEPORT_START:-13389}"
function set_vrde {
vm=$1
VBoxManage modifyvm "$vm" --vrde on --vrdeaddress 127.0.0.1 --vrdeport $vrdeport
let vrdeport=vrdeport+1
}
function my_error {
echo "Error: $1"
my_trap_clean
exit 1
}
function my_trap_clean {
echo "deleting created VMS ${CREATED_VMS[@]}..."
for vm in ${CREATED_VMS[@]}; do
VBoxManage unregistervm "$vm" --delete
done
}
function init_hostonly_net {
# Create hostonly networks
VBoxManage list hostonlyifs | grep vboxnet0 && vboxnet="1"
if [ "x$vboxnet" != "x" ]; then
VBoxManage list hostonlyifs
read -r -p "Hostonly network vboxnet0 already existed. Are you sure to reconfigure it? [y/N] " response
case $response in
[yY][eE][sS]|[yY])
echo
;;
*)
my_error "Please make sure it's safe before you remove hostonly network vboxnet0!"
;;
esac
else
VBoxManage hostonlyif create
fi
VBoxManage hostonlyif ipconfig vboxnet0 --ip 10.10.10.1 --netmask 255.255.255.0
}
function createvm {
vm=$1
cpus=$2
mem=$3
echo "creating VM ${vm}..."
# Find if VM already existing
VBoxManage showvminfo "$vm" &>/dev/null && my_error "VM $vm already existed. Please delete it first"
CREATED_VMS+=("$vm")
# Create VM
VBoxManage createvm --name "$vm" --register
# Configure controller VM
# CPU
VBoxManage modifyvm "$vm" --ostype Linux_64 --cpus "$cpus" --pae on --longmode on --x2apic on --largepages off
# Memory
VBoxManage modifyvm "$vm" --memory "$mem"
# Network
VBoxManage modifyvm "$vm" --cableconnected1 on --nic1 hostonly --nictype1 82540EM --hostonlyadapter1 vboxnet0
VBoxManage modifyvm "$vm" --cableconnected2 on --nic2 intnet --nictype2 82540EM --intnet2 intnet-management-$(whoami) --nicpromisc2 allow-all --nicbootprio2 1
VBoxManage modifyvm "$vm" --cableconnected3 on --nic3 intnet --nictype3 virtio --intnet3 intnet-data1-$(whoami) --nicpromisc3 allow-all
VBoxManage modifyvm "$vm" --cableconnected4 on --nic4 intnet --nictype4 virtio --intnet4 intnet-data2-$(whoami) --nicpromisc4 allow-all
# Storage Medium
VBoxManage createmedium disk --filename "${machine_folder}/${vm}/${vm}-disk1.vdi" --size $CONTROLLER_DISK1 --format VDI
VBoxManage createmedium disk --filename "${machine_folder}/${vm}/${vm}-disk2.vdi" --size $CONTROLLER_DISK2 --format VDI
VBoxManage createmedium disk --filename "${machine_folder}/${vm}/${vm}-disk3.vdi" --size $CONTROLLER_DISK3 --format VDI
VBoxManage storagectl "$vm" --name SATA --add sata --controller IntelAhci --portcount 4 --hostiocache on --bootable on
VBoxManage storageattach "$vm" --storagectl SATA --port 0 --device 0 --type hdd --medium "${machine_folder}/${vm}/${vm}-disk1.vdi"
VBoxManage storageattach "$vm" --storagectl SATA --port 1 --device 0 --type hdd --medium "${machine_folder}/${vm}/${vm}-disk2.vdi"
VBoxManage storageattach "$vm" --storagectl SATA --port 2 --device 0 --type hdd --medium "${machine_folder}/${vm}/${vm}-disk3.vdi"
VBoxManage storageattach "$vm" --storagectl SATA --port 3 --device 0 --type dvddrive --medium emptydrive
# Display
VBoxManage modifyvm "$vm" --vram 16
# Audio
VBoxManage modifyvm "$vm" --audio none
# Boot Order
VBoxManage modifyvm "$vm" --boot1 dvd --boot2 disk --boot3 net --boot4 none
# Other
VBoxManage modifyvm "$vm" --ioapic on --rtcuseutc on
# VM sepcific
# Serial
VBoxManage modifyvm "$vm" --uart1 0x3F8 4 --uartmode1 server "/tmp/serial_$vm"
set_vrde "$vm"
}
function clonevm {
src=$1
target=$2
echo "creating VM ${target} from ${src}..."
# Find if vm already existing
VBoxManage showvminfo "$target" &>/dev/null && my_error "VM $target already existed. Please delete it first"
VBoxManage clonevm "$src" --mode machine --name "$target" --register
CREATED_VMS+=("$target")
# Serial
VBoxManage modifyvm "$target" --uart1 0x3F8 4 --uartmode1 server "/tmp/serial_$target"
set_vrde "$target"
}
trap my_trap_clean SIGINT SIGTERM
set -e
[[ -f $ISO ]] || my_error "Can not fild install image $ISO"
# Init hostonly network
init_hostonly_net
# Create host_add.sh for Compute and Controller node
rm -f "$HOSTADD_SCRIPT"
cat <<EOF > "$HOSTADD_SCRIPT"
#!/usr/bin/env bash
source /etc/platform/openrc
EOF
chmod +x "$HOSTADD_SCRIPT"
# Create Contoller VM, at least controller0
createvm "${VM_PREFIX_NAME}controller-0" $CONTROLLER_CPUS $CONTROLLER_MEM
COUNTER=1
while [ $COUNTER -lt $TIC_CONTROLLER_NUM ]; do
clonevm ${VM_PREFIX_NAME}controller-0 "${VM_PREFIX_NAME}controller-$COUNTER"
mac=`VBoxManage showvminfo "${VM_PREFIX_NAME}controller-$COUNTER" | grep intnet-management | grep -o "MAC: [0-9a-fA-F]*" | awk '{ print $2 }' | sed 's/../&:/g;s/:$//'`
echo "system host-add -n ${VM_PREFIX_NAME}controller-$COUNTER -p controller -m $mac" >> "$HOSTADD_SCRIPT"
let COUNTER=COUNTER+1
done
# Create Compute VM
COUNTER=0
while [ $COUNTER -lt $TIC_COMPUTE_NUM ]; do
clonevm ${VM_PREFIX_NAME}controller-0 "${VM_PREFIX_NAME}compute-$COUNTER"
mac=`VBoxManage showvminfo "${VM_PREFIX_NAME}compute-$COUNTER" | grep intnet-management | grep -o "MAC: [0-9a-fA-F]*" | awk '{ print $2 }' | sed 's/../&:/g;s/:$//'`
echo "system host-add -n ${VM_PREFIX_NAME}compute-$COUNTER -p compute -m $mac" >> "$HOSTADD_SCRIPT"
let COUNTER=COUNTER+1
done
# Start Controller-0 with bootiso.img
VBoxManage storageattach ${VM_PREFIX_NAME}controller-0 --storagectl SATA --port 3 --device 0 --type dvddrive --medium "$ISO"
$SCRIPTPATH/start_vm.sh ${VM_PREFIX_NAME}controller-0

View File

@ -1,20 +0,0 @@
# Number of Controller nodes
TIC_CONTROLLER_NUM=1
# Number of Compute nodes
TIC_COMPUTE_NUM=1
# vCPU
TIC_CONTROLLER_CPUS="4"
# Memory size, in MB
TIC_CONTROLLER_MEM="8192"
# Disk1 size, in 1 MB units
TIC_CONTROLLER_DISK1="81920"
# Disk2 size, in 1 MB units
TIC_CONTROLLER_DISK2="10240"
# First port for VRDE
# This is for a Virtualbox Remote Display Port
# https://www.virtualbox.org/manual/ch07.html#vrde
TIC_VDEPORT_START=13389
# Install image
TIC_INSTALL_ISO="$PWD/bootimage.iso"

View File

@ -1,19 +0,0 @@
#!/usr/bin/env bash
rdeport=`VBoxManage showvminfo $1 | grep "^VRDE:" | grep -o "Ports [0-9]*" | cut -d ' ' -f 2`
if [ "x$rdeport" == "x" ]; then
echo "Vm $1 not found or not configured to use rde".
exit 1
fi
VBoxManage startvm "$1" --type headless
sleep 3
echo rdesktop-vrdp -a 16 -N "127.0.0.1:$rdeport"
if xdpyinfo 2>&1 >> /dev/null; then
rdesktop-vrdp -a 16 -N "127.0.0.1:$rdeport" &
else
echo "Running without X display. Use a tunnel from your laptop"
echo "ssh -L $rdeport:127.0.0.1:$rdeport -N -f -l <uname> madbuild01.ostc.intel.com"
echo "Then run rdesktop-vrdp -a 16 -N 127.0.0.1:$rdeport from your laptop"
fi

View File

@ -1,5 +0,0 @@
#!/usr/bin/env bash
VBoxManage controlvm "$1" poweroff