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)
- }
+ netnsKillPids(ns)
// Prevent any conflicts with existing data
ip("netns", "del", ns)
// Don't remove anything in /etc/netns/ as the user might store
ip("netns", "add", ns)
// Write /etc/netns/$netns/hosts with all known hosts
- nsCfgPath := filepath.Join("/etc/netns", ns)
- nsHostsPath := filepath.Join(nsCfgPath, "hosts")
+ nsHostsPath := netnsHostsPath(ns)
log.Printf(" Writing %q", nsHostsPath)
- err := os.MkdirAll(nsCfgPath, 0755)
+ err := os.MkdirAll(netnsCfgPath(ns), 0755)
if err != nil {
log.Fatal(err)
}
}
}
+func mustDown(cfg *Config) {
+ for _, node := range cfg.Nodes {
+ log.Printf("Removing node %q ...", node.Name)
+
+ ns := node.Name
+ if !netnsExists(ns) {
+ log.Printf(" netns doesn't exist, skipping cleanup")
+ continue
+ }
+
+ netnsKillPids(ns)
+ ip("netns", "del", ns)
+
+ // Delete files we created in /etc/netns/. Keep the rest as the user
+ // might store configuration there!
+ nsHostsPath := netnsHostsPath(ns)
+ log.Printf(" Removing %q (including parent directory if empty)",
+ nsHostsPath)
+ err := os.Remove(nsHostsPath)
+ if err != nil && !os.IsNotExist(err) {
+ log.Fatal(err)
+ }
+ // Ignore error as /etc/netns/<ns>/ might not be empty
+ _ = os.Remove(netnsCfgPath(ns))
+ }
+}
+
func ip(args ...string) {
xargs := append([]string{"ip"}, args...)
log.Printf(" Running %q", xargs)
return res
}
+func netnsKillPids(netns string) {
+ for _, x := range netnsPids(netns) {
+ 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)
+ }
+}
+
+func netnsCfgPath(netns string) string {
+ return filepath.Join("/etc/netns", netns)
+}
+
+func netnsHostsPath(netns string) string {
+ return filepath.Join(netnsCfgPath(netns), "hosts")
+}
+
func ifaceExists(netns, name string) bool {
args := []string{"-n", netns, "-json", "link"}
xargs := append([]string{"ip"}, args...)