Skip to content

Commit

Permalink
Add documentation for monitor TUI application
Browse files Browse the repository at this point in the history
- add documentation for pkg/monitor container
- update NIM documentation
- add documentation for pkg/pillar/cmd/monitor service

Signed-off-by: Mikhail Malyshev <mike.malyshev@gmail.com>
  • Loading branch information
rucoder committed Nov 26, 2024
1 parent ba58003 commit e6be920
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 1 deletion.
41 changes: 41 additions & 0 deletions docs/LOCAL-TUI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# TUI (Text User Interface) for the local operator

EVE has a user-friendly TUI (Text User Interface) that can be used to interact with the system.
The implementation is consists of two parts

1. Client application responsible for rendering the TUI, sending user input to the server, and handling asynchronous server notification. The client is written in Rust and hosted at [https://github.com/lf-edge/eve-monitor-rs](https://github.com/lf-edge/eve-monitor-rs). Corresponding Dockerfile and LinuxKit build files are located at `pkg/monitor`
2. Server part is implemented inside [pkg/pillar/cmd/monitor](../pkg/pillar/cmd/monitor/)

The client communicates with the server over UNIX socket

## TTY and serial console

The UI is rendered on a local TTY (/dev/tty2) only i.e. on a physical monitor attached to the system. Neither Serial Console nor SSH connection has access to TUI. It is done to ensure the physical presence of the operator.

## /dev/ttyX vs /dev/console

There are two distinguishable console devices in Linux `/dev/console` and `/dev/ttyX`. The later points to a particular virtual terminal device and the former points to *currently active* TTY device. The user can switch between virtual terminals by using `Alt+Fx` or `Alt+<,>` keys. When the current TTY is set `/dev/console` tracks this change and always points to to the current terminal

Monitor application is spawned on a `/dev/tty2` using a `openvt` utility while the rest of the applications are spawned on the default kernel console defined by `console=` parameters on the kernel command line. When the application is in focus (`/dev/tty2` is an active console) writing to `/dev/console` which points to the same device corrupts TUI thus it cannot be used by other services in the system to produce the output. At least when `/dev/tty2` is a current console.

From the other hand `/dev/tty` (no digit at the end!) device always points to a TTY *in the context of running process*. This device can be used instead of `/dev/console` by other services for the output.

## Limitations of linux terminal

Rust application can be built and run on Linux host for testing and development purposes. When running on a host its terminal is used for rendering. Host terminals ( e.g. `TERM=xterm`) are very different in capabilities compared to the built in Linux terminal which is used for `/dev/ttyX` (`TERM=linux`) devices. The major differences important for monitor application are

* Number of supported colors.

`linux` terminal can use only 8 colors for foreground and 8 colors for background colors. In contrast host terminals can easily display 256 colors and more

* Limited number of pseudo-graphics glyphs.

These limitations can be relaxed by using a custom font with 256 glyphs compared to the standard one that uses 512 glyphs. In this case an extra bit can be used to render 16 colors. Besides, extra pseudo-graphics glyphs can be added instead of unused characters to display e.g. rounded boxes.

As of now a standard font is used so the look of the application on the host and on EVE is different

* Key handling.

By default `linux` terminal cannot properly handle many key combinations e.g. `PgDwn`, `Ctrl+left, Ctrl + right`, etc. A custom key map must be set to properly handle required combinations. It is done in [pkg/monitor/run-monitor.sh](../pkg/monitor/run-monitor.sh) by calling `loadkeys` utility

As of now only `Ctrl + [left|right|up|down]` are properly handled.
17 changes: 17 additions & 0 deletions pkg/pillar/docs/monitor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Monitor service implementation

The monitor service is a simple IPC server which uses a unix socket to communicate with external [rust client](../../monitor/Dockerfile) located at `pkg/monitor`. The server can send asynchronous updates about EVE status to the
connected client. The information is then used by rust client to display a TUI for the user.

## Client requests

Following requests are supported at the moment:

* `SetDPC` - sets a the current DPC with a key set to `manual`. It is used to apply a network configuration specified by local user through TUI. `NIM` service has a special handling of `manual` DPC
* `SetServer` - updates server URL in `/config/server` file. The request fails if the node is already onboarded.

## Request/response representation

All requests and responses are sent in JSON format. Some internal EVE structures e.g. DPCList are serialized into JSON as-is and deserialized on the rust application side.
It introduces a problem in case a structure is updated on EVE side, but the rust application is not updated.
To avoid this problem a proxy structures should be created on EVE side in future.
2 changes: 1 addition & 1 deletion pkg/pillar/docs/nim.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ to move to the most recent, aka the highest-priority configuration.
* DPC is received from different sources, such as zedagent (bootstrap config
or config from the controller), the `/config` partition with `override.json`,
specially formatted USB stick with `usb.json` and even from NIM itself,
which builds and publishes the *last-resort* config if enabled
which builds and publishes the *last-resort* config if enabled. If `monitor` application is enabled the user can also change current network settings manually from the local TUI. In this case [monitor](./monitor.md) service sets a DPC with a key set to `manual`. Only one instance of the DPC with key `manual` may exists at a given time thus it is always overwritten when the user changes network settings
* global configuration properties
* an instance of `ConfigItemValueMap` struct received from zedagent
* used to determine if last-resort should be enabled, also to obtain time
Expand Down

0 comments on commit e6be920

Please sign in to comment.