Skip to content

Commit

Permalink
Support wifi configuration
Browse files Browse the repository at this point in the history
- update config
- add so libraries for compilation
  • Loading branch information
wj-xiao committed Dec 4, 2024
1 parent a09ed2d commit 5a39562
Show file tree
Hide file tree
Showing 66 changed files with 4,072 additions and 3,202 deletions.
77 changes: 61 additions & 16 deletions server/README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,76 @@
# NanoKVM Server

The code of NanoKVM backend server. For more documentation, please refer to [Wiki](https://wiki.sipeed.com/nanokvm).
This is the backend server implementation for NanoKVM.

For detailed documentation, please visit our [Wiki](https://wiki.sipeed.com/nanokvm).

## Structure

```shell
server
├── config // server config
├── logger // server log
├── main.go
├── middleware // server middleware
├── proto // api request and response arguments
├── router // api routes
├── service // api handlers
└── utils // utils functions
├── common // Common utility components
├── config // Server configuration
├── dl_lib // Shared object libraries
├── include // Header files for shared objects
├── logger // Logging system
├── middleware // Server middleware components
├── proto // API request/response definitions
├── router // API route handlers
├── service // Core service implementations
├── utils // Utility functions
└── main.go
```

## Configuration

The configuration file path is `/etc/kvm/server.yaml`.

```yaml
proto: http
port:
http: 80
https: 443
cert:
crt: server.crt
key: server.key

# Log level (debug/info/warn/error)
# Note: Use 'info' or 'error' in production, 'debug' only for development
logger:
level: info
file: stdout

# Authentication setting (enable/disable)
# Note: Only disable authentication in development environment
authentication: enable

# JWT secret key configuration
# If left empty, a random key will be generated on each server start
secretKey: ""
```
## Development
The configuration file path is `/etc/kvm/server.yaml`. There are two configurable options:
## Compile & Deploy
- `log: error`: log level, default is `error`. Too many logs may affect service performance, it is recommended to use the `error` level in production environment.
Note: Use Linux operating system (x86-64). This build process is not compatible with ARM, Windows or macOS.
- `authentication: enable`: Whether to enable authentication, default is `enable`. Logging in is required after each service restart, use `disable` will skip the authentication check and don't need to log in again. Please delete this configuration for production environments!
1. Install the Toolchain
1. Download the toolchain from the following link: [Download Link](https://sophon-file.sophon.cn/sophon-prod-s3/drive/23/03/07/16/host-tools.tar.gz).
2. Extract the file and add the `host-tools/gcc/riscv64-linux-musl-x86_64/bin` directory to your PATH environment variable.
3. Run `riscv64-unknown-linux-musl-gcc -v`. If there is version information in the output, the installation is successful.

## Deployment
2. Compile the Project
1. Run `cd server` from the project root directory.
2. Run `go mod tidy` to install Go dependencies.
3. Run `CGO_ENABLED=1 GOOS=linux GOARCH=riscv64 CC=riscv64-unknown-linux-musl-gcc CGO_CFLAGS="-mcpu=c906fdv -march=rv64imafdcv0p7xthead -mcmodel=medany -mabi=lp64d" go build` to compile the project.
4. After compilation, an executable file named `NanoKVM-Server` will be generated.

Work in progress.
3. Modify RPATH
1. Run `sudo apt install patchelf` or `pip install patchelf` to install patchelf.
2. Run `patchelf --version`. Ensure the version is 0.14 or higher`.
3. Run `patchelf --add-rpath \$ORIGIN/dl_lib NanoKVM-Server` to modify the RPATH of the executable file.

The project requires CGO. It must be compiled on Linux with a toolchain installed. More details will be added later.
4. Deploy the Application
1. Before deploying, update the application to the latest version in your browser. Follow the instructions [here](https://wiki.sipeed.com/hardware/en/kvm/NanoKVM/system/updating.html).
2. Replace the original file in the NanoKVM `/kvmapp/server/` directory with the newly compiled `NanoKVM-Server`.
3. Restart the service on NanoKVM by executing `/etc/init.d/S95nanokvm restart`.
61 changes: 52 additions & 9 deletions server/README_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,68 @@ NanoKVM 后端服务的代码。更多文档请参考 [Wiki](https://wiki.sipeed

```shell
server
├── common // 公用组件
├── config // 服务配置
├── dl_lib // so 文件
├── include // 头文件
├── logger // 服务日志
├── main.go
├── middleware // 中间件
├── proto // api 请求响应参数
├── router // api 路由
├── service // api 处理逻辑
└── utils // 工具函数
├── utils // 工具函数
└── main.go
```

## 开发
## 配置文件

配置文件路径为 `/etc/kvm/server.yaml`有两个可配置的选项:
配置文件路径为 `/etc/kvm/server.yaml`

- `log: error`:日志等级,默认为 `error`。日志过多可能会影响服务性能,生产环境中建议使用 `error` 等级。
- `authentication: enable`:是否启用鉴权,默认开启。服务每次重启后都需要重新登录,将该选项设为 `disable` 会跳过鉴权检查,可以不用重复登录。生产环境请删除该条配置!
```yaml
proto: http
port:
http: 80
https: 443
cert:
crt: server.crt
key: server.key

# 日志级别(debug/info/warn/error)
# 注意:在生产环境中使用 info 或 error。debug 模式仅在开发环境中使用。
logger:
level: info
file: stdout

# 鉴权设置(enable/disable)
# 注意:生产环境中请勿使用 disable。
authentication: enable

## 部署
# JWT 密钥
# 如果不设置,则每次服务启动时使用随机生成的密钥。
secretKey: ""
```
## 编译部署
**注意:请使用 Linux 操作系统(x86-64)。该工具链无法在 ARM、Windows 或 macOS 下使用。**
1. 安装工具链
1. 下载工具链:[下载地址](https://sophon-file.sophon.cn/sophon-prod-s3/drive/23/03/07/16/host-tools.tar.gz);
2. 解压下载文件,然后将 `host-tools/gcc/riscv64-linux-musl-x86_64/bin` 目录加入到环境变量;
3. 执行 `riscv64-unknown-linux-musl-gcc -v`,如果显示版本信息则安装成功。

2. 编译
1. 在项目根目录下执行 `cd server` 进入 server 目录;
2. 执行 `go mod tidy` 安装 Go 依赖包;
3. 执行 `CGO_ENABLED=1 GOOS=linux GOARCH=riscv64 CC=riscv64-unknown-linux-musl-gcc CGO_CFLAGS="-mcpu=c906fdv -march=rv64imafdcv0p7xthead -mcmodel=medany -mabi=lp64d" go build` 进行编译;
4. 编译完成后,会生成可执行文件 `NanoKVM-Server`。

待完善。
3. 修改 RPATH
1. 执行 `sudo apt install patchelf` 或 `pip install patchelf` 安装 patchelf;
2. 执行 `patchelf --version`,确保版本大于等于 0.14;
3. 执行 `patchelf --add-rpath \$ORIGIN/dl_lib NanoKVM-Server` 修改可执行文件的 RPATH 属性。

项目中使用了 CGO,需要使用 Linux 并安装工具链后才能编译。这部分内容会晚一点更新。
4. 部署
1. 部署前,请先在浏览器中将应用[更新](https://wiki.sipeed.com/hardware/zh/kvm/NanoKVM/system/updating.html)到最新版本;
2. 使用编译生成的 `NanoKVM-Server` 文件,替换 NanoKVM 中 `/kvmapp/server/` 目录下的原始文件;
3. 在 NanoKVM 中执行 `/etc/init.d/S95nanokvm restart` 重启服务。
2 changes: 1 addition & 1 deletion server/config/default.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package config

var defaultConfig = &Config{
Protocol: "http",
Proto: "http",
Port: Port{
Http: 80,
Https: 443,
Expand Down
76 changes: 49 additions & 27 deletions server/config/hardware.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,59 +12,81 @@ type HWVersion int
const (
HWVersionAlpha HWVersion = iota
HWVersionBeta
)
HWVersionPcie

const (
hwVersionFile = "/etc/kvm/hw"
HWVersionFile = "/etc/kvm/hw"
)

gpioPower = "/sys/class/gpio/gpio503/value"
gpioPowerLED = "/sys/class/gpio/gpio504/value"
var HWAlpha = Hardware{
Version: HWVersionAlpha,
GPIOReset: "/sys/class/gpio/gpio507/value",
GPIOPower: "/sys/class/gpio/gpio503/value",
GPIOPowerLED: "/sys/class/gpio/gpio504/value",
GPIOHDDLed: "/sys/class/gpio/gpio505/value",
}

gpioResetAlpha = "/sys/class/gpio/gpio507/value"
gpioHDDLedAlpha = "/sys/class/gpio/gpio505/value"
var HWBeta = Hardware{
Version: HWVersionBeta,
GPIOReset: "/sys/class/gpio/gpio505/value",
GPIOPower: "/sys/class/gpio/gpio503/value",
GPIOPowerLED: "/sys/class/gpio/gpio504/value",
GPIOHDDLed: "",
}

gpioResetBeta = "/sys/class/gpio/gpio505/value"
)
var HWPcie = Hardware{
Version: HWVersionPcie,
GPIOReset: "/sys/class/gpio/gpio505/value",
GPIOPower: "/sys/class/gpio/gpio503/value",
GPIOPowerLED: "/sys/class/gpio/gpio504/value",
GPIOHDDLed: "",
}

func (h HWVersion) String() string {
switch h {
case HWVersionAlpha:
return "Alpha"
case HWVersionBeta:
return "Beta"
case HWVersionPcie:
return "PCIE"
default:
return "Unknown"
}
}

func getHwVersion() HWVersion {
content, err := os.ReadFile(hwVersionFile)
if err == nil {
version := strings.ReplaceAll(string(content), "\n", "")
if version == "beta" {
return HWVersionBeta
}
content, err := os.ReadFile(HWVersionFile)
if err != nil {
return HWVersionAlpha
}

version := strings.ReplaceAll(string(content), "\n", "")
if version == "beta" {
return HWVersionBeta
} else if version == "pcie" {
return HWVersionPcie
}

return HWVersionAlpha
}

func getHardware() Hardware {
h := Hardware{}

h.Version = getHwVersion()
h.GPIOPower = gpioPower
h.GPIOPowerLED = gpioPowerLED
func getHardware() (h Hardware) {
version := getHwVersion()

switch h.Version {
switch version {
case HWVersionAlpha:
h.GPIOHDDLed = gpioHDDLedAlpha
h.GPIOReset = gpioResetAlpha
h = HWAlpha

case HWVersionBeta:
h.GPIOReset = gpioResetBeta
h = HWBeta

case HWVersionPcie:
h = HWPcie

default:
log.Fatalf("Unsupported hardware version: %s", h.Version)
h = HWAlpha
log.Error("Unsupported hardware version: %s", version)
}

return h
return
}
2 changes: 1 addition & 1 deletion server/config/types.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package config

type Config struct {
Protocol string `yaml:"proto"`
Proto string `yaml:"proto"`
Port Port `yaml:"port"`
Cert Cert `yaml:"cert"`
Logger Logger `yaml:"logger"`
Expand Down
Binary file added server/dl_lib/libaaccomm2.so
Binary file not shown.
Binary file added server/dl_lib/libaacdec2.so
Binary file not shown.
Binary file added server/dl_lib/libaacenc2.so
Binary file not shown.
Binary file added server/dl_lib/libaacsbrdec2.so
Binary file not shown.
Binary file added server/dl_lib/libaacsbrenc2.so
Binary file not shown.
Binary file added server/dl_lib/libae.so
Binary file not shown.
Binary file added server/dl_lib/libaf.so
Binary file not shown.
Binary file added server/dl_lib/libawb.so
Binary file not shown.
Binary file added server/dl_lib/libcli.so
Binary file not shown.
Binary file added server/dl_lib/libcvi_RES1.so
Binary file not shown.
Binary file added server/dl_lib/libcvi_VoiceEngine.so
Binary file not shown.
Binary file added server/dl_lib/libcvi_audio.so
Binary file not shown.
Binary file added server/dl_lib/libcvi_bin.so
Binary file not shown.
Binary file added server/dl_lib/libcvi_bin_isp.so
Binary file not shown.
Binary file added server/dl_lib/libcvi_ispd2.so
Binary file not shown.
Binary file added server/dl_lib/libcvi_ive.so
Binary file not shown.
Binary file added server/dl_lib/libcvi_ssp.so
Binary file not shown.
Binary file added server/dl_lib/libcvi_vqe.so
Binary file not shown.
Binary file added server/dl_lib/libdnvqe.so
Binary file not shown.
Binary file added server/dl_lib/libini.so
Binary file not shown.
Binary file added server/dl_lib/libisp.so
Binary file not shown.
Binary file added server/dl_lib/libisp_algo.so
Binary file not shown.
Binary file added server/dl_lib/libjson-c.so.5
Binary file not shown.
Binary file modified server/dl_lib/libkvm.so
Binary file not shown.
Binary file added server/dl_lib/libmaixcam_lib.so
Binary file not shown.
Binary file added server/dl_lib/libmipi_tx.so
Binary file not shown.
Binary file added server/dl_lib/libmisc.so
Binary file not shown.
Binary file added server/dl_lib/libopencv_core.so.409
Binary file not shown.
Binary file added server/dl_lib/libopencv_highgui.so.409
Binary file not shown.
Binary file added server/dl_lib/libopencv_imgcodecs.so.409
Binary file not shown.
Binary file added server/dl_lib/libopencv_imgproc.so.409
Binary file not shown.
Binary file added server/dl_lib/libosdc.so
Binary file not shown.
Binary file added server/dl_lib/libraw_dump.so
Binary file not shown.
Binary file added server/dl_lib/libsys.so
Binary file not shown.
Binary file added server/dl_lib/libtinyalsa.so
Binary file not shown.
Binary file added server/dl_lib/libvdec.so
Binary file not shown.
Binary file added server/dl_lib/libvenc.so
Binary file not shown.
Binary file added server/dl_lib/libvpu.so
Binary file not shown.
3 changes: 2 additions & 1 deletion server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ func run(r *gin.Engine) {

httpAddr := fmt.Sprintf(":%d", conf.Port.Http)
httpsAddr := fmt.Sprintf(":%d", conf.Port.Https)
fmt.Printf("proto: %s, port: %d %d\n", conf.Proto, conf.Port.Http, conf.Port.Https)

if conf.Protocol == "https" {
if conf.Proto == "https" {
r.Use(middleware.Tls())

go func() {
Expand Down
5 changes: 5 additions & 0 deletions server/proto/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,8 @@ type ChangePasswordReq struct {
type IsPasswordUpdatedRsp struct {
IsUpdated bool `json:"isUpdated"`
}

type ConnectWifiReq struct {
Ssid string `validate:"required"`
Password string `valid:"required"`
}
1 change: 1 addition & 0 deletions server/proto/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type GetInfoRsp struct {
Mdns string `json:"mdns"`
Image string `json:"image"`
Application string `json:"application"`
Hardware string `json:"hardware"`
DeviceKey string `json:"deviceKey"`
}

Expand Down
3 changes: 2 additions & 1 deletion server/router/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import (
func authRouter(r *gin.Engine) {
service := auth.NewService()

r.POST("/api/auth/login", service.Login) // login
r.POST("/api/auth/login", service.Login) // login
r.POST("/api/auth/wifi", service.ConnectWifi) // connect Wi-Fi

api := r.Group("/api").Use(middleware.CheckToken())

Expand Down
Loading

0 comments on commit 5a39562

Please sign in to comment.