2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 10:17:17 +08:00

feat: 优化docker兼容

This commit is contained in:
耗子
2024-10-31 03:28:41 +08:00
parent 52e8830605
commit f01afacf34
13 changed files with 107 additions and 49 deletions

View File

@@ -197,9 +197,8 @@ func (r *Firewall) Port(rule FireInfo, operation Operation) error {
}
protocols := strings.Split(string(rule.Protocol), "/")
for protocol := range slices.Values(protocols) {
stdout, err := shell.Execf("firewall-cmd --zone=public --%s-port=%d-%d/%s --permanent", operation, rule.PortStart, rule.PortEnd, protocol)
if err != nil {
return fmt.Errorf("%s port %d-%d/%s failed, err: %s", operation, rule.PortStart, rule.PortEnd, protocol, stdout)
if _, err := shell.Execf("firewall-cmd --zone=public --%s-port=%d-%d/%s --permanent", operation, rule.PortStart, rule.PortEnd, protocol); err != nil {
return err
}
}
@@ -243,7 +242,7 @@ func (r *Firewall) RichRules(rule FireInfo, operation Operation) error {
ruleBuilder.WriteString(string(rule.Strategy))
_, err := shell.Execf("firewall-cmd --zone=public --%s-rich-rule '%s' --permanent", operation, ruleBuilder.String())
if err != nil {
return fmt.Errorf("%s rich rules (%s) failed, err: %v", operation, ruleBuilder.String(), err)
return err
}
}
@@ -269,7 +268,7 @@ func (r *Firewall) Forward(rule Forward, operation Operation) error {
_, err := shell.Execf(ruleBuilder.String()) // nolint: govet
if err != nil {
return fmt.Errorf("%s port forward failed, err: %v", operation, err)
return err
}
}

View File

@@ -10,7 +10,10 @@ import (
"os/exec"
"slices"
"strings"
"syscall"
"time"
"github.com/creack/pty"
)
// Execf 执行 shell 命令
@@ -26,12 +29,11 @@ func Execf(shell string, args ...any) (string, error) {
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
return strings.TrimSpace(stdout.String()), errors.New(strings.TrimSpace(stderr.String()))
if err := cmd.Run(); err != nil {
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", fmt.Sprintf(shell, args...), strings.TrimSpace(stderr.String()))
}
return strings.TrimSpace(stdout.String()), err
return strings.TrimSpace(stdout.String()), nil
}
// ExecfAsync 异步执行 shell 命令
@@ -50,7 +52,7 @@ func ExecfAsync(shell string, args ...any) error {
go func() {
if err = cmd.Wait(); err != nil {
fmt.Println(err.Error())
fmt.Println(fmt.Errorf("run %s failed, err: %s", fmt.Sprintf(shell, args...), strings.TrimSpace(err.Error())))
}
}()
@@ -72,7 +74,7 @@ func ExecfWithTimeout(timeout time.Duration, shell string, args ...any) (string,
err := cmd.Start()
if err != nil {
return "", err
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", fmt.Sprintf(shell, args...), strings.TrimSpace(stderr.String()))
}
done := make(chan error)
@@ -83,10 +85,10 @@ func ExecfWithTimeout(timeout time.Duration, shell string, args ...any) (string,
select {
case <-time.After(timeout):
_ = cmd.Process.Kill()
return strings.TrimSpace(stdout.String()), errors.New("执行超时")
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", fmt.Sprintf(shell, args...), "timeout")
case err = <-done:
if err != nil {
return strings.TrimSpace(stdout.String()), errors.New(strings.TrimSpace(stderr.String()))
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", fmt.Sprintf(shell, args...), strings.TrimSpace(stderr.String()))
}
}
@@ -140,12 +142,40 @@ func ExecfWithDir(dir, shell string, args ...any) (string, error) {
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
return strings.TrimSpace(stdout.String()), errors.New(strings.TrimSpace(stderr.String()))
if err := cmd.Run(); err != nil {
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", fmt.Sprintf(shell, args...), strings.TrimSpace(stderr.String()))
}
return strings.TrimSpace(stdout.String()), err
return strings.TrimSpace(stdout.String()), nil
}
// ExecfWithTTY 在伪终端下执行 shell 命令
func ExecfWithTTY(shell string, args ...any) (string, error) {
if !preCheckArg(args) {
return "", errors.New("command contains illegal characters")
}
_ = os.Setenv("LC_ALL", "C")
cmd := exec.Command("bash", "-i", "-c", fmt.Sprintf(shell, args...))
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stderr = &stderr // https://github.com/creack/pty/issues/147 取 stderr
f, err := pty.Start(cmd)
if err != nil {
return "", fmt.Errorf("run %s failed", fmt.Sprintf(shell, args...))
}
defer f.Close()
if _, err = io.Copy(&out, f); ptyError(err) != nil {
return "", fmt.Errorf("run %s failed, out: %s, err: %w", fmt.Sprintf(shell, args...), strings.TrimSpace(out.String()), err)
}
if stderr.Len() > 0 {
return "", fmt.Errorf("run %s failed, out: %s", fmt.Sprintf(shell, args...), strings.TrimSpace(stderr.String()))
}
return strings.TrimSpace(out.String()), nil
}
func preCheckArg(args []any) bool {
@@ -158,3 +188,15 @@ func preCheckArg(args []any) bool {
return true
}
// Linux kernel return EIO when attempting to read from a master pseudo
// terminal which no longer has an open slave. So ignore error here.
// See https://github.com/creack/pty/issues/21
func ptyError(err error) error {
var pathErr *os.PathError
if !errors.As(err, &pathErr) || !errors.Is(pathErr.Err, syscall.EIO) {
return err
}
return nil
}