package maker import ( "context" "fmt" "os" "path/filepath" "gitea.loveuer.com/yizhisec/pkg3/logger" "yizhisec.com/hsv2/forge/internal/opt" "yizhisec.com/hsv2/forge/pkg/model" "yizhisec.com/hsv2/forge/pkg/resource" ) type SeafileOpt func(*seafileOpt) type seafileOpt struct { DBHost string DBPassword string AdminEmail string AdminPassword string ServerHostname string Storage string } func WithSeafileStorage(storage string) SeafileOpt { return func(o *seafileOpt) { if opt.StorageSizeReg.MatchString(storage) { o.Storage = storage } } } func WithSeafileDBHost(host string) SeafileOpt { return func(o *seafileOpt) { if o.DBHost == "" { o.DBHost = host } } } func WithSeafileDBPassword(password string) SeafileOpt { return func(o *seafileOpt) { if o.DBPassword == "" { o.DBPassword = password } } } func WithSeafileAdminEmail(email string) SeafileOpt { return func(o *seafileOpt) { if opt.EmailReg.MatchString(email) { o.AdminEmail = email } } } func WithSeafileAdminPassword(password string) SeafileOpt { return func(o *seafileOpt) { if o.AdminPassword == "" { o.AdminPassword = password } } } func WithSeafileHostname(hostname string) SeafileOpt { return func(o *seafileOpt) { if o.ServerHostname == "" { o.ServerHostname = hostname } } } func (m *maker) Seafile(ctx context.Context, opts ...SeafileOpt) error { const ( _config = ` ControllerServer: UserManagement: user-service.hsv2:9013 Database: Mysql: Address: %s:3306 DBName: backup_server Password: %s SeafileDBName: seafile_db UserName: root Log: Dir: ./log Level: 1 Name: hs_backup_seafile SeafileServer: Admin: %s AdminPassword: %s BackupDir: /seafile/backup_data Host: seafile-service Port: 80 StorageDir: /seafile/storage Sentry: DSN: https://fd7149f063c211eda2b50242ac15001c@sentry.yizhisec.com:13443/7 TracesSampleRate: 1 Web: Host: 0.0.0.0 Mode: release Port: 9027 WorkDir: /yizhisec/hs_backup_seafile/workspace YosGuard: Host: 172.17.0.1 Port: 7788` _upsert = `#!/bin/bash kubectl create configmap config-backup-seafile --namespace seafile --from-file=config.yml=./config.yml --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap nginx-seafile --namespace hsv2 --from-file=seafile.conf=./nginx.conf --dry-run=client -o yaml | kubectl apply -f - kubectl apply -f deployment.yaml kubectl rollout restart deployment backup-seafile-deployment -n seafile` ) var ( err error o = &seafileOpt{ DBHost: "mysql-cluster-mysql-master.db-mysql", DBPassword: "L0hMysql.", AdminEmail: "admin@yizhisec.com", AdminPassword: "asecret", ServerHostname: "cloud.hybridscope.com", Storage: "50Gi", } workdir = filepath.Join(m.workdir, "dependency", "seafile") ) for _, fn := range opts { fn(o) } logger.Info("☑️ maker.Seafile: 开始构建 seafile 依赖, dir = %s", workdir) // 1. 准备工作目录 logger.Debug("☑️ make.Seafile: 准备工作目录: %s", workdir) if err = os.MkdirAll(workdir, 0755); err != nil { logger.Error("❌ make.Seafile: 准备工作目录: %s 失败, err = %v", workdir, err) return err } logger.Debug("✅ make.Seafile: 准备工作目录: %s 成功", workdir) // 2. seafile yaml logger.Debug("☑️ make.Seafile: 准备 seafile yaml") bs := []byte(fmt.Sprintf(resource.YAMLSeafile, o.DBHost, o.DBPassword, o.AdminEmail, o.AdminPassword, o.ServerHostname, o.Storage)) if err = os.WriteFile(filepath.Join(workdir, "seafile.yaml"), bs, 0644); err != nil { logger.Error("❌ make.Seafile: 准备 seafile yaml: %s 失败, err = %v", filepath.Join(workdir, "seafile.yaml"), err) return err } logger.Debug("✅ make.Seafile: 准备 seafile yaml 成功") // 3. backup-seafile deployment logger.Debug("☑️ make.Seafile: 准备 backup-seafile deployment") bs = []byte(resource.YAMLBackupSeafile) if err = os.WriteFile(filepath.Join(workdir, "deployment.yaml"), bs, 0644); err != nil { logger.Error("❌ make.Seafile: 准备 backup-seafile deployment: %s 失败, err = %v", filepath.Join(workdir, "deployment.yaml"), err) return err } logger.Debug("✅ make.Seafile: 准备 backup-seafile deployment 成功") // 4. config.yml logger.Debug("☑️ make.Seafile: 准备 config.yml") bs = []byte(fmt.Sprintf(_config, o.DBHost, o.DBPassword, o.AdminEmail, o.AdminPassword)) if err = os.WriteFile(filepath.Join(workdir, "config.yml"), bs, 0644); err != nil { logger.Error("❌ make.Seafile: 准备 config.yml: %s 失败, err = %v", filepath.Join(workdir, "config.yml"), err) return err } logger.Debug("✅ make.Seafile: 准备 config.yml 成功") // 5. seafile.conf logger.Debug("☑️ make.Seafile: 准备 seafile.conf") bs = resource.NGINXSeafile if err = os.WriteFile(filepath.Join(workdir, "seafile.conf"), bs, 0644); err != nil { logger.Error("❌ make.Seafile: 准备 seafile.conf: %s 失败, err = %v", filepath.Join(workdir, "seafile.conf"), err) return err } logger.Debug("✅ make.Seafile: 准备 seafile.conf 成功") // 6. upsert.sh logger.Debug("☑️ make.Seafile: 准备 upsert.sh") bs = []byte(_upsert) if err = os.WriteFile(filepath.Join(workdir, "upsert.sh"), bs, 0755); err != nil { logger.Error("❌ make.Seafile: 准备 upsert.sh: %s 失败, err = %v", filepath.Join(workdir, "upsert.sh"), err) return err } logger.Debug("✅ make.Seafile: 准备 upsert.sh 成功") // 7. prepare images logger.Debug("☑️ make.Seafile: 准备 images") imgDir := filepath.Join(m.workdir, "dependency", "image") if err = os.MkdirAll(imgDir, 0755); err != nil { logger.Error("❌ make.Seafile: 准备 images 目录: %s 失败, err = %v", imgDir, err) return err } var images = []*model.Image{ {Name: "hub.yizhisec.com/hybridscope/hs_backup_seafile:latest", Fallback: "", Save: "seafile.backup_seafile.tar", Force: true}, {Name: "hub.yizhisec.com/product/hybridscope/memcached:latest", Fallback: "", Save: "seafile.memcached.tar"}, {Name: "hub.yizhisec.com/product/hybridscope/seafile-mc:latest", Fallback: "", Save: "seafile.seafile_mc.tar"}, } for _, img := range images { img.Save = filepath.Join(imgDir, img.Save) if err = m.Image(ctx, img.Name, WithImageSave(img.Save), WithImageForcePull(img.Force)); err != nil { logger.Error("❌ make.Seafile: 准备 image: %s 失败, err = %v", img.Name, err) return err } } logger.Debug("✅ make.Seafile: 准备 images 成功") logger.Info("✅ maker.Seafile: 构建 seafile 依赖成功!!!") return nil }