1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Integrate local datascope network with swarm

Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
Alessandro Boch 2017-05-01 16:44:04 -07:00
parent fcafc7108b
commit b34d3e730f
6 changed files with 124 additions and 34 deletions

View file

@ -1,5 +1,9 @@
package swarm
import (
"github.com/docker/docker/api/types/network"
)
// Endpoint represents an endpoint.
type Endpoint struct {
Spec EndpointSpec `json:",omitempty"`
@ -78,12 +82,14 @@ type Network struct {
// NetworkSpec represents the spec of a network.
type NetworkSpec struct {
Annotations
DriverConfiguration *Driver `json:",omitempty"`
IPv6Enabled bool `json:",omitempty"`
Internal bool `json:",omitempty"`
Attachable bool `json:",omitempty"`
Ingress bool `json:",omitempty"`
IPAMOptions *IPAMOptions `json:",omitempty"`
DriverConfiguration *Driver `json:",omitempty"`
IPv6Enabled bool `json:",omitempty"`
Internal bool `json:",omitempty"`
Attachable bool `json:",omitempty"`
Ingress bool `json:",omitempty"`
IPAMOptions *IPAMOptions `json:",omitempty"`
ConfigFrom *network.ConfigReference `json:",omitempty"`
Scope string `json:",omitempty"`
}
// NetworkAttachmentConfig represents the configuration of a network attachment.

View file

@ -6,6 +6,7 @@ import (
basictypes "github.com/docker/docker/api/types"
networktypes "github.com/docker/docker/api/types/network"
types "github.com/docker/docker/api/types/swarm"
netconst "github.com/docker/libnetwork/datastore"
swarmapi "github.com/docker/swarmkit/api"
gogotypes "github.com/gogo/protobuf/types"
)
@ -30,10 +31,17 @@ func networkFromGRPC(n *swarmapi.Network) types.Network {
Attachable: n.Spec.Attachable,
Ingress: n.Spec.Ingress,
IPAMOptions: ipamFromGRPC(n.Spec.IPAM),
Scope: netconst.SwarmScope,
},
IPAMOptions: ipamFromGRPC(n.IPAM),
}
if n.Spec.ConfigFrom != "" {
network.Spec.ConfigFrom = &networktypes.ConfigReference{
Network: n.Spec.ConfigFrom,
}
}
// Meta
network.Version.Index = n.Meta.Version.Index
network.CreatedAt, _ = gogotypes.TimestampFromProto(n.Meta.CreatedAt)
@ -152,7 +160,7 @@ func BasicNetworkFromGRPC(n swarmapi.Network) basictypes.NetworkResource {
nr := basictypes.NetworkResource{
ID: n.ID,
Name: n.Spec.Annotations.Name,
Scope: "swarm",
Scope: netconst.SwarmScope,
EnableIPv6: spec.Ipv6Enabled,
IPAM: ipam,
Internal: spec.Internal,
@ -161,6 +169,12 @@ func BasicNetworkFromGRPC(n swarmapi.Network) basictypes.NetworkResource {
Labels: n.Spec.Annotations.Labels,
}
if n.Spec.ConfigFrom != "" {
nr.ConfigFrom = networktypes.ConfigReference{
Network: n.Spec.ConfigFrom,
}
}
if n.DriverState != nil {
nr.Driver = n.DriverState.Name
nr.Options = n.DriverState.Options
@ -206,5 +220,8 @@ func BasicNetworkCreateToGRPC(create basictypes.NetworkCreateRequest) swarmapi.N
}
ns.IPAM.Configs = ipamSpec
}
if create.ConfigFrom != nil {
ns.ConfigFrom = create.ConfigFrom.Network
}
return ns
}

View file

@ -176,7 +176,7 @@ func (c *containerAdapter) removeNetworks(ctx context.Context) error {
}
func (c *containerAdapter) networkAttach(ctx context.Context) error {
config := c.container.createNetworkingConfig()
config := c.container.createNetworkingConfig(c.backend)
var (
networkName string
@ -195,7 +195,7 @@ func (c *containerAdapter) networkAttach(ctx context.Context) error {
}
func (c *containerAdapter) waitForDetach(ctx context.Context) error {
config := c.container.createNetworkingConfig()
config := c.container.createNetworkingConfig(c.backend)
var (
networkName string
@ -216,20 +216,19 @@ func (c *containerAdapter) waitForDetach(ctx context.Context) error {
func (c *containerAdapter) create(ctx context.Context) error {
var cr containertypes.ContainerCreateCreatedBody
var err error
if cr, err = c.backend.CreateManagedContainer(types.ContainerCreateConfig{
Name: c.container.name(),
Config: c.container.config(),
HostConfig: c.container.hostConfig(),
// Use the first network in container create
NetworkingConfig: c.container.createNetworkingConfig(),
NetworkingConfig: c.container.createNetworkingConfig(c.backend),
}); err != nil {
return err
}
// Docker daemon currently doesn't support multiple networks in container create
// Connect to all other networks
nc := c.container.connectNetworkingConfig()
nc := c.container.connectNetworkingConfig(c.backend)
if nc != nil {
for n, ep := range nc.EndpointsConfig {

View file

@ -18,8 +18,10 @@ import (
enginemount "github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/network"
volumetypes "github.com/docker/docker/api/types/volume"
executorpkg "github.com/docker/docker/daemon/cluster/executor"
clustertypes "github.com/docker/docker/daemon/cluster/provider"
"github.com/docker/go-connections/nat"
netconst "github.com/docker/libnetwork/datastore"
"github.com/docker/swarmkit/agent/exec"
"github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/template"
@ -374,6 +376,14 @@ func (c *containerConfig) hostConfig() *enginecontainer.HostConfig {
}
}
if len(c.task.Networks) > 0 {
labels := c.task.Networks[0].Network.Spec.Annotations.Labels
name := c.task.Networks[0].Network.Spec.Annotations.Name
if v, ok := labels["com.docker.swarm.predefined"]; ok && v == "true" {
hc.NetworkMode = enginecontainer.NetworkMode(name)
}
}
return hc
}
@ -428,7 +438,7 @@ func (c *containerConfig) resources() enginecontainer.Resources {
}
// Docker daemon supports just 1 network during container create.
func (c *containerConfig) createNetworkingConfig() *network.NetworkingConfig {
func (c *containerConfig) createNetworkingConfig(b executorpkg.Backend) *network.NetworkingConfig {
var networks []*api.NetworkAttachment
if c.task.Spec.GetContainer() != nil || c.task.Spec.GetAttachment() != nil {
networks = c.task.Networks
@ -436,19 +446,18 @@ func (c *containerConfig) createNetworkingConfig() *network.NetworkingConfig {
epConfig := make(map[string]*network.EndpointSettings)
if len(networks) > 0 {
epConfig[networks[0].Network.Spec.Annotations.Name] = getEndpointConfig(networks[0])
epConfig[networks[0].Network.Spec.Annotations.Name] = getEndpointConfig(networks[0], b)
}
return &network.NetworkingConfig{EndpointsConfig: epConfig}
}
// TODO: Merge this function with createNetworkingConfig after daemon supports multiple networks in container create
func (c *containerConfig) connectNetworkingConfig() *network.NetworkingConfig {
func (c *containerConfig) connectNetworkingConfig(b executorpkg.Backend) *network.NetworkingConfig {
var networks []*api.NetworkAttachment
if c.task.Spec.GetContainer() != nil {
networks = c.task.Networks
}
// First network is used during container create. Other networks are used in "docker network connect"
if len(networks) < 2 {
return nil
@ -456,12 +465,12 @@ func (c *containerConfig) connectNetworkingConfig() *network.NetworkingConfig {
epConfig := make(map[string]*network.EndpointSettings)
for _, na := range networks[1:] {
epConfig[na.Network.Spec.Annotations.Name] = getEndpointConfig(na)
epConfig[na.Network.Spec.Annotations.Name] = getEndpointConfig(na, b)
}
return &network.NetworkingConfig{EndpointsConfig: epConfig}
}
func getEndpointConfig(na *api.NetworkAttachment) *network.EndpointSettings {
func getEndpointConfig(na *api.NetworkAttachment, b executorpkg.Backend) *network.EndpointSettings {
var ipv4, ipv6 string
for _, addr := range na.Addresses {
ip, _, err := net.ParseCIDR(addr)
@ -479,13 +488,19 @@ func getEndpointConfig(na *api.NetworkAttachment) *network.EndpointSettings {
}
}
return &network.EndpointSettings{
n := &network.EndpointSettings{
NetworkID: na.Network.ID,
IPAMConfig: &network.EndpointIPAMConfig{
IPv4Address: ipv4,
IPv6Address: ipv6,
},
}
if v, ok := na.Network.Spec.Annotations.Labels["com.docker.swarm.predefined"]; ok && v == "true" {
if ln, err := b.FindNetwork(na.Network.Spec.Annotations.Name); err == nil {
n.NetworkID = ln.ID()
}
}
return n
}
func (c *containerConfig) virtualIP(networkID string) string {
@ -570,27 +585,38 @@ func (c *containerConfig) networkCreateRequest(name string) (clustertypes.Networ
options := types.NetworkCreate{
// ID: na.Network.ID,
Driver: na.Network.DriverState.Name,
IPAM: &network.IPAM{
Driver: na.Network.IPAM.Driver.Name,
Options: na.Network.IPAM.Driver.Options,
},
Options: na.Network.DriverState.Options,
Labels: na.Network.Spec.Annotations.Labels,
Internal: na.Network.Spec.Internal,
Attachable: na.Network.Spec.Attachable,
Ingress: na.Network.Spec.Ingress,
EnableIPv6: na.Network.Spec.Ipv6Enabled,
CheckDuplicate: true,
Scope: netconst.SwarmScope,
}
for _, ic := range na.Network.IPAM.Configs {
c := network.IPAMConfig{
Subnet: ic.Subnet,
IPRange: ic.Range,
Gateway: ic.Gateway,
if na.Network.Spec.ConfigFrom != "" {
options.ConfigFrom = &network.ConfigReference{
Network: na.Network.Spec.ConfigFrom,
}
}
if na.Network.DriverState != nil {
options.Driver = na.Network.DriverState.Name
options.Options = na.Network.DriverState.Options
}
if na.Network.IPAM != nil {
options.IPAM = &network.IPAM{
Driver: na.Network.IPAM.Driver.Name,
Options: na.Network.IPAM.Driver.Options,
}
for _, ic := range na.Network.IPAM.Configs {
c := network.IPAMConfig{
Subnet: ic.Subnet,
IPRange: ic.Range,
Gateway: ic.Gateway,
}
options.IPAM.Config = append(options.IPAM.Config, c)
}
options.IPAM.Config = append(options.IPAM.Config, c)
}
return clustertypes.NetworkCreateRequest{

View file

@ -17,7 +17,28 @@ import (
// GetNetworks returns all current cluster managed networks.
func (c *Cluster) GetNetworks() ([]apitypes.NetworkResource, error) {
return c.getNetworks(nil)
list, err := c.getNetworks(nil)
if err != nil {
return nil, err
}
removePredefinedNetworks(&list)
return list, nil
}
func removePredefinedNetworks(networks *[]apitypes.NetworkResource) {
if networks == nil {
return
}
var idxs []int
for i, n := range *networks {
if v, ok := n.Labels["com.docker.swarm.predefined"]; ok && v == "true" {
idxs = append(idxs, i)
}
}
for i, idx := range idxs {
idx -= i
*networks = append((*networks)[:idx], (*networks)[idx+1:]...)
}
}
func (c *Cluster) getNetworks(filters *swarmapi.ListNetworksRequest_Filters) ([]apitypes.NetworkResource, error) {
@ -269,16 +290,27 @@ func (c *Cluster) populateNetworkID(ctx context.Context, client swarmapi.Control
if len(networks) == 0 {
networks = s.Networks
}
for i, n := range networks {
apiNetwork, err := getNetwork(ctx, client, n.Target)
if err != nil {
if ln, _ := c.config.Backend.FindNetwork(n.Target); ln != nil && !ln.Info().Dynamic() {
ln, _ := c.config.Backend.FindNetwork(n.Target)
if ln != nil && runconfig.IsPreDefinedNetwork(ln.Name()) {
// Need to retrieve the corresponding predefined swarm network
// and use its id for the request.
apiNetwork, err = getNetwork(ctx, client, ln.Name())
if err != nil {
err = fmt.Errorf("could not find the corresponding predefined swarm network: %v", err)
return apierrors.NewRequestNotFoundError(err)
}
goto setid
}
if ln != nil && !ln.Info().Dynamic() {
err = fmt.Errorf("The network %s cannot be used with services. Only networks scoped to the swarm can be used, such as those created with the overlay driver.", ln.Name())
return apierrors.NewRequestForbiddenError(err)
}
return err
}
setid:
networks[i].Target = apiNetwork.ID
}
return nil

View file

@ -507,6 +507,16 @@ func (daemon *Daemon) deleteNetwork(networkID string, dynamic bool) error {
return apierrors.NewRequestForbiddenError(err)
}
if dynamic && !nw.Info().Dynamic() {
if runconfig.IsPreDefinedNetwork(nw.Name()) {
// Predefined networks now support swarm services. Make this
// a no-op when cluster requests to remove the predefined network.
return nil
}
err := fmt.Errorf("%s is not a dynamic network", nw.Name())
return apierrors.NewRequestForbiddenError(err)
}
if err := nw.Delete(); err != nil {
return err
}