cert-manager-webhook-sthome/pkg/dns/shell.go

78 lines
1.7 KiB
Go

package dns
import (
"bytes"
"io"
"os"
"os/exec"
"sync"
"k8s.io/klog/v2"
)
// CapturingPassThroughWriter is a writer that remembers
// data written to it and passes it to w
type CapturingPassThroughWriter struct {
buf bytes.Buffer
w io.Writer
}
// NewCapturingPassThroughWriter creates new CapturingPassThroughWriter
func NewCapturingPassThroughWriter(w io.Writer) *CapturingPassThroughWriter {
return &CapturingPassThroughWriter{
w: w,
}
}
func (w *CapturingPassThroughWriter) Write(d []byte) (int, error) {
w.buf.Write(d)
return w.w.Write(d)
}
// Bytes returns bytes written to the writer
func (w *CapturingPassThroughWriter) Bytes() []byte {
return w.buf.Bytes()
}
func Execute(shell string, arg ...string) (bool, error) {
var errStdout, errStderr error
crlf := []byte("\r\n")
lf := []byte("\n")
cmd := exec.Command(shell, arg...)
stdoutIn, _ := cmd.StdoutPipe()
stderrIn, _ := cmd.StderrPipe()
stdout := NewCapturingPassThroughWriter(os.Stdout)
stderr := NewCapturingPassThroughWriter(os.Stderr)
err := cmd.Start()
if err != nil {
klog.Fatalf("cmd.Start() failed with '%s'\n", err)
}
var wg sync.WaitGroup
wg.Add(1)
go func() {
_, errStdout = io.Copy(stdout, stdoutIn)
wg.Done()
}()
_, errStderr = io.Copy(stderr, stderrIn)
wg.Wait()
err = cmd.Wait()
if err != nil {
klog.Fatalf("cmd.Run() failed with %s\n", err)
}
if errStdout != nil || errStderr != nil {
klog.Fatalf("failed to capture stdout or stderr\n")
}
//outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
//fmt.Printf("\nout:\n%s\nerr:\n%s\n", outStr, errStr)
errb := bytes.TrimSuffix(stderr.Bytes(), crlf)
errb = bytes.TrimSuffix(errb, lf)
if stderr != nil {
klog.Infof("err:\n%s\n", string(errb))
}
return true, nil
}