Fix issue in API POST /services/(id or name)/update
This fix tries to address the issue raised in 26090 where remote API `POST /services/(id or name)/update` cannot use `name` to update. This is not consistent with the documentation of the remote API. This fix fixes this issue by performing a lookup with `getService` in case `name` instead of `id` is used in API. This fix adds an integration test to cover the changes. This fix fixes 26090. Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
parent
13094ffef9
commit
80e3975117
2 changed files with 25 additions and 6 deletions
|
@ -892,7 +892,7 @@ func (c *Cluster) GetService(input string) (types.Service, error) {
|
|||
}
|
||||
|
||||
// UpdateService updates existing service to match new properties.
|
||||
func (c *Cluster) UpdateService(serviceID string, version uint64, spec types.ServiceSpec, encodedAuth string) error {
|
||||
func (c *Cluster) UpdateService(serviceIDOrName string, version uint64, spec types.ServiceSpec, encodedAuth string) error {
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
|
||||
|
@ -913,6 +913,11 @@ func (c *Cluster) UpdateService(serviceID string, version uint64, spec types.Ser
|
|||
return err
|
||||
}
|
||||
|
||||
currentService, err := getService(ctx, c.client, serviceIDOrName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if encodedAuth != "" {
|
||||
ctnr := serviceSpec.Task.GetContainer()
|
||||
if ctnr == nil {
|
||||
|
@ -922,10 +927,6 @@ func (c *Cluster) UpdateService(serviceID string, version uint64, spec types.Ser
|
|||
} else {
|
||||
// this is needed because if the encodedAuth isn't being updated then we
|
||||
// shouldn't lose it, and continue to use the one that was already present
|
||||
currentService, err := getService(ctx, c.client, serviceID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctnr := currentService.Spec.Task.GetContainer()
|
||||
if ctnr == nil {
|
||||
return fmt.Errorf("service does not use container tasks")
|
||||
|
@ -936,7 +937,7 @@ func (c *Cluster) UpdateService(serviceID string, version uint64, spec types.Ser
|
|||
_, err = c.client.UpdateService(
|
||||
ctx,
|
||||
&swarmapi.UpdateServiceRequest{
|
||||
ServiceID: serviceID,
|
||||
ServiceID: currentService.ID,
|
||||
Spec: &serviceSpec,
|
||||
ServiceVersion: &swarmapi.Version{
|
||||
Index: version,
|
||||
|
|
|
@ -1168,3 +1168,21 @@ func (s *DockerSwarmSuite) TestApiSwarmRestartCluster(c *check.C) {
|
|||
|
||||
checkClusterHealth(c, nodes, mCount, wCount)
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) TestApiSwarmServicesUpdateWithName(c *check.C) {
|
||||
d := s.AddDaemon(c, true, true)
|
||||
|
||||
instances := 2
|
||||
id := d.createService(c, simpleTestService, setInstances(instances))
|
||||
waitAndAssert(c, defaultReconciliationTimeout, d.checkActiveContainerCount, checker.Equals, instances)
|
||||
|
||||
service := d.getService(c, id)
|
||||
instances = 5
|
||||
|
||||
setInstances(instances)(service)
|
||||
url := fmt.Sprintf("/services/%s/update?version=%d", service.Spec.Name, service.Version.Index)
|
||||
status, out, err := d.SockRequest("POST", url, service.Spec)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
|
||||
waitAndAssert(c, defaultReconciliationTimeout, d.checkActiveContainerCount, checker.Equals, instances)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue