systemd
D-Bus client for org.freedesktop.systemd1 and org.freedesktop.machine1, plus a one-shot journal
reader. Linux-only — the table is empty on other platforms. Plan 18 / v0.15.1.
Backed by zbus 5 (async); a single system-bus connection is opened lazily on first call and cached
for the lifetime of the Lua VM. Every public function is async at the Rust level; mlua drives them
as Lua coroutines so callers write straight-line code.
Units
systemd.list_units(filter?)—filteris a glob like"*.service"or"*.timer"; nil for all.systemd.unit_status(name)— full property dict includingsince,main_pid,exec_main_status,fragment_path.systemd.is_active(name)→ booleansystemd.list_timers()→ list of timer rows withnext_elapse_realtime/last_trigger_realtime/passed/activates.systemd.start(name)/stop(name)/restart(name)/reload(name)— return the job object path.
Machines (systemd-machined)
systemd.list_machines()→[{name, class, service, leader_pid, addresses, root_directory}, …]systemd.machine_status(name)— full per-machine dictsystemd.machine_start(name)/machine_poweroff(name)/machine_reboot(name)/machine_terminate(name)
Journal
systemd.journal({unit?, machine?, since?, until?, lines?, priority?})— one-shot read of the most recent N entries. Implementation shells out tojournalctl --output=json; subprocess is on-demand only.systemd.journal_follow(opts, fn)— not yet implemented; returns an explicit runtime error. Tracked as a Phase 3 follow-up (sd_journal_wait + cancellation handle across the FFI boundary).
Machine exec (v0.15.5+)
systemd.machine_exec(name, cmd, opts?)→{status, stdout, stderr, timed_out}— Run a command inside a systemd-machined nspawn container. The command is passed to/bin/sh -c.name(string): machine name as returned bysystemd.list_machines()cmd(string): shell command stringopts(table, optional):timeout(number): seconds; triggers a graceful kill of the container process on elapseenv(table):{ [name] = value }— extra environment variables
- Returns
{status=integer, stdout=string, stderr=string, timed_out=boolean}— same shape asshell.exec.timed_outistrueif the timeout elapsed before the process exited.
local r = systemd.machine_exec("mycontainer", "dpkg-query -W curl", { timeout = 10 }) if r.timed_out then error("exec timed out") end print(r.stdout)
Permissions
Lifecycle methods (start, stop, machine lifecycle) require the calling process to have polkit
authorisation for the relevant D-Bus interface. Read-only queries (list_*, unit_status,
is_active) work for any caller with system-bus access.