Skip to content

Commit 40a1d23

Browse files
committed
feat: support self-hosted firmware WebUI interface
Add support for the self-hosted firmware WebUI interface. Signed-off-by: GL.iNet-Yongping.Xie <yongping.xie@gl-inet.com>
1 parent 80112c7 commit 40a1d23

7 files changed

Lines changed: 82 additions & 7 deletions

File tree

docker-compose/.env.arm64.example

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ COTURN_IMAGE=coturn/coturn:edge-alpine-arm64v8
2222
# https://github.com/gl-inet/glkvm-cloud/blob/main/docker-compose/nginx-reverse-proxy-example.conf
2323
REVERSE_PROXY_ENABLED=false
2424

25+
# =====================================================
26+
# Selfhost WebUI URL (Optional)
27+
# =====================================================
28+
# The full URL (including scheme) of the self-hosted cloud WebUI.
29+
# This URL is written to the KVM device as /etc/kvmd/user/selfhost-cloud.json
30+
# so firmware can read it and create a navigation link in the device's web page.
31+
#
32+
# If left empty, the URL is automatically derived from the browser's current
33+
# address when copying the installation script.
34+
#
35+
# Examples:
36+
# SELFHOST_WEBUI_URL=https://kvm.example.com
37+
# SELFHOST_WEBUI_URL=https://192.168.1.100
38+
SELFHOST_WEBUI_URL=
39+
2540
# =====================================================
2641
# Device Remote Access Domain (Reverse Proxy Mode Only)
2742
# =====================================================

docker-compose/.env.example

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ COTURN_IMAGE=coturn/coturn:edge-alpine
2222
# https://github.com/gl-inet/glkvm-cloud/blob/main/docker-compose/nginx-reverse-proxy-example.conf
2323
REVERSE_PROXY_ENABLED=false
2424

25+
# =====================================================
26+
# Selfhost WebUI URL (Optional)
27+
# =====================================================
28+
# The full URL (including scheme) of the self-hosted cloud WebUI.
29+
# This URL is written to the KVM device as /etc/kvmd/user/selfhost-cloud.json
30+
# so firmware can read it and create a navigation link in the device's web page.
31+
#
32+
# If left empty, the URL is automatically derived from the browser's current
33+
# address when copying the installation script.
34+
#
35+
# Examples:
36+
# SELFHOST_WEBUI_URL=https://kvm.example.com
37+
# SELFHOST_WEBUI_URL=https://192.168.1.100
38+
SELFHOST_WEBUI_URL=
39+
40+
2541
# =====================================================
2642
# Device Remote Access Domain (Reverse Proxy Mode Only)
2743
# =====================================================

docker-compose/docker-compose.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ services:
5353
OIDC_ADMIN_GROUP: ${OIDC_ADMIN_GROUP:-}
5454
OIDC_ADMIN_USERS: ${OIDC_ADMIN_USERS:-}
5555

56+
# ---- Selfhost WebUI URL ----
57+
SELFHOST_WEBUI_URL: ${SELFHOST_WEBUI_URL:-}
58+
5659
# ---- Reverse Proxy ----
5760
REVERSE_PROXY_ENABLED: ${REVERSE_PROXY_ENABLED:-false}
5861

internal/http/router.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,19 @@ func RegisterAPIRoutes(r *gin.Engine, d Deps) {
9090
}
9191
}
9292

93+
// Determine selfhost WebUI URL
94+
webUIURL := strings.TrimSpace(cfg.SelfhostWebUIURL)
95+
if webUIURL == "" {
96+
scheme := "https"
97+
if c.Request.TLS == nil {
98+
scheme = "http"
99+
}
100+
if fwdProto := c.GetHeader("X-Forwarded-Proto"); fwdProto != "" {
101+
scheme = fwdProto
102+
}
103+
webUIURL = scheme + "://" + c.Request.Host
104+
}
105+
93106
data := scriptInfoResp{
94107
Hostname: chosen, // reuse the same chosen value
95108
Port: cfg.AddrDev,
@@ -98,6 +111,7 @@ func RegisterAPIRoutes(r *gin.Engine, d Deps) {
98111
WebrtcPort: cfg.WebrtcPort,
99112
WebrtcUsername: cfg.WebrtcUsername,
100113
WebrtcPassword: cfg.WebrtcPassword,
114+
WebUIURL: webUIURL,
101115
}
102116

103117
dto.Write(c, dto.Ok(traceID, data))
@@ -158,6 +172,7 @@ type scriptInfoResp struct {
158172
WebrtcPort string `json:"webrtcPort"`
159173
WebrtcUsername string `json:"webrtcUsername"`
160174
WebrtcPassword string `json:"webrtcPassword"`
175+
WebUIURL string `json:"webUIURL"`
161176
}
162177

163178
func isIP(addr string) bool {

internal/server/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package server
22

33
const RttysVersion = "5.2.0"
4-
const KVMCloudVersion = "v2.4.0"
4+
const KVMCloudVersion = "v2.5.0"
55

66
var (
77
GitCommit = ""

ui/src/views/device/components/addDeviceDialog.vue

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const OperatingSystemTranslated = computed(() => {
7070
])
7171
})
7272
73-
const generateScript = (hostname: string, port:string, token: string, webrtcIP: string, webrtcPort: string, webrtcUsername: string, webrtcPassword: string) => {
73+
const generateScript = (hostname: string, port:string, token: string, webrtcIP: string, webrtcPort: string, webrtcUsername: string, webrtcPassword: string, webUIURL: string) => {
7474
if (state.operatingSystem === OperatingSystemEnum.GL_KVM) {
7575
return `#!/bin/sh
7676
@@ -81,15 +81,25 @@ WEBRTC_IP="${webrtcIP}"
8181
WEBRTC_PORT="${webrtcPort}"
8282
WEBRTC_USERNAME="${webrtcUsername}"
8383
WEBRTC_PASSWORD="${webrtcPassword}"
84+
WEBUI_URL="${webUIURL}"
8485
8586
TARGET_DIR="/etc/kvmd/user/scripts"
8687
SCRIPT_FILE="$TARGET_DIR/S01selfCloud"
8788
WATCHDOG_SCRIPT="$TARGET_DIR/rtty-loop.sh"
89+
CLOUD_CONFIG="/etc/kvmd/user/selfhost-cloud.json"
8890
8991
# 1. Create directory
9092
mkdir -p "$TARGET_DIR"
9193
92-
# 2. Write S01selfCloud script
94+
# 2. Write selfhost cloud config JSON
95+
cat <<CLOUDCFG > "$CLOUD_CONFIG"
96+
{
97+
"webui_url": "$WEBUI_URL",
98+
"updated_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
99+
}
100+
CLOUDCFG
101+
102+
# 3. Write S01selfCloud script
93103
cat <<'EOF' > "$SCRIPT_FILE"
94104
#!/bin/sh
95105
@@ -181,10 +191,10 @@ esac
181191
exit 0
182192
EOF
183193
184-
# 3. Add execution permissions
194+
# 4. Add execution permissions
185195
chmod +x "$SCRIPT_FILE"
186196
187-
# 4. Execute restart once
197+
# 5. Execute restart once
188198
"$SCRIPT_FILE" restart
189199
190200
`
@@ -202,8 +212,8 @@ chmod +x "$SCRIPT_FILE"
202212
203213
/** 组装脚本 */
204214
const handleGenerateScript = () => {
205-
const { hostname, port, token, webrtcIP, webrtcPort, webrtcUsername, webrtcPassword } = state.scriptData as any
206-
state.scriptContent = generateScript(hostname, port, token, webrtcIP, webrtcPort, webrtcUsername, webrtcPassword)
215+
const { hostname, port, token, webrtcIP, webrtcPort, webrtcUsername, webrtcPassword, webUIURL } = state.scriptData as any
216+
state.scriptContent = generateScript(hostname, port, token, webrtcIP, webrtcPort, webrtcUsername, webrtcPassword, webUIURL)
207217
}
208218
209219
/** 复制脚本 */

xconfig/config.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,15 @@ type Config struct {
105105
// Platform access domain restriction.
106106
// When set, only requests with a matching domain are allowed to access the platform.
107107
WebUIHost string
108+
109+
// =====================================================
110+
// Selfhost WebUI URL
111+
// =====================================================
112+
// The full URL (including scheme) of the self-hosted cloud WebUI.
113+
// Written to the KVM device as /etc/kvmd/user/selfhost-cloud.json
114+
// so firmware can read it and create a link in the device's web page.
115+
// If empty, the URL is derived from the browser's current request.
116+
SelfhostWebUIURL string
108117
}
109118

110119
// docker mode fixed path for reading certificate
@@ -202,6 +211,9 @@ func parseYamlCfg(cfg *Config, conf string) error {
202211
getConfigOpt(yamlCfg, "ldap-admin-group", &cfg.LdapAdminGroup)
203212
getConfigOpt(yamlCfg, "ldap-admin-users", &cfg.LdapAdminUsers)
204213

214+
// Selfhost WebUI URL
215+
getConfigOpt(yamlCfg, "selfhost-webui-url", &cfg.SelfhostWebUIURL)
216+
205217
// ===== OIDC configuration (generic OIDC provider) =====
206218
// Switch and basic endpoints
207219
getConfigOpt(yamlCfg, "oidc-enabled", &cfg.OIDCEnabled)
@@ -342,6 +354,10 @@ func applyEnvCfg(cfg *Config) error {
342354
cfg.DeviceEndpointHost = cleaned
343355
}
344356

357+
if v := strings.TrimSpace(os.Getenv("SELFHOST_WEBUI_URL")); v != "" {
358+
cfg.SelfhostWebUIURL = v
359+
}
360+
345361
if v := strings.TrimSpace(os.Getenv("WEB_UI_HOST")); v != "" {
346362
cleaned := v
347363
// 1. Remove scheme if present (http:// or https://)

0 commit comments

Comments
 (0)