X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=system%2FSubstrate.py;h=a6d02e2e1e3e2f69ddfe0f3a24787dc91dae73f4;hb=6f9cfa7ae380b6582f2ef85b39d01399093baf11;hp=d6d54242a735888d4fd136ddeabe5659cdcda5ff;hpb=4297f83e55247a16c587d1aae4205f198d17fd69;p=tests.git diff --git a/system/Substrate.py b/system/Substrate.py index d6d5424..a6d02e2 100644 --- a/system/Substrate.py +++ b/system/Substrate.py @@ -1,6 +1,6 @@ # # Thierry Parmentelat -# Copyright (C) 2010 INRIA +# Copyright (C) 2010-2015 INRIA # # #################### history # @@ -84,6 +84,9 @@ class Starting: def __init__ (self): self.tuples=[] + def __repr__(self): + return '' + def load (self): try: with open(Starting.location) as starting: @@ -134,6 +137,9 @@ class PoolItem: self.status = None self.ip = None + def __repr__(self): + return "".format(self.hostname, self.userdata) + def line(self): return "Pooled {} ({}) -> {}".format(self.hostname, self.userdata, self.status) @@ -145,10 +151,10 @@ class PoolItem: elif self.status == 'starting': return 'S' def get_ip(self): - if self.ip: return self.ip - ip=socket.gethostbyname(self.hostname) - self.ip=ip - return ip + if self.ip: + return self.ip + self.ip = socket.gethostbyname(self.hostname) + return self.ip class Pool: @@ -158,7 +164,11 @@ class Pool: # where to send notifications upon load_starting self.substrate = substrate + def __repr__(self): + return "".format(self.message, self.pool_items[0], self.pool_items[-1]) + def list (self, verbose=False): + print(self) for i in self.pool_items: print(i.line()) def line (self): @@ -169,7 +179,7 @@ class Pool: def _item (self, hostname): for i in self.pool_items: if i.hostname == hostname: return i - raise Exception ("Could not locate hostname %s in pool %s"%(hostname,self.message)) + raise Exception ("Could not locate hostname {} in pool {}".format(hostname, self.message)) def retrieve_userdata (self, hostname): return self._item(hostname).userdata @@ -184,12 +194,12 @@ class Pool: try: self._item(hostname).status='mine' except: - print('WARNING: host %s not found in IP pool %s'%(hostname,self.message)) + print('WARNING: host {} not found in IP pool {}'.format(hostname, self.message)) def next_free (self): for i in self.pool_items: if i.status == 'free': - i.status='mine' + i.status = 'mine' return (i.hostname, i.userdata) return None @@ -234,12 +244,14 @@ class Pool: else: item.status = 'free' print('.', end=' ') + sys.stdout.flush() def sense (self): print('Sensing IP pool', self.message, end=' ') + sys.stdout.flush() self._sense() print('Done') - for (vname,bname) in self.load_starting(): + for vname, bname in self.load_starting(): self.substrate.add_starting_dummy(bname, vname) print("After having loaded 'starting': IP pool") print(self.line()) @@ -247,6 +259,8 @@ class Pool: ping_timeout_option = None # returns True when a given hostname/ip responds to ping def check_ping (self, hostname): + if '.' not in hostname: + hostname = self.substrate.fqdn(hostname) if not Pool.ping_timeout_option: (status, osname) = subprocess.getstatusoutput("uname -s") if status != 0: @@ -256,7 +270,7 @@ class Pool: elif osname == "Darwin": Pool.ping_timeout_option = "-t" - command="ping -c 1 {} 1 {}".format(Pool.ping_timeout_option, hostname) + command = "ping -c 1 {} 1 {}".format(Pool.ping_timeout_option, hostname) (status, output) = subprocess.getstatusoutput(command) return status == 0 @@ -265,6 +279,8 @@ class Box: def __init__ (self, hostname): self.hostname = hostname self._probed = None + def __repr__(self): + return "".format(self.hostname) def shortname (self): return short_hostname(self.hostname) def test_ssh (self): @@ -399,6 +415,8 @@ class BuildInstance: self.buildname = buildname self.buildbox = buildbox self.pids = [pid] + def __repr__(self): + return "".format(self.buildname, self.buildbox) def add_pid(self,pid): self.pids.append(pid) @@ -410,6 +428,8 @@ class BuildBox (Box): def __init__ (self, hostname): Box.__init__(self, hostname) self.build_instances = [] + def __repr__(self): + return "".format(self.hostname) def add_build(self, buildname, pid): for build in self.build_instances: @@ -443,6 +463,7 @@ class BuildLxcBox (BuildBox): # inspect box and find currently running builds def sense(self, options): print('xb', end=' ') + sys.stdout.flush() pids = self.backquote_ssh(['pgrep','lbuild'], trash_err=True) if not pids: return command = ['ps', '-o', 'pid,command'] + [ pid for pid in pids.split("\n") if pid] @@ -469,6 +490,8 @@ class PlcInstance: self.plc_box = plcbox # unknown yet self.timestamp = 0 + def __repr__(self): + return "".format(self.plc_box) def set_timestamp (self,timestamp): self.timestamp = timestamp @@ -483,6 +506,8 @@ class PlcLxcInstance (PlcInstance): PlcInstance.__init__(self, plcbox) self.lxcname = lxcname self.pid = pid + def __repr__(self): + return "".format(self.lxcname) def vplcname (self): return self.lxcname.split('-')[-1] @@ -511,6 +536,8 @@ class PlcBox (Box): Box.__init__(self, hostname) self.plc_instances = [] self.max_plcs = max_plcs + def __repr__(self): + return "".format(self.hostname) def free_slots (self): return self.max_plcs - len(self.plc_instances) @@ -576,12 +603,17 @@ class PlcLxcBox (PlcBox): # to describe the currently running VM's def sense(self, options): print("xp", end=' ') + sys.stdout.flush() command = "rsync lxc-driver.sh {}:/root".format(self.hostname) subprocess.getstatusoutput(command) command = ['/root/lxc-driver.sh', '-c', 'sense_all'] lxc_stat = self.backquote_ssh (command) for lxc_line in lxc_stat.split("\n"): - if not lxc_line: continue + if not lxc_line: + continue + # we mix build and plc VMs + if 'vplc' not in lxc_line: + continue lxcname = lxc_line.split(";")[0] pid = lxc_line.split(";")[1] timestamp = lxc_line.split(";")[2] @@ -604,6 +636,8 @@ class QemuInstance: # not known yet self.buildname = None self.timestamp = 0 + def __repr__(self): + return "".format(self.nodename) def set_buildname (self, buildname): self.buildname = buildname @@ -637,6 +671,8 @@ class QemuBox (Box): Box.__init__(self, hostname) self.qemu_instances = [] self.max_qemus = max_qemus + def __repr__(self): + return "".format(self.hostname) def add_node(self, nodename, pid): for qemu in self.qemu_instances: @@ -704,6 +740,7 @@ class QemuBox (Box): def sense(self, options): print('qn', end=' ') + sys.stdout.flush() modules = self.backquote_ssh(['lsmod']).split('\n') self._driver = '*NO kqemu/kvm_intel MODULE LOADED*' for module in modules: @@ -787,6 +824,8 @@ class TestInstance: # has a KO test self.broken_steps = [] self.timestamp = 0 + def __repr__(self): + return "".format(self.buildname) def set_timestamp(self, timestamp): self.timestamp = timestamp @@ -840,6 +879,8 @@ class TestBox(Box): Box.__init__(self, hostname) self.starting_ips = [] self.test_instances = [] + def __repr__(self): + return "".format(self.hostname) def reboot(self, options): # can't reboot a vserver VM @@ -885,7 +926,7 @@ class TestBox(Box): def sense(self, options): print('tm', end=' ') - self.starting_ips = [x for x in self.backquote_ssh(['cat',Starting.location], trash_err=True).strip().split('\n') if x] + self.starting_ips = [ x for x in self.backquote_ssh( ['cat', Starting.location], trash_err=True).strip().split('\n') if x ] # scan timestamps on all tests # this is likely to not invoke ssh so we need to be a bit smarter to get * expanded @@ -999,11 +1040,13 @@ class Substrate: self.plc_boxes = self.plc_lxc_boxes self.default_boxes = self.plc_boxes + self.qemu_boxes self.all_boxes = self.build_boxes + [ self.test_box ] + self.plc_boxes + self.qemu_boxes + def __repr__(self): + return "".format(self.summary_line()) def summary_line (self): msg = "[" msg += " {} xp".format(len(self.plc_lxc_boxes)) - msg += " {} tried plc boxes".format(len(self.plc_boxes)) + msg += " {} xq".format(len(self.qemu_boxes)) msg += "]" return msg @@ -1017,6 +1060,7 @@ class Substrate: if self._sensed and not force: return False print('Sensing local substrate...', end=' ') + sys.stdout.flush() for b in self.default_boxes: b.sense(self.options) print('Done') @@ -1290,6 +1334,7 @@ class Substrate: def list_boxes(self): print('Sensing', end=' ') + sys.stdout.flush() for box in self.focus_all: box.sense(self.options) print('Done')