diff --git a/changelog.md b/CHANGELOG.md similarity index 97% rename from changelog.md rename to CHANGELOG.md index 7b6063f..a7fdc6e 100644 --- a/changelog.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +#### 2.1.1 + +Buggy Oven + +* Use arguments for the LOG field +* Update dependencies + #### 2.1.0 Degraded Mastiff diff --git a/README.md b/README.md index 6422d72..af6e4d5 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,11 @@ shell script manager and runner inspired by rerun[1], bashing[2] and drist[3] [2] https://github.com/xsc/bashing [3] git://bitreich.org/drist -Your shell script multi-tool. Automate all the things. Can be used for: +Your shell script multi-tool. For: 1. Runbooks 1. Deployment 1. Builds 1. Configuration management +1. C2 +1. Hooks diff --git a/const.go b/const.go index 5810e23..7ab9049 100644 --- a/const.go +++ b/const.go @@ -1,7 +1,7 @@ package main -const cVERSION = "2.1.0" -const cCODE = "Degraded Mastiff" +const cVERSION = "2.1.1" +const cCODE = "Buggy Oven" const cOP = "LOG" const cINC = "VARS" diff --git a/go.mod b/go.mod index a5ed9a1..ab18476 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ toolchain go1.22rc1 require ( github.com/mattn/go-isatty v0.0.20 github.com/tongson/gl v0.0.0-20240508154845-d8f4b3b2979b - golang.org/x/term v0.20.0 + golang.org/x/term v0.21.0 ) -require golang.org/x/sys v0.20.0 // indirect +require golang.org/x/sys v0.21.0 // indirect diff --git a/go.sum b/go.sum index 778929d..377a5a2 100644 --- a/go.sum +++ b/go.sum @@ -3,7 +3,7 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/tongson/gl v0.0.0-20240508154845-d8f4b3b2979b h1:vtkczRK2RtzEryIDuCIAPpbarsyZZTQVzmO9+X/2wGg= github.com/tongson/gl v0.0.0-20240508154845-d8f4b3b2979b/go.mod h1:fU6I0Ftr9DkKCYHb2TQmMmEGowPXcOqHUrikGo8CUrM= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= diff --git a/main.go b/main.go index fe3728d..ec979f2 100644 --- a/main.go +++ b/main.go @@ -641,6 +641,7 @@ rrl = report` var nsScript string var code string var interp string + var opLog string jsonFile, _ := os.OpenFile(cLOG, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600) defer jsonFile.Close() jsonLog := slog.New(slog.NewJSONHandler(jsonFile, &slog.HandlerOptions{Level: slog.LevelDebug})) @@ -701,6 +702,16 @@ rrl = report` } else { arguments = os.Args[offset+1:] } + // Set LOG field + if eop, ok := os.LookupEnv(cOP); !ok { + if len(arguments) == 0 { + opLog = "UNDEFINED" + } else { + opLog = strings.Join(arguments, " ") + } + } else { + opLog = eop + } fnWalkDir := lib.PathWalker(&sh) if lib.IsDir(".lib") { if err := filepath.WalkDir(".lib", fnWalkDir); err != nil { @@ -775,13 +786,7 @@ rrl = report` } else { opt.interp = interp } - var op string - if eop, ok := os.LookupEnv(cOP); !ok { - op = "UNDEFINED" - } else { - op = eop - } - jsonLog.Info(op, "app", "rr", "id", id, "namespace", namespace, "script", script, "target", hostname) + jsonLog.Info(opLog, "app", "rr", "id", id, "namespace", namespace, "script", script, "target", hostname) log.Printf("Running %s:%s via %s…", namespace, script, hostname) if hostname == "local" || hostname == "localhost" { if opt.sudo { @@ -831,11 +836,11 @@ rrl = report` } } } - if op == "UNDEFINED" { + if opLog == "UNDEFINED" { log.Printf("Running %s…", script) jsonLog.Debug("running", "app", "rr", "id", id, "script", script) } else { - msgop := strings.TrimSuffix(op, "\n") + msgop := strings.TrimSuffix(opLog, "\n") log.Printf("%s…", msgop) jsonLog.Debug(msgop, "app", "rr", "id", id, "script", script) } @@ -849,12 +854,12 @@ rrl = report` b64sc := base64.StdEncoding.EncodeToString([]byte(code)) if !ret { failed = true - jsonLog.Error(op, "app", "rr", "id", id, "code", b64sc, "stdout", b64so, "stderr", b64se, "error", out.Error) + jsonLog.Error(opLog, "app", "rr", "id", id, "code", b64sc, "stdout", b64so, "stderr", b64se, "error", out.Error) switch opt.mode { case oPlain: stdWriter(out.Stdout, out.Stderr) case oJson: - serrLog.Error(op, "stdout", out.Stdout, "stderr", out.Stderr, "error", out.Error) + serrLog.Error(opLog, "stdout", out.Stdout, "stderr", out.Stderr, "error", out.Error) case oTerm: log.Printf("Failure running script!\n%s%s%s%s%s%s", he, be, fe, hd, bd, fd) } @@ -866,8 +871,8 @@ rrl = report` result = "repaired" } } - jsonLog.Debug(op, "app", "rr", "id", id, "code", b64sc, "stdout", b64so, "stderr", b64se, "error", out.Error) - jsonLog.Info(op, "app", "rr", "id", id, "result", result) + jsonLog.Debug(opLog, "app", "rr", "id", id, "code", b64sc, "stdout", b64so, "stderr", b64se, "error", out.Error) + jsonLog.Info(opLog, "app", "rr", "id", id, "result", result) switch opt.mode { case oPlain: stdWriter(out.Stdout, out.Stderr) @@ -877,7 +882,7 @@ rrl = report` } case oJson: if out.Stdout != "" || out.Stderr != "" || out.Error != "" { - serrLog.Info(op, "stdout", out.Stdout, "stderr", out.Stderr, "error", out.Error) + serrLog.Info(opLog, "stdout", out.Stdout, "stderr", out.Stderr, "error", out.Error) } } } @@ -940,12 +945,12 @@ rrl = report` b64sc := base64.StdEncoding.EncodeToString([]byte(code)) if !ret { failed = true - jsonLog.Error(op, "app", "rr", "id", id, "code", b64sc, "stdout", b64so, "stderr", b64se, "error", out.Error) + jsonLog.Error(opLog, "app", "rr", "id", id, "code", b64sc, "stdout", b64so, "stderr", b64se, "error", out.Error) switch opt.mode { case oPlain: stdWriter(out.Stdout, out.Stderr) case oJson: - serrLog.Error(op, "stdout", out.Stdout, "stderr", out.Stderr, "error", out.Error) + serrLog.Error(opLog, "stdout", out.Stdout, "stderr", out.Stderr, "error", out.Error) case oTerm: log.Printf("Failure running script!\n%s%s%s%s%s%s", he, be, fe, hd, bd, fd) } @@ -957,8 +962,8 @@ rrl = report` result = "repaired" } } - jsonLog.Debug(op, "app", "rr", "id", id, "code", b64sc, "stdout", b64so, "stderr", b64se, "error", out.Error) - jsonLog.Info(op, "app", "rr", "id", id, "result", result) + jsonLog.Debug(opLog, "app", "rr", "id", id, "code", b64sc, "stdout", b64so, "stderr", b64se, "error", out.Error) + jsonLog.Info(opLog, "app", "rr", "id", id, "result", result) switch opt.mode { case oPlain: stdWriter(out.Stdout, out.Stderr) @@ -968,7 +973,7 @@ rrl = report` } case oJson: if out.Stdout != "" || out.Stderr != "" || out.Error != "" { - serrLog.Info(op, "stdout", out.Stdout, "stderr", out.Stderr, "error", out.Error) + serrLog.Info(opLog, "stdout", out.Stdout, "stderr", out.Stderr, "error", out.Error) } } } @@ -1054,14 +1059,14 @@ rrl = report` b64sc := base64.StdEncoding.EncodeToString([]byte(code)) if !ret { failed = true - jsonLog.Debug(op, "app", "rr", "id", id, "code", b64sc, "stdout", b64so, "stderr", b64se, "error", out.Error) + jsonLog.Debug(opLog, "app", "rr", "id", id, "code", b64sc, "stdout", b64so, "stderr", b64se, "error", out.Error) switch opt.mode { case oPlain: stdWriter(out.Stdout, out.Stderr) case oTerm: log.Printf("Failure running script!\n%s%s%s%s%s%s", he, be, fe, hd, bd, fd) case oJson: - serrLog.Error(op, "stdout", out.Stdout, "stderr", out.Stderr, "error", out.Error) + serrLog.Error(opLog, "stdout", out.Stdout, "stderr", out.Stderr, "error", out.Error) } } else { scanner := bufio.NewScanner(strings.NewReader(out.Stderr)) @@ -1071,8 +1076,8 @@ rrl = report` result = "repaired" } } - jsonLog.Debug(op, "app", "rr", "id", id, "code", b64sc, "stdout", b64so, "stderr", b64se, "error", out.Error) - jsonLog.Info(op, "app", "rr", "id", id, "result", result) + jsonLog.Debug(opLog, "app", "rr", "id", id, "code", b64sc, "stdout", b64so, "stderr", b64se, "error", out.Error) + jsonLog.Info(opLog, "app", "rr", "id", id, "result", result) switch opt.mode { case oPlain: stdWriter(out.Stdout, out.Stderr) @@ -1082,7 +1087,7 @@ rrl = report` } case oJson: if out.Stdout != "" || out.Stderr != "" || out.Error != "" { - serrLog.Info(op, "stdout", out.Stdout, "stderr", out.Stderr, "error", out.Error) + serrLog.Info(opLog, "stdout", out.Stdout, "stderr", out.Stderr, "error", out.Error) } } } @@ -1093,14 +1098,14 @@ rrl = report` tm = "<1s" } if !failed { - jsonLog.Debug(result, "app", "rr", "id", id, "start", start.Format(cTIME), "task", op, "target", hostname, "namespace", namespace, "script", script, "duration", tm) + jsonLog.Debug(result, "app", "rr", "id", id, "start", start.Format(cTIME), "task", opLog, "target", hostname, "namespace", namespace, "script", script, "duration", tm) if opt.mode == oTerm { log.Printf("Total run time: %s. All OK.", tm) } _ = jsonFile.Close() os.Exit(0) } else { - jsonLog.Debug("failed", "app", "rr", "id", id, "start", start.Format(cTIME), "task", op, "target", hostname, "namespace", namespace, "script", script, "duration", tm) + jsonLog.Debug("failed", "app", "rr", "id", id, "start", start.Format(cTIME), "task", opLog, "target", hostname, "namespace", namespace, "script", script, "duration", tm) switch opt.mode { case oPlain: // Nothing to do diff --git a/rrl.go b/rrl.go index aa25b05..8fb5b4e 100644 --- a/rrl.go +++ b/rrl.go @@ -56,7 +56,7 @@ func rrlMain() { w.Init(os.Stdout, 0, 8, 1, ' ', 0) rrl, err := os.Open(cLOG) if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "Missing `%s` in the current directory.\n", cLOG) + _, _ = fmt.Fprintf(os.Stderr, "Missing `%s` file in the current directory.\n", cLOG) os.Exit(1) } defer rrl.Close() diff --git a/test/rr_test.go b/test/rr_test.go index 6c4010b..79623c6 100644 --- a/test/rr_test.go +++ b/test/rr_test.go @@ -75,6 +75,15 @@ func TestOp(T *testing.T) { t.Error("wants `true`") } }) + T.Run("argument", func(t *testing.T) { + rr := RunArg{Exe: cEXE, Args: []string{"op:env", "__argument__"}} + if ret, _ := rr.Run(); !ret { + t.Error("wants `true`") + } + if got := strings.Contains(FileRead("LOG"), "__argument__"); !got { + t.Error("wants `true`") + } + }) } func TestRepaired(T *testing.T) {