mirror of
https://github.com/rancher/os.git
synced 2025-09-09 02:31:36 +00:00
Move in code from netconf and docker-from-scratch
This commit is contained in:
143
netconf/bonding.go
Normal file
143
netconf/bonding.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package netconf
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
const (
|
||||
base = "/sys/class/net/"
|
||||
bondingMasters = "/sys/class/net/bonding_masters"
|
||||
)
|
||||
|
||||
type Bonding struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func (b *Bonding) init() error {
|
||||
_, err := os.Stat(bondingMasters)
|
||||
if os.IsNotExist(err) {
|
||||
logrus.Info("Loading bonding kernel module")
|
||||
cmd := exec.Command("modprobe", "bonding")
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdout = os.Stdin
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
for i := 0; i < 30; i++ {
|
||||
if _, err = os.Stat(bondingMasters); err == nil {
|
||||
break
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
}
|
||||
_, err = os.Stat(bondingMasters)
|
||||
return err
|
||||
}
|
||||
|
||||
func contains(file, word string) (bool, error) {
|
||||
words, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, s := range strings.Split(strings.TrimSpace(string(words)), " ") {
|
||||
if s == strings.TrimSpace(word) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (b *Bonding) linkDown() error {
|
||||
link, err := netlink.LinkByName(b.name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return netlink.LinkSetDown(link)
|
||||
}
|
||||
|
||||
func (b *Bonding) ListSlaves() ([]string, error) {
|
||||
file := base + b.name + "/bonding/slaves"
|
||||
words, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []string{}
|
||||
for _, s := range strings.Split(strings.TrimSpace(string(words)), " ") {
|
||||
if s != "" {
|
||||
result = append(result, s)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (b *Bonding) RemoveSlave(slave string) error {
|
||||
if ok, err := contains(base+b.name+"/bonding/slaves", slave); err != nil {
|
||||
return err
|
||||
} else if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
p := base + b.name + "/bonding/slaves"
|
||||
logrus.Infof("Removing slave %s from master %s", slave, b.name)
|
||||
return ioutil.WriteFile(p, []byte("-"+slave), 0644)
|
||||
}
|
||||
|
||||
func (b *Bonding) AddSlave(slave string) error {
|
||||
if ok, err := contains(base+b.name+"/bonding/slaves", slave); err != nil {
|
||||
return err
|
||||
} else if ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
p := base + b.name + "/bonding/slaves"
|
||||
logrus.Infof("Adding slave %s to master %s", slave, b.name)
|
||||
return ioutil.WriteFile(p, []byte("+"+slave), 0644)
|
||||
}
|
||||
|
||||
func (b *Bonding) Opt(key, value string) error {
|
||||
if key == "mode" {
|
||||
// Don't care about errors here
|
||||
b.linkDown()
|
||||
slaves, _ := b.ListSlaves()
|
||||
for _, slave := range slaves {
|
||||
b.RemoveSlave(slave)
|
||||
}
|
||||
}
|
||||
|
||||
p := base + b.name + "/bonding/" + key
|
||||
if err := ioutil.WriteFile(p, []byte(value), 0644); err != nil {
|
||||
logrus.Errorf("Failed to set %s=%s on %s: %v", key, value, b.name, err)
|
||||
return err
|
||||
} else {
|
||||
logrus.Infof("Set %s=%s on %s", key, value, b.name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Bond(name string) (*Bonding, error) {
|
||||
b := &Bonding{name: name}
|
||||
if err := b.init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ok, err := contains(bondingMasters, name); err != nil {
|
||||
return nil, err
|
||||
} else if ok {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
logrus.Infof("Creating bond %s", name)
|
||||
return b, ioutil.WriteFile(bondingMasters, []byte("+"+name), 0644)
|
||||
}
|
Reference in New Issue
Block a user