2022-06-06 21:48:53 +08:00
|
|
|
package bootstrap
|
|
|
|
|
|
|
|
import (
|
2023-02-18 19:03:07 +08:00
|
|
|
"net/url"
|
2022-06-15 14:57:13 +08:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2023-02-18 19:03:07 +08:00
|
|
|
"strings"
|
2022-06-15 14:57:13 +08:00
|
|
|
|
2025-07-01 09:54:50 +08:00
|
|
|
"github.com/OpenListTeam/OpenList/v4/cmd/flags"
|
|
|
|
"github.com/OpenListTeam/OpenList/v4/drivers/base"
|
|
|
|
"github.com/OpenListTeam/OpenList/v4/internal/conf"
|
|
|
|
"github.com/OpenListTeam/OpenList/v4/internal/net"
|
|
|
|
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
2023-07-10 22:06:50 +08:00
|
|
|
"github.com/caarlos0/env/v9"
|
2025-08-05 21:42:54 +08:00
|
|
|
"github.com/shirou/gopsutil/v4/mem"
|
2022-06-06 21:48:53 +08:00
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
)
|
|
|
|
|
2025-07-22 10:51:28 +08:00
|
|
|
// Program working directory
|
|
|
|
func PWD() string {
|
2022-11-01 19:14:49 +08:00
|
|
|
if flags.ForceBinDir {
|
2025-07-22 10:51:28 +08:00
|
|
|
ex, err := os.Executable()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
2022-11-01 19:14:49 +08:00
|
|
|
}
|
2025-07-22 10:51:28 +08:00
|
|
|
pwd := filepath.Dir(ex)
|
|
|
|
return pwd
|
|
|
|
}
|
|
|
|
d, err := os.Getwd()
|
|
|
|
if err != nil {
|
|
|
|
d = "."
|
|
|
|
}
|
|
|
|
return d
|
|
|
|
}
|
|
|
|
|
|
|
|
func InitConfig() {
|
|
|
|
pwd := PWD()
|
|
|
|
dataDir := flags.DataDir
|
|
|
|
if !filepath.IsAbs(dataDir) {
|
|
|
|
flags.DataDir = filepath.Join(pwd, flags.DataDir)
|
2022-11-01 19:14:49 +08:00
|
|
|
}
|
|
|
|
configPath := filepath.Join(flags.DataDir, "config.json")
|
|
|
|
log.Infof("reading config file: %s", configPath)
|
|
|
|
if !utils.Exists(configPath) {
|
2022-06-06 21:48:53 +08:00
|
|
|
log.Infof("config file not exists, creating default config file")
|
2022-11-01 19:14:49 +08:00
|
|
|
_, err := utils.CreateNestedFile(configPath)
|
2022-06-06 21:48:53 +08:00
|
|
|
if err != nil {
|
2022-06-23 16:49:37 +08:00
|
|
|
log.Fatalf("failed to create config file: %+v", err)
|
2022-06-06 21:48:53 +08:00
|
|
|
}
|
2025-07-22 10:51:28 +08:00
|
|
|
conf.Conf = conf.DefaultConfig(dataDir)
|
2024-12-30 22:48:33 +08:00
|
|
|
LastLaunchedVersion = conf.Version
|
|
|
|
conf.Conf.LastLaunchedVersion = conf.Version
|
2022-11-01 19:14:49 +08:00
|
|
|
if !utils.WriteJsonToFile(configPath, conf.Conf) {
|
2022-06-06 21:48:53 +08:00
|
|
|
log.Fatalf("failed to create default config file")
|
|
|
|
}
|
|
|
|
} else {
|
2022-11-01 19:14:49 +08:00
|
|
|
configBytes, err := os.ReadFile(configPath)
|
2022-06-06 21:48:53 +08:00
|
|
|
if err != nil {
|
2022-08-07 13:09:59 +08:00
|
|
|
log.Fatalf("reading config file error: %+v", err)
|
2022-06-06 21:48:53 +08:00
|
|
|
}
|
2025-07-22 10:51:28 +08:00
|
|
|
conf.Conf = conf.DefaultConfig(dataDir)
|
2022-08-03 14:26:59 +08:00
|
|
|
err = utils.Json.Unmarshal(configBytes, conf.Conf)
|
2022-06-06 21:48:53 +08:00
|
|
|
if err != nil {
|
2022-08-07 13:09:59 +08:00
|
|
|
log.Fatalf("load config error: %+v", err)
|
2022-06-06 21:48:53 +08:00
|
|
|
}
|
2024-12-30 22:48:33 +08:00
|
|
|
LastLaunchedVersion = conf.Conf.LastLaunchedVersion
|
2025-01-23 22:49:35 +08:00
|
|
|
if strings.HasPrefix(conf.Version, "v") || LastLaunchedVersion == "" {
|
2024-12-30 22:48:33 +08:00
|
|
|
conf.Conf.LastLaunchedVersion = conf.Version
|
|
|
|
}
|
2022-06-06 21:48:53 +08:00
|
|
|
// update config.json struct
|
2022-08-03 14:26:59 +08:00
|
|
|
confBody, err := utils.Json.MarshalIndent(conf.Conf, "", " ")
|
2022-06-06 21:48:53 +08:00
|
|
|
if err != nil {
|
2022-08-07 13:09:59 +08:00
|
|
|
log.Fatalf("marshal config error: %+v", err)
|
2022-06-06 21:48:53 +08:00
|
|
|
}
|
2023-02-08 22:01:26 +08:00
|
|
|
err = os.WriteFile(configPath, confBody, 0o777)
|
2022-06-06 21:48:53 +08:00
|
|
|
if err != nil {
|
2022-08-07 13:09:59 +08:00
|
|
|
log.Fatalf("update config struct error: %+v", err)
|
2022-06-06 21:48:53 +08:00
|
|
|
}
|
|
|
|
}
|
2025-01-27 20:08:39 +08:00
|
|
|
if conf.Conf.MaxConcurrency > 0 {
|
|
|
|
net.DefaultConcurrencyLimit = &net.ConcurrencyLimit{Limit: conf.Conf.MaxConcurrency}
|
|
|
|
}
|
2025-08-05 21:42:54 +08:00
|
|
|
if conf.Conf.MaxBufferLimit < 0 {
|
|
|
|
m, _ := mem.VirtualMemory()
|
|
|
|
if m != nil {
|
|
|
|
conf.MaxBufferLimit = max(int(float64(m.Total)*0.05), 4*utils.MB)
|
|
|
|
conf.MaxBufferLimit -= conf.MaxBufferLimit % utils.MB
|
|
|
|
} else {
|
|
|
|
conf.MaxBufferLimit = 16 * utils.MB
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
conf.MaxBufferLimit = conf.Conf.MaxBufferLimit * utils.MB
|
|
|
|
}
|
2025-08-11 23:41:22 +08:00
|
|
|
log.Infof("max buffer limit: %dMB", conf.MaxBufferLimit/utils.MB)
|
2022-08-03 14:26:59 +08:00
|
|
|
if !conf.Conf.Force {
|
2022-06-06 21:48:53 +08:00
|
|
|
confFromEnv()
|
|
|
|
}
|
2025-07-25 11:33:27 +08:00
|
|
|
if len(conf.Conf.Log.Filter.Filters) == 0 {
|
|
|
|
conf.Conf.Log.Filter.Enable = false
|
|
|
|
}
|
2022-06-23 16:49:37 +08:00
|
|
|
// convert abs path
|
2025-07-22 10:51:28 +08:00
|
|
|
convertAbsPath := func(path *string) {
|
|
|
|
if !filepath.IsAbs(*path) {
|
|
|
|
*path = filepath.Join(pwd, *path)
|
2022-06-23 16:49:37 +08:00
|
|
|
}
|
2025-07-22 10:51:28 +08:00
|
|
|
}
|
|
|
|
convertAbsPath(&conf.Conf.TempDir)
|
|
|
|
convertAbsPath(&conf.Conf.BleveDir)
|
|
|
|
convertAbsPath(&conf.Conf.Log.Name)
|
|
|
|
convertAbsPath(&conf.Conf.Database.DBFile)
|
|
|
|
if conf.Conf.DistDir != "" {
|
|
|
|
convertAbsPath(&conf.Conf.DistDir)
|
2022-06-23 16:49:37 +08:00
|
|
|
}
|
2024-08-07 12:16:21 +08:00
|
|
|
err := os.MkdirAll(conf.Conf.TempDir, 0o777)
|
2022-06-06 21:48:53 +08:00
|
|
|
if err != nil {
|
2022-08-07 13:09:59 +08:00
|
|
|
log.Fatalf("create temp dir error: %+v", err)
|
2022-06-06 21:48:53 +08:00
|
|
|
}
|
2022-08-03 14:26:59 +08:00
|
|
|
log.Debugf("config: %+v", conf.Conf)
|
2023-05-14 17:05:47 +08:00
|
|
|
base.InitClient()
|
2023-02-18 19:03:07 +08:00
|
|
|
initURL()
|
2022-06-06 21:48:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func confFromEnv() {
|
2025-06-16 16:29:45 +08:00
|
|
|
prefix := "OPENLIST_"
|
2022-08-07 13:09:59 +08:00
|
|
|
if flags.NoPrefix {
|
2022-06-06 21:48:53 +08:00
|
|
|
prefix = ""
|
|
|
|
}
|
|
|
|
log.Infof("load config from env with prefix: %s", prefix)
|
2023-07-10 22:06:50 +08:00
|
|
|
if err := env.ParseWithOptions(conf.Conf, env.Options{
|
2022-06-06 21:48:53 +08:00
|
|
|
Prefix: prefix,
|
|
|
|
}); err != nil {
|
2022-08-07 13:09:59 +08:00
|
|
|
log.Fatalf("load config from env error: %+v", err)
|
2022-06-06 21:48:53 +08:00
|
|
|
}
|
|
|
|
}
|
2023-02-18 19:03:07 +08:00
|
|
|
|
|
|
|
func initURL() {
|
|
|
|
if !strings.Contains(conf.Conf.SiteURL, "://") {
|
|
|
|
conf.Conf.SiteURL = utils.FixAndCleanPath(conf.Conf.SiteURL)
|
|
|
|
}
|
|
|
|
u, err := url.Parse(conf.Conf.SiteURL)
|
|
|
|
if err != nil {
|
|
|
|
utils.Log.Fatalf("can't parse site_url: %+v", err)
|
|
|
|
}
|
|
|
|
conf.URL = u
|
|
|
|
}
|
2024-08-07 12:16:21 +08:00
|
|
|
|
|
|
|
func CleanTempDir() {
|
2024-09-08 10:44:34 +08:00
|
|
|
files, err := os.ReadDir(conf.Conf.TempDir)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorln("failed list temp file: ", err)
|
|
|
|
}
|
|
|
|
for _, file := range files {
|
|
|
|
if err := os.RemoveAll(filepath.Join(conf.Conf.TempDir, file.Name())); err != nil {
|
|
|
|
log.Errorln("failed delete temp file: ", err)
|
|
|
|
}
|
2024-08-07 12:16:21 +08:00
|
|
|
}
|
|
|
|
}
|