1
0
mirror of https://github.com/rancher/os.git synced 2025-07-01 09:11:48 +00:00

Bump vendored netconf

This commit is contained in:
Darren Shepherd 2015-12-22 21:50:04 -07:00
parent 7e4f8fe87d
commit 6cf84c7dc6
4 changed files with 295 additions and 39 deletions

View File

@ -69,7 +69,7 @@ import:
version: 1.9.1-2
- package: github.com/rancher/netconf
version: 02925e7cf5a0f0bb0aa5360ee260ef7378e5eff8
version: 8080e4909627bbdf51d7f427211a7c0517136373
- package: github.com/ryanuber/go-glob
version: 0067a9abd927e50aed5190662702f81231413ae0

129
vendor/github.com/rancher/netconf/bonding.go generated vendored Normal file
View File

@ -0,0 +1,129 @@
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 {
err error
name string
}
func (b *Bonding) Error() error {
return b.err
}
func (b *Bonding) init() {
_, 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
b.err = cmd.Run()
if b.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)
if err != nil {
b.err = 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) AddSlave(slave string) {
if b.err != nil {
return
}
if ok, err := contains(base+b.name+"/bonding/slaves", slave); err != nil {
b.err = err
return
} else if ok {
return
}
link, err := netlink.LinkByName(slave)
if err != nil {
b.err = err
return
}
b.err = netlink.LinkSetDown(link)
if b.err != nil {
return
}
p := base + b.name + "/bonding/slaves"
logrus.Infof("Adding slave %s to master %s", slave, b.name)
b.err = ioutil.WriteFile(p, []byte("+"+slave), 0644)
}
func (b *Bonding) Opt(key, value string) {
if b.err != nil {
return
}
p := base + b.name + "/bonding/" + key
b.err = ioutil.WriteFile(p, []byte(value), 0644)
if b.err != nil {
logrus.Errorf("Failed to set %s=%s on %s", key, value, b.name)
} else {
logrus.Infof("Set %s=%s on %s", key, value, b.name)
}
}
func (b *Bonding) Clear() {
b.err = nil
}
func Bond(name string) *Bonding {
b := &Bonding{name: name}
b.init()
if b.err != nil {
return b
}
if ok, err := contains(bondingMasters, name); err != nil {
b.err = err
return b
} else if ok {
return b
}
logrus.Infof("Creating bond %s", name)
b.err = ioutil.WriteFile(bondingMasters, []byte("+"+name), 0644)
return b
}

View File

@ -3,36 +3,83 @@ package netconf
import (
"bytes"
"errors"
"io/ioutil"
"net"
"os"
"os/exec"
"strings"
"syscall"
log "github.com/Sirupsen/logrus"
"github.com/flynn/go-shlex"
"github.com/ryanuber/go-glob"
"github.com/vishvananda/netlink"
)
const (
CONF = "/var/lib/rancher/conf"
NET_SCRIPT = "/var/lib/rancher/conf/network.sh"
)
func createInterfaces(netCfg *NetworkConfig) error {
for name, iface := range netCfg.Interfaces {
if !iface.Bridge {
continue
}
if iface.Bridge {
bridge := netlink.Bridge{}
bridge.LinkAttrs.Name = name
if err := netlink.LinkAdd(&bridge); err != nil {
log.Errorf("Failed to create bridge %s: %v", name, err)
}
} else if iface.Bond != "" {
bondIface, ok := netCfg.Interfaces[iface.Bond]
if !ok {
log.Errorf("Failed to find bond configuration for [%s]", iface.Bond)
continue
}
bond := Bond(iface.Bond)
if bond.Error() != nil {
log.Errorf("Failed to create bond [%s]: %v", iface.Bond, bond.Error())
continue
}
for k, v := range bondIface.BondOpts {
bond.Opt(k, v)
bond.Clear()
}
}
}
return nil
}
func runScript(netCfg *NetworkConfig) error {
if netCfg.Script == "" {
return nil
}
if _, err := os.Stat(CONF); os.IsNotExist(err) {
if err := os.MkdirAll(CONF, 0700); err != nil {
return err
}
}
if err := ioutil.WriteFile(NET_SCRIPT, []byte(netCfg.Script), 0700); err != nil {
return err
}
cmd := exec.Command(NET_SCRIPT)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
func ApplyNetworkConfigs(netCfg *NetworkConfig) error {
log.Debugf("Config: %#v", netCfg)
if err := runScript(netCfg); err != nil {
log.Errorf("Failed to run script: %v", err)
}
if err := createInterfaces(netCfg); err != nil {
return err
}
@ -63,7 +110,8 @@ func ApplyNetworkConfigs(netCfg *NetworkConfig) error {
if err != nil {
return err
}
if bytes.Compare(haAddr, link.Attrs().HardwareAddr) == 0 {
// Don't match mac address of the bond because it is the same as the slave
if bytes.Compare(haAddr, link.Attrs().HardwareAddr) == 0 && link.Attrs().Name != netConf.Bond {
// MAC address match is used over all other matches
match = netConf
break
@ -108,24 +156,87 @@ func ApplyNetworkConfigs(netCfg *NetworkConfig) error {
return nil
}
func linkUp(link netlink.Link, netConf InterfaceConfig) error {
if err := netlink.LinkSetUp(link); err != nil {
log.Errorf("failed to setup link: %v", err)
return err
}
return nil
}
func applyAddress(address string, link netlink.Link, netConf InterfaceConfig) error {
addr, err := netlink.ParseAddr(address)
if err != nil {
return err
}
if err := netlink.AddrAdd(link, addr); err == syscall.EEXIST {
//Ignore this error
} else if err != nil {
log.Errorf("addr add failed: %v", err)
} else {
log.Infof("Set %s on %s", netConf.Address, link.Attrs().Name)
}
return nil
}
func setGateway(gateway string) error {
if gateway == "" {
return nil
}
gatewayIp := net.ParseIP(gateway)
if gatewayIp == nil {
return errors.New("Invalid gateway address " + gateway)
}
route := netlink.Route{
Scope: netlink.SCOPE_UNIVERSE,
Gw: gatewayIp,
}
if err := netlink.RouteAdd(&route); err == syscall.EEXIST {
//Ignore this error
} else if err != nil {
log.Errorf("gateway set failed: %v", err)
return err
}
log.Infof("Set default gateway %s", gateway)
return nil
}
func applyNetConf(link netlink.Link, netConf InterfaceConfig) error {
if netConf.Bond != "" {
b := Bond(netConf.Bond)
b.AddSlave(link.Attrs().Name)
if b.Error() != nil {
return b.Error()
}
return linkUp(link, netConf)
}
if netConf.IPV4LL {
if err := AssignLinkLocalIP(link); err != nil {
log.Errorf("IPV4LL set failed: %v", err)
return err
}
} else if netConf.Address == "" {
} else if netConf.Address == "" && len(netConf.Addresses) == 0 {
return nil
} else {
addr, err := netlink.ParseAddr(netConf.Address)
if netConf.Address != "" {
err := applyAddress(netConf.Address, link, netConf)
if err != nil {
return err
log.Errorf("Failed to apply address %s to %s: %v", netConf.Address, link.Attrs().Name, err)
}
}
for _, address := range netConf.Addresses {
err := applyAddress(address, link, netConf)
if err != nil {
log.Errorf("Failed to apply address %s to %s: %v", address, link.Attrs().Name, err)
}
if err := netlink.AddrAdd(link, addr); err != nil {
//Ignore this error
log.Errorf("addr add failed: %v", err)
} else {
log.Infof("Set %s on %s", netConf.Address, link.Attrs().Name)
}
}
@ -136,27 +247,37 @@ func applyNetConf(link netlink.Link, netConf InterfaceConfig) error {
}
}
if err := netlink.LinkSetUp(link); err != nil {
log.Errorf("failed to setup link: %v", err)
if err := linkUp(link, netConf); err != nil {
return err
}
if netConf.Gateway != "" {
gatewayIp := net.ParseIP(netConf.Gateway)
if gatewayIp == nil {
return errors.New("Invalid gateway address " + netConf.Gateway)
if err := setGateway(netConf.Gateway); err != nil {
log.Errorf("Fail to set gateway %s", netConf.Gateway)
}
route := netlink.Route{
Scope: netlink.SCOPE_UNIVERSE,
Gw: net.ParseIP(netConf.Gateway),
}
if err := netlink.RouteAdd(&route); err != nil {
log.Errorf("gateway set failed: %v", err)
return err
if err := setGateway(netConf.GatewayIpv6); err != nil {
log.Errorf("Fail to set gateway %s", netConf.Gateway)
}
log.Infof("Set default gateway %s", netConf.Gateway)
for _, postUp := range netConf.PostUp {
postUp = strings.TrimSpace(postUp)
if postUp == "" {
continue
}
args, err := shlex.Split(strings.Replace(postUp, "$iface", link.Attrs().Name, -1))
if err != nil {
log.Errorf("Failed to parse command [%s]: %v", postUp, err)
continue
}
cmd := exec.Command(args[0], args[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
log.Errorf("Failed to run command [%s]: %v", postUp, err)
continue
}
}
return nil

View File

@ -1,6 +1,7 @@
package netconf
type NetworkConfig struct {
Script string `yaml:"script,omitempty"`
Dns DnsConfig `yaml:"dns,omitempty"`
Interfaces map[string]InterfaceConfig `yaml:"interfaces,omitempty"`
}
@ -9,10 +10,15 @@ type InterfaceConfig struct {
Match string `yaml:"match,omitempty"`
DHCP bool `yaml:"dhcp,omitempty"`
Address string `yaml:"address,omitempty"`
Addresses []string `yaml:"addresses,omitempty"`
IPV4LL bool `yaml:"ipv4ll,omitempty"`
Gateway string `yaml:"gateway,omitempty"`
GatewayIpv6 string `yaml:"gateway_ipv6,omitempty"`
MTU int `yaml:"mtu,omitempty"`
Bridge bool `yaml:"bridge,omitempty"`
Bond string `yaml:"bond,omitempty"`
BondOpts map[string]string `yaml:"bond_opts,omitempty"`
PostUp []string `yaml:"post_up,omitempty"`
}
type DnsConfig struct {