def StartTransientUnit(self, interface_name, name, smode, properties, extra_units=None): assert interface_name == b"org.freedesktop.systemd1.Manager" assert extra_units is None, "extra_units not yet supported" args = apply_signature(b"ss", [name, smode]) args += [(ord(b"a"), b"(sv)")] for prop_name, prop_value in properties.items(): prop_name = x2char_star(prop_name) signature = KNOWN_UNIT_SIGNATURES[prop_name] if callable(signature): prop_name, signature, prop_value = signature( prop_name, prop_value) args += [(ord(b"r"), b"sv"), (ord(b"s"), prop_name)] args += [(ord(b"v"), signature)] args += apply_signature(signature, [prop_value]) args += [(-1, None), (-1, None)] args += [(-1, None)] # extra units args += [(ord(b"a"), b"(sa(sv))")] args += [(-1, None)] with self.bus_context() as bus: return bus.call_method(self.destination, self.path, interface_name, b"StartTransientUnit", args).body
def StartTransientUnit(self, interface_name, name, smode, properties, extra_units=None): assert interface_name == b'org.freedesktop.systemd1.Manager' assert extra_units is None, 'extra_units not yet supported' args = apply_signature(b'ss', [name, smode]) args += [(ord(b'a'), b'(sv)')] for prop_name, prop_value in properties.items(): signature = KNOWN_UNIT_SIGNATURES[prop_name] if callable(signature): prop_name, signature, prop_value = signature( prop_name, prop_value) args += [(ord(b'r'), b'sv'), (ord(b's'), prop_name)] args += [(ord(b'v'), signature)] args += apply_signature(signature, [prop_value]) args += [(-1, None), (-1, None)] args += [(-1, None)] # extra units args += [(ord(b'a'), b'(sa(sv))')] args += [(-1, None)] with self.bus_context() as bus: return bus.call_method(self.destination, self.path, interface_name, b'StartTransientUnit', args).body
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 SetUnitProperties(self, interface_name, unit_name, runtime, properties): assert interface_name == b"org.freedesktop.systemd1.Manager" args = apply_signature(b"sb", [unit_name, runtime]) args += signature_array(properties) with self.bus_context() as bus: return bus.call_method(self.destination, self.path, interface_name, b"SetUnitProperties", args).body
def StartTransientUnit(self, interface_name, name, smode, properties, extra_units=None): assert interface_name == b"org.freedesktop.systemd1.Manager" args = apply_signature(b"ss", [name, smode]) args += signature_array(properties) # extra units args += [(ord(b"a"), b"(sa(sv))")] for eu_name, eu_properties in extra_units or []: args += [(ord(b"r"), b"sa(sv)")] args += apply_signature(b"s", [eu_name]) args += signature_array(eu_properties) args += [(-1, None)] args += [(-1, None)] with self.bus_context() as bus: return bus.call_method(self.destination, self.path, interface_name, b"StartTransientUnit", args).body
def signature_array(properties): args = [(ord(b"a"), b"(sv)")] for prop_name, prop_value in properties.items(): prop_name = x2char_star(prop_name) signature = KNOWN_UNIT_SIGNATURES[prop_name] if callable(signature): prop_name, signature, prop_value = signature(prop_name, prop_value) args += [(ord(b"r"), b"sv"), (ord(b"s"), prop_name)] args += [(ord(b"v"), signature)] args += apply_signature(signature, [prop_value]) args += [(-1, None), (-1, None)] args += [(-1, None)] return args
def _auto_call_dbus_method(self, method_name, in_args, *args): if len(args) != len(in_args): raise TypeError('method %s require %s arguments, %s supplied' % (method_name, len(in_args), len(args))) block_chars = re.compile(r'v|\{') if any(any(block_chars.finditer(arg)) for arg in in_args): raise NotImplementedError( 'still not implemented methods with complex ' 'arguments') in_signature = ''.join(in_args) call_args = apply_signature(six.b(in_signature), list(args)) with self.sd_object.bus_context() as bus: return bus.call_method(self.sd_object.destination, self.sd_object.path, self.interface_name, six.b(method_name), call_args).body