Some optimizations

- refactor config
- fix updating lib
- fix resting hid
- optimize the update process
This commit is contained in:
wj-xiao
2024-10-17 11:55:29 +08:00
parent 888d0db5fa
commit df69d50ff0
17 changed files with 249 additions and 153 deletions

View File

@@ -1,13 +1,13 @@
package config
import (
"bytes"
"crypto/rand"
"encoding/base64"
"errors"
"fmt"
"log"
"os"
"strings"
"sync"
"time"
@@ -15,18 +15,6 @@ import (
"gopkg.in/yaml.v3"
)
const (
hwVersionFile = "/etc/kvm/hw"
gpioPower = "/sys/class/gpio/gpio503/value"
gpioPowerLED = "/sys/class/gpio/gpio504/value"
gpioResetAlpha = "/sys/class/gpio/gpio507/value"
gpioHDDLedAlpha = "/sys/class/gpio/gpio505/value"
gpioResetBeta = "/sys/class/gpio/gpio505/value"
)
var (
config Config
once sync.Once
@@ -41,68 +29,83 @@ var (
Crt: "server.crt",
Key: "server.key",
},
Logger: LoggerConfig{
Logger: Logger{
Level: "info",
File: "stdout",
},
Authentication: "enable",
SecretKey: generateRandomString(),
}
)
func GetInstance() *Config {
once.Do(read)
once.Do(initialize)
return &config
}
func read() {
viper.SetConfigName("server")
viper.SetConfigType("yaml")
viper.AddConfigPath("/etc/kvm/")
if err := viper.ReadInConfig(); err != nil {
func initialize() {
if err := readByFile(); err != nil {
if errors.As(err, &viper.ConfigFileNotFoundError{}) {
create()
log.Println("File /etc/kvm/server.yaml not found. Create a new one with default configuration.")
} else {
log.Println("Failed to read config file /etc/kvm/server.yaml. Using default configuration.")
}
if err = readByDefault(); err != nil {
log.Fatalf("Failed to read default configuration!")
}
log.Println("using default configuration")
}
if err := validate(); err != nil {
log.Fatalf("Failed to validate configuration!")
}
if err := viper.Unmarshal(&config); err != nil {
log.Fatalf("Failed to parse configuration file /etc/kvm/server.yaml: %s", err)
}
validate()
if config.SecretKey == "" {
config.SecretKey = defaultConfig.SecretKey
log.Fatalf("Failed to parse configuration: %s", err)
}
if config.Authentication == "disable" {
log.Println("NOTICE: Authentication is disabled! Please ensure your service is secure!")
}
log.Println("config loaded successfully")
config.HW.Version = getHwVersion()
config.HW.GPIOPower = gpioPower
config.HW.GPIOPowerLED = gpioPowerLED
switch config.HW.Version {
case HWVersionAlpha:
config.HW.GPIOHDDLed = gpioHDDLedAlpha
config.HW.GPIOReset = gpioResetAlpha
case HWVersionBeta:
config.HW.GPIOReset = gpioResetBeta
default:
log.Fatalf("Unsupported hardware version: %s", config.HW.Version)
if config.SecretKey == "" {
config.SecretKey = generateRandomString()
}
config.Hardware = getHardware()
log.Println("config loaded successfully")
}
func readByFile() error {
viper.SetConfigName("server")
viper.SetConfigType("yaml")
viper.AddConfigPath("/etc/kvm/")
return viper.ReadInConfig()
}
func readByDefault() error {
data, err := yaml.Marshal(defaultConfig)
if err != nil {
log.Printf("failed to marshal default config: %s", err)
return err
}
return viper.ReadConfig(bytes.NewBuffer(data))
}
// Create configuration file.
func create() {
var (
file *os.File
data []byte
err error
)
_ = os.MkdirAll("/etc/kvm", 0o644)
file, err := os.OpenFile("/etc/kvm/server.yaml", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644)
file, err = os.OpenFile("/etc/kvm/server.yaml", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644)
if err != nil {
log.Printf("open config failed: %s", err)
return
@@ -111,37 +114,39 @@ func create() {
_ = file.Close()
}()
data, err := yaml.Marshal(defaultConfig)
if err != nil {
if data, err = yaml.Marshal(defaultConfig); err != nil {
log.Printf("failed to marshal default config: %s", err)
return
}
_, err = file.Write(data)
if err != nil {
if _, err = file.Write(data); err != nil {
log.Printf("failed to save config: %s", err)
return
}
err = file.Sync()
if err != nil {
if err = file.Sync(); err != nil {
log.Printf("failed to sync config: %s", err)
return
}
log.Println("create file /etc/kvm/server.yaml with default configuration")
}
func validate() {
if config.Port.Http > 0 && config.Port.Https > 0 {
return
// Validate the configuration. This is to ensure compatibility with earlier versions.
func validate() error {
if viper.GetInt("port.http") > 0 && viper.GetInt("port.https") > 0 {
return nil
}
_ = os.Remove("/etc/kvm/server.yaml")
log.Println("delete empty configuration file")
if err := viper.Unmarshal(&config); err != nil {
log.Fatalf("Failed to read configuration file /etc/kvm/server.yaml: %v", err)
}
create()
return readByDefault()
}
// Generate random string for secret key.
func generateRandomString() string {
b := make([]byte, 64)
_, err := rand.Read(b)
@@ -153,15 +158,3 @@ func generateRandomString() string {
return base64.URLEncoding.EncodeToString(b)
}
func getHwVersion() HWVersion {
content, err := os.ReadFile(hwVersionFile)
if err == nil {
version := strings.ReplaceAll(string(content), "\n", "")
if version == "beta" {
return HWVersionBeta
}
}
return HWVersionAlpha
}

70
server/config/hardware.go Normal file
View File

@@ -0,0 +1,70 @@
package config
import (
"os"
"strings"
log "github.com/sirupsen/logrus"
)
type HWVersion int
const (
HWVersionAlpha HWVersion = iota
HWVersionBeta
)
const (
hwVersionFile = "/etc/kvm/hw"
gpioPower = "/sys/class/gpio/gpio503/value"
gpioPowerLED = "/sys/class/gpio/gpio504/value"
gpioResetAlpha = "/sys/class/gpio/gpio507/value"
gpioHDDLedAlpha = "/sys/class/gpio/gpio505/value"
gpioResetBeta = "/sys/class/gpio/gpio505/value"
)
func (h HWVersion) String() string {
switch h {
case HWVersionAlpha:
return "Alpha"
case HWVersionBeta:
return "Beta"
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
}
}
return HWVersionAlpha
}
func getHardware() Hardware {
h := Hardware{}
h.Version = getHwVersion()
h.GPIOPower = gpioPower
h.GPIOPowerLED = gpioPowerLED
switch h.Version {
case HWVersionAlpha:
h.GPIOHDDLed = gpioHDDLedAlpha
h.GPIOReset = gpioResetAlpha
case HWVersionBeta:
h.GPIOReset = gpioResetBeta
default:
log.Fatalf("Unsupported hardware version: %s", h.Version)
}
return h
}

View File

@@ -1,43 +1,17 @@
package config
type HWVersion int
const (
HWVersionAlpha HWVersion = iota
HWVersionBeta
)
func (h HWVersion) String() string {
switch h {
case HWVersionAlpha:
return "Alpha"
case HWVersionBeta:
return "Beta"
default:
return "Unknown"
}
}
type Config struct {
Protocol string `yaml:"proto"`
Port Port `yaml:"port"`
Cert Cert `yaml:"cert"`
Logger LoggerConfig `yaml:"logger"`
Authentication string `yaml:"authentication"`
SecretKey string `yaml:"secretKey"`
Protocol string `yaml:"proto"`
Port Port `yaml:"port"`
Cert Cert `yaml:"cert"`
Logger Logger `yaml:"logger"`
Authentication string `yaml:"authentication"`
SecretKey string `yaml:"secretKey"`
HW HW `yaml:"-"`
Hardware Hardware `yaml:"-"`
}
type HW struct {
Version HWVersion `yaml:"-"`
GPIOReset string `yaml:"-"`
GPIOPower string `yaml:"-"`
GPIOPowerLED string `yaml:"-"`
GPIOHDDLed string `yaml:"-"`
}
type LoggerConfig struct {
type Logger struct {
Level string `yaml:"level"`
File string `yaml:"file"`
}
@@ -51,3 +25,11 @@ type Cert struct {
Crt string `yaml:"crt"`
Key string `yaml:"key"`
}
type Hardware struct {
Version HWVersion `yaml:"-"`
GPIOReset string `yaml:"-"`
GPIOPower string `yaml:"-"`
GPIOPowerLED string `yaml:"-"`
GPIOHDDLed string `yaml:"-"`
}

View File

@@ -9,11 +9,12 @@ require (
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/gorilla/websocket v1.5.3
github.com/mervick/aes-everywhere/go/aes256 v0.0.0-20240803013625-6759956693c0
github.com/pion/webrtc/v4 v4.0.1
github.com/rs/cors/wrapper/gin v0.0.0-20240830163046-1084d89a1692
github.com/sirupsen/logrus v1.9.3
github.com/spf13/viper v1.19.0
github.com/unrolled/secure v1.15.0
golang.org/x/crypto v0.23.0
golang.org/x/crypto v0.28.0
gopkg.in/yaml.v3 v3.0.1
)
@@ -28,6 +29,7 @@ require (
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
@@ -38,6 +40,21 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pion/datachannel v1.5.9 // indirect
github.com/pion/dtls/v3 v3.0.3 // indirect
github.com/pion/ice/v4 v4.0.2 // indirect
github.com/pion/interceptor v0.1.37 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/mdns/v2 v2.0.7 // indirect
github.com/pion/randutil v0.1.0 // indirect
github.com/pion/rtcp v1.2.14 // indirect
github.com/pion/rtp v1.8.9 // indirect
github.com/pion/sctp v1.8.33 // indirect
github.com/pion/sdp/v3 v3.0.9 // indirect
github.com/pion/srtp/v3 v3.0.4 // indirect
github.com/pion/stun/v3 v3.0.0 // indirect
github.com/pion/transport/v3 v3.0.7 // indirect
github.com/pion/turn/v4 v4.0.0 // indirect
github.com/rs/cors v1.11.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
@@ -48,13 +65,14 @@ require (
github.com/subosito/gotenv v1.6.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/wlynxg/anet v0.0.3 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/text v0.19.0 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)

View File

@@ -37,6 +37,8 @@ github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVI
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
@@ -68,6 +70,38 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pion/datachannel v1.5.9 h1:LpIWAOYPyDrXtU+BW7X0Yt/vGtYxtXQ8ql7dFfYUVZA=
github.com/pion/datachannel v1.5.9/go.mod h1:kDUuk4CU4Uxp82NH4LQZbISULkX/HtzKa4P7ldf9izE=
github.com/pion/dtls/v3 v3.0.3 h1:j5ajZbQwff7Z8k3pE3S+rQ4STvKvXUdKsi/07ka+OWM=
github.com/pion/dtls/v3 v3.0.3/go.mod h1:weOTUyIV4z0bQaVzKe8kpaP17+us3yAuiQsEAG1STMU=
github.com/pion/ice/v4 v4.0.2 h1:1JhBRX8iQLi0+TfcavTjPjI6GO41MFn4CeTBX+Y9h5s=
github.com/pion/ice/v4 v4.0.2/go.mod h1:DCdqyzgtsDNYN6/3U8044j3U7qsJ9KFJC92VnOWHvXg=
github.com/pion/interceptor v0.1.37 h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI=
github.com/pion/interceptor v0.1.37/go.mod h1:JzxbJ4umVTlZAf+/utHzNesY8tmRkM2lVmkS82TTj8Y=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/mdns/v2 v2.0.7 h1:c9kM8ewCgjslaAmicYMFQIde2H9/lrZpjBkN8VwoVtM=
github.com/pion/mdns/v2 v2.0.7/go.mod h1:vAdSYNAT0Jy3Ru0zl2YiW3Rm/fJCwIeM0nToenfOJKA=
github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE=
github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk=
github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
github.com/pion/sctp v1.8.33 h1:dSE4wX6uTJBcNm8+YlMg7lw1wqyKHggsP5uKbdj+NZw=
github.com/pion/sctp v1.8.33/go.mod h1:beTnqSzewI53KWoG3nqB282oDMGrhNxBdb+JZnkCwRM=
github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY=
github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M=
github.com/pion/srtp/v3 v3.0.4 h1:2Z6vDVxzrX3UHEgrUyIGM4rRouoC7v+NiF1IHtp9B5M=
github.com/pion/srtp/v3 v3.0.4/go.mod h1:1Jx3FwDoxpRaTh1oRV8A/6G1BnFL+QI82eK4ms8EEJQ=
github.com/pion/stun/v3 v3.0.0 h1:4h1gwhWLWuZWOJIJR9s2ferRO+W3zA/b6ijOI6mKzUw=
github.com/pion/stun/v3 v3.0.0/go.mod h1:HvCN8txt8mwi4FBvS3EmDghW6aQJ24T+y+1TKjB5jyU=
github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0=
github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo=
github.com/pion/turn/v4 v4.0.0 h1:qxplo3Rxa9Yg1xXDxxH8xaqcyGUtbHYw4QSCvmFWvhM=
github.com/pion/turn/v4 v4.0.0/go.mod h1:MuPDkm15nYSklKpN8vWJ9W2M0PlyQZqYt1McGuxG7mA=
github.com/pion/webrtc/v4 v4.0.1 h1:6Unwc6JzoTsjxetcAIoWH81RUM4K5dBc1BbJGcF9WVE=
github.com/pion/webrtc/v4 v4.0.1/go.mod h1:SfNn8CcFxR6OUVjLXVslAQ3a3994JhyE3Hw1jAuqEto=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -113,6 +147,8 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/unrolled/secure v1.15.0 h1:q7x+pdp8jAHnbzxu6UheP8fRlG/rwYTb8TPuQ3rn9Og=
github.com/unrolled/secure v1.15.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
github.com/wlynxg/anet v0.0.3 h1:PvR53psxFXstc12jelG6f1Lv4MWqE0tI76/hHGjh9rg=
github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
@@ -120,21 +156,21 @@ go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTV
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -1,15 +1,13 @@
package router
import (
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"NanoKVM-Server/middleware"
"NanoKVM-Server/service/application"
"github.com/gin-gonic/gin"
)
func applicationRouter(r *gin.Engine) {
log.Debugf("application router init")
service := application.NewService()
api := r.Group("/api").Use(middleware.CheckToken())
@@ -17,5 +15,4 @@ func applicationRouter(r *gin.Engine) {
api.POST("/application/update", service.Update) // update application
api.GET("/application/lib", service.GetLib) // check if lib exists
api.POST("/application/lib", service.UpdateLib) // update lib
log.Debugf("application router init done")
}

View File

@@ -7,11 +7,13 @@ import (
"github.com/gin-gonic/contrib/static"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
)
func Init(r *gin.Engine) {
web(r)
server(r)
log.Debugf("router init done")
}
func web(r *gin.Engine) {

View File

@@ -1,6 +1,8 @@
package application
import (
"NanoKVM-Server/proto"
"NanoKVM-Server/utils"
"errors"
"fmt"
"net/http"
@@ -11,9 +13,6 @@ import (
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"NanoKVM-Server/proto"
"NanoKVM-Server/utils"
)
func (s *Service) GetLib(c *gin.Context) {
@@ -52,7 +51,7 @@ func (s *Service) UpdateLib(c *gin.Context) {
return
}
err := utils.MoveFile(temporary+"/"+libName, libDir+"/") // update lib
err := utils.MoveFile(temporary+"/"+libName, libDir+"/"+libName) // update lib
if err != nil {
rsp.ErrRsp(c, -2, "update lib failed")
return

View File

@@ -80,7 +80,7 @@ func (h *Hid) mouseMoveRelative(event []int) {
}
func (h *Hid) writeWithTimeout(file *os.File, data []byte) {
deadline := time.Now().Add(9 * time.Millisecond)
deadline := time.Now().Add(8 * time.Millisecond)
_ = file.SetWriteDeadline(deadline)
_, err := file.Write(data)
@@ -88,7 +88,7 @@ func (h *Hid) writeWithTimeout(file *os.File, data []byte) {
switch {
case errors.Is(err, os.ErrClosed):
log.Debugf("hid already closed, reopen it...")
h.Open()
h.OpenNoLock()
case errors.Is(err, os.ErrDeadlineExceeded):
log.Debugf("write to hid timeout")
default:

View File

@@ -61,7 +61,7 @@ func (h *Hid) Write(file *os.File, data []byte) {
if err != nil {
if errors.Is(err, os.ErrClosed) {
log.Debugf("hid already closed, reopen it...")
h.Open()
h.OpenNoLock()
} else {
log.Errorf("write to hid failed: %s", err)
}

View File

@@ -1,12 +1,11 @@
package hid
import (
"NanoKVM-Server/proto"
"os"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"NanoKVM-Server/proto"
)
func (s *Service) Reset(c *gin.Context) {
@@ -15,7 +14,7 @@ func (s *Service) Reset(c *gin.Context) {
defer s.hid.kbMutex.Unlock()
// reset USB
f, err := os.Open("/sys/kernel/config/usb_gadget/g0/UDC")
f, err := os.OpenFile("/sys/kernel/config/usb_gadget/g0/UDC", os.O_WRONLY, 0644)
if err != nil {
log.Errorf("open /sys/kernel/config/usb_gadget/g0/UDC failed: %s", err)
rsp.ErrRsp(c, -1, "open usb gadget file failed")
@@ -51,7 +50,7 @@ func (s *Service) Reset(c *gin.Context) {
return
}
f, err = os.Open("/sys/kernel/config/usb_gadget/g0/UDC")
f, err = os.OpenFile("/sys/kernel/config/usb_gadget/g0/UDC", os.O_WRONLY, 0644)
if err != nil {
log.Errorf("open /sys/kernel/config/usb_gadget/g0/UDC failed: %s", err)
rsp.ErrRsp(c, -1, "open usb gadget file failed")

View File

@@ -26,9 +26,9 @@ func (s *Service) SetGpio(c *gin.Context) {
switch req.Type {
case "power":
device = s.config.HW.GPIOPower
device = s.config.Hardware.GPIOPower
case "reset":
device = s.config.HW.GPIOReset
device = s.config.Hardware.GPIOReset
default:
rsp.ErrRsp(c, -2, fmt.Sprintf("invalid power event: %s", req.Type))
return
@@ -53,15 +53,15 @@ func (s *Service) SetGpio(c *gin.Context) {
func (s *Service) GetGpio(c *gin.Context) {
var rsp proto.Response
pwr, err := readGpio(s.config.HW.GPIOPowerLED)
pwr, err := readGpio(s.config.Hardware.GPIOPowerLED)
if err != nil {
rsp.ErrRsp(c, -2, fmt.Sprintf("failed to read power led: %s", err))
return
}
hdd := false
if s.config.HW.Version == config.HWVersionAlpha {
hdd, err = readGpio(s.config.HW.GPIOHDDLed)
if s.config.Hardware.Version == config.HWVersionAlpha {
hdd, err = readGpio(s.config.Hardware.GPIOHDDLed)
if err != nil {
rsp.ErrRsp(c, -2, fmt.Sprintf("failed to read hdd led: %s", err))
return

View File

@@ -25,7 +25,7 @@ func Unzip(filename string, dest string) error {
}
} else {
err = unzipFile(dstPath, f)
if err == nil {
if err != nil {
return err
}
}

View File

@@ -21,5 +21,9 @@ export function getLib() {
// download lib
export function updateLib() {
return http.post('/api/application/lib');
return http.request({
method: 'post',
url: '/api/application/lib',
timeout: 15 * 60 * 1000
});
}

View File

@@ -44,10 +44,10 @@ export const Lib = ({ setIsLoading, setTips }: LibProps) => {
}
})
.finally(() => {
setIsLoading(false);
setTips('');
setTimeout(() => {
setIsLoading(false);
setTips('');
window.location.reload();
}, 6000);
});

View File

@@ -84,13 +84,11 @@ export const Update = ({ setIsBadgeVisible }: UpdateProps) => {
setErrMsg(t('update.updateFailed'));
}
})
.catch(() => {
setErrMsg(t('update.updateFailed'));
})
.finally(() => {
setIsUpdating(false);
setTimeout(() => {
setIsUpdating(false);
setErrMsg('');
window.location.reload();
}, 6000);
});

View File

@@ -84,13 +84,11 @@ export const Update = ({ setIsBadgeVisible }: UpdateProps) => {
setErrMsg(t('update.updateFailed'));
}
})
.catch(() => {
setErrMsg(t('update.updateFailed'));
})
.finally(() => {
setIsUpdating(false);
setTimeout(() => {
setIsUpdating(false);
setErrMsg('');
window.location.reload();
}, 6000);
});