Move network aspect of links into driver as a job

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
Michael Crosby 2014-01-30 12:43:49 -08:00
parent 2df0166107
commit 167403988d
3 changed files with 77 additions and 45 deletions

View File

@ -670,10 +670,6 @@ func (container *Container) Start() (err error) {
} }
if len(children) > 0 { if len(children) > 0 {
panic("todo crosbymichael")
/*
linking is specific to iptables and the bridge we need to move this to a job
container.activeLinks = make(map[string]*Link, len(children)) container.activeLinks = make(map[string]*Link, len(children))
// If we encounter an error make sure that we rollback any network // If we encounter an error make sure that we rollback any network
@ -686,7 +682,7 @@ func (container *Container) Start() (err error) {
} }
for p, child := range children { for p, child := range children {
link, err := NewLink(container, child, p, runtime.networkManager.bridgeIface) link, err := NewLink(container, child, p, runtime.eng)
if err != nil { if err != nil {
rollback() rollback()
return err return err
@ -702,7 +698,6 @@ func (container *Container) Start() (err error) {
env = append(env, envVar) env = append(env, envVar)
} }
} }
*/
} }
for _, elem := range container.Config.Env { for _, elem := range container.Config.Env {

View File

@ -2,7 +2,7 @@ package docker
import ( import (
"fmt" "fmt"
"github.com/dotcloud/docker/pkg/iptables" "github.com/dotcloud/docker/engine"
"path" "path"
"strings" "strings"
) )
@ -11,13 +11,13 @@ type Link struct {
ParentIP string ParentIP string
ChildIP string ChildIP string
Name string Name string
BridgeInterface string
ChildEnvironment []string ChildEnvironment []string
Ports []Port Ports []Port
IsEnabled bool IsEnabled bool
eng *engine.Engine
} }
func NewLink(parent, child *Container, name, bridgeInterface string) (*Link, error) { func NewLink(parent, child *Container, name string, eng *engine.Engine) (*Link, error) {
if parent.ID == child.ID { if parent.ID == child.ID {
return nil, fmt.Errorf("Cannot link to self: %s == %s", parent.ID, child.ID) return nil, fmt.Errorf("Cannot link to self: %s == %s", parent.ID, child.ID)
} }
@ -33,12 +33,12 @@ func NewLink(parent, child *Container, name, bridgeInterface string) (*Link, err
} }
l := &Link{ l := &Link{
BridgeInterface: bridgeInterface,
Name: name, Name: name,
ChildIP: child.NetworkSettings.IPAddress, ChildIP: child.NetworkSettings.IPAddress,
ParentIP: parent.NetworkSettings.IPAddress, ParentIP: parent.NetworkSettings.IPAddress,
ChildEnvironment: child.Config.Env, ChildEnvironment: child.Config.Env,
Ports: ports, Ports: ports,
eng: eng,
} }
return l, nil return l, nil
@ -119,18 +119,21 @@ func (l *Link) Disable() {
} }
func (l *Link) toggle(action string, ignoreErrors bool) error { func (l *Link) toggle(action string, ignoreErrors bool) error {
for _, p := range l.Ports { job := l.eng.Job("link", action)
if output, err := iptables.Raw(action, "FORWARD",
"-i", l.BridgeInterface, "-o", l.BridgeInterface, job.Setenv("ParentIP", l.ParentIP)
"-p", p.Proto(), job.Setenv("ChildIP", l.ChildIP)
"-s", l.ParentIP, job.SetenvBool("IgnoreErrors", ignoreErrors)
"--dport", p.Port(),
"-d", l.ChildIP, out := make([]string, len(l.Ports))
"-j", "ACCEPT"); !ignoreErrors && err != nil { for i, p := range l.Ports {
return err out[i] = fmt.Sprintf("%s/%s", p.Port(), p.Proto())
} else if len(output) != 0 {
return fmt.Errorf("Error toggle iptables forward: %s", output)
} }
job.SetenvList("Ports", out)
if err := job.Run(); err != nil {
// TODO: get ouput from job
return err
} }
return nil return nil
} }

View File

@ -13,6 +13,7 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"net" "net"
"strings"
"syscall" "syscall"
"unsafe" "unsafe"
) )
@ -137,6 +138,7 @@ func InitDriver(job *engine.Job) engine.Status {
"allocate_interface": Allocate, "allocate_interface": Allocate,
"release_interface": Release, "release_interface": Release,
"allocate_port": AllocatePort, "allocate_port": AllocatePort,
"link": LinkContainers,
} { } {
if err := job.Eng.Register(name, f); err != nil { if err := job.Eng.Register(name, f); err != nil {
job.Error(err) job.Error(err)
@ -423,3 +425,35 @@ func AllocatePort(job *engine.Job) engine.Status {
return engine.StatusOK return engine.StatusOK
} }
func LinkContainers(job *engine.Job) engine.Status {
var (
action = job.Args[0]
childIP = job.Getenv("ChildIP")
parentIP = job.Getenv("ParentIP")
ignoreErrors = job.GetenvBool("IgnoreErrors")
ports = job.GetenvList("Ports")
)
split := func(p string) (string, string) {
parts := strings.Split(p, "/")
return parts[0], parts[1]
}
for _, p := range ports {
port, proto := split(p)
if output, err := iptables.Raw(action, "FORWARD",
"-i", bridgeIface, "-o", bridgeIface,
"-p", proto,
"-s", parentIP,
"--dport", port,
"-d", childIP,
"-j", "ACCEPT"); !ignoreErrors && err != nil {
job.Error(err)
return engine.StatusErr
} else if len(output) != 0 {
job.Errorf("Error toggle iptables forward: %s", output)
return engine.StatusErr
}
}
return engine.StatusOK
}