87 lines
2.0 KiB
Go
87 lines
2.0 KiB
Go
package network
|
|
|
|
import (
|
|
"fmt"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
// IfDown brings an interface down via ifdown (or ip link set down as fallback).
|
|
func IfDown(name string) error {
|
|
out, err := exec.Command("ifdown", "--force", name).CombinedOutput()
|
|
if err != nil {
|
|
// fallback: ip link set down
|
|
out2, err2 := exec.Command("ip", "link", "set", name, "down").CombinedOutput()
|
|
if err2 != nil {
|
|
return fmt.Errorf("ifdown %s: %s\nip fallback: %s", name, strings.TrimSpace(string(out)), strings.TrimSpace(string(out2)))
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// IfUp brings an interface up via ifup (or ip link set up as fallback).
|
|
func IfUp(name string) error {
|
|
out, err := exec.Command("ifup", name).CombinedOutput()
|
|
if err != nil {
|
|
out2, err2 := exec.Command("ip", "link", "set", name, "up").CombinedOutput()
|
|
if err2 != nil {
|
|
return fmt.Errorf("ifup %s: %s\nip fallback: %s", name, strings.TrimSpace(string(out)), strings.TrimSpace(string(out2)))
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// IfRestart brings an interface down then up.
|
|
func IfRestart(name string) error {
|
|
_ = IfDown(name) // ignore "already down" errors
|
|
return IfUp(name)
|
|
}
|
|
|
|
// ApplyPending merges pending configs into /etc/network/interfaces,
|
|
// writes the file, and restarts affected interfaces.
|
|
// Returns a per-interface error map (nil key = write error).
|
|
func ApplyPending() map[string]error {
|
|
errs := map[string]error{}
|
|
|
|
pending := GetAllPending()
|
|
if len(pending) == 0 {
|
|
return errs
|
|
}
|
|
|
|
// Read current file config
|
|
configs, err := ParseConfig()
|
|
if err != nil {
|
|
errs["__parse__"] = err
|
|
return errs
|
|
}
|
|
|
|
// Merge
|
|
for name, cfg := range pending {
|
|
configs[name] = cfg
|
|
}
|
|
|
|
// Write file
|
|
if err := WriteConfig(configs); err != nil {
|
|
errs["__write__"] = err
|
|
return errs
|
|
}
|
|
|
|
// Restart each changed interface
|
|
for name := range pending {
|
|
if name == "lo" {
|
|
ClearPendingConfig(name)
|
|
continue
|
|
}
|
|
_ = IfDown(name)
|
|
if cfg := configs[name]; cfg != nil && cfg.Auto {
|
|
if err := IfUp(name); err != nil {
|
|
errs[name] = err
|
|
continue
|
|
}
|
|
}
|
|
ClearPendingConfig(name)
|
|
}
|
|
|
|
return errs
|
|
}
|