Files
forge/internal/controller/maker/elastic.go
2025-12-31 18:58:52 +08:00

207 lines
6.4 KiB
Go

package maker
import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"gitea.loveuer.com/yizhisec/pkg3/logger"
"yizhisec.com/hsv2/forge/internal/opt"
"yizhisec.com/hsv2/forge/pkg/archiver"
"yizhisec.com/hsv2/forge/pkg/model"
"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 opt.StorageSizeReg.MatchString(storage) {
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(m.workdir, "dependency", "elastic")
helperTarLocation = filepath.Join(m.workdir, "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.Debug("☑️ maker.Elastic: 开始获取所需镜像...")
var images = []*model.Image{
{Name: "hub.yizhisec.com/external/elasticsearch:7.17.28", Fallback: "", Save: "elasticsearch.7.17.28.tar"},
{Name: "hub.yizhisec.com/external/kibana:7.17.28", Fallback: "", Save: "kibana.7.17.28.tar"},
}
for _, image := range images {
opts := []ImageOpt{
WithImageFallback(image.Fallback),
WithImageSave(filepath.Join(location, image.Save)),
WithImageForcePull(image.Force),
}
if err := m.Image(ctx, image.Name, opts...); err != nil {
logger.Error("❌ maker.Elastic: 获取镜像失败: %s, 可以手动获取后重试", image.Name)
logger.Debug("❌ maker.Elastic: 获取镜像失败: %s, %v", image.Name, err)
return err
}
}
logger.Debug("✅ maker.Elastic: 获取所需镜像成功!!!")
logger.Info("✅ maker.Elastic: 构建 elastic(es) 依赖成功!!!")
return nil
}