1
0
mirror of https://github.com/rancher/os.git synced 2025-06-30 16:51:47 +00:00

Rebase on rancher/netconf

This commit is contained in:
Darren Shepherd 2015-07-29 00:45:06 -07:00
parent 0f6668be43
commit 889c80b682
4 changed files with 9 additions and 258 deletions

View File

@ -38,8 +38,8 @@ import (
"github.com/coreos/coreos-cloudinit/initialize"
"github.com/coreos/coreos-cloudinit/pkg"
"github.com/coreos/coreos-cloudinit/system"
"github.com/rancher/netconf"
"github.com/rancherio/os/cmd/cloudinit/hostname"
rancherNetwork "github.com/rancherio/os/cmd/network"
rancherConfig "github.com/rancherio/os/config"
"github.com/rancherio/os/util"
)
@ -402,8 +402,8 @@ func getDatasources(cfg *rancherConfig.CloudConfig) []datasource.Datasource {
}
func enableDoLinkLocal() {
err := rancherNetwork.ApplyNetworkConfigs(&rancherConfig.NetworkConfig{
Interfaces: map[string]rancherConfig.InterfaceConfig{
err := netconf.ApplyNetworkConfigs(&netconf.NetworkConfig{
Interfaces: map[string]netconf.InterfaceConfig{
"eth0": {
IPV4LL: true,
},

View File

@ -1,75 +0,0 @@
package network
import (
"encoding/binary"
"fmt"
"math/rand"
"net"
log "github.com/Sirupsen/logrus"
"github.com/j-keck/arping"
"github.com/vishvananda/netlink"
)
func AssignLinkLocalIP(link netlink.Link) error {
ifaceName := link.Attrs().Name
iface, err := net.InterfaceByName(ifaceName)
if err != nil {
log.Error("could not get information about interface")
return err
}
addrs, err := iface.Addrs()
if err != nil {
log.Error("Error fetching existing ip on interface")
}
for _, addr := range addrs {
if addr.String()[:7] == "169.254" {
log.Info("Link Local IP already set on interface")
return nil
}
}
randSource, err := getPseudoRandomGenerator(link.Attrs().HardwareAddr)
if err != nil {
return err
}
// try a random address upto 10 times
for i := 0; i < 10; i++ {
randGenerator := rand.New(*randSource)
randomNum := randGenerator.Uint32()
dstIP := getNewIPV4LLAddr(randomNum)
if dstIP[2] == 0 || dstIP[2] == 255 {
i--
continue
}
_, _, err := arping.PingOverIfaceByName(dstIP, ifaceName)
if err != nil {
// this ip is not being used
addr, err := netlink.ParseAddr(dstIP.String() + "/16")
if err != nil {
log.Errorf("error while parsing ipv4ll addr, err = %v", err)
return err
}
if err := netlink.AddrAdd(link, addr); err != nil {
log.Error("ipv4ll addr add failed")
return err
}
log.Infof("Set %s on %s", dstIP.String(), link.Attrs().Name)
return nil
}
}
log.Error("Could not find a suitable ipv4ll")
return fmt.Errorf("Could not find a suitable ipv4ll")
}
func getNewIPV4LLAddr(randomNum uint32) net.IP {
byte1 := randomNum & 255 // use least significant 8 bits
byte2 := randomNum >> 24 // use most significant 8 bits
return []byte{169, 254, byte(byte1), byte(byte2)}
}
func getPseudoRandomGenerator(haAddr []byte) (*rand.Source, error) {
seed, _ := binary.Varint(haAddr)
src := rand.NewSource(seed)
return &src, nil
}

View File

@ -1,20 +1,13 @@
package network
import (
"bytes"
"errors"
"fmt"
"net"
"os"
"os/exec"
"strings"
log "github.com/Sirupsen/logrus"
"github.com/rancher/netconf"
"github.com/rancherio/os/config"
"github.com/rancherio/os/docker"
"github.com/ryanuber/go-glob"
"github.com/vishvananda/netlink"
)
func Main() {
@ -27,153 +20,7 @@ func Main() {
if err != nil {
log.Fatal(err)
}
ApplyNetworkConfigs(&cfg.Rancher.Network)
}
func createInterfaces(netCfg *config.NetworkConfig) error {
for name, iface := range netCfg.Interfaces {
if !iface.Bridge {
continue
}
bridge := netlink.Bridge{}
bridge.LinkAttrs.Name = name
if err := netlink.LinkAdd(&bridge); err != nil {
log.Errorf("Failed to create bridge %s: %v", name, err)
}
}
return nil
}
func ApplyNetworkConfigs(netCfg *config.NetworkConfig) error {
if err := createInterfaces(netCfg); err != nil {
return err
}
links, err := netlink.LinkList()
if err != nil {
return err
}
//apply network config
for _, link := range links {
linkName := link.Attrs().Name
var match config.InterfaceConfig
for key, netConf := range netCfg.Interfaces {
if netConf.Match == "" {
netConf.Match = key
}
if netConf.Match == "" {
continue
}
if len(netConf.Match) > 4 && strings.ToLower(netConf.Match[:3]) == "mac" {
haAddr, err := net.ParseMAC(netConf.Match[4:])
if err != nil {
return err
}
if bytes.Compare(haAddr, link.Attrs().HardwareAddr) == 0 {
// MAC address match is used over all other matches
match = netConf
break
}
}
// "" means match has not been found
if match.Match == "" && matches(linkName, netConf.Match) {
match = netConf
}
if netConf.Match == linkName {
// Found exact match, use it over wildcard match
match = netConf
}
}
if match.Match != "" {
err = applyNetConf(link, match)
if err != nil {
log.Errorf("Failed to apply settings to %s : %v", linkName, err)
}
}
}
if err != nil {
return err
}
//post run
if netCfg.PostRun != nil {
return docker.StartAndWait(config.DOCKER_SYSTEM_HOST, netCfg.PostRun)
}
return nil
}
func applyNetConf(link netlink.Link, netConf config.InterfaceConfig) error {
if netConf.DHCP {
log.Infof("Running DHCP on %s", link.Attrs().Name)
cmd := exec.Command("dhcpcd", "-A4", "-e", "force_hostname=true", link.Attrs().Name)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
log.Error(err)
}
} else if netConf.IPV4LL {
if err := AssignLinkLocalIP(link); err != nil {
log.Error("IPV4LL set failed")
return err
}
} else if netConf.Address == "" {
return nil
} else {
addr, err := netlink.ParseAddr(netConf.Address)
if err != nil {
return err
}
if err := netlink.AddrAdd(link, addr); err != nil {
log.Error("addr add failed")
return err
}
log.Infof("Set %s on %s", netConf.Address, link.Attrs().Name)
}
if netConf.MTU > 0 {
if err := netlink.LinkSetMTU(link, netConf.MTU); err != nil {
log.Error("set MTU Failed")
return err
}
}
if err := netlink.LinkSetUp(link); err != nil {
log.Error("failed to setup link")
return err
}
if netConf.Gateway != "" {
gatewayIp := net.ParseIP(netConf.Gateway)
if gatewayIp == nil {
return errors.New("Invalid gateway address " + netConf.Gateway)
}
route := netlink.Route{
Scope: netlink.SCOPE_UNIVERSE,
Gw: net.ParseIP(netConf.Gateway),
}
if err := netlink.RouteAdd(&route); err != nil {
log.Error("gateway set failed")
return err
}
log.Infof("Set default gateway %s", netConf.Gateway)
}
return nil
}
func matches(link, conf string) bool {
return glob.Glob(conf, link)
if err := netconf.ApplyNetworkConfigs(&cfg.Rancher.Network); err != nil {
log.Fatal(err)
}
}

View File

@ -2,6 +2,7 @@ package config
import (
"github.com/coreos/coreos-cloudinit/config"
"github.com/rancher/netconf"
"github.com/rancherio/rancher-compose/librcompose/project"
)
@ -76,7 +77,7 @@ type RancherConfig struct {
Disable []string `yaml:"disable,omitempty"`
ServicesInclude map[string]bool `yaml:"services_include,omitempty"`
Modules []string `yaml:"modules,omitempty"`
Network NetworkConfig `yaml:"network,omitempty"`
Network netconf.NetworkConfig `yaml:"network,omitempty"`
Repositories Repositories `yaml:"repositories,omitempty"`
Ssh SshConfig `yaml:"ssh,omitempty"`
State StateConfig `yaml:"state,omitempty"`
@ -97,28 +98,6 @@ type UpgradeConfig struct {
Rollback string `yaml:"rollback,omitempty"`
}
type DnsConfig struct {
Nameservers []string `yaml:"nameservers,flow,omitempty"`
Search []string `yaml:"search,flow,omitempty"`
Domain string `yaml:"domain,omitempty"`
}
type NetworkConfig struct {
Dns DnsConfig `yaml:"dns,omitempty"`
Interfaces map[string]InterfaceConfig `yaml:"interfaces,omitempty"`
PostRun *ContainerConfig `yaml:"post_run,omitempty"`
}
type InterfaceConfig struct {
Match string `yaml:"match,omitempty"`
DHCP bool `yaml:"dhcp,omitempty"`
Address string `yaml:"address,omitempty"`
IPV4LL bool `yaml:"ipv4ll,omitempty"`
Gateway string `yaml:"gateway,omitempty"`
MTU int `yaml:"mtu,omitempty"`
Bridge bool `yaml:"bridge,omitempty"`
}
type DockerConfig struct {
TLS bool `yaml:"tls,omitempty"`
TLSArgs []string `yaml:"tls_args,flow,omitempty"`