doc: Fix formatting

Replace tabs with spaces, and use proper Markdown verbatim syntax.

Mark the JSON and CSS code blocks as such for proper syntax highlighting
and inline editor validation, and fix the various comma and quoting
errors.
This commit is contained in:
Martin Pitt 2024-09-19 08:21:00 +02:00 committed by Martin Pitt
parent 44a60b913a
commit 5ce7b4ce73
5 changed files with 275 additions and 219 deletions

View file

@ -26,7 +26,7 @@ Anaconda needs to tell Cockpit which devices can be used to install
the OS on. This is done with the "available_devices" entry, which is
an array of strings.
```
```json
{
"available_devices": [ "/dev/sda" ]
}
@ -42,7 +42,7 @@ Mount point prefix
Cockpit can be put into a kind of "chroot" environment by giving it a
mount point prefix like so:
```
```json
{
"mount_point_prefix": "/sysroot"
}
@ -68,7 +68,7 @@ created easily.
This is done by setting the "efi" flag to true or false:
```
```json
{
"efi": true
}
@ -83,7 +83,7 @@ back to the type of the filesystem mounted as "/". When in Anaconda
mode, there might not be anything assigned to "/" yet, and in this
case, Cockpit will use the type from "default_fsys_type".
```
```json
{
"default_fsys_type": "xfs"
}
@ -99,11 +99,11 @@ is mostly information from fstab.
The "cockpit_mount_points" entry in local storage will have a JSON
encoded object, for example:
```
```json
{
"/dev/sda": {
"type": "filesystem",
"dir": "/",
"dir": "/"
},
"/dev/sdb": {
"type": "swap"
@ -113,7 +113,7 @@ encoded object, for example:
"content": {
"type": "filesystem",
"subvolumes": {
"home": { dir: "/home" }
"home": { "dir": "/home" }
}
}
}
@ -160,5 +160,4 @@ Cockpit also remembers and exports encryption passphrases in session
storage, in the "cockpit_passphrases" entry. This is a map from device
names to cleartext passphrases. This is only done when Cockpit runs in
a "secure context", see
https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts
https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts

View file

@ -10,7 +10,7 @@ system itself, and are incorporated into the branding.
## How Cockpit Selects Branding
In ```$prefix/share/cockpit/branding``` are multiple directories, each of which
In `$prefix/share/cockpit/branding` are multiple directories, each of which
contain branding information. Branding files are served from the directories
based in the order below, if a file is not present in the first directory on
the list, the second will be consulted, and so on.
@ -20,8 +20,8 @@ the list, the second will be consulted, and so on.
$prefix/share/cockpit/branding/default
$prefix/share/cockpit/static
The ```$ID``` and ```$VARIANT_ID``` variables are those listed in ```/etc/os-release```,
and ```$prefix``` is usually ```/usr```.
The `$ID` and `$VARIANT_ID` variables are those listed in `/etc/os-release`,
and `$prefix` is usually `/usr`.
All of the files served from these directories are available over HTTP
without authentication. This is required since these resources will be used
@ -43,32 +43,34 @@ on the system.
## Branding Styles
The Cockpit login screen and navigation area loads a ```branding.css``` file
The Cockpit login screen and navigation area loads a `branding.css` file
from the above directories.
The branding.css file should override the following areas of the login screen:
/* Background of the login prompt */
body.login-pf {
background: url("my-background-image.jpg");
background-size: cover;
}
```css
/* Background of the login prompt */
body.login-pf {
background: url("my-background-image.jpg");
background-size: cover;
}
/* Upper right logo of login screen */
#badge {
width: 225px;
height: 80px;
background-image: url("logo.png");
background-size: contain;
background-repeat: no-repeat;
}
/* Upper right logo of login screen */
#badge {
width: 225px;
height: 80px;
background-image: url("logo.png");
background-size: contain;
background-repeat: no-repeat;
}
/* The brand text above the login fields */
#brand {
font-size: 18pt;
text-transform: uppercase;
content: "${NAME} <b>${VARIANT}</b>";
}
/* The brand text above the login fields */
#brand {
font-size: 18pt;
text-transform: uppercase;
content: "${NAME} <b>${VARIANT}</b>";
}
```
Notice how we can use variables from ```/etc/os-release``` in the branding.
Notice how we can use variables from `/etc/os-release` in the branding.
The value for these variables come from the machine that cockpit is logged into.

View file

@ -10,12 +10,12 @@ header is built like this.
Basic base64(user:password)
```
A successful response is a 200 http code with a json body that contains a ```user``` field with the user
A successful response is a 200 http code with a json body that contains a `user` field with the user
name of the user that was just logged in. Additional fields may be present
Other http codes are considered errors. Generally these are 401 or 403 http status codes.
In most cases the error can detrived from the status text. Examples are
```authentication-failed```, ```authentication-unavailable``` or ```access-denied```
`authentication-failed`, `authentication-unavailable` or `access-denied`
In some cases additional error messages may be included.
In some authentication setups additional steps are required. When this happens cockpit will

View file

@ -55,11 +55,13 @@ Control messages are always sent in the control channel. They always have an
empty channel. The payload of a control message is always a json
object. There is always a "command" field:
{
"command": <command>,
"channel": <channel>,
...
}
```
{
"command": <command>,
"channel": <channel>,
...
}
```
If a control message pertains to a specific channel it has a "channel" field
containing the id of the channel. It is invalid to have a present but empty
@ -125,12 +127,14 @@ The channel id must not already be in use by another channel.
An example of an open:
{
"command": "open",
"channel": "a4",
"payload": "stream",
"host": "localhost"
}
```json
{
"command": "open",
"channel": "a4",
"payload": "stream",
"host": "localhost"
}
```
This message is sent to the cockpit-bridge.
@ -176,30 +180,33 @@ wish to throttle the data that they're sending to the bridge.
Because the host parameter is how cockpit maps url requests to the correct bridge,
cockpit may need to additional information to route the message correctly.
For example you want to connect to a container ```my-container``` running
For example you want to connect to a container `my-container` running
on "my.host".
To allow this the host parameter can encode a key/value pair that will
be expanded in the open command json. The format is host+key+value. For example
{
"command": "open",
"channel": "a4",
"payload": "stream",
"host": "my.host+container+my-container"
}
```json
{
"command": "open",
"channel": "a4",
"payload": "stream",
"host": "my.host+container+my-container"
}
```
will be expanded to
{
"command": "open",
"channel": "a4",
"payload": "stream",
"host": "my.host",
"host-container": "my-container",
"host": "my.host"
}
```json
{
"command": "open",
"channel": "a4",
"payload": "stream",
"host": "my.host",
"host-container": "my-container",
"host": "my.host"
}
```
Command: close
--------------
@ -213,11 +220,13 @@ The following fields are defined:
The channel id must be set. An example of a close:
{
"command": "close",
"channel" : "5x",
"problem": "access-denied"
}
```json
{
"command": "close",
"channel" : "5x",
"problem": "access-denied"
}
```
Any protocol participant can send this message. The cockpit-bridge and cockpit-ws
backends will send this message when a channel closes whether because of an
@ -236,9 +245,11 @@ The "auth-method-results" object contains a key for each method that cockpit-ws
is able to attempt authentication with as well as the result of the attempt.
For example:
{
"password": "denied"
}
```json
{
"password": "denied"
}
```
This possible "result" values are:
@ -304,9 +315,11 @@ is set this "ping" will be forwarded. Otherwise it be limited to a single hop.
An example of a ping:
{
"command": "ping",
}
```json
{
"command": "ping"
}
```
Any protocol participant can send a "ping". It is responded to by sending
a "pong" with identical options as a reply. If a "ping" is sent with a
@ -331,27 +344,33 @@ For challenge/response authentication, the following fields are defined:
Example authorize challenge and response messages:
{
"command": "authorize",
"cookie": "555",
"challenge": "crypt1:74657374:$6$2rcph,noe92ot..."
}
```json
{
"command": "authorize",
"cookie": "555",
"challenge": "crypt1:74657374:$6$2rcph,noe92ot..."
}
```
{
"command": "authorize",
"cookie": "555",
"response": "crypt1:$6$r0oetn2039ntoen..."
}
```json
{
"command": "authorize",
"cookie": "555",
"response": "crypt1:$6$r0oetn2039ntoen..."
}
```
Authorize messages are used during authentication by authentication
commands (ei: cockpit-session, cockpit-ssh) to obtain the users credentials
from cockpit-ws. An authentication command can send a authorize message
with a response but no cookie. For example
{
"command": "authorize",
"response": "Basic ..."
}
```json
{
"command": "authorize",
"response": "Basic ..."
}
```
In that case cockpit-ws will store the response and use it in a reply
to a subsequent challenge.
@ -438,10 +457,12 @@ is received, then the channel is closed with a "protocol-error".
Method calls are a JSON object with a "call" field, whose value is an array,
with parameters in this order: path, interface, method, in arguments.
{
"call": [ "/path", "org.Interface", "Method", [ "arg0", 1, "arg2" ] ],
"id": "cookie"
}
```json
{
"call": [ "/path", "org.Interface", "Method", [ "arg0", 1, "arg2" ] ],
"id": "cookie"
}
```
All the various parameters must be valid for their use. arguments may be
null if no DBus method call body is expected. If a "type" field is specified
@ -468,26 +489,30 @@ Method reply messages are JSON objects with a "reply" field whose value is
an array, the array contains another array of out arguments, or null if
the DBus reply had no body.
{
"reply": [ [ "arg0", 1, 2 ] ],
"id": "cookie"
}
```json
{
"reply": [ [ "arg0", 1, 2 ] ],
"id": "cookie"
}
```
If the call had a "type" field, then the reply will have one too containing
the DBus type signature of the arguments. If a "flags" field was present on
the call, then "flags" will also be present on the reply. Valid out flags
are:
* ">": Big endian message
* "<": Little endian message
* `>`: Big endian message
* `<`: Little endian message
An error message is JSON object with an "error" field whose value is an
array. The array contains: error name, error arguments
{
"error": [ "org.Error", [ "Usually a message" ] ]
"id": "cookie"
}
```json
{
"error": [ "org.Error", [ "Usually a message" ] ],
"id": "cookie"
}
```
To receive signals you must subscribe to them. This is done by sending a
"add-match" message. It contains various fields to match on. If a field
@ -506,15 +531,17 @@ given string as their first argument. If any of the values are not
valid according to the dbus specification, the channel will close with
a "protocol-error".
{
"add-match": {
"name": "org.the.Name",
"path": "/the/path",
"interface": "org.Interface",
"member": "SignalName",
"arg0": "first argument",
}
```json
{
"add-match": {
"name": "org.the.Name",
"path": "/the/path",
"interface": "org.Interface",
"member": "SignalName",
"arg0": "first argument"
}
}
```
If the "name" field is omitted, it will be populated from the "open" message.
If no "name" was specified in the "open" message, then DBus messages from any
@ -526,31 +553,37 @@ times before the signals are actually unsubscribed.
The form of "remove-match" is identical to "add-match".
{
"remove-match": {
"name": "org.the.Name",
"path": "/the/path",
"interface": "org.Interface",
"member": "SignalName",
"arg0": "first argument",
}
```json
{
"remove-match": {
"name": "org.the.Name",
"path": "/the/path",
"interface": "org.Interface",
"member": "SignalName",
"arg0": "first argument"
}
}
```
Signals are sent in JSON objects that have a "signal" field, which is an
array of parameters: path, interface, signal name, and arguments. arguments
may be null if the DBus signal had no body.
{
"signal": [ "/the/path", "org.Interface", "SignalName", [ "arg0", 1, 2 ] ]
}
```json
{
"signal": [ "/the/path", "org.Interface", "SignalName", [ "arg0", 1, 2 ] ]
}
```
If a signal message is sent to the bridge, the signal will be emitted.
In addition a "destination" field may be present to indicate whether
the signal should be broadcast or not.
{
"signal": [ "/the/path", "org.Interface", "SignalName", [ "arg0", 1, 2 ] ]
}
```json
{
"signal": [ "/the/path", "org.Interface", "SignalName", [ "arg0", 1, 2 ] ]
}
```
If the bus name of the sender of the signal does not match the "name" field of
the "open" message, then a "name" field will be included with the "signal" message.
@ -563,23 +596,27 @@ interfaces, otherwise DBus introspection is used. The "id" field is
optional, if present a "reply" will be sent with this same "id" when
the watch has sent "notify" messages about the things being watched.
{
"watch": {
"name": "org.the.Name",
"path": "/the/path/to/watch",
"interface": org.Interface
}
"id": 5
}
```json
{
"watch": {
"name": "org.the.Name",
"path": "/the/path/to/watch",
"interface": "org.Interface"
},
"id": 5
}
```
To remove a watch, pass the identical parameters with an "unwatch"
request.
{
"unwatch": {
"path": "/the/path/to/watch"
}
```json
{
"unwatch": {
"path": "/the/path/to/watch"
}
}
```
If the "name" field is omitted, it will be populated from the "open" message.
Either a "name" field must be specified here or in the "open" message.
@ -589,20 +626,22 @@ addition of interfaces without properties, which will be an empty
interface object, or interfaces removed, which will be null. Only the
changes since the last "notify" message will be sent.
{
"notify": {
"/a/path": {
"org.Interface1": {
"Prop1": x,
"Prop2": y
},
"org.Interface2": { }
```json
{
"notify": {
"/a/path": {
"org.Interface1": {
"Prop1": "x",
"Prop2": 1
},
"/another/path": {
"org.Removed": null
}
"org.Interface2": { }
},
"/another/path": {
"org.Removed": null
}
}
}
```
If the bus name of the sender of the signal does not match the "name" field of
the "open" message, then a "name" field will be included with the "notify" message.
@ -612,20 +651,22 @@ first time an interface is sent using a "notify" message, a "meta"
will be sent with that interface introspection info. Additional fields
will be defined here, but this is it for now.
{
"meta": {
"org.Interface": {
"methods": {
"Method1": { },
"Method2": { }
},
"properties": {
"Prop1": { "flags": "rw" },
"Prop2": { "flags": "r" }
}
```json
{
"meta": {
"org.Interface": {
"methods": {
"Method1": { },
"Method2": { }
},
"properties": {
"Prop1": { "flags": "rw" },
"Prop2": { "flags": "r" }
}
}
}
}
```
If the bus name of the sender of the signal does not match the "name" field of
the "open" message, then a "name" field will be included with the "meta" message.
@ -636,9 +677,11 @@ When the owner of the DBus "name" (specified in the open message) changes an "ow
message is sent. The owner value will be the id of the owner or null if the name
is unowned.
{
"owner": "1:"
}
```json
{
"owner": "1:"
}
```
A "publish" message can be used to export DBus interfaces on the bus. The bridge
will then send "call" messages back to the frontend for each method invocation
@ -647,17 +690,21 @@ with DBus meta information. If a cookie is specified then a reply will be sent
when the interface is published. If the interface is already published at the given
path, it will be replaced.
{
"publish": [ "/a/path", "org.Interface" ],
"id": "cookie"
}
```json
{
"publish": [ "/a/path", "org.Interface" ],
"id": "cookie"
}
```
An "unpublish" message will unexport a DBus interface on the bus. It is not an
error if no such interface has been published.
{
"unpublish": [ "/a/path", "org.Interface" ],
}
```json
{
"unpublish": [ "/a/path", "org.Interface" ]
}
```
DBus types are encoded in various places in these messages, such as the
arguments. These types are encoded as follows:
@ -674,10 +721,12 @@ arguments. These types are encoded as follows:
* variant: encoded as a JSON object with a "v" field containing a value
and a "t" field containing a DBus type signature.
{
"v": "value",
"t": "s"
}
```json
{
"v": "value",
"t": "s"
}
```
Payload: http-stream2
---------------------
@ -1188,12 +1237,16 @@ The general open options are:
You specify the desired metrics as an array of objects, where each
object describes one metric. For example:
[ { name: "kernel.all.cpu.user",
units: "millisec",
derive: "rate"
},
...
]
```json
[
{
"name": "kernel.all.cpu.user",
"units": "millisec",
"derive": "rate"
},
...
]
```
A metric description can contain the following fields:
@ -1256,6 +1309,7 @@ message, and more fields might be present in the objects of the
The 'data' messages are nested arrays in this shape:
```
[ // first point in time
[
// first metric (instanced, with two instances)
@ -1275,10 +1329,11 @@ The 'data' messages are nested arrays in this shape:
// same shape again as for the first point in time
]
]
```
Thus, a 'data' message contains data for one or more points in time
where samples have been taken. A point in time is always one
"interval" later than the previous point in time, even when they are
`interval` later than the previous point in time, even when they are
reported in the same 'data' message.
For real time monitoring, you will generally only receive one point in
@ -1287,12 +1342,12 @@ might report multiple points in time in one message, to improve
efficiency.
For each point in time, there is an array with samples for each
metric, in the same order as the "metrics" option used when opening
metric, in the same order as the `metrics` option used when opening
the channel.
For non-instanced metrics, the array contains the value of the metric.
For instanced metrics, the array contains another array with samples
for each instance, in the same order as reported in the "instances"
for each instance, in the same order as reported in the `instances`
field of the most recent 'meta' message.
In order to gain efficiency, 'data' messages are usually compressed.
@ -1300,8 +1355,8 @@ This is done by only transmitting the differences from one point in
time to the next.
If a value for a metric or a instance is the same as at the previous
point in time, the channel transmits a "null" value instead.
Additionally, "null" values at the end of an array are suppressed by
point in time, the channel transmits a `null` value instead.
Additionally, `null` values at the end of an array are suppressed by
transmitting a shorter array.
For example, say the samples for three points in time are
@ -1320,8 +1375,8 @@ This compression only happens when the last and current value belong
to the same instance of the same metric. Thus, the client does not
need to track layout changes when decompressing data messages.
Instead of a number of "null", a data message can also contain
"false". This indicates an error of some kind, or an unavailable
Instead of a number of `null`, a data message can also contain
`false`. This indicates an error of some kind, or an unavailable
value.
**PCP metric source**
@ -1336,11 +1391,11 @@ The format of the "units" member is the same as the one used by
The metric information objects in the 'meta' messages for PCP sources
also contain these fields:
* "semantics" (string): The semantics of this metric, one of
"counter", "instant", or "discrete".
* `semantics` (string): The semantics of this metric, one of
`counter`, `instant`, or `discrete`.
Only numeric metrics are currently supported. Non-numeric metrics
have all their samples set to "false".
have all their samples set to `false`.
Problem codes
-------------
@ -1348,15 +1403,15 @@ Problem codes
These are problem codes for errors that cockpit-web responds to. They should
be self explanatory. It's totally not interesting to arbitrarily invent new
codes. Instead the web needs to be ready to react to these problems. When in
doubt use "internal-error".
doubt use `internal-error`.
* "internal-error"
* "no-cockpit"
* "no-session"
* "access-denied"
* "authentication-failed"
* "not-found"
* "terminated"
* "timeout"
* "unknown-hostkey"
* "no-forwarding"
* `internal-error`
* `no-cockpit`
* `no-session`
* `access-denied`
* `authentication-failed`
* `not-found`
* `terminated`
* `timeout`
* `unknown-hostkey`
* `no-forwarding`

View file

@ -7,41 +7,41 @@ and their characteristics. This doesn't apply to the visible URLs shown
in the main Cockpit address bar.
Cockpit URLs are based on an application. A valid application name is
either the word ```cockpit``` or a string that begins with ```cockpit+```
for example ```cockpit+application-name```. Each of the following URLs
are valid for any application, just replace ```/cockpit/``` with ```/cockpit+application-name/```
either the word `cockpit` or a string that begins with `cockpit+`
for example `cockpit+application-name`. Each of the following URLs
are valid for any application, just replace `/cockpit/` with `/cockpit+application-name/`
* ```/cockpit/static``` static files available without authentication. Files
* `/cockpit/static` static files available without authentication. Files
are cached for as long as possible, and names *must* change when the
contents of the file changes. The exception to this is when the application
refers to a different machine. In that case the user must be authenticated
to serve those files and the cache varies on cookie.
* ```/cockpit/login``` authenticates a user and sets cookie based on application
* `/cockpit/login` authenticates a user and sets cookie based on application
name.
* ```/cockpit/$xxxxxxxxxxxxxxx/package/path/to/file.ext``` are files which
* `/cockpit/$xxxxxxxxxxxxxxx/package/path/to/file.ext` are files which
are cached by packages for as long as possible. The checksum changes when
any of the packages on a system change. Only available after authentication.
* ```/cockpit/$xxxxxxxxxxxxxxx/*/path/to/file.ext``` are concatenated files from
* `/cockpit/$xxxxxxxxxxxxxxx/*/path/to/file.ext` are concatenated files from
packages, as seen above.
* ```/cockpit/@host/package/path/to/file.ext``` are files from packages (on
* `/cockpit/@host/package/path/to/file.ext` are files from packages (on
specific hosts) that are not cached. Only available after authentication.
* ```/cockpit/@host/*/path/to/file.ext``` are concatenated files from
* `/cockpit/@host/*/path/to/file.ext` are concatenated files from
packages (on specific hosts). They are served uncompressed.
* ```/cockpit/@host/manifests.json``` includes a summary of all the manifest
* `/cockpit/@host/manifests.json` includes a summary of all the manifest
files from all the packages
* ```/cockpit/@host/manifests.js``` includes a summary of all the manifest
* `/cockpit/@host/manifests.js` includes a summary of all the manifest
files from all the packages, as an AMD loadable module
* ```/cockpit/socket``` The main web socket
* `/cockpit/socket` The main web socket
* ```/cockpit/channel/csrftoken?query``` External channel URLs
* `/cockpit/channel/csrftoken?query` External channel URLs
These are commonly used to wrap/proxy port access for Cockpit pages, as
their JavaScript cannot talk to them directly due to Cockpit's strict
@ -53,7 +53,7 @@ are valid for any application, just replace ```/cockpit/``` with ```/cockpit+app
When loading through cockpit-ws any URL that does not begin with an
application will be handled by the shell (shell/index.html by default)
using the default application ```cockpit```.
using the default application `cockpit`.
Direct to machine urls
@ -64,16 +64,16 @@ authenticating on the machine that cockpit-ws is running on. A cockpit-ssh
processes is spawned that connects via SSH to the remote machine and all
requests are proxied via that connection.
To use this feature the application name MUST begin with an ```=``` for
example ```/cockpit+=machine/socket``` will attempt to open a socket on
```machine``` ```/cockpit+machine/socket``` will attempt to open a socket
To use this feature the application name MUST begin with an `=` for
example `/cockpit+=machine/socket` will attempt to open a socket on
`machine` `/cockpit+machine/socket` will attempt to open a socket
on localhost.
When loading through cockpit-ws any URL that does not begin with an
application will be handled by the shell (shell/index.html by default)
using the default application ```cockpit```.
using the default application `cockpit`.
In addition any url that begins with ```/=``` will attempt to load
In addition any url that begins with `/=` will attempt to load
the shell from the specified machine. For example a URL of
```/=machine/system``` will attempt to load ```shell/index.html```
from ```machine``` using the application ```cockpit+machine```.
`/=machine/system` will attempt to load `shell/index.html`
from `machine` using the application `cockpit+machine`.