Rust Axum/Vue WebSocket Demo

The following github project might be helpful for you. It builds a rust tokio/axum web-service binary, integrating a webui frontend based on Vue framework (npm based): https://github.com/frehberg/rust-vue-demo

The web-service backend is based on Rust Tokio-Axum framework.

The frontend is based on Vue JavaScript framework; vue template files will be compiled to static files (HTML/CSS/JavsScript) and embedded into the executable.

The web-service will read read/return the embedded files on request.

This compact Vue app realizes a dynamic web frontend, displaying the data it receives via websocket from web-service.

Step by step

After download, at first the npm project must be initialized, downloading the node.js dependencies.

> cd webui; npm install

Vue code and Rust code will be built together and executed using a single command, combining the cargo and npm build process

> cargo run

The Vue application (web frontend) is defined by template file webui/src/App.vue, and the result of the npm-build-process will be placed in folder webui/dist/. The Rust backend binary is defined by src/main.rs. The following image shows the complete source tree.

First, the build process will compile the Vue application (see build.rs), producing the files in folder webui/dist. Then the rust_embed macros in src/main.rs will embed the generated files of webui/dist/ and the rust compiler will generate the executable.

The web-service is self contained, the webui assets (Html and JavaScript files, images, etc.) are integrated into the binary.

When connecting with web-browser to host at port 3000, eg http://127.0.0.1:3000, the webui will be loaded and it will open a websocket, receiving data from web-service once per second, suitable for process monitoring.

This combination of rust-binary and Vue frontend (HTML/CSS/JavaScript) can be used either for backend server systems but is also suitable for embedded systems. The stripped release binary of rust-vue-demo will occupy ca. 4MB, containing the web-service backend, and the webui frontend (HTML/CSS/JavaScript files).

Why I kicked out MS Office 365

MS Office 365 is the web-based version of MS Office (Word,Excel, etc). Its functionality is limited comparing to the original desktop version, it feels like MS Works I used 1992. But the worst, it is not possible to copy&paste between two documents in two different web-browser windows, no clipboard! A limited clipboard is available via browser-plugin only, but it did not work with Firefox on Ubuntu 2022.

Buildroot Verity Setup – Rootfs Integrity

I investigated the usage of Verity feature of Linux kernel, ingrating this feature into the OpenCritis environment. The Verity Device Mapper of the Linux kernel is verifying the integrity of a read-only file system (eg partition rootfs) using a Merkle tree; over the data blocks of the file system. If signing the top hash, the authenticity and integrity of the rootfs can be enforced while booting and during runtime!

Source: Wikipedia, Merkle Tree

Credits: Nathan Barrett-Morrison did a very good posting explaining the details https://www.timesys.com/security/dm-verity-without-an-initramfs/

Locking down U-Boot Environment

Performing secure boot U-Boot, the U-Boot-Env in mmc or flash should be static, read-only. In case of A-B boot concept as being used for OpenCritis, the bootloader needs to know the active partition to boot into. Therefore 3 variables shall be writable only, being stored in U-Boot Environmentn, namely

boot_order: Hex value, either “AB” or “BA”
boot_a_left: Dec value counting the number of trials, by default 3
boot_b_left: Dec value counting the number of trials, by default 3

To acieve this setup the uboot defconfig should have the following setup:

CONFIG_CMD_ENV_CALLBACK=y
CONFIG_CMD_ENV_FLAGS=y
CONFIG_ENV_IS_NOWHERE=y
CONFIG_ENV_IS_IN_MMC=y or CONFIG_ENV_IS_IN_FAT=y
CONFIG_ENV_APPEND=y
CONFIG_ENV_WRITEABLE_LIST=y
CONFIG_ENV_ACCESS_IGNORE_FORCE=y
CONFIG_CMD_NVEDIT_LOAD=y
CONFIG_SYS_CONSOLE_ENV_OVERWRITE=y

In the board header file (eg. include/configs/qemu-arm.h) the following definitions must be added , for example as patch file.

#define CONFIG_ENV_FLAGS_LIST_DEFAULT "boot_order:xw,boot_a_left:dw,boot_b_left:dw"
#define CONFIG_ENV_FLAGS_LIST_STATIC  "boot_order:xw,boot_a_left:dw,boot_b_left:dw"

See the following README explaining the flag attributes: https://github.com/u-boot/u-boot/blob/master/README#L1588

Solar Position Algorithm (SPA) release 0.3.0

The release 0.3.0 of the crate spa is fixing the flaw of the API, and updating to Rust edition 2021.

The SPA can be used to calculate solar position (azimuth and zenith_angle) and the time of sunrise and sunset. This data can be used to optimize the position of solar panels, to optimize load-cycles of energy storages, or to increase or reduce the lighting at home or in vehicles.

As for the flaw in the API: Just implementing unittests, I wasn’t aware that the members of the structure SolarPos lacked the declaration pub. Users of the lib were not able to read the result from return value! Now, after adding example files, these examples are verifying those members are publicly accessible, see below.

// ...
pub enum SunriseAndSet {
    PolarNight,
    PolarDay,
    Daylight(DateTime<Utc>, DateTime<Utc>),
}

// ...
pub struct SolarPos {
    // horizontal angle measured clockwise ...
    pub azimuth: f64,
    // the angle between the zenith and the center of the sun's disc
    pub zenith_angle: f64,
}

Moreover the bench tests caused additional complexity due to the required feature handling and conditional builds. For that reason the bench tests have been removed.

In the moment the bench API is getting stabilized any time in future, these bench test will be put back.

Lessons learned: Avoid superfluous complexity and ship with examples always!