diff --git a/libnetwork/api/api.go b/libnetwork/api/api.go index c558d9a09d..8befe63d23 100644 --- a/libnetwork/api/api.go +++ b/libnetwork/api/api.go @@ -307,7 +307,17 @@ func procCreateNetwork(c libnetwork.NetworkController, vars map[string]string, b if len(create.DriverOpts) > 0 { options = append(options, libnetwork.NetworkOptionDriverOpts(create.DriverOpts)) } - nw, err := c.NewNetwork(create.NetworkType, create.Name, "", options...) + + if len(create.IPv4Conf) > 0 { + ipamV4Conf := &libnetwork.IpamConf{ + PreferredPool: create.IPv4Conf[0].PreferredPool, + SubPool: create.IPv4Conf[0].SubPool, + } + + options = append(options, libnetwork.NetworkOptionIpam("default", "", []*libnetwork.IpamConf{ipamV4Conf}, nil, nil)) + } + + nw, err := c.NewNetwork(create.NetworkType, create.Name, create.ID, options...) if err != nil { return nil, convertNetworkError(err) } @@ -697,6 +707,7 @@ func procAttachBackend(c libnetwork.NetworkController, vars map[string]string, b if err != nil { return nil, convertNetworkError(err) } + return sb.Key(), &successResponse } diff --git a/libnetwork/api/types.go b/libnetwork/api/types.go index e13144be73..640891b2c4 100644 --- a/libnetwork/api/types.go +++ b/libnetwork/api/types.go @@ -32,10 +32,19 @@ type sandboxResource struct { Body types ************/ +type ipamConf struct { + PreferredPool string + SubPool string + Gateway string + AuxAddresses map[string]string +} + // networkCreate is the expected body of the "create network" http request message type networkCreate struct { Name string `json:"name"` + ID string `json:"id"` NetworkType string `json:"network_type"` + IPv4Conf []ipamConf `json:"ipv4_configuration"` DriverOpts map[string]string `json:"driver_opts"` NetworkOpts map[string]string `json:"network_opts"` } diff --git a/libnetwork/client/network.go b/libnetwork/client/network.go index 08e69ed033..b8437b2984 100644 --- a/libnetwork/client/network.go +++ b/libnetwork/client/network.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "net/http" + "strings" "text/tabwriter" flag "github.com/docker/docker/pkg/mflag" @@ -42,8 +43,13 @@ func (cli *NetworkCli) CmdNetwork(chain string, args ...string) error { func (cli *NetworkCli) CmdNetworkCreate(chain string, args ...string) error { cmd := cli.Subcmd(chain, "create", "NETWORK-NAME", "Creates a new network with a name specified by the user", false) flDriver := cmd.String([]string{"d", "-driver"}, "", "Driver to manage the Network") + flID := cmd.String([]string{"-id"}, "", "Network ID string") + flOpts := cmd.String([]string{"o", "-opt"}, "", "Network options") flInternal := cmd.Bool([]string{"-internal"}, false, "Config the network to be internal") flIPv6 := cmd.Bool([]string{"-ipv6"}, false, "Enable IPv6 on the network") + flSubnet := cmd.String([]string{"-subnet"}, "", "Subnet option") + flRange := cmd.String([]string{"-ip-range"}, "", "Range option") + cmd.Require(flag.Exact, 1) err := cmd.ParseFlags(args, true) if err != nil { @@ -56,9 +62,30 @@ func (cli *NetworkCli) CmdNetworkCreate(chain string, args ...string) error { if *flIPv6 { networkOpts[netlabel.EnableIPv6] = "true" } + + driverOpts := make(map[string]string) + if *flOpts != "" { + opts := strings.Split(*flOpts, ",") + for _, opt := range opts { + driverOpts[netlabel.Key(opt)] = netlabel.Value(opt) + } + } + + var icList []ipamConf + if *flSubnet != "" { + ic := ipamConf{ + PreferredPool: *flSubnet, + } + + if *flRange != "" { + ic.SubPool = *flRange + } + + icList = append(icList, ic) + } + // Construct network create request body - var driverOpts []string - nc := networkCreate{Name: cmd.Arg(0), NetworkType: *flDriver, DriverOpts: driverOpts, NetworkOpts: networkOpts} + nc := networkCreate{Name: cmd.Arg(0), NetworkType: *flDriver, ID: *flID, IPv4Conf: icList, DriverOpts: driverOpts, NetworkOpts: networkOpts} obj, _, err := readBody(cli.call("POST", "/networks", nc, nil)) if err != nil { return err diff --git a/libnetwork/client/types.go b/libnetwork/client/types.go index 18cd288253..9675bd3a65 100644 --- a/libnetwork/client/types.go +++ b/libnetwork/client/types.go @@ -31,12 +31,20 @@ type SandboxResource struct { /*********** Body types ************/ +type ipamConf struct { + PreferredPool string + SubPool string + Gateway string + AuxAddresses map[string]string +} // networkCreate is the expected body of the "create network" http request message type networkCreate struct { Name string `json:"name"` + ID string `json:"id"` NetworkType string `json:"network_type"` - DriverOpts []string `json:"driver_opts"` + IPv4Conf []ipamConf `json:"ipv4_configuration"` + DriverOpts map[string]string `json:"driver_opts"` NetworkOpts map[string]string `json:"network_opts"` } diff --git a/libnetwork/cmd/dnet/dnet.go b/libnetwork/cmd/dnet/dnet.go index b7d5d970ad..885691f009 100644 --- a/libnetwork/cmd/dnet/dnet.go +++ b/libnetwork/cmd/dnet/dnet.go @@ -91,6 +91,15 @@ func processConfig(cfg *config.Config) []config.Option { dd = cfg.Daemon.DefaultDriver } options = append(options, config.OptionDefaultDriver(dd)) + if cfg.Daemon.IsAgent { + options = append(options, config.OptionAgent()) + } + + if cfg.Daemon.Bind != "" { + options = append(options, config.OptionBind(cfg.Daemon.Bind)) + } + + options = append(options, config.OptionNeighbors(cfg.Daemon.Neighbors)) if cfg.Daemon.Labels != nil { options = append(options, config.OptionLabels(cfg.Daemon.Labels)) diff --git a/libnetwork/test/integration/dnet/helpers.bash b/libnetwork/test/integration/dnet/helpers.bash index 11196638fa..67e4fcc8a3 100644 --- a/libnetwork/test/integration/dnet/helpers.bash +++ b/libnetwork/test/integration/dnet/helpers.bash @@ -10,6 +10,10 @@ function dnet_container_name() { echo dnet-$1-$2 } +function dnet_container_ip() { + docker inspect --format '{{.NetworkSettings.IPAddress}}' dnet-$1-$2 +} + function get_sbox_id() { local line @@ -18,17 +22,17 @@ function get_sbox_id() { } function net_connect() { - local al gl - if [ -n "$4" ]; then - if [ "${4}" != ":" ]; then - al="--alias=${4}" - fi - fi - if [ -n "$5" ]; then - gl="--alias=${5}" - fi - dnet_cmd $(inst_id2port ${1}) service publish $gl ${2}.${3} - dnet_cmd $(inst_id2port ${1}) service attach $al ${2} ${2}.${3} + local al gl + if [ -n "$4" ]; then + if [ "${4}" != ":" ]; then + al="--alias=${4}" + fi + fi + if [ -n "$5" ]; then + gl="--alias=${5}" + fi + dnet_cmd $(inst_id2port ${1}) service publish $gl ${2}.${3} + dnet_cmd $(inst_id2port ${1}) service attach $al ${2} ${2}.${3} } function net_disconnect() { @@ -107,7 +111,7 @@ function parse_discovery_str() { } function start_dnet() { - local inst suffix name hport cport hopt store bridge_ip labels tomlfile + local inst suffix name hport cport hopt store bridge_ip labels tomlfile nip local discovery provider address inst=$1 @@ -115,13 +119,16 @@ function start_dnet() { suffix=$1 shift - stop_dnet ${inst} ${suffix} - name=$(dnet_container_name ${inst} ${suffix}) + store=$(echo $suffix | cut -d":" -f1) + nip=$(echo $suffix | cut -s -d":" -f2) + + + stop_dnet ${inst} ${store} + name=$(dnet_container_name ${inst} ${store}) hport=$((41000+${inst}-1)) cport=2385 hopt="" - store=${suffix} while [ -n "$1" ] do @@ -138,21 +145,32 @@ function start_dnet() { bridge_ip=$(get_docker_bridge_ip) - echo "start_dnet parsed values: " ${inst} ${suffix} ${name} ${hport} ${cport} ${hopt} ${store} ${labels} + echo "start_dnet parsed values: " ${inst} ${suffix} ${name} ${hport} ${cport} ${hopt} ${store} mkdir -p /tmp/dnet/${name} tomlfile="/tmp/dnet/${name}/libnetwork.toml" # Try discovery URLs with or without path + neigh_ip="" + neighbors="" if [ "$store" = "zookeeper" ]; then read discovery provider address < <(parse_discovery_str zk://${bridge_ip}:2182) elif [ "$store" = "etcd" ]; then read discovery provider address < <(parse_discovery_str etcd://${bridge_ip}:42000/custom_prefix) - else + elif [ "$store" = "consul" ]; then read discovery provider address < <(parse_discovery_str consul://${bridge_ip}:8500/custom_prefix) + else + if [ "$nip" != "" ]; then + neighbors="neighbors = [\"${nip}:7946\"]" + fi + + discovery="" + provider="" + address="" fi - cat > ${tomlfile} < ${tomlfile} < ${tomlfile} <>${INTEGRATION_ROOT}/test.log 2>&1 + cmap[dnet-1-local]=dnet-1-local + start_dnet 2 local:$(dnet_container_ip 1 local) 1>>${INTEGRATION_ROOT}/test.log 2>&1 + cmap[dnet-2-local]=dnet-2-local + start_dnet 3 local:$(dnet_container_ip 1 local) 1>>${INTEGRATION_ROOT}/test.log 2>&1 + cmap[dnet-3-local]=dnet-3-local + + ## Run the test cases + ./integration-tmp/bin/bats ./test/integration/dnet/overlay-local.bats + + ## Teardown + stop_dnet 1 local 1>>${INTEGRATION_ROOT}/test.log 2>&1 + unset cmap[dnet-1-local] + stop_dnet 2 local 1>>${INTEGRATION_ROOT}/test.log 2>&1 + unset cmap[dnet-2-local] + stop_dnet 3 local 1>>${INTEGRATION_ROOT}/test.log 2>&1 + unset cmap[dnet-3-local] +} + function run_overlay_consul_tests() { ## Test overlay network with consul ## Setup