Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- import numa_dict
- import os
- import sys
- import time
- import subprocess
- import string
- from novaclient.v2 import aggregates
- from novaclient.v2 import hosts
- from novaclient.v2 import servers
- from credential_helper import CredentialHelper
- from datetime import datetime
- import novaclient.client as nova_client
- from novaclient import client as nvclient
- from ironic_helper import IronicHelper
- from dracclient import client
- import requests
- from requests.packages.urllib3.exceptions import InsecureRequestWarning
- requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
- home_dir = os.path.expanduser('~')
- DELL_AGGREGATE_METADATA = {"Dell_Aggr": {'pinned': 'False' , 'hugepages': 'False'}}
- # Dell nfv configuration global values
- undercloudrc_file_name = "stackrc"
- UC_USERNAME = UC_PASSWORD = UC_PROJECT_ID = UC_AUTH_URL = ''
- class ConfigOvercloud(object):
- """
- Description: Class responsible for overcloud configurations.
- """
- # These are not parameters. So defined as class variables
- ironic = IronicHelper()
- ironic_client = ironic.get_ironic_client()
- nodes = ironic_client.node.list()
- get_drac_credentail = CredentialHelper()
- def __init__(self, overcloud_name):
- self.overcloud_name = overcloud_name
- self.source_stackrc = "source ~/stackrc;"
- self.overcloudrc = "source " + home_dir + "/" + self.overcloud_name + "rc;"
- @classmethod
- def get_undercloud_details(cls):
- try:
- global UC_USERNAME, UC_PASSWORD, UC_PROJECT_ID, UC_AUTH_URL
- file_path = home_dir + '/' + undercloudrc_file_name
- if not os.path.isfile(file_path):
- raise Exception("The Undercloud rc file does not exist {}".format(file_path))
- with open(file_path) as rc_file:
- for line in rc_file:
- if 'OS_USERNAME=' in line:
- UC_USERNAME = line.split('OS_USERNAME=')[1].strip("\n").strip("'")
- elif 'OS_PASSWORD=' in line:
- cmd = 'sudo hiera admin_password'
- proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- output = proc.communicate()
- output = output[0]
- UC_PASSWORD = output[:-1]
- elif 'OS_TENANT_NAME=' in line:
- UC_PROJECT_ID = line.split('OS_TENANT_NAME=')[1].strip("\n").strip("'")
- elif 'OS_AUTH_URL=' in line:
- UC_AUTH_URL = line.split('OS_AUTH_URL=')[1].strip("\n").strip("'")
- except Exception as error:
- message = "Exception {}: {}".format(type(error).__name__, str(error))
- print "{}".format(message)
- raise Exception("Failed to get undercloud details from the undercloud rc file {}".format(file_path))
- @classmethod
- def get_overcloud_details(cls, overcloud_name):
- try:
- global UC_USERNAME, UC_PASSWORD, UC_PROJECT_ID, UC_AUTH_URL
- file_path = home_dir + '/' + overcloud_name + "rc"
- if not os.path.isfile(file_path):
- raise Exception("The Overcloud rc file does not exist {}".format(file_path))
- with open(file_path) as rc_file:
- for line in rc_file:
- if 'OS_USERNAME' in line:
- UC_USERNAME = line.split('OS_USERNAME=')[1].strip("\n").strip("'")
- elif 'OS_PASSWORD' in line:
- UC_PASSWORD = line.split('OS_PASSWORD=')[1].strip("\n").strip("'")
- elif 'OS_PROJECT_NAME' in line:
- UC_PROJECT_ID = line.split('OS_PROJECT_NAME=')[1].strip("\n").strip("'")
- elif 'OS_AUTH_URL' in line:
- UC_AUTH_URL = line.split('OS_AUTH_URL=')[1].strip("\n").strip("'")
- except Exception as error:
- message = "Exception {}: {}".format(type(error).__name__, str(error))
- print "{}".format(message)
- raise Exception("Failed to get overcloud details from the overcloud rc file {}".format(file_path))
- def reboot_dell_nfv_nodes(self):
- try:
- print "Rebooting dellnfv nodes"
- ConfigOvercloud.get_undercloud_details()
- # Create servers object
- nova = nvclient.Client(2, UC_USERNAME, UC_PASSWORD, UC_PROJECT_ID, UC_AUTH_URL)
- server_obj = servers.ServerManager(nova)
- for server in server_obj.list():
- if "dell-nfv-compute" in str(server):
- server_obj.reboot(server)
- except Exception as error:
- message = "Exception {}: {}".format(type(error).__name__, str(error))
- print "Failed to reboot dell nfv nodes with error {}".format(message)
- @classmethod
- def calculate_hostos_cpus(self,number_of_host_os_cpu):
- try:
- cpu_count_list = []
- for node in ConfigOvercloud.nodes:
- # for every compute node get the corresponding drac credentials to fetch the cpu details
- node_uuid = node.uuid
- node_details=ConfigOvercloud.ironic_client.node.get(node_uuid)
- node_type=node_details.properties['capabilities'].split(',')[0].split(':')[1]
- if 'dell-nfv-compute' not in node_type:
- # filter for getting compute node
- continue
- drac_ip, drac_user, drac_password = ConfigOvercloud.get_drac_credentail.get_drac_creds(ConfigOvercloud.ironic_client, node_uuid)
- stor = client.DRACClient(drac_ip, drac_user, drac_password)
- sockets = stor.list_cpus() # cpu socket information for every compute node
- cpu_count = 0
- for socket in sockets :
- if socket.ht_enabled :
- cpu_count += socket.cores*2
- else:
- print "Hyperthreading is not enabled in " + str(node_uuid) + ". So exiting the code execution."
- sys.exit()
- cpu_count_list.append(cpu_count)
- min_cpu_count = min(cpu_count_list)
- if min_cpu_count not in [40,48,56,64,72] :
- print "CPU count should be one of these values : [40,48,56,64,72]. But number of cpu is " + str(min_cpu_count)
- sys.exit()
- number_of_host_os_cpu=int(number_of_host_os_cpu)
- print "Host OS CPUs : {}".format(numa_dict.numa_info[min_cpu_count][number_of_host_os_cpu]["List of host os cpu"])
- print "vCPUs : {}".format(numa_dict.numa_info[min_cpu_count][number_of_host_os_cpu]["List of vcpu"])
- return numa_dict.numa_info[min_cpu_count][number_of_host_os_cpu]["List of vcpu"]
- except Exception as error:
- message = "Exception {}: {}".format(type(error).__name__, str(error))
- print "Failed to calculate Numa Vcpu list {}".format(message)
- @classmethod
- def calculate_hugepage_count(self,hugepage_size):
- try:
- pages = []
- for node in ConfigOvercloud.nodes:
- node_uuid = node.uuid # uuid of a node
- node_details = ConfigOvercloud.ironic_client.node.get(node_uuid) # details of a node
- memory_count = node_details.properties['memory_mb']
- node_properties_capabilities = node_details.properties['capabilities'].split(',')[0].split(':')[1]
- if 'dell-nfv-compute' in node_properties_capabilities:
- if hugepage_size == "2MB":
- pages.append((memory_count / 2))
- if hugepage_size == "1GB":
- pages.append((memory_count / 1024))
- return min(pages)
- except Exception as error:
- message = "Exception {}: {}".format(type(error).__name__, str(error))
- print "Failed to calculate hugepage count {}".format(message)
- def edit_dellnfv_environment_file(self, enable_hugepage, enable_numa, hugepage_size, hostos_cpu_count, dell_nfv_compute_count=0):
- try:
- print "Editing dellnfv environment file"
- file_path = home_dir + '/pilot/templates/overcloud/dellnfv_environment.yaml'
- if not os.path.isfile(file_path):
- raise Exception("The dellnfv_environment.yaml file does not exist")
- cmds = ['sed -i "s|dellnfv::hugepages::enable:.*|dellnfv::hugepages::enable: ' + str(
- enable_hugepage) + '|" ' + file_path,
- 'sed -i "s|dellnfv::numa::enable:.*|dellnfv::numa::enable: ' + str(enable_numa) + '|" ' + file_path]
- if dell_nfv_compute_count > 0:
- cmds.append('sed -i "s|DellNfvComputeCount:.*|DellNfvComputeCount: ' + str(
- dell_nfv_compute_count) + '|" ' + file_path)
- if enable_hugepage:
- hugepage_number = ConfigOvercloud.calculate_hugepage_count(hugepage_size)
- cmds.append(
- 'sed -i "s|dellnfv::hugepages::hugepagesize:.*|dellnfv::hugepages::hugepagesize: ' + hugepage_size[
- 0:-1] + '|" ' + file_path)
- cmds.append('sed -i "s|dellnfv::hugepages::hugepagecount:.*|dellnfv::hugepages::hugepagecount: ' + str(
- hugepage_number) + '|" ' + file_path)
- if enable_numa:
- vcpu_pin_set = ConfigOvercloud.calculate_hostos_cpus(hostos_cpu_count)
- cmds.append(
- 'sed -i "s|dellnfv::numa::vcpu_pin_set:.*|dellnfv::numa::vcpu_pin_set: \\\\\\\\\\"' + vcpu_pin_set + '\\\\\\\\\\"|" ' + file_path)
- for cmd in cmds:
- status = os.system(cmd)
- print "cmd: {}".format(cmd)
- if status != 0:
- raise Exception("Failed to execute the command {} with error code {}".format(cmd, status))
- except Exception as error:
- message = "Exception {}: {}".format(type(error).__name__, str(error))
- print
- "{}".format(message)
- raise Exception("Failed to modify the dellnfv_environment.yaml at location {}".format(file_path))
- def get_dell_nfv_compute_nodes_hostnames(self, nova):
- try:
- print "Getting dellnfv compute node hostnames"
- # Create host object
- host_obj = hosts.HostManager(nova)
- # Get list of dell nfv nodes
- dell_nfv_hosts = []
- for host in host_obj.list():
- if "dell-nfv-compute" in host.host_name:
- hostname = str(host.host_name)
- dell_nfv_hosts.append(hostname)
- return dell_nfv_hosts
- except Exception as error:
- message = "Exception {}: {}".format(type(error).__name__, str(error))
- print "{}".format(message)
- raise Exception("Failed to get the Dell Nfv Compute nodes.")
- def edit_aggregate_environment_file(self, aggr_name, aggr_metadata, hostname_list):
- print "Editing create aggregate environment file"
- file_path = home_dir + '/pilot/templates/overcloud/create_aggregate_environment.yaml'
- if not os.path.isfile(file_path):
- raise Exception("The create_aggregate_environment.yaml file does not exist")
- cmds = list()
- cmds.append(
- 'sed -i "s|aggregate_name:.*|aggregate_name: ' + str(aggr_name) + '|" ' + file_path)
- cmds.append(
- 'sed -i "s|aggregate_metadata:.*|aggregate_metadata: ' + str(aggr_metadata) + '|" ' + file_path)
- cmds.append(
- 'sed -i "s|hosts:.*|hosts: ' + str(hostname_list) + '|" ' + file_path)
- for cmd in cmds:
- status = os.system(cmd)
- print "cmd: {}".format(cmd)
- if status != 0:
- raise Exception("Failed to execute the command {} with error code {}".format(cmd, status))
- def create_aggregates(self, aggr_name):
- env_opts = " -e ~/pilot/templates/overcloud/create_aggregate_environment.yaml"
- cmd = self.overcloudrc + "openstack stack create " \
- " {}" \
- " --template ~/pilot/templates/overcloud/puppet/services/DellNfv/createaggregate.yaml" \
- " {}" \
- "".format(aggr_name,
- env_opts)
- aggregate_create_status = os.system(cmd)
- if aggregate_create_status == 0:
- print "Aggregate {} created".format(aggr_name)
- else:
- print "Aggregate {} could not be created... Exiting post deployment tasks".format(aggr_name)
- sys.exit(0)
- def set_aggregate_metadata(self):
- try:
- # Get the overcloud details
- ConfigOvercloud.get_overcloud_details(self.overcloud_name)
- # Create nova client object
- nova = nvclient.Client(2, UC_USERNAME, UC_PASSWORD, UC_PROJECT_ID, UC_AUTH_URL)
- aggregate_dict = dict()
- hostname_list = self.get_dell_nfv_compute_nodes_hostnames(nova)
- aggregate_dict.update(DELL_AGGREGATE_METADATA)
- for aggregate_name, aggregate_metadata in aggregate_dict.items():
- self.edit_aggregate_environment_file(aggregate_name, aggregate_metadata, hostname_list)
- self.create_aggregates(aggregate_name)
- except Exception as error:
- message = "Exception {}: {}".format(type(error).__name__, str(error))
- print message
- print "Unable to set aggregate metadata. Exiting post deployment task..."
- sys.exit(0)
- def post_deployment_tasks(self, enable_hugepage, enable_numa, hpg_size):
- try:
- # Reboot all the Dell NFV compute nodes
- self.reboot_dell_nfv_nodes()
- # Wait for 5 mins to let dll nfv nodes boot up
- time.sleep(300)
- print "Initiating post deployment tasks"
- # create aggregate
- self.set_aggregate_metadata()
- except Exception as error:
- message = "Exception {}: {}".format(type(error).__name__, str(error))
- print
- "{}".format(message)
Add Comment
Please, Sign In to add comment