mirror of https://github.com/docker/docs.git
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:
parent
2df0166107
commit
167403988d
53
container.go
53
container.go
|
@ -670,39 +670,34 @@ func (container *Container) Start() (err error) {
|
|||
}
|
||||
|
||||
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
|
||||
// config and ip table changes
|
||||
rollback := func() {
|
||||
for _, link := range container.activeLinks {
|
||||
link.Disable()
|
||||
}
|
||||
container.activeLinks = nil
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
for p, child := range children {
|
||||
link, err := NewLink(container, child, p, runtime.eng)
|
||||
if 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
|
||||
}
|
||||
container.activeLinks[link.Alias()] = link
|
||||
if err := link.Enable(); err != nil {
|
||||
rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
container.activeLinks[link.Alias()] = link
|
||||
if err := link.Enable(); err != nil {
|
||||
rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
for _, envVar := range link.ToEnv() {
|
||||
env = append(env, envVar)
|
||||
}
|
||||
}
|
||||
*/
|
||||
for _, envVar := range link.ToEnv() {
|
||||
env = append(env, envVar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, elem := range container.Config.Env {
|
||||
|
|
35
links.go
35
links.go
|
@ -2,7 +2,7 @@ package docker
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/dotcloud/docker/pkg/iptables"
|
||||
"github.com/dotcloud/docker/engine"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
@ -11,13 +11,13 @@ type Link struct {
|
|||
ParentIP string
|
||||
ChildIP string
|
||||
Name string
|
||||
BridgeInterface string
|
||||
ChildEnvironment []string
|
||||
Ports []Port
|
||||
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 {
|
||||
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{
|
||||
BridgeInterface: bridgeInterface,
|
||||
Name: name,
|
||||
ChildIP: child.NetworkSettings.IPAddress,
|
||||
ParentIP: parent.NetworkSettings.IPAddress,
|
||||
ChildEnvironment: child.Config.Env,
|
||||
Ports: ports,
|
||||
eng: eng,
|
||||
}
|
||||
return l, nil
|
||||
|
||||
|
@ -119,18 +119,21 @@ func (l *Link) Disable() {
|
|||
}
|
||||
|
||||
func (l *Link) toggle(action string, ignoreErrors bool) error {
|
||||
for _, p := range l.Ports {
|
||||
if output, err := iptables.Raw(action, "FORWARD",
|
||||
"-i", l.BridgeInterface, "-o", l.BridgeInterface,
|
||||
"-p", p.Proto(),
|
||||
"-s", l.ParentIP,
|
||||
"--dport", p.Port(),
|
||||
"-d", l.ChildIP,
|
||||
"-j", "ACCEPT"); !ignoreErrors && err != nil {
|
||||
return err
|
||||
} else if len(output) != 0 {
|
||||
return fmt.Errorf("Error toggle iptables forward: %s", output)
|
||||
}
|
||||
job := l.eng.Job("link", action)
|
||||
|
||||
job.Setenv("ParentIP", l.ParentIP)
|
||||
job.Setenv("ChildIP", l.ChildIP)
|
||||
job.SetenvBool("IgnoreErrors", ignoreErrors)
|
||||
|
||||
out := make([]string, len(l.Ports))
|
||||
for i, p := range l.Ports {
|
||||
out[i] = fmt.Sprintf("%s/%s", p.Port(), p.Proto())
|
||||
}
|
||||
job.SetenvList("Ports", out)
|
||||
|
||||
if err := job.Run(); err != nil {
|
||||
// TODO: get ouput from job
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
@ -137,6 +138,7 @@ func InitDriver(job *engine.Job) engine.Status {
|
|||
"allocate_interface": Allocate,
|
||||
"release_interface": Release,
|
||||
"allocate_port": AllocatePort,
|
||||
"link": LinkContainers,
|
||||
} {
|
||||
if err := job.Eng.Register(name, f); err != nil {
|
||||
job.Error(err)
|
||||
|
@ -423,3 +425,35 @@ func AllocatePort(job *engine.Job) engine.Status {
|
|||
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue