package cmd import ( "fmt" "os" "path/filepath" "gitea.loveuer.com/yizhisec/pkg3/logger" "github.com/spf13/cobra" "yizhisec.com/hsv2/forge/internal/opt" "yizhisec.com/hsv2/forge/pkg/downloader" ) func makeMysql() *cobra.Command { const ( _yaml = ` apiVersion: v1 kind: Secret metadata: name: mysql-secret namespace: db-mysql type: Opaque data: ROOT_PASSWORD: TDBoTXlzcWwu --- apiVersion: mysql.presslabs.org/v1alpha1 kind: MysqlCluster metadata: name: mysql-cluster namespace: db-mysql spec: mysqlVersion: "8.0" replicas: %d image: docker.io/library/percona:8.0.28-20 secretName: mysql-secret volumeSpec: persistentVolumeClaim: accessModes: ["ReadWriteOnce"] storageClassName: longhorn resources: requests: storage: %dGi # podSpec: # affinity: # podAntiAffinity: # requiredDuringSchedulingIgnoredDuringExecution: # 强制规则 # - labelSelector: # matchExpressions: # - key: app.kubernetes.io/name # operator: In # values: ["mysql"] # - key: app.kubernetes.io/instance # operator: In # values: ["mysql-cluster"] # topologyKey: "kubernetes.io/hostname" # 确保不同节点 # resources: # requests: # cpu: "2" # memory: "2Gi" # limits: # cpu: "8" # memory: "8Gi" --- apiVersion: mysql.presslabs.org/v1alpha1 kind: MysqlDatabase metadata: name: my-database-mie namespace: db-mysql spec: database: mie clusterRef: name: mysql-cluster namespace: db-mysql ` ) var ( replicas int storage int ) _cmd := &cobra.Command{ Use: "mysql", Short: "Build MySQL resources", Long: `Build and prepare MySQL database resources.`, PreRunE: func(cmd *cobra.Command, args []string) error { return os.MkdirAll(filepath.Join(opt.Cfg.Make.Dir, "dependency", "mysql"), 0755) }, RunE: func(cmd *cobra.Command, args []string) error { var ( err error chartURL = "https://artifactory.yizhisec.com:443/artifactory/filestore/hsv3/charts/mysql-operator-0.6.3.tgz" mysqlDir = filepath.Join(opt.Cfg.Make.Dir, "dependency", "mysql") chartFile = filepath.Join(mysqlDir, "mysql-operator-0.6.3.tgz") clusterFile = filepath.Join(mysqlDir, "cluster.yaml") ) logger.Info("开始构建 MySQL 资源...") logger.Debug("下载地址: %s", chartURL) logger.Debug("目标目录: %s", mysqlDir) // Download MySQL operator chart logger.Info("正在下载 MySQL operator chart...") if err := downloader.Download( cmd.Context(), chartURL, chartFile, downloader.WithInsecureSkipVerify(), ); err != nil { logger.Info("❌ 下载 MySQL operator chart 失败") return err } logger.Info("✅ 成功下载 MySQL operator chart") bs := []byte(fmt.Sprintf(_yaml, replicas, storage)) // Generate secret.yaml if err = os.WriteFile(clusterFile, bs, 0644); err != nil { logger.Debug("创建 database.yaml 失败: %v", err) logger.Info("❌ 创建 database.yaml 失败") return err } logger.Info("✅ 成功创建 database.yaml") logger.Info("✅ MySQL 资源构建成功") logger.Debug("MySQL 资源准备完成") return nil }, } _cmd.Flags().IntVar(&replicas, "replica-count", 2, "mysql 的副本数") _cmd.Flags().IntVar(&storage, "storage-size", 50, "mysql 的存储空间") return _cmd }