X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=system%2FSubstrate.py;h=cca7b5e8dc9df6bcb942a327fb48610e323a5801;hb=f96f84a81d6b9cba763f9ccee30a51754da074ee;hp=30ac997e24ec630cd4dd8084438789080b6724fd;hpb=f4444d855e421187fbc54a4c6e062548f187285c;p=tests.git diff --git a/system/Substrate.py b/system/Substrate.py index 30ac997..cca7b5e 100644 --- a/system/Substrate.py +++ b/system/Substrate.py @@ -267,7 +267,7 @@ class Box: def hostname_fedora (self,virt=None): result = "%s {"%self.hostname if virt: result += "%s-"%virt - result += "%s"%self.fedora() + result += "%s %s"%(self.fedora(),self.memory()) # too painful to propagate this cleanly global verbose if verbose: @@ -290,6 +290,8 @@ class Box: composite_command += [ "uname", "-r"] composite_command += [ ";" , "echo", Box.separator , ";" ] composite_command += [ "cat" , "/etc/fedora-release" ] + composite_command += [ ";" , "echo", Box.separator , ";" ] + composite_command += [ "grep", "MemTotal", "/proc/meminfo" ] # due to colons and all, this is going wrong on the local box (typically testmaster) # I am reluctant to change TestSsh as it might break all over the place, so @@ -298,7 +300,7 @@ class Box: else: probe_argv=self.test_ssh().actual_argv(composite_command) composite=self.backquote ( probe_argv, trash_err=True ) - self._hostname = self._uptime = self._uname = self._fedora = "** Unknown **" + self._hostname = self._uptime = self._uname = self._fedora = self._memory = "** Unknown **" if not composite: print "root@%s unreachable"%self.hostname self._probed='' @@ -306,10 +308,15 @@ class Box: try: pieces = composite.split(Box.separator) pieces = [ x.strip() for x in pieces ] - [self._hostname, self._uptime, self._uname, self._fedora] = pieces + # get raw data + [hostname, uptime, uname, fedora, memory] = pieces # customize - self._uptime = ', '.join([ x.strip() for x in self._uptime.split(',')[2:]]) - self._fedora = self._fedora.replace("Fedora release ","f").split(" ")[0] + self._hostname = hostname + self._uptime = ', '.join([ x.strip() for x in uptime.split(',')[2:]]).replace("load average","load") + self._uname = uname + self._fedora = fedora.replace("Fedora release ","f").split(" ")[0] + # translate into Mb + self._memory = int(memory.split()[1])/(1024) except: import traceback print 'BEG issue with pieces',pieces @@ -331,6 +338,10 @@ class Box: self.probe() if hasattr(self,'_fedora') and self._fedora: return self._fedora return '*unprobed* fedora' + def memory(self): + self.probe() + if hasattr(self,'_memory') and self._memory: return "%s Mb"%self._memory + return '*unprobed* memory' def run(self,argv,message=None,trash_err=False,dry_run=False): if dry_run: @@ -610,6 +621,9 @@ class QemuBox (Box): return self.qemu_instances.append(QemuInstance(nodename,pid,self)) + def node_names (self): + return [ qi.nodename for qi in self.qemu_instances ] + def forget (self, qemu_instance): self.qemu_instances.remove(qemu_instance) @@ -713,9 +727,13 @@ class QemuBox (Box): timestamp=int(timestamp) q=self.qemu_instance_by_nodename_buildname(nodename,buildname) if not q: - print 'WARNING zombie qemu',self.hostname,ts_line - print '... was expecting (',short_hostname(nodename),buildname,') in',\ - [ (short_hostname(i.nodename),i.buildname) for i in self.qemu_instances ] + # this warning corresponds to qemu instances that were not killed properly + # and that have a dangling qemu.pid - and not even all of them as they need + # to be attached to a build that has a node running... + # it is more confusing than helpful, so let's just trash it + #print 'WARNING zombie qemu',self.hostname,ts_line + #print '... was expecting (',short_hostname(nodename),buildname,') in',\ + # [ (short_hostname(i.nodename),i.buildname) for i in self.qemu_instances ] continue q.set_timestamp(timestamp) except: print 'WARNING, could not parse ts line',ts_line @@ -1069,12 +1087,14 @@ class Substrate: 'name': plc_name, 'vservername':vservername, 'vserverip':vplc_ip, - 'PLC_DB_HOST':vplc_hostname, - 'PLC_API_HOST':vplc_hostname, - 'PLC_BOOT_HOST':vplc_hostname, - 'PLC_WWW_HOST':vplc_hostname, - 'PLC_NET_DNS1' : self.network_settings() [ 'interface_fields:dns1' ], - 'PLC_NET_DNS2' : self.network_settings() [ 'interface_fields:dns2' ], +# 'settings': { + 'settings:PLC_DB_HOST':vplc_hostname, + 'settings:PLC_API_HOST':vplc_hostname, + 'settings:PLC_BOOT_HOST':vplc_hostname, + 'settings:PLC_WWW_HOST':vplc_hostname, + 'settings:PLC_NET_DNS1' : self.network_settings() [ 'interface_fields:dns1' ], + 'settings:PLC_NET_DNS2' : self.network_settings() [ 'interface_fields:dns2' ], +# } } ) ] } @@ -1163,11 +1183,11 @@ class Substrate: def localize_sfa_rspec (self,plc,options): - plc['sfa']['SFA_REGISTRY_HOST'] = plc['PLC_DB_HOST'] - plc['sfa']['SFA_AGGREGATE_HOST'] = plc['PLC_DB_HOST'] - plc['sfa']['SFA_SM_HOST'] = plc['PLC_DB_HOST'] - plc['sfa']['SFA_DB_HOST'] = plc['PLC_DB_HOST'] - plc['sfa']['SFA_PLC_URL'] = 'https://' + plc['PLC_API_HOST'] + ':443/PLCAPI/' + plc['sfa']['settings']['SFA_REGISTRY_HOST'] = plc['settings']['PLC_DB_HOST'] + plc['sfa']['settings']['SFA_AGGREGATE_HOST'] = plc['settings']['PLC_DB_HOST'] + plc['sfa']['settings']['SFA_SM_HOST'] = plc['settings']['PLC_DB_HOST'] + plc['sfa']['settings']['SFA_DB_HOST'] = plc['settings']['PLC_DB_HOST'] + plc['sfa']['settings']['SFA_PLC_URL'] = 'https://%s:443/PLCAPI/' % plc['settings']['PLC_API_HOST'] return plc #################### release: @@ -1186,24 +1206,52 @@ class Substrate: print "Could not find box %s"%boxname return None - def list_boxes(self,box_or_names): - print 'Sensing', + # deal with the mix of boxes and names and stores the current focus + # as a list of Box instances in self.focus_all + def normalize (self, box_or_names): + self.focus_all=[] for box in box_or_names: if not isinstance(box,Box): box=self.get_box(box) - if not box: continue + if not box: + print 'Warning - could not handle box',box + self.focus_all.append(box) + # elaborate by type + self.focus_build = [ x for x in self.focus_all if isinstance(x,BuildBox) ] + self.focus_plc = [ x for x in self.focus_all if isinstance(x,PlcBox) ] + self.focus_qemu = [ x for x in self.focus_all if isinstance(x,QemuBox) ] + + def list_boxes(self): + print 'Sensing', + for box in self.focus_all: box.sense(self.options) print 'Done' - for box in box_or_names: - if not isinstance(box,Box): box=self.get_box(box) - if not box: continue + for box in self.focus_all: box.list(self.options.verbose) - def reboot_boxes(self,box_or_names): - for box in box_or_names: - if not isinstance(box,Box): box=self.get_box(box) - if not box: continue + def reboot_boxes(self): + for box in self.focus_all: box.reboot(self.options) + def sanity_check (self): + print 'Sanity check' + self.sanity_check_plc() + self.sanity_check_qemu() + + def sanity_check_plc (self): + pass + + def sanity_check_qemu (self): + all_nodes=[] + for box in self.focus_qemu: + all_nodes += box.node_names() + hash={} + for node in all_nodes: + if node not in hash: hash[node]=0 + hash[node]+=1 + for (node,count) in hash.items(): + if count!=1: print 'WARNING - duplicate node',node + + #################### # can be run as a utility to probe/display/manage the local infrastructure def main (self): @@ -1241,5 +1289,10 @@ class Substrate: if not boxes: boxes = self.build_boxes + self.plc_boxes + self.qemu_boxes + [self.test_box] - if self.options.reboot: self.reboot_boxes (boxes) - else: self.list_boxes (boxes) + self.normalize (boxes) + + if self.options.reboot: + self.reboot_boxes () + else: + self.list_boxes () + self.sanity_check ()