class WPAMonitor(Thread): def __init__(self, ifname): self.log = Log("monitor") mon_path = "/tmp/wpa_mon_%s" % getpid() atexit.register(lambda: unlink(mon_path)) server_path = "/var/run/wpa_supplicant/%s" % ifname self.log.debug("connecting to %s" % server_path) self.socket = socket(AF_UNIX, SOCK_DGRAM) self.socket.bind(mon_path) self.socket.connect(server_path) super().__init__(daemon=True) def run(self): self.socket.send(b"AUTOSCAN periodic:10") self.socket.send(b"AP_SCAN 1") self.socket.send(b"ATTACH") while True: try: data = self.socket.recv(65535).strip().decode('ascii', 'ignore') self.log.debug("got %s" % data) if data == 'OK': continue if data == 'FAIL': raise Exception("Failure detected") mask, evtype = data.split('>', 1) if evtype == 'CTRL-EVENT-SCAN-RESULTS': print("scan results") for cb in events['scan_results']: cb() else: self.log.info("unknown event %s" % data) except Exception as e: self.log.critical(e) sys.exit(e)
class Proxy(threading.Thread): def __init__(self, src=None, dst=None, buf=128*Kb, backlog=128): assert src and dst, \ "please specify src and dst addresses" self.src = src self.dst = dst self.buf = buf self.backlog = backlog self.log = Log("%s => %s" % (src, dst)) super().__init__() def run(self): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.log.info("listening on {}".format(self.src)) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(self.src) s.listen(self.backlog) while True: #if __debug__: self.log.debug("waiting for incoming connections on {}" # .format(self.src)) conn, addr = s.accept() #if __debug__: self.log.debug("connection from {}".format(addr)) tun = Tun(conn, self.dst, self.buf) tun.start()
""" Get NUMA topology. Only online CPUs are counted. """ def __init__(self): self.all = read_int_list(PREFIX + "cpu/online") self.ht_map = {} for cpu in self.all: self.ht_map[cpu] = self.get_thread_sibling(cpu) self.no_ht = filter_ht(self.all) ht = list(set(self.all) - set(self.no_ht)) self.by_rank = sorted(self.no_ht) + sorted(ht) def get_thread_sibling(self, cpu): siblings = read_int_list(PREFIX + "cpu/cpu%s/topology/thread_siblings_list" % cpu) siblings.remove(cpu) return siblings def __str__(self): return "All cpus: {cpus}\n" \ "Without HT: {noht}\n" \ "Hyper-Threading map: {htmap}\n" \ "Ranked: {rank}\n" \ .format(cpus=self.all, noht=self.no_ht, htmap=self.ht_map.items(), rank=self.by_rank) topology = CPUTopology() if __name__ == '__main__': log.info(topology)
class Manager(CLI): """ Class to orchestrate several instances at once. """ autostart_delay = 3 def __init__(self, name="default"): self.instances = OrderedDict() self.name = name self.log = Log(name) def add_instance(self, inst): assert inst.name not in self.instances, \ "we already have a machine with the name %s" % inst.name self.instances[inst.name] = inst def check_instance(self, name): if name not in self.instances: raise UnknownInstance("no such instance: %s" % name) @command("gen mac") def genmac(self): mac = gen_mac() print(mac) return mac @command("list") def do_list(self): return self.instances.keys() @command("autostart") def autostart(self): log.debug("starting all stopped instances with auto=True") sleep = 0 # do not do a pause if there is only one instance for instance in self.instances.values(): time.sleep(sleep) if not instance.auto: self.log.debug("%s is skipped because it has auto=False" % instance) continue if instance.is_running(): log.debug("skipping %s because it is already started" % instance) continue log.info("Starting %s" % instance) instance.start() sleep = self.autostart_delay @command("[name] start") @command("start [name]") def start(self, name): assert isinstance(name, str), "name should be string" self.log.debug("Starting %s" % name) self.check_instance(name) inst = self.instances[name] inst.start() return inst @command("stop all") @command("shutdown all") def stop_all(self): for inst in self.instances.values(): inst.stop() @command("stop [name]") @command("[name] stop") @command("shutdown [name]") @command("[name] shutdown") def stop(self, name): self.check_instance(name) self.instances[name].stop() @command("[name] reboot") @command("reboot [name]") def reboot(self, name=None): self.check_instance(name) self.instances[name].reboot() @command("[name] reset") @command("reset [name]") def reset(self, name=None): self.check_instance(name) self.instances[name].reset() @command("unfreeze all") @command("defrost all") def kill_defrost(self): for inst in self.instances.values(): inst.unfreeze() @command("killall") @command("kill all") def kill_all(self): self.log.critical("KILLING ALL instances (even with auto=False)") for inst in self.instances.values(): inst.kill() @command("[name] kill") @command("kill [name]") def kill(self, name): self.check_instance(name) self.instances[name].kill() @command("show cmd [name]") def show_cmd(self, name): print(self.instances[name].get_cmd()) @command("console [name]") @command("[name] console") def console(self, name=None): self.log.debug("attaching to %s" % name) if name and not self.instances[name].is_running(): sys.exit("Instance is not started") self.instances[name].tmux.attach(name=name) @command("status") def status(self): for inst in self.instances.values(): print(inst.format_status()) @command("wait all timeout [timeout]") def wait_all(self, timeout): timeout = int(timeout) while True: running = 0 for inst in self.instances.values(): if inst.is_running(): running = 1 if not running: break timeout -= 1 if timeout < 0: raise TimeoutError("instances still running") time.sleep(1) print('.', end='', file=sys.stderr, flush=True) @command("graceful stop timeout [timeout]") def graceful(self, timeout=30): self.log.info("stopping ALL instances (even with auto=False)") timeout = int(timeout) self.stop_all() try: self.wait_all(timeout) except TimeoutError: self.log.critical("kvms still running: %s" \ % list(filter(lambda x: x.is_running(), self.instances.values()))) self.kill_all()