From 12a0f9d2b1c63950b206a83b942e34a3b5d9d010 Mon Sep 17 00:00:00 2001 From: mountain Date: Mon, 5 Aug 2024 10:20:41 +0900 Subject: [PATCH] =?UTF-8?q?argument=20=EC=88=98=EC=8B=9D=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/operation.go | 73 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/client/operation.go b/client/operation.go index be31ea0..e71c757 100644 --- a/client/operation.go +++ b/client/operation.go @@ -14,11 +14,14 @@ import ( "os/exec" "path" "path/filepath" + "regexp" "sort" + "strconv" "strings" "syscall" "time" + "github.com/Knetic/govaluate" "repositories.action2quare.com/ayo/gocommon/logger" "repositories.action2quare.com/ayo/gocommon/metric" "repositories.action2quare.com/ayo/houston/shared" @@ -237,6 +240,68 @@ func makeLogFilePrefix(meta *procmeta, index int) string { return path.Join(meta.verpath, "logs", fmt.Sprintf("%s_%d_%s", nameonly, index, ts)) } +func evaluateExpression(expression string, params map[string]any) (any, error) { + expression = strings.TrimSpace(expression) + expr, err := govaluate.NewEvaluableExpression(expression) + if err != nil { + return 0, err + } + + return expr.Evaluate(params) +} + +func evaluateArgs(args []string, params map[string]any) ([]string, error) { + re := regexp.MustCompile(`\$\(\((.*?)\)\)`) + + for i, input := range args { + matches := re.FindAllStringSubmatch(input, -1) + if len(matches) == 0 { + continue + } + + for _, match := range matches { + if len(match) > 1 { + expression := strings.TrimSpace(match[1]) + expr, err := govaluate.NewEvaluableExpression(expression) + if err != nil { + return nil, err + } + + result, err := expr.Evaluate(params) + if err != nil { + return nil, err + } + + // 원래 표현식을 결과로 대체 + input = strings.Replace(input, match[0], fmt.Sprintf("%v", result), -1) + } + } + + args[i] = input + } + + return args, nil +} + +func parseEnv(input []string) map[string]any { + output := make(map[string]any, len(input)) + for _, envkv := range input { + kv := strings.SplitN(envkv, "=", 2) + parsed, err := strconv.ParseInt(kv[1], 10, 0) + if err == nil { + output[kv[0]] = parsed + } else { + parsed, err := strconv.ParseFloat(kv[1], 32) + if err == nil { + output[kv[0]] = parsed + } else { + output[kv[0]] = kv[1] + } + } + } + return output +} + func (hc *houstonClient) launch(meta *procmeta) error { stdout, err := meta.cmd.StdoutPipe() if err != nil { @@ -423,8 +488,14 @@ func (hc *houstonClient) launch(meta *procmeta) error { go stdReader(meta.name, stdout, index) - logger.Println("startChildProcess :", meta.cmd.Args) meta.cmd.Env = append(os.Environ(), fmt.Sprintf("HOUSTON_SIBLIING_INDEX=%d", index)) + meta.cmd.Args, err = evaluateArgs(meta.cmd.Args, parseEnv(meta.cmd.Env)) + if err != nil { + logger.Println("evaluateArgs failed :", err) + return err + } + logger.Println("startChildProcess :", meta.cmd.Args) + err = meta.cmd.Start() if err == nil { logger.Println("process index, pid =", index, meta.cmd.Process.Pid)