ok-1
This commit is contained in:
41
cmd/init/config.go
Normal file
41
cmd/init/config.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package initcmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"sunhpc/internal/auth"
|
||||
"sunhpc/internal/config"
|
||||
"sunhpc/internal/log"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var configCmd = &cobra.Command{
|
||||
Use: "config",
|
||||
Short: "生成基础配置文件",
|
||||
Long: "创建 /etc/sunhpc 目录并生成所有默认配置文件(若目录已存在则跳过)",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := auth.RequireRoot(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 检查目录是否已存在
|
||||
if _, err := os.Stat(config.BaseDir); err == nil {
|
||||
log.Warnf("配置目录 %s 已存在,跳过初始化", config.BaseDir)
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Info("初始化 SunHPC 配置目录...")
|
||||
if err := config.InitDirs(); err != nil {
|
||||
return fmt.Errorf("创建目录失败: %v", err)
|
||||
}
|
||||
|
||||
if err := config.CreateDefaultConfigs(); err != nil {
|
||||
return fmt.Errorf("生成默认配置文件失败: %v", err)
|
||||
}
|
||||
|
||||
log.Info("配置文件已生成,请根据需要编辑 /etc/sunhpc/ 下的 YAML 文件")
|
||||
return nil
|
||||
},
|
||||
}
|
||||
193
cmd/init/database.go
Normal file
193
cmd/init/database.go
Normal file
@@ -0,0 +1,193 @@
|
||||
package initcmd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"sunhpc/internal/auth"
|
||||
"sunhpc/internal/db"
|
||||
"sunhpc/internal/log"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
appName string = "sunhpc"
|
||||
defaultDBPath string = "/var/lib/sunhpc"
|
||||
defaultDBName string = "sunhpc.db"
|
||||
)
|
||||
|
||||
var (
|
||||
forceDB bool
|
||||
dbPath string
|
||||
dbName string
|
||||
dbFullPath string
|
||||
)
|
||||
|
||||
func initDBPathWithViper() error {
|
||||
/*
|
||||
从 Viper 配置文件获取数据库路径
|
||||
配置文件里的键要和 Viper.GetXXX 的键对应
|
||||
配置文件格式:
|
||||
db:
|
||||
path: "/tmp/sunhpc" # 自定义数据库路径
|
||||
name: "my_sunhpc.db" # 自定义数据库名
|
||||
*/
|
||||
|
||||
log.Infof("从 Viper 配置文件获取数据库路径...")
|
||||
|
||||
// ========== 第一步:设置 Viper 配置文件规则(核心) ==========
|
||||
// 1. 设置Viper基础规则
|
||||
viper.SetConfigType("yaml") // 配置文件类型
|
||||
viper.SetConfigName("config") // 配置文件名(不带后缀)
|
||||
viper.SetEnvPrefix(appName) // 环境变量前缀:SUNHPC_
|
||||
viper.AutomaticEnv() // 自动读取环境变量(可选,增强兼容性)
|
||||
|
||||
// 2. 添加配置文件搜索目录(Viper 会按顺序查找,找到第一个就停止)
|
||||
// 优先级:当前目录 → 用户级目录 → 系统级目录
|
||||
|
||||
// ① 当前目录(开发/测试常用)
|
||||
viper.AddConfigPath(".")
|
||||
|
||||
// ② Linux/macOS 用户级目录(~/.config/sunhpc/)
|
||||
if homeDir, err := os.UserHomeDir(); err == nil {
|
||||
viper.AddConfigPath(filepath.Join(homeDir, ".config", appName))
|
||||
}
|
||||
// ③ Linux/macOS 系统级目录(/etc/sunhpc/)
|
||||
viper.AddConfigPath(filepath.Join("/etc", appName))
|
||||
|
||||
// ========== 第二步:设置默认值(最低优先级) ==========
|
||||
viper.SetDefault("db.path", defaultDBPath)
|
||||
viper.SetDefault("db.name", defaultDBName)
|
||||
|
||||
// ========== 第三步:绑定环境变量(优先级高于默认值,低于配置文件) ==========
|
||||
viper.BindEnv("db.path", "DB_PATH") // 绑定 SUNHPC_DB_PATH → db.path
|
||||
viper.BindEnv("db.name", "DB_NAME") // 绑定 SUNHPC_DB_NAME → db.name
|
||||
|
||||
// ========== 第四步:读取配置文件(优先级高于环境变量,低于默认值) ==========
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
||||
log.Info("未找到配置文件,将使用环境变量/默认值")
|
||||
return nil // 配置文件存在但格式错误,返回错误
|
||||
}
|
||||
log.Warnf("读取配置文件失败: %v", err)
|
||||
return fmt.Errorf("读取配置文件失败: %w", err)
|
||||
}
|
||||
|
||||
log.Infof("成功加载配置文件: %s", viper.ConfigFileUsed())
|
||||
return nil
|
||||
}
|
||||
|
||||
func initDBPath() error {
|
||||
|
||||
// 1. 从 Viper 配置文件获取数据库路径(加载配置文件->环境变量->默认值)
|
||||
if err := initDBPathWithViper(); err != nil {
|
||||
return fmt.Errorf("Viper初始化数据库失败: %v", err)
|
||||
}
|
||||
|
||||
// 2. 从Viper获取数据库路径
|
||||
dbPath = viper.GetString("db.path")
|
||||
dbName = viper.GetString("db.name")
|
||||
|
||||
// 3. 拼接数据库路径
|
||||
dbFullPath = filepath.Join(dbPath, dbName)
|
||||
log.Infof("数据库完整路径: %s", dbFullPath)
|
||||
|
||||
// 3. 检查数据库文件是否存在
|
||||
dir := filepath.Dir(dbFullPath)
|
||||
// 4. 检查数据库目录是否存在
|
||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
||||
log.Infof("数据库目录不存在,创建目录: %s", dir)
|
||||
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
return fmt.Errorf("创建数据库目录失败: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var databaseCmd = &cobra.Command{
|
||||
Use: "database",
|
||||
Short: "初始化数据库",
|
||||
Long: `初始化SQLite数据库,创建所有表结构和默认数据。
|
||||
|
||||
示例:
|
||||
sunhpc init database # 初始化数据库
|
||||
sunhpc init database --force # 强制重新初始化`,
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := auth.RequireRoot(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debug("初始化数据库...")
|
||||
|
||||
if err := initDBPath(); err != nil {
|
||||
return fmt.Errorf("初始化数据库路径失败: %w", err)
|
||||
}
|
||||
|
||||
log.Debugf("数据库目录存在: %s", dbPath)
|
||||
|
||||
// 强制模式:用户确认
|
||||
if forceDB {
|
||||
log.Warn("⚠️ 警告:强制重新初始化将清空数据库中的所有数据!")
|
||||
fmt.Printf("数据库路径: %s\n", dbFullPath)
|
||||
fmt.Print("确认要重新初始化数据库吗?这将删除所有现有数据。(Y/yes): ")
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
input, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return fmt.Errorf("读取用户输入失败: %v", err)
|
||||
}
|
||||
|
||||
input = strings.TrimSpace(strings.ToLower(input))
|
||||
if input != "y" && input != "yes" {
|
||||
log.Info("操作已取消")
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Info("用户确认重新初始化数据库")
|
||||
}
|
||||
|
||||
// 数据库存在且不是强制模式则跳过初始化
|
||||
if _, err := os.Stat(dbFullPath); err == nil && !forceDB {
|
||||
log.Infof("数据库文件已存在: %s", dbFullPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 初始化数据库(使用配置的路径)
|
||||
database, err := db.GetInstanceWithConfig(dbPath, dbName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("初始化数据库失败: %v", err)
|
||||
}
|
||||
defer database.Close()
|
||||
|
||||
// 如果是强制模式,设置强制重新初始化标志
|
||||
if forceDB {
|
||||
database.SetForceInit(true)
|
||||
log.Info("强制重新初始化数据库表...")
|
||||
|
||||
// 关闭现有连接以触发重新连接
|
||||
if err := database.CloseConnection(); err != nil {
|
||||
return fmt.Errorf("关闭现有数据库连接失败: %v", err)
|
||||
}
|
||||
|
||||
// 重新连接并初始化
|
||||
if err := database.Connect(); err != nil {
|
||||
return fmt.Errorf("强制重新初始化数据库失败: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("数据库初始化成功: %s", dbFullPath)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
databaseCmd.Flags().BoolVarP(&forceDB, "force", "f", false, "强制重新初始化,删除现有数据库")
|
||||
Cmd.AddCommand(databaseCmd)
|
||||
}
|
||||
17
cmd/init/init.go
Normal file
17
cmd/init/init.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package initcmd
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var Cmd = &cobra.Command{
|
||||
Use: "init",
|
||||
Short: "初始化集群配置",
|
||||
Long: "初始化 SunHPC 配置文件、数据库、系统参数及相关服务",
|
||||
}
|
||||
|
||||
func init() {
|
||||
Cmd.AddCommand(configCmd)
|
||||
Cmd.AddCommand(systemCmd)
|
||||
Cmd.AddCommand(serviceCmd)
|
||||
}
|
||||
37
cmd/init/service.go
Normal file
37
cmd/init/service.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package initcmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"sunhpc/internal/auth"
|
||||
"sunhpc/internal/config"
|
||||
"sunhpc/internal/log"
|
||||
"sunhpc/internal/service"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var serviceCmd = &cobra.Command{
|
||||
Use: "service",
|
||||
Short: "根据配置文件初始化服务",
|
||||
Long: `读取 /etc/sunhpc/services.yaml 并部署/配置相关服务。
|
||||
支持 HTTPD、TFTPD、DHCPD 等。`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := auth.RequireRoot(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
svcCfg, err := config.LoadServices()
|
||||
if err != nil {
|
||||
return fmt.Errorf("加载 services.yaml 失败: %v", err)
|
||||
}
|
||||
|
||||
log.Info("开始部署服务...")
|
||||
if err := service.Deploy(svcCfg); err != nil {
|
||||
return fmt.Errorf("服务部署失败: %v", err)
|
||||
}
|
||||
|
||||
log.Info("服务初始化完成")
|
||||
return nil
|
||||
},
|
||||
}
|
||||
49
cmd/init/system.go
Normal file
49
cmd/init/system.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package initcmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"sunhpc/internal/auth"
|
||||
"sunhpc/internal/config"
|
||||
"sunhpc/internal/system"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
dryRun bool // --dry-run -n: 仅模拟执行,不实际应用
|
||||
verbose bool // --verbose -v: 启用详细日志输出
|
||||
)
|
||||
|
||||
var systemCmd = &cobra.Command{
|
||||
Use: "system [flags]",
|
||||
Short: "根据配置文件初始化系统",
|
||||
Long: `读取 /etc/sunhpc/sunhpc.yaml 中的系统配置项并应用到当前节点。
|
||||
示例:
|
||||
sunhpc init system # 应用所有配置项
|
||||
sunhpc init system --dry-run # 仅模拟执行,不实际应用
|
||||
sunhpc init system --verbose # 启用详细日志输出
|
||||
`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
// 权限检查:必须以 root 或 sudo 运行
|
||||
if err := auth.RequireRoot(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 加载主配置
|
||||
cfg, err := config.LoadSunHPC()
|
||||
if err != nil {
|
||||
return fmt.Errorf("加载 sunhpc.yaml 失败: %v", err)
|
||||
}
|
||||
|
||||
// 统一应用所有配置
|
||||
return system.ApplyAll(cfg)
|
||||
},
|
||||
}
|
||||
|
||||
// init 初始化 systemCmd 的标志,添加长参数和段参数.
|
||||
func init() {
|
||||
// 注册长参数, 布尔参数
|
||||
systemCmd.Flags().BoolVarP(&dryRun, "dry-run", "n", false, "仅模拟执行,不实际应用")
|
||||
systemCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "启用详细日志输出")
|
||||
}
|
||||
113
cmd/node.go
Normal file
113
cmd/node.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"sunhpc/internal/db"
|
||||
"sunhpc/internal/log"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var nodeCmd = &cobra.Command{
|
||||
Use: "node",
|
||||
Short: "节点管理",
|
||||
Long: "管理集群节点,包括添加、删除、查询等操作",
|
||||
}
|
||||
|
||||
var nodeListCmd = &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "列出所有节点",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
log.Info("查询节点列表...")
|
||||
|
||||
// 获取数据库实例(自动使用之前配置的路径)
|
||||
database, err := db.GetInstance()
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取数据库连接失败: %v", err)
|
||||
}
|
||||
defer database.Close()
|
||||
|
||||
// 执行查询
|
||||
_, err = database.Execute("SELECT id, name, rack, rank, cpus, memory, disk, os, kernel FROM nodes ORDER BY name")
|
||||
if err != nil {
|
||||
return fmt.Errorf("查询节点失败: %v", err)
|
||||
}
|
||||
|
||||
// 获取所有结果
|
||||
rows, err := database.FetchAll()
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取结果失败: %v", err)
|
||||
}
|
||||
|
||||
if len(rows) == 0 {
|
||||
log.Info("暂无节点数据")
|
||||
return nil
|
||||
}
|
||||
|
||||
// 打印结果
|
||||
fmt.Printf("%-5s %-20s %-8s %-8s %-8s %-10s %-10s %-10s\n",
|
||||
"ID", "名称", "机架", "排名", "CPU", "内存", "磁盘", "操作系统")
|
||||
fmt.Println("----------------------------------------------------------------------------------")
|
||||
for _, row := range rows {
|
||||
fmt.Printf("%-5v %-20s %-8v %-8v %-8v %-10v %-10v %-10s\n",
|
||||
row["id"], row["name"], row["rack"], row["rank"],
|
||||
row["cpus"], row["memory"], row["disk"], row["os"])
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var nodeAddCmd = &cobra.Command{
|
||||
Use: "add <name>",
|
||||
Short: "添加节点",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
nodeName := args[0]
|
||||
log.Infof("添加节点: %s", nodeName)
|
||||
|
||||
database, err := db.GetInstance()
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取数据库连接失败: %v", err)
|
||||
}
|
||||
defer database.Close()
|
||||
|
||||
// 插入节点
|
||||
_, err = database.Execute(
|
||||
"INSERT INTO nodes (name, rack, rank, cpus, memory, disk, os, kernel) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
nodeName, rack, rank, cpus, memory, disk, nodeOS, kernel,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("添加节点失败: %v", err)
|
||||
}
|
||||
|
||||
log.Infof("节点 %s 添加成功", nodeName)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var (
|
||||
rack int
|
||||
rank int
|
||||
cpus int
|
||||
memory int
|
||||
disk int
|
||||
nodeOS string
|
||||
kernel string
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 添加子命令
|
||||
nodeCmd.AddCommand(nodeListCmd)
|
||||
nodeCmd.AddCommand(nodeAddCmd)
|
||||
|
||||
// 添加参数
|
||||
nodeAddCmd.Flags().IntVar(&rack, "rack", 0, "机架号")
|
||||
nodeAddCmd.Flags().IntVar(&rank, "rank", 0, "排名")
|
||||
nodeAddCmd.Flags().IntVar(&cpus, "cpus", 0, "CPU核心数")
|
||||
nodeAddCmd.Flags().IntVar(&memory, "memory", 0, "内存大小(GB)")
|
||||
nodeAddCmd.Flags().IntVar(&disk, "disk", 0, "磁盘大小(GB)")
|
||||
nodeAddCmd.Flags().StringVar(&nodeOS, "os", "", "操作系统")
|
||||
nodeAddCmd.Flags().StringVar(&kernel, "kernel", "", "内核版本")
|
||||
}
|
||||
73
cmd/root.go
Normal file
73
cmd/root.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
initcmd "sunhpc/cmd/init"
|
||||
"sunhpc/cmd/soft"
|
||||
"sunhpc/internal/log"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var (
|
||||
cfgFile string
|
||||
verbose bool
|
||||
noColor bool
|
||||
)
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "sunhpc",
|
||||
Short: "SunHPC - HPC集群一体化运维工具",
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
// 初始化日志
|
||||
log.Init(verbose)
|
||||
|
||||
// 是否禁用颜色
|
||||
if noColor {
|
||||
log.EnableColor(false)
|
||||
}
|
||||
|
||||
log.Debugf("命令: %s", cmd.Name())
|
||||
log.Debugf("详细模式: %v", verbose)
|
||||
},
|
||||
PersistentPostRun: func(cmd *cobra.Command, args []string) {
|
||||
// 同步日志
|
||||
log.Sync()
|
||||
log.Close()
|
||||
},
|
||||
}
|
||||
|
||||
func Execute() error {
|
||||
return rootCmd.Execute()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
109
cmd/soft/install.go
Normal file
109
cmd/soft/install.go
Normal file
@@ -0,0 +1,109 @@
|
||||
// cmd/soft/install.go
|
||||
package soft
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sunhpc/internal/auth"
|
||||
"sunhpc/internal/log"
|
||||
"sunhpc/internal/soft"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
installType string // --type, -t
|
||||
srcPath string // --src-path, -s
|
||||
binPath string // --bin-path, -b
|
||||
prefix string // --prefix, -p
|
||||
version string // --version, -v
|
||||
forceInstall bool // --force, -f
|
||||
dryRun bool // --dry-run, -n
|
||||
keepSource bool // --keep-source, -k
|
||||
jobs int // --jobs, -j
|
||||
offlineMode bool // --offline, -o
|
||||
)
|
||||
|
||||
var installCmd = &cobra.Command{
|
||||
Use: "install <software>",
|
||||
Short: "安装软件",
|
||||
Long: `安装指定的软件包,支持多种安装方式。
|
||||
|
||||
安装类型:
|
||||
source - 从源码编译安装
|
||||
binary - 从二进制压缩包安装
|
||||
rpm - 通过 RPM 包管理器安装
|
||||
deb - 通过 APT 包管理器安装
|
||||
|
||||
示例:
|
||||
sunhpc soft install vasp --type source --src-path /tmp/vasp.tar.gz
|
||||
sunhpc soft install openmpi --type binary --bin-path openmpi.tar.gz -p /opt/openmpi
|
||||
sunhpc soft install htop --type rpm --force
|
||||
sunhpc soft install nginx --type deb --dry-run`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := auth.RequireRoot(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
software := args[0]
|
||||
|
||||
if dryRun {
|
||||
log.Infof("[干运行] 将要安装 %s", software)
|
||||
log.Infof(" 安装类型: %s", installType)
|
||||
if srcPath != "" {
|
||||
log.Infof(" 源码路径: %s", srcPath)
|
||||
}
|
||||
if binPath != "" {
|
||||
log.Infof(" 二进制包: %s", binPath)
|
||||
}
|
||||
if prefix != "" {
|
||||
log.Infof(" 安装路径: %s", prefix)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
ctx := &soft.InstallContext{
|
||||
Force: forceInstall,
|
||||
DryRun: dryRun,
|
||||
KeepSource: keepSource,
|
||||
Jobs: jobs,
|
||||
Offline: offlineMode,
|
||||
}
|
||||
|
||||
switch installType {
|
||||
case "source":
|
||||
return soft.InstallFromSource(software, srcPath, prefix, version, ctx)
|
||||
case "binary":
|
||||
return soft.InstallFromBinary(software, binPath, prefix, ctx)
|
||||
case "rpm", "deb":
|
||||
return soft.InstallFromPackage(software, installType, ctx)
|
||||
default:
|
||||
return fmt.Errorf("不支持的安装类型: %s", installType)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
// 必选参数
|
||||
installCmd.Flags().StringVarP(&installType, "type", "t", "", "安装类型: source/binary/rpm/deb")
|
||||
installCmd.MarkFlagRequired("type")
|
||||
|
||||
// 路径参数
|
||||
installCmd.Flags().StringVarP(&srcPath, "src-path", "s", "", "源码路径或URL")
|
||||
installCmd.Flags().StringVarP(&binPath, "bin-path", "b", "", "二进制压缩包路径")
|
||||
installCmd.Flags().StringVarP(&prefix, "prefix", "p", "/opt/sunhpc/software", "安装路径")
|
||||
|
||||
// 版本参数
|
||||
installCmd.Flags().StringVarP(&version, "version", "v", "", "软件版本号")
|
||||
|
||||
// 行为控制
|
||||
installCmd.Flags().BoolVarP(&forceInstall, "force", "f", false, "强制安装,覆盖已有版本")
|
||||
installCmd.Flags().BoolVarP(&dryRun, "dry-run", "n", false, "仅显示将要执行的操作")
|
||||
installCmd.Flags().BoolVarP(&keepSource, "keep-source", "k", false, "保留源码文件")
|
||||
installCmd.Flags().IntVarP(&jobs, "jobs", "j", 4, "编译线程数")
|
||||
installCmd.Flags().BoolVarP(&offlineMode, "offline", "o", false, "离线模式,不联网下载")
|
||||
|
||||
// 参数互斥
|
||||
installCmd.MarkFlagsMutuallyExclusive("src-path", "bin-path")
|
||||
installCmd.MarkFlagsOneRequired("src-path", "bin-path")
|
||||
}
|
||||
16
cmd/soft/soft.go
Normal file
16
cmd/soft/soft.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package soft
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var Cmd = &cobra.Command{
|
||||
Use: "soft",
|
||||
Short: "软件包管理",
|
||||
Long: "安装、卸载、编译软件,支持源码、RPM、DEB、二进制压缩包",
|
||||
}
|
||||
|
||||
func init() {
|
||||
Cmd.AddCommand(installCmd)
|
||||
// 后续可添加 remove、list 等子命令
|
||||
}
|
||||
Reference in New Issue
Block a user