feat: 添加版本和构建时间变量 fix: 修正短信队列类型注释错误 style: 清理未使用的代码和测试文件 docs: 更新安装文档中的下载链接 chore: 迁移数据库脚本添加日志和订阅配置
157 lines
4.0 KiB
Go
157 lines
4.0 KiB
Go
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/perfect-panel/server/pkg/constant"
|
|
|
|
"log"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/perfect-panel/server/initialize"
|
|
"github.com/perfect-panel/server/internal"
|
|
"github.com/perfect-panel/server/internal/config"
|
|
"github.com/perfect-panel/server/internal/svc"
|
|
"github.com/perfect-panel/server/pkg/conf"
|
|
"github.com/perfect-panel/server/pkg/logger"
|
|
"github.com/perfect-panel/server/pkg/orm"
|
|
"github.com/perfect-panel/server/pkg/service"
|
|
"github.com/perfect-panel/server/pkg/tool"
|
|
"github.com/perfect-panel/server/queue"
|
|
"github.com/perfect-panel/server/scheduler"
|
|
"github.com/spf13/cobra"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
func init() {
|
|
startCmd.Flags().StringVar(&startConfigPath, "config", "etc/ppanel.yaml", "ppanel.yaml directory to read from")
|
|
}
|
|
|
|
var (
|
|
startConfigPath string
|
|
)
|
|
|
|
var startCmd = &cobra.Command{
|
|
Use: "run",
|
|
Short: "start PPanel",
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
fmt.Println("[PPanel version] v" + fmt.Sprintf("%s(%s)", constant.Version, constant.BuildTime))
|
|
run()
|
|
},
|
|
}
|
|
|
|
func run() {
|
|
services := getServers()
|
|
defer services.Stop()
|
|
go services.Start()
|
|
quit := make(chan os.Signal, 1)
|
|
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
|
|
<-quit
|
|
}
|
|
func getServers() *service.Group {
|
|
var c config.Config
|
|
|
|
// check config file is exist
|
|
if _, err := os.Stat(startConfigPath); os.IsNotExist(err) {
|
|
// check directory is existed
|
|
if _, err := os.Stat("etc"); os.IsNotExist(err) {
|
|
logger.Errorf("Directory %s does not exist. Creating it...\n", "etc")
|
|
if err = os.MkdirAll("etc", os.ModePerm); err != nil {
|
|
log.Fatalf("Please create the directory %s and place the configuration file %s in it.\n", "etc", startConfigPath)
|
|
}
|
|
}
|
|
// create new config file
|
|
if _, err := os.Create(startConfigPath); err != nil {
|
|
logger.Errorf("Please create the configuration file %s in the directory %s.\n", startConfigPath, "etc")
|
|
panic(fmt.Sprintf("Please create the configuration file %s in the directory %s.\n", startConfigPath, "etc"))
|
|
}
|
|
}
|
|
// check config file is empty, if empty, start init web server
|
|
if initConfig(&c) {
|
|
status, server := initialize.Config(startConfigPath)
|
|
<-status
|
|
if err := server.Shutdown(context.TODO()); err != nil {
|
|
log.Printf("Init Server Shutdown: %s\n", err.Error())
|
|
}
|
|
}
|
|
conf.MustLoad(startConfigPath, &c)
|
|
if !c.Debug {
|
|
gin.SetMode(gin.ReleaseMode)
|
|
}
|
|
// init logger
|
|
if err := logger.SetUp(c.Logger); err != nil {
|
|
logger.Errorf("Logger setup failed: %v", err.Error())
|
|
}
|
|
|
|
// init service context
|
|
ctx := svc.NewServiceContext(c)
|
|
services := service.NewServiceGroup()
|
|
services.Add(internal.NewService(ctx))
|
|
services.Add(queue.NewService(ctx))
|
|
services.Add(scheduler.NewService(ctx))
|
|
return services
|
|
}
|
|
|
|
func initConfig(c *config.Config) bool {
|
|
// load config
|
|
conf.MustLoad(startConfigPath, c)
|
|
// check custom config
|
|
if startConfigPath != "etc/ppanel.yaml" && c.MySQL.Addr == "" {
|
|
return true
|
|
}
|
|
// check access secret
|
|
if c.JwtAuth.AccessSecret == "" && startConfigPath == "etc/ppanel.yaml" {
|
|
c.JwtAuth.AccessSecret = uuid.New().String()
|
|
// Get environment variables
|
|
dsn := os.Getenv("PPANEL_DB")
|
|
if dsn == "" {
|
|
return true
|
|
}
|
|
cfg := orm.ParseDSN(dsn)
|
|
if cfg == nil {
|
|
return true
|
|
} else {
|
|
c.MySQL = *cfg
|
|
}
|
|
|
|
// Get environment variables
|
|
uri := os.Getenv("PPANEL_REDIS")
|
|
if uri == "" {
|
|
return true
|
|
}
|
|
addr, pass, db, err := tool.ParseRedisURI(uri)
|
|
if err != nil {
|
|
return true
|
|
} else {
|
|
c.Redis.Host = addr
|
|
c.Redis.Pass = pass
|
|
c.Redis.DB = db
|
|
}
|
|
// save yaml file
|
|
newConfig := config.File{
|
|
Host: c.Host,
|
|
Port: c.Port,
|
|
Debug: c.Debug,
|
|
JwtAuth: c.JwtAuth,
|
|
Logger: c.Logger,
|
|
MySQL: c.MySQL,
|
|
Redis: c.Redis,
|
|
}
|
|
fileData, err := yaml.Marshal(newConfig)
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
// write to file
|
|
if err := os.WriteFile(startConfigPath, fileData, 0644); err != nil {
|
|
panic(err.Error())
|
|
}
|
|
}
|
|
return false
|
|
}
|