[robot] Add configs and environment setup
Enable different configurations and setup requirements for deployment environments as well as pip requirements. - Config : Serie of configuration files to be used on deployment as well as exposed to the framework in order to use the values on the test cases. - Qemu : All artifacts needed to deploy the virtual machines that simulate the nodes on libvirt/qemu - Baremetal : Series of configuration files used to setup a deployment on a baremetal environment - requirements.txt, test-requirements.txt : series of packages needed by the suite to work on a python virtualenv. Depends-On: I796dcaf71089424dd37a050691fd0ee003ad3176 Change-Id: I34dfe1c01b27e5e8ce046de3305dd78c7f9d1383 Signed-off-by: Jose Perez Carranza <jose.perez.carranza@intel.com>
This commit is contained in:
parent
2d3d047a8c
commit
4ee20f9e40
|
@ -0,0 +1,54 @@
|
||||||
|
[general]
|
||||||
|
LOG_PATH = /tmp/logs
|
||||||
|
IP_UNIT_0_ADDRESS = 10.10.10.3
|
||||||
|
IP_UNIT_1_ADDRESS = 10.10.10.4
|
||||||
|
CIRROS_FILE = cirros-0.4.0-x86_64-disk.qcow2
|
||||||
|
CENTOS_FILE = CentOS-7-x86_64-GenericCloud.qcow2
|
||||||
|
UBUNTU_FILE = xenial-server-cloudimg-amd64-disk1.qcow2
|
||||||
|
WINDOWS_FILE = windows_server_2012_r2.qcow2
|
||||||
|
APP_TARBALL = stx-openstack.tgz
|
||||||
|
STX_ISO_FILE = bootimage.iso
|
||||||
|
ENV_YAML_FILE = Qemu/qemu_setup.yaml
|
||||||
|
CONFIGURATION_TYPE = simplex
|
||||||
|
ENVIRONMENT = virtual
|
||||||
|
CONFIGURATION_FILE = stx-simplex.yml
|
||||||
|
|
||||||
|
[credentials]
|
||||||
|
STX_DEPLOY_USER_NAME = sysadmin
|
||||||
|
STX_DEPLOY_USER_PSWD = St4rlingX*
|
||||||
|
|
||||||
|
[iso_installer]
|
||||||
|
KERNEL_OPTION = 0
|
||||||
|
VIRSH_CMD = virsh -c qemu:///system console controller-0
|
||||||
|
VMLINUZ = vmlinuz append rootwait
|
||||||
|
CONSOLES = console=tty0,115200 console=ttyS0,115200 inst.text
|
||||||
|
SERIAL = serial
|
||||||
|
OPTS_1 = inst.stage2=hd:LABEL=oe_iso_boot user_namespace.enable=1
|
||||||
|
SYS_TYPE_1 = inst.ks=hd:LABEL=oe_iso_boot:/ks.cfg
|
||||||
|
SYS_TYPE_2 = inst.ks=hd:LABEL=oe_iso_boot:/smallsystem_ks.cfg
|
||||||
|
SYS_TYPE_3 = inst.ks=hd:LABEL=oe_iso_boot:/smallsystem_lowlatency_ks.cfg
|
||||||
|
OPTS_2 = boot_device=sda rootfs_device=sda biosdevname=0 usbcore.autosuspend=-1 inst.gpt
|
||||||
|
SEC_PROF_1 = security_profile=standard
|
||||||
|
SEC_PROF_2 = security_profile=extended
|
||||||
|
INITRD = initrd=initrd.img
|
||||||
|
BOOT_TIMEOUT = 1200
|
||||||
|
CONFIG_CONTROLLER_TIMEOUT = 3600
|
||||||
|
CONTROLLER_TMP_IP = 10.10.10.3
|
||||||
|
CONTROLLER_TMP_GATEWAY = 10.10.10.1
|
||||||
|
|
||||||
|
[logical_interface]
|
||||||
|
OAM = enp2s1
|
||||||
|
MGMT = enp2s2
|
||||||
|
|
||||||
|
[baremetal]
|
||||||
|
HTTP_SERVER = 192.168.200.3
|
||||||
|
|
||||||
|
[dashboard]
|
||||||
|
HORIZON_USERNAME = admin
|
||||||
|
HORIZON_PASSWORD = St4rlingX*
|
||||||
|
BROWSER = firefox
|
||||||
|
PROFILE = nk0f1p65.automation
|
||||||
|
|
||||||
|
[qemu]
|
||||||
|
XML = /etc/libvirt/qemu/networks/autostart/default.xml
|
||||||
|
CONFIG_FILE = /etc/libvirt/qemu.conf
|
|
@ -0,0 +1,144 @@
|
||||||
|
"""Config file parser and config file generator.
|
||||||
|
|
||||||
|
Configuration values will be read from a file called <CONFIG_FILE>.
|
||||||
|
A config file with default values can be generated by running this module as a
|
||||||
|
script and using the --generate option.
|
||||||
|
|
||||||
|
The config file is a standard INI file that contains [sections] and options.
|
||||||
|
|
||||||
|
Variables that are between %(option)s are interpolated automatically by the
|
||||||
|
ConfigParser (with the caveat that they have to be in the same section).
|
||||||
|
Variables that are between ${section:option} will be interpolated with the
|
||||||
|
value from the appropriate section (similar to the way ConfigParse from
|
||||||
|
Python3 works).
|
||||||
|
|
||||||
|
Example of a config file:
|
||||||
|
|
||||||
|
E.g.
|
||||||
|
|
||||||
|
[Section1]
|
||||||
|
key_1 = value 1
|
||||||
|
key_2 = value 2
|
||||||
|
country = mexico
|
||||||
|
|
||||||
|
[section2]
|
||||||
|
name = John
|
||||||
|
lastname = Doe
|
||||||
|
fullname = %(name)s %(lastname)s
|
||||||
|
country = ${Section1:country}
|
||||||
|
|
||||||
|
To access config values from other modules follow this approach:
|
||||||
|
|
||||||
|
import Config.config as CONF
|
||||||
|
full_name = CONF.get('section2', 'fullname')
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import configparser
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_FILE = os.path.join(os.path.dirname(__file__), 'config.ini')
|
||||||
|
CONFIG = configparser.SafeConfigParser()
|
||||||
|
|
||||||
|
|
||||||
|
def get(section, option, raw=False, variables=None):
|
||||||
|
"""Wrapper function to mimic behavior of ConfigParse (Python3).
|
||||||
|
|
||||||
|
Python3 uses a ConfigParse that is different than the Python2 ConfigParser,
|
||||||
|
it has some additional functionality. One of the biggest differences is
|
||||||
|
that with ConfigParse you can interpolate variables from one section into
|
||||||
|
another section of the config file. This functionality is not included in
|
||||||
|
the ConfigParse. Since it is very useful, this function wraps the original
|
||||||
|
get function from ConfigParser so it includes the missing interpolation.
|
||||||
|
:param section: the section where the option to be gotten is
|
||||||
|
:param option: the option to look for in the config file
|
||||||
|
:param raw: all the '%' interpolations are expanded in the return values,
|
||||||
|
unless the raw argument is true.
|
||||||
|
:param variables: the option is looked up in variables (if provided)
|
||||||
|
:return: the specified value from the config file
|
||||||
|
"""
|
||||||
|
# ensure file readed is up to date always
|
||||||
|
CONFIG.read(CONFIG_FILE)
|
||||||
|
original_option = CONFIG.get(section, option, raw=raw, vars=variables)
|
||||||
|
# find all matches that have the following pattern: ${something}
|
||||||
|
matches = re.findall(r'\$\{(.*?)\}', original_option)
|
||||||
|
new_value = original_option
|
||||||
|
for match in matches:
|
||||||
|
# interpolate matches found with ${something} with the referenced
|
||||||
|
# option from the appropriate section
|
||||||
|
pattern = '${' + match + '}'
|
||||||
|
value = match.split(':')
|
||||||
|
foreign_value = CONFIG.get(value[0], value[1])
|
||||||
|
new_value = new_value.replace(pattern, foreign_value)
|
||||||
|
if original_option != new_value:
|
||||||
|
CONFIG.set(section, option, new_value)
|
||||||
|
|
||||||
|
# return the interpolated value
|
||||||
|
return CONFIG.get(section, option, raw=raw, vars=variables)
|
||||||
|
|
||||||
|
|
||||||
|
def getint(section, option):
|
||||||
|
"""Wrapper that returns the value as an integer.
|
||||||
|
|
||||||
|
:param section: the section where the option to be gotten is
|
||||||
|
:param option: the option to look for in the config file
|
||||||
|
:return: the specified value from the config file
|
||||||
|
"""
|
||||||
|
return int(CONFIG.get(section, option))
|
||||||
|
|
||||||
|
|
||||||
|
def getfloat(section, option):
|
||||||
|
"""Wrapper that returns the value as a float.
|
||||||
|
|
||||||
|
:param section: the section where the option to be gotten is
|
||||||
|
:param option: the option to look for in the config file
|
||||||
|
:return: the specified value from the config file
|
||||||
|
"""
|
||||||
|
return float(CONFIG.get(section, option))
|
||||||
|
|
||||||
|
|
||||||
|
def getboolean(section, option):
|
||||||
|
"""Wrapper that returns the value as a boolean.
|
||||||
|
|
||||||
|
:param section: the section where the option to be gotten is
|
||||||
|
:param option: the option to look for in the config file
|
||||||
|
:return: the specified value from the config file
|
||||||
|
"""
|
||||||
|
value = CONFIG.get(section, option)
|
||||||
|
return value.lower() == 'true'
|
||||||
|
|
||||||
|
|
||||||
|
def _unload_current_values():
|
||||||
|
"""Removes current sections from the existing config object"""
|
||||||
|
for section in CONFIG.sections():
|
||||||
|
CONFIG.remove_section(section)
|
||||||
|
|
||||||
|
|
||||||
|
def create_config():
|
||||||
|
"""Creates the config file in the current directory"""
|
||||||
|
if os.path.isfile(CONFIG_FILE):
|
||||||
|
os.remove(CONFIG_FILE)
|
||||||
|
with open(CONFIG_FILE, 'wb') as configfile:
|
||||||
|
_unload_current_values()
|
||||||
|
CONFIG.write(configfile)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_arguments():
|
||||||
|
"""Parses arguments from the command line"""
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='Config file generator')
|
||||||
|
parser.add_argument(
|
||||||
|
'--generate', action='store_true',
|
||||||
|
help='Generates a config file with default values')
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
ARGUMENTS = parse_arguments()
|
||||||
|
if ARGUMENTS.generate:
|
||||||
|
create_config()
|
||||||
|
print('Config file created at: {name}'.format(name=CONFIG_FILE))
|
|
@ -0,0 +1,16 @@
|
||||||
|
system_mode: duplex
|
||||||
|
|
||||||
|
dns_servers:
|
||||||
|
- 8.8.8.8
|
||||||
|
|
||||||
|
docker_http_proxy: http://<url>:<port>
|
||||||
|
docker_https_proxy: http://<url>:<port>
|
||||||
|
|
||||||
|
external_oam_subnet: 10.10.10.0/24
|
||||||
|
external_oam_gateway_address: 10.10.10.1
|
||||||
|
external_oam_floating_address: 10.10.10.2
|
||||||
|
external_oam_node_0_address: 10.10.10.3
|
||||||
|
external_oam_node_1_address: 10.10.10.4
|
||||||
|
|
||||||
|
ansible_become_pass: ANSIBLE_PASS
|
||||||
|
admin_password: ADMIN_PASS
|
|
@ -0,0 +1,16 @@
|
||||||
|
system_mode: duplex
|
||||||
|
|
||||||
|
dns_servers:
|
||||||
|
- 8.8.8.8
|
||||||
|
|
||||||
|
docker_http_proxy: http://<url>:<port>
|
||||||
|
docker_https_proxy: http://<url>:<port>
|
||||||
|
|
||||||
|
external_oam_subnet: 10.10.10.0/24
|
||||||
|
external_oam_gateway_address: 10.10.10.1
|
||||||
|
external_oam_floating_address: 10.10.10.2
|
||||||
|
external_oam_node_0_address: 10.10.10.3
|
||||||
|
external_oam_node_1_address: 10.10.10.4
|
||||||
|
|
||||||
|
ansible_become_pass: ANSIBLE_PASS
|
||||||
|
admin_password: ADMIN_PASS
|
|
@ -0,0 +1,12 @@
|
||||||
|
dns_servers:
|
||||||
|
- 8.8.8.8
|
||||||
|
|
||||||
|
docker_http_proxy: http://<url>:<port>
|
||||||
|
docker_https_proxy: http://<url>:<port>
|
||||||
|
|
||||||
|
external_oam_subnet: 10.10.10.0/24
|
||||||
|
external_oam_gateway_address: 10.10.10.1
|
||||||
|
external_oam_floating_address: 10.10.10.3
|
||||||
|
|
||||||
|
ansible_become_pass: ANSIBLE_PASS
|
||||||
|
admin_password: ADMIN_PASS
|
|
@ -0,0 +1,155 @@
|
||||||
|
[qemu_logo]: ./images/qemu_logo.png
|
||||||
|
|
||||||
|
![alt text][qemu_logo]
|
||||||
|
|
||||||
|
Table of Contents
|
||||||
|
|
||||||
|
- [qemu_setup.yml](#qemu_setupyml)
|
||||||
|
- [Description](#description)
|
||||||
|
- [Examples](#examples)
|
||||||
|
- [1 controller + 2 compute](#1-controller--2-computes)
|
||||||
|
- [parameters](#parameters)
|
||||||
|
- [1 controller + 2 computes & 1 controller + 1 compute](#1-controller--2-computes--1-controller--1-compute)
|
||||||
|
- [Highlights](#highlights)
|
||||||
|
- [general_system_configurations section](#general_system_configurations-section)
|
||||||
|
|
||||||
|
# qemu_setup.yml
|
||||||
|
The purpose of this configurations file is to setup easily QEMU in the host.
|
||||||
|
|
||||||
|
# Description
|
||||||
|
YAML is a human-readable data serialization format that takes concepts from
|
||||||
|
programming languages such as C, Perl, and Python, and ideas from XML and the
|
||||||
|
data format of electronic mail.
|
||||||
|
It is available for several programming languages.
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
|
||||||
|
## 1 controller + 2 computes
|
||||||
|
Please consider the following example to setup the following configuration:
|
||||||
|
|
||||||
|
`1 controller + 2 computes`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
configuration_0:
|
||||||
|
controller-0:
|
||||||
|
controller_0_partition_a: 20
|
||||||
|
controller_0_partition_b: 10
|
||||||
|
controller_0_memory_size: 5120
|
||||||
|
controller_0_system_cores: 2
|
||||||
|
controller-0-compute-0:
|
||||||
|
controller_0_compute_0_partition_a: 20
|
||||||
|
controller_0_compute_0_partition_b: 20
|
||||||
|
controller_0_compute_0_memory_size: 3072
|
||||||
|
controller_0_compute_0_system_cores: 1
|
||||||
|
controller-0-compute-1:
|
||||||
|
controller_0_compute_1_partition_a: 20
|
||||||
|
controller_0_compute_1_partition_b: 20
|
||||||
|
controller_0_compute_1_memory_size: 3072
|
||||||
|
controller_0_compute_1_system_cores: 1
|
||||||
|
````
|
||||||
|
|
||||||
|
### parameters
|
||||||
|
|
||||||
|
**`@param: configuration_0`**: which contains the controller and the computes.<br>
|
||||||
|
|
||||||
|
**`@param: controller-0`**: which contains the following:<br>
|
||||||
|
- `@param: controller_0_partition_a`: which is the controller 0 partition size
|
||||||
|
A in GB.
|
||||||
|
- `@param: controller_0_partition_b`: which is the controller 0 partition size
|
||||||
|
B size in GB.
|
||||||
|
- `@param: controller_0_memory_size`: which is the controller 0 memory size
|
||||||
|
in MB.
|
||||||
|
- `@param: controller_0_system_cores`: which is the controller 0 system cores
|
||||||
|
to be assigned.
|
||||||
|
|
||||||
|
**`@param: controller-0-compute-0`**: which contains the following:<br>
|
||||||
|
- `@param: controller_0_compute_0_partition_a`: which is the controller's
|
||||||
|
compute 0 partition size A in GB.
|
||||||
|
- `@param: controller_0_compute_0_partition_b`: which is the controller's
|
||||||
|
compute 0 partition size B in GB.
|
||||||
|
- `@param: controller_0_compute_0_memory_size`: which is the controller's
|
||||||
|
compute 0 memory size B in MB.
|
||||||
|
- `@param: controller_0_compute_0_system_cores`: which is the controller's
|
||||||
|
compute 0 system cores to be assigned.
|
||||||
|
|
||||||
|
**`@param: controller-0-compute-1`**: which contains the following:<br>
|
||||||
|
- `@param: controller_0_compute_1_partition_a`: which is the controller's
|
||||||
|
compute 1 partition size A in GB.
|
||||||
|
- `@param: controller_0_compute_1_partition_b`: which is the controller's
|
||||||
|
compute 1 partition size B in GB.
|
||||||
|
- `@param: controller_0_compute_1_memory_size`: which is the controller's
|
||||||
|
compute 1 memory size B in MB.
|
||||||
|
- `@param: controller_0_compute_1_system_cores`: which is the controller's
|
||||||
|
compute 1 system cores to be assigned.
|
||||||
|
|
||||||
|
## 1 controller + 2 computes & 1 controller + 1 compute
|
||||||
|
Please consider the following example to setup the following configuration:
|
||||||
|
|
||||||
|
`1 controller + 2 computes & 1 controller + 1 compute`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
configuration_0:
|
||||||
|
controller-0:
|
||||||
|
controller_0_partition_a: 20
|
||||||
|
controller_0_partition_b: 10
|
||||||
|
controller_0_memory_size: 5120
|
||||||
|
controller_0_system_cores: 2
|
||||||
|
controller-0-compute-0:
|
||||||
|
controller_0_compute_0_partition_a: 20
|
||||||
|
controller_0_compute_0_partition_b: 20
|
||||||
|
controller_0_compute_0_memory_size: 3072
|
||||||
|
controller_0_compute_0_system_cores: 1
|
||||||
|
controller-0-compute-1:
|
||||||
|
controller_0_compute_1_partition_a: 20
|
||||||
|
controller_0_compute_1_partition_b: 20
|
||||||
|
controller_0_compute_1_memory_size: 3072
|
||||||
|
controller_0_compute_1_system_cores: 1
|
||||||
|
configuration_1:
|
||||||
|
controller-1:
|
||||||
|
controller_1_partition_a: 15
|
||||||
|
controller_1_partition_b: 10
|
||||||
|
controller_1_memory_size: 5120
|
||||||
|
controller_1_system_cores: 2
|
||||||
|
controller-1-compute-0:
|
||||||
|
controller_1_compute_0_partition_a: 20
|
||||||
|
controller_1_compute_0_partition_b: 20
|
||||||
|
controller_1_compute_0_memory_size: 3072
|
||||||
|
controller_1_compute_0_system_cores: 1
|
||||||
|
```
|
||||||
|
|
||||||
|
:notebook: the parameters description are the same that the [section above](#parameters).
|
||||||
|
|
||||||
|
## Highlights
|
||||||
|
Please consider the following when creating the yaml configuration file:
|
||||||
|
|
||||||
|
- The total sum of the partitions must not exceed of the total free disk space
|
||||||
|
in the host.
|
||||||
|
- The total sum of the memory size must not exceed of the total free memory
|
||||||
|
size in the host.
|
||||||
|
- The total sum of the system cores must not exceed of the total system cores
|
||||||
|
subtracting the `os_system_cores` assigned in `general_system_configurations`
|
||||||
|
section.
|
||||||
|
|
||||||
|
|
||||||
|
## general_system_configurations section
|
||||||
|
The general_system_configurations will be explained below:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
general_system_configurations:
|
||||||
|
os_system_memory: 1024
|
||||||
|
disk_space_allocated_to_os: 20
|
||||||
|
os_system_cores: 2
|
||||||
|
default_mount_point: '/'
|
||||||
|
```
|
||||||
|
|
||||||
|
**`@param: general_system_configurations`**: which contains the following:
|
||||||
|
- `@param: os_system_memory`: which is the system memory reserved for the OS.
|
||||||
|
- `@param: disk_space_allocated_to_os`: which is the disk space reserved for
|
||||||
|
the OS.
|
||||||
|
- `@param: os_system_cores`: which is the system cores reserved for the OS.
|
||||||
|
- `@param: default_mount_point`: which is the mount point where the space in
|
||||||
|
disk will be analyzed by the script.
|
||||||
|
|
||||||
|
:notebook: The first 3 params are used for system reservation and they are for
|
||||||
|
the user's consideration in order to avoid that QEMU takes all the resources
|
||||||
|
making slow the current system.
|
|
@ -0,0 +1,92 @@
|
||||||
|
<domain type='kvm' id='187'>
|
||||||
|
<name>NAME</name>
|
||||||
|
<memory unit='UNIT'>MEMORY</memory>
|
||||||
|
<currentMemory unit='UNIT'>MEMORY</currentMemory>
|
||||||
|
<vcpu placement='static'>CORES</vcpu>
|
||||||
|
<resource>
|
||||||
|
<partition>/machine</partition>
|
||||||
|
</resource>
|
||||||
|
<os>
|
||||||
|
<type arch='x86_64' machine='pc'>hvm</type>
|
||||||
|
</os>
|
||||||
|
<features>
|
||||||
|
<acpi/>
|
||||||
|
<apic/>
|
||||||
|
<pae/>
|
||||||
|
</features>
|
||||||
|
<cpu match='exact'>
|
||||||
|
<model fallback='forbid'>Nehalem</model>
|
||||||
|
<topology sockets='1' cores='CORES' 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='stxbr1'/>
|
||||||
|
<target dev='vnet8'/>
|
||||||
|
<model type='e1000'/>
|
||||||
|
<alias name='net0'/>
|
||||||
|
</interface>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<source bridge='stxbr2'/>
|
||||||
|
<target dev='vnet9'/>
|
||||||
|
<model type='e1000'/>
|
||||||
|
<boot order='2'/>
|
||||||
|
<alias name='net1'/>
|
||||||
|
</interface>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<source bridge='stxbr3'/>
|
||||||
|
<target dev='vnet10'/>
|
||||||
|
<model type='virtio'/>
|
||||||
|
<alias name='net2'/>
|
||||||
|
</interface>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<source bridge='stxbr4'/>
|
||||||
|
<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'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
|
||||||
|
</video>
|
||||||
|
<memballoon model='virtio'>
|
||||||
|
<alias name='balloon0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
|
||||||
|
</memballoon>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
|
@ -0,0 +1,18 @@
|
||||||
|
Controllers:
|
||||||
|
controller-0:
|
||||||
|
partition_a: 600
|
||||||
|
partition_b: 100
|
||||||
|
partition_d: 100
|
||||||
|
memory_size: 25600
|
||||||
|
system_cores: 6
|
||||||
|
controller-1:
|
||||||
|
partition_a: 600
|
||||||
|
partition_b: 100
|
||||||
|
partition_d: 100
|
||||||
|
memory_size: 25600
|
||||||
|
system_cores: 6
|
||||||
|
general_system_configurations:
|
||||||
|
os_system_memory: 1024
|
||||||
|
disk_space_allocated_to_os: 20
|
||||||
|
os_system_cores: 2
|
||||||
|
default_mount_point: '/'
|
|
@ -0,0 +1,29 @@
|
||||||
|
Controllers:
|
||||||
|
controller-0:
|
||||||
|
partition_a: 250
|
||||||
|
partition_b: 250
|
||||||
|
partition_d: 50
|
||||||
|
memory_size: 16384
|
||||||
|
system_cores: 4
|
||||||
|
controller-1:
|
||||||
|
partition_a: 250
|
||||||
|
partition_b: 250
|
||||||
|
partition_d: 50
|
||||||
|
memory_size: 16384
|
||||||
|
system_cores: 4
|
||||||
|
Computes:
|
||||||
|
compute-0:
|
||||||
|
partition_a: 250
|
||||||
|
partition_b: 250
|
||||||
|
memory_size: 10240
|
||||||
|
system_cores: 3
|
||||||
|
compute-1:
|
||||||
|
partition_a: 250
|
||||||
|
partition_b: 250
|
||||||
|
memory_size: 10240
|
||||||
|
system_cores: 3
|
||||||
|
general_system_configurations:
|
||||||
|
os_system_memory: 1024
|
||||||
|
disk_space_allocated_to_os: 20
|
||||||
|
os_system_cores: 2
|
||||||
|
default_mount_point: '/'
|
|
@ -0,0 +1,42 @@
|
||||||
|
Controllers:
|
||||||
|
controller-0:
|
||||||
|
partition_a: 250
|
||||||
|
partition_b: 250
|
||||||
|
partition_d: 50
|
||||||
|
memory_size: 16384
|
||||||
|
system_cores: 4
|
||||||
|
controller-1:
|
||||||
|
partition_a: 250
|
||||||
|
partition_b: 250
|
||||||
|
partition_d: 50
|
||||||
|
memory_size: 16384
|
||||||
|
system_cores: 4
|
||||||
|
Computes:
|
||||||
|
compute-0:
|
||||||
|
partition_a: 250
|
||||||
|
partition_b: 250
|
||||||
|
memory_size: 10240
|
||||||
|
system_cores: 3
|
||||||
|
compute-1:
|
||||||
|
partition_a: 250
|
||||||
|
partition_b: 250
|
||||||
|
memory_size: 10240
|
||||||
|
system_cores: 3
|
||||||
|
Storages:
|
||||||
|
storage-0:
|
||||||
|
partition_a: 250
|
||||||
|
partition_b: 250
|
||||||
|
partition_d: 50
|
||||||
|
memory_size: 6144
|
||||||
|
system_cores: 3
|
||||||
|
storage-1:
|
||||||
|
partition_a: 250
|
||||||
|
partition_b: 250
|
||||||
|
partition_d: 50
|
||||||
|
memory_size: 6144
|
||||||
|
system_cores: 3
|
||||||
|
general_system_configurations:
|
||||||
|
os_system_memory: 1024
|
||||||
|
disk_space_allocated_to_os: 20
|
||||||
|
os_system_cores: 2
|
||||||
|
default_mount_point: '/'
|
|
@ -0,0 +1,12 @@
|
||||||
|
Controllers:
|
||||||
|
controller-0:
|
||||||
|
partition_a: 600
|
||||||
|
partition_b: 100
|
||||||
|
partition_d: 100
|
||||||
|
memory_size: 25600
|
||||||
|
system_cores: 6
|
||||||
|
general_system_configurations:
|
||||||
|
os_system_memory: 1024
|
||||||
|
disk_space_allocated_to_os: 20
|
||||||
|
os_system_cores: 2
|
||||||
|
default_mount_point: '/'
|
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
|
@ -0,0 +1,106 @@
|
||||||
|
<domain type='kvm' id='164'>
|
||||||
|
<name>NAME</name>
|
||||||
|
<memory unit='UNIT'>MEMORY</memory>
|
||||||
|
<currentMemory unit='UNIT'>MEMORY</currentMemory>
|
||||||
|
<vcpu placement='static'>CORES</vcpu>
|
||||||
|
<resource>
|
||||||
|
<partition>/machine</partition>
|
||||||
|
</resource>
|
||||||
|
<os>
|
||||||
|
<type arch='x86_64' machine='pc'>hvm</type>
|
||||||
|
</os>
|
||||||
|
<features>
|
||||||
|
<acpi/>
|
||||||
|
<apic/>
|
||||||
|
<pae/>
|
||||||
|
</features>
|
||||||
|
<cpu match='exact'>
|
||||||
|
<model fallback='forbid'>Nehalem</model>
|
||||||
|
<topology sockets='1' cores='CORES' 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='sdd' 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='network'>
|
||||||
|
<source network='stx-nat'/>
|
||||||
|
<target dev='vnet0'/>
|
||||||
|
<model type='e1000'/>
|
||||||
|
<alias name='net0'/>
|
||||||
|
</interface>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<source bridge='stxbr2'/>
|
||||||
|
<target dev='vnet1'/>
|
||||||
|
<model type='e1000'/>
|
||||||
|
<alias name='net1'/>
|
||||||
|
</interface>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<source bridge='stxbr3'/>
|
||||||
|
<target dev='vnet2'/>
|
||||||
|
<model type='virtio'/>
|
||||||
|
<alias name='net2'/>
|
||||||
|
</interface>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<source bridge='stxbr4'/>
|
||||||
|
<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'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
|
||||||
|
</video>
|
||||||
|
<memballoon model='virtio'>
|
||||||
|
<alias name='balloon0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
|
||||||
|
</memballoon>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<network>
|
||||||
|
<name>stx-nat</name>
|
||||||
|
<bridge name="stxbr1" stp="off"/>
|
||||||
|
<forward mode="nat"/>
|
||||||
|
<ip address="10.10.10.1" netmask="255.255.255.0">
|
||||||
|
</ip>
|
||||||
|
</network>
|
|
@ -0,0 +1,638 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""This module setup the controller(s)/computes(s) in the current host"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
from argparse import RawDescriptionHelpFormatter
|
||||||
|
from imp import reload
|
||||||
|
import multiprocessing
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
from shutil import copy
|
||||||
|
from shutil import rmtree
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# this needs to be exactly here after call network.delete_network_interfaces()
|
||||||
|
# otherwise the suite local modules they will not be recognized
|
||||||
|
# hence adding `noqa` to avoid linter issues.
|
||||||
|
SUITE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
sys.path.append(SUITE_DIR)
|
||||||
|
|
||||||
|
from Config import config # noqa: E402
|
||||||
|
from Utils import bash_utils as bash # noqa: E402
|
||||||
|
from Utils import logger # noqa: E402
|
||||||
|
from Utils import network # noqa: E402
|
||||||
|
from Utils import utils # noqa: E402
|
||||||
|
import kmodpy # noqa: E402
|
||||||
|
import yaml # noqa: E402
|
||||||
|
|
||||||
|
# reloading config.ini
|
||||||
|
reload(config)
|
||||||
|
|
||||||
|
# Global variables
|
||||||
|
THIS_PATH = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
# setup the logger
|
||||||
|
LOG_FILENAME = 'qemu_setup.log'
|
||||||
|
LOG_PATH = config.get('general', 'LOG_PATH')
|
||||||
|
LOG = logger.setup_logging(
|
||||||
|
'qemu_setup', log_file='{path}/{filename}'.format(
|
||||||
|
path=LOG_PATH, filename=LOG_FILENAME), console_log=False)
|
||||||
|
|
||||||
|
|
||||||
|
def enable_nat_network():
|
||||||
|
"""Enable NAT network for VMs
|
||||||
|
|
||||||
|
This function creates a NAT network to allow VM external connection
|
||||||
|
needed for download docker images.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
nat_xml = os.path.join(THIS_PATH, 'nat-network.xml')
|
||||||
|
nat_net_name = 'stx-nat'
|
||||||
|
bash.run_command('sudo virsh net-define {}'.format(nat_xml))
|
||||||
|
bash.run_command('sudo virsh net-start {}'.format(nat_net_name))
|
||||||
|
|
||||||
|
|
||||||
|
def exit_dict_status(code):
|
||||||
|
"""Exit status
|
||||||
|
|
||||||
|
The aim of this function is to provide a exit status in dictionary format
|
||||||
|
as an string in order to grab it for robot for perform actions.
|
||||||
|
|
||||||
|
:param code: which is the exit status code
|
||||||
|
code 0: which represents an exit status god.
|
||||||
|
code 1: which represents an exit status bad.
|
||||||
|
"""
|
||||||
|
# defining the dictionary
|
||||||
|
|
||||||
|
if code == 1:
|
||||||
|
LOG.info('status: FAIL')
|
||||||
|
elif code == 0:
|
||||||
|
LOG.info('status: PASS')
|
||||||
|
else:
|
||||||
|
LOG.error('exit code not valid')
|
||||||
|
|
||||||
|
sys.exit(code)
|
||||||
|
|
||||||
|
|
||||||
|
def check_kernel_virtualization():
|
||||||
|
"""Check kernel virtualization
|
||||||
|
|
||||||
|
Checks if Virtualization Technology is enabled in the BIOS and it is
|
||||||
|
present in the kernel as a module.
|
||||||
|
QEMU requires KVM (Kernel Virtualization Module) to run the nodes.
|
||||||
|
"""
|
||||||
|
_km = kmodpy.Kmod()
|
||||||
|
module_list = [m for m in _km.list()]
|
||||||
|
|
||||||
|
virtualization = filter(lambda mod: mod[0] == 'kvm_intel', module_list)
|
||||||
|
|
||||||
|
if not virtualization:
|
||||||
|
message = ('KVM (vmx) is disabled by your BIOS\nEnter your BIOS setup '
|
||||||
|
'and enable Virtualization Technology (VT), and then hard '
|
||||||
|
'power off/power on your system')
|
||||||
|
raise OSError(message)
|
||||||
|
|
||||||
|
|
||||||
|
def check_preconditions():
|
||||||
|
"""Check host preconditions
|
||||||
|
|
||||||
|
The aim of this function is to check the requirements to run QEMU in the
|
||||||
|
host.
|
||||||
|
"""
|
||||||
|
# if this script is running through ssh connection the following
|
||||||
|
# environment variable needs to be setup in the host bashrc
|
||||||
|
if 'DISPLAY' not in os.environ:
|
||||||
|
LOG.info('configuring DISPLAY environment variable')
|
||||||
|
os.environ['DISPLAY'] = ':0'
|
||||||
|
|
||||||
|
|
||||||
|
def get_system_memory(configurations):
|
||||||
|
"""Get the system memory
|
||||||
|
|
||||||
|
The aim of this function is to get the system memory to be setup with QEMU.
|
||||||
|
|
||||||
|
:param: configurations
|
||||||
|
- which is an object with the values loaded from the yaml.
|
||||||
|
:return:
|
||||||
|
- system_free_memory: which is the total system free memory.
|
||||||
|
- recommended_system_free_memory: which is the recommended system free
|
||||||
|
memory.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# calculating the system memory to be assigned (value in megabytes)
|
||||||
|
# os_system_memory will return 0 if either key1 or key2 does not exists
|
||||||
|
os_system_memory = configurations.get(
|
||||||
|
'general_system_configurations', 0).get("os_system_memory", 0)
|
||||||
|
system_free_memory = map(
|
||||||
|
int, os.popen('free -m | grep Mem').readlines()[-1][4:].split())[-1]
|
||||||
|
# subtracting OS system memory
|
||||||
|
recommended_system_free_memory = system_free_memory - os_system_memory
|
||||||
|
|
||||||
|
return system_free_memory, recommended_system_free_memory
|
||||||
|
|
||||||
|
|
||||||
|
def get_free_disk_space(configurations):
|
||||||
|
"""Get the system free disk space
|
||||||
|
|
||||||
|
The aim of this function if to get the system free disk in order to setup
|
||||||
|
with QEMU.
|
||||||
|
|
||||||
|
:param: configurations
|
||||||
|
- which is an object with the values loaded from the yaml.
|
||||||
|
:return
|
||||||
|
- system_free_disk_size: which is the total system free disk size in GB
|
||||||
|
- r_system_free_disk_size: which is the recommended system
|
||||||
|
free disk size in GB subtracting the disk_space_allocated_to_os
|
||||||
|
from yaml configuration file for the host OS in order to avoid
|
||||||
|
low performance.
|
||||||
|
"""
|
||||||
|
# disk_space_allocated_to_os will return 0 if either key1 or key2 does
|
||||||
|
# not exists
|
||||||
|
disk_space_allocated_to_os = configurations.get(
|
||||||
|
'general_system_configurations', 0).get(
|
||||||
|
"disk_space_allocated_to_os", 0)
|
||||||
|
# the mount point in which will be calculated the free space in disk
|
||||||
|
default_mount_point = configurations.get(
|
||||||
|
'general_system_configurations', 0).get(
|
||||||
|
"default_mount_point", '/')
|
||||||
|
statvfs = os.statvfs(default_mount_point)
|
||||||
|
# the following value will be get in megabytes
|
||||||
|
system_free_disk_size = statvfs.f_frsize * statvfs.f_bavail / 1000000000
|
||||||
|
# subtracting the 20% of the total disk free
|
||||||
|
r_system_free_disk_size = (
|
||||||
|
(100 - disk_space_allocated_to_os) * system_free_disk_size / 100)
|
||||||
|
|
||||||
|
return system_free_disk_size, r_system_free_disk_size
|
||||||
|
|
||||||
|
|
||||||
|
def get_system_resources(configurations):
|
||||||
|
"""Get resources from the current host
|
||||||
|
|
||||||
|
The aim of this function is to get resources for the virtual environment
|
||||||
|
with QEMU in order to setup properly it and avoid configuration issues.
|
||||||
|
|
||||||
|
:param: configurations
|
||||||
|
- which is an object with the values loaded from the yaml.
|
||||||
|
:return:
|
||||||
|
- recommended_system_free_memory: which is the recommended system free
|
||||||
|
memory to be setup with QEMU.
|
||||||
|
- system_free_disk_size: which is the total system free disk size.
|
||||||
|
- r_system_free_disk_size: which is the recommended system
|
||||||
|
- r_system_free_disk_size: which is the recommended system
|
||||||
|
free disk size.
|
||||||
|
- recommended_system_cores: which is the recommended system cores to be
|
||||||
|
setup with QEMU.
|
||||||
|
"""
|
||||||
|
# os_system_cores will return 0 if either key1 or key2 does not exists
|
||||||
|
os_system_cores = configurations.get(
|
||||||
|
'general_system_configurations', 0).get("os_system_cores", 0)
|
||||||
|
|
||||||
|
# Getting the system free memory and the recommended system memory
|
||||||
|
_, recommended_system_free_memory = get_system_memory(
|
||||||
|
configurations)
|
||||||
|
|
||||||
|
# Getting the system free disk size and the recommended system free (GB)
|
||||||
|
system_free_disk_size, r_system_free_disk_size = (
|
||||||
|
get_free_disk_space(configurations))
|
||||||
|
|
||||||
|
# Calculating the system cores to be assigned to the controller/computes
|
||||||
|
recommended_system_cores = multiprocessing.cpu_count() - os_system_cores
|
||||||
|
|
||||||
|
return (
|
||||||
|
recommended_system_free_memory,
|
||||||
|
system_free_disk_size, r_system_free_disk_size,
|
||||||
|
recommended_system_cores)
|
||||||
|
|
||||||
|
|
||||||
|
def check_system_resources(configurations):
|
||||||
|
"""Check basic configurations.
|
||||||
|
|
||||||
|
The aim of this function is to check the following aspects before to
|
||||||
|
proceed to configure the nodes.
|
||||||
|
- checks if the disk setup by the user in the yaml is less than the
|
||||||
|
recommended free space
|
||||||
|
- checks if the memory size setup by the user in the yaml is less than the
|
||||||
|
recommended memory size.
|
||||||
|
- checks if the system cores setup by the user in the yaml is less than the
|
||||||
|
recommended system cores.
|
||||||
|
|
||||||
|
:param configurations: which is the object that contains all the
|
||||||
|
configurations from the yaml file.
|
||||||
|
"""
|
||||||
|
# checking how many configurations the yaml file has
|
||||||
|
configurations_keys = configurations.keys()
|
||||||
|
regex = re.compile('configuration_.')
|
||||||
|
total_configurations = list(filter(regex.match, configurations_keys))
|
||||||
|
|
||||||
|
# getting the system recommendations
|
||||||
|
(recommended_system_free_memory, _,
|
||||||
|
r_system_free_disk_size,
|
||||||
|
recommended_system_cores) = get_system_resources(configurations)
|
||||||
|
|
||||||
|
# iterating over the total configurations setup in yaml file in order to
|
||||||
|
# get the disk/memory space assigned by the user
|
||||||
|
user_memory_defined, user_disk_space_defined, user_system_cores_defined = (
|
||||||
|
0, 0, 0)
|
||||||
|
|
||||||
|
for configuration in range(0, len(total_configurations)):
|
||||||
|
# iterating over the configurations
|
||||||
|
|
||||||
|
current_controller = 'controller-{}'.format(configuration)
|
||||||
|
# controller will return NoneType if either key1 or key2 does
|
||||||
|
# not exists
|
||||||
|
controller = configurations.get(
|
||||||
|
'configuration_{}'.format(configuration), {}).get(
|
||||||
|
'controller-{}'.format(configuration), {})
|
||||||
|
controller_partition_a = int(controller.get(
|
||||||
|
'controller_{}_partition_a'.format(configuration)))
|
||||||
|
controller_partition_b = int(controller.get(
|
||||||
|
'controller_{}_partition_b'.format(configuration)))
|
||||||
|
controller_partition_d = int(controller.get(
|
||||||
|
'controller_{}_partition_d'.format(configuration)))
|
||||||
|
controller_memory = int(controller.get(
|
||||||
|
'controller_{}_memory_size'.format(configuration)))
|
||||||
|
controller_system_cores = int(controller.get(
|
||||||
|
'controller_{}_system_cores'.format(configuration)))
|
||||||
|
|
||||||
|
# checking if the current controller at least has 1 cpu assigned in
|
||||||
|
# order to avoid the following error:
|
||||||
|
# error: XML error: Invalid CPU topology
|
||||||
|
if controller_system_cores < 1:
|
||||||
|
LOG.error('{}: must have assigned at least 1 core'.format(
|
||||||
|
current_controller))
|
||||||
|
exit_dict_status(1)
|
||||||
|
|
||||||
|
# checking how many computes the current controller has
|
||||||
|
compute_keys = configurations.get('configuration_{}'.format(
|
||||||
|
configuration), {}).keys()
|
||||||
|
regex = re.compile('controller-{0}-compute-.'.format(configuration))
|
||||||
|
total_computes = list(filter(regex.match, compute_keys))
|
||||||
|
|
||||||
|
for compute_number in range(0, len(total_computes)):
|
||||||
|
current_compute = '{0}-compute-{1}'.format(
|
||||||
|
current_controller, compute_number)
|
||||||
|
# compute will return NoneType if either key1 or key2 does
|
||||||
|
# not exists controller_1_compute_2:
|
||||||
|
compute = configurations.get('configuration_{}'.format(
|
||||||
|
configuration), {}).get(
|
||||||
|
'controller-{0}-compute-{1}'.format(
|
||||||
|
configuration, compute_number), {})
|
||||||
|
compute_partition_a = int(compute.get(
|
||||||
|
'controller_{0}_compute_{1}_partition_a'.format(
|
||||||
|
configuration, compute_number)))
|
||||||
|
compute_partition_b = int(compute.get(
|
||||||
|
'controller_{0}_compute_{1}_partition_b'.format(
|
||||||
|
configuration, compute_number)))
|
||||||
|
compute_memory = int(compute.get(
|
||||||
|
'controller_{0}_compute_{1}_memory_size'.format(
|
||||||
|
configuration, compute_number)))
|
||||||
|
compute_system_cores = int(compute.get(
|
||||||
|
'controller_{0}_compute_{1}_system_cores'.format(
|
||||||
|
configuration, compute_number)))
|
||||||
|
|
||||||
|
# checking if the current compute at least has 1 cpu assigned in
|
||||||
|
# order to avoid the following error:
|
||||||
|
# error: XML error: Invalid CPU topology
|
||||||
|
if compute_system_cores < 1:
|
||||||
|
LOG.error('{}: must have assigned at least 1 core'.format(
|
||||||
|
current_compute))
|
||||||
|
exit_dict_status(1)
|
||||||
|
|
||||||
|
# increasing the variables (computes loop)
|
||||||
|
user_disk_space_defined = (
|
||||||
|
user_disk_space_defined + compute_partition_a +
|
||||||
|
compute_partition_b)
|
||||||
|
user_memory_defined = user_memory_defined + compute_memory
|
||||||
|
user_system_cores_defined = (
|
||||||
|
user_system_cores_defined + compute_system_cores)
|
||||||
|
|
||||||
|
# increasing the variables (controller loop)
|
||||||
|
user_disk_space_defined = (
|
||||||
|
user_disk_space_defined + controller_partition_a +
|
||||||
|
controller_partition_b + controller_partition_d)
|
||||||
|
user_memory_defined = user_memory_defined + controller_memory
|
||||||
|
user_system_cores_defined = (
|
||||||
|
user_system_cores_defined + controller_system_cores)
|
||||||
|
|
||||||
|
# checking the conditions defined in the yaml
|
||||||
|
if user_memory_defined > recommended_system_free_memory:
|
||||||
|
LOG.error(
|
||||||
|
'the memory defined in the yaml is greater than the recommended '
|
||||||
|
'free memory')
|
||||||
|
LOG.error('user memory defined : {}'.format(
|
||||||
|
user_memory_defined))
|
||||||
|
LOG.error('recommended system free memory : {}'.format(
|
||||||
|
recommended_system_free_memory))
|
||||||
|
exit_dict_status(1)
|
||||||
|
elif user_disk_space_defined > r_system_free_disk_size:
|
||||||
|
LOG.error(
|
||||||
|
'the disk space defined in the yaml is greater than the '
|
||||||
|
'recommended free disk size')
|
||||||
|
LOG.error('user disk space defined : {}'.format(
|
||||||
|
user_disk_space_defined))
|
||||||
|
LOG.error('recommended system free disk size : {}'.format(
|
||||||
|
r_system_free_disk_size))
|
||||||
|
exit_dict_status(1)
|
||||||
|
elif user_system_cores_defined > recommended_system_cores:
|
||||||
|
LOG.error(
|
||||||
|
'the system cores defined in the yaml is greater than the '
|
||||||
|
'recommended system cores')
|
||||||
|
LOG.error('user system cores defined : {}'.format(
|
||||||
|
user_system_cores_defined))
|
||||||
|
LOG.error('recommended system cores : {}'.format(
|
||||||
|
recommended_system_cores))
|
||||||
|
exit_dict_status(1)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_controller_computes(iso_file, configurations):
|
||||||
|
"""Setup the configurations in the host
|
||||||
|
|
||||||
|
This function setup the network and the configurations from yaml in the
|
||||||
|
current host.
|
||||||
|
|
||||||
|
:param iso_file: which is the absolute/relative path to the iso file which
|
||||||
|
will be setup in the controller(s) node(s).
|
||||||
|
:param configurations: which is the object that has all the configurations
|
||||||
|
to be setup in the system.
|
||||||
|
"""
|
||||||
|
# define the module's variables
|
||||||
|
libvirt_images_path = '/var/lib/libvirt/images'
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# customize Qemu configuration files
|
||||||
|
# ----------------------------------
|
||||||
|
utils.qemu_configuration_files()
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# configuring the network interfaces
|
||||||
|
# ----------------------------------
|
||||||
|
network.delete_network_interfaces()
|
||||||
|
enable_nat_network()
|
||||||
|
network.configure_network_interfaces()
|
||||||
|
|
||||||
|
# ------------------------------
|
||||||
|
# clean qemu/libvirt environment
|
||||||
|
# ------------------------------
|
||||||
|
utils.clean_qemu_environment()
|
||||||
|
|
||||||
|
if os.path.exists(os.path.join(THIS_PATH, 'vms')):
|
||||||
|
rmtree(os.path.join(THIS_PATH, 'vms'))
|
||||||
|
|
||||||
|
os.mkdir(os.path.join(THIS_PATH, 'vms'))
|
||||||
|
|
||||||
|
# ----------------------------------------------------------
|
||||||
|
# iterating over the total configurations setup in yaml file
|
||||||
|
# ----------------------------------------------------------
|
||||||
|
|
||||||
|
for controller, values in configurations.get('Controllers').items():
|
||||||
|
# iterating over the controllers
|
||||||
|
controller_partition_a = int(values.get('partition_a'))
|
||||||
|
controller_partition_b = int(values.get('partition_b'))
|
||||||
|
controller_partition_d = int(values.get('partition_d'))
|
||||||
|
controller_memory = int(values.get('memory_size'))
|
||||||
|
controller_system_cores = int(values.get('system_cores'))
|
||||||
|
|
||||||
|
# creating controller's partitions in the system
|
||||||
|
bash.run_command(
|
||||||
|
'sudo qemu-img create -f qcow2 {0}/{1}-0.img {2}G'.format(
|
||||||
|
libvirt_images_path, controller, controller_partition_a),
|
||||||
|
raise_exception=True)
|
||||||
|
bash.run_command(
|
||||||
|
'sudo qemu-img create -f qcow2 {0}/{1}-1.img {2}G'.format(
|
||||||
|
libvirt_images_path, controller, controller_partition_b),
|
||||||
|
raise_exception=True)
|
||||||
|
bash.run_command(
|
||||||
|
'sudo qemu-img create -f qcow2 {0}/{1}-2.img {2}G'.format(
|
||||||
|
libvirt_images_path, controller, controller_partition_d),
|
||||||
|
raise_exception=True)
|
||||||
|
|
||||||
|
# Only controller-0 needs to have the ISO file in order to boot the
|
||||||
|
# subsequent controllers
|
||||||
|
# heck_controller = False if configuration == 'controller-0' else True
|
||||||
|
|
||||||
|
if controller == 'controller-0':
|
||||||
|
bash.run_command(
|
||||||
|
'sed -e "s,NAME,{0}," '
|
||||||
|
'-e "s,ISO,{1}," '
|
||||||
|
'-e "s,UNIT,MiB," '
|
||||||
|
'-e "s,MEMORY,{2}," '
|
||||||
|
'-e "s,CORES,{3}," '
|
||||||
|
'-e "s,DISK0,{4}/{0}-0.img," '
|
||||||
|
'-e "s,DISK1,{4}/{0}-1.img," '
|
||||||
|
'-e "s,DISK2,{4}/{0}-2.img," '
|
||||||
|
'-e "s,destroy,restart," {5}/master_controller.xml > '
|
||||||
|
'{5}/vms/{0}.xml'.format(
|
||||||
|
controller, iso_file, controller_memory,
|
||||||
|
controller_system_cores, libvirt_images_path, THIS_PATH),
|
||||||
|
raise_exception=True)
|
||||||
|
else:
|
||||||
|
# this mean that is the controller-N
|
||||||
|
# modifying xml parameters for the current controller
|
||||||
|
bash.run_command(
|
||||||
|
'sed -e "s,NAME,{0}," '
|
||||||
|
'-e "s,UNIT,MiB," '
|
||||||
|
'-e "s,MEMORY,{1}," '
|
||||||
|
'-e "s,CORES,{2}," '
|
||||||
|
'-e "s,DISK0,{3}/{0}-0.img," '
|
||||||
|
'-e "s,DISK1,{3}/{0}-1.img," '
|
||||||
|
'-e "s,DISK2,{3}/{0}-2.img," '
|
||||||
|
'-e "s,destroy,restart," {4}/slave_controller.xml > '
|
||||||
|
'{4}/vms/{0}.xml'.format(
|
||||||
|
controller, controller_memory,
|
||||||
|
controller_system_cores, libvirt_images_path, THIS_PATH),
|
||||||
|
raise_exception=True)
|
||||||
|
|
||||||
|
# the following command define a domain and it does not start it and
|
||||||
|
# makes it persistent even after shutdown
|
||||||
|
bash.run_command('sudo virsh define {0}/vms/{1}.xml'.format(
|
||||||
|
THIS_PATH, controller))
|
||||||
|
|
||||||
|
# starting only the controller-0 which is the one with ISO in the xml
|
||||||
|
if controller == 'controller-0':
|
||||||
|
# the following command start a domain
|
||||||
|
bash.run_command('sudo virsh start {}'.format(
|
||||||
|
controller), raise_exception=True)
|
||||||
|
|
||||||
|
if 'Computes' in configurations:
|
||||||
|
for compute, values in configurations.get('Computes').items():
|
||||||
|
# iterating over the computes
|
||||||
|
compute_partition_a = int(values.get('partition_a'))
|
||||||
|
compute_partition_b = int(values.get('partition_b'))
|
||||||
|
compute_memory = int(values.get('memory_size'))
|
||||||
|
compute_system_cores = int(values.get('system_cores'))
|
||||||
|
|
||||||
|
# copy the compute.xml to vms folder
|
||||||
|
origin = os.path.join(THIS_PATH, 'compute.xml')
|
||||||
|
destination = os.path.join(THIS_PATH,
|
||||||
|
'vms', '{}.xml'.format(compute))
|
||||||
|
|
||||||
|
copy(origin, destination)
|
||||||
|
|
||||||
|
# creating both compute's partitions in the system
|
||||||
|
bash.run_command(
|
||||||
|
'sudo qemu-img create -f qcow2 {0}/{1}-0.img {2}G'.format(
|
||||||
|
libvirt_images_path, compute, compute_partition_a),
|
||||||
|
raise_exception=True)
|
||||||
|
bash.run_command(
|
||||||
|
'sudo qemu-img create -f qcow2 {0}/{1}-1.img {2}G'.format(
|
||||||
|
libvirt_images_path, compute, compute_partition_b),
|
||||||
|
raise_exception=True)
|
||||||
|
|
||||||
|
# modifying xml compute parameters
|
||||||
|
bash.run_command(
|
||||||
|
'sed -i -e "s,NAME,{0}," '
|
||||||
|
'-e "s,UNIT,MiB," '
|
||||||
|
'-e "s,MEMORY,{1}," '
|
||||||
|
'-e "s,CORES,{2}," '
|
||||||
|
'-e "s,destroy,restart," '
|
||||||
|
'-e "s,DISK0,{3}/{0}-0.img," '
|
||||||
|
'-e "s,DISK1,{3}/{0}-1.img," '
|
||||||
|
'{4}/vms/{0}.xml'.format(compute, compute_memory,
|
||||||
|
compute_system_cores, libvirt_images_path, THIS_PATH),
|
||||||
|
raise_exception=True)
|
||||||
|
|
||||||
|
# creating the computes according to the XML, the following command
|
||||||
|
# create a domain but it does not start it and makes it persistent
|
||||||
|
# even after shutdown
|
||||||
|
bash.run_command('sudo virsh define {0}/vms/{1}.xml'.format(
|
||||||
|
THIS_PATH, compute))
|
||||||
|
|
||||||
|
if 'Storages' in configurations:
|
||||||
|
for storage, values in configurations.get('Storages').items():
|
||||||
|
# iterating over the storage
|
||||||
|
storage_partition_a = int(values.get('partition_a'))
|
||||||
|
storage_partition_b = int(values.get('partition_b'))
|
||||||
|
storage_memory = int(values.get('memory_size'))
|
||||||
|
storage_system_cores = int(values.get('system_cores'))
|
||||||
|
|
||||||
|
# copy the storage.xml to vms folder
|
||||||
|
origin = os.path.join(THIS_PATH, 'storage.xml')
|
||||||
|
destination = os.path.join(THIS_PATH,
|
||||||
|
'vms', '{}.xml'.format(storage))
|
||||||
|
|
||||||
|
copy(origin, destination)
|
||||||
|
|
||||||
|
# creating both storage's partitions in the system
|
||||||
|
bash.run_command(
|
||||||
|
'sudo qemu-img create -f qcow2 {0}/{1}-0.img {2}G'.format(
|
||||||
|
libvirt_images_path, storage, storage_partition_a),
|
||||||
|
raise_exception=True)
|
||||||
|
bash.run_command(
|
||||||
|
'sudo qemu-img create -f qcow2 {0}/{1}-1.img {2}G'.format(
|
||||||
|
libvirt_images_path, storage, storage_partition_b),
|
||||||
|
raise_exception=True)
|
||||||
|
|
||||||
|
# modifying xml storage parameters
|
||||||
|
bash.run_command(
|
||||||
|
'sed -i -e "s,NAME,{0}," '
|
||||||
|
'-e "s,UNIT,MiB," '
|
||||||
|
'-e "s,MEMORY,{1}," '
|
||||||
|
'-e "s,CORES,{2}," '
|
||||||
|
'-e "s,destroy,restart," '
|
||||||
|
'-e "s,DISK0,{3}/{0}-0.img," '
|
||||||
|
'-e "s,DISK1,{3}/{0}-1.img," '
|
||||||
|
'{4}/vms/{0}.xml'.format(storage, storage_memory,
|
||||||
|
storage_system_cores, libvirt_images_path, THIS_PATH),
|
||||||
|
raise_exception=True)
|
||||||
|
|
||||||
|
# creating the storage according to the XML, the following command
|
||||||
|
# create a domain but it does not start it and makes it persistent
|
||||||
|
# even after shutdown
|
||||||
|
bash.run_command('sudo virsh define {0}/vms/{1}.xml'.format(
|
||||||
|
THIS_PATH, storage))
|
||||||
|
|
||||||
|
# opening the graphical interface
|
||||||
|
if bash.is_process_running('virt-manager'):
|
||||||
|
# in order that virt-manager takes the new configurations from the yaml
|
||||||
|
# file, is needed to kill it and start again.
|
||||||
|
LOG.info('Virtual Machine Manager is active, killing it ...')
|
||||||
|
bash.run_command('sudo kill -9 $(pgrep -x virt-manager)',
|
||||||
|
raise_exception=True)
|
||||||
|
|
||||||
|
# opening Virtual Machine Manager
|
||||||
|
bash.run_command('sudo virt-manager', raise_exception=True)
|
||||||
|
# opening the controller console
|
||||||
|
bash.run_command('virt-manager -c qemu:///system --show-domain-console '
|
||||||
|
'controller-0', raise_exception=True)
|
||||||
|
exit_dict_status(0)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_qemu(iso_file, configuration_file):
|
||||||
|
"""Setup StarlingX
|
||||||
|
|
||||||
|
The aim of this function is to setup StarlingX in a smart way in order
|
||||||
|
to avoid configuration issues.
|
||||||
|
|
||||||
|
:param iso_file: the iso file to be configured in the controller(s).
|
||||||
|
:param configuration_file: the yaml configuration file.
|
||||||
|
"""
|
||||||
|
# before to run anything, KVM needs to be checked it this is present in the
|
||||||
|
# current host
|
||||||
|
check_kernel_virtualization()
|
||||||
|
|
||||||
|
# check the host requirements
|
||||||
|
check_preconditions()
|
||||||
|
|
||||||
|
# loading all the configurations from yaml file
|
||||||
|
configurations = yaml.safe_load(open(configuration_file))
|
||||||
|
|
||||||
|
# fixme(Humberto): check_system_resources is commented out due
|
||||||
|
# check is giving problems when configuring an instance on qemu virtual
|
||||||
|
# machine, for now this will be commented until more investigation is done
|
||||||
|
|
||||||
|
# this part will check the values given in the yaml
|
||||||
|
# check_system_resources(configurations)
|
||||||
|
|
||||||
|
# setting the controller/computes nodes
|
||||||
|
setup_controller_computes(iso_file, configurations)
|
||||||
|
|
||||||
|
|
||||||
|
def arguments():
|
||||||
|
"""Provides a set of arguments
|
||||||
|
|
||||||
|
Defined arguments must be specified in this function in order to interact
|
||||||
|
with the others functions in this module.
|
||||||
|
"""
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
formatter_class=RawDescriptionHelpFormatter, description='''
|
||||||
|
Program description:
|
||||||
|
This is a tool for setup virtual environments with libvirt/Qemu in the host.
|
||||||
|
maintainer : humberto.i.perez.rodriguez@intel.com''',
|
||||||
|
epilog='StarlingX |https://opendev.org/starlingx/test/',
|
||||||
|
usage='%(prog)s [options]')
|
||||||
|
group_mandatory = parser.add_argument_group('mandatory arguments')
|
||||||
|
group_mandatory.add_argument(
|
||||||
|
'-i', '--iso', dest='iso', required=True,
|
||||||
|
help='the iso file to be setup in the controller')
|
||||||
|
parser.add_argument(
|
||||||
|
'-c', '--configuration', dest='configuration',
|
||||||
|
help='the Qemu configuration file in yaml format. The default '
|
||||||
|
'configuration file is qemu_setup.yaml in this folder')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# checks if the iso file given exists
|
||||||
|
if not os.path.isfile(args.iso):
|
||||||
|
print('{0}: does not exists, please verify it'.format(args.iso))
|
||||||
|
exit_dict_status(1)
|
||||||
|
|
||||||
|
# checks if the configuration exists
|
||||||
|
configuration_file = os.path.join(THIS_PATH, 'qemu_setup.yaml')
|
||||||
|
if args.configuration:
|
||||||
|
configuration_file = args.configuration
|
||||||
|
|
||||||
|
if not os.path.exists(configuration_file):
|
||||||
|
print('{0}: does not exists, please verify it'.format(
|
||||||
|
configuration_file))
|
||||||
|
exit_dict_status(1)
|
||||||
|
|
||||||
|
setup_qemu(args.iso, configuration_file)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
arguments()
|
|
@ -0,0 +1,32 @@
|
||||||
|
configuration_0:
|
||||||
|
controller-0:
|
||||||
|
controller_0_partition_a: 200
|
||||||
|
controller_0_partition_b: 200
|
||||||
|
controller_0_memory_size: 10240
|
||||||
|
controller_0_system_cores: 4
|
||||||
|
controller-0-compute-0:
|
||||||
|
controller_0_compute_0_partition_a: 200
|
||||||
|
controller_0_compute_0_partition_b: 200
|
||||||
|
controller_0_compute_0_memory_size: 16384
|
||||||
|
controller_0_compute_0_system_cores: 4
|
||||||
|
controller-0-compute-1:
|
||||||
|
controller_0_compute_1_partition_a: 200
|
||||||
|
controller_0_compute_1_partition_b: 200
|
||||||
|
controller_0_compute_1_memory_size: 16384
|
||||||
|
controller_0_compute_1_system_cores: 4
|
||||||
|
configuration_1:
|
||||||
|
controller-1:
|
||||||
|
controller_1_partition_a: 200
|
||||||
|
controller_1_partition_b: 200
|
||||||
|
controller_1_memory_size: 10240
|
||||||
|
controller_1_system_cores: 4
|
||||||
|
controller-1-compute-0:
|
||||||
|
controller_1_compute_0_partition_a: 200
|
||||||
|
controller_1_compute_0_partition_b: 200
|
||||||
|
controller_1_compute_0_memory_size: 3072
|
||||||
|
controller_1_compute_0_system_cores: 2
|
||||||
|
general_system_configurations:
|
||||||
|
os_system_memory: 1024
|
||||||
|
disk_space_allocated_to_os: 20
|
||||||
|
os_system_cores: 2
|
||||||
|
default_mount_point: '/'
|
|
@ -0,0 +1,99 @@
|
||||||
|
<domain type='kvm' id='164'>
|
||||||
|
<name>NAME</name>
|
||||||
|
<memory unit='UNIT'>MEMORY</memory>
|
||||||
|
<currentMemory unit='UNIT'>MEMORY</currentMemory>
|
||||||
|
<vcpu placement='static'>CORES</vcpu>
|
||||||
|
<resource>
|
||||||
|
<partition>/machine</partition>
|
||||||
|
</resource>
|
||||||
|
<os>
|
||||||
|
<type arch='x86_64' machine='pc'>hvm</type>
|
||||||
|
</os>
|
||||||
|
<features>
|
||||||
|
<acpi/>
|
||||||
|
<apic/>
|
||||||
|
<pae/>
|
||||||
|
</features>
|
||||||
|
<cpu match='exact'>
|
||||||
|
<model fallback='forbid'>Nehalem</model>
|
||||||
|
<topology sockets='1' cores='CORES' 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='sdd' bus='sata'/>
|
||||||
|
</disk>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<source bridge='stxbr1'/>
|
||||||
|
<target dev='vnet0'/>
|
||||||
|
<model type='e1000'/>
|
||||||
|
<alias name='net0'/>
|
||||||
|
</interface>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<source bridge='stxbr2'/>
|
||||||
|
<target dev='vnet1'/>
|
||||||
|
<model type='e1000'/>
|
||||||
|
<boot order='2'/>
|
||||||
|
<alias name='net1'/>
|
||||||
|
</interface>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<source bridge='stxbr3'/>
|
||||||
|
<target dev='vnet2'/>
|
||||||
|
<model type='virtio'/>
|
||||||
|
<alias name='net2'/>
|
||||||
|
</interface>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<source bridge='stxbr4'/>
|
||||||
|
<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'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
|
||||||
|
</video>
|
||||||
|
<memballoon model='virtio'>
|
||||||
|
<alias name='balloon0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
|
||||||
|
</memballoon>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
<domain type='kvm' id='187'>
|
||||||
|
<name>NAME</name>
|
||||||
|
<memory unit='UNIT'>MEMORY</memory>
|
||||||
|
<currentMemory unit='UNIT'>MEMORY</currentMemory>
|
||||||
|
<vcpu placement='static'>CORES</vcpu>
|
||||||
|
<resource>
|
||||||
|
<partition>/machine</partition>
|
||||||
|
</resource>
|
||||||
|
<os>
|
||||||
|
<type arch='x86_64' machine='pc'>hvm</type>
|
||||||
|
</os>
|
||||||
|
<features>
|
||||||
|
<acpi/>
|
||||||
|
<apic/>
|
||||||
|
<pae/>
|
||||||
|
</features>
|
||||||
|
<cpu match='exact'>
|
||||||
|
<model fallback='forbid'>Nehalem</model>
|
||||||
|
<topology sockets='1' cores='CORES' 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='stxbr1'/>
|
||||||
|
<target dev='vnet8'/>
|
||||||
|
<model type='e1000'/>
|
||||||
|
<alias name='net0'/>
|
||||||
|
</interface>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<source bridge='stxbr2'/>
|
||||||
|
<target dev='vnet9'/>
|
||||||
|
<model type='e1000'/>
|
||||||
|
<boot order='2'/>
|
||||||
|
<alias name='net1'/>
|
||||||
|
</interface>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<source bridge='stxbr3'/>
|
||||||
|
<target dev='vnet10'/>
|
||||||
|
<model type='virtio'/>
|
||||||
|
<alias name='net2'/>
|
||||||
|
</interface>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<source bridge='stxbr4'/>
|
||||||
|
<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'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
|
||||||
|
</video>
|
||||||
|
<memballoon model='virtio'>
|
||||||
|
<alias name='balloon0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
|
||||||
|
</memballoon>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
|
@ -0,0 +1,47 @@
|
||||||
|
nodes:
|
||||||
|
controller-0:
|
||||||
|
name: controller-0
|
||||||
|
personality: controller
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: psw
|
||||||
|
pxe_nic_mac:
|
||||||
|
installation_ip:
|
||||||
|
controller-1:
|
||||||
|
name: controller-1
|
||||||
|
personality: controller
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: psw
|
||||||
|
pxe_nic_mac:
|
||||||
|
compute-0:
|
||||||
|
name: compute-0
|
||||||
|
personality: worker
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: psw
|
||||||
|
pxe_nic_mac:
|
||||||
|
compute-1:
|
||||||
|
name: compute-1
|
||||||
|
personality: worker
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: psw
|
||||||
|
pxe_nic_mac:
|
||||||
|
storage-0:
|
||||||
|
name: storage-0
|
||||||
|
personality: storage
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: psw
|
||||||
|
pxe_nic_mac:
|
||||||
|
storage-1:
|
||||||
|
name: storage-1
|
||||||
|
personality: storage
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: psw
|
||||||
|
pxe_nic_mac:
|
||||||
|
extra_data_if_needed:
|
||||||
|
value1:
|
||||||
|
value2:
|
|
@ -0,0 +1,18 @@
|
||||||
|
nodes:
|
||||||
|
controller-0:
|
||||||
|
name: controller-0
|
||||||
|
personality: controller
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: pswd
|
||||||
|
pxe_nic_mac:
|
||||||
|
installation_ip:
|
||||||
|
oam_if:
|
||||||
|
mgmt_if:
|
||||||
|
controller-1:
|
||||||
|
name: controller-1
|
||||||
|
personality: controller
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: pswd
|
||||||
|
pxe_nic_mac:
|
|
@ -0,0 +1,32 @@
|
||||||
|
nodes:
|
||||||
|
controller-0:
|
||||||
|
name: controller-0
|
||||||
|
personality: controller
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: pswd
|
||||||
|
pxe_nic_mac:
|
||||||
|
installation_ip:
|
||||||
|
oam_if:
|
||||||
|
mgmt_if:
|
||||||
|
controller-1:
|
||||||
|
name: controller-1
|
||||||
|
personality: controller
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: pswd
|
||||||
|
pxe_nic_mac:
|
||||||
|
compute-0:
|
||||||
|
name: compute-0
|
||||||
|
personality: worker
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: pswd
|
||||||
|
pxe_nic_mac:
|
||||||
|
compute-1:
|
||||||
|
name: compute-1
|
||||||
|
personality: worker
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: pswd
|
||||||
|
pxe_nic_mac:
|
|
@ -0,0 +1,46 @@
|
||||||
|
nodes:
|
||||||
|
controller-0:
|
||||||
|
name: controller-0
|
||||||
|
personality: controller
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: pswd
|
||||||
|
pxe_nic_mac:
|
||||||
|
installation_ip:
|
||||||
|
oam_if:
|
||||||
|
mgmt_if:
|
||||||
|
controller-1:
|
||||||
|
name: controller-1
|
||||||
|
personality: controller
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: pswd
|
||||||
|
pxe_nic_mac:
|
||||||
|
compute-0:
|
||||||
|
name: compute-0
|
||||||
|
personality: worker
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: pswd
|
||||||
|
pxe_nic_mac:
|
||||||
|
compute-1:
|
||||||
|
name: compute-1
|
||||||
|
personality: worker
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: pswd
|
||||||
|
pxe_nic_mac:
|
||||||
|
storage-0:
|
||||||
|
name: storage-0
|
||||||
|
personality: storage
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: pswd
|
||||||
|
pxe_nic_mac:
|
||||||
|
storage-1:
|
||||||
|
name: storage-1
|
||||||
|
personality: storage
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: pswd
|
||||||
|
pxe_nic_mac:
|
|
@ -0,0 +1,11 @@
|
||||||
|
nodes:
|
||||||
|
controller-0:
|
||||||
|
name: controller-0
|
||||||
|
personality: controller
|
||||||
|
bmc_ip:
|
||||||
|
bmc_user: usr
|
||||||
|
bmc_pswd: pswd
|
||||||
|
pxe_nic_mac:
|
||||||
|
installation_ip:
|
||||||
|
oam_if:
|
||||||
|
mgmt_if:
|
|
@ -0,0 +1,14 @@
|
||||||
|
watchdog
|
||||||
|
robotframework==3.1.1
|
||||||
|
robotframework-debuglibrary
|
||||||
|
robotframework-seleniumlibrary
|
||||||
|
robotframework-sshlibrary
|
||||||
|
pexpect
|
||||||
|
PyYaml
|
||||||
|
netifaces
|
||||||
|
bash
|
||||||
|
elevate
|
||||||
|
ifparser
|
||||||
|
pynetlinux
|
||||||
|
kmodpy
|
||||||
|
psutil
|
|
@ -0,0 +1,9 @@
|
||||||
|
flake8==2.6.2
|
||||||
|
hacking
|
||||||
|
flake8-import-order
|
||||||
|
mock
|
||||||
|
coverage
|
||||||
|
pylint
|
||||||
|
pep8-naming
|
||||||
|
ipdb
|
||||||
|
ipython
|
Loading…
Reference in New Issue