package maker import ( "context" "fmt" "os" "os/exec" "path/filepath" "regexp" "gitea.loveuer.com/yizhisec/pkg3/logger" "yizhisec.com/hsv2/forge/internal/opt" "yizhisec.com/hsv2/forge/pkg/archiver" "yizhisec.com/hsv2/forge/pkg/resource" ) type ElasticOpt func(*elasticOpt) type elasticOpt struct { MakeHelper bool MemRate int Storage string } func WithElasticMakeHelper(makeHelper bool) ElasticOpt { return func(o *elasticOpt) { o.MakeHelper = makeHelper } } func WithElasticMemRate(memRate int) ElasticOpt { return func(o *elasticOpt) { if memRate > 0 { o.MemRate = memRate } } } func WithElasticStorageGi(storage string) ElasticOpt { return func(o *elasticOpt) { if matched, _ := regexp.MatchString(`^\d+(\.\d+)?[EPTGMK]i?$`, storage); matched { o.Storage = storage } } } func (m *maker) Elastic(ctx context.Context, opts ...ElasticOpt) error { const ( dockerFile = ` FROM docker-mirror.yizhisec.com/library/alpine:3.22.2 WORKDIR /data RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories && apk add curl ENV TZ=Asia/Shanghai COPY plugins /data/plugins COPY create_index.sh /data/create_index.sh RUN chmod +x /data/create_index.sh ` helperImageName = "hub.yizhisec.com/hybridscope/v2/es-init-helper:alpine-3.22.2" pluginUrl = "https://artifactory.yizhisec.com:443/artifactory/filestore/hsv3/dependency/elasticsearch/v2-es-plugins.tar.gz" ) var ( err error output []byte location = filepath.Join(opt.Cfg.Make.Dir, "dependency", "elastic") helperTarLocation = filepath.Join(opt.Cfg.Make.Dir, "dependency", "image", "es-init-helper.alpine-3.22.2.tar") ) opt := &elasticOpt{ MemRate: 1, Storage: "100Gi", } for _, fn := range opts { fn(opt) } logger.Info("☑️ maker.Elastic: 开始构建 elasticsearch(es) 依赖...") logger.Debug("☑️ maker.Elastic: 开始构建 elasticsearch(es) 依赖..., opt = %#v", opt) logger.Debug("☑️ maker.Elastic: 创建目录 %s", location) if err = os.MkdirAll(location, 0755); err != nil { logger.Debug("❌ maker.Elastic: 创建目录失败: %v", err) return err } logger.Debug("✅ maker.Elastic: 创建目录 %s 成功", location) if opt.MakeHelper { tmp := filepath.Join(os.TempDir(), "make-es") logger.Debug("☑️ maker.Elastic: 构建 helper..., dir = %s", tmp) logger.Debug("☑️ maker.Elastic: 删除并创建临时目录 %s", tmp) if err = os.RemoveAll(tmp); err != nil { logger.Debug("❌ maker.Elastic: 删除临时目录失败: %v", err) return err } if err = os.MkdirAll(tmp, 0755); err != nil { logger.Debug("❌ maker.Elastic: 创建临时目录失败: %v", err) return err } logger.Debug("✅ maker.Elastic: 删除并创建临时目录 %s 成功", tmp) logger.Debug("☑️ maker.Elastic: 写入 Dockerfile ...") if err = os.WriteFile(filepath.Join(tmp, "Dockerfile"), []byte(dockerFile), 0644); err != nil { logger.Debug("❌ maker.Elastic: 写入 Dockerfile 失败: %v", err) return err } logger.Debug("✅ maker.Elastic: 写入 Dockerfile 成功") logger.Debug("☑️ maker.Elastic: 下载 es 插件... url = %s", pluginUrl) if err = archiver.DownloadAndExtract( ctx, pluginUrl, tmp, archiver.WithInsecureSkipVerify(), ); err != nil { logger.Debug("❌ maker.Elastic: 下载 es 插件失败: url = %s, err = %v", pluginUrl, err) return err } logger.Debug("✅ maker.Elastic: 下载 es 插件成功, url = %s", pluginUrl) logger.Debug("☑️ maker.Elastic: 写入 create_index.sh 文件...") if err = os.WriteFile(filepath.Join(tmp, "create_index.sh"), resource.BashESInit, 0644); err != nil { logger.Debug("❌ maker.Elastic: 写入 create_index.sh 文件失败: %v", err) return err } logger.Debug("✅ maker.Elastic: 写入 create_index.sh 文件成功") helpCmd := exec.CommandContext(ctx, "docker", "build", "-t", helperImageName, "-f", filepath.Join(tmp, "Dockerfile"), tmp, ) logger.Debug("☑️ maker.Elastic: 重新构建 helper 镜像..., cmd = %s", helpCmd.String()) if output, err = helpCmd.CombinedOutput(); err != nil { logger.Debug("MakeES: 重新构建 helper 镜像失败, err = %v, output = %s", err, string(output)) return err } logger.Debug("✅ maker.Elastic: 重新构建 helper 镜像成功, cmd = %s", helpCmd.String()) logger.Debug("✅ maker.Elastic: 构建 helper 成功, dir = %s", tmp) } logger.Debug("☑️ maker.Elastic: 准备 es init helper 镜像..., location = %s", helperTarLocation) if err = m.Image( ctx, helperImageName, WithImageSave(helperTarLocation), ); err != nil { logger.Debug("❌ maker.Elastic: 准备 es init helper 镜像失败, location = %s, err = %v", helperTarLocation, err) return err } logger.Debug("✅ maker.Elastic: 准备 es init helper 镜像成功, location = %s", helperTarLocation) bs := []byte(fmt.Sprintf(resource.YAMLES, opt.MemRate, opt.MemRate*2, opt.MemRate, opt.MemRate, opt.MemRate*2, opt.MemRate*2, opt.Storage, )) logger.Debug("☑️ maker.Elastic: 写入 es.yaml 文件...") if err = os.WriteFile(filepath.Join(location, "es.yaml"), bs, 0644); err != nil { logger.Debug("❌ maker.Elastic: 写入 es.yaml 文件失败: %v", err) return err } logger.Debug("✅ maker.Elastic: 写入 es.yaml 文件成功") logger.Debug("☑️ maker.Elastic: 写入 kibana.yaml 文件...") if err = os.WriteFile(filepath.Join(location, "kibana.yaml"), resource.YAMLKibana, 0644); err != nil { logger.Debug("❌ maker.Elastic: 写入 kibana.yaml 文件失败: %v", err) return err } logger.Debug("✅ maker.Elastic: 写入 kibana.yaml 文件成功") logger.Info("✅ maker.Elastic: 构建 elastic(es) 依赖成功!!!") return nil }