"os"
"os/exec"
"path/filepath"
+ "strconv"
+ "strings"
+ "syscall"
)
func main() {
// One namespace per node, named as the node's name
ns := node.Name
if netnsExists(ns) {
+ // Terminate processes in old namespaces
+ for _, x := range netnsPids(ns) {
+ log.Printf(" Killing old PID %d", x)
+ err := syscall.Kill(x, syscall.SIGTERM)
+ if err != nil {
+ log.Fatalf("failed to kill %d: %v", x, err)
+ }
+ // Also try SIGHUP to terminate shells which ignore SIGTERM
+ _ = syscall.Kill(x, syscall.SIGHUP)
+ }
// Prevent any conflicts with existing data
ip("netns", "del", ns)
// Don't remove anything in /etc/netns/ as the user might store
return true
}
+func netnsPids(netns string) []int {
+ args := []string{"netns", "pids", netns}
+ xargs := append([]string{"ip"}, args...)
+
+ cmd := exec.Command("ip", args...)
+ out, err := cmd.Output()
+ if err != nil {
+ log.Fatalf("failed to run %q: %v", xargs, err)
+ }
+
+ var res []int
+ xs := strings.FieldsFunc(string(out), func(c rune) bool {
+ return c == '\n'
+ })
+ for _, x := range xs {
+ y, err := strconv.Atoi(x)
+ if err != nil {
+ log.Fatal(err)
+ }
+ res = append(res, y)
+ }
+ return res
+}
+
func ifaceExists(netns, name string) bool {
args := []string{"-n", netns, "-json", "link"}
xargs := append([]string{"ip"}, args...)