update: enhance command execution with real-time logging and add shorthand flag for deployment file
This commit is contained in:
parent
4b8a27a2d7
commit
5f448d7fc7
3 changed files with 90 additions and 8 deletions
46
app/k8s.go
46
app/k8s.go
|
|
@ -1,6 +1,7 @@
|
||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
@ -67,19 +68,52 @@ func k8sCreateNamespace(project string) error {
|
||||||
func RunCommand(command string) error {
|
func RunCommand(command string) error {
|
||||||
slog.Debug(fmt.Sprintf("🐞 Running command: %s", command))
|
slog.Debug(fmt.Sprintf("🐞 Running command: %s", command))
|
||||||
cmd := exec.Command("sh", "-c", command)
|
cmd := exec.Command("sh", "-c", command)
|
||||||
|
|
||||||
var stdout, stderr bytes.Buffer
|
var stdout, stderr bytes.Buffer
|
||||||
cmd.Stdout = &stdout
|
|
||||||
cmd.Stderr = &stderr
|
// Get pipes for real-time reading
|
||||||
err := cmd.Run()
|
stdoutPipe, err := cmd.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create stdout pipe: %w", err)
|
||||||
|
}
|
||||||
|
stderrPipe, err := cmd.StderrPipe()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create stderr pipe: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the command
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
return fmt.Errorf("failed to start command: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read stdout line by line and log through slog
|
||||||
|
go func() {
|
||||||
|
scanner := bufio.NewScanner(stdoutPipe)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
stdout.WriteString(line + "\n")
|
||||||
|
slog.Info(line)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Read stderr line by line and log through slog
|
||||||
|
go func() {
|
||||||
|
scanner := bufio.NewScanner(stderrPipe)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
stderr.WriteString(line + "\n")
|
||||||
|
slog.Error(line)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Wait for command to complete
|
||||||
|
err = cmd.Wait()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error(fmt.Sprintf("❌ Command failed with error: %v\n", err))
|
slog.Error(fmt.Sprintf("❌ Command failed with error: %v\n", err))
|
||||||
slog.Debug(fmt.Sprintf("🐞 Stdout: %s\n", stdout.String()))
|
slog.Debug(fmt.Sprintf("🐞 Stdout: %s\n", stdout.String()))
|
||||||
slog.Debug(fmt.Sprintf("🐞 Stderr: %s\n", stderr.String()))
|
slog.Debug(fmt.Sprintf("🐞 Stderr: %s\n", stderr.String()))
|
||||||
return fmt.Errorf("failed to run script command: %w", err)
|
return fmt.Errorf("failed to run script command: %w", err)
|
||||||
}
|
}
|
||||||
output := stdout.String()
|
|
||||||
slog.Debug(fmt.Sprintf("RunCommand executed successfully: %s", command))
|
|
||||||
slog.Debug(fmt.Sprintf("RunCommand output: %s", output))
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ func ReadBaseConfig(path string) (BaseConfig, error) {
|
||||||
deploymentType := os.Getenv("DEPLOYMENT_TYPE")
|
deploymentType := os.Getenv("DEPLOYMENT_TYPE")
|
||||||
|
|
||||||
deploymentFile := flag.String("deployment-file", "", "path to config file")
|
deploymentFile := flag.String("deployment-file", "", "path to config file")
|
||||||
|
deploymentFileShorthand := flag.String("f", "", "shorthand for -deployment-file")
|
||||||
|
|
||||||
helpFlag := flag.Bool("help", false, "show help")
|
helpFlag := flag.Bool("help", false, "show help")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
|
@ -45,7 +47,9 @@ func ReadBaseConfig(path string) (BaseConfig, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var config BaseConfig
|
var config BaseConfig
|
||||||
if *deploymentFile != "" {
|
if *deploymentFileShorthand != "" {
|
||||||
|
config.DeploymentFile = *deploymentFileShorthand
|
||||||
|
} else if *deploymentFile != "" {
|
||||||
config.DeploymentFile = *deploymentFile
|
config.DeploymentFile = *deploymentFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
46
main.go
46
main.go
|
|
@ -14,6 +14,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
@ -23,11 +24,54 @@ import (
|
||||||
"headshed/infctl-cli/config"
|
"headshed/infctl-cli/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type customMessageOnlyHandler struct {
|
||||||
|
output *os.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *customMessageOnlyHandler) Enabled(_ context.Context, _ slog.Level) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *customMessageOnlyHandler) Handle(_ context.Context, r slog.Record) error {
|
||||||
|
// Directly retrieve the message from the record
|
||||||
|
msg := r.Message
|
||||||
|
if msg != "" {
|
||||||
|
_, err := fmt.Fprintln(h.output, msg)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *customMessageOnlyHandler) WithAttrs(_ []slog.Attr) slog.Handler {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *customMessageOnlyHandler) WithGroup(_ string) slog.Handler {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
var levelVar slog.LevelVar
|
var levelVar slog.LevelVar
|
||||||
levelVar.Set(slog.LevelDebug)
|
levelVar.Set(slog.LevelDebug)
|
||||||
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: &levelVar}))
|
|
||||||
|
var logger *slog.Logger
|
||||||
|
if os.Getenv("LOG_FORMAT") == "basic" {
|
||||||
|
logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
|
||||||
|
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
|
||||||
|
if a.Key == slog.TimeKey {
|
||||||
|
return slog.Attr{}
|
||||||
|
}
|
||||||
|
return a
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
|
} else if os.Getenv("LOG_FORMAT") == "none" {
|
||||||
|
logger = slog.New(&customMessageOnlyHandler{output: os.Stdout})
|
||||||
|
|
||||||
|
} else {
|
||||||
|
logger = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: &levelVar}))
|
||||||
|
}
|
||||||
|
|
||||||
slog.SetDefault(logger)
|
slog.SetDefault(logger)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue