platform: modularize api/gui, add docs-tests-web foundation, and refresh root config
This commit is contained in:
97
selective-vpn-api/app/transport_netns_exec.go
Normal file
97
selective-vpn-api/app/transport_netns_exec.go
Normal file
@@ -0,0 +1,97 @@
|
||||
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...)
|
||||
}
|
||||
Reference in New Issue
Block a user