Merge pull request #50987 from thaJeztah/version_constraints

move endpoint API version constraints to API server
This commit is contained in:
Sebastiaan van Stijn
2025-09-16 18:59:18 +02:00
committed by GitHub
56 changed files with 53 additions and 239 deletions

View File

@@ -23,10 +23,6 @@ type BuildCachePruneOptions struct {
// BuildCachePrune requests the daemon to delete unused cache data.
func (cli *Client) BuildCachePrune(ctx context.Context, opts BuildCachePruneOptions) (*build.CachePruneReport, error) {
if err := cli.NewVersionError(ctx, "1.31", "build prune"); err != nil {
return nil, err
}
query := url.Values{}
if opts.All {
query.Set("all", "1")

View File

@@ -9,16 +9,13 @@ import (
// ConfigCreate creates a new config.
func (cli *Client) ConfigCreate(ctx context.Context, config swarm.ConfigSpec) (swarm.ConfigCreateResponse, error) {
var response swarm.ConfigCreateResponse
if err := cli.NewVersionError(ctx, "1.30", "config create"); err != nil {
return response, err
}
resp, err := cli.post(ctx, "/configs/create", nil, config, nil)
defer ensureReaderClosed(resp)
if err != nil {
return response, err
return swarm.ConfigCreateResponse{}, err
}
var response swarm.ConfigCreateResponse
err = json.NewDecoder(resp.Body).Decode(&response)
return response, err
}

View File

@@ -16,17 +16,6 @@ import (
is "gotest.tools/v3/assert/cmp"
)
func TestConfigCreateUnsupported(t *testing.T) {
client, err := NewClientWithOpts(
WithVersion("1.29"),
WithHTTPClient(&http.Client{}),
)
assert.NilError(t, err)
_, err = client.ConfigCreate(context.Background(), swarm.ConfigSpec{})
assert.Check(t, is.Error(err, `"config create" requires API version 1.30, but the Docker daemon API version is 1.29`))
}
func TestConfigCreateError(t *testing.T) {
client, err := NewClientWithOpts(
WithVersion("1.30"),

View File

@@ -15,9 +15,6 @@ func (cli *Client) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.C
if err != nil {
return swarm.Config{}, nil, err
}
if err := cli.NewVersionError(ctx, "1.30", "config inspect"); err != nil {
return swarm.Config{}, nil, err
}
resp, err := cli.get(ctx, "/configs/"+id, nil, nil)
defer ensureReaderClosed(resp)
if err != nil {

View File

@@ -43,17 +43,6 @@ func TestConfigInspectWithEmptyID(t *testing.T) {
assert.Check(t, is.ErrorContains(err, "value is empty"))
}
func TestConfigInspectUnsupported(t *testing.T) {
client, err := NewClientWithOpts(
WithVersion("1.29"),
WithHTTPClient(&http.Client{}),
)
assert.NilError(t, err)
_, _, err = client.ConfigInspectWithRaw(context.Background(), "nothing")
assert.Check(t, is.Error(err, `"config inspect" requires API version 1.30, but the Docker daemon API version is 1.29`))
}
func TestConfigInspectError(t *testing.T) {
client, err := NewClientWithOpts(
WithVersion("1.30"),

View File

@@ -11,9 +11,6 @@ import (
// ConfigList returns the list of configs.
func (cli *Client) ConfigList(ctx context.Context, options ConfigListOptions) ([]swarm.Config, error) {
if err := cli.NewVersionError(ctx, "1.30", "config list"); err != nil {
return nil, err
}
query := url.Values{}
if options.Filters.Len() > 0 {

View File

@@ -17,17 +17,6 @@ import (
is "gotest.tools/v3/assert/cmp"
)
func TestConfigListUnsupported(t *testing.T) {
client, err := NewClientWithOpts(
WithVersion("1.29"),
WithHTTPClient(&http.Client{}),
)
assert.NilError(t, err)
_, err = client.ConfigList(context.Background(), ConfigListOptions{})
assert.Check(t, is.Error(err, `"config list" requires API version 1.30, but the Docker daemon API version is 1.29`))
}
func TestConfigListError(t *testing.T) {
client, err := NewClientWithOpts(
WithVersion("1.30"),

View File

@@ -8,9 +8,6 @@ func (cli *Client) ConfigRemove(ctx context.Context, id string) error {
if err != nil {
return err
}
if err := cli.NewVersionError(ctx, "1.30", "config remove"); err != nil {
return err
}
resp, err := cli.delete(ctx, "/configs/"+id, nil, nil)
defer ensureReaderClosed(resp)
return err

View File

@@ -14,17 +14,6 @@ import (
is "gotest.tools/v3/assert/cmp"
)
func TestConfigRemoveUnsupported(t *testing.T) {
client, err := NewClientWithOpts(
WithVersion("1.29"),
WithHTTPClient(&http.Client{}),
)
assert.NilError(t, err)
err = client.ConfigRemove(context.Background(), "config_id")
assert.Check(t, is.Error(err, `"config remove" requires API version 1.30, but the Docker daemon API version is 1.29`))
}
func TestConfigRemoveError(t *testing.T) {
client, err := NewClientWithOpts(
WithVersion("1.30"),

View File

@@ -13,9 +13,6 @@ func (cli *Client) ConfigUpdate(ctx context.Context, id string, version swarm.Ve
if err != nil {
return err
}
if err := cli.NewVersionError(ctx, "1.30", "config update"); err != nil {
return err
}
query := url.Values{}
query.Set("version", version.String())
resp, err := cli.post(ctx, "/configs/"+id+"/update", query, config, nil)

View File

@@ -15,17 +15,6 @@ import (
is "gotest.tools/v3/assert/cmp"
)
func TestConfigUpdateUnsupported(t *testing.T) {
client, err := NewClientWithOpts(
WithVersion("1.29"),
WithHTTPClient(&http.Client{}),
)
assert.NilError(t, err)
err = client.ConfigUpdate(context.Background(), "config_id", swarm.Version{}, swarm.ConfigSpec{})
assert.Check(t, is.Error(err, `"config update" requires API version 1.30, but the Docker daemon API version is 1.29`))
}
func TestConfigUpdateError(t *testing.T) {
client, err := NewClientWithOpts(
WithVersion("1.30"),

View File

@@ -11,10 +11,6 @@ import (
// ContainersPrune requests the daemon to delete unused data
func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) {
if err := cli.NewVersionError(ctx, "1.25", "container prune"); err != nil {
return container.PruneReport{}, err
}
query, err := getFiltersQuery(pruneFilters)
if err != nil {
return container.PruneReport{}, err

View File

@@ -15,10 +15,6 @@ func (cli *Client) DistributionInspect(ctx context.Context, imageRef, encodedReg
return registry.DistributionInspect{}, objectNotFoundError{object: "distribution", id: imageRef}
}
if err := cli.NewVersionError(ctx, "1.30", "distribution inspect"); err != nil {
return registry.DistributionInspect{}, err
}
var headers http.Header
if encodedRegistryAuth != "" {
headers = http.Header{

View File

@@ -11,13 +11,6 @@ import (
is "gotest.tools/v3/assert/cmp"
)
func TestDistributionInspectUnsupported(t *testing.T) {
client, err := NewClientWithOpts(WithVersion("1.29"), WithHTTPClient(&http.Client{}))
assert.NilError(t, err)
_, err = client.DistributionInspect(context.Background(), "foobar:1.0", "")
assert.Check(t, is.Error(err, `"distribution inspect" requires API version 1.30, but the Docker daemon API version is 1.29`))
}
func TestDistributionInspectWithEmptyID(t *testing.T) {
client, err := NewClientWithOpts(WithMockClient(func(req *http.Request) (*http.Response, error) {
return nil, errors.New("should not make request")

View File

@@ -11,10 +11,6 @@ import (
// ImagesPrune requests the daemon to delete unused data
func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (image.PruneReport, error) {
if err := cli.NewVersionError(ctx, "1.25", "image prune"); err != nil {
return image.PruneReport{}, err
}
query, err := getFiltersQuery(pruneFilters)
if err != nil {
return image.PruneReport{}, err

View File

@@ -11,10 +11,6 @@ import (
// NetworksPrune requests the daemon to delete unused networks
func (cli *Client) NetworksPrune(ctx context.Context, pruneFilters filters.Args) (network.PruneReport, error) {
if err := cli.NewVersionError(ctx, "1.25", "network prune"); err != nil {
return network.PruneReport{}, err
}
query, err := getFiltersQuery(pruneFilters)
if err != nil {
return network.PruneReport{}, err

View File

@@ -19,9 +19,6 @@ func (cli *Client) PluginUpgrade(ctx context.Context, name string, options Plugi
return nil, err
}
if err := cli.NewVersionError(ctx, "1.26", "plugin upgrade"); err != nil {
return nil, err
}
query := url.Values{}
if _, err := reference.ParseNormalizedNamed(options.RemoteRef); err != nil {
return nil, fmt.Errorf("invalid remote reference: %w", err)

View File

@@ -9,9 +9,6 @@ import (
// SecretCreate creates a new secret.
func (cli *Client) SecretCreate(ctx context.Context, secret swarm.SecretSpec) (swarm.SecretCreateResponse, error) {
if err := cli.NewVersionError(ctx, "1.25", "secret create"); err != nil {
return swarm.SecretCreateResponse{}, err
}
resp, err := cli.post(ctx, "/secrets/create", nil, secret, nil)
defer ensureReaderClosed(resp)
if err != nil {

View File

@@ -16,13 +16,6 @@ import (
is "gotest.tools/v3/assert/cmp"
)
func TestSecretCreateUnsupported(t *testing.T) {
client, err := NewClientWithOpts(WithVersion("1.24"), WithHTTPClient(&http.Client{}))
assert.NilError(t, err)
_, err = client.SecretCreate(context.Background(), swarm.SecretSpec{})
assert.Check(t, is.Error(err, `"secret create" requires API version 1.25, but the Docker daemon API version is 1.24`))
}
func TestSecretCreateError(t *testing.T) {
client, err := NewClientWithOpts(WithVersion("1.25"), WithMockClient(errorMock(http.StatusInternalServerError, "Server error")))
assert.NilError(t, err)

View File

@@ -15,9 +15,6 @@ func (cli *Client) SecretInspectWithRaw(ctx context.Context, id string) (swarm.S
if err != nil {
return swarm.Secret{}, nil, err
}
if err := cli.NewVersionError(ctx, "1.25", "secret inspect"); err != nil {
return swarm.Secret{}, nil, err
}
resp, err := cli.get(ctx, "/secrets/"+id, nil, nil)
defer ensureReaderClosed(resp)
if err != nil {

View File

@@ -17,13 +17,6 @@ import (
is "gotest.tools/v3/assert/cmp"
)
func TestSecretInspectUnsupported(t *testing.T) {
client, err := NewClientWithOpts(WithVersion("1.24"), WithHTTPClient(&http.Client{}))
assert.NilError(t, err)
_, _, err = client.SecretInspectWithRaw(context.Background(), "nothing")
assert.Check(t, is.Error(err, `"secret inspect" requires API version 1.25, but the Docker daemon API version is 1.24`))
}
func TestSecretInspectError(t *testing.T) {
client, err := NewClientWithOpts(WithVersion("1.25"), WithMockClient(errorMock(http.StatusInternalServerError, "Server error")))
assert.NilError(t, err)

View File

@@ -11,9 +11,6 @@ import (
// SecretList returns the list of secrets.
func (cli *Client) SecretList(ctx context.Context, options SecretListOptions) ([]swarm.Secret, error) {
if err := cli.NewVersionError(ctx, "1.25", "secret list"); err != nil {
return nil, err
}
query := url.Values{}
if options.Filters.Len() > 0 {

View File

@@ -17,13 +17,6 @@ import (
is "gotest.tools/v3/assert/cmp"
)
func TestSecretListUnsupported(t *testing.T) {
client, err := NewClientWithOpts(WithVersion("1.24"), WithHTTPClient(&http.Client{}))
assert.NilError(t, err)
_, err = client.SecretList(context.Background(), SecretListOptions{})
assert.Check(t, is.Error(err, `"secret list" requires API version 1.25, but the Docker daemon API version is 1.24`))
}
func TestSecretListError(t *testing.T) {
client, err := NewClientWithOpts(WithVersion("1.25"), WithMockClient(errorMock(http.StatusInternalServerError, "Server error")))
assert.NilError(t, err)

View File

@@ -8,9 +8,6 @@ func (cli *Client) SecretRemove(ctx context.Context, id string) error {
if err != nil {
return err
}
if err := cli.NewVersionError(ctx, "1.25", "secret remove"); err != nil {
return err
}
resp, err := cli.delete(ctx, "/secrets/"+id, nil, nil)
defer ensureReaderClosed(resp)
return err

View File

@@ -14,13 +14,6 @@ import (
is "gotest.tools/v3/assert/cmp"
)
func TestSecretRemoveUnsupported(t *testing.T) {
client, err := NewClientWithOpts(WithVersion("1.24"), WithHTTPClient(&http.Client{}))
assert.NilError(t, err)
err = client.SecretRemove(context.Background(), "secret_id")
assert.Check(t, is.Error(err, `"secret remove" requires API version 1.25, but the Docker daemon API version is 1.24`))
}
func TestSecretRemoveError(t *testing.T) {
client, err := NewClientWithOpts(WithVersion("1.25"), WithMockClient(errorMock(http.StatusInternalServerError, "Server error")))
assert.NilError(t, err)

View File

@@ -13,9 +13,6 @@ func (cli *Client) SecretUpdate(ctx context.Context, id string, version swarm.Ve
if err != nil {
return err
}
if err := cli.NewVersionError(ctx, "1.25", "secret update"); err != nil {
return err
}
query := url.Values{}
query.Set("version", version.String())
resp, err := cli.post(ctx, "/secrets/"+id+"/update", query, secret, nil)

View File

@@ -15,13 +15,6 @@ import (
is "gotest.tools/v3/assert/cmp"
)
func TestSecretUpdateUnsupported(t *testing.T) {
client, err := NewClientWithOpts(WithVersion("1.24"), WithHTTPClient(&http.Client{}))
assert.NilError(t, err)
err = client.SecretUpdate(context.Background(), "secret_id", swarm.Version{}, swarm.SecretSpec{})
assert.Check(t, is.Error(err, `"secret update" requires API version 1.25, but the Docker daemon API version is 1.24`))
}
func TestSecretUpdateError(t *testing.T) {
client, err := NewClientWithOpts(WithVersion("1.25"), WithMockClient(errorMock(http.StatusInternalServerError, "Server error")))
assert.NilError(t, err)

View File

@@ -11,10 +11,6 @@ import (
// VolumesPrune requests the daemon to delete unused data
func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters filters.Args) (volume.PruneReport, error) {
if err := cli.NewVersionError(ctx, "1.25", "volume prune"); err != nil {
return volume.PruneReport{}, err
}
query, err := getFiltersQuery(pruneFilters)
if err != nil {
return volume.PruneReport{}, err

View File

@@ -15,9 +15,6 @@ func (cli *Client) VolumeUpdate(ctx context.Context, volumeID string, version sw
if err != nil {
return err
}
if err := cli.NewVersionError(ctx, "1.42", "volume update"); err != nil {
return err
}
query := url.Values{}
query.Set("version", version.String())

View File

@@ -32,7 +32,7 @@ func (br *buildRouter) Routes() []router.Route {
func (br *buildRouter) initRoutes() {
br.routes = []router.Route{
router.NewPostRoute("/build", br.postBuild),
router.NewPostRoute("/build/prune", br.postPrune),
router.NewPostRoute("/build/prune", br.postPrune, router.WithMinimumAPIVersion("1.31")),
router.NewPostRoute("/build/cancel", br.postCancel),
}
}

View File

@@ -54,7 +54,7 @@ func (c *containerRouter) initRoutes() {
router.NewPostRoute("/exec/{name:.*}/resize", c.postContainerExecResize),
router.NewPostRoute("/containers/{name:.*}/rename", c.postContainerRename),
router.NewPostRoute("/containers/{name:.*}/update", c.postContainerUpdate),
router.NewPostRoute("/containers/prune", c.postContainersPrune),
router.NewPostRoute("/containers/prune", c.postContainersPrune, router.WithMinimumAPIVersion("1.25")),
router.NewPostRoute("/commit", c.postCommit),
// PUT
router.NewPutRoute("/containers/{name:.*}/archive", c.putContainersArchive),

View File

@@ -26,6 +26,6 @@ func (dr *distributionRouter) Routes() []router.Route {
func (dr *distributionRouter) initRoutes() {
dr.routes = []router.Route{
// GET
router.NewGetRoute("/distribution/{name:.*}/json", dr.getDistributionInfo),
router.NewGetRoute("/distribution/{name:.*}/json", dr.getDistributionInfo, router.WithMinimumAPIVersion("1.30")),
}
}

View File

@@ -41,7 +41,7 @@ func (ir *imageRouter) initRoutes() {
router.NewPostRoute("/images/create", ir.postImagesCreate),
router.NewPostRoute("/images/{name:.*}/push", ir.postImagesPush),
router.NewPostRoute("/images/{name:.*}/tag", ir.postImagesTag),
router.NewPostRoute("/images/prune", ir.postImagesPrune),
router.NewPostRoute("/images/prune", ir.postImagesPrune, router.WithMinimumAPIVersion("1.25")),
// DELETE
router.NewDeleteRoute("/images/{name:.*}", ir.deleteImages),
}

View File

@@ -1,8 +1,10 @@
package router
import (
"context"
"net/http"
"github.com/moby/moby/api/types/versions"
"github.com/moby/moby/v2/daemon/server/httputils"
)
@@ -71,3 +73,32 @@ func NewOptionsRoute(path string, handler httputils.APIFunc, opts ...RouteWrappe
func NewHeadRoute(path string, handler httputils.APIFunc, opts ...RouteWrapper) Route {
return NewRoute(http.MethodHead, path, handler, opts...)
}
// WithMinimumAPIVersion configures the minimum API version required for
// a route. It produces a 400 (Invalid Request) error when accessing the
// endpoint on API versions lower than "minAPIVersion".
//
// Note that technically, it should produce a 404 ("not found") error,
// as the endpoint should be considered "non-existing" on such API versions,
// but 404 status-codes are used in business logic for various endpoints.
func WithMinimumAPIVersion(minAPIVersion string) RouteWrapper {
return func(route Route) Route {
return localRoute{
method: route.Method(),
path: route.Path(),
handler: func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if v := httputils.VersionFromContext(ctx); v != "" && versions.LessThan(v, minAPIVersion) {
return versionError(route.Method() + " " + route.Path() + " requires minimum API version " + minAPIVersion)
}
return route.Handler()(ctx, w, r, vars)
},
}
}
}
type versionError string
func (e versionError) Error() string {
return string(e)
}
func (e versionError) InvalidParameter() {}

View File

@@ -36,7 +36,7 @@ func (n *networkRouter) initRoutes() {
router.NewPostRoute("/networks/create", n.postNetworkCreate),
router.NewPostRoute("/networks/{id:.*}/connect", n.postNetworkConnect),
router.NewPostRoute("/networks/{id:.*}/disconnect", n.postNetworkDisconnect),
router.NewPostRoute("/networks/prune", n.postNetworksPrune),
router.NewPostRoute("/networks/prune", n.postNetworksPrune, router.WithMinimumAPIVersion("1.25")),
// DELETE
router.NewDeleteRoute("/networks/{id:.*}", n.deleteNetwork),
}

View File

@@ -32,7 +32,7 @@ func (pr *pluginRouter) initRoutes() {
router.NewPostRoute("/plugins/{name:.*}/disable", pr.disablePlugin),
router.NewPostRoute("/plugins/pull", pr.pullPlugin),
router.NewPostRoute("/plugins/{name:.*}/push", pr.pushPlugin),
router.NewPostRoute("/plugins/{name:.*}/upgrade", pr.upgradePlugin),
router.NewPostRoute("/plugins/{name:.*}/upgrade", pr.upgradePlugin, router.WithMinimumAPIVersion("1.26")),
router.NewPostRoute("/plugins/{name:.*}/set", pr.setPlugin),
router.NewPostRoute("/plugins/create", pr.createPlugin),
}

View File

@@ -48,16 +48,16 @@ func (sr *swarmRouter) initRoutes() {
router.NewGetRoute("/tasks/{id}", sr.getTask),
router.NewGetRoute("/tasks/{id}/logs", sr.getTaskLogs),
router.NewGetRoute("/secrets", sr.getSecrets),
router.NewPostRoute("/secrets/create", sr.createSecret),
router.NewDeleteRoute("/secrets/{id}", sr.removeSecret),
router.NewGetRoute("/secrets/{id}", sr.getSecret),
router.NewPostRoute("/secrets/{id}/update", sr.updateSecret),
router.NewGetRoute("/secrets", sr.getSecrets, router.WithMinimumAPIVersion("1.25")),
router.NewPostRoute("/secrets/create", sr.createSecret, router.WithMinimumAPIVersion("1.25")),
router.NewDeleteRoute("/secrets/{id}", sr.removeSecret, router.WithMinimumAPIVersion("1.25")),
router.NewGetRoute("/secrets/{id}", sr.getSecret, router.WithMinimumAPIVersion("1.25")),
router.NewPostRoute("/secrets/{id}/update", sr.updateSecret, router.WithMinimumAPIVersion("1.25")),
router.NewGetRoute("/configs", sr.getConfigs),
router.NewPostRoute("/configs/create", sr.createConfig),
router.NewDeleteRoute("/configs/{id}", sr.removeConfig),
router.NewGetRoute("/configs/{id}", sr.getConfig),
router.NewPostRoute("/configs/{id}/update", sr.updateConfig),
router.NewGetRoute("/configs", sr.getConfigs, router.WithMinimumAPIVersion("1.30")),
router.NewPostRoute("/configs/create", sr.createConfig, router.WithMinimumAPIVersion("1.30")),
router.NewDeleteRoute("/configs/{id}", sr.removeConfig, router.WithMinimumAPIVersion("1.30")),
router.NewGetRoute("/configs/{id}", sr.getConfig, router.WithMinimumAPIVersion("1.30")),
router.NewPostRoute("/configs/{id}/update", sr.updateConfig, router.WithMinimumAPIVersion("1.30")),
}
}

View File

@@ -31,9 +31,9 @@ func (v *volumeRouter) initRoutes() {
router.NewGetRoute("/volumes/{name:.*}", v.getVolumeByName),
// POST
router.NewPostRoute("/volumes/create", v.postVolumesCreate),
router.NewPostRoute("/volumes/prune", v.postVolumesPrune),
router.NewPostRoute("/volumes/prune", v.postVolumesPrune, router.WithMinimumAPIVersion("1.25")),
// PUT
router.NewPutRoute("/volumes/{name:.*}", v.putVolumesUpdate),
router.NewPutRoute("/volumes/{name:.*}", v.putVolumesUpdate, router.WithMinimumAPIVersion("1.42")),
// DELETE
router.NewDeleteRoute("/volumes/{name:.*}", v.deleteVolumes),
}

View File

@@ -23,10 +23,6 @@ type BuildCachePruneOptions struct {
// BuildCachePrune requests the daemon to delete unused cache data.
func (cli *Client) BuildCachePrune(ctx context.Context, opts BuildCachePruneOptions) (*build.CachePruneReport, error) {
if err := cli.NewVersionError(ctx, "1.31", "build prune"); err != nil {
return nil, err
}
query := url.Values{}
if opts.All {
query.Set("all", "1")

View File

@@ -9,16 +9,13 @@ import (
// ConfigCreate creates a new config.
func (cli *Client) ConfigCreate(ctx context.Context, config swarm.ConfigSpec) (swarm.ConfigCreateResponse, error) {
var response swarm.ConfigCreateResponse
if err := cli.NewVersionError(ctx, "1.30", "config create"); err != nil {
return response, err
}
resp, err := cli.post(ctx, "/configs/create", nil, config, nil)
defer ensureReaderClosed(resp)
if err != nil {
return response, err
return swarm.ConfigCreateResponse{}, err
}
var response swarm.ConfigCreateResponse
err = json.NewDecoder(resp.Body).Decode(&response)
return response, err
}

View File

@@ -15,9 +15,6 @@ func (cli *Client) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.C
if err != nil {
return swarm.Config{}, nil, err
}
if err := cli.NewVersionError(ctx, "1.30", "config inspect"); err != nil {
return swarm.Config{}, nil, err
}
resp, err := cli.get(ctx, "/configs/"+id, nil, nil)
defer ensureReaderClosed(resp)
if err != nil {

View File

@@ -11,9 +11,6 @@ import (
// ConfigList returns the list of configs.
func (cli *Client) ConfigList(ctx context.Context, options ConfigListOptions) ([]swarm.Config, error) {
if err := cli.NewVersionError(ctx, "1.30", "config list"); err != nil {
return nil, err
}
query := url.Values{}
if options.Filters.Len() > 0 {

View File

@@ -8,9 +8,6 @@ func (cli *Client) ConfigRemove(ctx context.Context, id string) error {
if err != nil {
return err
}
if err := cli.NewVersionError(ctx, "1.30", "config remove"); err != nil {
return err
}
resp, err := cli.delete(ctx, "/configs/"+id, nil, nil)
defer ensureReaderClosed(resp)
return err

View File

@@ -13,9 +13,6 @@ func (cli *Client) ConfigUpdate(ctx context.Context, id string, version swarm.Ve
if err != nil {
return err
}
if err := cli.NewVersionError(ctx, "1.30", "config update"); err != nil {
return err
}
query := url.Values{}
query.Set("version", version.String())
resp, err := cli.post(ctx, "/configs/"+id+"/update", query, config, nil)

View File

@@ -11,10 +11,6 @@ import (
// ContainersPrune requests the daemon to delete unused data
func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) {
if err := cli.NewVersionError(ctx, "1.25", "container prune"); err != nil {
return container.PruneReport{}, err
}
query, err := getFiltersQuery(pruneFilters)
if err != nil {
return container.PruneReport{}, err

View File

@@ -15,10 +15,6 @@ func (cli *Client) DistributionInspect(ctx context.Context, imageRef, encodedReg
return registry.DistributionInspect{}, objectNotFoundError{object: "distribution", id: imageRef}
}
if err := cli.NewVersionError(ctx, "1.30", "distribution inspect"); err != nil {
return registry.DistributionInspect{}, err
}
var headers http.Header
if encodedRegistryAuth != "" {
headers = http.Header{

View File

@@ -11,10 +11,6 @@ import (
// ImagesPrune requests the daemon to delete unused data
func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (image.PruneReport, error) {
if err := cli.NewVersionError(ctx, "1.25", "image prune"); err != nil {
return image.PruneReport{}, err
}
query, err := getFiltersQuery(pruneFilters)
if err != nil {
return image.PruneReport{}, err

View File

@@ -11,10 +11,6 @@ import (
// NetworksPrune requests the daemon to delete unused networks
func (cli *Client) NetworksPrune(ctx context.Context, pruneFilters filters.Args) (network.PruneReport, error) {
if err := cli.NewVersionError(ctx, "1.25", "network prune"); err != nil {
return network.PruneReport{}, err
}
query, err := getFiltersQuery(pruneFilters)
if err != nil {
return network.PruneReport{}, err

View File

@@ -19,9 +19,6 @@ func (cli *Client) PluginUpgrade(ctx context.Context, name string, options Plugi
return nil, err
}
if err := cli.NewVersionError(ctx, "1.26", "plugin upgrade"); err != nil {
return nil, err
}
query := url.Values{}
if _, err := reference.ParseNormalizedNamed(options.RemoteRef); err != nil {
return nil, fmt.Errorf("invalid remote reference: %w", err)

View File

@@ -9,9 +9,6 @@ import (
// SecretCreate creates a new secret.
func (cli *Client) SecretCreate(ctx context.Context, secret swarm.SecretSpec) (swarm.SecretCreateResponse, error) {
if err := cli.NewVersionError(ctx, "1.25", "secret create"); err != nil {
return swarm.SecretCreateResponse{}, err
}
resp, err := cli.post(ctx, "/secrets/create", nil, secret, nil)
defer ensureReaderClosed(resp)
if err != nil {

View File

@@ -15,9 +15,6 @@ func (cli *Client) SecretInspectWithRaw(ctx context.Context, id string) (swarm.S
if err != nil {
return swarm.Secret{}, nil, err
}
if err := cli.NewVersionError(ctx, "1.25", "secret inspect"); err != nil {
return swarm.Secret{}, nil, err
}
resp, err := cli.get(ctx, "/secrets/"+id, nil, nil)
defer ensureReaderClosed(resp)
if err != nil {

View File

@@ -11,9 +11,6 @@ import (
// SecretList returns the list of secrets.
func (cli *Client) SecretList(ctx context.Context, options SecretListOptions) ([]swarm.Secret, error) {
if err := cli.NewVersionError(ctx, "1.25", "secret list"); err != nil {
return nil, err
}
query := url.Values{}
if options.Filters.Len() > 0 {

View File

@@ -8,9 +8,6 @@ func (cli *Client) SecretRemove(ctx context.Context, id string) error {
if err != nil {
return err
}
if err := cli.NewVersionError(ctx, "1.25", "secret remove"); err != nil {
return err
}
resp, err := cli.delete(ctx, "/secrets/"+id, nil, nil)
defer ensureReaderClosed(resp)
return err

View File

@@ -13,9 +13,6 @@ func (cli *Client) SecretUpdate(ctx context.Context, id string, version swarm.Ve
if err != nil {
return err
}
if err := cli.NewVersionError(ctx, "1.25", "secret update"); err != nil {
return err
}
query := url.Values{}
query.Set("version", version.String())
resp, err := cli.post(ctx, "/secrets/"+id+"/update", query, secret, nil)

View File

@@ -11,10 +11,6 @@ import (
// VolumesPrune requests the daemon to delete unused data
func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters filters.Args) (volume.PruneReport, error) {
if err := cli.NewVersionError(ctx, "1.25", "volume prune"); err != nil {
return volume.PruneReport{}, err
}
query, err := getFiltersQuery(pruneFilters)
if err != nil {
return volume.PruneReport{}, err

View File

@@ -15,9 +15,6 @@ func (cli *Client) VolumeUpdate(ctx context.Context, volumeID string, version sw
if err != nil {
return err
}
if err := cli.NewVersionError(ctx, "1.42", "volume update"); err != nil {
return err
}
query := url.Values{}
query.Set("version", version.String())