56 lines
1.3 KiB
Go
56 lines
1.3 KiB
Go
package syscmd
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"os/exec"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func RunCommand(name string, args ...string) (string, string, int, error) {
|
|
return RunCommandTimeout(60*time.Second, name, args...)
|
|
}
|
|
|
|
func CheckPolicyRoute(iface, table string) (bool, error) {
|
|
stdout, _, exitCode, err := RunCommand("ip", "route", "show", "table", table)
|
|
if exitCode != 0 {
|
|
if err == nil {
|
|
err = fmt.Errorf("ip route show exited with %d", exitCode)
|
|
}
|
|
return false, err
|
|
}
|
|
want := fmt.Sprintf("default dev %s", iface)
|
|
for _, line := range strings.Split(stdout, "\n") {
|
|
line = strings.TrimSpace(line)
|
|
if strings.HasPrefix(line, want) {
|
|
return true, nil
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func RunCommandTimeout(timeout time.Duration, name string, args ...string) (string, string, int, error) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
defer cancel()
|
|
|
|
cmd := exec.CommandContext(ctx, name, args...)
|
|
out, err := cmd.CombinedOutput()
|
|
stdout := string(out)
|
|
stderr := stdout
|
|
|
|
exitCode := 0
|
|
if err != nil {
|
|
if ee, ok := err.(*exec.ExitError); ok {
|
|
exitCode = ee.ExitCode()
|
|
} else if errors.Is(err, context.DeadlineExceeded) {
|
|
exitCode = -1
|
|
err = fmt.Errorf("command timeout: %w", err)
|
|
} else {
|
|
exitCode = -1
|
|
}
|
|
}
|
|
return stdout, stderr, exitCode, err
|
|
}
|