98 lines
2.5 KiB
Go
98 lines
2.5 KiB
Go
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func transportWrapExecWithNetns(client TransportClient, command string) string {
|
|
cmd := strings.TrimSpace(command)
|
|
if cmd == "" || !transportNetnsEnabled(client) {
|
|
return cmd
|
|
}
|
|
ns := transportNetnsName(client)
|
|
if ns == "" {
|
|
return cmd
|
|
}
|
|
name, args, err := transportNetnsExecCommand(client, ns, "/bin/sh", "-lc", cmd)
|
|
if err != nil {
|
|
return cmd
|
|
}
|
|
return shellJoinArgs(append([]string{name}, args...))
|
|
}
|
|
|
|
func transportResolveNetnsNsenterBin(client TransportClient) string {
|
|
if explicit := strings.TrimSpace(transportConfigString(client.Config, "netns_nsenter_bin")); explicit != "" {
|
|
return explicit
|
|
}
|
|
if p, err := exec.LookPath("nsenter"); err == nil {
|
|
return strings.TrimSpace(p)
|
|
}
|
|
candidates := []string{
|
|
"/usr/bin/nsenter",
|
|
"/bin/nsenter",
|
|
"/usr/sbin/nsenter",
|
|
"/sbin/nsenter",
|
|
}
|
|
for _, cand := range candidates {
|
|
if _, err := os.Stat(cand); err == nil {
|
|
return cand
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func transportNetnsExecCommand(client TransportClient, ns string, command ...string) (string, []string, error) {
|
|
if strings.TrimSpace(ns) == "" {
|
|
return "", nil, fmt.Errorf("netns name is empty")
|
|
}
|
|
if len(command) == 0 {
|
|
return "", nil, fmt.Errorf("netns command is empty")
|
|
}
|
|
mode := strings.ToLower(strings.TrimSpace(transportConfigString(client.Config, "netns_exec_mode")))
|
|
useNsenter := false
|
|
switch mode {
|
|
case "ip", "ip-netns", "ip_netns":
|
|
useNsenter = false
|
|
case "nsenter":
|
|
useNsenter = true
|
|
case "", "auto":
|
|
useNsenter = true
|
|
default:
|
|
useNsenter = true
|
|
}
|
|
if useNsenter {
|
|
if bin := transportResolveNetnsNsenterBin(client); bin != "" {
|
|
args := []string{"--net=/var/run/netns/" + ns, "--"}
|
|
args = append(args, command...)
|
|
return bin, args, nil
|
|
}
|
|
}
|
|
ipBin := strings.TrimSpace(transportConfigString(client.Config, "netns_ip_bin"))
|
|
if ipBin == "" {
|
|
ipBin = "ip"
|
|
}
|
|
args := []string{"netns", "exec", ns}
|
|
args = append(args, command...)
|
|
return ipBin, args, nil
|
|
}
|
|
|
|
func transportRunInNetnsMust(timeout time.Duration, client TransportClient, ns string, command ...string) error {
|
|
name, args, err := transportNetnsExecCommand(client, ns, command...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return transportRunMust(timeout, name, args...)
|
|
}
|
|
|
|
func transportRunInNetnsSoft(timeout time.Duration, client TransportClient, ns string, command ...string) error {
|
|
name, args, err := transportNetnsExecCommand(client, ns, command...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return transportRunSoft(timeout, name, args...)
|
|
}
|