def start_server(self) -> bool: with DBus(user_mode=True) as bus, \ Unit(self.__config.get_system_service_unit_name(), \ bus=bus, _autoload=True) as service: try: service.Unit.Start(b"replace") except Exception as e: print(f"Can't start server: {e}") return False # print(f'Server\'s state: {service.Unit.ActiveState}') return True print('Can\t read server state via Dbus!') return False
def bus_context(self): close_bus_at_end = self._bus is None try: if self._bus is None: bus = DBus() bus.open() else: bus = self._bus yield bus finally: if close_bus_at_end: bus.close()
def monitor(name): unit = Unit(name) with DBus() as bus: bus.match_signal( unit.destination, unit.path, b"org.freedesktop.DBus.Properties", b"PropertiesChanged", process, # callback for this message STATE, # maybe pass custom python objects as userdata? ) fd = bus.get_fd() while not STATE.EXIT: select.select([fd], [], []) # wait for message bus.process() # execute all methods (driver)
def _unit_action_sync(self, action, wait, timeout): unit = self._get_systemd_unit() job = getattr(unit.Unit, action)(b"replace") if wait: with DBus() as bus: done = False def callback(msg, error=None, userdata=None): nonlocal done msg.process_reply(True) if msg.body[1] == job: done = True bus.match_signal( b"org.freedesktop.systemd1", b"/org/freedesktop/systemd1", b"org.freedesktop.systemd1.Manager", b"JobRemoved", callback, None, ) job_object = Job(job, bus) try: job_object.load() except DBusUnknownObjectError: # Job has already completed return fd = bus.get_fd() while True: fds = select.select([fd], [], [], timeout) if not any(fds): break bus.process() if done: break
def monitor(): with DBus() as bus: bus.match_signal( b"org.freedesktop.systemd1", None, b"org.freedesktop.DBus.Properties", b"PropertiesChanged", process, # callback for this message None, ) fd = bus.get_fd() while True: try: select.select([fd], [], []) # wait for message bus.process() # execute all methods (driver) except KeyboardInterrupt: break
def monitor(*args): """ This is a simple mock of the monitor function inside busctl. the c version can be found in https://github.com/systemd/systemd/blob/master/src/busctl/busctl.c#L1081 a couple of interesting stuff here: 1.- We interface directly with dbus, as we need to keep it open. 2.- we construct argument for `BecomeMonitor`. 3.- we dump stuff to stdout as simple as possible. """ with DBus() as bus: cargs = apply_signature( b"asu", # signature [ chain(*[[b"sender='%s'" % arg, b"destination='%s'" % arg] for arg in args]), 0, ], ) # BecomeMonitor takes 2 argument an array of string (filters) and a # uint32 flag. We could have known this by inspecting # /org/freedesktop/DBus object. bus.call_method( b"org.freedesktop.DBus", b"/org/freedesktop/DBus", b"org.freedesktop.DBus.Monitoring", b"BecomeMonitor", cargs, ) name = bus.get_unique_name() while True: msg = bus.process() if not msg.is_signal(b"org.freedesktop.DBus", b"NameLost"): continue msg.process_reply(False) if msg.body == name: break while True: msg = bus.process() if msg.is_empty(): bus.wait(1000000000) continue msg.process_reply(True) # print headers pprint({k: v for k, v in msg.headers.items() if v is not None}) # print response pprint(msg.body) print("#*" * 40) if msg.is_signal(b"org.freedesktop.DBus.Local", b"Disconnected"): break bus.wait(1000000000)
def bus_factory(): if machine: return DBusMachine(x2char_star(machine)) else: return DBus(user_mode=user_mode)
def bus_factory(): if machine: return DBusMachine(machine) else: return DBus(user_mode=user_mode)
from app import app, db from app.models import Image from app.schemas import ImageSchema from app.camera import Camera CORS(app) dbus = None yolo_unit = None camera = None yolo_version = app.config['YOLO_VERSION'] if app.config['JETSON_PLATFORM'] == 'True': from pystemd.systemd1 import Unit from pystemd.dbuslib import DBus dbus = DBus(user_mode=True) dbus.open() yolo_unit = Unit(b'orninet-yolov5.service', bus=dbus, _autoload=True) # yolo_unit = Unit(bytes(f'orninet-yolov{yolo_version}.service', 'utf-8'), bus=dbus, _autoload=True) else: class PlaceholderUnit(object): def __init__(self): self.ActiveState = 'inactive' class PlaceholderYoloUnit(object): def __init__(self): self.Unit = PlaceholderUnit()
class McUnit: """ A class to represent a Unit of the minecraft service. The factory function discover_units expects to find installations of Minecraft Server in folders under /home/minecraft/MinecraftServers and returns a list of McUnit """ repr_format = "{:3.2s}{:20.19s}{:11.10s}{:8.7s}{:9.8s}{:10.9s}{:15.14s}{:4.4s}" heading = repr_format.format("No", "Name", "State", "SubSt", "Auto Start", "GameMode", "World", "Wlds") config_name = "server.properties" # keep a dbus and a manager for the lifetime of the class/app dbus = DBus(user_mode=True) dbus.open() manager = Manager(bus=dbus) manager.load() def __init__(self, name, unit, unit_name, num): self.name = name self.unit = unit self.unit_name = unit_name self.num = num self.config_path = Config.mc_root / name / self.config_name self.properties = Properties(self.config_path) self.properties.read() self.world = self.properties["level-name"] self.mode = self.properties["gamemode"] self.worlds = [ f.name for f in (Config.mc_root / name).iterdir() if f.name not in Config.non_worlds and f.is_dir() ] @classmethod def discover_units(cls): # factory function that queries systemd files and returns a list # of McUints (1 systemd unit per Minecraft installation) mc_installs = list(Config.mc_root.glob("*")) mc_names = [ str(mc.name) for mc in mc_installs if not str(mc.name).startswith(".") ] units = [] for i, mc_name in enumerate(mc_names): unit_name = Config.unit_name_format.format(mc_name) unit = Unit(unit_name.encode("utf8"), bus=cls.dbus) unit.load() units.append(McUnit(mc_name, unit, unit_name, i)) return units def __repr__(self): state = self.unit.Unit.ActiveState.decode("utf8") sub_state = self.unit.Unit.SubState.decode("utf8") enabled = self.manager.Manager.GetUnitFileState( self.unit_name).decode() return self.repr_format.format(str(self.num), self.name, state, sub_state, enabled, self.mode, self.world, str(len(self.worlds))) def get_world_path(self, world_num): if not len(self.worlds) >= world_num >= 0: raise ValueError(f"world number {world_num} does not exist") return Config.mc_root / self.name / self.worlds[world_num] def set_world(self, world_num): self.properties.read() if not len(self.worlds) >= world_num >= 0: raise ValueError(f"world number {world_num} does not exist") self.properties["level-name"] = self.worlds[world_num] self.properties.write() self.world = self.worlds[world_num] def start(self): print(f"Starting {self.name} ...") self.unit.Start(b"replace") def stop(self): print(f"Stopping {self.name} ...") self.unit.Stop(b"replace") # wait for the service to complete termination while self.running: sleep(.2) def restart(self): # unit.Restart does not work for some reason self.stop() self.start() def enable(self): self.manager.Manager.EnableUnitFiles([self.unit_name], False, False) def disable(self): self.manager.Manager.DisableUnitFiles([self.unit_name], False) def console(self): cmd = Config.screen_cmd_format.format(self.name) os.system(cmd) @property def running(self): state = self.unit.Unit.ActiveState.decode("utf8") return state != "inactive" actions = { "s": start, "k": stop, "e": enable, "d": disable, "r": restart, "c": console, }