Pārlūkot izejas kodu

Move network aspect of links into driver as a job

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
Michael Crosby 11 gadi atpakaļ
vecāks
revīzija
167403988d
3 mainītis faili ar 80 papildinājumiem un 48 dzēšanām
  1. 27 32
      container.go
  2. 19 16
      links.go
  3. 34 0
      networkdriver/lxc/driver.go

+ 27 - 32
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))
-
-						// 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
-							}
-
-							container.activeLinks[link.Alias()] = link
-							if err := link.Enable(); err != nil {
-								rollback()
-								return err
-							}
-
-							for _, envVar := range link.ToEnv() {
-								env = append(env, envVar)
-							}
-						}
-		*/
+		// 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
+			}
+
+			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 {

+ 19 - 16
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
 }

+ 34 - 0
networkdriver/lxc/driver.go

@@ -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
+}