This commit is contained in:
2026-02-15 07:18:14 +08:00
parent d7cd899983
commit 8a7bf8a39c
39 changed files with 1578 additions and 2868 deletions

View File

@@ -1,12 +1,16 @@
package cmd
import (
"os"
"strings"
initcmd "sunhpc/cmd/init"
"sunhpc/cmd/soft"
"sunhpc/cmd/tmpl"
"sunhpc/internal/auth"
"sunhpc/internal/config"
"sunhpc/internal/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var (
@@ -15,26 +19,85 @@ var (
noColor bool
)
func checkDB() error {
cfg, err := config.LoadConfig()
if err != nil {
log.Fatal("加载配置失败: ", err)
}
// 统一转为小写,避免用户输入错误
dbType := strings.ToLower(cfg.DB.Type)
// 打印配置(调试用)
log.Debugf("数据库类型: %s", dbType)
log.Debugf("数据库名称: %s", cfg.DB.Name)
log.Debugf("数据库路径: %s", cfg.DB.Path)
log.Debugf("数据库用户: %s", cfg.DB.User)
log.Debugf("数据库主机: %s", cfg.DB.Host)
log.Debugf("数据库套接字: %s", cfg.DB.Socket)
log.Debugf("数据库详细日志: %v", cfg.DB.Verbose)
// 支持 sqlitemysql的常见别名
isSQLite := dbType == "sqlite" || dbType == "sqlite3"
isMySQL := dbType == "mysql"
// 检查数据库类型,只允许 sqlite 和 mysql
if !isSQLite && !isMySQL {
log.Fatalf("不支持的数据库类型: %s(仅支持 sqlite、sqlite3、mysql)", dbType)
}
// 检查数据库路径是否存在
if isSQLite {
if _, err := os.Stat(cfg.DB.Path); os.IsNotExist(err) {
log.Warnf("SQLite 数据库路径 %s 不存在", cfg.DB.Path)
log.Fatalf("必须先执行 'sunhpc init database' 初始化数据库")
}
}
return nil
}
var rootCmd = &cobra.Command{
Use: "sunhpc",
Short: "SunHPC - HPC集群一体化运维工具",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
// 初始化日志
// 初始化日志verbose=false 不显示调试信息)
log.Init(verbose)
// 是否禁用颜色
if noColor {
log.EnableColor(false)
log.EnableColor(!noColor)
log.Debugf("当前命令 Annotations: %+v", cmd.Annotations)
// 检查当前命令是否标记为跳过 DB 检查
if cmd.Annotations["skip-db-check"] == "true" {
log.Debugf("当前命令 %s 标记为跳过 DB 检查", cmd.Name())
return
} else {
// 检查数据库
if err := checkDB(); err != nil {
log.Fatalf("数据库检查失败: %v", err)
}
}
log.Debugf("命令: %s", cmd.Name())
// 需要 root 权限
if cmd.Annotations["require-root"] == "true" {
if err := auth.RequireRoot(); err != nil {
log.Fatalf("需要 root 权限: %v", err)
}
}
log.Debugf("当前命令: %s", cmd.Name())
log.Debugf("详细模式: %v", verbose)
log.Debugf("禁用颜色: %v", noColor)
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
// 同步日志
log.Sync()
log.Close()
},
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
},
}
func Execute() error {
@@ -42,32 +105,12 @@ func Execute() error {
}
func init() {
cobra.OnInitialize(initConfig)
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "配置文件路径 (默认为 /etc/sunhpc/sunhpc.yaml)")
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "启用详细日志输出")
rootCmd.PersistentFlags().BoolVar(&noColor, "no-color", false, "禁用彩色输出")
// 注册一级子命令
// 注册一级子命令下的子命令树
rootCmd.AddCommand(initcmd.Cmd)
rootCmd.AddCommand(soft.Cmd)
rootCmd.AddCommand(nodeCmd)
}
func initConfig() {
if cfgFile != "" {
viper.SetConfigFile(cfgFile)
} else {
viper.AddConfigPath("/etc/sunhpc")
viper.SetConfigType("yaml")
viper.SetConfigName("sunhpc")
}
viper.AutomaticEnv()
if err := viper.ReadInConfig(); err == nil {
log.Infof("使用配置文件: %s", viper.ConfigFileUsed())
} else {
log.Debugf("未找到配置文件: %v", err)
}
rootCmd.AddCommand(tmpl.Cmd)
}