X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=modules%2Fopnfv%2Fdeployment%2Fmanager.py;h=2b5aedbc7e3e4c4d6d712227dd60081ca93d5c66;hb=55016b8d48ff3871dc08bf41224b9986da3b5723;hp=43a79488b8829ee87421a18696b41313eeb88d42;hpb=a6e69f43e9d791cbe00d9b6fb53fed7dcb3fd742;p=releng.git diff --git a/modules/opnfv/deployment/manager.py b/modules/opnfv/deployment/manager.py index 43a79488b..2b5aedbc7 100644 --- a/modules/opnfv/deployment/manager.py +++ b/modules/opnfv/deployment/manager.py @@ -27,7 +27,7 @@ class Deployment(object): status, openstack_version, sdn_controller, - nodes=[]): + nodes=None): self.deployment_info = { 'installer': installer, @@ -95,6 +95,7 @@ class Deployment(object): class Role(): + INSTALLER = 'installer' CONTROLLER = 'controller' COMPUTE = 'compute' ODL = 'opendaylight' @@ -107,6 +108,7 @@ class NodeStatus(): STATUS_OFFLINE = 'offline' STATUS_ERROR = 'error' STATUS_UNUSED = 'unused' + STATUS_UNKNOWN = 'unknown' class Node(object): @@ -116,9 +118,9 @@ class Node(object): ip, name, status, - roles=[], + roles=None, ssh_client=None, - info={}): + info=None): self.id = id self.ip = ip self.name = name @@ -127,6 +129,16 @@ class Node(object): self.roles = roles self.info = info + self.cpu_info = 'unknown' + self.memory = 'unknown' + self.ovs = 'unknown' + + if ssh_client and Role.INSTALLER not in self.roles: + sys_info = self.get_system_info() + self.cpu_info = sys_info['cpu_info'] + self.memory = sys_info['memory'] + self.ovs = self.get_ovs_info() + def get_file(self, src, dest): ''' SCP file from a node @@ -164,13 +176,15 @@ class Node(object): Run command remotely on a node ''' if self.status is not NodeStatus.STATUS_OK: - logger.error("The node %s is not active" % self.ip) + logger.error( + "Error running command %s. The node %s is not active" + % (cmd, self.ip)) return None _, stdout, stderr = (self.ssh_client.exec_command(cmd)) error = stderr.readlines() if len(error) > 0: logger.error("error %s" % ''.join(error)) - return error + return None output = ''.join(stdout.readlines()).rstrip() return output @@ -184,53 +198,97 @@ class Node(object): 'name': self.name, 'status': self.status, 'roles': self.roles, + 'cpu_info': self.cpu_info, + 'memory': self.memory, + 'ovs': self.ovs, 'info': self.info } - def get_attribute(self, attribute): + def is_active(self): ''' - Returns an attribute given the name + Returns if the node is active ''' - return self.get_dict()[attribute] + if self.status == NodeStatus.STATUS_OK: + return True + return False def is_controller(self): ''' Returns if the node is a controller ''' - if 'controller' in self.roles: - return True - return False + return Role.CONTROLLER in self.roles def is_compute(self): ''' Returns if the node is a compute ''' - if 'compute' in self.roles: - return True - return False + return Role.COMPUTE in self.roles + + def is_odl(self): + ''' + Returns if the node is an opendaylight + ''' + return Role.ODL in self.roles + + def is_onos(self): + ''' + Returns if the node is an ONOS + ''' + return Role.ONOS in self.roles def get_ovs_info(self): ''' Returns the ovs version installed ''' - cmd = "ovs-vsctl --version|head -1| sed 's/^.*) //'" - return self.run_cmd(cmd) + if self.is_active(): + cmd = "ovs-vsctl --version 2>/dev/null|head -1| sed 's/^.*) //'" + return self.run_cmd(cmd) or None + return None + + def get_system_info(self): + ''' + Returns system information + ''' + cmd = 'grep MemTotal /proc/meminfo' + memory = self.run_cmd(cmd).partition('MemTotal:')[-1].strip().encode() + + cpu_info = {} + cmd = 'lscpu' + result = self.run_cmd(cmd) + for line in result.splitlines(): + if line.startswith('CPU(s)'): + cpu_info['num_cpus'] = line.split(' ')[-1].encode() + elif line.startswith('Thread(s) per core'): + cpu_info['threads/core'] = line.split(' ')[-1].encode() + elif line.startswith('Core(s) per socket'): + cpu_info['cores/socket'] = line.split(' ')[-1].encode() + elif line.startswith('Model name'): + cpu_info['model'] = line.partition( + 'Model name:')[-1].strip().encode() + elif line.startswith('Architecture'): + cpu_info['arch'] = line.split(' ')[-1].encode() + + return {'memory': memory, 'cpu_info': cpu_info} def __str__(self): return ''' - name: {name} - id: {id} - ip: {ip} - status: {status} - roles: {roles} - ovs: {ovs} - info: {info}'''.format(name=self.name, - id=self.id, - ip=self.ip, - status=self.status, - roles=self.roles, - ovs=self.get_ovs_info(), - info=self.info) + name: {name} + id: {id} + ip: {ip} + status: {status} + roles: {roles} + cpu: {cpu_info} + memory: {memory} + ovs: {ovs} + info: {info}'''.format(name=self.name, + id=self.id, + ip=self.ip, + status=self.status, + roles=self.roles, + cpu_info=self.cpu_info, + memory=self.memory, + ovs=self.ovs, + info=self.info) class DeploymentHandler(object): @@ -268,7 +326,7 @@ class DeploymentHandler(object): name=installer, status=NodeStatus.STATUS_OK, ssh_client=self.installer_connection, - roles='installer node') + roles=Role.INSTALLER) else: raise Exception( 'Cannot establish connection to the installer node!') @@ -309,6 +367,18 @@ class DeploymentHandler(object): ''' return self.installer_node + def get_arch(self): + ''' + Returns the architecture of the first compute node found + ''' + arch = None + for node in self.nodes: + if node.is_compute(): + arch = node.cpu_info.get('arch', None) + if arch: + break + return arch + def get_deployment_info(self): ''' Returns an object of type Deployment @@ -320,4 +390,4 @@ class DeploymentHandler(object): pod=os.getenv('NODE_NAME', 'Unknown'), openstack_version=self.get_openstack_version(), sdn_controller=self.get_sdn_version(), - nodes=self.get_nodes()) + nodes=self.nodes)