Cockpit allows access to DBus services via this API.
DBus Types
DBus values are represented as javascript values and objects as follows:
BYTE 'y'-
Javascript number.
BOOLEAN 'b'-
Javascript boolean.
INT16 'n'-
Javascript number.
UINT16 'q'-
Javascript number.
INT32 'i'-
Javascript number.
UINT32 'u'-
Javascript number.
INT64 'x'-
Javascript number.
UINT64 't'-
Javascript number.
DOUBLE 'd'-
Javascript number.
STRING 's'-
Javascript string.
OBJECT_PATH 'o'-
Javascript string.
SIGNATURE 'g'-
Javascript string.
ARRAY of BYTE 'ay'-
A string containing base64 encoded data.
ARRAY of DICT_ENTRY with STRING keys 'a{s?}'-
A javascript plain object with the keys as property names.
ARRAY of DICT_ENTRY with other keys 'a{??}'-
A javascript plain object each key JSON encoded into a string property name.
ARRAY of other-
A javascript array.
VARIANT-
A javascript plain object with the
"t"property set to a DBus type string, and the"v"property set to a value. HANDLE 'h'-
A javascript object that describes a cockpit channel which represents the passed file descriptor. The
payloadis always set tostream. Pass it to cockpit.channel() to create the channel and start reading or writing on it. Handles can only be received, not sent from within cockpit.
cockpit.dbus()
client = cockpit.dbus(name, [options])
Create a DBus client for the given bus name (eg: service name). Use
the following functions to make DBus method calls, watch for events,
etc. The optional options argument is a javascript plain object, and
may include:
"bus"-
The DBus bus to connect to. Specifying
"session"will connect to the DBus user session bus,"user"will connect to the user bus (on some systems this is identical to the session bus),"system"will connect to the DBus system bus, and"none"to the non-standard bus specified with theaddressoption. This defaults to "system" if not present. "address"-
The bus address to connect to in case
busis"none". "superuser"-
Set to
"require"to talk to this service as root. The DBus service will see the DBus method calls and accesses as coming from root, rather than the logged in user. This is useful for talking to services that do not correctly use polkit to authorize administrative users. If the currently logged in user is not permitted to become root (eg: viapkexec) then theclientwill immediately be closed with a"access-denied"problem code. + Set to"try"to try to talk as root, but if that fails, fall back to unprivileged. "track"-
It is valid for a DBus service to exit, and be restarted in such a way that clients continue to talk to it across the restart. Some services are not written with this in mind. If the
"track"option is set totruethen the channel will close when the service exits and/or disconnects from the DBus bus.
If the name argument is null, and no options other than "bus"
are specified, then a shared DBus client is created. When using such
a client with a DBus bus, a "name" option must be specified on
various other methods in order to specify which client to talk to.
client.wait()
promise = client.wait([callback])
Returns a promise that is ready when the client is ready, or fails
if the client closes. If a callback is specified, it is attached to
the promise.
client.close()
client.close([problem])
Close the DBus client. If problem is specified it should be a
problem code string.
client.onclose
client.addEventListener("close", options => { ... })
An event triggered when the DBus client closes. This can happen either because client.close() function was called, or the DBus service went away, or some other problem or disconnection.
The options will contain various close information, including a
"problem" field which will be set if the channel was closed because
of a problem.
client.onowner
client.addEventListener("owner", (event, owner) => { ... })
An event triggered when the owner of the DBus name changes. The owner value will be the id of the name owner on the bus or null if the name is unowned. The absence of an owner should not be treated as a disconnection. However this makes it possible to take some action based on the actual status of the service, for example disconnecting a pending signal handler.
client.options
Set to the options used when creating the client. Will not change for the life of the client.
client.unique_name
The unique DBus name of the client. Initially null, and becomes valid once the the client is ready.
client.proxy()
proxy = client.proxy([interface, path], [options])
Create proxy javascript object for a DBus interface. At the
specified DBus object path. The proxy will have properties, methods
and signals from to the DBus interface, and allows for natural
interaction. If no interface is specified then the DBus bus name of
the client is used. If no path is specified, then the DBus name of
the client is converted to a path.
If creating lots of proxies for a given interface it is more
efficient to use the client.proxies()
function.
The proxy is loaded when the
proxy.valid field is true, and
it is set to false if the underlying interface and/or path
don’t or no longer exist, or the client has closed. You can wait for
proxy to become valid by passing a callback to its
proxy.wait() function. The
proxy.onchanged event will also
fire when the proxy becomes valid or invalid. DBus properties and
methods on the proxy are not defined until the proxy becomes valid.
value = proxy.Prop1 proxy.WritableProp = value
All DBus properties on the interface that start with an upper case
letter (as is convention) will be automatically defined on this proxy,
and will update their values as the DBus property values change. In
addition the proxy.onchanged
event will fire every time the properties change.
If you assign a value to a writable property on the proxy, the proxy
will try to set that property on the DBus interface at path. The
actual proxy property value will not update until the DBus service has
notified the proxy of the change. If setting a property fails a warning
will be logged. In order to have more reliable setting of properties, or
track when they have been set, or if setting fails, use the
client.call() directly. It should be noted
that DBus service implementations may also be inconsistent in their
behavior when setting a property fails.
You can access the raw property data using the
proxy.data field, including data for
properties that do not start with an upper case letter.
proxy.Method(arg1, arg2)
.then((retval1, retval2) => {
...
})
.catch(ex => {
...
});
All DBus methods on the interface that start with an upper case
letter (as is convention) will be automatically defined on this proxy.
These methods are called with arguments as normal javascript arguments.
A
Promise
that will complete successfully when the method returns, or fail if an
error occurs. The return values from the DBus method will be passed to
the then handler function directly.
Methods that do not start with an upper case letter can be invoked by
using the usual proxy.call()
directly.
proxy.addEventListener("signal", (event, arg1, arg2) => {
...
});
All DBus signals on the interface that start with an upper case
letter (as is convention) will be automatically emit events on this
proxy. These events will contain the signal arguments after the standard
event argument.
Signals that do not start with an upper case letter can be subscribed to
by using proxy.onsignal directly.
Usually a proxy asks the client to watch and notify it of changes to
the relevant object or path. You can pass an options argument with
the watch field set to false to prevent this.
proxy.client
Set to the DBus client of the proxy. Will not change for the life of the proxy.
proxy.path
Set to the DBus object path of the proxy. Will not change for the life of the proxy.
proxy.iface
Set to the DBus interface name of the proxy. Will not change for the life of the proxy.
proxy.valid
Set to true when the proxy’s DBus interface is present at its DBus
path, and all information for the proxy has loaded. Is set to false
while loading, and after the proxy no longer refers a DBus interface and
path. Also set to false if the client closes.
Use the by proxy.wait() function to
wait for a proxy to load. The
proxy.onchanged event will also
be emitted when the proxy becomes valid or invalid. DBus properties and
methods on the proxy are not defined until the proxy becomes valid.
proxy.data
A plain javascript object containing all the raw property data that this
proxy has loaded. This will be updated automatically as the proxy is
notified of property changes from the DBus service. The
proxy.onchanged event will be
emitted when it changes.
proxy.call()
invocation = proxy.call(method, args, [options])
Make a DBus method call on this proxy.
For DBus methods that start with an upper case letter, is usually more convenient to call the method directly on the proxy. However if methods that do not follow the usual DBus convention, or specify additional options, or the caller cannot be sure that the method actually exists, you can use this method.
This function also works on proxies that have are still loading and have not become valid yet.
The method should be a DBus method name, and the args should be
an array of arguments to pass to the method. The options are
described elsewhere.
The returned value is identical to the one returned from client.call(). It is a Promise that will complete successfully when the method returns, or fail if an error occurs.
proxy.wait()
promise = proxy.wait()
proxy.wait(() => {
...
});
Wait for a proxy to finish loading. This function returns a promise. If
a callback function is passed as an argument then that function will be
invoked when the proxy is ready. If this method is called after a proxy
has already loaded, then the promise will be resolved immediately, and
any callback will be invoked immediately. Use the promise or
proxy.valid to determine whether the proxy is valid.
proxy.onchanged
proxy.addEventListener("changed", (event, data) => {
...
});
This event is emitted when the proxy’s properties change.
The data has the following form, and will only include properties
that have changed:
{
"Prop1": "value",
"Prop2": 5
}
proxy.onsignal
proxy.addEventListener("signal", (event, name, args) => {
...
});
This event is emitted when the proxy’s emits an event.
For most events, that have names which start with an upper case letter, you can just connect to that event as a signal directly. However if you wish to be notified when any signal is emitted, or for signals that do not follow the usual DBus convention, you can connect to this event.
The name is the DBus signal name, and the args is an array of
arguments that were emitted with the signal.
client.proxies()
proxies = client.proxies([interface], [path_namespace], [options])
Create proxy javascript objects for a DBus
interfaces. The proxies will have properties, methods and signals from
the DBus interface, and allow for natural interaction. If no
interface is specified then the DBus bus name of the client is used.
If no path_namespace is provided then "/" will be used.
Proxies will be automatically created for instances of the interface
available at the DBus service. The optional path_namespace argument
can be used to restrict the proxies for instances that have DBus paths
which have the namespace path prefix.
proxy1 = proxies["/dbus/path1"];
proxy2 = proxies["/dbus/path2"];
for (proxy in proxies) {
...
}
The returned proxies object will is used as a dictionary, and will
have values containing proxies for DBus interface instances, with the
keys being the DBus paths of those instances. It is possible to
enumerate over the returned proxies.
Proxies will be automatically added and removed from the proxies
object as they appear and disappear in the service. The
proxies.onadded and
proxies.onremoved events will
be emitted. DBus services may not support notifications of paths
disappearing.
Use the proxies.wait() function to be notified when the initial set
of proxies has been populated.
Usually a proxies ask the client to watch and be notified of changes
to the relevant object or path. You can pass an options argument
with the watch field set to false to prevent this.
proxies.wait()
promise = proxies.wait()
proxies.wait(() => {
...
});
Wait for a proxies object to populate its initial set of proxies.
This function returns a promise. If a callback function is passed as an
argument then that function will be invoked when the proxies are ready.
If this method is called after the proxies have populated, then the
promise will be resolved immediately, and any callback will be invoked
immediately.
proxies.client
Set to the DBus client of the proxies. Will not change.
proxies.iface
Set to the DBus interface name of the proxies. Will not change.
proxies.path_namespace
Set to the DBus path namespace used which the proxies must have as a DBus path prefix. Will not change.
proxies.onadded
proxies.addEventListener("added", (event, proxy) => {
...
})
This event is emitted when a proxy is added to the proxies object.
The proxy will already have loaded.
proxies.onchanged
proxies.addEventListener("changed", (event, proxy) => {
...
})
This event is emitted when one of the proxy in the proxies object
changes its properties.
proxies.onremoved
proxies.addEventListener("removed", (event, proxy) => {
...
})
This event is emitted when a proxy is removed to the proxies object.
client.call()
invocation = client.call(path, interface, method, args, [options])
Make a DBus method call.
The path is the DBus object path to make the call on, interface
is the DBus interface for the method and method is the name of the
method to call. The args is an array of arguments to pass to the
method, each of which must be appropriate for the expected
DBus type of that argument. The args may be
null if no arguments are to be sent.
The returned value is a Promise that will complete successfully when the method returns, or fail if an error occurs.
If options is specified it should be a plain javascript object,
which may contain the following properties:
flags-
A string containing DBus message flags. The character
"i"indicates to the dbus service that interactive authentication is allowed. If the entireflagsfield is missing, then"i"is set by default. type-
A valid DBus type signature to use when calling the method. In the absence of this, the DBus service will be introspected (and the result cached) to ask what the method type signature is.
timeout-
The timeout of the call in milliseconds. The call will fail with the
"timeout"problem code. If "timeout" is not given, the call will never time out.
invocation.then()
invocation.then((args, options) => { ... })
This is a standard Promise method. It sets up a handler to be called when the DBus method call finishes successfully.
The args argument is an array of return values from the DBus method.
Each of them will be converted to an appropriate
javascript type.
The options argument may contain additional information about the
reply. If the type option was specified when performing the method
call, then the options in the reply here will also contain a
type field containing the DBus type signature of the output. If the
flags option was specified when performing the call then the
options in the reply here will contain message flags. Possible out
message flags are:
>-
A big endian message.
<-
A little endian message.
invocation.catch()
invocation.catch(exception => { ... })
This is a standard Promise method. It sets up a handler to be called when the DBus method call fails.
The exception object passed to the handler can have the following
properties:
problem-
A problem code string when a problem occurred starting or communicating with the DBus service. This is
nullin the cases where an actual DBus error was occurred. name-
The DBus error name. This will be
nullin cases where the failure was not due to a DBus error. message-
A DBus error message. This will be
nullin cases where the failure was not due to a DBus error.
client.subscribe()
subscription = client.subscribe(match, (path, interface, signal, args) => { ... })
Subscribe to signals. The match argument is a javascript plain
object which defines what signals to subscribe to. Each property in the
match argument restricts signals subscribed to. If a property is not
present then it is treated as a wildcard, matching anything. If an empty
object is specified as match then all signals will be subscribed to.
The match argument may contain the following properties:
interface-
A DBus interface to match.
path-
A DBus object path to match. May not be used together with the
path_namespaceproperty. It should be a valid DBus object path, that is, it should have no trailing slash. path_namespace-
A DBus object path prefix to match. Any paths in the hierarchy below this top path will match. May not be used together with the
pathproperty. member-
The DBus signal name to match.
arg0-
Matches the first argument of a DBus message, which must be a string.
The handler passed as the second argument will be invoked when the
signal is received. A subscription is returned which can be used to
remove the subscription by calling its subscription.remove() method.
It is not a problem to subscribe to the same signals more than once,
with identical or slightly different match arguments.
subscription.remove()
subscription.remove()
Unsubscribe from the DBus signal subscription.
client.watch()
watch = client.watch(path)
watch = client.watch({ "path_namespace": path_namespace, "interface": interface })
Watch for property and interface changes on the given DBus object
path DBus path_namespace. If interface is specified only
properties on that DBus interface will be watched.
The client.proxy() and
client.proxies() functions and the
objects they return are high level wrappers around client.watch().
The property and interface changes will be available in raw form on the
client.onnotify event.
Property and interface changes that are caused by a method call or signal will show up before that method call reply is received, or signal event is triggered. It should be possible to rely on this guarantee, unless the DBus service in question behaves incorrectly. Internally these watches work well with code that implements the ObjectManager portion of the DBus specification. If no ObjectManager implementation is available, the watch falls back to using DBus Introspection along with the usual PropertiesChanged signal. If the DBus service implements none of these, or implements them in an inconsistent manner, then this function will provide inconsistent or unexpected results.
The parameter is either a DBus path or a plain javascript object
with zero or more of the following fields. If an empty javascript object
is used as an argument, then all paths, interfaces and properties will
be watched.
interface-
Watch properties on this DBus interface.
path-
Watch interfaces and properties at this DBus path. May not be used together with the
path_namespaceproperty. path_namespace-
Watch interfaces and properties under this DBus path. It should be a valid DBus object path, that is, it should have no trailing slash. If an ObjectManager implementation is available at this interface, then it is used. May not be used together with the
pathproperty.
The returned value is a
Promise
that will complete successfully when the watch has populated its initial
set of properties and interfaces, and these have been notified via
client.onnotify.
A watch can be removed by calling the
watch.remove() method on the
returned value. If identical watches are added more than once, then they
must also be removed the same number of times before the removal takes
effect.
watch.then()
watch.then(() => { ... })
This is a standard Promise method. It sets up a handler to be called when the watch has populated its initial properties and interfaces.
watch.catch()
watch.catch(ex => { ... })
This is a standard Promise method. It sets up a handler to be called if the watch fails to populate its initial properties and interfaces. Note that a watch will only fail if the DBus client closes or is somehow disconnected. It does not fail in the case of missing interfaces or properties.
watch.remove()
watch.remove()
Remove the watch. This may not have any immediate effect if other watches are in place. In particular, if identical watches are added more than once, then they must also be removed the same number of times before the removal takes effect.
client.onnotify
client.addEventListener("notify", data => { ... })
An event triggered when watched properties or interfaces change.
The client.proxy() and
client.proxies() functions and the
objects they return are high level wrappers around the data provided
by this event.
The data has the following form:
{
"/path1": {
"org.Interface1": {
"Prop1": "value",
"Prop2": 5
},
"org.Interface2": null
}
}
Multiple paths may be present, each of which may have multiple
interfaces, each of which may have multiple properties. The first time a
given path and interface is emitted from this signal, it will have all
its properties and interfaces. Thereafter only changes are noted. If an
interface is set to null, then that interface has disappeared.
client.notify()
client.notify(data)
Emits a synthetic notify event. The
data argument should follow the same layout as described for the
notify event.
client.onmeta
client.onmeta = (ev, data) => { ... }
An event triggered when the meta data about watched interfaces is loaded.
The client.proxy() and
client.proxies() functions and the
objects they return are high level wrappers around the data provided
by this event.
The data has the following form:
{
"org.Interface": {
"methods": {
"Method1": {
"in": [ "s", "v" ],
"out": [ "i" ]
},
"Method2": { }
},
"signals": {
"Signal": {
"in": [ "b", "s" ]
}
},
"properties": {
"Prop1": {
"flags": "rw",
"type": "s"
},
"Prop2": {
"flags": "r",
"type": "b"
}
}
}
}
Multiple interfaces may be present, each of which may have methods and
properties. This is emitted before the first
client.onnotify event for the relevant
interface.
cockpit.variant()
variant = cockpit.variant(type, value)
A DBus variant is represented as a plain javascript object with a
"t" property represesting the full DBus type of the variant, and a
"v" property containing the variant value.
This is a helper function for creating such a variant object.