package main import ( "os/exec" "strings" udev "github.com/jochenvg/go-udev" "github.com/rs/zerolog/log" config "novit.tech/direktil/pkg/bootstrapconfig" ) func setupNetworks(cfg *config.Config) { if len(cfg.Networks) == 0 { log.Info().Msg("no networks configured.") return } type Iface struct { Name string AliasOf string } ifaces := make([]NameAliases, 0) { enum := new(udev.Udev).NewEnumerate() enum.AddMatchSubsystem("net") devs, err := enum.Devices() if err != nil { fatal("udev enumeration failed") } for _, dev := range devs { iface := nameAliases(dev.Sysname(), dev.PropertyValue("INTERFACE"), dev.PropertyValue("ID_NET_NAME"), dev.PropertyValue("ID_NET_NAME_PATH"), dev.PropertyValue("ID_NET_NAME_MAC"), dev.PropertyValue("ID_NET_NAME_SLOT"), ) log.Info().Str("name", iface.Name).Any("aliases", iface.Aliases).Msg("found network device") ifaces = append(ifaces, iface) } } assigned := map[string]bool{} for _, network := range cfg.Networks { log := log.With().Str("network", network.Name).Logger() log.Info().Msg("setting up network") unassigned := filter(ifaces, func(iface NameAliases) bool { return !assigned[iface.Name] }) // assign envvars envvars := make([]string, 0, 1+len(network.Interfaces)) envvars = append(envvars, "PATH=/bin:/sbin:/usr/bin:/usr/sbin") for _, match := range network.Interfaces { envvar := new(strings.Builder) envvar.WriteString(match.Var) envvar.WriteByte('=') for i, m := range regexpSelectN(match.N, match.Regexps, unassigned) { assigned[m] = true if i != 0 { envvar.WriteByte(' ') } envvar.WriteString(m) } envvars = append(envvars, envvar.String()) } log.Info().Strs("env", envvars).Msg("running script") cmd := exec.Command("/bin/sh", "-c", network.Script) cmd.Env = envvars cmd.Stdout = stdout cmd.Stderr = stderr if err := cmd.Run(); err != nil { fatal("failed to setup network: ", err) } } }