mirror of
https://github.com/jetkvm/kvm.git
synced 2026-05-21 05:20:35 +00:00
b3ce335922
* fix: implement factory reset replacing config-only reset (#529) - Add rpcFactoryReset that removes all user data (config, images, TLS certs, SSH keys, serial settings, crash dumps) and reboots - Remove rpcResetConfig RPC handler (keep internal resetConfig for OTA and native event use) - Replace Reset Config UI with Factory Reset button (danger theme) and confirmation dialog in Settings > Advanced - Update localization: add factory reset keys, remove reset config keys - Add E2E test verifying factory reset UI and dialog copy - Update ra-all factory reset test to restore SSH keys after reset * fix: ensure factory reset reboots even when path removal fails The early return on error exited rpcFactoryReset before reaching the goroutine that triggers hwReboot, leaving the device partially wiped with no reboot. Log the warning instead and always fall through to the reboot. * fix: remove hardcoded screenshot path from factory reset e2e test
110 lines
3.3 KiB
Go
110 lines
3.3 KiB
Go
package kvm
|
|
|
|
import (
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/jetkvm/kvm/internal/diagnostics"
|
|
"github.com/jetkvm/kvm/internal/native"
|
|
"github.com/jetkvm/kvm/internal/sync"
|
|
|
|
"github.com/Masterminds/semver/v3"
|
|
"github.com/pion/webrtc/v4/pkg/media"
|
|
)
|
|
|
|
var (
|
|
nativeInstance native.NativeInterface
|
|
nativeCmdLock = sync.Mutex{}
|
|
)
|
|
|
|
func initNative(systemVersion *semver.Version, appVersion *semver.Version) {
|
|
if failsafeModeActive {
|
|
nativeInstance = &native.EmptyNativeInterface{}
|
|
nativeLogger.Warn().Msg("failsafe mode active, using empty native interface")
|
|
return
|
|
}
|
|
|
|
nativeLogger.Info().Msg("initializing native proxy")
|
|
var err error
|
|
nativeInstance, err = native.NewNativeProxy(native.NativeOptions{
|
|
SystemVersion: systemVersion,
|
|
AppVersion: appVersion,
|
|
DisplayRotation: config.GetDisplayRotation(),
|
|
DefaultQualityFactor: config.VideoQualityFactor,
|
|
MaxRestartAttempts: config.NativeMaxRestart,
|
|
OnNativeRestart: func() {
|
|
configureDisplayOnNativeRestart()
|
|
},
|
|
OnVideoStateChange: func(state native.VideoState) {
|
|
lastVideoState = state
|
|
triggerVideoStateUpdate()
|
|
requestDisplayUpdate(false, "video_state_changed")
|
|
},
|
|
OnIndevEvent: func(event string) {
|
|
nativeLogger.Trace().Str("event", event).Msg("indev event received")
|
|
wakeDisplay(false, "indev_event")
|
|
},
|
|
OnRpcEvent: func(event string) {
|
|
nativeCmdLock.Lock()
|
|
defer nativeCmdLock.Unlock()
|
|
|
|
nativeLogger.Trace().Str("event", event).Msg("rpc event received")
|
|
switch event {
|
|
case "resetConfig":
|
|
nativeLogger.Info().Msg("Reset configuration request via native rpc event")
|
|
err := resetConfig()
|
|
if err != nil {
|
|
nativeLogger.Warn().Err(err).Msg("error resetting config")
|
|
}
|
|
_ = rpcReboot(true)
|
|
case "reboot":
|
|
nativeLogger.Info().Msg("Reboot request via native rpc event")
|
|
_ = rpcReboot(true)
|
|
case "toggleDHCPClient":
|
|
nativeLogger.Info().Msg("Toggle DHCP request via native rpc event")
|
|
_ = rpcToggleDHCPClient()
|
|
default:
|
|
nativeLogger.Warn().Str("event", event).Msg("unknown rpc event received")
|
|
}
|
|
},
|
|
OnVideoFrameReceived: func(frame []byte, duration time.Duration) {
|
|
if currentSession != nil {
|
|
err := currentSession.VideoTrack.WriteSample(media.Sample{Data: frame, Duration: duration})
|
|
if err != nil {
|
|
nativeLogger.Warn().Err(err).Msg("error writing sample")
|
|
}
|
|
}
|
|
},
|
|
GetSessionInfo: func() diagnostics.SessionInfo {
|
|
info := diagnostics.SessionInfo{
|
|
ActiveSessions: getActiveSessions(),
|
|
HasCurrentSession: currentSession != nil,
|
|
}
|
|
if currentSession != nil {
|
|
sessionInfo := currentSession.GetDiagnosticsInfo()
|
|
info.ICEConnectionState = sessionInfo.ICEConnectionState
|
|
info.SignalingState = sessionInfo.SignalingState
|
|
info.ConnectionState = sessionInfo.ConnectionState
|
|
info.DataChannels = sessionInfo.DataChannels
|
|
}
|
|
return info
|
|
},
|
|
})
|
|
if err != nil {
|
|
nativeLogger.Fatal().Err(err).Msg("failed to create native proxy")
|
|
}
|
|
|
|
if err := nativeInstance.Start(); err != nil {
|
|
nativeLogger.Fatal().Err(err).Msg("failed to start native proxy")
|
|
}
|
|
go func() {
|
|
if err := nativeInstance.VideoSetEDID(config.EdidString); err != nil {
|
|
nativeLogger.Warn().Err(err).Msg("error setting EDID")
|
|
}
|
|
}()
|
|
|
|
if os.Getenv("JETKVM_CRASH_TESTING") == "1" {
|
|
nativeInstance.DoNotUseThisIsForCrashTestingOnly()
|
|
}
|
|
}
|