Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,27 +1,38 @@
{
"name": "JetKVM",
"image": "mcr.microsoft.com/devcontainers/go:1-1.23-bookworm",
"image": "mcr.microsoft.com/devcontainers/go:1.25-trixie",
"features": {
"ghcr.io/devcontainers/features/node:1": {
// Should match what is defined in ui/package.json
"version": "22.15.0"
"version": "22.19.0"
}
},
"mounts": [
"source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind,consistency=cached"
"source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind,consistency=cached"
],
"onCreateCommand": ".devcontainer/install-deps.sh",
"customizations": {
"vscode": {
"extensions": [
"bradlc.vscode-tailwindcss",
// coding styles
"chrislajoie.vscode-modelines",
"editorconfig.editorconfig",
// GitHub
"GitHub.vscode-pull-request-github",
"dbaeumer.vscode-eslint",
"github.vscode-github-actions",
// Golang
"golang.go",
// C / C++
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
// CMake / Makefile
"ms-vscode.makefile-tools",
"ms-vscode.cmake-tools",
// Frontend
"esbenp.prettier-vscode",
"github.vscode-github-actions"
"dbaeumer.vscode-eslint",
"bradlc.vscode-tailwindcss"
]
}
}
}

35 changes: 35 additions & 0 deletions .devcontainer/install-deps.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash

SUDO_PATH=$(which sudo)
function sudo() {
if [ "$UID" -eq 0 ]; then
"$@"
else
${SUDO_PATH} "$@"
fi
}

set -ex

export DEBIAN_FRONTEND=noninteractive
sudo apt-get update && \
sudo apt-get install -y --no-install-recommends \
build-essential \
device-tree-compiler \
gperf g++-multilib gcc-multilib \
libnl-3-dev libdbus-1-dev libelf-dev libmpc-dev dwarves \
bc openssl flex bison libssl-dev python3 python-is-python3 texinfo kmod cmake \
wget zstd \
python3-venv python3-kconfiglib \
&& sudo rm -rf /var/lib/apt/lists/*

# Install buildkit
BUILDKIT_VERSION="v0.2.5"
BUILDKIT_TMPDIR="$(mktemp -d)"
pushd "${BUILDKIT_TMPDIR}" > /dev/null

wget https://github.com/jetkvm/rv1106-system/releases/download/${BUILDKIT_VERSION}/buildkit.tar.zst && \
sudo mkdir -p /opt/jetkvm-native-buildkit && \
sudo tar --use-compress-program="unzstd --long=31" -xvf buildkit.tar.zst -C /opt/jetkvm-native-buildkit && \
rm buildkit.tar.zst
popd
30 changes: 25 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,48 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up docker image context
run: |
./scripts/ci_helper.sh prepare
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build docker image
uses: docker/build-push-action@v6
with:
context: ${{ env.DOCKER_BUILD_CONTEXT_DIR }}
file: ${{ env.DOCKER_BUILD_CONTEXT_DIR }}/Dockerfile.build
tags: ${{ env.DOCKER_BUILD_TAG }}
push: false
load: true
- name: Set up Cmake cache
uses: actions/cache@v4
with:
path: internal/native/cgo/build
key: jetkvm-cgo-${{ hashFiles('internal/native/cgo/**/*.c', 'internal/native/cgo/**/*.h', 'internal/native/cgo/**/*.patch', 'internal/native/cgo/**/*.txt', 'internal/native/cgo/**/*.sh', '!internal/native/cgo/build/**') }}
restore-keys: |
jetkvm-cgo-${{ hashFiles('internal/native/cgo/**/*.c', 'internal/native/cgo/**/*.h', 'internal/native/cgo/**/*.patch', 'internal/native/cgo/**/*.txt', 'internal/native/cgo/**/*.sh', '!internal/native/cgo/build/**') }}
- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version: "22"
cache: "npm"
cache-dependency-path: "**/package-lock.json"
- name: Set up Golang
uses: actions/setup-go@v5
uses: actions/setup-go@v6.0.0
with:
go-version: "1.24.4"
go-version: "^1.25.1"
- name: Build frontend
run: |
make frontend
- name: Build application
- name: Build application inside Docker container
run: |
make build_dev
./scripts/ci_helper.sh make build_dev
- name: Run tests
run: |
go test ./... -json > testreport.json
- name: Make test cases
run: |
make build_dev_test
./scripts/ci_helper.sh make build_dev_test
- name: Golang Test Report
uses: becheran/[email protected]
with:
Expand Down
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,13 @@ static/*
.idea
.DS_Store

device-tests.tar.gz
.cache
.vite
.pnpm-store

device-tests.tar.gz
node_modules

# generated during the build process
#internal/native/include
#internal/native/lib
6 changes: 5 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
{
"tailwindCSS.classFunctions": ["cva", "cx"]
"tailwindCSS.classFunctions": [
"cva",
"cx"
],
"git.ignoreLimitWarning": true
}
25 changes: 24 additions & 1 deletion DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,15 @@ tail -f /var/log/jetkvm.log
├── ui/ # React frontend
│ ├── src/routes/ # Pages (login, settings, etc.)
│ └── src/components/ # UI components
└── internal/ # Internal Go packages
├── internal/ # Internal Go packages
│ ├── native/ # CGO / Native code glue layer
│ ├── native/cgo/ # C files for the native library (HDMI, Touchscreen, etc.)
│ ├── native/eez/ # EEZ Studio Project files (for Touchscreen)
│ ├── hidrpc/ # HIDRPC implementation for HID devices (keyboard, mouse, etc.)
│ ├── logging/ # Logging implementation
│ ├── usbgadget/ # USB gadget
│ └── websecurity/ # TLS certificate management
└── resource # netboot iso and other resources
```

**Key files for beginners:**
Expand Down Expand Up @@ -136,6 +144,10 @@ npm install
./dev_device.sh <YOUR_DEVICE_IP>
```

### Touchscreen Changes

Please click the `Build` button in EEZ Studio then run `./dev_deploy.sh -r <YOUR_DEVICE_IP> --skip-ui-build` to deploy the changes to your device. Initial build might take more than 10 minutes as it will also need to fetch and build LVGL and other dependencies.

### Quick Backend Changes

*Best for: API or backend logic changes*
Expand Down Expand Up @@ -349,6 +361,17 @@ The application uses a JSON configuration file stored at `/userdata/kvm_config.j
3. **Add migration logic if needed for existing installations**


### LVGL Build

We modified the LVGL code a little bit to remove unused fonts and examples.
The patches are generated by

```bash
git diff --cached --diff-filter=d > ../internal/native/cgo/lvgl-minify.patch && \
git diff --name-only --diff-filter=D --cached > ../internal/native/cgo/lvgl-minify.del
```


---

**Happy coding!**
Expand Down
24 changes: 24 additions & 0 deletions Dockerfile.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# syntax=docker/dockerfile:1
FROM --platform=${BUILDPLATFORM} golang:1.25.1-trixie AS builder

ENV GOTOOLCHAIN=local
ENV GOPATH=/go
ENV PATH=$GOPATH/bin:/usr/local/go/bin:$PATH

COPY install-deps.sh /install-deps.sh
RUN /install-deps.sh

# Create build directory
RUN mkdir -p /build/

# Copy go.mod and go.sum
COPY go.mod go.sum /build/

WORKDIR /build

RUN go mod download && go mod verify

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

ENTRYPOINT [ "/entrypoint.sh" ]
72 changes: 49 additions & 23 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ VERSION := 0.4.8
PROMETHEUS_TAG := github.com/prometheus/common/version
KVM_PKG_NAME := github.com/jetkvm/kvm

BUILDKIT_FLAVOR := arm-rockchip830-linux-uclibcgnueabihf
BUILDKIT_PATH ?= /opt/jetkvm-native-buildkit
SKIP_NATIVE_IF_EXISTS ?= 0
SKIP_UI_BUILD ?= 0
GO_BUILD_ARGS := -tags netgo,timetzdata,nomsgpack
GO_RELEASE_BUILD_ARGS := -trimpath $(GO_BUILD_ARGS)
GO_LDFLAGS := \
Expand All @@ -17,20 +21,40 @@ GO_LDFLAGS := \
-X $(PROMETHEUS_TAG).Revision=$(REVISION) \
-X $(KVM_PKG_NAME).builtTimestamp=$(BUILDTS)

GO_CMD := GOOS=linux GOARCH=arm GOARM=7 go
GO_ARGS := GOOS=linux GOARCH=arm GOARM=7 ARCHFLAGS="-arch arm"
# if BUILDKIT_PATH exists, use buildkit to build
ifneq ($(wildcard $(BUILDKIT_PATH)),)
GO_ARGS := $(GO_ARGS) \
CGO_CFLAGS="-I$(BUILDKIT_PATH)/$(BUILDKIT_FLAVOR)/include -I$(BUILDKIT_PATH)/$(BUILDKIT_FLAVOR)/sysroot/usr/include" \
CGO_LDFLAGS="-L$(BUILDKIT_PATH)/$(BUILDKIT_FLAVOR)/lib -L$(BUILDKIT_PATH)/$(BUILDKIT_FLAVOR)/sysroot/usr/lib -lrockit -lrockchip_mpp -lrga -lpthread -lm" \
CC="$(BUILDKIT_PATH)/bin/$(BUILDKIT_FLAVOR)-gcc" \
LD="$(BUILDKIT_PATH)/bin/$(BUILDKIT_FLAVOR)-ld" \
CGO_ENABLED=1
# GO_RELEASE_BUILD_ARGS := $(GO_RELEASE_BUILD_ARGS) -x -work
endif

GO_CMD := $(GO_ARGS) go

BIN_DIR := $(shell pwd)/bin

TEST_DIRS := $(shell find . -name "*_test.go" -type f -exec dirname {} \; | sort -u)

hash_resource:
@shasum -a 256 resource/jetkvm_native | cut -d ' ' -f 1 > resource/jetkvm_native.sha256
build_native:
@if [ "$(SKIP_NATIVE_IF_EXISTS)" = "1" ] && [ -f "internal/native/cgo/lib/libjknative.a" ]; then \
echo "libjknative.a already exists, skipping native build..."; \
else \
echo "Building native..."; \
CC="$(BUILDKIT_PATH)/bin/$(BUILDKIT_FLAVOR)-gcc" \
LD="$(BUILDKIT_PATH)/bin/$(BUILDKIT_FLAVOR)-ld" \
./scripts/build_cgo.sh; \
fi

build_dev: hash_resource
build_dev: build_native
@echo "Building..."
$(GO_CMD) build \
-ldflags="$(GO_LDFLAGS) -X $(KVM_PKG_NAME).builtAppVersion=$(VERSION_DEV)" \
$(GO_RELEASE_BUILD_ARGS) \
-o $(BIN_DIR)/jetkvm_app cmd/main.go
-o $(BIN_DIR)/jetkvm_app -v cmd/main.go

build_test2json:
$(GO_CMD) build -o $(BIN_DIR)/test2json cmd/test2json
Expand Down Expand Up @@ -62,30 +86,32 @@ build_dev_test: build_test2json build_gotestsum
tar czfv device-tests.tar.gz -C $(BIN_DIR)/tests .

frontend:
cd ui && npm ci && npm run build:device && \
find ../static/ \
-type f \
\( -name '*.js' \
-o -name '*.css' \
-o -name '*.html' \
-o -name '*.ico' \
-o -name '*.png' \
-o -name '*.jpg' \
-o -name '*.jpeg' \
-o -name '*.gif' \
-o -name '*.svg' \
-o -name '*.webp' \
-o -name '*.woff2' \
\) \
-exec sh -c 'gzip -9 -kfv {}' \;
@if [ "$(SKIP_UI_BUILD)" = "1" ] && [ -f "static/index.html" ]; then \
echo "Skipping frontend build..."; \
else \
cd ui && npm ci && npm run build:device && \
find ../static/ -type f \
\( -name '*.js' \
-o -name '*.css' \
-o -name '*.html' \
-o -name '*.ico' \
-o -name '*.png' \
-o -name '*.jpg' \
-o -name '*.jpeg' \
-o -name '*.gif' \
-o -name '*.svg' \
-o -name '*.webp' \
-o -name '*.woff2' \
\) -exec sh -c 'gzip -9 -kfv {}' \; ;\
fi

dev_release: frontend build_dev
@echo "Uploading release... $(VERSION_DEV)"
@shasum -a 256 bin/jetkvm_app | cut -d ' ' -f 1 > bin/jetkvm_app.sha256
rclone copyto bin/jetkvm_app r2://jetkvm-update/app/$(VERSION_DEV)/jetkvm_app
rclone copyto bin/jetkvm_app.sha256 r2://jetkvm-update/app/$(VERSION_DEV)/jetkvm_app.sha256

build_release: frontend hash_resource
build_release: frontend build_native
@echo "Building release..."
$(GO_CMD) build \
-ldflags="$(GO_LDFLAGS) -X $(KVM_PKG_NAME).builtAppVersion=$(VERSION)" \
Expand All @@ -101,4 +127,4 @@ release:
@echo "Uploading release..."
@shasum -a 256 bin/jetkvm_app | cut -d ' ' -f 1 > bin/jetkvm_app.sha256
rclone copyto bin/jetkvm_app r2://jetkvm-update/app/$(VERSION)/jetkvm_app
rclone copyto bin/jetkvm_app.sha256 r2://jetkvm-update/app/$(VERSION)/jetkvm_app.sha256
rclone copyto bin/jetkvm_app.sha256 r2://jetkvm-update/app/$(VERSION)/jetkvm_app.sha256
1 change: 1 addition & 0 deletions cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ func setCloudConnectionState(state CloudConnectionState) {

go waitCtrlAndRequestDisplayUpdate(
previousState != state,
"set_cloud_connection_state",
)
}

Expand Down
Loading