Since a few weeks it's no longer possible to perform a call to update() when networks are being defined. For instance:
service.update( name = service.name
, image = updated_image
, networks = networks
# ... omitted other parameters.
)
Previously would refresh the service, only modifying the image. Now it throws the following error:
"rpc error: code = 12 desc = networks must be migrated to TaskSpec before being changed"
Please note, that the first update() works, this only occurs after performing an update() again on a service which was previously updated using the update() function.
For us this is critical, as currently rolling deployments (nightly builds) are no longer being deployed automatically.
Docker version: 17.05.0-ce
Docker Python version: 2.3.0
From swarmkit code: https://github.com/docker/swarmkit/blob/master/manager/controlapi/service.go
line 755-763:
// It's not okay to update Service.Spec.Networks on its own.
// However, if Service.Spec.Task.Networks is also being
// updated, that's okay (for example when migrating from the
// deprecated Spec.Networks field to Spec.Task.Networks).
if (len(request.Spec.Networks) != 0 || len(service.Spec.Networks) != 0) &&
!reflect.DeepEqual(request.Spec.Networks, service.Spec.Networks) &&
reflect.DeepEqual(request.Spec.Task.Networks, service.Spec.Task.Networks) {
return grpc.Errorf(codes.Unimplemented, errNetworkUpdateNotSupported.Error())
}
Further investigation confirm that the spec defined by docker itself differs from what the Docker Python API does.
Services created/updated by the Docker CLI tools result in having networks under Spec/TaskTemplate/Networks, whereas updating a Service through the Docker Python API still results in defining it as Spec/Networks.
Any update on this one?
The Network configuration was moved to the TaskSpec structure in https://github.com/docker/engine-api/pull/375 , which was Aug 2016. It would probably be a good idea if docker-py also did this, that would mean we conform to the actual current API.
Keep in mind that the actual behavior is not as lenient as the commit message makes you believe.
If you create a Service using the new TaskSpec structure and then update (well, re-create really) the service using docker-py it will just blatantly fail -- see OP.
If you use the new format, then you can change whatever you like. If you use the old format, then yes it break on any changes.
ISTM there is no reason to use the old format except for backward compatibility.
I'm trying to point out that this is what the docker-py API currently breaks.
I think update_service needs work across the board. Thank you for bringing this particular issue to my attention!
@darkl0rd were you ever able to work around this or did you end up subprocess'ing the docker CLI?
Most helpful comment
I think
update_serviceneeds work across the board. Thank you for bringing this particular issue to my attention!