1
0
mirror of https://github.com/rancher/os.git synced 2025-06-26 15:01:34 +00:00
os/cmd/network/network.go
Darren Shepherd 106fb36c8c Set hostname from DHCP (broken)
This adds the proper variable we need to set the hostname from DHCP. End
to end this does not work though.  The hostname does not propagate
outside the container.  More changes need to be done for this.
2015-04-10 07:28:28 -07:00

180 lines
3.7 KiB
Go

package network
import (
"bytes"
"errors"
"fmt"
"net"
"os"
"os/exec"
"strings"
log "github.com/Sirupsen/logrus"
"github.com/rancherio/os/config"
"github.com/rancherio/os/docker"
"github.com/ryanuber/go-glob"
"github.com/vishvananda/netlink"
)
func Main() {
args := os.Args
if len(args) > 1 {
fmt.Println("call " + args[0] + " to load network config from rancher.yml config file")
return
}
cfg, err := config.LoadConfig()
if err != nil {
log.Fatal(err)
}
ApplyNetworkConfigs(&cfg.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)
}