Various fixes:
- Don't capitalize error messages
- Rename variables that collided with imports or types
- Prefer assert.Check over assert.Assert to prevent tests covering multiple
cases from failing early
- Fix inconsistent order of expected <--> actual, which made it difficult to
check which output was the expected output.
- Fix formatting of some comments
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When marshaling the type with `gopkg.in/yaml.v3`, unmarshaling would
recursively call the type's `MarshalYAML()` function, which ultimately
resulted in a crash:
runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0x140202e0430 stack=[0x140202e0000, 0x140402e0000]
fatal error: stack overflow
This applies a similar fix as was implemented in e7788d6f9a
for the `MarshalJSON()` implementation. An alternative would be to use
a type alias (to remove the `MarshalYAML()`), but keeping it simple.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The version was originally added in 570ee9cb54,
at the time the `expected` config did not have a `version:` field. A later
refactor in 0cf2e6353a updated the `expected`
config to have a `version:` included. However, the test was not updated,
which now resulted in the test using a compose file with a duplicate version
field:
version: '3.10'
version: "3.10"
services:
foo:
build:
This issue was masked by `yaml.Unmarshal()` from `gopkg.in/yaml.v2` which
silently ignores the duplicate, taking the value of the last occurrence. When
upgrading to `gopkg.in/yaml.v3`, the duplicate value resulted in an error:
yaml: unmarshal errors:
line 2: mapping key "version" already defined at line 1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Looks like the linter uses an explicit -lang, which (for go1.19)
results in some additional formatting for octal values.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Also removing redundant defer for env.PatchAll(), which is now automatically
handled in t.Cleanup()
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Older versions of Go do not format these comments, so we can already
reformat them ahead of time to prevent gofmt linting failing once
we update to Go 1.19 or up.
Result of:
gofmt -s -w $(find . -type f -name '*.go' | grep -v "/vendor/")
With some manual adjusting.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
cli/compose/interpolation/interpolation.go:102:4: error-strings: error strings should not be capitalized or end with punctuation or a newline (revive)
"invalid interpolation format for %s: %#v. You may need to escape any $ with another $.",
^
cli/command/stack/loader/loader.go:30:30: error-strings: error strings should not be capitalized or end with punctuation or a newline (revive)
return nil, errors.Errorf("Compose file contains unsupported options:\n\n%s\n",
^
cli/command/formatter/formatter.go:76:30: error-strings: error strings should not be capitalized or end with punctuation or a newline (revive)
return tmpl, errors.Errorf("Template parsing error: %v\n", err)
^
cli/command/formatter/formatter.go:97:24: error-strings: error strings should not be capitalized or end with punctuation or a newline (revive)
return errors.Errorf("Template parsing error: %v\n", err)
^
cli/command/image/build.go:257:25: error-strings: error strings should not be capitalized or end with punctuation or a newline (revive)
return errors.Errorf("error checking context: '%s'.", err)
^
cli/command/volume/create.go:35:27: error-strings: error strings should not be capitalized or end with punctuation or a newline (revive)
return errors.Errorf("Conflicting options: either specify --name or provide positional arg, not both\n")
^
cli/command/container/create.go:160:24: error-strings: error strings should not be capitalized or end with punctuation or a newline (revive)
return errors.Errorf("failed to remove the CID file '%s': %s \n", cid.path, err)
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Previously, `version: "3"` was equivalent to `version: "3.0"`, which
caused confusion for many users, as they expected it to be "3.x".
docker-compose and docker compose (v2) have adopted the compose-spec
(https://compose-spec.io), which no longer has a version field in
the compose file, and always picks the "latest" supported version.
This changes how `docker stack` interprets "major" version numbers
specified in compose-files:
When only the major version ("3") is specified, it is now equivalent
to "3.x" (latest supported v3 schema).
Compose-files that specify both major and minor version (e.g. "3.0"
or "3.1") continue to use the existing behavior; validation is down-
graded to the specified version and will produce an error if options
are used that are not supported in that schema version. This allows
users to locally verify that a composse-file does not use options
that are not supported in the intended deployment environment (for
example if the deploy environment only supports older versions of
the schema).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The compose spec (https://compose-spec.io) defines the version to be optional,
and implementations of the spec to check for supported attributes instead.
While this change does not switch the `docker stack` implementation to use the
compose-spec, it makes it function more similar. Previously, omitting a version
number would either produce an error (as the field was required), or switched
the handling to assume it was version 1.0 (which is deprecated).
With this change, compose files without a version number will be handled as
the latest version supported by `docker stack` (currently 3.10). This allows
users that work with docker-compose or docker compose (v2) to deploy their
compose file, without having to re-add a version number. Fields that are
not supported by stackes (schema 3.10) will still produce an error.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Adding a copy of the 3.9 schema, with only the version-string changed.
This makes it easier to find changes since 3.9, which are added after
this.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This allows us to drop the `//go:generate` and use of the github.com/mjibson/esc
utility.
worth noting that Go's native "embed" does not compress files. We could compress
these files as part of a build / validate step (which would add some complexity
when updating these files) if this is a concern, but not sure if the additional
complexity is warranted.
Comparing before/after sizes (see below);
macOS: 54125840 - 54005264 = 120576 (+120.58 kB)
Linux: 52393231 - 52277701 = 115530 (+115.53 kB)
Before:
ls -l build/
total 208736
lrwxr-xr-x 1 sebastiaan staff 19 Aug 15 09:36 docker@ -> docker-linux-amd64
-rwxr-xr-x 1 sebastiaan staff 54005264 Aug 15 09:35 docker-darwin-amd64*
-rwxr-xr-x 1 sebastiaan staff 52277701 Aug 15 09:36 docker-linux-amd64*
After:
ls -l build/
total 208960
lrwxr-xr-x 1 sebastiaan staff 18 Aug 15 09:32 docker@ -> docker-linux-amd64
-rwxr-xr-x 1 sebastiaan staff 54125840 Aug 15 09:31 docker-darwin-amd64*
-rwxr-xr-x 1 sebastiaan staff 52393231 Aug 15 09:32 docker-linux-amd64*
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When creating and updating services, we need to avoid unneeded service churn.
The interaction of separate lists to "add" and "drop" capabilities, a special
("ALL") capability, as well as a "relaxed" format for accepted capabilities
(case-insensitive, `CAP_` prefix optional) make this rather involved.
This patch updates how we handle `--cap-add` / `--cap-drop` when _creating_ as
well as _updating_, with the following rules/assumptions applied:
- both existing (service spec) and new (values passed through flags or in
the compose-file) are normalized and de-duplicated before use.
- the special "ALL" capability is equivalent to "all capabilities" and taken
into account when normalizing capabilities. Combining "ALL" capabilities
and other capabilities is therefore equivalent to just specifying "ALL".
- adding capabilities takes precedence over dropping, which means that if
a capability is both set to be "dropped" and to be "added", it is removed
from the list to "drop".
- the final lists should be sorted and normalized to reduce service churn
- no validation of capabilities is handled by the client. Validation is
delegated to the daemon/server.
When deploying a service using a docker-compose file, the docker-compose file
is *mostly* handled as being "declarative". However, many of the issues outlined
above also apply to compose-files, so similar handling is applied to compose
files as well to prevent service churn.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Both libaries provide similar functionality. We're currently using
Google Shlex in more places, so prefering that one for now, but we
could decide to switch to mattn/go-shellwords in future if that
library is considered better (it looks to be more actively maintained,
but that may be related to it providing "more features").
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This is not currently used by the CLI, but can be used by
docker compose to bring parity on this feature with the
compose v2.4 schema.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
67ebcd6dcf added an exception for
the "host-gateway" magic value to the validation rules, but didn't
add thise value to any of the tests.
This patch adds the magic value to tests, to verify the validation
is skipped for this magic value.
Note that validation on the client side is "optional" and mostly
done to provide a more user-friendly error message for regular
values (IP-addresses).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before this change, this would cause a panic:
docker run -it --rm -v 1:/1 alpine
panic: runtime error: index out of range
goroutine 1 [running]:
github.com/docker/cli/cli/compose/loader.isFilePath(0xc42027e058, 0x1, 0x557dcb978c20)
...
After this change, a correct error is returned:
docker run -it --rm -v 1:/1 alpine
docker: Error response from daemon: create 1: volume name is too short, names should be at least two alphanumeric characters.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Added transforms for when merging compose overrides to preserve the
functionality that was broken by bumping mergo to v1.3.8
This includes:
- Special transform for ulimits so single overrides both soft/hard and
the reverse
- Special transform for service network configs so the override replaces
all aliases
Signed-off-by: Nick Adcock <nick.adcock@docker.com>
```
cli/compose/template/template_test.go:279:31: Using the variable on range scope `tc` in function literal (scopelint)
actual := ExtractVariables(tc.dict, defaultPattern)
^
cli/compose/template/template_test.go:280:41: Using the variable on range scope `tc` in function literal (scopelint)
assert.Check(t, is.DeepEqual(actual, tc.expected))
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/compose/loader/merge.go:64:41: Using a reference for the variable on range scope `overrideService` (scopelint)
if err := mergo.Merge(&baseService, &overrideService, mergo.WithAppendSlice, mergo.WithOverride, mergo.WithTransformers(specials)); err != nil {
^
cli/compose/loader/loader_test.go:1587:28: Using the variable on range scope `testcase` in function literal (scopelint)
config, err := loadYAML(testcase.yaml)
^
cli/compose/loader/loader_test.go:1590:58: Using the variable on range scope `testcase` in function literal (scopelint)
assert.Check(t, is.DeepEqual(config.Services[0].Init, testcase.init))
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This test was intending to run all tests, but didn't, which was
caught by golangci-lint;
cli/compose/loader/windows_path_test.go:46:17: SA4010: this result of append is never used, except maybe in other appends (staticcheck)
tests := append(isabstests, winisabstests...)
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>