package main import ( "bytes" "net" "os" "os/exec" "path/filepath" "strconv" "syscall" "time" "github.com/sparrc/go-ping" "novit.nc/direktil/inits/pkg/apply" "novit.nc/direktil/inits/pkg/vars" "novit.nc/direktil/pkg/config" "novit.nc/direktil/pkg/log" ) func init() { services.Register(configure{}) } type configure struct{} func (_ configure) GetName() string { return "configure" } func (_ configure) CanStart() bool { return services.HasFlag("service:lvm", "service:udev trigger") } func (_ configure) Run(_ func()) error { // make root rshared (default in systemd, required by Kubernetes 1.10+) // equivalent to "mount --make-rshared /" // see kernel's Documentation/sharedsubtree.txt (search rshared) if err := syscall.Mount("", "/", "", syscall.MS_SHARED|syscall.MS_REC, ""); err != nil { fatalf("mount --make-rshared / failed: %v", err) } // - setup root user if passwordHash := cfg.RootUser.PasswordHash; passwordHash == "" { run("/usr/bin/passwd", "-d", "root") } else { run("/bin/sh", "-c", "chpasswd --encrypted < 3 { return } time.Sleep(1 * time.Second) initLog.Taintf(log.Warning, "network[%d] retrying (try: %d)", idx, tries) goto retry } } func startNetwork(ifaceName string, idx int, network config.NetworkDef) { initLog.Taintf(log.Info, "starting network[%d]", idx) script := vars.Substitute([]byte(network.Script), cfg) c := exec.Command("/bin/sh") c.Stdin = bytes.NewBuffer(script) c.Stdout = os.Stdout c.Stderr = os.Stderr // TODO doc c.Env = append(append(make([]string, 0), os.Environ()...), "IFNAME="+ifaceName) if err := c.Run(); err != nil { links, _ := exec.Command("ip", "link", "ls").CombinedOutput() fatalf("network setup failed (link list below): %v\n%s", err, string(links)) } networkStarted[ifaceName] = true } func networkPingCheck(ifName string, network config.NetworkDef) (bool, error) { check := network.Match.Ping source := string(vars.Substitute([]byte(check.Source), cfg)) run("ip", "addr", "add", source, "dev", ifName) run("ip", "link", "set", ifName, "up") defer func() { run("ip", "link", "set", ifName, "down") run("ip", "addr", "del", source, "dev", ifName) }() pinger, err := ping.NewPinger(network.Match.Ping.Target) if err != nil { return false, err } pinger.Count = 3 if check.Count > 0 { pinger.Count = check.Count } pinger.Timeout = 1 * time.Second if check.Timeout > 0 { pinger.Timeout = time.Duration(check.Timeout) * time.Second } pinger.SetPrivileged(true) pinger.Run() return pinger.Statistics().PacketsRecv > 0, nil }