-
Notifications
You must be signed in to change notification settings - Fork 164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add monitor application to EVE #4410
Changes from all commits
25543dc
d313132
5cb3ec9
0b6b39d
09a3533
7f9dad8
2ffa2e9
a4117a4
ba58003
e6be920
9d800b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# Copyright (c) 2024 Zededa, Inc. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
ARG MONITOR_RS_VERSION=v0.1.1 | ||
ARG RUST_VERSION=lfedge/eve-rust:1.80.1 | ||
FROM --platform=$BUILDPLATFORM ${RUST_VERSION} AS toolchain-base | ||
ARG TARGETARCH | ||
|
||
FROM toolchain-base AS target-amd64 | ||
ENV CARGO_BUILD_TARGET="x86_64-unknown-linux-musl" | ||
|
||
FROM toolchain-base AS target-arm64 | ||
ENV CARGO_BUILD_TARGET="aarch64-unknown-linux-musl" | ||
|
||
FROM toolchain-base AS target-riscv64 | ||
ENV CARGO_BUILD_TARGET="riscv64gc-unknown-linux-gnu" | ||
|
||
FROM target-$TARGETARCH AS toolchain | ||
ARG MONITOR_RS_VERSION | ||
RUN echo "Cargo target: $CARGO_BUILD_TARGET" | ||
|
||
FROM toolchain AS planer | ||
ADD --keep-git-dir=true https://github.com/lf-edge/eve-monitor-rs.git#${MONITOR_RS_VERSION} /app | ||
|
||
WORKDIR /app | ||
# create a recipe | ||
RUN cargo chef prepare --recipe-path recipe.json | ||
|
||
FROM toolchain AS cacher | ||
# copy the recipe | ||
WORKDIR /app | ||
COPY --from=planer /app/recipe.json recipe.json | ||
# build the dependencies | ||
RUN cargo chef cook --release --recipe-path recipe.json | ||
|
||
# building the final image | ||
FROM toolchain AS builder | ||
ADD --keep-git-dir=true https://github.com/lf-edge/eve-monitor-rs.git#${MONITOR_RS_VERSION} /app | ||
WORKDIR /app | ||
|
||
# copy prebuilt dependencies | ||
# and the cargo directory with crates.io index | ||
COPY --from=cacher /app/target /app/target | ||
COPY --from=cacher $CARGO_HOME $CARGO_HOME | ||
RUN echo "Cargo target: $CARGO_BUILD_TARGET" | ||
|
||
RUN cargo build --release | ||
RUN cargo sbom > sbom.spdx.json | ||
RUN cp /app/target/$CARGO_BUILD_TARGET/release/monitor /app/target/ | ||
|
||
|
||
FROM lfedge/eve-alpine:591df01e581889c3027514c8a91feaca1c8ad49f AS runtime | ||
ENV PKGS="kbd pciutils usbutils" | ||
RUN eve-alpine-deploy.sh | ||
|
||
FROM scratch | ||
COPY --from=runtime /out/usr/bin/openvt /usr/bin/openvt | ||
COPY --from=runtime /out/usr/bin/loadkeys /usr/bin/loadkeys | ||
COPY --from=runtime /out/bin/dmesg /usr/bin/dmesg | ||
COPY --from=runtime /out/usr/bin/lsusb /usr/bin/lsusb | ||
COPY --from=runtime /out/usr/bin/lspci /usr/bin/lspci | ||
COPY --from=runtime /out/usr/share/keymaps/xkb/us.map.gz /usr/share/keymaps/xkb/us.map.gz | ||
COPY --from=runtime /out/lib /lib | ||
COPY --from=runtime /out/usr/lib /usr/lib | ||
|
||
# copy busybox and install all symbolic links but just for debugging | ||
COPY --from=runtime /out/bin/busybox /bin/busybox | ||
# using an 'exec' form of RUN, shell form of 'RUN' | ||
# command expects /bin/sh which doesn't yet exist | ||
RUN [ "/bin/busybox", "--install", "-s", "/bin" ] | ||
COPY --from=runtime /out/usr/bin/du /usr/bin/du | ||
|
||
COPY --from=builder /app/target/monitor /sbin/monitor | ||
COPY --from=builder /app/sbom.spdx.json /sbin/sbom.spdx.json | ||
COPY run-monitor.sh /sbin/run-monitor.sh | ||
COPY monitor-wrapper.sh /sbin/monitor-wrapper.sh | ||
|
||
CMD ["/sbin/run-monitor.sh"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Copyright (c) 2024 Zededa, Inc. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
org: lfedge | ||
image: eve-monitor | ||
network: yes | ||
config: | ||
pid: host | ||
binds: | ||
# for tty/console devices | ||
- /dev:/dev | ||
# for temporary files and UNIX socket | ||
- /run:/run | ||
# to save logs | ||
- /persist:/persist:rshared,rbind | ||
|
||
devices: | ||
- path: "/dev/tty" | ||
type: c | ||
major: 5 | ||
minor: 0 | ||
mode: 0666 | ||
- path: "/dev/console" | ||
type: c | ||
major: 5 | ||
minor: 1 | ||
mode: 0666 | ||
- path: "/dev/tty0" | ||
type: c | ||
major: 4 | ||
minor: 0 | ||
mode: 0666 | ||
- path: "/dev/ttyS0" | ||
type: c | ||
major: 4 | ||
minor: 64 | ||
mode: 0666 | ||
- path: "/dev/ttyAMA0" | ||
type: c | ||
major: 204 | ||
minor: 64 | ||
mode: 0666 | ||
# we run the monitor on tty2 | ||
- path: "/dev/tty2" | ||
type: c | ||
major: 4 | ||
minor: 2 | ||
mode: 0666 | ||
# direct access to the kernel log | ||
- path: "/dev/kmsg" | ||
type: c | ||
major: 1 | ||
minor: 11 | ||
mode: 0660 | ||
capabilities: | ||
- all | ||
rootfsPropagation: shared |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#!/bin/sh | ||
|
||
# Copyright (c) 2024 Zededa, Inc. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
/sbin/monitor | ||
# wait for key press so user can see the panic info | ||
# shellcheck disable=SC3045,SC2162 | ||
read -r -p "Press any key to continue... " -n1 -s |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#!/bin/sh | ||
|
||
# Copyright (c) 2024 Zededa, Inc. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
echo "Running EVE monitor" | ||
export RUST_BACKTRACE=1 | ||
|
||
# leave only panic on console | ||
dmesg -n 1 | ||
|
||
# setup keymap | ||
loadkeys -s us - <<EOF | ||
control keycode 103 = F103 | ||
control keycode 108 = F108 | ||
control keycode 106 = F106 | ||
control keycode 105 = F105 | ||
string F103 = "\033[1;5A" | ||
string F108 = "\033[1;5B" | ||
string F106 = "\033[1;5C" | ||
string F105 = "\033[1;5D" | ||
EOF | ||
|
||
# run monitor on 2nd console in infinite loop | ||
while true; do | ||
openvt -c 2 -s -f -w -- /sbin/monitor-wrapper.sh | ||
done |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -292,7 +292,7 @@ func RebootReason(reason string, bootReason types.BootReason, agentName string, | |
} | ||
|
||
// Printing the reboot reason to the console | ||
filename = "/dev/console" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some scripts from pkg/pillar/scripts also write to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rene I checked those and they do not affect monitor app. They actually should write to console so we see the output on /dev/ttyS* if connected. Monitor is started after they finish so it should be ok. I still need to modify getty to properly handle console devices anyways |
||
filename = "/dev/tty" | ||
|
||
operation := "Rebooting" | ||
if bootReason == types.BootReasonPoweroffCmd { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same question here, is all these access needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shjala probably not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you go through them, pick the ones you really need and add a comment above each one that is needed stating why it is needed? it makes creating apparmor profile much easier.
same for this.