Systemd bindings for Lua
C Lua Objective-C
Latest commit d64c914 May 17, 2016 @daurnimator src/daemon: Bind sd_listen_fds
Fixes #6

README.md

Systemd for Lua.

This library is for working with systemd from scripts and daemons written in Lua.

Where necessary, the low level libsystemd functions have been bound in C. Higher level functions with more idiomatic lua semantics are written in Lua on top of these C primitives.

Compatible with Lua 5.1, 5.2 and 5.3 (thanks compat-5.3).

Status

Waiting for API to stabilise before making an initial release.

Todo

Installation

lua-systemd is on luarocks: https://luarocks.org/modules/daurnimator/systemd

Install via luarocks: luarocks install --server=http://luarocks.org/manifests/daurnimator systemd

Usage

Bound from C

All functions return nil, error_message [, errno] in case of error.

C Lua Comments
SD_LISTEN_FDS_START systemd.daemon.LISTEN_FDS_START
sd_notify() systemd.daemon.notify()
sd_pid_notify() systemd.daemon.pid_notify()
sd_pid_notify_with_fds() systemd.daemon.pid_notify_with_fds()
sd_booted() systemd.daemon.booted()
sd_listen_fds() systemd.daemon.listen_fds()
sd_journal_sendv() systemd.journal.sendv()
sd_journal_perror() systemd.journal.perror()
sd_journal_stream_fd() systemd.journal.stream_fd() On success, returns a Lua file object instead of raw file descriptor
SD_JOURNAL_LOCAL_ONLY systemd.journal.OPEN.LOCAL_ONLY
SD_JOURNAL_RUNTIME_ONLY systemd.journal.OPEN.RUNTIME_ONLY
SD_JOURNAL_SYSTEM systemd.journal.OPEN.SYSTEM
SD_JOURNAL_CURRENT_USER systemd.journal.OPEN.CURRENT_USER
sd_journal_open() systemd.journal.open()
sd_journal_open_directory() systemd.journal.open_directory()
sd_journal_open_files() systemd.journal.open_files()
sd_journal_open_container() systemd.journal.open_container()
sd_journal_close() Bound as __gc metamethod on journal objects
sd_journal_get_cutoff_realtime_usec() my_journal:get_cutoff_realtime_usec()
sd_journal_get_cutoff_monotonic_usec() my_journal:get_cutoff_monotonic_usec()
sd_journal_get_usage() my_journal:get_usage()
sd_journal_next() my_journal:next()
sd_journal_next_skip() my_journal:next_skip()
sd_journal_previous() my_journal:previous()
sd_journal_previous_skip() my_journal:previous_skip()
sd_journal_seek_head() my_journal:seek_head()
sd_journal_seek_tail() my_journal:seek_tail()
sd_journal_seek_monotonic_usec() my_journal:seek_monotonic_usec()
sd_journal_seek_realtime_usec() my_journal:seek_realtime_usec()
sd_journal_seek_cursor() my_journal:seek_cursor()
sd_journal_get_cursor() my_journal:get_cursor()
sd_journal_test_cursor() my_journal:test_cursor()
sd_journal_get_realtime_usec() my_journal:get_realtime_usec()
sd_journal_get_monotonic_usec() my_journal:get_monotonic_usec()
sd_journal_get_data() my_journal:get_data()
sd_journal_enumerate_data() my_journal:enumerate_data()
sd_journal_restart_data() my_journal:restart_data()
sd_journal_query_unique() my_journal:query_unique()
sd_journal_enumerate_unique() my_journal:enumerate_unique()
sd_journal_restart_unique() my_journal:restart_unique()
sd_journal_set_data_threshold() my_journal:set_data_threshold()
sd_journal_get_data_threshold() my_journal:get_data_threshold()
sd_journal_add_match() my_journal:add_match()
sd_journal_add_disjunction() my_journal:add_disjunction()
sd_journal_add_conjunction() my_journal:add_conjunction()
sd_journal_flush_matches() my_journal:flush_matches()
SD_JOURNAL_NOP systemd.journal.WAKEUP.NOP
SD_JOURNAL_APPEND systemd.journal.WAKEUP.APPEND
SD_JOURNAL_INVALIDATE systemd.journal.WAKEUP.INVALIDATE
sd_journal_get_fd() my_journal:get_fd()
sd_journal_get_events() my_journal:get_events()
sd_journal_get_timeout() my_journal:get_timeout() Returns false if timeout isn't available, otherwise returns value in seconds
sd_journal_process() my_journal:process()
sd_journal_wait() my_journal:wait() timeout is in seconds instead of microseconds
sd_journal_reliable_fd() my_journal:reliable_fd()
sd_id128_randomize() systemd.id128.randomize() Also available as randomise for any non-americans out there
sd_id128_from_string() systemd.id128.from_string()
sd_id128_get_machine() systemd.id128.get_machine()
sd_id128_get_boot() systemd.id128.get_boot()
sd_id128_to_string() my_id128:to_string() Also available as __tostring metamethod: tostring(my_id128_t)
sd_id128_equal() id128_a == id128_b Bound as __eq metamethod
sd_journal_get_catalog_for_message_id() my_id128:get_catalog()
sd_get_seats() systemd.login.get_seats()
sd_get_sessions() systemd.login.get_sessions()
sd_get_uids() systemd.login.get_uids()
sd_get_machine_names() systemd.login.get_machine_names()
sd_pid_get_session() systemd.login.pid_get_session()
sd_pid_get_unit() systemd.login.pid_get_unit()
sd_pid_get_user_unit() systemd.login.pid_get_user_unit()
sd_pid_get_owner_uid() systemd.login.pid_get_owner_uid()
sd_pid_get_machine_name() systemd.login.pid_get_machine_name()
sd_pid_get_slice() systemd.login.pid_get_slice()
sd_pid_get_user_slice() systemd.login.pid_get_user_slice()
sd_peer_get_session() systemd.login.peer_get_session()
sd_peer_get_unit() systemd.login.peer_get_unit()
sd_peer_get_user_unit() systemd.login.peer_get_user_unit()
sd_peer_get_owner_uid() systemd.login.peer_get_owner_uid()
sd_peer_get_machine_name() systemd.login.peer_get_machine_name()
sd_peer_get_slice() systemd.login.peer_get_slice()
sd_peer_get_user_slice() systemd.login.peer_get_user_slice()
sd_uid_get_state() systemd.login.uid_get_state()
sd_uid_is_on_seat() systemd.login.uid_is_on_seat()
sd_uid_get_sessions() systemd.login.uid_get_sessions()
sd_uid_get_seats() systemd.login.uid_get_seats()
sd_uid_get_display() systemd.login.uid_get_display()
sd_session_is_active() systemd.login.session_is_active()
sd_session_is_remote() systemd.login.session_is_remote()
sd_session_get_state() systemd.login.session_get_state()
sd_session_get_uid() systemd.login.session_get_uid()
sd_session_get_seat() systemd.login.session_get_seat()
sd_session_get_service() systemd.login.session_get_service()
sd_session_get_type() systemd.login.session_get_type()
sd_session_get_class() systemd.login.session_get_class()
sd_session_get_desktop() systemd.login.session_get_desktop()
sd_session_get_display() systemd.login.session_get_display()
sd_session_get_remote_host() systemd.login.session_get_remote_host()
sd_session_get_remote_user() systemd.login.session_get_remote_user()
sd_session_get_tty() systemd.login.session_get_tty()
sd_session_get_vt() systemd.login.session_get_vt()
sd_seat_get_active() systemd.login.seat_get_active() On success, returns session, uid
sd_seat_get_sessions() systemd.login.seat_get_sessions() On success, returns sessions, uids
sd_seat_can_multi_session() systemd.login.seat_can_multi_session()
sd_seat_can_tty() systemd.login.seat_can_tty()
sd_seat_can_graphical() systemd.login.seat_can_graphical()
sd_machine_get_class() systemd.login.machine_get_class()
sd_machine_get_ifindices() systemd.login.machine_get_ifindices()
sd_login_monitor_new() systemd.login.monitor()
sd_login_monitor_unref() Bound as __gc metamethod on monitor objects
sd_login_monitor_flush() my_login_monitor:flush()
sd_login_monitor_get_fd() my_login_monitor:get_fd()
sd_login_monitor_get_events() my_login_monitor:get_events()
sd_login_monitor_get_timeout() my_login_monitor:get_timeout() Returns false if timeout isn't available, otherwise returns value in seconds

Misc extras

systemd.daemon.notifyt(tbl) and systemd.daemon.pid_notifyt(tbl)

Like notify, but takes a lua table instead of a newline delimited list. Numbers will be coerced to strings.

notifyt { READY = 1, STATUS = "Server now accepting connections", WATCHDOG = 1 }

interval = systemd.daemon.watchdog_enabled()

Returns the watchdog interval (in seconds) if there is one set otherwise returns false.

You should call kick_dog or notify("WATCHDOG=1") every half of this interval.

Similar functionality to sd_watchdog_enabled()

systemd.daemon.kick_dog()

Tells systemd to update the watchdog timestamp. This should be called on an interval.

systemd.journal.LOG

Table containing the syslog(3) priority constants: EMERG, ALERT, CRIT, ERR, WARNING, NOTICE, INFO, DEBUG

Useful as the second argument to systemd.journal.streamfd()

systemd.journal.print(priority, fmt_string, ...)

Same argument signature as C, but written in lua on top of sendv() and string.format()

systemd.journal.sendt(tbl)

Log a message to the journal with the key/value pairs from tbl

systemd.journal.sendt {
    SYSLOG_IDENTIFIER = "identifier" ;
    SYSLOG_FACILITY = "facility" ;
    PRIORITY = systemd.journal.LOG.ERR ;
    MESSAGE = "something happended!" ;
    MY_CUSTOM_FIELD = "extra detail.";
}

value = my_journal:get(field)

Returns the given field from the current journal entry (which may be nil)

Throws a lua error on failure.

my_journal:each_data()

A valid lua iterator that enumerates through field, value pairs.

for field, value in my_journal:each_data() do
    print(field, value)
end

Throws a lua error on failure.

my_journal:each_unique(field_name)

A valid lua iterator that enumerates through unique field values.

-- Print each different `_SYSTEMD_UNIT`
for value in my_journal:each_unique("_SYSTEMD_UNIT") do
    print(value)
end

Throws a lua error on failure.

t = my_journal:to_table()

Converts the current journal entry to a lua table.

Includes Address Fields:

  • __CURSOR
  • __REALTIME_TIMESTAMP
  • __MONOTONIC_TIMESTAMP

text = my_journal:get_catalog()

Looks up the current journal entry's MESSAGE_ID in the message catalog. Substitutes the templated fields (between @ symbols) with values from this journal entry.

Returns:

  • the filled out catalogue entry as a string
  • false if MESSAGE_ID is not set, or does not exist in the catalogue
  • nil, err_msg, errno in case of failure.

Same functionality as sd_journal_get_catalog().

systemd.messages

A table of well-known message ids as id128 objects.

Taken from sd-messages.h