This package contains basic support API available to other packages.
cockpit.js
Basic cockpit API to interact with the system
Loading cockpit.js
cockpit.js should be loaded via a script tag.
<script src="../base1/cockpit.js">
cockpit.js: Object Caching
If the same information is displayed by multiple components in Cockpit,
cockpit.cache() provides a way to share data between them. The
shared data should be simple objects, arrays, and values, and not
contain functions or other objects.
cockpit.cache()
cache = cockpit.cache(key, provider, consumer)
Create a new cache object. The key should be a globally unique
string that describes the data being cached. This string must describe
the data, across all machines and all versions of cockpit. It is
customary to include a version number in the key string.
function provider(result, key) {
result("myvalue");
return {
close: function() {
/* closed */
}
};
}
The provider is a function that will be invoked to start retrieving
data for the cache. It will be passed a result function as its first
argument. The result should be invoked whenever new data is
available. The key argument matches the key string the cache was
created with.
The provider can return an object with a close method. This
method will be invoked when the cache no longer needs data from the
provider.
function consumer(value, key) {
/* ... */
}
The consumer is a function that will be passed new values when they
are available, whether they come from the provider or a source in a
different component/frame.
cache.close()
cache.close()
Close a cache and stop calling its consumer. If the provider was
invoked, then the close() method it returned will be invoked.
cockpit.js: Raw Channels
At a low level Cockpit communicates with the system via messages passed
through various channels. These are usually exposed via higher level
APIs, such as the cockpit.spawn() function. It is rare to use raw
channels directly.
cockpit.channel()
channel = cockpit.channel(options)
This function creates a new channel for communication with the system.
It returns a new channel object. The options argument is a plain
object. At least the "payload" option is required, and based on the
payload type, other options may be required.
"binary"-
Set to
trueto transfer binary payloads. Both messages sent viachannel.send()and those received viachannel.onmessageshould be arrays of bytes, eitherUint8ArrayorArraydepending on browser support. "payload"-
The payload type for the channel. Only specific payload types are supported.
"superuser"-
Set to
"require"to open this channel as root. If the currently logged in user is not permitted to become root (eg: viapkexec) then thechannelwill immediately be closed with a"access-denied"problem code. + Set to"try"to try to open the channel as root, but if that fails, then fall back to an unprivileged channel.
The channel object returned has the following fields and methods and
events. You should call the channel.close() method when done with
the channel.
A valid channel will always be returned and the is ready to
channel.send(). The channel may
close shortly afterword due to a
failure.
channel.binary
Will be true for an binary channel. Will be set to false if the
channel is textual.
channel.options
The options used to open this channel. This should not be changed.
channel.valid
Will be true for an open channel. Will be set to false if the
channel closes.
channel.send()
channel.send(data)
Send a message over the channel. The contents of the message depends on
the payload type of the channel. If a binary channel, then data is
expected to be an Array of bytes or a Uint8Array. If not binary,
then the data will be converted to a string if not already a string.
channel.control()
channel.control(options)
Notify the channel to tune certain parameters on the fly. The
options is a plain javascript object, and the contents depend on the
"payload" of the channel.
One common operation is to set "command" to "done" in the
options field. To indicate that no further messages will be sent through
the channel.
channel.wait()
promise = channel.wait([callback])
Returns a promise that is ready when the channel is ready, or fails
if the client closes. If a callback is specified, it is attached to
the promise. The promise will be rejected or resolved with the contents
options passed to the
channel.onready and
channel.onclose events respectively.
In general it’s not necessary to wait for the channel before starting to use the channel.
channel.close()
channel.close([options])
Close the channel.
If options is present it can be a plain javascript object containing
additional channel close options to send to the peer. If closing for
because of a problem, set the "problem" field to a
problem code. If options is not an object it
will be treated as a "problem".
The close event will fire. A channel can also be closed by a peer or if the underlying transport closes.
channel.onmessage
channel.addEventListener("message", function(event, data) { ... })
An event triggered when the channel receives a message. The message is
passed as a string to the handler in the data. In the case of binary
channels data is an Uint8Array or an Array of bytes if the
former is not supported by the browser. The contents of the message
depends on the payload type of the channel.
channel.oncontrol
channel.addEventListener("control", function(event, options) { ... })
An event triggered when the channel receives an control message in the
middle of the flow. One particular use is when the command is set to
"done" then no further messages will be received in the channel. The
exact form of these messages depend on the "payload" of the channel.
channel.onready
channel.addEventListener("ready", function(event, options) { ... })
An event triggered when the other end of the channel is ready to start processing messages. This indicates the channel is completely open. It is possible to start sending messages on the channel before this point.
channel.onclose
channel.addEventListener("close", function(event, options) { ... })
An event triggered when the channel closes. This can happen either because channel.close() function was called, or if the peer closed the channel, or the underlying transport closes.
The options will contain various close information, including a
"problem" field which will be set if the channel was closed because
of a problem.
cockpit.transport.origin
cockpit.transport.origin
The HTTP origin that is being used by the underlying channel transport.
This is read-only, you should not assign a value. If the browser
supports window.location.origin then this will be identical to that
value.
cockpit.transport.host
cockpit.transport.host
The host that this transport is going to talk to by default. This is read-only, you should not assign a value. If the value is null that means that the transport has not been setup yet.
cockpit.transport.csrf_token
cockpit.transport.csrf_token
A cross site request forgery token for use with external channels. This becomes valid once the connection is properly established.
cockpit.transport.options
cockpit.transport.options
Initialization options received over the underlying channel transport. These will be empty until connection is properly established.
cockpit.transport.wait()
cockpit.transport.wait(callback)
Call the callback function once the underlying channel transport is
initialized. This will start the initialization if not already in
progress or completed. If the channel transport is already initialized,
then callback will be called immediately.
In general it’s not necessary to wait for the transport before starting to open channels.
cockpit.transport.close()
cockpit.transport.close([problem])
Close the underlying channel transport. All channels open channels will
close. The problem argument should be a problem code string. If not
specified it will default to "disconnected".
cockpit.transport.filter()
cockpit.transport.filter((message, channelid, control) => { ... })
Add a filter to the underlying channel transport. All incoming messages will be passed to each of the filter callbacks that are registered.
This function is rarely used.
Filter callbacks are called in the order they are registered. If a
filter callback returns false then the message will not be
dispatched further, whether to other filters, or to channels, etc.
The message is the string or array with the raw message including,
the framing. The channelid is the channel identifier or an empty
string for control messages. If control is set then this is a
control message,d and the control argument contains the parsed JSON
object of the control message.
cockpit.transport.inject()
cockpit.transport.inject(message, [out])
Inject a message into the underlying channel transport. The message
should be a string or an array of bytes, and should be valid
according to the Cockpit message protocol. If the out argument is
equal to false then the message will be injected as an incoming
message as if it was received on the underlying channel transport.
This function is rarely used. In general you should only inject()
messages you got from a filter().
cockpit.base64_encode()
string = cockpit.base64_encode(data)
Encode binary data into a string using the Base64 encoding. The data
argument can either be a string, an Array, an ArrayBuffer or
a Uint8Array. The return value is a string.
cockpit.base64_decode()
data = cockpit.base64_decode(string, [constructor])
Decode binary data from a Base64 encoded string. The string argument
should be a javascript string. The returned data> will be an array
of bytes.
You can pass Uint8Array, Array or String as an alternate
constructor if you want the decoded data in an alternate form. The
default is to return an Array. Note that if you use a String for
the decoded data, then you must guarantee that the data does not contain
bytes that would be invalid for a string.
cockpit.js: DBus Client
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.
cockpit.js: Errors
cockpit.js: Errors
Problem codes and messages
Problem Codes
Cockpit represents problems with standardized problem string codes.
"access-denied"-
The user is not permitted to perform the action in question.
"authentication-failed"-
User authentication failed.
"internal-error"-
An unexpected internal error without further info. This should not happen during the normal course of operations.
"no-cockpit"-
The system does not have a compatible version of Cockpit installed or installed properly.
"no-session"-
Cockpit is not logged in.
"not-found"-
Something specifically requested was not found, such as a file, executable etc.
"terminated"-
Something was terminated forcibly, such as a connection, process session, etc.
"timeout"-
Something timed out.
"unknown-hostkey"-
The remote host had an unexpected or unknown key.
"no-forwarding"-
Could not forward authentication credentials to the remote host.
cockpit.message()
message = cockpit.message(problem) message = cockpit.message(exception)
Return a message for the exception or problem code passed as an
argument. If the argument is an object with a "message" property, as
is the case with most exceptions, that will be returned directly. If the
argument is an object with a "problem" property, then it will be
used as the problem code. An appropriate message will be returned for
problem codes.
cockpit.js: File Access
The cockpit.file API lets you read, write, and watch regular files
in their entirety. It cannot efficiently do random access in a big file
or read non-regular files such as /dev/random.
file = cockpit.file(path,
{ syntax: syntax_object,
binary: boolean,
max_read_size: int,
superuser: string,
})
promise = file.read()
promise
.then((content, tag) => { ... })
.catch(error => { ... })
promise = file.replace(content, [ expected_tag ])
promise
.then(new_tag => { ... })
.catch(error => { ... })
promise = file.modify(callback, [ initial_content, initial_tag ]
promise
.then((new_content, new_tag) => { ... })
.catch(error => { ... })
file.watch((content, tag, [error]) => { }, [ { read: boolean } ])
file.close()
Simple reading and writing
You can read a file with code like this:
cockpit.file("/path/to/file").read()
.then((content, tag) => {
...
})
.catch(error => {
...
});
It is recommended to use absolute paths. Relative paths are resolved
against /. To work with the current user’s files
cockpit.user() can be used to get the user’s home
directory.
The read() method returns a
Promise.
When successful, the promise will be resolved with the content of the
file. Unless you specify options to change this (see below), the file is
assumed to be text in the UTF-8 encoding, and content will be a
string.
The tag that is passed to the then() callback is a short string that
is associated with the file and changes whenever the content of the file
changes. It is meant to be used with replace().
It is not an error when the file does not exist. In this case, the
then() callback will be called with a null value for content
and tag is "-".
The superuser option can be used the same way as described in the
cockpit.channel() to provide a different
access level to the file.
You can use the max_read_size option to limit the amount of data
that is read. If the file is larger than the given number of bytes, no
data is read and the channel is closed with problem code too-large.
The default limit is 16 MiB. The limit can be completely removed by
setting it to -1.
To write to a file, use code like this:
cockpit.file("/path/to/file").replace("my new content\n")
.then(tag => {
...
})
.catch(error => {
...
});
The replace() method returns a
Promise.
When the promise is resolved, the file has been atomically replaced (via
the rename() syscall) with the new content. As with read(), by
default the new content is a string and will be written to the file as
UTF-8. The returned tag corresponds to the new content of the file.
When the promise is rejected because of an error, the file or its meta data has not been changed in any way.
As a special case, passing the value null to replace() will
remove the file.
The replace() method can also check for conflicting changes to a
file. You can pass a tag (as returned by read() or replace()) to
replace(), and the file will only be replaced if it still has the
given tag. If the tag of the file has changed, replace() will fail
with an error object that has error.problem == "change-conflict".
See modify() below for a convenient way to achieve transactional
updates to a file.
File format
By default, a file is assumed to be text encoded in UTF-8, and the
read() and replace() functions use strings to represent the
content.
By specifying the syntax.parser() and syntax.stringify()
options, you can cause read() to parse the content before passing it
back to you, and replace() to unparse it before writing.
The main idea is to be able to write { syntax: JSON }, of course,
but you can easily pass in individual functions or make your own
parser/unparser object:
cockpit.file("/path/to/file.json", { syntax: JSON })
var syntax_object = {
parse: my_parser,
stringify: my_unparser
};
cockpit.file("/path/to/file", { syntax: syntax_object })
Any exceptions thrown by the parse() and stringify() functions
are caught and reported as read or write errors.
The null value that is used to represent the content of a
non-existing file (see "Simple reading and writing", above) is not
passed through the parse() and stringify() functions.
Binary files
By default the content of the file is assumed to be text encoded as
UTF-8 and it can not contain zero bytes. The content is represented as a
JavaScript string with read(), replace(), etc. By setting the
binary option to true when creating the proxy, no assumptions are
placed on the content, and it is represented as a Uint8Array in
JavaScript.
Atomic modifications
Use modify() to modify the content of the file safely. A call to
modify() will read the content of the file, call callback on the
content, and then replace the content of the file with the return value
of the callback.
The modify() method uses the read() and replace() methods
internally in the obvious way. Thus, the syntax.parse() and
syntax.stringify() options work as expected, null represents a
non-existing file, and the watch callbacks are fired.
It will do this one or more times, until no other conflicting changes have been made to the file between reading and replacing it.
The callback is called like this
new_content = callback (old_content)
The callback is allowed to mutate old_content, but note that this
will also mutate the objects that are passed to the watch callbacks.
Returning undefined from the proxy is the same as returning
old_content.
The modify() method returns a
Promise.
The promise will be resolved with the new content and its tag, like so
function shout(old_content) {
return old_content.toUpperCase();
}
cockpit.file("/path/to/file").modify(shout)
.then((content, tag) => {
...
})
.catch(error => {
...
});
If you have cached the last content and tag results of the read() or
modify() method, or the last values passed to a watch callback, you
can pass them to modify() as the second and third argument. In this
case, modify() will skip the initial read and start with the given
values.
Change notifications
Calling watch() will start monitoring the file for external changes.
handle = file.watch(callback);
handle_no_read = file.watch(callback, { read: false });
Whenever a change occurs, the callback() is called with the new
content and tag of the file. This might happen because of external
changes, but also as part of calls to read(), replace(), and
modify().
When a read error occurs, the callback() is called with an error as
a third argument. Write errors are not reported via the watch callback.
Calling watch() will also automatically call read() to get the
initial content of the file. Thus, you normally don’t need to call
read() at all when using watch().
To disable the automatic reading, e.g. for large files or unreadable
file system objects, set the read option to false. The first
content argument of the callback will then always be null.
To free the resources used for monitoring, call handle.remove().
file.path
A string containing the path that was passed to the cockpit.file()
method.
Closing
Call the close() method on a file proxy to cancel all ongoing
operations, such as reading, writing, and monitoring. The proxy should
not be used after closing it.
cockpit.js: HTTP Client
Cockpit allows access to local HTTP and REST services via this API.
cockpit.http()
http = cockpit.http(endpoint, [options]) http = cockpit.http(options)
Create a new HTTP client. The endpoint can be a file path starting
with / to connect to a unix socket, or it can be a port number to
connect to. The optional options argument is a javascript plain
object, and may include:
"address"-
Connect to an address other than localhost. Must be a valid host name or IP address. To use this option you also must provide a port number.
"port"-
Port number to use with "address" option, when not given in
endpoint. "tls"-
Object properties for an https connection. See
http-stream2 TLS options. "headers"-
Additional HTTP headers to include with the HTTP request. This is a plain javascript object with each key as a header name, and each value as the header value.
"superuser"-
Set to
"require"to open this channel as root. If the currently logged in user is not permitted to become root (eg: viapkexec) then thechannelwill immediately be closed with a"access-denied"problem code. + Set to"try"to try to make the request as root, but if that fails, fall back to perform an unprivileged request. "tls"-
If set to a plain javascript object, then the connection will be an HTTPS connection and include TLS encryption. The fields of the
tlsobject declare various TLS configuration and data. All fields are optional: +-
"authority": Certificate authority(s) to expect as signers of the server’s TLS certificate, represented as a plain javascript object. It should have either a"file"field containing a readable PEM file on the system containing authorities, or a"data"with PEM encoded certificate data. -
"certificate": A client certificate to use, represented as a plain javascript object. It should have either a"file"field containing a readable PEM file on the system to use as a certificate, or a"data"with PEM encoded certificate data. -
"key": A client key to use, represented as a plain javascript object. It should have either a"file"field containing a readable PEM file on the system to use as a key, or a"data"with PEM encoded key data. -
"validate": A boolean that describes whether to validate the server’s TLS certificate or not. By default local connections are not validated, and remote connections are validated.
-
Here is a somewhat complex example of using most of the above
options when when calling cockpit.http():
http = cockpit.http({
"address": "localhost",
"headers": {
"Authorization": "Basic dXNlcjpwYXNzd29yZA=="
},
"port": 443,
"tls": {
"validate": true,
"authority": {
"file": "/etc/pki/tls/certs/ca-bundle.crt",
},
"certificate": {
"data": "-----BEGIN CERTIFICATE-----\nMIIDsDCCA..."
},
"key": {
"data": "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBA..."
}
}
});
http.get()
request = http.get(path, [params, [headers]])
Perform an HTTP GET request for the given path. If the params is
specified it should be a plain javascript object, which will be turned
into a query string.
Optionally a plain javascript object containing headers can be included
in the headers argument.
The return value is a Promise that will complete if the request happens successfully, or fail if there’s a problem.
http.post()
request = http.post(path, body, [headers])
Perform an HTTP POST request for the given path. The body can be
a string, or a javascript plain object, which will be encoded as JSON
data. If body is undefined or null then an empty HTTP body
will be sent.
Optionally a plain javascript object containing headers can be included
in the headers argument.
The return value is a Promise that will complete if the request happens successfully, or fail if there’s a problem.
http.request()
request = http.request(options)
Perform an HTTP request. The options can contain the following:
"body"-
The HTTP request body. If you do not specify a body, then you must call request.input() to complete the body and allow the request to start.
"headers"-
A javascript plain object containing HTTP headers.
"method"-
The HTTP method. Defaults to
"GET". "params"-
A javascript plain object containing query string parameters.
"path"-
The HTTP path. Defaults to
/.
The return value is a Promise that will complete if the request happens successfully, or fail if there’s a problem.
request.then()
request.then(data => { ... })
This is a standard Promise method. It sets up a handler to be called when the request finishes successfully.
The data argument contains the body result of the request. If it a
string, unless the process was opened in binary mode, in which case the
data is an array of bytes. If a request.stream() handler is set
up, then any standard output data consumed by the handler will not be
included in the data argument.
request.catch()
request.catch((exception[, data]) => { ... })
This is a standard Promise method. It sets up a handler to be called when the request fails, or returns an error code.
The exception object passed to the handler can have the following
fields:
problem-
A problem code string when a problem occurred starting or communicating with the server. This is
nullif the process exited or was terminated. status-
The numeric status of the response. This is
nullif no response was received. reason-
A string reason returned in the response. This is
nullif no response was received. message-
A string message returned in the response. This is
nullif no response was received.
If the request returned a response body, it will be available in the
data argument. Otherwise this argument will be undefined.
request.response()
request.response((status, headers) => { ... })
This sets up a handler to be called when the HTTP request gets the
initial response from the server. The status argument is the HTTP
status integer, and the headers is a plain javascript object
containing the headers of the response.
request.stream()
request.stream(data => { ... })
This sets up a handler to be called when the request returns output data. The handler will be called multiple times.
Only one handler may be registered at a time. Registering an additional
handler replaces the previous one. The handler receives either string
data or an array of binary bytes as its argument. A stream handler
may return a number, which indicates the number of characters or bytes
consumed from data. Any data not consumed will be included again the
next time the handler is called.
If a request.stream() handler is set up, then the request.then()
handlers will only get any remaining data not consumed by the stream
handler.
request.input()
request.input(data, [stream])
This method writes data to the HTTP request body. It is only valid
if no "body" has been specified in
http.request() options. If stream is
true then this function can be called again to provide further data.
request.close()
request.close([problem])
Cancel the request. If problem is specified it should be a standard
problem code string.
http.close()
http.close([problem])
Cancel all outstanding requests with the given problem code. This is useful when you know that the server is going down soon.
cockpit.js: Localization
Cockpit provides a gettext()
like API for easy translation of strings.
cockpit.language
The current locale language code. This is set based on the
cockpit.locale() data loaded.
cockpit.locale()
cockpit.locale(po)
Load locale information for a given po data. The data should be JSON
data in the po2json format. The
data will be loaded globally. If po data has already been loaded,
then this will extend that loaded data with additional strings. Any
identical translations strings will be replaced with the new strings. A
null argument clears all the locale information previously loaded.
Various methods such as
cockpit.gettext() make use of the
loaded data.
cockpit.gettext()
translated = cockpit.gettext([context], string)
var _ = cockpit.gettext
var C_ = cockpit.gettext
translated = _("string")
translated = C_("context", "string")
Lookup string for translation in the loaded locale data. The
translated string will be returned, or string will be returned if no
such translated string is present. The context argument is an
optional string used to qualify the string.
This function can be assigned to a variable called _ (underscore)
which will make your code work with the typical _("string") syntax.
cockpit.noop()
var N_ = cockpit.noop var NC_ = cockpit.noop
A noop function suitable for assigning to N_ or NC_ so that
gettext scanners will be able to find translatable strings. More
specifically this function returns its last argument.
cockpit.ngettext()
translated = cockpit.ngettext([context], string1, stringN, number)
Lookup a string appropriate for a pluralization form of the number.
Various languages have complex pluralization forms that go far between
the singular and plural forms speakers of English are familiar with. If
no such translated string is found then either one of string1 or
stringN is returned according to simple pluralization rules.
The context argument is an optional string used to qualify the
string.
cockpit.translate()
cockpit.translate() cockpit.translate(element, ...) cockpit.translate(selection)
The document will be scanned for translate tags and they will be
translated according to the strings in loaded locale data. One or more
element arguments may be specified. These are DOM elements for
specific parts of the document to be translated. If no element is
specified then the entire document is translated.
If an array or array-like object is passed as a selection then all
DOM elements in the array will be treated as parts of the document to be
translated.
cockpit.js: Page Location and Jumping
Page location and navigation between components
Page location
location = cockpit.location cockpit.location = "/path"
Cockpit components often have different views, without changing the HTML
file that is being viewed. These are known as pages.
cockpit.location is an object that can be used to read the current
page and to navigate to a different page location. It works by updating
window.location.hash.
The cockpit.location looks like a HTTP path with a possible query
string:
/path/sub/page?option=value,option2
The location.path and
location.options contain a parsed
form of the location. While the location cannot be modified in place, a
new one can be created by assigning a string to cockpit.location or
by calling the location.go() function.
cockpit.location is designed similarly to window.location in
that the location object is preplaced whenever the current page location
changes. To be aware of when the page location changes listen for the
cockpit.onlocationchanged event.
Using the location object as a string will result in the
location.href.
location.href
The string representation of this page location, including any options.
location.path
An array of path segments, parsed and decoded appropriately. An empty array denotes the root path.
location.options
A javascript object containing the various options present in the location.
If an option appears more than once, its value will be an array.
location.go()
location.go(path, [options])
Changes the current location to the given path and options. If
the path argument is a string, it will be parsed into a path. If it
is a relative path, then the result will be relative to the current
location.path. If the path argument is an array of path
segments, it will be treated as a full parsed absolute path.
Any options found in a path will be added to those in the optional
options argument, and used in the result.
The location change will only take effect if the location has not
changed in the meantime. This can be to good effect by saving a
cockpit.location object and doing a conditional navigation, by
calling the saved location.go() method later. This will only
navigate if the user or other code has not navigated in the meantime.
location.replace()
location.replace(path, [options])
Similar to location.go() except the
location change will not result in a navigation change in the browser’s
history.
location.decode()
path = location.decode(href, [options])
Decode a cockpit href into its path array. If the options
argument is specified, then it will be populated with options found in
the href.
If href is a relative path it will be resolved relative to
location.href.
location.encode()
href = location.encode(path, [options])
Encode the given path and options into a cockpit href. The
path argument may be an array of path segments, or a string path. If
a relative path is passed, it will be resolved relative to
location.href.
cockpit.onlocationchanged
cockpit.addEventListener("locationchanged", function() { ... })
An event emitted when over the cockpit.location changes. Typically a
component reacts to this event by updating its interface to reflect the
new cockpit.location.path and
cockpit.location.options.
This event is not triggered immediately during a location.go() or
similar call. It will be triggered asynchronously at a later time.
Jumping between components
cockpit.jump("/system/log")
In Cockpit in there multiple components shown. In order to tell Cockpit
to jump to and show another component and a certain location within that
component, use the cockpit.jump() function. Stable component paths
are documented. Don’t assume you can navigate into paths that are not
stable API.
cockpit.jump()
cockpit.jump(path, [ host ])
Ask Cockpit to jump to another component. The location of the current
component will not be affected. The path argument can be a string
path, starting with / or an array containing the parts of a path
that will be joined to create a path. If host is not specified, then
the component on the same host as the caller will be displayed. If host
is null, then the host portion of the path will be removed, displaying
the component on the host that cockpit is connected directly to.
If the calling component is not running within Cockpit, or the calling component is not currently displayed, then the jump will not happen, and this function has no effect.
cockpit.hidden
A boolean property that indicates if the current component page is
visible or hidden. When the code or user jumps to another component, the
prior one remains loaded and initialized but is hidden. Use this
property together with the
cockpit.onvisibilitychange
event to decide whether or not to perform expensive tasks to update the
interface.
This property is analogous to the document.hidden page visibility
API, but works with the document and frame implementation of Cockpit.
cockpit.onvisibilitychange
cockpit.onvisibilitychange = function() { ... }
This event is emitted when the
cockpit.hidden property changes. This
event is similar to the document.onvisibilitychange API, but works
with the document and frame implementation of Cockpit.
cockpit.js: User Session
User information and login session state
cockpit.logout()
cockpit.logout([reload])
Logout of Cockpit. Unless reload is false this will also cause
the page to be reloaded, so that the user can see the logged out state.
cockpit.user()
var promise = cockpit.user();
promise.then(user => { ... });
This object contains information about the user that’s currently logged into cockpit. The following fields are defined:
"id"-
This is unix user id.
"gid"-
This is unix user group id.
"name"-
This is the unix user name like
"root". "full_name"-
This is a readable name for the user.
"groups"-
This is an array of group names to which the user belongs. Since version 318, the first item in this list is the primary group.
"home"-
This is user’s home directory.
"shell"-
This is unix user shell.
Returns a promise that completes once the user information is available.
|
Warning
|
|
Permission lookup
Cockpit provides a mechanism for checking if the current user satisfies a given criteria. This is meant for updating UI elements based on what actions the user can perform. It is not an access control mechanism.
cockpit.permission()
permission = cockpit.permission([options])
Create a new permission object to check if the current user has a
particular permission specified by options:
admin: true-
True if the session has superuser privileges, i.e. can run channels as root with
{ superuser: "require" }. group:name-
True if the currently logged user is a member of group name.
The permission result is always true for the "root" user. When
options is not given, check if the current user is root.
permission.allowed
A boolean value which indicates if the permission is allowed or not.
This will be null if the permission is unknown, or there was an
error checking the permission or the permission data has not yet loaded.
This property will update asynchronously and if you wish to be notified
of changes connect to the
permission.onchanged event.
permission.onchanged
permission.addEventListener("changed", function() { ... })
This event is fired when the permission changes. In particular the permission.allowed property.
permission.close()
permission.close()
Closes the permission object and tears down any registered callbacks and dbus subscriptions.
cockpit.js: Manifests
Loading Manifests
For a convenient access to all page manifests, include
<script src="../manifests.js"></script> into your page to register
the manifests at the cockpit.manifests global variable.
You can also load ../manifests.json directly in your page, with
fetch().
cockpit.js: Metrics
Metrics about the system can be retrieved from several sources using
cockpit.metrics() metrics channels. The
metrics are made available as series data, and can be used with the
cockpit.series() and
cockpit.grid() facilities.
cockpit.metrics()
metrics = cockpit.metrics(interval, options, cache)
Opens a new metrics channel. The data retrieved will be available in the
metrics.series series sink, and can be
used together with cockpit.grid() objects.
The interval is in milliseconds, and is the granularity of the
series data retrieved. Any grids consuming the data must have the same
interval.
The cache argument is a cache identifier. If specified, then this
metrics channel will share data with other metrics channels of the same
identifier. Make sure to use a globally unique string.
The options argument is either a javascript plain object, or an
array of those. Each object can have the following fields.
"metrics"-
An array of full metric descriptions, as javascript objects. The specifics of these, and how to determine which ones to use, can unfortunately only be found in the low-level protocol documentation. This option is required.
"source"-
The source to use for real-time data. This is used by the
followmethod, see below. Set to"internal"to retrieve internal metrics read by the bridge. If set to"direct"or"pmcd"then data will be retrieved from PCPif it is available. The default is"internal". "archive_source"-
The source to use for retrieving historical data. This is used by the
fetchmethod, see below. Set to"pcp-archive"to retrieve data from PCP archives. The default is not to try to retrieve historical data.
When the options argument is an array of javascript objects, then
the metrics channel tries to use them in order until one succeeds. This
way, you can prefer PCP as the source but fall back to internal metrics
when PCP is not available, for example. The channel gives no indication
which of the options has been used, and fetch and follow might
use different entries from the list.
metrics.fetch()
metrics.fetch(beg, end)
Retrieve archived metrics data between beg and end. The
arguments can either be numbers, in which case they are interval based
offsets, or they can be javascript Date objects.
metrics.follow()
metrics.follow()
Start retrieving live metrics data as it become available.
metrics.close()
metrics.close()
Stop the retrieval of metrics and release resources.
metrics.series
The series sink where data retrieved data will be processed.
metrics.meta
The metrics meta data last received.
metrics.onchanged
metrics.onchanged = function() { }
An event triggered when one of the properties on this metrics object changes.
cockpit.js: Series Data
Series data consists of values along a continuous (usually time) axis. We can place these in grids which expose a distinct subset of these values. These are the underlying mechanism for displaying metrics data in graphs.
cockpit.grid()
grid = cockpit.grid(interval, [beg, end])
Creates a grid object to contain series data.
The interval is the granularity of the grid. Usually this is a
number of milliseconds, when used with time series data. The beg and
end are the bounds of the grid. If omitted they will be set to zero
for an initially empty grid.
If beg and/or end are negative (including negative zero) then
they are interpreted in number of intervals relative to the current
time. Thus cockpit.grid(1000, -300, -0) will create a grid for the most
recent 5 minutes.
grid.add()
row = grid.add(series, path) row = grid.add(callback, [early]) row = grid.add()
Adds a row to the grid. The returned row is a Javascript array that
will contain series data. The arguments control how the row is populated
from the series data. The row is a sparse array. Its row.length
will not match the expected size of the grid, unless and until the row
has been completely filled in. The first index of the row will
contain the data from the series data at the
grid.beg offset.
When no arguments are passed, an empty row is added, and it is not populated with data.
When called with a series and path argument then the row will be
populated directly with series data. The series can either be a
series object or an object that has an
obj.series property. The series
interval must match the interval of this grid. If path is missing
or empty, then the series data is placed into the row directly.
Otherwise path indicates which part of the series data to place in
the row. When path is an array, it is used as a set of property
names or array indexes to follow into nested series data. When path
is a dotted string, it is split and used the same way to locate the
correct value in nested series data. The exact format of the series data
depends on its producer, and relevant paths will be documented there.
If a callback function is specified, then it will be invoked to
provide series data for the row. The function is invoked as
callback(row, index, count), where the row is the row to fill
in, the index is the index to start filling in and count is the
number of items to fill in. The this variable will be set to the
grid while invoking the callback. The callback is called after other
data rows for a given series have been filled in. Callbacks are called
in the order added, unless the early argument is set to true, in
which case the callback is called earlier than callbacks without the
early argument set.
To remove the row use the grid.remove()
method.
The row will start being populated with data when the series
produces data. To make this happen right away, use the
grid.sync() method.
grid.remove()
grid.remove(row)
Remove a previously added row from the grid. The row will no longer
be updated with series data.
grid.sync()
grid.sync()
Load or reload data from the series into the rows. This does not clear
the rows before populating them. Some data may be populated immediately,
others may have to wait until data can be loaded. Internally this
function calls series.load() for each
series.
All rows with callbacks will be invoked to regenerate all the data. The
grid.onnotify event will be triggered.
It is not necessary to call this function after a call of the
grid.move() method.
grid.move()
grid.move(beg[, end])
Move the grid to new beg and end range. Data will be discarded
from the rows and grid.sync() will be
called to load or reload series data for the new range of offsets.
If end is not specified it will be set to beg. If beg and/or
end are negative (including negative zero) then they will be set to
the number of intervals prior to the current time taken as an interval.
If beg and/or end are negative (including negative zero) then
they are interpreted in number of intervals relative to the current
time. Thus cockpit.grid(1000, -300, -0) will create a grid for the most
recent 5 minutes.
grid.walk()
grid.walk()
Move the grid forward every
grid.interval milliseconds. To stop
moving forward, call grid.move().
grid.notify()
grid.notify(index, count)
This function is called to have rows with callbacks recalculate their
data. It is not normally necessary to call this function, as it will be
invoked automatically when new series data is available or has been
loaded. This function triggers the
grid.onnotify event.
grid.onnotify
grid.addEventListener("notify", function(index, count) { ... });
An event that is triggered when some part of the series data in grid
changes. The index is the row index where things changed, and the
count is the length of the data that changed.
grid.close()
grid.close()
Close the grid, and stop updating the rows.
grid.interval
grid.beg
The beginning offset of the series data in the grid. Do not set this property directly. Use the grid.move() method instead.
grid.end
The ending offset of the series data in the grid. Do not set this property directly. Use the grid.move() method instead.
cockpit.series()
series = cockpit.series(interval, [cache, fetch])
Create a new sink of series data. This is usually done by producers of series data, and it is rare to invoke this function directly.
The interval is the granularity of the series data. For time series
data this is an interval in milliseconds. If a cache string is
specified, series data will be cached across frames for series with the
same cache cache identifier to load and/or reload.
If a fetch callback is specified, then it will be invoked when grids
request certain ranges of data. The fetch callback is invoked with
function fetch(beg, end) { ... } range offsets. The
series.input() should be called with data
retrieved, either immediately or at a later time. The callback may be
called multiple times for the same ranges of data. It is up to the
callback to determine when or whether it should retrieve the data more
than once.
A producer of series data, usually calls this function and creates
itself a obj.series property containing this series object.
series.input()
series.input(beg, items[, mapping])
Send series data into the series sink. Any grids that have added rows
based on this series, will have data filled in. The beg is the
beginning offset of items. The items are an array one or more
series data items.
Producers may wish to provide additional properties that can be used in
lookup paths that rows can pull from. This is done in the mapping
argument. If specified it is a tree of objects. Each sub object should
have a property with the name "" empty string, which will be used as
the property name or index in place of the one used in the lookup path.
series.load()
series.load(beg, end)
Load data from the series into any grids that have rows based on this series data. Any cached data will be filled in immediately. Any data not cached, will be requested from the producer, if possible, and may arrive at a later time.
The beg and end denote the range of data to load.
series.interval
series.limit
The maximum number of items to cache for loading and/or reloading. You
can change this value to a different number. Having a number close to
zero will break certain usage of grids, such as
grid.walk().
cockpit.js: Spawning Processes
This is the API for spawning a process and receiving its output, as well as exit codes.
cockpit.spawn()
process = cockpit.spawn(args, [options])
Spawns a process on the system.
The args should be an array starting with the executable and
containing all the arguments to pass on the command line. If args is
a string then it is interpreted as an executable name. The optional
options argument is a javascript plain object and can contain any of
the following fields:
"binary"-
If set to
truethen handle the input and output of the process as arrays of binary bytes. "directory"-
The directory to spawn the process in.
"err"-
Controls where the standard error is sent. By default it is logged to the journal. If set to
"out"it is included in with the output data. If set to"ignore"then the error output is discarded. If set to"message", then it will be returned as the error message. When the"pty"field is set, this field has no effect. "environ"-
An optional array that contains strings to be used as additional environment variables for the new process. These are
"NAME=VALUE"strings. "pty"-
Launch the process in its own PTY terminal, and send/receive terminal input and output.
"batch"-
Batch data coming from the process in blocks of at least this size. This is not a guarantee. After a short timeout the data will be sent even if the data doesn’t match the batch size. Defaults to zero.
"latency"-
The timeout for flushing any cached data in milliseconds.
"superuser"-
Set to
"require"to spawn the process as root instead of the logged in user. 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 run the process as root, but if that fails, fall back to an unprivileged process.
The spawned process is a promise that will complete if the process exits successfully, or fail if there’s a problem. Some additional methods besides the standard promise methods are documented below.
The standard output of the process is made available via the spawned process object. Any non-UTF8 output from the process will be coerced into textual form. It is highly recommended that only textual output be produced by the command. The standard error is logged to the journal.
cockpit.script()
process = cockpit.script(script, [args], [options])
Run a shell script on the system.
This function spawns a Bourne shell script
process. The full text of the /bin/sh shell script should be passed
in as the first argument. The args can be an array of arguments, not
including the executable, which are passed to the script as $1,
$2 and so on. Shebang options are not used or respected.
The options is an optional javascript plain object and can include
any of the fields listed for the
cockpit.spawn() function.
The spawned process is a promise that will complete if the script exits successfully, or fail if there’s a problem. Some additional methods besides the standard promise methods are documented below.
The standard output of the process is made available via the spawned process object. Any non-UTF8 output from the process will be coerced into textual form. It is highly recommended that only textual output be produced by the command. The standard error is logged to the journal by default.
process.then()
process.then((data[, message]) => { ... })
This is a standard promise method. It sets up a handler to be called when the process finishes successfully.
The data argument contains the standard output of the process. If it
a string, unless the process was opened in binary mode, in which case
the data is an array of bytes. If a process.stream() handler is
set up, then any standard output data consumed by the handler will not
be included in the data argument.
If the process was spawned with the "err" option set to
"message" then the second argument will contain the standard error
output of the process.
process.catch()
process.catch((exception[, data]) => { ... })
This is a standard Promise method. It sets up a handler to be called when the process fails, terminates or exits.
The exception object passed to the handler can have the following
fields:
message-
A message describing the exception. If the process was spawned with the
"err"option set to"message"then the second argument will contain the standard error output of the process. problem-
A problem code string when a problem occurred starting or communicating with the process. This is
nullif the process exited or was terminated. exit_status-
The numeric exit status of the process. This is
nullif the process did not exit. exit_signal-
A string representing a unix signal that caused the process to terminate. This is
nullif the process did not terminate because of a signal.
If the process actually ran and produced output before failing, it will
be available in the data argument. Otherwise this argument will be
undefined.
process.stream()
process.stream(data => { ... })
This sets up a handler to be called when the process has standard output. The handler will be called multiple times. The handler will be called regardless of whether the process ends up exiting successfully or not.
Only one handler may be registered at a time. Registering an additional
handler replaces the previous one. The handler receives either string
data or an array of binary bytes as its argument. A stream handler
may return a number, which indicates the number of characters or bytes
consumed from data. Any data not consumed will be included again the
next time the handler is called.
If a process.stream() handler is set up, then the process.then()
handlers will only get any remaining data not consumed by the stream
handler.
process.input()
process.input(data, [stream])
This method writes data to the standard input of the process. If
data is null or undefined it is not sent. The data
should be a string or an array of bytes if the process was opened in
binary mode.
If stream is set to true then this function may be called again
with further input. Otherwise the standard input of the process is
closed.
process.close()
process.close([problem])
Close the process by closing its standard input and output. If
problem is specified it should be a standard
problem code string. In this case the process
will be terminated with a signal.
cockpit.js: Utilities
Various utility functions
cockpit.format()
string = cockpit.format(template, args) string = cockpit.format(template, [arg, ...])
Format a string interpolating args into template using shell
like syntax. The args may be either an array or javascript object.
The template can contain fields that look like $name or
${name} or $0. Numeric fields are used with array args and
start at zero.
In the second form, multiple arg arguments may be passed directly,
and interpolated as as numeric fields in the template.
All falsy arguments except the numbers 0 and `0.0`are replaced by
an empty string.
cockpit.format_number()
string = cockpit.format_number(number, [precision])
Formats number into a displayable string. If the number is not
an integer, it is rounded to the given number of decimal places,
defaulting to 3. If the number is near zero, but not quite zero it is
rounded to the smallest non-zero value of the given precision; i.e.
±0.001 for default precision 3.
If number is null or undefined an empty string will be
returned.
cockpit.format_bytes()
string = cockpit.format_bytes(number, [options])
Formats number into a displayable string with a suffix, such as
kB or MB.
By default, SI units are used. IEC units (1024-based) can be requested
by including base2: true in options.
By default, non-integer numbers will be formatted with 3 digits of
precision. This can be changed with options.precision.
If number is null or undefined an empty string will be
returned.
cockpit.format_bytes_per_sec()
string = cockpit.format_bytes_per_sec(number, [options])
Format number of bytes into a displayable speed string.
This function is mostly equivalent to cockpit.format_bytes() but the
returned value contains a unit like kB/s or MB/s.
cockpit.format_bits_per_sec()
string = cockpit.format_bits_per_sec(number, [options])
Format number of bits into a displayable speed string.
This function is mostly equivalent to cockpit.format_bytes() but the
returned value contains a unit like kbps or Mbps.
This function does not support IEC units. base2 may not be passed as
part of options.
cockpit.init()
await cockpit.init();
cockpit.init().then(() => { ... });
Requests initialization of the Cockpit client library. This will ensure
that the transport is connected and we are ready to create channels. It
also populates the cockpit.info field.
This function returns a promise. Initialization isn’t complete until the
promise has resolved. You can either await it or call .then() on
it.
cockpit.info
cockpit.info.channels[payload] cockpit.info.os_release[field] cockpit.info.user cockpit.info.ws.version
This object contains information about Cockpit itself. It is only available after cockpit.init() has been called and awaited.
channels-
This is a mapping of channel payload types (keys, strings) supported by the bridge to capabilities advertised by those channels (values, lists of strings). Channels are listed even if they don’t advertise any capabilities, making this useful as a way to determine which channel types are supported by the bridge.
os_release-
This is the data from the
/etc/os-releaseor/usr/lib/os-releaseon the system that the bridge is running on. It is a mapping from the key names to their values. See the os-release Specification for information about the available keys. user-
Contains information about the user we’re logged in as.
uid-
This is unix user id as an integer.
gid-
This is unix user group id as an integer.
name-
This is the unix user name like
"root". fullname-
This is a readable name for the user, from the GECOS field.
group-
This is the primary group name of the user.
groups-
This is an array of group names to which the user belongs. The first item in this list is the primary group.
home-
This is user’s home directory.
shell-
This is unix user shell.
ws-
Contains information about the webserver Cockpit is being served with.
version-
The version of the webserver.
cockpit.event_target
cockpit.event_target(object, [handlers])
Adds an
EventTarget
implementation to the object. Optionally store the handlers in
handlers if its specified.