Signed-off-by: Tibor Vass <tibor@docker.com>
| ... | ... |
@@ -1,10 +1,10 @@ |
| 1 | 1 |
package client |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "encoding/json" |
|
| 4 | 5 |
"fmt" |
| 5 | 6 |
"strings" |
| 6 | 7 |
|
| 7 |
- "github.com/docker/docker/engine" |
|
| 8 | 8 |
"github.com/docker/docker/nat" |
| 9 | 9 |
flag "github.com/docker/docker/pkg/mflag" |
| 10 | 10 |
) |
| ... | ... |
@@ -23,12 +23,13 @@ func (cli *DockerCli) CmdPort(args ...string) error {
|
| 23 | 23 |
return err |
| 24 | 24 |
} |
| 25 | 25 |
|
| 26 |
- env := engine.Env{}
|
|
| 27 |
- if err := env.Decode(stream); err != nil {
|
|
| 28 |
- return err |
|
| 26 |
+ var c struct {
|
|
| 27 |
+ NetworkSettings struct {
|
|
| 28 |
+ Ports nat.PortMap |
|
| 29 |
+ } |
|
| 29 | 30 |
} |
| 30 |
- ports := nat.PortMap{}
|
|
| 31 |
- if err := env.GetSubEnv("NetworkSettings").GetJson("Ports", &ports); err != nil {
|
|
| 31 |
+ |
|
| 32 |
+ if err := json.NewDecoder(stream).Decode(&c); err != nil {
|
|
| 32 | 33 |
return err |
| 33 | 34 |
} |
| 34 | 35 |
|
| ... | ... |
@@ -44,7 +45,7 @@ func (cli *DockerCli) CmdPort(args ...string) error {
|
| 44 | 44 |
proto = parts[1] |
| 45 | 45 |
} |
| 46 | 46 |
natPort := port + "/" + proto |
| 47 |
- if frontends, exists := ports[nat.Port(port+"/"+proto)]; exists && frontends != nil {
|
|
| 47 |
+ if frontends, exists := c.NetworkSettings.Ports[nat.Port(port+"/"+proto)]; exists && frontends != nil {
|
|
| 48 | 48 |
for _, frontend := range frontends {
|
| 49 | 49 |
fmt.Fprintf(cli.out, "%s:%s\n", frontend.HostIp, frontend.HostPort) |
| 50 | 50 |
} |
| ... | ... |
@@ -53,7 +54,7 @@ func (cli *DockerCli) CmdPort(args ...string) error {
|
| 53 | 53 |
return fmt.Errorf("Error: No public port '%s' published for %s", natPort, cmd.Arg(0))
|
| 54 | 54 |
} |
| 55 | 55 |
|
| 56 |
- for from, frontends := range ports {
|
|
| 56 |
+ for from, frontends := range c.NetworkSettings.Ports {
|
|
| 57 | 57 |
for _, frontend := range frontends {
|
| 58 | 58 |
fmt.Fprintf(cli.out, "%s -> %s:%s\n", from, frontend.HostIp, frontend.HostPort) |
| 59 | 59 |
} |
| ... | ... |
@@ -6,15 +6,11 @@ import ( |
| 6 | 6 |
"github.com/docker/docker/api" |
| 7 | 7 |
apiserver "github.com/docker/docker/api/server" |
| 8 | 8 |
"github.com/docker/docker/autogen/dockerversion" |
| 9 |
- "github.com/docker/docker/daemon/networkdriver/bridge" |
|
| 10 | 9 |
"github.com/docker/docker/engine" |
| 11 | 10 |
"github.com/docker/docker/pkg/parsers/kernel" |
| 12 | 11 |
) |
| 13 | 12 |
|
| 14 | 13 |
func Register(eng *engine.Engine) error {
|
| 15 |
- if err := daemon(eng); err != nil {
|
|
| 16 |
- return err |
|
| 17 |
- } |
|
| 18 | 14 |
if err := remote(eng); err != nil {
|
| 19 | 15 |
return err |
| 20 | 16 |
} |
| ... | ... |
@@ -33,25 +29,6 @@ func remote(eng *engine.Engine) error {
|
| 33 | 33 |
return eng.Register("acceptconnections", apiserver.AcceptConnections)
|
| 34 | 34 |
} |
| 35 | 35 |
|
| 36 |
-// daemon: a default execution and storage backend for Docker on Linux, |
|
| 37 |
-// with the following underlying components: |
|
| 38 |
-// |
|
| 39 |
-// * Pluggable storage drivers including aufs, vfs, lvm and btrfs. |
|
| 40 |
-// * Pluggable execution drivers including lxc and chroot. |
|
| 41 |
-// |
|
| 42 |
-// In practice `daemon` still includes most core Docker components, including: |
|
| 43 |
-// |
|
| 44 |
-// * The reference registry client implementation |
|
| 45 |
-// * Image management |
|
| 46 |
-// * The build facility |
|
| 47 |
-// * Logging |
|
| 48 |
-// |
|
| 49 |
-// These components should be broken off into plugins of their own. |
|
| 50 |
-// |
|
| 51 |
-func daemon(eng *engine.Engine) error {
|
|
| 52 |
- return eng.Register("init_networkdriver", bridge.InitDriver)
|
|
| 53 |
-} |
|
| 54 |
- |
|
| 55 | 36 |
// builtins jobs independent of any subsystem |
| 56 | 37 |
func dockerVersion(job *engine.Job) error {
|
| 57 | 38 |
v := &engine.Env{}
|
| ... | ... |
@@ -1,9 +1,8 @@ |
| 1 | 1 |
package daemon |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "net" |
|
| 5 |
- |
|
| 6 | 4 |
"github.com/docker/docker/daemon/networkdriver" |
| 5 |
+ "github.com/docker/docker/daemon/networkdriver/bridge" |
|
| 7 | 6 |
"github.com/docker/docker/opts" |
| 8 | 7 |
flag "github.com/docker/docker/pkg/mflag" |
| 9 | 8 |
"github.com/docker/docker/pkg/ulimit" |
| ... | ... |
@@ -20,35 +19,27 @@ const ( |
| 20 | 20 |
// to the docker daemon when you launch it with say: `docker -d -e lxc` |
| 21 | 21 |
// FIXME: separate runtime configuration from http api configuration |
| 22 | 22 |
type Config struct {
|
| 23 |
- Pidfile string |
|
| 24 |
- Root string |
|
| 25 |
- AutoRestart bool |
|
| 26 |
- Dns []string |
|
| 27 |
- DnsSearch []string |
|
| 28 |
- EnableIPv6 bool |
|
| 29 |
- EnableIptables bool |
|
| 30 |
- EnableIpForward bool |
|
| 31 |
- EnableIpMasq bool |
|
| 32 |
- DefaultIp net.IP |
|
| 33 |
- BridgeIface string |
|
| 34 |
- BridgeIP string |
|
| 35 |
- FixedCIDR string |
|
| 36 |
- FixedCIDRv6 string |
|
| 37 |
- InterContainerCommunication bool |
|
| 38 |
- GraphDriver string |
|
| 39 |
- GraphOptions []string |
|
| 40 |
- ExecDriver string |
|
| 41 |
- Mtu int |
|
| 42 |
- SocketGroup string |
|
| 43 |
- EnableCors bool |
|
| 44 |
- CorsHeaders string |
|
| 45 |
- DisableNetwork bool |
|
| 46 |
- EnableSelinuxSupport bool |
|
| 47 |
- Context map[string][]string |
|
| 48 |
- TrustKeyPath string |
|
| 49 |
- Labels []string |
|
| 50 |
- Ulimits map[string]*ulimit.Ulimit |
|
| 51 |
- LogConfig runconfig.LogConfig |
|
| 23 |
+ Bridge bridge.Config |
|
| 24 |
+ |
|
| 25 |
+ Pidfile string |
|
| 26 |
+ Root string |
|
| 27 |
+ AutoRestart bool |
|
| 28 |
+ Dns []string |
|
| 29 |
+ DnsSearch []string |
|
| 30 |
+ GraphDriver string |
|
| 31 |
+ GraphOptions []string |
|
| 32 |
+ ExecDriver string |
|
| 33 |
+ Mtu int |
|
| 34 |
+ SocketGroup string |
|
| 35 |
+ EnableCors bool |
|
| 36 |
+ CorsHeaders string |
|
| 37 |
+ DisableNetwork bool |
|
| 38 |
+ EnableSelinuxSupport bool |
|
| 39 |
+ Context map[string][]string |
|
| 40 |
+ TrustKeyPath string |
|
| 41 |
+ Labels []string |
|
| 42 |
+ Ulimits map[string]*ulimit.Ulimit |
|
| 43 |
+ LogConfig runconfig.LogConfig |
|
| 52 | 44 |
} |
| 53 | 45 |
|
| 54 | 46 |
// InstallFlags adds command-line options to the top-level flag parser for |
| ... | ... |
@@ -59,15 +50,15 @@ func (config *Config) InstallFlags() {
|
| 59 | 59 |
flag.StringVar(&config.Pidfile, []string{"p", "-pidfile"}, "/var/run/docker.pid", "Path to use for daemon PID file")
|
| 60 | 60 |
flag.StringVar(&config.Root, []string{"g", "-graph"}, "/var/lib/docker", "Root of the Docker runtime")
|
| 61 | 61 |
flag.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, "--restart on the daemon has been deprecated in favor of --restart policies on docker run")
|
| 62 |
- flag.BoolVar(&config.EnableIptables, []string{"#iptables", "-iptables"}, true, "Enable addition of iptables rules")
|
|
| 63 |
- flag.BoolVar(&config.EnableIpForward, []string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")
|
|
| 64 |
- flag.BoolVar(&config.EnableIpMasq, []string{"-ip-masq"}, true, "Enable IP masquerading")
|
|
| 65 |
- flag.BoolVar(&config.EnableIPv6, []string{"-ipv6"}, false, "Enable IPv6 networking")
|
|
| 66 |
- flag.StringVar(&config.BridgeIP, []string{"#bip", "-bip"}, "", "Specify network bridge IP")
|
|
| 67 |
- flag.StringVar(&config.BridgeIface, []string{"b", "-bridge"}, "", "Attach containers to a network bridge")
|
|
| 68 |
- flag.StringVar(&config.FixedCIDR, []string{"-fixed-cidr"}, "", "IPv4 subnet for fixed IPs")
|
|
| 69 |
- flag.StringVar(&config.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", "IPv6 subnet for fixed IPs")
|
|
| 70 |
- flag.BoolVar(&config.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
|
|
| 62 |
+ flag.BoolVar(&config.Bridge.EnableIptables, []string{"#iptables", "-iptables"}, true, "Enable addition of iptables rules")
|
|
| 63 |
+ flag.BoolVar(&config.Bridge.EnableIpForward, []string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")
|
|
| 64 |
+ flag.BoolVar(&config.Bridge.EnableIpMasq, []string{"-ip-masq"}, true, "Enable IP masquerading")
|
|
| 65 |
+ flag.BoolVar(&config.Bridge.EnableIPv6, []string{"-ipv6"}, false, "Enable IPv6 networking")
|
|
| 66 |
+ flag.StringVar(&config.Bridge.IP, []string{"#bip", "-bip"}, "", "Specify network bridge IP")
|
|
| 67 |
+ flag.StringVar(&config.Bridge.Iface, []string{"b", "-bridge"}, "", "Attach containers to a network bridge")
|
|
| 68 |
+ flag.StringVar(&config.Bridge.FixedCIDR, []string{"-fixed-cidr"}, "", "IPv4 subnet for fixed IPs")
|
|
| 69 |
+ flag.StringVar(&config.Bridge.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", "IPv6 subnet for fixed IPs")
|
|
| 70 |
+ flag.BoolVar(&config.Bridge.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
|
|
| 71 | 71 |
flag.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", "Storage driver to use")
|
| 72 | 72 |
flag.StringVar(&config.ExecDriver, []string{"e", "-exec-driver"}, "native", "Exec driver to use")
|
| 73 | 73 |
flag.BoolVar(&config.EnableSelinuxSupport, []string{"-selinux-enabled"}, false, "Enable selinux support")
|
| ... | ... |
@@ -75,7 +66,7 @@ func (config *Config) InstallFlags() {
|
| 75 | 75 |
flag.StringVar(&config.SocketGroup, []string{"G", "-group"}, "docker", "Group for the unix socket")
|
| 76 | 76 |
flag.BoolVar(&config.EnableCors, []string{"#api-enable-cors", "#-api-enable-cors"}, false, "Enable CORS headers in the remote API, this is deprecated by --api-cors-header")
|
| 77 | 77 |
flag.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", "Set CORS headers in the remote API")
|
| 78 |
- opts.IPVar(&config.DefaultIp, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP when binding container ports")
|
|
| 78 |
+ opts.IPVar(&config.Bridge.DefaultIp, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP when binding container ports")
|
|
| 79 | 79 |
opts.ListVar(&config.GraphOptions, []string{"-storage-opt"}, "Set storage driver options")
|
| 80 | 80 |
// FIXME: why the inconsistency between "hosts" and "sockets"? |
| 81 | 81 |
opts.IPListVar(&config.Dns, []string{"#dns", "-dns"}, "DNS server to use")
|
| ... | ... |
@@ -24,6 +24,8 @@ import ( |
| 24 | 24 |
"github.com/docker/docker/daemon/logger" |
| 25 | 25 |
"github.com/docker/docker/daemon/logger/jsonfilelog" |
| 26 | 26 |
"github.com/docker/docker/daemon/logger/syslog" |
| 27 |
+ "github.com/docker/docker/daemon/network" |
|
| 28 |
+ "github.com/docker/docker/daemon/networkdriver/bridge" |
|
| 27 | 29 |
"github.com/docker/docker/engine" |
| 28 | 30 |
"github.com/docker/docker/image" |
| 29 | 31 |
"github.com/docker/docker/links" |
| ... | ... |
@@ -73,7 +75,7 @@ type Container struct {
|
| 73 | 73 |
Config *runconfig.Config |
| 74 | 74 |
ImageID string `json:"Image"` |
| 75 | 75 |
|
| 76 |
- NetworkSettings *NetworkSettings |
|
| 76 |
+ NetworkSettings *network.Settings |
|
| 77 | 77 |
|
| 78 | 78 |
ResolvConfPath string |
| 79 | 79 |
HostnamePath string |
| ... | ... |
@@ -571,17 +573,12 @@ func (container *Container) AllocateNetwork() error {
|
| 571 | 571 |
} |
| 572 | 572 |
|
| 573 | 573 |
var ( |
| 574 |
- env *engine.Env |
|
| 575 | 574 |
err error |
| 576 | 575 |
eng = container.daemon.eng |
| 577 | 576 |
) |
| 578 | 577 |
|
| 579 |
- job := eng.Job("allocate_interface", container.ID)
|
|
| 580 |
- job.Setenv("RequestedMac", container.Config.MacAddress)
|
|
| 581 |
- if env, err = job.Stdout.AddEnv(); err != nil {
|
|
| 582 |
- return err |
|
| 583 |
- } |
|
| 584 |
- if err = job.Run(); err != nil {
|
|
| 578 |
+ networkSettings, err := bridge.Allocate(container.ID, container.Config.MacAddress, "", "") |
|
| 579 |
+ if err != nil {
|
|
| 585 | 580 |
return err |
| 586 | 581 |
} |
| 587 | 582 |
|
| ... | ... |
@@ -591,12 +588,12 @@ func (container *Container) AllocateNetwork() error {
|
| 591 | 591 |
|
| 592 | 592 |
if container.Config.PortSpecs != nil {
|
| 593 | 593 |
if err = migratePortMappings(container.Config, container.hostConfig); err != nil {
|
| 594 |
- eng.Job("release_interface", container.ID).Run()
|
|
| 594 |
+ bridge.Release(container.ID) |
|
| 595 | 595 |
return err |
| 596 | 596 |
} |
| 597 | 597 |
container.Config.PortSpecs = nil |
| 598 | 598 |
if err = container.WriteHostConfig(); err != nil {
|
| 599 |
- eng.Job("release_interface", container.ID).Run()
|
|
| 599 |
+ bridge.Release(container.ID) |
|
| 600 | 600 |
return err |
| 601 | 601 |
} |
| 602 | 602 |
} |
| ... | ... |
@@ -626,23 +623,14 @@ func (container *Container) AllocateNetwork() error {
|
| 626 | 626 |
|
| 627 | 627 |
for port := range portSpecs {
|
| 628 | 628 |
if err = container.allocatePort(eng, port, bindings); err != nil {
|
| 629 |
- eng.Job("release_interface", container.ID).Run()
|
|
| 629 |
+ bridge.Release(container.ID) |
|
| 630 | 630 |
return err |
| 631 | 631 |
} |
| 632 | 632 |
} |
| 633 | 633 |
container.WriteHostConfig() |
| 634 | 634 |
|
| 635 |
- container.NetworkSettings.Ports = bindings |
|
| 636 |
- container.NetworkSettings.Bridge = env.Get("Bridge")
|
|
| 637 |
- container.NetworkSettings.IPAddress = env.Get("IP")
|
|
| 638 |
- container.NetworkSettings.IPPrefixLen = env.GetInt("IPPrefixLen")
|
|
| 639 |
- container.NetworkSettings.MacAddress = env.Get("MacAddress")
|
|
| 640 |
- container.NetworkSettings.Gateway = env.Get("Gateway")
|
|
| 641 |
- container.NetworkSettings.LinkLocalIPv6Address = env.Get("LinkLocalIPv6")
|
|
| 642 |
- container.NetworkSettings.LinkLocalIPv6PrefixLen = 64 |
|
| 643 |
- container.NetworkSettings.GlobalIPv6Address = env.Get("GlobalIPv6")
|
|
| 644 |
- container.NetworkSettings.GlobalIPv6PrefixLen = env.GetInt("GlobalIPv6PrefixLen")
|
|
| 645 |
- container.NetworkSettings.IPv6Gateway = env.Get("IPv6Gateway")
|
|
| 635 |
+ networkSettings.Ports = bindings |
|
| 636 |
+ container.NetworkSettings = networkSettings |
|
| 646 | 637 |
|
| 647 | 638 |
return nil |
| 648 | 639 |
} |
| ... | ... |
@@ -651,12 +639,10 @@ func (container *Container) ReleaseNetwork() {
|
| 651 | 651 |
if container.Config.NetworkDisabled || !container.hostConfig.NetworkMode.IsPrivate() {
|
| 652 | 652 |
return |
| 653 | 653 |
} |
| 654 |
- eng := container.daemon.eng |
|
| 655 | 654 |
|
| 656 |
- job := eng.Job("release_interface", container.ID)
|
|
| 657 |
- job.SetenvBool("overrideShutdown", true)
|
|
| 658 |
- job.Run() |
|
| 659 |
- container.NetworkSettings = &NetworkSettings{}
|
|
| 655 |
+ bridge.Release(container.ID) |
|
| 656 |
+ |
|
| 657 |
+ container.NetworkSettings = &network.Settings{}
|
|
| 660 | 658 |
} |
| 661 | 659 |
|
| 662 | 660 |
func (container *Container) isNetworkAllocated() bool {
|
| ... | ... |
@@ -675,10 +661,7 @@ func (container *Container) RestoreNetwork() error {
|
| 675 | 675 |
eng := container.daemon.eng |
| 676 | 676 |
|
| 677 | 677 |
// Re-allocate the interface with the same IP and MAC address. |
| 678 |
- job := eng.Job("allocate_interface", container.ID)
|
|
| 679 |
- job.Setenv("RequestedIP", container.NetworkSettings.IPAddress)
|
|
| 680 |
- job.Setenv("RequestedMac", container.NetworkSettings.MacAddress)
|
|
| 681 |
- if err := job.Run(); err != nil {
|
|
| 678 |
+ if _, err := bridge.Allocate(container.ID, container.NetworkSettings.MacAddress, container.NetworkSettings.IPAddress, ""); err != nil {
|
|
| 682 | 679 |
return err |
| 683 | 680 |
} |
| 684 | 681 |
|
| ... | ... |
@@ -1077,7 +1060,7 @@ func (container *Container) setupContainerDns() error {
|
| 1077 | 1077 |
latestResolvConf, latestHash := resolvconf.GetLastModified() |
| 1078 | 1078 |
|
| 1079 | 1079 |
// clean container resolv.conf re: localhost nameservers and IPv6 NS (if IPv6 disabled) |
| 1080 |
- updatedResolvConf, modified := resolvconf.FilterResolvDns(latestResolvConf, container.daemon.config.EnableIPv6) |
|
| 1080 |
+ updatedResolvConf, modified := resolvconf.FilterResolvDns(latestResolvConf, container.daemon.config.Bridge.EnableIPv6) |
|
| 1081 | 1081 |
if modified {
|
| 1082 | 1082 |
// changes have occurred during resolv.conf localhost cleanup: generate an updated hash |
| 1083 | 1083 |
newHash, err := utils.HashData(bytes.NewReader(updatedResolvConf)) |
| ... | ... |
@@ -1131,7 +1114,7 @@ func (container *Container) setupContainerDns() error {
|
| 1131 | 1131 |
} |
| 1132 | 1132 |
|
| 1133 | 1133 |
// replace any localhost/127.*, and remove IPv6 nameservers if IPv6 disabled in daemon |
| 1134 |
- resolvConf, _ = resolvconf.FilterResolvDns(resolvConf, daemon.config.EnableIPv6) |
|
| 1134 |
+ resolvConf, _ = resolvconf.FilterResolvDns(resolvConf, daemon.config.Bridge.EnableIPv6) |
|
| 1135 | 1135 |
} |
| 1136 | 1136 |
//get a sha256 hash of the resolv conf at this point so we can check |
| 1137 | 1137 |
//for changes when the host resolv.conf changes (e.g. network update) |
| ... | ... |
@@ -1481,24 +1464,10 @@ func (container *Container) allocatePort(eng *engine.Engine, port nat.Port, bind |
| 1481 | 1481 |
} |
| 1482 | 1482 |
|
| 1483 | 1483 |
for i := 0; i < len(binding); i++ {
|
| 1484 |
- b := binding[i] |
|
| 1485 |
- |
|
| 1486 |
- job := eng.Job("allocate_port", container.ID)
|
|
| 1487 |
- job.Setenv("HostIP", b.HostIp)
|
|
| 1488 |
- job.Setenv("HostPort", b.HostPort)
|
|
| 1489 |
- job.Setenv("Proto", port.Proto())
|
|
| 1490 |
- job.Setenv("ContainerPort", port.Port())
|
|
| 1491 |
- |
|
| 1492 |
- portEnv, err := job.Stdout.AddEnv() |
|
| 1484 |
+ b, err := bridge.AllocatePort(container.ID, port, binding[i]) |
|
| 1493 | 1485 |
if err != nil {
|
| 1494 | 1486 |
return err |
| 1495 | 1487 |
} |
| 1496 |
- if err := job.Run(); err != nil {
|
|
| 1497 |
- return err |
|
| 1498 |
- } |
|
| 1499 |
- b.HostIp = portEnv.Get("HostIP")
|
|
| 1500 |
- b.HostPort = portEnv.Get("HostPort")
|
|
| 1501 |
- |
|
| 1502 | 1488 |
binding[i] = b |
| 1503 | 1489 |
} |
| 1504 | 1490 |
bindings[port] = binding |
| ... | ... |
@@ -25,7 +25,8 @@ import ( |
| 25 | 25 |
"github.com/docker/docker/daemon/execdriver/lxc" |
| 26 | 26 |
"github.com/docker/docker/daemon/graphdriver" |
| 27 | 27 |
_ "github.com/docker/docker/daemon/graphdriver/vfs" |
| 28 |
- _ "github.com/docker/docker/daemon/networkdriver/bridge" |
|
| 28 |
+ "github.com/docker/docker/daemon/network" |
|
| 29 |
+ "github.com/docker/docker/daemon/networkdriver/bridge" |
|
| 29 | 30 |
"github.com/docker/docker/engine" |
| 30 | 31 |
"github.com/docker/docker/graph" |
| 31 | 32 |
"github.com/docker/docker/image" |
| ... | ... |
@@ -445,7 +446,7 @@ func (daemon *Daemon) setupResolvconfWatcher() error {
|
| 445 | 445 |
logrus.Debugf("Error retrieving updated host resolv.conf: %v", err)
|
| 446 | 446 |
} else if updatedResolvConf != nil {
|
| 447 | 447 |
// because the new host resolv.conf might have localhost nameservers.. |
| 448 |
- updatedResolvConf, modified := resolvconf.FilterResolvDns(updatedResolvConf, daemon.config.EnableIPv6) |
|
| 448 |
+ updatedResolvConf, modified := resolvconf.FilterResolvDns(updatedResolvConf, daemon.config.Bridge.EnableIPv6) |
|
| 449 | 449 |
if modified {
|
| 450 | 450 |
// changes have occurred during localhost cleanup: generate an updated hash |
| 451 | 451 |
newHash, err := utils.HashData(bytes.NewReader(updatedResolvConf)) |
| ... | ... |
@@ -653,7 +654,7 @@ func (daemon *Daemon) newContainer(name string, config *runconfig.Config, imgID |
| 653 | 653 |
Config: config, |
| 654 | 654 |
hostConfig: &runconfig.HostConfig{},
|
| 655 | 655 |
ImageID: imgID, |
| 656 |
- NetworkSettings: &NetworkSettings{},
|
|
| 656 |
+ NetworkSettings: &network.Settings{},
|
|
| 657 | 657 |
Name: name, |
| 658 | 658 |
Driver: daemon.driver.String(), |
| 659 | 659 |
ExecDriver: daemon.execDriver.Name(), |
| ... | ... |
@@ -807,16 +808,16 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine, registryService |
| 807 | 807 |
config.Mtu = getDefaultNetworkMtu() |
| 808 | 808 |
} |
| 809 | 809 |
// Check for mutually incompatible config options |
| 810 |
- if config.BridgeIface != "" && config.BridgeIP != "" {
|
|
| 810 |
+ if config.Bridge.Iface != "" && config.Bridge.IP != "" {
|
|
| 811 | 811 |
return nil, fmt.Errorf("You specified -b & --bip, mutually exclusive options. Please specify only one.")
|
| 812 | 812 |
} |
| 813 |
- if !config.EnableIptables && !config.InterContainerCommunication {
|
|
| 813 |
+ if !config.Bridge.EnableIptables && !config.Bridge.InterContainerCommunication {
|
|
| 814 | 814 |
return nil, fmt.Errorf("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.")
|
| 815 | 815 |
} |
| 816 |
- if !config.EnableIptables && config.EnableIpMasq {
|
|
| 817 |
- config.EnableIpMasq = false |
|
| 816 |
+ if !config.Bridge.EnableIptables && config.Bridge.EnableIpMasq {
|
|
| 817 |
+ config.Bridge.EnableIpMasq = false |
|
| 818 | 818 |
} |
| 819 |
- config.DisableNetwork = config.BridgeIface == disableNetworkBridge |
|
| 819 |
+ config.DisableNetwork = config.Bridge.Iface == disableNetworkBridge |
|
| 820 | 820 |
|
| 821 | 821 |
// Claim the pidfile first, to avoid any and all unexpected race conditions. |
| 822 | 822 |
// Some of the init doesn't need a pidfile lock - but let's not try to be smart. |
| ... | ... |
@@ -948,20 +949,7 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine, registryService |
| 948 | 948 |
} |
| 949 | 949 |
|
| 950 | 950 |
if !config.DisableNetwork {
|
| 951 |
- job := eng.Job("init_networkdriver")
|
|
| 952 |
- |
|
| 953 |
- job.SetenvBool("EnableIptables", config.EnableIptables)
|
|
| 954 |
- job.SetenvBool("InterContainerCommunication", config.InterContainerCommunication)
|
|
| 955 |
- job.SetenvBool("EnableIpForward", config.EnableIpForward)
|
|
| 956 |
- job.SetenvBool("EnableIpMasq", config.EnableIpMasq)
|
|
| 957 |
- job.SetenvBool("EnableIPv6", config.EnableIPv6)
|
|
| 958 |
- job.Setenv("BridgeIface", config.BridgeIface)
|
|
| 959 |
- job.Setenv("BridgeIP", config.BridgeIP)
|
|
| 960 |
- job.Setenv("FixedCIDR", config.FixedCIDR)
|
|
| 961 |
- job.Setenv("FixedCIDRv6", config.FixedCIDRv6)
|
|
| 962 |
- job.Setenv("DefaultBindingIP", config.DefaultIp.String())
|
|
| 963 |
- |
|
| 964 |
- if err := job.Run(); err != nil {
|
|
| 951 |
+ if err := bridge.InitDriver(&config.Bridge); err != nil {
|
|
| 965 | 952 |
return nil, err |
| 966 | 953 |
} |
| 967 | 954 |
} |
| 968 | 955 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,18 @@ |
| 0 |
+package network |
|
| 1 |
+ |
|
| 2 |
+import "github.com/docker/docker/nat" |
|
| 3 |
+ |
|
| 4 |
+type Settings struct {
|
|
| 5 |
+ IPAddress string |
|
| 6 |
+ IPPrefixLen int |
|
| 7 |
+ MacAddress string |
|
| 8 |
+ LinkLocalIPv6Address string |
|
| 9 |
+ LinkLocalIPv6PrefixLen int |
|
| 10 |
+ GlobalIPv6Address string |
|
| 11 |
+ GlobalIPv6PrefixLen int |
|
| 12 |
+ Gateway string |
|
| 13 |
+ IPv6Gateway string |
|
| 14 |
+ Bridge string |
|
| 15 |
+ PortMapping map[string]map[string]string // Deprecated |
|
| 16 |
+ Ports nat.PortMap |
|
| 17 |
+} |
| 0 | 18 |
deleted file mode 100644 |
| ... | ... |
@@ -1,23 +0,0 @@ |
| 1 |
-package daemon |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "github.com/docker/docker/nat" |
|
| 5 |
-) |
|
| 6 |
- |
|
| 7 |
-// FIXME: move deprecated port stuff to nat to clean up the core. |
|
| 8 |
-type PortMapping map[string]string // Deprecated |
|
| 9 |
- |
|
| 10 |
-type NetworkSettings struct {
|
|
| 11 |
- IPAddress string |
|
| 12 |
- IPPrefixLen int |
|
| 13 |
- MacAddress string |
|
| 14 |
- LinkLocalIPv6Address string |
|
| 15 |
- LinkLocalIPv6PrefixLen int |
|
| 16 |
- GlobalIPv6Address string |
|
| 17 |
- GlobalIPv6PrefixLen int |
|
| 18 |
- Gateway string |
|
| 19 |
- IPv6Gateway string |
|
| 20 |
- Bridge string |
|
| 21 |
- PortMapping map[string]PortMapping // Deprecated |
|
| 22 |
- Ports nat.PortMap |
|
| 23 |
-} |
| ... | ... |
@@ -7,14 +7,15 @@ import ( |
| 7 | 7 |
"io/ioutil" |
| 8 | 8 |
"net" |
| 9 | 9 |
"os" |
| 10 |
+ "strconv" |
|
| 10 | 11 |
"strings" |
| 11 | 12 |
"sync" |
| 12 | 13 |
|
| 13 | 14 |
"github.com/Sirupsen/logrus" |
| 15 |
+ "github.com/docker/docker/daemon/network" |
|
| 14 | 16 |
"github.com/docker/docker/daemon/networkdriver" |
| 15 | 17 |
"github.com/docker/docker/daemon/networkdriver/ipallocator" |
| 16 | 18 |
"github.com/docker/docker/daemon/networkdriver/portmapper" |
| 17 |
- "github.com/docker/docker/engine" |
|
| 18 | 19 |
"github.com/docker/docker/nat" |
| 19 | 20 |
"github.com/docker/docker/pkg/iptables" |
| 20 | 21 |
"github.com/docker/docker/pkg/parsers/kernel" |
| ... | ... |
@@ -91,29 +92,34 @@ func initPortMapper() {
|
| 91 | 91 |
}) |
| 92 | 92 |
} |
| 93 | 93 |
|
| 94 |
-func InitDriver(job *engine.Job) error {
|
|
| 94 |
+type Config struct {
|
|
| 95 |
+ EnableIPv6 bool |
|
| 96 |
+ EnableIptables bool |
|
| 97 |
+ EnableIpForward bool |
|
| 98 |
+ EnableIpMasq bool |
|
| 99 |
+ DefaultIp net.IP |
|
| 100 |
+ Iface string |
|
| 101 |
+ IP string |
|
| 102 |
+ FixedCIDR string |
|
| 103 |
+ FixedCIDRv6 string |
|
| 104 |
+ InterContainerCommunication bool |
|
| 105 |
+} |
|
| 106 |
+ |
|
| 107 |
+func InitDriver(config *Config) error {
|
|
| 95 | 108 |
var ( |
| 96 |
- networkv4 *net.IPNet |
|
| 97 |
- networkv6 *net.IPNet |
|
| 98 |
- addrv4 net.Addr |
|
| 99 |
- addrsv6 []net.Addr |
|
| 100 |
- enableIPTables = job.GetenvBool("EnableIptables")
|
|
| 101 |
- enableIPv6 = job.GetenvBool("EnableIPv6")
|
|
| 102 |
- icc = job.GetenvBool("InterContainerCommunication")
|
|
| 103 |
- ipMasq = job.GetenvBool("EnableIpMasq")
|
|
| 104 |
- ipForward = job.GetenvBool("EnableIpForward")
|
|
| 105 |
- bridgeIP = job.Getenv("BridgeIP")
|
|
| 106 |
- bridgeIPv6 = "fe80::1/64" |
|
| 107 |
- fixedCIDR = job.Getenv("FixedCIDR")
|
|
| 108 |
- fixedCIDRv6 = job.Getenv("FixedCIDRv6")
|
|
| 109 |
+ networkv4 *net.IPNet |
|
| 110 |
+ networkv6 *net.IPNet |
|
| 111 |
+ addrv4 net.Addr |
|
| 112 |
+ addrsv6 []net.Addr |
|
| 113 |
+ bridgeIPv6 = "fe80::1/64" |
|
| 109 | 114 |
) |
| 110 | 115 |
initPortMapper() |
| 111 | 116 |
|
| 112 |
- if defaultIP := job.Getenv("DefaultBindingIP"); defaultIP != "" {
|
|
| 113 |
- defaultBindingIP = net.ParseIP(defaultIP) |
|
| 117 |
+ if config.DefaultIp != nil {
|
|
| 118 |
+ defaultBindingIP = config.DefaultIp |
|
| 114 | 119 |
} |
| 115 | 120 |
|
| 116 |
- bridgeIface = job.Getenv("BridgeIface")
|
|
| 121 |
+ bridgeIface = config.Iface |
|
| 117 | 122 |
usingDefaultBridge := false |
| 118 | 123 |
if bridgeIface == "" {
|
| 119 | 124 |
usingDefaultBridge = true |
| ... | ... |
@@ -130,7 +136,7 @@ func InitDriver(job *engine.Job) error {
|
| 130 | 130 |
} |
| 131 | 131 |
|
| 132 | 132 |
// If the iface is not found, try to create it |
| 133 |
- if err := configureBridge(bridgeIP, bridgeIPv6, enableIPv6); err != nil {
|
|
| 133 |
+ if err := configureBridge(config.IP, bridgeIPv6, config.EnableIPv6); err != nil {
|
|
| 134 | 134 |
return err |
| 135 | 135 |
} |
| 136 | 136 |
|
| ... | ... |
@@ -139,19 +145,19 @@ func InitDriver(job *engine.Job) error {
|
| 139 | 139 |
return err |
| 140 | 140 |
} |
| 141 | 141 |
|
| 142 |
- if fixedCIDRv6 != "" {
|
|
| 142 |
+ if config.FixedCIDRv6 != "" {
|
|
| 143 | 143 |
// Setting route to global IPv6 subnet |
| 144 |
- logrus.Infof("Adding route to IPv6 network %q via device %q", fixedCIDRv6, bridgeIface)
|
|
| 145 |
- if err := netlink.AddRoute(fixedCIDRv6, "", "", bridgeIface); err != nil {
|
|
| 146 |
- logrus.Fatalf("Could not add route to IPv6 network %q via device %q", fixedCIDRv6, bridgeIface)
|
|
| 144 |
+ logrus.Infof("Adding route to IPv6 network %q via device %q", config.FixedCIDRv6, bridgeIface)
|
|
| 145 |
+ if err := netlink.AddRoute(config.FixedCIDRv6, "", "", bridgeIface); err != nil {
|
|
| 146 |
+ logrus.Fatalf("Could not add route to IPv6 network %q via device %q", config.FixedCIDRv6, bridgeIface)
|
|
| 147 | 147 |
} |
| 148 | 148 |
} |
| 149 | 149 |
} else {
|
| 150 | 150 |
// Bridge exists already, getting info... |
| 151 | 151 |
// Validate that the bridge ip matches the ip specified by BridgeIP |
| 152 |
- if bridgeIP != "" {
|
|
| 152 |
+ if config.IP != "" {
|
|
| 153 | 153 |
networkv4 = addrv4.(*net.IPNet) |
| 154 |
- bip, _, err := net.ParseCIDR(bridgeIP) |
|
| 154 |
+ bip, _, err := net.ParseCIDR(config.IP) |
|
| 155 | 155 |
if err != nil {
|
| 156 | 156 |
return err |
| 157 | 157 |
} |
| ... | ... |
@@ -164,7 +170,7 @@ func InitDriver(job *engine.Job) error {
|
| 164 | 164 |
// (for example, an existing Docker installation that has only been used |
| 165 | 165 |
// with IPv4 and docker0 already is set up) In that case, we can perform |
| 166 | 166 |
// the bridge init for IPv6 here, else we will error out below if --ipv6=true |
| 167 |
- if len(addrsv6) == 0 && enableIPv6 {
|
|
| 167 |
+ if len(addrsv6) == 0 && config.EnableIPv6 {
|
|
| 168 | 168 |
if err := setupIPv6Bridge(bridgeIPv6); err != nil {
|
| 169 | 169 |
return err |
| 170 | 170 |
} |
| ... | ... |
@@ -175,10 +181,10 @@ func InitDriver(job *engine.Job) error {
|
| 175 | 175 |
} |
| 176 | 176 |
} |
| 177 | 177 |
|
| 178 |
- // TODO: Check if route to fixedCIDRv6 is set |
|
| 178 |
+ // TODO: Check if route to config.FixedCIDRv6 is set |
|
| 179 | 179 |
} |
| 180 | 180 |
|
| 181 |
- if enableIPv6 {
|
|
| 181 |
+ if config.EnableIPv6 {
|
|
| 182 | 182 |
bip6, _, err := net.ParseCIDR(bridgeIPv6) |
| 183 | 183 |
if err != nil {
|
| 184 | 184 |
return err |
| ... | ... |
@@ -198,7 +204,7 @@ func InitDriver(job *engine.Job) error {
|
| 198 | 198 |
|
| 199 | 199 |
networkv4 = addrv4.(*net.IPNet) |
| 200 | 200 |
|
| 201 |
- if enableIPv6 {
|
|
| 201 |
+ if config.EnableIPv6 {
|
|
| 202 | 202 |
if len(addrsv6) == 0 {
|
| 203 | 203 |
return errors.New("IPv6 enabled but no IPv6 detected")
|
| 204 | 204 |
} |
| ... | ... |
@@ -206,20 +212,20 @@ func InitDriver(job *engine.Job) error {
|
| 206 | 206 |
} |
| 207 | 207 |
|
| 208 | 208 |
// Configure iptables for link support |
| 209 |
- if enableIPTables {
|
|
| 210 |
- if err := setupIPTables(addrv4, icc, ipMasq); err != nil {
|
|
| 209 |
+ if config.EnableIptables {
|
|
| 210 |
+ if err := setupIPTables(addrv4, config.InterContainerCommunication, config.EnableIpMasq); err != nil {
|
|
| 211 | 211 |
return err |
| 212 | 212 |
} |
| 213 | 213 |
|
| 214 | 214 |
} |
| 215 | 215 |
|
| 216 |
- if ipForward {
|
|
| 216 |
+ if config.EnableIpForward {
|
|
| 217 | 217 |
// Enable IPv4 forwarding |
| 218 | 218 |
if err := ioutil.WriteFile("/proc/sys/net/ipv4/ip_forward", []byte{'1', '\n'}, 0644); err != nil {
|
| 219 | 219 |
logrus.Warnf("WARNING: unable to enable IPv4 forwarding: %s\n", err)
|
| 220 | 220 |
} |
| 221 | 221 |
|
| 222 |
- if fixedCIDRv6 != "" {
|
|
| 222 |
+ if config.FixedCIDRv6 != "" {
|
|
| 223 | 223 |
// Enable IPv6 forwarding |
| 224 | 224 |
if err := ioutil.WriteFile("/proc/sys/net/ipv6/conf/default/forwarding", []byte{'1', '\n'}, 0644); err != nil {
|
| 225 | 225 |
logrus.Warnf("WARNING: unable to enable IPv6 default forwarding: %s\n", err)
|
| ... | ... |
@@ -235,7 +241,7 @@ func InitDriver(job *engine.Job) error {
|
| 235 | 235 |
return err |
| 236 | 236 |
} |
| 237 | 237 |
|
| 238 |
- if enableIPTables {
|
|
| 238 |
+ if config.EnableIptables {
|
|
| 239 | 239 |
_, err := iptables.NewChain("DOCKER", bridgeIface, iptables.Nat)
|
| 240 | 240 |
if err != nil {
|
| 241 | 241 |
return err |
| ... | ... |
@@ -248,8 +254,8 @@ func InitDriver(job *engine.Job) error {
|
| 248 | 248 |
} |
| 249 | 249 |
|
| 250 | 250 |
bridgeIPv4Network = networkv4 |
| 251 |
- if fixedCIDR != "" {
|
|
| 252 |
- _, subnet, err := net.ParseCIDR(fixedCIDR) |
|
| 251 |
+ if config.FixedCIDR != "" {
|
|
| 252 |
+ _, subnet, err := net.ParseCIDR(config.FixedCIDR) |
|
| 253 | 253 |
if err != nil {
|
| 254 | 254 |
return err |
| 255 | 255 |
} |
| ... | ... |
@@ -259,8 +265,8 @@ func InitDriver(job *engine.Job) error {
|
| 259 | 259 |
} |
| 260 | 260 |
} |
| 261 | 261 |
|
| 262 |
- if fixedCIDRv6 != "" {
|
|
| 263 |
- _, subnet, err := net.ParseCIDR(fixedCIDRv6) |
|
| 262 |
+ if config.FixedCIDRv6 != "" {
|
|
| 263 |
+ _, subnet, err := net.ParseCIDR(config.FixedCIDRv6) |
|
| 264 | 264 |
if err != nil {
|
| 265 | 265 |
return err |
| 266 | 266 |
} |
| ... | ... |
@@ -274,19 +280,6 @@ func InitDriver(job *engine.Job) error {
|
| 274 | 274 |
// Block BridgeIP in IP allocator |
| 275 | 275 |
ipAllocator.RequestIP(bridgeIPv4Network, bridgeIPv4Network.IP) |
| 276 | 276 |
|
| 277 |
- // https://github.com/docker/docker/issues/2768 |
|
| 278 |
- job.Eng.HackSetGlobalVar("httpapi.bridgeIP", bridgeIPv4Network.IP)
|
|
| 279 |
- |
|
| 280 |
- for name, f := range map[string]engine.Handler{
|
|
| 281 |
- "allocate_interface": Allocate, |
|
| 282 |
- "release_interface": Release, |
|
| 283 |
- "allocate_port": AllocatePort, |
|
| 284 |
- "link": LinkContainers, |
|
| 285 |
- } {
|
|
| 286 |
- if err := job.Eng.Register(name, f); err != nil {
|
|
| 287 |
- return err |
|
| 288 |
- } |
|
| 289 |
- } |
|
| 290 | 277 |
return nil |
| 291 | 278 |
} |
| 292 | 279 |
|
| ... | ... |
@@ -513,70 +506,67 @@ func linkLocalIPv6FromMac(mac string) (string, error) {
|
| 513 | 513 |
} |
| 514 | 514 |
|
| 515 | 515 |
// Allocate a network interface |
| 516 |
-func Allocate(job *engine.Job) error {
|
|
| 516 |
+func Allocate(id, requestedMac, requestedIP, requestedIPv6 string) (*network.Settings, error) {
|
|
| 517 | 517 |
var ( |
| 518 |
- ip net.IP |
|
| 519 |
- mac net.HardwareAddr |
|
| 520 |
- err error |
|
| 521 |
- id = job.Args[0] |
|
| 522 |
- requestedIP = net.ParseIP(job.Getenv("RequestedIP"))
|
|
| 523 |
- requestedIPv6 = net.ParseIP(job.Getenv("RequestedIPv6"))
|
|
| 524 |
- globalIPv6 net.IP |
|
| 518 |
+ ip net.IP |
|
| 519 |
+ mac net.HardwareAddr |
|
| 520 |
+ err error |
|
| 521 |
+ globalIPv6 net.IP |
|
| 525 | 522 |
) |
| 526 | 523 |
|
| 527 |
- ip, err = ipAllocator.RequestIP(bridgeIPv4Network, requestedIP) |
|
| 524 |
+ ip, err = ipAllocator.RequestIP(bridgeIPv4Network, net.ParseIP(requestedIP)) |
|
| 528 | 525 |
if err != nil {
|
| 529 |
- return err |
|
| 526 |
+ return nil, err |
|
| 530 | 527 |
} |
| 531 | 528 |
|
| 532 | 529 |
// If no explicit mac address was given, generate a random one. |
| 533 |
- if mac, err = net.ParseMAC(job.Getenv("RequestedMac")); err != nil {
|
|
| 530 |
+ if mac, err = net.ParseMAC(requestedMac); err != nil {
|
|
| 534 | 531 |
mac = generateMacAddr(ip) |
| 535 | 532 |
} |
| 536 | 533 |
|
| 537 | 534 |
if globalIPv6Network != nil {
|
| 538 | 535 |
// If globalIPv6Network Size is at least a /80 subnet generate IPv6 address from MAC address |
| 539 | 536 |
netmaskOnes, _ := globalIPv6Network.Mask.Size() |
| 540 |
- if requestedIPv6 == nil && netmaskOnes <= 80 {
|
|
| 541 |
- requestedIPv6 = make(net.IP, len(globalIPv6Network.IP)) |
|
| 542 |
- copy(requestedIPv6, globalIPv6Network.IP) |
|
| 537 |
+ ipv6 := net.ParseIP(requestedIPv6) |
|
| 538 |
+ if ipv6 == nil && netmaskOnes <= 80 {
|
|
| 539 |
+ ipv6 = make(net.IP, len(globalIPv6Network.IP)) |
|
| 540 |
+ copy(ipv6, globalIPv6Network.IP) |
|
| 543 | 541 |
for i, h := range mac {
|
| 544 |
- requestedIPv6[i+10] = h |
|
| 542 |
+ ipv6[i+10] = h |
|
| 545 | 543 |
} |
| 546 | 544 |
} |
| 547 | 545 |
|
| 548 |
- globalIPv6, err = ipAllocator.RequestIP(globalIPv6Network, requestedIPv6) |
|
| 546 |
+ globalIPv6, err = ipAllocator.RequestIP(globalIPv6Network, ipv6) |
|
| 549 | 547 |
if err != nil {
|
| 550 | 548 |
logrus.Errorf("Allocator: RequestIP v6: %v", err)
|
| 551 |
- return err |
|
| 549 |
+ return nil, err |
|
| 552 | 550 |
} |
| 553 | 551 |
logrus.Infof("Allocated IPv6 %s", globalIPv6)
|
| 554 | 552 |
} |
| 555 | 553 |
|
| 556 |
- out := engine.Env{}
|
|
| 557 |
- out.Set("IP", ip.String())
|
|
| 558 |
- out.Set("Mask", bridgeIPv4Network.Mask.String())
|
|
| 559 |
- out.Set("Gateway", bridgeIPv4Network.IP.String())
|
|
| 560 |
- out.Set("MacAddress", mac.String())
|
|
| 561 |
- out.Set("Bridge", bridgeIface)
|
|
| 562 |
- |
|
| 563 |
- size, _ := bridgeIPv4Network.Mask.Size() |
|
| 564 |
- out.SetInt("IPPrefixLen", size)
|
|
| 554 |
+ maskSize, _ := bridgeIPv4Network.Mask.Size() |
|
| 565 | 555 |
|
| 566 | 556 |
// If linklocal IPv6 |
| 567 | 557 |
localIPv6Net, err := linkLocalIPv6FromMac(mac.String()) |
| 568 | 558 |
if err != nil {
|
| 569 |
- return err |
|
| 559 |
+ return nil, err |
|
| 570 | 560 |
} |
| 571 | 561 |
localIPv6, _, _ := net.ParseCIDR(localIPv6Net) |
| 572 |
- out.Set("LinkLocalIPv6", localIPv6.String())
|
|
| 573 |
- out.Set("MacAddress", mac.String())
|
|
| 562 |
+ |
|
| 563 |
+ networkSettings := &network.Settings{
|
|
| 564 |
+ IPAddress: ip.String(), |
|
| 565 |
+ Gateway: bridgeIPv4Network.IP.String(), |
|
| 566 |
+ MacAddress: mac.String(), |
|
| 567 |
+ Bridge: bridgeIface, |
|
| 568 |
+ IPPrefixLen: maskSize, |
|
| 569 |
+ LinkLocalIPv6Address: localIPv6.String(), |
|
| 570 |
+ } |
|
| 574 | 571 |
|
| 575 | 572 |
if globalIPv6Network != nil {
|
| 576 |
- out.Set("GlobalIPv6", globalIPv6.String())
|
|
| 577 |
- sizev6, _ := globalIPv6Network.Mask.Size() |
|
| 578 |
- out.SetInt("GlobalIPv6PrefixLen", sizev6)
|
|
| 579 |
- out.Set("IPv6Gateway", bridgeIPv6Addr.String())
|
|
| 573 |
+ networkSettings.GlobalIPv6Address = globalIPv6.String() |
|
| 574 |
+ maskV6Size, _ := globalIPv6Network.Mask.Size() |
|
| 575 |
+ networkSettings.GlobalIPv6PrefixLen = maskV6Size |
|
| 576 |
+ networkSettings.IPv6Gateway = bridgeIPv6Addr.String() |
|
| 580 | 577 |
} |
| 581 | 578 |
|
| 582 | 579 |
currentInterfaces.Set(id, &networkInterface{
|
| ... | ... |
@@ -584,20 +574,15 @@ func Allocate(job *engine.Job) error {
|
| 584 | 584 |
IPv6: globalIPv6, |
| 585 | 585 |
}) |
| 586 | 586 |
|
| 587 |
- out.WriteTo(job.Stdout) |
|
| 588 |
- |
|
| 589 |
- return nil |
|
| 587 |
+ return networkSettings, nil |
|
| 590 | 588 |
} |
| 591 | 589 |
|
| 592 | 590 |
// Release an interface for a select ip |
| 593 |
-func Release(job *engine.Job) error {
|
|
| 594 |
- var ( |
|
| 595 |
- id = job.Args[0] |
|
| 596 |
- containerInterface = currentInterfaces.Get(id) |
|
| 597 |
- ) |
|
| 591 |
+func Release(id string) {
|
|
| 592 |
+ var containerInterface = currentInterfaces.Get(id) |
|
| 598 | 593 |
|
| 599 | 594 |
if containerInterface == nil {
|
| 600 |
- return fmt.Errorf("No network information to release for %s", id)
|
|
| 595 |
+ logrus.Warnf("No network information to release for %s", id)
|
|
| 601 | 596 |
} |
| 602 | 597 |
|
| 603 | 598 |
for _, nat := range containerInterface.PortMappings {
|
| ... | ... |
@@ -614,27 +599,21 @@ func Release(job *engine.Job) error {
|
| 614 | 614 |
logrus.Infof("Unable to release IPv6 %s", err)
|
| 615 | 615 |
} |
| 616 | 616 |
} |
| 617 |
- return nil |
|
| 618 | 617 |
} |
| 619 | 618 |
|
| 620 | 619 |
// Allocate an external port and map it to the interface |
| 621 |
-func AllocatePort(job *engine.Job) error {
|
|
| 620 |
+func AllocatePort(id string, port nat.Port, binding nat.PortBinding) (nat.PortBinding, error) {
|
|
| 622 | 621 |
var ( |
| 623 |
- err error |
|
| 624 |
- |
|
| 625 | 622 |
ip = defaultBindingIP |
| 626 |
- id = job.Args[0] |
|
| 627 |
- hostIP = job.Getenv("HostIP")
|
|
| 628 |
- hostPort = job.GetenvInt("HostPort")
|
|
| 629 |
- containerPort = job.GetenvInt("ContainerPort")
|
|
| 630 |
- proto = job.Getenv("Proto")
|
|
| 623 |
+ proto = port.Proto() |
|
| 624 |
+ containerPort = port.Int() |
|
| 631 | 625 |
network = currentInterfaces.Get(id) |
| 632 | 626 |
) |
| 633 | 627 |
|
| 634 |
- if hostIP != "" {
|
|
| 635 |
- ip = net.ParseIP(hostIP) |
|
| 628 |
+ if binding.HostIp != "" {
|
|
| 629 |
+ ip = net.ParseIP(binding.HostIp) |
|
| 636 | 630 |
if ip == nil {
|
| 637 |
- return fmt.Errorf("Bad parameter: invalid host ip %s", hostIP)
|
|
| 631 |
+ return nat.PortBinding{}, fmt.Errorf("Bad parameter: invalid host ip %s", binding.HostIp)
|
|
| 638 | 632 |
} |
| 639 | 633 |
} |
| 640 | 634 |
|
| ... | ... |
@@ -646,7 +625,7 @@ func AllocatePort(job *engine.Job) error {
|
| 646 | 646 |
case "udp": |
| 647 | 647 |
container = &net.UDPAddr{IP: network.IP, Port: containerPort}
|
| 648 | 648 |
default: |
| 649 |
- return fmt.Errorf("unsupported address type %s", proto)
|
|
| 649 |
+ return nat.PortBinding{}, fmt.Errorf("unsupported address type %s", proto)
|
|
| 650 | 650 |
} |
| 651 | 651 |
|
| 652 | 652 |
// |
| ... | ... |
@@ -656,7 +635,14 @@ func AllocatePort(job *engine.Job) error {
|
| 656 | 656 |
// yields. |
| 657 | 657 |
// |
| 658 | 658 |
|
| 659 |
- var host net.Addr |
|
| 659 |
+ var ( |
|
| 660 |
+ host net.Addr |
|
| 661 |
+ err error |
|
| 662 |
+ ) |
|
| 663 |
+ hostPort, err := nat.ParsePort(binding.HostPort) |
|
| 664 |
+ if err != nil {
|
|
| 665 |
+ return nat.PortBinding{}, err
|
|
| 666 |
+ } |
|
| 660 | 667 |
for i := 0; i < MaxAllocatedPortAttempts; i++ {
|
| 661 | 668 |
if host, err = portMapper.Map(container, ip, hostPort); err == nil {
|
| 662 | 669 |
break |
| ... | ... |
@@ -671,36 +657,24 @@ func AllocatePort(job *engine.Job) error {
|
| 671 | 671 |
} |
| 672 | 672 |
|
| 673 | 673 |
if err != nil {
|
| 674 |
- return err |
|
| 674 |
+ return nat.PortBinding{}, err
|
|
| 675 | 675 |
} |
| 676 | 676 |
|
| 677 | 677 |
network.PortMappings = append(network.PortMappings, host) |
| 678 | 678 |
|
| 679 |
- out := engine.Env{}
|
|
| 680 | 679 |
switch netAddr := host.(type) {
|
| 681 | 680 |
case *net.TCPAddr: |
| 682 |
- out.Set("HostIP", netAddr.IP.String())
|
|
| 683 |
- out.SetInt("HostPort", netAddr.Port)
|
|
| 681 |
+ return nat.PortBinding{HostIp: netAddr.IP.String(), HostPort: strconv.Itoa(netAddr.Port)}, nil
|
|
| 684 | 682 |
case *net.UDPAddr: |
| 685 |
- out.Set("HostIP", netAddr.IP.String())
|
|
| 686 |
- out.SetInt("HostPort", netAddr.Port)
|
|
| 687 |
- } |
|
| 688 |
- if _, err := out.WriteTo(job.Stdout); err != nil {
|
|
| 689 |
- return err |
|
| 683 |
+ return nat.PortBinding{HostIp: netAddr.IP.String(), HostPort: strconv.Itoa(netAddr.Port)}, nil
|
|
| 684 |
+ default: |
|
| 685 |
+ return nat.PortBinding{}, fmt.Errorf("unsupported address type %T", netAddr)
|
|
| 690 | 686 |
} |
| 691 |
- |
|
| 692 |
- return nil |
|
| 693 | 687 |
} |
| 694 | 688 |
|
| 695 |
-func LinkContainers(job *engine.Job) error {
|
|
| 696 |
- var ( |
|
| 697 |
- action = job.Args[0] |
|
| 698 |
- nfAction iptables.Action |
|
| 699 |
- childIP = job.Getenv("ChildIP")
|
|
| 700 |
- parentIP = job.Getenv("ParentIP")
|
|
| 701 |
- ignoreErrors = job.GetenvBool("IgnoreErrors")
|
|
| 702 |
- ports = job.GetenvList("Ports")
|
|
| 703 |
- ) |
|
| 689 |
+//TODO: should it return something more than just an error? |
|
| 690 |
+func LinkContainers(action, parentIP, childIP string, ports []nat.Port, ignoreErrors bool) error {
|
|
| 691 |
+ var nfAction iptables.Action |
|
| 704 | 692 |
|
| 705 | 693 |
switch action {
|
| 706 | 694 |
case "-A": |
| ... | ... |
@@ -723,8 +697,7 @@ func LinkContainers(job *engine.Job) error {
|
| 723 | 723 |
} |
| 724 | 724 |
|
| 725 | 725 |
chain := iptables.Chain{Name: "DOCKER", Bridge: bridgeIface}
|
| 726 |
- for _, p := range ports {
|
|
| 727 |
- port := nat.Port(p) |
|
| 726 |
+ for _, port := range ports {
|
|
| 728 | 727 |
if err := chain.Link(nfAction, ip1, ip2, port.Int(), port.Proto()); !ignoreErrors && err != nil {
|
| 729 | 728 |
return err |
| 730 | 729 |
} |
| ... | ... |
@@ -6,8 +6,9 @@ import ( |
| 6 | 6 |
"strconv" |
| 7 | 7 |
"testing" |
| 8 | 8 |
|
| 9 |
+ "github.com/docker/docker/daemon/network" |
|
| 9 | 10 |
"github.com/docker/docker/daemon/networkdriver/portmapper" |
| 10 |
- "github.com/docker/docker/engine" |
|
| 11 |
+ "github.com/docker/docker/nat" |
|
| 11 | 12 |
"github.com/docker/docker/pkg/iptables" |
| 12 | 13 |
) |
| 13 | 14 |
|
| ... | ... |
@@ -16,7 +17,7 @@ func init() {
|
| 16 | 16 |
portmapper.NewProxy = portmapper.NewMockProxyCommand |
| 17 | 17 |
} |
| 18 | 18 |
|
| 19 |
-func findFreePort(t *testing.T) int {
|
|
| 19 |
+func findFreePort(t *testing.T) string {
|
|
| 20 | 20 |
l, err := net.Listen("tcp", ":0")
|
| 21 | 21 |
if err != nil {
|
| 22 | 22 |
t.Fatal("Failed to find a free port")
|
| ... | ... |
@@ -27,143 +28,85 @@ func findFreePort(t *testing.T) int {
|
| 27 | 27 |
if err != nil {
|
| 28 | 28 |
t.Fatal("Failed to resolve address to identify free port")
|
| 29 | 29 |
} |
| 30 |
- return result.Port |
|
| 31 |
-} |
|
| 32 |
- |
|
| 33 |
-func newPortAllocationJob(eng *engine.Engine, port int) (job *engine.Job) {
|
|
| 34 |
- strPort := strconv.Itoa(port) |
|
| 35 |
- |
|
| 36 |
- job = eng.Job("allocate_port", "container_id")
|
|
| 37 |
- job.Setenv("HostIP", "127.0.0.1")
|
|
| 38 |
- job.Setenv("HostPort", strPort)
|
|
| 39 |
- job.Setenv("Proto", "tcp")
|
|
| 40 |
- job.Setenv("ContainerPort", strPort)
|
|
| 41 |
- return |
|
| 42 |
-} |
|
| 43 |
- |
|
| 44 |
-func newPortAllocationJobWithInvalidHostIP(eng *engine.Engine, port int) (job *engine.Job) {
|
|
| 45 |
- strPort := strconv.Itoa(port) |
|
| 46 |
- |
|
| 47 |
- job = eng.Job("allocate_port", "container_id")
|
|
| 48 |
- job.Setenv("HostIP", "localhost")
|
|
| 49 |
- job.Setenv("HostPort", strPort)
|
|
| 50 |
- job.Setenv("Proto", "tcp")
|
|
| 51 |
- job.Setenv("ContainerPort", strPort)
|
|
| 52 |
- return |
|
| 30 |
+ return strconv.Itoa(result.Port) |
|
| 53 | 31 |
} |
| 54 | 32 |
|
| 55 | 33 |
func TestAllocatePortDetection(t *testing.T) {
|
| 56 |
- eng := engine.New() |
|
| 57 |
- eng.Logging = false |
|
| 58 |
- |
|
| 59 | 34 |
freePort := findFreePort(t) |
| 60 | 35 |
|
| 61 |
- // Init driver |
|
| 62 |
- job := eng.Job("initdriver")
|
|
| 63 |
- if res := InitDriver(job); res != nil {
|
|
| 36 |
+ if err := InitDriver(new(Config)); err != nil {
|
|
| 64 | 37 |
t.Fatal("Failed to initialize network driver")
|
| 65 | 38 |
} |
| 66 | 39 |
|
| 67 | 40 |
// Allocate interface |
| 68 |
- job = eng.Job("allocate_interface", "container_id")
|
|
| 69 |
- if res := Allocate(job); res != nil {
|
|
| 41 |
+ if _, err := Allocate("container_id", "", "", ""); err != nil {
|
|
| 70 | 42 |
t.Fatal("Failed to allocate network interface")
|
| 71 | 43 |
} |
| 72 | 44 |
|
| 45 |
+ port := nat.Port(freePort + "/tcp") |
|
| 46 |
+ binding := nat.PortBinding{HostIp: "127.0.0.1", HostPort: freePort}
|
|
| 47 |
+ |
|
| 73 | 48 |
// Allocate same port twice, expect failure on second call |
| 74 |
- job = newPortAllocationJob(eng, freePort) |
|
| 75 |
- if res := AllocatePort(job); res != nil {
|
|
| 49 |
+ if _, err := AllocatePort("container_id", port, binding); err != nil {
|
|
| 76 | 50 |
t.Fatal("Failed to find a free port to allocate")
|
| 77 | 51 |
} |
| 78 |
- if res := AllocatePort(job); res == nil {
|
|
| 52 |
+ if _, err := AllocatePort("container_id", port, binding); err == nil {
|
|
| 79 | 53 |
t.Fatal("Duplicate port allocation granted by AllocatePort")
|
| 80 | 54 |
} |
| 81 | 55 |
} |
| 82 | 56 |
|
| 83 | 57 |
func TestHostnameFormatChecking(t *testing.T) {
|
| 84 |
- eng := engine.New() |
|
| 85 |
- eng.Logging = false |
|
| 86 |
- |
|
| 87 | 58 |
freePort := findFreePort(t) |
| 88 | 59 |
|
| 89 |
- // Init driver |
|
| 90 |
- job := eng.Job("initdriver")
|
|
| 91 |
- if res := InitDriver(job); res != nil {
|
|
| 60 |
+ if err := InitDriver(new(Config)); err != nil {
|
|
| 92 | 61 |
t.Fatal("Failed to initialize network driver")
|
| 93 | 62 |
} |
| 94 | 63 |
|
| 95 | 64 |
// Allocate interface |
| 96 |
- job = eng.Job("allocate_interface", "container_id")
|
|
| 97 |
- if res := Allocate(job); res != nil {
|
|
| 65 |
+ if _, err := Allocate("container_id", "", "", ""); err != nil {
|
|
| 98 | 66 |
t.Fatal("Failed to allocate network interface")
|
| 99 | 67 |
} |
| 100 | 68 |
|
| 101 |
- // Allocate port with invalid HostIP, expect failure with Bad Request http status |
|
| 102 |
- job = newPortAllocationJobWithInvalidHostIP(eng, freePort) |
|
| 103 |
- if res := AllocatePort(job); res == nil {
|
|
| 69 |
+ port := nat.Port(freePort + "/tcp") |
|
| 70 |
+ binding := nat.PortBinding{HostIp: "localhost", HostPort: freePort}
|
|
| 71 |
+ |
|
| 72 |
+ if _, err := AllocatePort("container_id", port, binding); err == nil {
|
|
| 104 | 73 |
t.Fatal("Failed to check invalid HostIP")
|
| 105 | 74 |
} |
| 106 | 75 |
} |
| 107 | 76 |
|
| 108 |
-func newInterfaceAllocation(t *testing.T, input engine.Env) (output engine.Env) {
|
|
| 109 |
- eng := engine.New() |
|
| 110 |
- eng.Logging = false |
|
| 111 |
- |
|
| 112 |
- done := make(chan bool) |
|
| 113 |
- |
|
| 77 |
+func newInterfaceAllocation(t *testing.T, globalIPv6 *net.IPNet, requestedMac, requestedIP, requestedIPv6 string, expectFail bool) *network.Settings {
|
|
| 114 | 78 |
// set IPv6 global if given |
| 115 |
- if input.Exists("globalIPv6Network") {
|
|
| 116 |
- _, globalIPv6Network, _ = net.ParseCIDR(input.Get("globalIPv6Network"))
|
|
| 79 |
+ if globalIPv6 != nil {
|
|
| 80 |
+ globalIPv6Network = globalIPv6 |
|
| 117 | 81 |
} |
| 118 | 82 |
|
| 119 |
- job := eng.Job("allocate_interface", "container_id")
|
|
| 120 |
- job.Env().Init(&input) |
|
| 121 |
- reader, _ := job.Stdout.AddPipe() |
|
| 122 |
- go func() {
|
|
| 123 |
- output.Decode(reader) |
|
| 124 |
- done <- true |
|
| 125 |
- }() |
|
| 126 |
- |
|
| 127 |
- res := Allocate(job) |
|
| 128 |
- job.Stdout.Close() |
|
| 129 |
- <-done |
|
| 130 |
- |
|
| 131 |
- if input.Exists("expectFail") && input.GetBool("expectFail") {
|
|
| 132 |
- if res == nil {
|
|
| 133 |
- t.Fatal("Doesn't fail to allocate network interface")
|
|
| 134 |
- } |
|
| 135 |
- } else {
|
|
| 136 |
- if res != nil {
|
|
| 137 |
- t.Fatal("Failed to allocate network interface")
|
|
| 138 |
- } |
|
| 83 |
+ networkSettings, err := Allocate("container_id", requestedMac, requestedIP, requestedIPv6)
|
|
| 84 |
+ if err == nil && expectFail {
|
|
| 85 |
+ t.Fatal("Doesn't fail to allocate network interface")
|
|
| 86 |
+ } else if err != nil && !expectFail {
|
|
| 87 |
+ t.Fatal("Failed to allocate network interface")
|
|
| 88 |
+ |
|
| 139 | 89 |
} |
| 140 | 90 |
|
| 141 |
- if input.Exists("globalIPv6Network") {
|
|
| 91 |
+ if globalIPv6 != nil {
|
|
| 142 | 92 |
// check for bug #11427 |
| 143 |
- _, subnet, _ := net.ParseCIDR(input.Get("globalIPv6Network"))
|
|
| 144 |
- if globalIPv6Network.IP.String() != subnet.IP.String() {
|
|
| 93 |
+ if globalIPv6Network.IP.String() != globalIPv6.IP.String() {
|
|
| 145 | 94 |
t.Fatal("globalIPv6Network was modified during allocation")
|
| 146 | 95 |
} |
| 147 | 96 |
// clean up IPv6 global |
| 148 | 97 |
globalIPv6Network = nil |
| 149 | 98 |
} |
| 150 | 99 |
|
| 151 |
- return |
|
| 100 |
+ return networkSettings |
|
| 152 | 101 |
} |
| 153 | 102 |
|
| 154 | 103 |
func TestIPv6InterfaceAllocationAutoNetmaskGt80(t *testing.T) {
|
| 155 |
- |
|
| 156 |
- input := engine.Env{}
|
|
| 157 |
- |
|
| 158 | 104 |
_, subnet, _ := net.ParseCIDR("2001:db8:1234:1234:1234::/81")
|
| 159 |
- |
|
| 160 |
- // set global ipv6 |
|
| 161 |
- input.Set("globalIPv6Network", subnet.String())
|
|
| 162 |
- |
|
| 163 |
- output := newInterfaceAllocation(t, input) |
|
| 105 |
+ networkSettings := newInterfaceAllocation(t, subnet, "", "", "", false) |
|
| 164 | 106 |
|
| 165 | 107 |
// ensure low manually assigend global ip |
| 166 |
- ip := net.ParseIP(output.Get("GlobalIPv6"))
|
|
| 108 |
+ ip := net.ParseIP(networkSettings.GlobalIPv6Address) |
|
| 167 | 109 |
_, subnet, _ = net.ParseCIDR(fmt.Sprintf("%s/%d", subnet.IP.String(), 120))
|
| 168 | 110 |
if !subnet.Contains(ip) {
|
| 169 | 111 |
t.Fatalf("Error ip %s not in subnet %s", ip.String(), subnet.String())
|
| ... | ... |
@@ -171,26 +114,18 @@ func TestIPv6InterfaceAllocationAutoNetmaskGt80(t *testing.T) {
|
| 171 | 171 |
} |
| 172 | 172 |
|
| 173 | 173 |
func TestIPv6InterfaceAllocationAutoNetmaskLe80(t *testing.T) {
|
| 174 |
- |
|
| 175 |
- input := engine.Env{}
|
|
| 176 |
- |
|
| 177 | 174 |
_, subnet, _ := net.ParseCIDR("2001:db8:1234:1234:1234::/80")
|
| 178 |
- |
|
| 179 |
- // set global ipv6 |
|
| 180 |
- input.Set("globalIPv6Network", subnet.String())
|
|
| 181 |
- input.Set("RequestedMac", "ab:cd:ab:cd:ab:cd")
|
|
| 182 |
- |
|
| 183 |
- output := newInterfaceAllocation(t, input) |
|
| 175 |
+ networkSettings := newInterfaceAllocation(t, subnet, "ab:cd:ab:cd:ab:cd", "", "", false) |
|
| 184 | 176 |
|
| 185 | 177 |
// ensure global ip with mac |
| 186 |
- ip := net.ParseIP(output.Get("GlobalIPv6"))
|
|
| 178 |
+ ip := net.ParseIP(networkSettings.GlobalIPv6Address) |
|
| 187 | 179 |
expectedIP := net.ParseIP("2001:db8:1234:1234:1234:abcd:abcd:abcd")
|
| 188 | 180 |
if ip.String() != expectedIP.String() {
|
| 189 | 181 |
t.Fatalf("Error ip %s should be %s", ip.String(), expectedIP.String())
|
| 190 | 182 |
} |
| 191 | 183 |
|
| 192 | 184 |
// ensure link local format |
| 193 |
- ip = net.ParseIP(output.Get("LinkLocalIPv6"))
|
|
| 185 |
+ ip = net.ParseIP(networkSettings.LinkLocalIPv6Address) |
|
| 194 | 186 |
expectedIP = net.ParseIP("fe80::a9cd:abff:fecd:abcd")
|
| 195 | 187 |
if ip.String() != expectedIP.String() {
|
| 196 | 188 |
t.Fatalf("Error ip %s should be %s", ip.String(), expectedIP.String())
|
| ... | ... |
@@ -199,27 +134,19 @@ func TestIPv6InterfaceAllocationAutoNetmaskLe80(t *testing.T) {
|
| 199 | 199 |
} |
| 200 | 200 |
|
| 201 | 201 |
func TestIPv6InterfaceAllocationRequest(t *testing.T) {
|
| 202 |
- |
|
| 203 |
- input := engine.Env{}
|
|
| 204 |
- |
|
| 205 | 202 |
_, subnet, _ := net.ParseCIDR("2001:db8:1234:1234:1234::/80")
|
| 206 |
- expectedIP := net.ParseIP("2001:db8:1234:1234:1234::1328")
|
|
| 207 |
- |
|
| 208 |
- // set global ipv6 |
|
| 209 |
- input.Set("globalIPv6Network", subnet.String())
|
|
| 210 |
- input.Set("RequestedIPv6", expectedIP.String())
|
|
| 203 |
+ expectedIP := "2001:db8:1234:1234:1234::1328" |
|
| 211 | 204 |
|
| 212 |
- output := newInterfaceAllocation(t, input) |
|
| 205 |
+ networkSettings := newInterfaceAllocation(t, subnet, "", "", expectedIP, false) |
|
| 213 | 206 |
|
| 214 | 207 |
// ensure global ip with mac |
| 215 |
- ip := net.ParseIP(output.Get("GlobalIPv6"))
|
|
| 216 |
- if ip.String() != expectedIP.String() {
|
|
| 217 |
- t.Fatalf("Error ip %s should be %s", ip.String(), expectedIP.String())
|
|
| 208 |
+ ip := net.ParseIP(networkSettings.GlobalIPv6Address) |
|
| 209 |
+ if ip.String() != expectedIP {
|
|
| 210 |
+ t.Fatalf("Error ip %s should be %s", ip.String(), expectedIP)
|
|
| 218 | 211 |
} |
| 219 | 212 |
|
| 220 | 213 |
// retry -> fails for duplicated address |
| 221 |
- input.SetBool("expectFail", true)
|
|
| 222 |
- output = newInterfaceAllocation(t, input) |
|
| 214 |
+ _ = newInterfaceAllocation(t, subnet, "", "", expectedIP, true) |
|
| 223 | 215 |
} |
| 224 | 216 |
|
| 225 | 217 |
func TestMacAddrGeneration(t *testing.T) {
|
| ... | ... |
@@ -239,40 +166,27 @@ func TestMacAddrGeneration(t *testing.T) {
|
| 239 | 239 |
} |
| 240 | 240 |
|
| 241 | 241 |
func TestLinkContainers(t *testing.T) {
|
| 242 |
- eng := engine.New() |
|
| 243 |
- eng.Logging = false |
|
| 244 |
- |
|
| 245 | 242 |
// Init driver |
| 246 |
- job := eng.Job("initdriver")
|
|
| 247 |
- if res := InitDriver(job); res != nil {
|
|
| 243 |
+ if err := InitDriver(new(Config)); err != nil {
|
|
| 248 | 244 |
t.Fatal("Failed to initialize network driver")
|
| 249 | 245 |
} |
| 250 | 246 |
|
| 251 | 247 |
// Allocate interface |
| 252 |
- job = eng.Job("allocate_interface", "container_id")
|
|
| 253 |
- if res := Allocate(job); res != nil {
|
|
| 248 |
+ if _, err := Allocate("container_id", "", "", ""); err != nil {
|
|
| 254 | 249 |
t.Fatal("Failed to allocate network interface")
|
| 255 | 250 |
} |
| 256 | 251 |
|
| 257 |
- job.Args[0] = "-I" |
|
| 258 |
- |
|
| 259 |
- job.Setenv("ChildIP", "172.17.0.2")
|
|
| 260 |
- job.Setenv("ParentIP", "172.17.0.1")
|
|
| 261 |
- job.SetenvBool("IgnoreErrors", false)
|
|
| 262 |
- job.SetenvList("Ports", []string{"1234"})
|
|
| 263 |
- |
|
| 264 | 252 |
bridgeIface = "lo" |
| 265 |
- _, err := iptables.NewChain("DOCKER", bridgeIface, iptables.Filter)
|
|
| 266 |
- if err != nil {
|
|
| 253 |
+ if _, err := iptables.NewChain("DOCKER", bridgeIface, iptables.Filter); err != nil {
|
|
| 267 | 254 |
t.Fatal(err) |
| 268 | 255 |
} |
| 269 | 256 |
|
| 270 |
- if res := LinkContainers(job); res != nil {
|
|
| 271 |
- t.Fatalf("LinkContainers failed")
|
|
| 257 |
+ if err := LinkContainers("-I", "172.17.0.1", "172.17.0.2", []nat.Port{nat.Port("1234")}, false); err != nil {
|
|
| 258 |
+ t.Fatal("LinkContainers failed")
|
|
| 272 | 259 |
} |
| 273 | 260 |
|
| 274 | 261 |
// flush rules |
| 275 |
- if _, err = iptables.Raw([]string{"-F", "DOCKER"}...); err != nil {
|
|
| 262 |
+ if _, err := iptables.Raw([]string{"-F", "DOCKER"}...); err != nil {
|
|
| 276 | 263 |
t.Fatal(err) |
| 277 | 264 |
} |
| 278 | 265 |
|
| ... | ... |
@@ -18,6 +18,7 @@ import ( |
| 18 | 18 |
|
| 19 | 19 |
"github.com/docker/docker/builtins" |
| 20 | 20 |
"github.com/docker/docker/daemon" |
| 21 |
+ "github.com/docker/docker/daemon/networkdriver/bridge" |
|
| 21 | 22 |
"github.com/docker/docker/engine" |
| 22 | 23 |
flag "github.com/docker/docker/pkg/mflag" |
| 23 | 24 |
"github.com/docker/docker/registry" |
| ... | ... |
@@ -185,9 +186,11 @@ func newTestEngine(t Fataler, autorestart bool, root string) *engine.Engine {
|
| 185 | 185 |
ExecDriver: "native", |
| 186 | 186 |
// Either InterContainerCommunication or EnableIptables must be set, |
| 187 | 187 |
// otherwise NewDaemon will fail because of conflicting settings. |
| 188 |
- InterContainerCommunication: true, |
|
| 189 |
- TrustKeyPath: filepath.Join(root, "key.json"), |
|
| 190 |
- LogConfig: runconfig.LogConfig{Type: "json-file"},
|
|
| 188 |
+ Bridge: bridge.Config{
|
|
| 189 |
+ InterContainerCommunication: true, |
|
| 190 |
+ }, |
|
| 191 |
+ TrustKeyPath: filepath.Join(root, "key.json"), |
|
| 192 |
+ LogConfig: runconfig.LogConfig{Type: "json-file"},
|
|
| 191 | 193 |
} |
| 192 | 194 |
d, err := daemon.NewDaemon(cfg, eng, registry.NewService(nil)) |
| 193 | 195 |
if err != nil {
|
| ... | ... |
@@ -2,10 +2,12 @@ package links |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 |
- "github.com/docker/docker/engine" |
|
| 6 |
- "github.com/docker/docker/nat" |
|
| 7 | 5 |
"path" |
| 8 | 6 |
"strings" |
| 7 |
+ |
|
| 8 |
+ "github.com/docker/docker/daemon/networkdriver/bridge" |
|
| 9 |
+ "github.com/docker/docker/engine" |
|
| 10 |
+ "github.com/docker/docker/nat" |
|
| 9 | 11 |
) |
| 10 | 12 |
|
| 11 | 13 |
type Link struct {
|
| ... | ... |
@@ -158,21 +160,5 @@ func (l *Link) Disable() {
|
| 158 | 158 |
} |
| 159 | 159 |
|
| 160 | 160 |
func (l *Link) toggle(action string, ignoreErrors bool) error {
|
| 161 |
- job := l.eng.Job("link", action)
|
|
| 162 |
- |
|
| 163 |
- job.Setenv("ParentIP", l.ParentIP)
|
|
| 164 |
- job.Setenv("ChildIP", l.ChildIP)
|
|
| 165 |
- job.SetenvBool("IgnoreErrors", ignoreErrors)
|
|
| 166 |
- |
|
| 167 |
- out := make([]string, len(l.Ports)) |
|
| 168 |
- for i, p := range l.Ports {
|
|
| 169 |
- out[i] = string(p) |
|
| 170 |
- } |
|
| 171 |
- job.SetenvList("Ports", out)
|
|
| 172 |
- |
|
| 173 |
- if err := job.Run(); err != nil {
|
|
| 174 |
- // TODO: get ouput from job |
|
| 175 |
- return err |
|
| 176 |
- } |
|
| 177 |
- return nil |
|
| 161 |
+ return bridge.LinkContainers(action, l.ParentIP, l.ChildIP, l.Ports, ignoreErrors) |
|
| 178 | 162 |
} |