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:
parent
fcafc7108b
commit
b34d3e730f
6 changed files with 124 additions and 34 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue