Files

105 lines
2.4 KiB
Go
Raw Permalink Normal View History

2026-04-13 09:46:02 +03:00
package network
import (
"fmt"
"os/exec"
"strings"
)
2026-04-15 11:38:26 +03:00
// LinkDown sets admin state down without deconfiguring (ip link set <name> down).
func LinkDown(name string) error {
out, err := exec.Command("ip", "link", "set", name, "down").CombinedOutput()
if err != nil {
return fmt.Errorf("ip link set down %s: %s", name, strings.TrimSpace(string(out)))
}
return nil
}
// LinkUp sets admin state up without re-running ifup (ip link set <name> up).
func LinkUp(name string) error {
out, err := exec.Command("ip", "link", "set", name, "up").CombinedOutput()
if err != nil {
return fmt.Errorf("ip link set up %s: %s", name, strings.TrimSpace(string(out)))
}
return nil
}
// IfDown brings an interface down via ifdown --force.
2026-04-13 09:46:02 +03:00
func IfDown(name string) error {
out, err := exec.Command("ifdown", "--force", name).CombinedOutput()
if err != nil {
2026-04-15 11:38:26 +03:00
return fmt.Errorf("ifdown %s: %s", name, strings.TrimSpace(string(out)))
2026-04-13 09:46:02 +03:00
}
return nil
}
2026-04-15 11:38:26 +03:00
// IfUp brings an interface up via ifup --force.
2026-04-13 09:46:02 +03:00
func IfUp(name string) error {
2026-04-15 11:38:26 +03:00
out, err := exec.Command("ifup", "--force", name).CombinedOutput()
2026-04-13 09:46:02 +03:00
if err != nil {
2026-04-15 11:38:26 +03:00
return fmt.Errorf("ifup %s: %s", name, strings.TrimSpace(string(out)))
2026-04-13 09:46:02 +03:00
}
return nil
}
// IfRestart brings an interface down then up.
func IfRestart(name string) error {
2026-04-15 11:38:26 +03:00
_ = IfDown(name)
2026-04-13 09:46:02 +03:00
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
}
2026-04-13 12:40:49 +03:00
// For VLAN interfaces ensure the kernel interface exists before ifup.
if IsVLAN(name) {
if err := EnsureVLANExists(name); err != nil {
errs[name] = err
continue
}
}
2026-04-13 09:46:02 +03:00
_ = IfDown(name)
if cfg := configs[name]; cfg != nil && cfg.Auto {
if err := IfUp(name); err != nil {
errs[name] = err
continue
}
}
ClearPendingConfig(name)
}
return errs
}