Files
BatchuKVM/server/config/config.go

123 lines
2.3 KiB
Go

package config
import (
"bytes"
"errors"
"log"
"os"
"sync"
"github.com/spf13/viper"
"gopkg.in/yaml.v3"
)
var (
instance Config
once sync.Once
)
func GetInstance() *Config {
once.Do(initialize)
return &instance
}
func initialize() {
if err := readByFile(); err != nil {
if errors.As(err, &viper.ConfigFileNotFoundError{}) {
create()
}
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(&instance); err != nil {
log.Fatalf("Failed to parse configuration: %s", err)
}
checkDefaultValue()
if instance.Authentication == "disable" {
log.Println("NOTICE: Authentication is disabled! Please ensure your service is secure!")
}
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)
if err != nil {
log.Printf("open config failed: %s", err)
return
}
defer func() {
_ = file.Close()
}()
if data, err = yaml.Marshal(defaultConfig); err != nil {
log.Printf("failed to marshal default config: %s", err)
return
}
if _, err = file.Write(data); err != nil {
log.Printf("failed to save config: %s", err)
return
}
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")
}
// 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")
create()
return readByDefault()
}