mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
api/types/swarm: remove deprecated ServiceSpec.Networks field
This field was deprecated in [engine-api@5c4b684], which got vendored into Moby in [moby@8f7a8c7] (API v1.25), and wired up in [moby@99a98cc]. [engine-api@5c4b684]:5c4b684b2f[moby@8f7a8c7]:8f7a8c75ae[moby@99a98cc]:99a98ccc14Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -35,12 +35,7 @@ type ServiceSpec struct {
|
||||
Mode ServiceMode `json:",omitempty"`
|
||||
UpdateConfig *UpdateConfig `json:",omitempty"`
|
||||
RollbackConfig *UpdateConfig `json:",omitempty"`
|
||||
|
||||
// Networks specifies which networks the service should attach to.
|
||||
//
|
||||
// Deprecated: This field is deprecated since v1.44. The Networks field in TaskSpec should be used instead.
|
||||
Networks []NetworkAttachmentConfig `json:",omitempty"`
|
||||
EndpointSpec *EndpointSpec `json:",omitempty"`
|
||||
EndpointSpec *EndpointSpec `json:",omitempty"`
|
||||
}
|
||||
|
||||
// ServiceMode represents the mode of a service.
|
||||
|
||||
@@ -94,17 +94,30 @@ func serviceSpecFromGRPC(spec *swarmapi.ServiceSpec) (*types.ServiceSpec, error)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
serviceNetworks := make([]types.NetworkAttachmentConfig, 0, len(spec.Networks))
|
||||
for _, n := range spec.Networks {
|
||||
netConfig := types.NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases, DriverOpts: n.DriverAttachmentOpts}
|
||||
serviceNetworks = append(serviceNetworks, netConfig)
|
||||
}
|
||||
|
||||
taskTemplate, err := taskSpecFromGRPC(spec.Task)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(taskTemplate.Networks) == 0 && len(spec.Networks) > 0 {
|
||||
// The ServiceSpec.Networks field was deprecated in API v1.25, with
|
||||
// the deprecation notice updated in API v1.44. We only consider this
|
||||
// field on API < v1.44 and if the replacement TaskSpec.Networks is
|
||||
// not set.
|
||||
//
|
||||
// Account for any service that was created using the old spec.
|
||||
//
|
||||
// TODO(thaJeztah): would swarm still return this? Remove this when we drop API v1.25
|
||||
taskTemplate.Networks = make([]types.NetworkAttachmentConfig, 0, len(spec.Networks))
|
||||
for _, n := range spec.Networks {
|
||||
taskTemplate.Networks = append(taskTemplate.Networks, types.NetworkAttachmentConfig{
|
||||
Target: n.Target,
|
||||
Aliases: n.Aliases,
|
||||
DriverOpts: n.DriverAttachmentOpts,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
switch t := spec.Task.GetRuntime().(type) {
|
||||
case *swarmapi.TaskSpec_Container:
|
||||
containerConfig := t.Container
|
||||
@@ -125,7 +138,6 @@ func serviceSpecFromGRPC(spec *swarmapi.ServiceSpec) (*types.ServiceSpec, error)
|
||||
convertedSpec := &types.ServiceSpec{
|
||||
Annotations: annotationsFromGRPC(spec.Annotations),
|
||||
TaskTemplate: taskTemplate,
|
||||
Networks: serviceNetworks,
|
||||
EndpointSpec: endpointSpecFromGRPC(spec.Endpoint),
|
||||
}
|
||||
|
||||
@@ -160,12 +172,6 @@ func ServiceSpecToGRPC(s types.ServiceSpec) (swarmapi.ServiceSpec, error) {
|
||||
name = namesgenerator.GetRandomName(0)
|
||||
}
|
||||
|
||||
serviceNetworks := make([]*swarmapi.NetworkAttachmentConfig, 0, len(s.Networks)) //nolint:staticcheck // ignore SA1019: field is deprecated.
|
||||
for _, n := range s.Networks { //nolint:staticcheck // ignore SA1019: field is deprecated.
|
||||
netConfig := &swarmapi.NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases, DriverAttachmentOpts: n.DriverOpts}
|
||||
serviceNetworks = append(serviceNetworks, netConfig)
|
||||
}
|
||||
|
||||
taskNetworks := make([]*swarmapi.NetworkAttachmentConfig, 0, len(s.TaskTemplate.Networks))
|
||||
for _, n := range s.TaskTemplate.Networks {
|
||||
netConfig := &swarmapi.NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases, DriverAttachmentOpts: n.DriverOpts}
|
||||
@@ -183,7 +189,6 @@ func ServiceSpecToGRPC(s types.ServiceSpec) (swarmapi.ServiceSpec, error) {
|
||||
Networks: taskNetworks,
|
||||
ForceUpdate: s.TaskTemplate.ForceUpdate,
|
||||
},
|
||||
Networks: serviceNetworks,
|
||||
}
|
||||
|
||||
switch s.TaskTemplate.Runtime {
|
||||
@@ -672,8 +677,11 @@ func networkAttachmentSpecFromGRPC(attachment swarmapi.NetworkAttachmentSpec) *t
|
||||
func taskSpecFromGRPC(taskSpec swarmapi.TaskSpec) (types.TaskSpec, error) {
|
||||
taskNetworks := make([]types.NetworkAttachmentConfig, 0, len(taskSpec.Networks))
|
||||
for _, n := range taskSpec.Networks {
|
||||
netConfig := types.NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases, DriverOpts: n.DriverAttachmentOpts}
|
||||
taskNetworks = append(taskNetworks, netConfig)
|
||||
taskNetworks = append(taskNetworks, types.NetworkAttachmentConfig{
|
||||
Target: n.Target,
|
||||
Aliases: n.Aliases,
|
||||
DriverOpts: n.DriverAttachmentOpts,
|
||||
})
|
||||
}
|
||||
|
||||
t := types.TaskSpec{
|
||||
|
||||
@@ -328,12 +328,7 @@ func (c *Cluster) RemoveNetwork(input string) error {
|
||||
}
|
||||
|
||||
func (c *Cluster) populateNetworkID(ctx context.Context, client swarmapi.ControlClient, s *types.ServiceSpec) error {
|
||||
// Always prefer NetworkAttachmentConfigs from TaskTemplate
|
||||
// but fallback to service spec for backward compatibility
|
||||
networks := s.TaskTemplate.Networks
|
||||
if len(networks) == 0 {
|
||||
networks = s.Networks //nolint:staticcheck // ignore SA1019: field is deprecated.
|
||||
}
|
||||
for i, nw := range networks {
|
||||
apiNetwork, err := getNetwork(ctx, client, nw.Target, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
types "github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/v2/daemon/internal/compat"
|
||||
"github.com/moby/moby/v2/daemon/internal/filters"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
@@ -171,6 +172,13 @@ func (sr *swarmRouter) getServices(ctx context.Context, w http.ResponseWriter, r
|
||||
log.G(ctx).WithContext(ctx).WithError(err).Debug("Error getting services")
|
||||
return err
|
||||
}
|
||||
if versions.LessThan(cliVersion, "1.25") {
|
||||
legacyResponse := make([]*compat.Wrapper, 0, len(services))
|
||||
for _, s := range services {
|
||||
legacyResponse = append(legacyResponse, backFillLegacyNetwork(s))
|
||||
}
|
||||
return httputils.WriteJSON(w, http.StatusOK, legacyResponse)
|
||||
}
|
||||
|
||||
return httputils.WriteJSON(w, http.StatusOK, services)
|
||||
}
|
||||
@@ -201,11 +209,29 @@ func (sr *swarmRouter) getService(ctx context.Context, w http.ResponseWriter, r
|
||||
return err
|
||||
}
|
||||
|
||||
cliVersion := httputils.VersionFromContext(ctx)
|
||||
if versions.LessThan(cliVersion, "1.25") {
|
||||
return httputils.WriteJSON(w, http.StatusOK, backFillLegacyNetwork(service))
|
||||
}
|
||||
|
||||
return httputils.WriteJSON(w, http.StatusOK, service)
|
||||
}
|
||||
|
||||
// serviceWithLegacy is used to unmarshal legacy requests that contain
|
||||
// the ServiceSpec.Networks field.
|
||||
type serviceWithLegacy struct {
|
||||
types.ServiceSpec
|
||||
|
||||
// Networks specifies which networks the service should attach to.
|
||||
//
|
||||
// This field was deprecated in API v1.25, with the deprecation notice
|
||||
// updated in API v1.44. We only consider this field on API < v1.44,
|
||||
// and if the replacement TaskSpec.Networks is not set.
|
||||
Networks []types.NetworkAttachmentConfig `json:",omitempty"`
|
||||
}
|
||||
|
||||
func (sr *swarmRouter) createService(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
var service types.ServiceSpec
|
||||
var service serviceWithLegacy
|
||||
if err := httputils.ReadJSON(r, &service); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -220,7 +246,8 @@ func (sr *swarmRouter) createService(ctx context.Context, w http.ResponseWriter,
|
||||
adjustForAPIVersion(v, &service)
|
||||
}
|
||||
|
||||
resp, err := sr.backend.CreateService(service, encodedAuth, queryRegistry)
|
||||
serviceSpec := service.ServiceSpec
|
||||
resp, err := sr.backend.CreateService(serviceSpec, encodedAuth, queryRegistry)
|
||||
if err != nil {
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"error": err,
|
||||
@@ -233,7 +260,7 @@ func (sr *swarmRouter) createService(ctx context.Context, w http.ResponseWriter,
|
||||
}
|
||||
|
||||
func (sr *swarmRouter) updateService(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
var service types.ServiceSpec
|
||||
var service serviceWithLegacy
|
||||
if err := httputils.ReadJSON(r, &service); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -259,7 +286,8 @@ func (sr *swarmRouter) updateService(ctx context.Context, w http.ResponseWriter,
|
||||
adjustForAPIVersion(v, &service)
|
||||
}
|
||||
|
||||
resp, err := sr.backend.UpdateService(vars["id"], version, service, flags, queryRegistry)
|
||||
serviceSpec := service.ServiceSpec
|
||||
resp, err := sr.backend.UpdateService(vars["id"], version, serviceSpec, flags, queryRegistry)
|
||||
if err != nil {
|
||||
log.G(ctx).WithContext(ctx).WithFields(log.Fields{
|
||||
"error": err,
|
||||
@@ -549,3 +577,22 @@ func (sr *swarmRouter) updateConfig(ctx context.Context, w http.ResponseWriter,
|
||||
id := vars["id"]
|
||||
return sr.backend.UpdateConfig(id, version, config)
|
||||
}
|
||||
|
||||
func backFillLegacyNetwork(s types.Service) *compat.Wrapper {
|
||||
var opts []compat.Option
|
||||
if len(s.Spec.TaskTemplate.Networks) > 0 {
|
||||
opts = append(opts, compat.WithExtraFields(map[string]any{
|
||||
"Spec": map[string]any{
|
||||
"Networks": s.Spec.TaskTemplate.Networks,
|
||||
},
|
||||
}))
|
||||
}
|
||||
if s.PreviousSpec != nil && len(s.PreviousSpec.TaskTemplate.Networks) > 0 {
|
||||
opts = append(opts, compat.WithExtraFields(map[string]any{
|
||||
"PreviousSpec": map[string]any{
|
||||
"Networks": s.PreviousSpec.TaskTemplate.Networks,
|
||||
},
|
||||
}))
|
||||
}
|
||||
return compat.Wrap(s, opts...)
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ func (sr *swarmRouter) swarmLogs(ctx context.Context, w http.ResponseWriter, r *
|
||||
|
||||
// adjustForAPIVersion takes a version and service spec and removes fields to
|
||||
// make the spec compatible with the specified version.
|
||||
func adjustForAPIVersion(cliVersion string, service *swarm.ServiceSpec) {
|
||||
func adjustForAPIVersion(cliVersion string, service *serviceWithLegacy) {
|
||||
if cliVersion == "" {
|
||||
return
|
||||
}
|
||||
@@ -142,6 +142,25 @@ func adjustForAPIVersion(cliVersion string, service *swarm.ServiceSpec) {
|
||||
service.TaskTemplate.ContainerSpec.Healthcheck.StartInterval = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Always prefer NetworkAttachmentConfigs from TaskTemplate
|
||||
// but fallback to service spec for backward compatibility.
|
||||
//
|
||||
// The ServiceSpec.Networks field was deprecated in API v1.25, with
|
||||
// the deprecation notice updated in API v1.44. We only consider this
|
||||
// field on API < v1.44 and if the replacement TaskSpec.Networks is
|
||||
// not set.
|
||||
if len(service.TaskTemplate.Networks) == 0 && len(service.Networks) > 0 {
|
||||
service.TaskTemplate.Networks = make([]swarm.NetworkAttachmentConfig, 0, len(service.Networks))
|
||||
for _, n := range service.Networks {
|
||||
service.TaskTemplate.Networks = append(service.TaskTemplate.Networks, swarm.NetworkAttachmentConfig{
|
||||
Target: n.Target,
|
||||
Aliases: n.Aliases,
|
||||
DriverOpts: n.DriverOpts,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if versions.LessThan(cliVersion, "1.46") {
|
||||
|
||||
@@ -14,7 +14,7 @@ func TestAdjustForAPIVersion(t *testing.T) {
|
||||
// testing the negative -- does this leave everything else alone? -- is
|
||||
// prohibitively time-consuming to write, because it would need an object
|
||||
// with literally every field filled in.
|
||||
spec := &swarm.ServiceSpec{
|
||||
serviceSpec := swarm.ServiceSpec{
|
||||
TaskTemplate: swarm.TaskSpec{
|
||||
ContainerSpec: &swarm.ContainerSpec{
|
||||
Sysctls: expectedSysctls,
|
||||
@@ -70,6 +70,9 @@ func TestAdjustForAPIVersion(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
spec := &serviceWithLegacy{
|
||||
ServiceSpec: serviceSpec,
|
||||
}
|
||||
adjustForAPIVersion("1.46", spec)
|
||||
if !reflect.DeepEqual(
|
||||
spec.TaskTemplate.ContainerSpec.Mounts[0].TmpfsOptions.Options,
|
||||
|
||||
7
vendor/github.com/moby/moby/api/types/swarm/service.go
generated
vendored
7
vendor/github.com/moby/moby/api/types/swarm/service.go
generated
vendored
@@ -35,12 +35,7 @@ type ServiceSpec struct {
|
||||
Mode ServiceMode `json:",omitempty"`
|
||||
UpdateConfig *UpdateConfig `json:",omitempty"`
|
||||
RollbackConfig *UpdateConfig `json:",omitempty"`
|
||||
|
||||
// Networks specifies which networks the service should attach to.
|
||||
//
|
||||
// Deprecated: This field is deprecated since v1.44. The Networks field in TaskSpec should be used instead.
|
||||
Networks []NetworkAttachmentConfig `json:",omitempty"`
|
||||
EndpointSpec *EndpointSpec `json:",omitempty"`
|
||||
EndpointSpec *EndpointSpec `json:",omitempty"`
|
||||
}
|
||||
|
||||
// ServiceMode represents the mode of a service.
|
||||
|
||||
Reference in New Issue
Block a user