Update core calls to network drivers
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
parent
90494600d3
commit
c712e74b45
5 changed files with 128 additions and 86 deletions
18
config.go
18
config.go
|
@ -5,6 +5,11 @@ import (
|
|||
"net"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultNetworkMtu = 1500
|
||||
DisableNetworkBridge = "none"
|
||||
)
|
||||
|
||||
// FIXME: separate runtime configuration from http api configuration
|
||||
type DaemonConfig struct {
|
||||
Pidfile string
|
||||
|
@ -13,12 +18,13 @@ type DaemonConfig struct {
|
|||
Dns []string
|
||||
EnableIptables bool
|
||||
EnableIpForward bool
|
||||
BridgeIface string
|
||||
BridgeIp string
|
||||
DefaultIp net.IP
|
||||
BridgeIface string
|
||||
BridgeIP string
|
||||
InterContainerCommunication bool
|
||||
GraphDriver string
|
||||
Mtu int
|
||||
DisableNetwork bool
|
||||
}
|
||||
|
||||
// ConfigFromJob creates and returns a new DaemonConfig object
|
||||
|
@ -30,7 +36,7 @@ func DaemonConfigFromJob(job *engine.Job) *DaemonConfig {
|
|||
AutoRestart: job.GetenvBool("AutoRestart"),
|
||||
EnableIptables: job.GetenvBool("EnableIptables"),
|
||||
EnableIpForward: job.GetenvBool("EnableIpForward"),
|
||||
BridgeIp: job.Getenv("BridgeIp"),
|
||||
BridgeIP: job.Getenv("BridgeIp"),
|
||||
DefaultIp: net.ParseIP(job.Getenv("DefaultIp")),
|
||||
InterContainerCommunication: job.GetenvBool("InterContainerCommunication"),
|
||||
GraphDriver: job.Getenv("GraphDriver"),
|
||||
|
@ -38,16 +44,12 @@ func DaemonConfigFromJob(job *engine.Job) *DaemonConfig {
|
|||
if dns := job.GetenvList("Dns"); dns != nil {
|
||||
config.Dns = dns
|
||||
}
|
||||
if br := job.Getenv("BridgeIface"); br != "" {
|
||||
config.BridgeIface = br
|
||||
} else {
|
||||
config.BridgeIface = DefaultNetworkBridge
|
||||
}
|
||||
if mtu := job.GetenvInt("Mtu"); mtu != 0 {
|
||||
config.Mtu = mtu
|
||||
} else {
|
||||
config.Mtu = DefaultNetworkMtu
|
||||
}
|
||||
config.DisableNetwork = job.Getenv("BridgeIface") == DisableNetworkBridge
|
||||
|
||||
return config
|
||||
}
|
||||
|
|
140
container.go
140
container.go
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/dotcloud/docker/engine"
|
||||
"github.com/dotcloud/docker/execdriver"
|
||||
"github.com/dotcloud/docker/graphdriver"
|
||||
"github.com/dotcloud/docker/networkdriver/ipallocator"
|
||||
"github.com/dotcloud/docker/pkg/mount"
|
||||
"github.com/dotcloud/docker/pkg/term"
|
||||
"github.com/dotcloud/docker/utils"
|
||||
|
@ -16,7 +15,6 @@ import (
|
|||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
@ -47,7 +45,6 @@ type Container struct {
|
|||
State State
|
||||
Image string
|
||||
|
||||
network *NetworkInterface
|
||||
NetworkSettings *NetworkSettings
|
||||
|
||||
ResolvConfPath string
|
||||
|
@ -558,6 +555,7 @@ func populateCommand(c *Container) {
|
|||
en *execdriver.Network
|
||||
driverConfig []string
|
||||
)
|
||||
|
||||
if !c.Config.NetworkDisabled {
|
||||
network := c.NetworkSettings
|
||||
en = &execdriver.Network{
|
||||
|
@ -603,15 +601,18 @@ func (container *Container) Start() (err error) {
|
|||
if container.State.IsRunning() {
|
||||
return fmt.Errorf("The container %s is already running.", container.ID)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
container.cleanup()
|
||||
}
|
||||
}()
|
||||
|
||||
if err := container.Mount(); err != nil {
|
||||
return err
|
||||
}
|
||||
if container.runtime.networkManager.disabled {
|
||||
|
||||
if container.runtime.config.DisableNetwork {
|
||||
container.Config.NetworkDisabled = true
|
||||
container.buildHostnameAndHostsFiles("127.0.1.1")
|
||||
} else {
|
||||
|
@ -669,34 +670,39 @@ func (container *Container) Start() (err error) {
|
|||
}
|
||||
|
||||
if len(children) > 0 {
|
||||
container.activeLinks = make(map[string]*Link, len(children))
|
||||
panic("todo crosbymichael")
|
||||
/*
|
||||
linking is specific to iptables and the bridge we need to move this to a job
|
||||
|
||||
// If we encounter an error make sure that we rollback any network
|
||||
// config and ip table changes
|
||||
rollback := func() {
|
||||
for _, link := range container.activeLinks {
|
||||
link.Disable()
|
||||
}
|
||||
container.activeLinks = nil
|
||||
}
|
||||
container.activeLinks = make(map[string]*Link, len(children))
|
||||
|
||||
for p, child := range children {
|
||||
link, err := NewLink(container, child, p, runtime.networkManager.bridgeIface)
|
||||
if err != nil {
|
||||
rollback()
|
||||
return err
|
||||
}
|
||||
// If we encounter an error make sure that we rollback any network
|
||||
// config and ip table changes
|
||||
rollback := func() {
|
||||
for _, link := range container.activeLinks {
|
||||
link.Disable()
|
||||
}
|
||||
container.activeLinks = nil
|
||||
}
|
||||
|
||||
container.activeLinks[link.Alias()] = link
|
||||
if err := link.Enable(); err != nil {
|
||||
rollback()
|
||||
return err
|
||||
}
|
||||
for p, child := range children {
|
||||
link, err := NewLink(container, child, p, runtime.networkManager.bridgeIface)
|
||||
if err != nil {
|
||||
rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
for _, envVar := range link.ToEnv() {
|
||||
env = append(env, envVar)
|
||||
}
|
||||
}
|
||||
container.activeLinks[link.Alias()] = link
|
||||
if err := link.Enable(); err != nil {
|
||||
rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
for _, envVar := range link.ToEnv() {
|
||||
env = append(env, envVar)
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
for _, elem := range container.Config.Env {
|
||||
|
@ -1102,34 +1108,44 @@ func (container *Container) allocateNetwork() error {
|
|||
}
|
||||
|
||||
var (
|
||||
iface *NetworkInterface
|
||||
err error
|
||||
env *engine.Env
|
||||
eng = container.runtime.srv.Eng
|
||||
)
|
||||
if container.State.IsGhost() {
|
||||
if manager := container.runtime.networkManager; manager.disabled {
|
||||
iface = &NetworkInterface{disabled: true}
|
||||
if container.runtime.config.DisableNetwork {
|
||||
env = &engine.Env{}
|
||||
} else {
|
||||
iface = &NetworkInterface{
|
||||
IPNet: net.IPNet{IP: net.ParseIP(container.NetworkSettings.IPAddress), Mask: manager.bridgeNetwork.Mask},
|
||||
Gateway: manager.bridgeNetwork.IP,
|
||||
manager: manager,
|
||||
}
|
||||
if iface != nil && iface.IPNet.IP != nil {
|
||||
if _, err := ipallocator.RequestIP(manager.bridgeNetwork, &iface.IPNet.IP); err != nil {
|
||||
return err
|
||||
// TODO: @crosbymichael
|
||||
panic("not implemented")
|
||||
/*
|
||||
iface = &NetworkInterface{
|
||||
IPNet: net.IPNet{IP: net.ParseIP(container.NetworkSettings.IPAddress), Mask: manager.bridgeNetwork.Mask},
|
||||
Gateway: manager.bridgeNetwork.IP,
|
||||
}
|
||||
} else {
|
||||
iface, err = container.runtime.networkManager.Allocate()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
// request an existing ip
|
||||
if iface != nil && iface.IPNet.IP != nil {
|
||||
if _, err := ipallocator.RequestIP(manager.bridgeNetwork, &iface.IPNet.IP); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
job = eng.Job("allocate_interface", container.ID)
|
||||
if err := job.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
} else {
|
||||
iface, err = container.runtime.networkManager.Allocate()
|
||||
job := eng.Job("allocate_interface", container.ID)
|
||||
var err error
|
||||
env, err = job.Stdout.AddEnv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := job.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if container.Config.PortSpecs != nil {
|
||||
|
@ -1171,37 +1187,43 @@ func (container *Container) allocateNetwork() error {
|
|||
if container.hostConfig.PublishAllPorts && len(binding) == 0 {
|
||||
binding = append(binding, PortBinding{})
|
||||
}
|
||||
|
||||
for i := 0; i < len(binding); i++ {
|
||||
b := binding[i]
|
||||
nat, err := iface.AllocatePort(port, b)
|
||||
if err != nil {
|
||||
iface.Release()
|
||||
|
||||
portJob := eng.Job("allocate_port", container.ID)
|
||||
portJob.Setenv("HostIP", b.HostIp)
|
||||
portJob.Setenv("HostPort", b.HostPort)
|
||||
portJob.Setenv("Proto", port.Proto())
|
||||
portJob.Setenv("ContainerPort", port.Port())
|
||||
|
||||
if err := portJob.Run(); err != nil {
|
||||
eng.Job("release_interface", container.ID).Run()
|
||||
return err
|
||||
}
|
||||
utils.Debugf("Allocate port: %s:%s->%s", nat.Binding.HostIp, port, nat.Binding.HostPort)
|
||||
binding[i] = nat.Binding
|
||||
}
|
||||
bindings[port] = binding
|
||||
}
|
||||
container.writeHostConfig()
|
||||
|
||||
container.NetworkSettings.Ports = bindings
|
||||
container.network = iface
|
||||
|
||||
container.NetworkSettings.Bridge = container.runtime.networkManager.bridgeIface
|
||||
container.NetworkSettings.IPAddress = iface.IPNet.IP.String()
|
||||
container.NetworkSettings.IPPrefixLen, _ = iface.IPNet.Mask.Size()
|
||||
container.NetworkSettings.Gateway = iface.Gateway.String()
|
||||
container.NetworkSettings.Bridge = env.Get("Bridge")
|
||||
container.NetworkSettings.IPAddress = env.Get("IP")
|
||||
container.NetworkSettings.IPPrefixLen = env.GetInt("IPPrefixLen")
|
||||
container.NetworkSettings.Gateway = env.Get("Gateway")
|
||||
fmt.Printf("\n-----> %#v\n", container.NetworkSettings)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (container *Container) releaseNetwork() {
|
||||
if container.Config.NetworkDisabled || container.network == nil {
|
||||
if container.Config.NetworkDisabled {
|
||||
return
|
||||
}
|
||||
container.network.Release()
|
||||
container.network = nil
|
||||
eng := container.runtime.srv.Eng
|
||||
|
||||
eng.Job("release_interface", container.ID).Run()
|
||||
container.NetworkSettings = &NetworkSettings{}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@ import (
|
|||
|
||||
const (
|
||||
DefaultNetworkBridge = "docker0"
|
||||
DisableNetworkBridge = "none"
|
||||
DefaultNetworkMtu = 1500
|
||||
siocBRADDBR = 0x89a0
|
||||
)
|
||||
|
||||
|
@ -70,17 +68,24 @@ func InitDriver(job *engine.Job) engine.Status {
|
|||
enableIPTables = job.GetenvBool("EnableIptables")
|
||||
icc = job.GetenvBool("InterContainerCommunication")
|
||||
ipForward = job.GetenvBool("EnableIpForward")
|
||||
bridgeIP = job.Getenv("BridgeIP")
|
||||
)
|
||||
|
||||
bridgeIface = job.Getenv("BridgeIface")
|
||||
if bridgeIface == "" {
|
||||
bridgeIface = DefaultNetworkBridge
|
||||
}
|
||||
|
||||
addr, err := networkdriver.GetIfaceAddr(bridgeIface)
|
||||
if err != nil {
|
||||
// If the iface is not found, try to create it
|
||||
if err := createBridgeIface(bridgeIface); err != nil {
|
||||
job.Logf("creating new bridge for %s", bridgeIface)
|
||||
if err := createBridge(bridgeIP); err != nil {
|
||||
job.Error(err)
|
||||
return engine.StatusErr
|
||||
}
|
||||
|
||||
job.Logf("getting iface addr")
|
||||
addr, err = networkdriver.GetIfaceAddr(bridgeIface)
|
||||
if err != nil {
|
||||
job.Error(err)
|
||||
|
@ -122,9 +127,14 @@ func InitDriver(job *engine.Job) engine.Status {
|
|||
}
|
||||
|
||||
bridgeNetwork = network
|
||||
|
||||
// https://github.com/dotcloud/docker/issues/2768
|
||||
job.Eng.Hack_SetGlobalVar("httpapi.bridgeIP", bridgeNetwork.IP)
|
||||
|
||||
for name, f := range map[string]engine.Handler{
|
||||
"allocate_interface": Allocate,
|
||||
"release_interface": Release,
|
||||
"allocate_port": AllocatePort,
|
||||
} {
|
||||
if err := job.Eng.Register(name, f); err != nil {
|
||||
job.Error(err)
|
||||
|
@ -304,6 +314,10 @@ func Allocate(job *engine.Job) engine.Status {
|
|||
out.Set("IP", string(*ip))
|
||||
out.Set("Mask", string(bridgeNetwork.Mask))
|
||||
out.Set("Gateway", string(bridgeNetwork.IP))
|
||||
out.Set("Bridge", bridgeIface)
|
||||
|
||||
size, _ := bridgeNetwork.Mask.Size()
|
||||
out.SetInt("IPPrefixLen", size)
|
||||
|
||||
currentInterfaces[id] = &networkInterface{
|
||||
IP: *ip,
|
||||
|
|
29
runtime.go
29
runtime.go
|
@ -4,6 +4,7 @@ import (
|
|||
"container/list"
|
||||
"fmt"
|
||||
"github.com/dotcloud/docker/archive"
|
||||
"github.com/dotcloud/docker/engine"
|
||||
"github.com/dotcloud/docker/execdriver"
|
||||
"github.com/dotcloud/docker/execdriver/chroot"
|
||||
"github.com/dotcloud/docker/execdriver/lxc"
|
||||
|
@ -12,6 +13,7 @@ import (
|
|||
_ "github.com/dotcloud/docker/graphdriver/btrfs"
|
||||
_ "github.com/dotcloud/docker/graphdriver/devmapper"
|
||||
_ "github.com/dotcloud/docker/graphdriver/vfs"
|
||||
_ "github.com/dotcloud/docker/networkdriver/lxc"
|
||||
"github.com/dotcloud/docker/networkdriver/portallocator"
|
||||
"github.com/dotcloud/docker/pkg/graphdb"
|
||||
"github.com/dotcloud/docker/pkg/sysinfo"
|
||||
|
@ -42,7 +44,6 @@ type Runtime struct {
|
|||
repository string
|
||||
sysInitPath string
|
||||
containers *list.List
|
||||
networkManager *NetworkManager
|
||||
graph *Graph
|
||||
repositories *TagStore
|
||||
idIndex *utils.TruncIndex
|
||||
|
@ -609,15 +610,15 @@ func (runtime *Runtime) RegisterLink(parent, child *Container, alias string) err
|
|||
}
|
||||
|
||||
// FIXME: harmonize with NewGraph()
|
||||
func NewRuntime(config *DaemonConfig) (*Runtime, error) {
|
||||
runtime, err := NewRuntimeFromDirectory(config)
|
||||
func NewRuntime(config *DaemonConfig, eng *engine.Engine) (*Runtime, error) {
|
||||
runtime, err := NewRuntimeFromDirectory(config, eng)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return runtime, nil
|
||||
}
|
||||
|
||||
func NewRuntimeFromDirectory(config *DaemonConfig) (*Runtime, error) {
|
||||
func NewRuntimeFromDirectory(config *DaemonConfig, eng *engine.Engine) (*Runtime, error) {
|
||||
|
||||
// Set the default driver
|
||||
graphdriver.DefaultDriver = config.GraphDriver
|
||||
|
@ -664,12 +665,19 @@ func NewRuntimeFromDirectory(config *DaemonConfig) (*Runtime, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("Couldn't create Tag store: %s", err)
|
||||
}
|
||||
if config.BridgeIface == "" {
|
||||
config.BridgeIface = DefaultNetworkBridge
|
||||
}
|
||||
netManager, err := newNetworkManager(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
if !config.DisableNetwork {
|
||||
job := eng.Job("init_networkdriver")
|
||||
|
||||
job.SetenvBool("EnableIptables", config.EnableIptables)
|
||||
job.SetenvBool("InterContainerCommunication", config.InterContainerCommunication)
|
||||
job.SetenvBool("EnableIpForward", config.EnableIpForward)
|
||||
job.Setenv("BridgeIface", config.BridgeIface)
|
||||
job.Setenv("BridgeIP", config.BridgeIP)
|
||||
|
||||
if err := job.Run(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
graphdbPath := path.Join(config.Root, "linkgraph.db")
|
||||
|
@ -721,7 +729,6 @@ func NewRuntimeFromDirectory(config *DaemonConfig) (*Runtime, error) {
|
|||
runtime := &Runtime{
|
||||
repository: runtimeRepo,
|
||||
containers: list.New(),
|
||||
networkManager: netManager,
|
||||
graph: g,
|
||||
repositories: repositories,
|
||||
idIndex: utils.NewTruncIndex(),
|
||||
|
|
|
@ -65,10 +65,7 @@ func jobInitApi(job *engine.Job) engine.Status {
|
|||
}()
|
||||
job.Eng.Hack_SetGlobalVar("httpapi.server", srv)
|
||||
job.Eng.Hack_SetGlobalVar("httpapi.runtime", srv.runtime)
|
||||
// https://github.com/dotcloud/docker/issues/2768
|
||||
if srv.runtime.networkManager.bridgeNetwork != nil {
|
||||
job.Eng.Hack_SetGlobalVar("httpapi.bridgeIP", srv.runtime.networkManager.bridgeNetwork.IP)
|
||||
}
|
||||
|
||||
for name, handler := range map[string]engine.Handler{
|
||||
"export": srv.ContainerExport,
|
||||
"create": srv.ContainerCreate,
|
||||
|
@ -2354,7 +2351,7 @@ func (srv *Server) ContainerCopy(job *engine.Job) engine.Status {
|
|||
}
|
||||
|
||||
func NewServer(eng *engine.Engine, config *DaemonConfig) (*Server, error) {
|
||||
runtime, err := NewRuntime(config)
|
||||
runtime, err := NewRuntime(config, eng)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue