Browse code

client: consistently use defer for ensureReaderClosed

ensureReaderClosed was designed to be usable regardless if a response
was nil (error) or non-nil (success). Some code-paths were optimized to
avoid using a defer (which used to have an overhead), but the overhead
of defer is neglectable in current versions of Go, and some of these
optimizations made the logic more complicated (and err-prone).

This patch switches to use a defer for all places.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2025/08/13 06:39:45
Showing 54 changed files
... ...
@@ -12,6 +12,6 @@ func (cli *Client) BuildCancel(ctx context.Context, id string) error {
12 12
 	query.Set("id", id)
13 13
 
14 14
 	resp, err := cli.post(ctx, "/build/cancel", query, nil, nil)
15
-	ensureReaderClosed(resp)
15
+	defer ensureReaderClosed(resp)
16 16
 	return err
17 17
 }
... ...
@@ -14,6 +14,6 @@ func (cli *Client) CheckpointCreate(ctx context.Context, containerID string, opt
14 14
 	}
15 15
 
16 16
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/checkpoints", nil, options, nil)
17
-	ensureReaderClosed(resp)
17
+	defer ensureReaderClosed(resp)
18 18
 	return err
19 19
 }
... ...
@@ -20,6 +20,6 @@ func (cli *Client) CheckpointDelete(ctx context.Context, containerID string, opt
20 20
 	}
21 21
 
22 22
 	resp, err := cli.delete(ctx, "/containers/"+containerID+"/checkpoints/"+options.CheckpointID, query, nil)
23
-	ensureReaderClosed(resp)
23
+	defer ensureReaderClosed(resp)
24 24
 	return err
25 25
 }
... ...
@@ -19,6 +19,6 @@ func (cli *Client) ConfigUpdate(ctx context.Context, id string, version swarm.Ve
19 19
 	query := url.Values{}
20 20
 	query.Set("version", version.String())
21 21
 	resp, err := cli.post(ctx, "/configs/"+id+"/update", query, config, nil)
22
-	ensureReaderClosed(resp)
22
+	defer ensureReaderClosed(resp)
23 23
 	return err
24 24
 }
... ...
@@ -58,7 +58,7 @@ func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config
58 58
 		config.ConsoleSize = nil
59 59
 	}
60 60
 	resp, err := cli.post(ctx, "/exec/"+execID+"/start", nil, config, nil)
61
-	ensureReaderClosed(resp)
61
+	defer ensureReaderClosed(resp)
62 62
 	return err
63 63
 }
64 64
 
... ...
@@ -91,13 +91,13 @@ func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, confi
91 91
 
92 92
 // ContainerExecInspect returns information about a specific exec process on the docker host.
93 93
 func (cli *Client) ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, error) {
94
-	var response container.ExecInspect
95 94
 	resp, err := cli.get(ctx, "/exec/"+execID+"/json", nil, nil)
95
+	defer ensureReaderClosed(resp)
96 96
 	if err != nil {
97
-		return response, err
97
+		return container.ExecInspect{}, err
98 98
 	}
99 99
 
100
+	var response container.ExecInspect
100 101
 	err = json.NewDecoder(resp.Body).Decode(&response)
101
-	ensureReaderClosed(resp)
102 102
 	return response, err
103 103
 }
... ...
@@ -18,6 +18,6 @@ func (cli *Client) ContainerKill(ctx context.Context, containerID, signal string
18 18
 	}
19 19
 
20 20
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/kill", query, nil, nil)
21
-	ensureReaderClosed(resp)
21
+	defer ensureReaderClosed(resp)
22 22
 	return err
23 23
 }
... ...
@@ -10,6 +10,6 @@ func (cli *Client) ContainerPause(ctx context.Context, containerID string) error
10 10
 	}
11 11
 
12 12
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/pause", nil, nil, nil)
13
-	ensureReaderClosed(resp)
13
+	defer ensureReaderClosed(resp)
14 14
 	return err
15 15
 }
... ...
@@ -15,6 +15,6 @@ func (cli *Client) ContainerRename(ctx context.Context, containerID, newContaine
15 15
 	query := url.Values{}
16 16
 	query.Set("name", newContainerName)
17 17
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/rename", query, nil, nil)
18
-	ensureReaderClosed(resp)
18
+	defer ensureReaderClosed(resp)
19 19
 	return err
20 20
 }
... ...
@@ -33,6 +33,6 @@ func (cli *Client) resize(ctx context.Context, basePath string, height, width ui
33 33
 	query.Set("w", strconv.FormatUint(uint64(width), 10))
34 34
 
35 35
 	resp, err := cli.post(ctx, basePath+"/resize", query, nil, nil)
36
-	ensureReaderClosed(resp)
36
+	defer ensureReaderClosed(resp)
37 37
 	return err
38 38
 }
... ...
@@ -36,6 +36,6 @@ func (cli *Client) ContainerRestart(ctx context.Context, containerID string, opt
36 36
 		}
37 37
 	}
38 38
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/restart", query, nil, nil)
39
-	ensureReaderClosed(resp)
39
+	defer ensureReaderClosed(resp)
40 40
 	return err
41 41
 }
... ...
@@ -23,6 +23,6 @@ func (cli *Client) ContainerStart(ctx context.Context, containerID string, optio
23 23
 	}
24 24
 
25 25
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/start", query, nil, nil)
26
-	ensureReaderClosed(resp)
26
+	defer ensureReaderClosed(resp)
27 27
 	return err
28 28
 }
... ...
@@ -40,6 +40,6 @@ func (cli *Client) ContainerStop(ctx context.Context, containerID string, option
40 40
 		}
41 41
 	}
42 42
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/stop", query, nil, nil)
43
-	ensureReaderClosed(resp)
43
+	defer ensureReaderClosed(resp)
44 44
 	return err
45 45
 }
... ...
@@ -10,6 +10,6 @@ func (cli *Client) ContainerUnpause(ctx context.Context, containerID string) err
10 10
 	}
11 11
 
12 12
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/unpause", nil, nil, nil)
13
-	ensureReaderClosed(resp)
13
+	defer ensureReaderClosed(resp)
14 14
 	return err
15 15
 }
... ...
@@ -33,6 +33,6 @@ func (cli *Client) ImageTag(ctx context.Context, source, target string) error {
33 33
 	}
34 34
 
35 35
 	resp, err := cli.post(ctx, "/images/"+source+"/tag", query, nil, nil)
36
-	ensureReaderClosed(resp)
36
+	defer ensureReaderClosed(resp)
37 37
 	return err
38 38
 }
... ...
@@ -23,6 +23,6 @@ func (cli *Client) NetworkConnect(ctx context.Context, networkID, containerID st
23 23
 		EndpointConfig: config,
24 24
 	}
25 25
 	resp, err := cli.post(ctx, "/networks/"+networkID+"/connect", nil, nc, nil)
26
-	ensureReaderClosed(resp)
26
+	defer ensureReaderClosed(resp)
27 27
 	return err
28 28
 }
... ...
@@ -23,6 +23,6 @@ func (cli *Client) NetworkDisconnect(ctx context.Context, networkID, containerID
23 23
 		Force:     force,
24 24
 	}
25 25
 	resp, err := cli.post(ctx, "/networks/"+networkID+"/disconnect", nil, nd, nil)
26
-	ensureReaderClosed(resp)
26
+	defer ensureReaderClosed(resp)
27 27
 	return err
28 28
 }
... ...
@@ -17,6 +17,6 @@ func (cli *Client) NodeUpdate(ctx context.Context, nodeID string, version swarm.
17 17
 	query := url.Values{}
18 18
 	query.Set("version", version.String())
19 19
 	resp, err := cli.post(ctx, "/nodes/"+nodeID+"/update", query, node, nil)
20
-	ensureReaderClosed(resp)
20
+	defer ensureReaderClosed(resp)
21 21
 	return err
22 22
 }
... ...
@@ -21,6 +21,6 @@ func (cli *Client) PluginCreate(ctx context.Context, createContext io.Reader, cr
21 21
 	query.Set("name", createOptions.RepoName)
22 22
 
23 23
 	resp, err := cli.postRaw(ctx, "/plugins/create", query, createContext, headers)
24
-	ensureReaderClosed(resp)
24
+	defer ensureReaderClosed(resp)
25 25
 	return err
26 26
 }
... ...
@@ -21,6 +21,6 @@ func (cli *Client) PluginDisable(ctx context.Context, name string, options Plugi
21 21
 		query.Set("force", "1")
22 22
 	}
23 23
 	resp, err := cli.post(ctx, "/plugins/"+name+"/disable", query, nil, nil)
24
-	ensureReaderClosed(resp)
24
+	defer ensureReaderClosed(resp)
25 25
 	return err
26 26
 }
... ...
@@ -21,6 +21,6 @@ func (cli *Client) PluginEnable(ctx context.Context, name string, options Plugin
21 21
 	query.Set("timeout", strconv.Itoa(options.Timeout))
22 22
 
23 23
 	resp, err := cli.post(ctx, "/plugins/"+name+"/enable", query, nil, nil)
24
-	ensureReaderClosed(resp)
24
+	defer ensureReaderClosed(resp)
25 25
 	return err
26 26
 }
... ...
@@ -12,6 +12,6 @@ func (cli *Client) PluginSet(ctx context.Context, name string, args []string) er
12 12
 	}
13 13
 
14 14
 	resp, err := cli.post(ctx, "/plugins/"+name+"/set", nil, args, nil)
15
-	ensureReaderClosed(resp)
15
+	defer ensureReaderClosed(resp)
16 16
 	return err
17 17
 }
... ...
@@ -19,6 +19,6 @@ func (cli *Client) SecretUpdate(ctx context.Context, id string, version swarm.Ve
19 19
 	query := url.Values{}
20 20
 	query.Set("version", version.String())
21 21
 	resp, err := cli.post(ctx, "/secrets/"+id+"/update", query, secret, nil)
22
-	ensureReaderClosed(resp)
22
+	defer ensureReaderClosed(resp)
23 23
 	return err
24 24
 }
... ...
@@ -9,6 +9,6 @@ import (
9 9
 // SwarmJoin joins the swarm.
10 10
 func (cli *Client) SwarmJoin(ctx context.Context, req swarm.JoinRequest) error {
11 11
 	resp, err := cli.post(ctx, "/swarm/join", nil, req, nil)
12
-	ensureReaderClosed(resp)
12
+	defer ensureReaderClosed(resp)
13 13
 	return err
14 14
 }
... ...
@@ -12,6 +12,6 @@ func (cli *Client) SwarmLeave(ctx context.Context, force bool) error {
12 12
 		query.Set("force", "1")
13 13
 	}
14 14
 	resp, err := cli.post(ctx, "/swarm/leave", query, nil, nil)
15
-	ensureReaderClosed(resp)
15
+	defer ensureReaderClosed(resp)
16 16
 	return err
17 17
 }
... ...
@@ -9,6 +9,6 @@ import (
9 9
 // SwarmUnlock unlocks locked swarm.
10 10
 func (cli *Client) SwarmUnlock(ctx context.Context, req swarm.UnlockRequest) error {
11 11
 	resp, err := cli.post(ctx, "/swarm/unlock", nil, req, nil)
12
-	ensureReaderClosed(resp)
12
+	defer ensureReaderClosed(resp)
13 13
 	return err
14 14
 }
... ...
@@ -16,6 +16,6 @@ func (cli *Client) SwarmUpdate(ctx context.Context, version swarm.Version, swarm
16 16
 	query.Set("rotateManagerToken", strconv.FormatBool(flags.RotateManagerToken))
17 17
 	query.Set("rotateManagerUnlockKey", strconv.FormatBool(flags.RotateManagerUnlockKey))
18 18
 	resp, err := cli.post(ctx, "/swarm/update", query, swarm, nil)
19
-	ensureReaderClosed(resp)
19
+	defer ensureReaderClosed(resp)
20 20
 	return err
21 21
 }
... ...
@@ -23,6 +23,6 @@ func (cli *Client) VolumeUpdate(ctx context.Context, volumeID string, version sw
23 23
 	query.Set("version", version.String())
24 24
 
25 25
 	resp, err := cli.put(ctx, "/volumes/"+volumeID, query, options, nil)
26
-	ensureReaderClosed(resp)
26
+	defer ensureReaderClosed(resp)
27 27
 	return err
28 28
 }
... ...
@@ -12,6 +12,6 @@ func (cli *Client) BuildCancel(ctx context.Context, id string) error {
12 12
 	query.Set("id", id)
13 13
 
14 14
 	resp, err := cli.post(ctx, "/build/cancel", query, nil, nil)
15
-	ensureReaderClosed(resp)
15
+	defer ensureReaderClosed(resp)
16 16
 	return err
17 17
 }
... ...
@@ -14,6 +14,6 @@ func (cli *Client) CheckpointCreate(ctx context.Context, containerID string, opt
14 14
 	}
15 15
 
16 16
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/checkpoints", nil, options, nil)
17
-	ensureReaderClosed(resp)
17
+	defer ensureReaderClosed(resp)
18 18
 	return err
19 19
 }
... ...
@@ -20,6 +20,6 @@ func (cli *Client) CheckpointDelete(ctx context.Context, containerID string, opt
20 20
 	}
21 21
 
22 22
 	resp, err := cli.delete(ctx, "/containers/"+containerID+"/checkpoints/"+options.CheckpointID, query, nil)
23
-	ensureReaderClosed(resp)
23
+	defer ensureReaderClosed(resp)
24 24
 	return err
25 25
 }
... ...
@@ -19,6 +19,6 @@ func (cli *Client) ConfigUpdate(ctx context.Context, id string, version swarm.Ve
19 19
 	query := url.Values{}
20 20
 	query.Set("version", version.String())
21 21
 	resp, err := cli.post(ctx, "/configs/"+id+"/update", query, config, nil)
22
-	ensureReaderClosed(resp)
22
+	defer ensureReaderClosed(resp)
23 23
 	return err
24 24
 }
... ...
@@ -58,7 +58,7 @@ func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config
58 58
 		config.ConsoleSize = nil
59 59
 	}
60 60
 	resp, err := cli.post(ctx, "/exec/"+execID+"/start", nil, config, nil)
61
-	ensureReaderClosed(resp)
61
+	defer ensureReaderClosed(resp)
62 62
 	return err
63 63
 }
64 64
 
... ...
@@ -91,13 +91,13 @@ func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, confi
91 91
 
92 92
 // ContainerExecInspect returns information about a specific exec process on the docker host.
93 93
 func (cli *Client) ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, error) {
94
-	var response container.ExecInspect
95 94
 	resp, err := cli.get(ctx, "/exec/"+execID+"/json", nil, nil)
95
+	defer ensureReaderClosed(resp)
96 96
 	if err != nil {
97
-		return response, err
97
+		return container.ExecInspect{}, err
98 98
 	}
99 99
 
100
+	var response container.ExecInspect
100 101
 	err = json.NewDecoder(resp.Body).Decode(&response)
101
-	ensureReaderClosed(resp)
102 102
 	return response, err
103 103
 }
... ...
@@ -18,6 +18,6 @@ func (cli *Client) ContainerKill(ctx context.Context, containerID, signal string
18 18
 	}
19 19
 
20 20
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/kill", query, nil, nil)
21
-	ensureReaderClosed(resp)
21
+	defer ensureReaderClosed(resp)
22 22
 	return err
23 23
 }
... ...
@@ -10,6 +10,6 @@ func (cli *Client) ContainerPause(ctx context.Context, containerID string) error
10 10
 	}
11 11
 
12 12
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/pause", nil, nil, nil)
13
-	ensureReaderClosed(resp)
13
+	defer ensureReaderClosed(resp)
14 14
 	return err
15 15
 }
... ...
@@ -15,6 +15,6 @@ func (cli *Client) ContainerRename(ctx context.Context, containerID, newContaine
15 15
 	query := url.Values{}
16 16
 	query.Set("name", newContainerName)
17 17
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/rename", query, nil, nil)
18
-	ensureReaderClosed(resp)
18
+	defer ensureReaderClosed(resp)
19 19
 	return err
20 20
 }
... ...
@@ -33,6 +33,6 @@ func (cli *Client) resize(ctx context.Context, basePath string, height, width ui
33 33
 	query.Set("w", strconv.FormatUint(uint64(width), 10))
34 34
 
35 35
 	resp, err := cli.post(ctx, basePath+"/resize", query, nil, nil)
36
-	ensureReaderClosed(resp)
36
+	defer ensureReaderClosed(resp)
37 37
 	return err
38 38
 }
... ...
@@ -36,6 +36,6 @@ func (cli *Client) ContainerRestart(ctx context.Context, containerID string, opt
36 36
 		}
37 37
 	}
38 38
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/restart", query, nil, nil)
39
-	ensureReaderClosed(resp)
39
+	defer ensureReaderClosed(resp)
40 40
 	return err
41 41
 }
... ...
@@ -23,6 +23,6 @@ func (cli *Client) ContainerStart(ctx context.Context, containerID string, optio
23 23
 	}
24 24
 
25 25
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/start", query, nil, nil)
26
-	ensureReaderClosed(resp)
26
+	defer ensureReaderClosed(resp)
27 27
 	return err
28 28
 }
... ...
@@ -40,6 +40,6 @@ func (cli *Client) ContainerStop(ctx context.Context, containerID string, option
40 40
 		}
41 41
 	}
42 42
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/stop", query, nil, nil)
43
-	ensureReaderClosed(resp)
43
+	defer ensureReaderClosed(resp)
44 44
 	return err
45 45
 }
... ...
@@ -10,6 +10,6 @@ func (cli *Client) ContainerUnpause(ctx context.Context, containerID string) err
10 10
 	}
11 11
 
12 12
 	resp, err := cli.post(ctx, "/containers/"+containerID+"/unpause", nil, nil, nil)
13
-	ensureReaderClosed(resp)
13
+	defer ensureReaderClosed(resp)
14 14
 	return err
15 15
 }
... ...
@@ -33,6 +33,6 @@ func (cli *Client) ImageTag(ctx context.Context, source, target string) error {
33 33
 	}
34 34
 
35 35
 	resp, err := cli.post(ctx, "/images/"+source+"/tag", query, nil, nil)
36
-	ensureReaderClosed(resp)
36
+	defer ensureReaderClosed(resp)
37 37
 	return err
38 38
 }
... ...
@@ -23,6 +23,6 @@ func (cli *Client) NetworkConnect(ctx context.Context, networkID, containerID st
23 23
 		EndpointConfig: config,
24 24
 	}
25 25
 	resp, err := cli.post(ctx, "/networks/"+networkID+"/connect", nil, nc, nil)
26
-	ensureReaderClosed(resp)
26
+	defer ensureReaderClosed(resp)
27 27
 	return err
28 28
 }
... ...
@@ -23,6 +23,6 @@ func (cli *Client) NetworkDisconnect(ctx context.Context, networkID, containerID
23 23
 		Force:     force,
24 24
 	}
25 25
 	resp, err := cli.post(ctx, "/networks/"+networkID+"/disconnect", nil, nd, nil)
26
-	ensureReaderClosed(resp)
26
+	defer ensureReaderClosed(resp)
27 27
 	return err
28 28
 }
... ...
@@ -17,6 +17,6 @@ func (cli *Client) NodeUpdate(ctx context.Context, nodeID string, version swarm.
17 17
 	query := url.Values{}
18 18
 	query.Set("version", version.String())
19 19
 	resp, err := cli.post(ctx, "/nodes/"+nodeID+"/update", query, node, nil)
20
-	ensureReaderClosed(resp)
20
+	defer ensureReaderClosed(resp)
21 21
 	return err
22 22
 }
... ...
@@ -21,6 +21,6 @@ func (cli *Client) PluginCreate(ctx context.Context, createContext io.Reader, cr
21 21
 	query.Set("name", createOptions.RepoName)
22 22
 
23 23
 	resp, err := cli.postRaw(ctx, "/plugins/create", query, createContext, headers)
24
-	ensureReaderClosed(resp)
24
+	defer ensureReaderClosed(resp)
25 25
 	return err
26 26
 }
... ...
@@ -21,6 +21,6 @@ func (cli *Client) PluginDisable(ctx context.Context, name string, options Plugi
21 21
 		query.Set("force", "1")
22 22
 	}
23 23
 	resp, err := cli.post(ctx, "/plugins/"+name+"/disable", query, nil, nil)
24
-	ensureReaderClosed(resp)
24
+	defer ensureReaderClosed(resp)
25 25
 	return err
26 26
 }
... ...
@@ -21,6 +21,6 @@ func (cli *Client) PluginEnable(ctx context.Context, name string, options Plugin
21 21
 	query.Set("timeout", strconv.Itoa(options.Timeout))
22 22
 
23 23
 	resp, err := cli.post(ctx, "/plugins/"+name+"/enable", query, nil, nil)
24
-	ensureReaderClosed(resp)
24
+	defer ensureReaderClosed(resp)
25 25
 	return err
26 26
 }
... ...
@@ -12,6 +12,6 @@ func (cli *Client) PluginSet(ctx context.Context, name string, args []string) er
12 12
 	}
13 13
 
14 14
 	resp, err := cli.post(ctx, "/plugins/"+name+"/set", nil, args, nil)
15
-	ensureReaderClosed(resp)
15
+	defer ensureReaderClosed(resp)
16 16
 	return err
17 17
 }
... ...
@@ -19,6 +19,6 @@ func (cli *Client) SecretUpdate(ctx context.Context, id string, version swarm.Ve
19 19
 	query := url.Values{}
20 20
 	query.Set("version", version.String())
21 21
 	resp, err := cli.post(ctx, "/secrets/"+id+"/update", query, secret, nil)
22
-	ensureReaderClosed(resp)
22
+	defer ensureReaderClosed(resp)
23 23
 	return err
24 24
 }
... ...
@@ -9,6 +9,6 @@ import (
9 9
 // SwarmJoin joins the swarm.
10 10
 func (cli *Client) SwarmJoin(ctx context.Context, req swarm.JoinRequest) error {
11 11
 	resp, err := cli.post(ctx, "/swarm/join", nil, req, nil)
12
-	ensureReaderClosed(resp)
12
+	defer ensureReaderClosed(resp)
13 13
 	return err
14 14
 }
... ...
@@ -12,6 +12,6 @@ func (cli *Client) SwarmLeave(ctx context.Context, force bool) error {
12 12
 		query.Set("force", "1")
13 13
 	}
14 14
 	resp, err := cli.post(ctx, "/swarm/leave", query, nil, nil)
15
-	ensureReaderClosed(resp)
15
+	defer ensureReaderClosed(resp)
16 16
 	return err
17 17
 }
... ...
@@ -9,6 +9,6 @@ import (
9 9
 // SwarmUnlock unlocks locked swarm.
10 10
 func (cli *Client) SwarmUnlock(ctx context.Context, req swarm.UnlockRequest) error {
11 11
 	resp, err := cli.post(ctx, "/swarm/unlock", nil, req, nil)
12
-	ensureReaderClosed(resp)
12
+	defer ensureReaderClosed(resp)
13 13
 	return err
14 14
 }
... ...
@@ -16,6 +16,6 @@ func (cli *Client) SwarmUpdate(ctx context.Context, version swarm.Version, swarm
16 16
 	query.Set("rotateManagerToken", strconv.FormatBool(flags.RotateManagerToken))
17 17
 	query.Set("rotateManagerUnlockKey", strconv.FormatBool(flags.RotateManagerUnlockKey))
18 18
 	resp, err := cli.post(ctx, "/swarm/update", query, swarm, nil)
19
-	ensureReaderClosed(resp)
19
+	defer ensureReaderClosed(resp)
20 20
 	return err
21 21
 }
... ...
@@ -23,6 +23,6 @@ func (cli *Client) VolumeUpdate(ctx context.Context, volumeID string, version sw
23 23
 	query.Set("version", version.String())
24 24
 
25 25
 	resp, err := cli.put(ctx, "/volumes/"+volumeID, query, options, nil)
26
-	ensureReaderClosed(resp)
26
+	defer ensureReaderClosed(resp)
27 27
 	return err
28 28
 }