From a585faf3d2c2ec19cba192921f6ff16ffdd909f1 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Mon, 28 Oct 2024 17:26:28 -0700 Subject: [PATCH] vendor: update compose to v2.4.1 Signed-off-by: Tonis Tiigi --- go.mod | 2 +- go.sum | 4 +- .../compose-spec/compose-go/v2/cli/options.go | 64 +- .../compose-go/v2/dotenv/format.go | 38 + .../compose-go/v2/dotenv/godotenv.go | 6 +- .../compose-go/v2/dotenv/parser.go | 6 +- .../compose-go/v2/format/volume.go | 2 +- .../compose-go/v2/loader/loader.go | 61 +- .../compose-go/v2/loader/normalize.go | 14 +- .../compose-go/v2/loader/omitEmpty.go | 74 ++ .../compose-go/v2/loader/reset.go | 28 +- .../compose-go/v2/override/merge.go | 40 +- .../compose-go/v2/schema/compose-spec.json | 52 +- .../compose-go/v2/transform/canonical.go | 10 + .../compose-go/v2/transform/defaults.go | 2 + .../compose-go/v2/transform/devices.go | 36 + .../compose-spec/compose-go/v2/types/cpus.go | 48 ++ .../compose-go/v2/types/derived.gen.go | 681 +++++++++++------- .../compose-go/v2/types/device.go | 1 + .../compose-go/v2/types/envfile.go | 1 + .../compose-spec/compose-go/v2/types/hooks.go | 28 + .../compose-go/v2/types/project.go | 42 +- .../compose-spec/compose-go/v2/types/types.go | 32 +- .../compose-go/v2/validation/validation.go | 12 + vendor/modules.txt | 2 +- 25 files changed, 907 insertions(+), 379 deletions(-) create mode 100644 vendor/github.com/compose-spec/compose-go/v2/dotenv/format.go create mode 100644 vendor/github.com/compose-spec/compose-go/v2/loader/omitEmpty.go create mode 100644 vendor/github.com/compose-spec/compose-go/v2/transform/devices.go create mode 100644 vendor/github.com/compose-spec/compose-go/v2/types/cpus.go create mode 100644 vendor/github.com/compose-spec/compose-go/v2/types/hooks.go diff --git a/go.mod b/go.mod index 9bcfb68a..61b9c5ef 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/Masterminds/semver/v3 v3.2.1 github.com/Microsoft/go-winio v0.6.2 github.com/aws/aws-sdk-go-v2/config v1.26.6 - github.com/compose-spec/compose-go/v2 v2.2.0 + github.com/compose-spec/compose-go/v2 v2.4.1 github.com/containerd/console v1.0.4 github.com/containerd/containerd v1.7.22 github.com/containerd/continuity v0.4.4 diff --git a/go.sum b/go.sum index 8b0c8a46..8d11c353 100644 --- a/go.sum +++ b/go.sum @@ -83,8 +83,8 @@ github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnTh github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= -github.com/compose-spec/compose-go/v2 v2.2.0 h1:VsQosGhuO+H9wh5laiIiAe4TVd73kQ5NWwmNrdm0HRA= -github.com/compose-spec/compose-go/v2 v2.2.0/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc= +github.com/compose-spec/compose-go/v2 v2.4.1 h1:tEg6Qn/9LZnKg42fZlFmxN4lxSqnCvsiG5TXnxzvI4c= +github.com/compose-spec/compose-go/v2 v2.4.1/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0= github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE= diff --git a/vendor/github.com/compose-spec/compose-go/v2/cli/options.go b/vendor/github.com/compose-spec/compose-go/v2/cli/options.go index c4b2f57a..b2ab60e8 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/cli/options.go +++ b/vendor/github.com/compose-spec/compose-go/v2/cli/options.go @@ -403,22 +403,24 @@ func (o *ProjectOptions) GetWorkingDir() (string, error) { return os.Getwd() } -func (o *ProjectOptions) GetConfigFiles() ([]types.ConfigFile, error) { - configPaths, err := o.getConfigPaths() +// ReadConfigFiles reads ConfigFiles and populates the content field +func (o *ProjectOptions) ReadConfigFiles(ctx context.Context, workingDir string, options *ProjectOptions) (*types.ConfigDetails, error) { + config, err := loader.LoadConfigFiles(ctx, options.ConfigPaths, workingDir, options.loadOptions...) if err != nil { return nil, err } + configs := make([][]byte, len(config.ConfigFiles)) - var configs []types.ConfigFile - for _, f := range configPaths { + for i, c := range config.ConfigFiles { + var err error var b []byte - if f == "-" { + if c.Filename == "-" { b, err = io.ReadAll(os.Stdin) if err != nil { return nil, err } } else { - f, err := filepath.Abs(f) + f, err := filepath.Abs(c.Filename) if err != nil { return nil, err } @@ -427,27 +429,31 @@ func (o *ProjectOptions) GetConfigFiles() ([]types.ConfigFile, error) { return nil, err } } - configs = append(configs, types.ConfigFile{ - Filename: f, - Content: b, - }) + configs[i] = b } - return configs, err + for i, c := range configs { + config.ConfigFiles[i].Content = c + } + return config, nil } // LoadProject loads compose file according to options and bind to types.Project go structs func (o *ProjectOptions) LoadProject(ctx context.Context) (*types.Project, error) { - configDetails, err := o.prepare() + config, err := o.prepare(ctx) if err != nil { return nil, err } - project, err := loader.LoadWithContext(ctx, configDetails, o.loadOptions...) + project, err := loader.LoadWithContext(ctx, types.ConfigDetails{ + ConfigFiles: config.ConfigFiles, + WorkingDir: config.WorkingDir, + Environment: o.Environment, + }, o.loadOptions...) if err != nil { return nil, err } - for _, config := range configDetails.ConfigFiles { + for _, config := range config.ConfigFiles { project.ComposeFiles = append(project.ComposeFiles, config.Filename) } @@ -456,36 +462,31 @@ func (o *ProjectOptions) LoadProject(ctx context.Context) (*types.Project, error // LoadModel loads compose file according to options and returns a raw (yaml tree) model func (o *ProjectOptions) LoadModel(ctx context.Context) (map[string]any, error) { - configDetails, err := o.prepare() + configDetails, err := o.prepare(ctx) if err != nil { return nil, err } - return loader.LoadModelWithContext(ctx, configDetails, o.loadOptions...) + return loader.LoadModelWithContext(ctx, *configDetails, o.loadOptions...) } // prepare converts ProjectOptions into loader's types.ConfigDetails and configures default load options -func (o *ProjectOptions) prepare() (types.ConfigDetails, error) { - configs, err := o.GetConfigFiles() +func (o *ProjectOptions) prepare(ctx context.Context) (*types.ConfigDetails, error) { + defaultDir, err := o.GetWorkingDir() if err != nil { - return types.ConfigDetails{}, err + return &types.ConfigDetails{}, err } - workingDir, err := o.GetWorkingDir() + configDetails, err := o.ReadConfigFiles(ctx, defaultDir, o) if err != nil { - return types.ConfigDetails{}, err - } - - configDetails := types.ConfigDetails{ - ConfigFiles: configs, - WorkingDir: workingDir, - Environment: o.Environment, + return configDetails, err } o.loadOptions = append(o.loadOptions, - withNamePrecedenceLoad(workingDir, o), + withNamePrecedenceLoad(defaultDir, o), withConvertWindowsPaths(o), withListeners(o)) + return configDetails, nil } @@ -502,8 +503,13 @@ func withNamePrecedenceLoad(absWorkingDir string, options *ProjectOptions) func( } else if nameFromEnv, ok := options.Environment[consts.ComposeProjectName]; ok && nameFromEnv != "" { opts.SetProjectName(nameFromEnv, true) } else { + dirname := filepath.Base(absWorkingDir) + symlink, err := filepath.EvalSymlinks(absWorkingDir) + if err == nil && filepath.Base(symlink) != dirname { + logrus.Warnf("project has been loaded without an explicit name from a symlink. Using name %q", dirname) + } opts.SetProjectName( - loader.NormalizeProjectName(filepath.Base(absWorkingDir)), + loader.NormalizeProjectName(dirname), false, ) } diff --git a/vendor/github.com/compose-spec/compose-go/v2/dotenv/format.go b/vendor/github.com/compose-spec/compose-go/v2/dotenv/format.go new file mode 100644 index 00000000..c583d212 --- /dev/null +++ b/vendor/github.com/compose-spec/compose-go/v2/dotenv/format.go @@ -0,0 +1,38 @@ +/* + Copyright 2020 The Compose Specification Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package dotenv + +import ( + "fmt" + "io" +) + +var formats = map[string]Parser{} + +type Parser func(r io.Reader, filename string, lookup func(key string) (string, bool)) (map[string]string, error) + +func RegisterFormat(format string, p Parser) { + formats[format] = p +} + +func ParseWithFormat(r io.Reader, filename string, resolve LookupFn, format string) (map[string]string, error) { + parser, ok := formats[format] + if !ok { + return nil, fmt.Errorf("unsupported env_file format %q", format) + } + return parser(r, filename, resolve) +} diff --git a/vendor/github.com/compose-spec/compose-go/v2/dotenv/godotenv.go b/vendor/github.com/compose-spec/compose-go/v2/dotenv/godotenv.go index e6635ce3..76907249 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/dotenv/godotenv.go +++ b/vendor/github.com/compose-spec/compose-go/v2/dotenv/godotenv.go @@ -86,7 +86,7 @@ func ReadWithLookup(lookupFn LookupFn, filenames ...string) (map[string]string, envMap := make(map[string]string) for _, filename := range filenames { - individualEnvMap, individualErr := readFile(filename, lookupFn) + individualEnvMap, individualErr := ReadFile(filename, lookupFn) if individualErr != nil { return envMap, individualErr @@ -129,7 +129,7 @@ func filenamesOrDefault(filenames []string) []string { } func loadFile(filename string, overload bool) error { - envMap, err := readFile(filename, nil) + envMap, err := ReadFile(filename, nil) if err != nil { return err } @@ -150,7 +150,7 @@ func loadFile(filename string, overload bool) error { return nil } -func readFile(filename string, lookupFn LookupFn) (map[string]string, error) { +func ReadFile(filename string, lookupFn LookupFn) (map[string]string, error) { file, err := os.Open(filename) if err != nil { return nil, err diff --git a/vendor/github.com/compose-spec/compose-go/v2/dotenv/parser.go b/vendor/github.com/compose-spec/compose-go/v2/dotenv/parser.go index d7b4a646..85dda738 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/dotenv/parser.go +++ b/vendor/github.com/compose-spec/compose-go/v2/dotenv/parser.go @@ -119,7 +119,7 @@ loop: offset = i + 1 inherited = rune == '\n' break loop - case '_', '.', '[', ']': + case '_', '.', '-', '[', ']': default: // variable name should match [A-Za-z0-9_.-] if unicode.IsLetter(rune) || unicode.IsNumber(rune) { @@ -136,6 +136,10 @@ loop: return "", "", inherited, errors.New("zero length string") } + if inherited && strings.IndexByte(key, ' ') == -1 { + p.line++ + } + // trim whitespace key = strings.TrimRightFunc(key, unicode.IsSpace) cutset := strings.TrimLeftFunc(src[offset:], isSpace) diff --git a/vendor/github.com/compose-spec/compose-go/v2/format/volume.go b/vendor/github.com/compose-spec/compose-go/v2/format/volume.go index 0083a62c..a976042c 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/format/volume.go +++ b/vendor/github.com/compose-spec/compose-go/v2/format/volume.go @@ -95,7 +95,7 @@ func populateFieldFromBuffer(char rune, buffer []rune, volume *types.ServiceVolu if isBindOption(option) { setBindOption(volume, option) } - // ignore unknown options + // ignore unknown options FIXME why not report an error here? } } return nil diff --git a/vendor/github.com/compose-spec/compose-go/v2/loader/loader.go b/vendor/github.com/compose-spec/compose-go/v2/loader/loader.go index 25d2d0c6..62030f23 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/loader/loader.go +++ b/vendor/github.com/compose-spec/compose-go/v2/loader/loader.go @@ -30,6 +30,7 @@ import ( "strings" "github.com/compose-spec/compose-go/v2/consts" + "github.com/compose-spec/compose-go/v2/errdefs" interp "github.com/compose-spec/compose-go/v2/interpolation" "github.com/compose-spec/compose-go/v2/override" "github.com/compose-spec/compose-go/v2/paths" @@ -139,9 +140,9 @@ func (l localResourceLoader) abs(p string) string { return filepath.Join(l.WorkingDir, p) } -func (l localResourceLoader) Accept(p string) bool { - _, err := os.Stat(l.abs(p)) - return err == nil +func (l localResourceLoader) Accept(_ string) bool { + // LocalResourceLoader is the last loader tested so it always should accept the config and try to get the content. + return true } func (l localResourceLoader) Load(_ context.Context, p string) (string, error) { @@ -300,6 +301,51 @@ func parseYAML(decoder *yaml.Decoder) (map[string]interface{}, PostProcessor, er return converted.(map[string]interface{}), &processor, nil } +// LoadConfigFiles ingests config files with ResourceLoader and returns config details with paths to local copies +func LoadConfigFiles(ctx context.Context, configFiles []string, workingDir string, options ...func(*Options)) (*types.ConfigDetails, error) { + if len(configFiles) < 1 { + return &types.ConfigDetails{}, fmt.Errorf("no configuration file provided: %w", errdefs.ErrNotFound) + } + + opts := &Options{} + config := &types.ConfigDetails{ + ConfigFiles: make([]types.ConfigFile, len(configFiles)), + } + + for _, op := range options { + op(opts) + } + opts.ResourceLoaders = append(opts.ResourceLoaders, localResourceLoader{}) + + for i, p := range configFiles { + for _, loader := range opts.ResourceLoaders { + _, isLocalResourceLoader := loader.(localResourceLoader) + if !loader.Accept(p) { + continue + } + local, err := loader.Load(ctx, p) + if err != nil { + return nil, err + } + if config.WorkingDir == "" && !isLocalResourceLoader { + config.WorkingDir = filepath.Dir(local) + } + abs, err := filepath.Abs(local) + if err != nil { + abs = local + } + config.ConfigFiles[i] = types.ConfigFile{ + Filename: abs, + } + break + } + } + if config.WorkingDir == "" { + config.WorkingDir = workingDir + } + return config, nil +} + // Load reads a ConfigDetails and returns a fully loaded configuration. // Deprecated: use LoadWithContext. func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.Project, error) { @@ -470,6 +516,8 @@ func loadYamlFile(ctx context.Context, file types.ConfigFile, opts *Options, wor return err } + dict = OmitEmpty(dict) + // Canonical transformation can reveal duplicates, typically as ports can be a range and conflict with an override dict, err = override.EnforceUnicity(dict) return err @@ -675,6 +723,7 @@ func NormalizeProjectName(s string) string { var userDefinedKeys = []tree.Path{ "services", + "services.*.depends_on", "volumes", "networks", "secrets", @@ -687,7 +736,7 @@ func processExtensions(dict map[string]any, p tree.Path, extensions map[string]a for key, value := range dict { skip := false for _, uk := range userDefinedKeys { - if uk.Matches(p) { + if p.Matches(uk) { skip = true break } @@ -770,14 +819,14 @@ func secretConfigDecoderHook(from, to reflect.Type, data interface{}) (interface // Check if the input is a map and we're decoding into a SecretConfig if from.Kind() == reflect.Map && to == reflect.TypeOf(types.SecretConfig{}) { if v, ok := data.(map[string]interface{}); ok { - if ext, ok := v["#extensions"].(map[string]interface{}); ok { + if ext, ok := v[consts.Extensions].(map[string]interface{}); ok { if val, ok := ext[types.SecretConfigXValue].(string); ok { // Return a map with the Content field populated v["Content"] = val delete(ext, types.SecretConfigXValue) if len(ext) == 0 { - delete(v, "#extensions") + delete(v, consts.Extensions) } } } diff --git a/vendor/github.com/compose-spec/compose-go/v2/loader/normalize.go b/vendor/github.com/compose-spec/compose-go/v2/loader/normalize.go index e99b61b5..bae70be8 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/loader/normalize.go +++ b/vendor/github.com/compose-spec/compose-go/v2/loader/normalize.go @@ -18,6 +18,7 @@ package loader import ( "fmt" + "path" "strconv" "strings" @@ -102,6 +103,17 @@ func Normalize(dict map[string]any, env types.Mapping) (map[string]any, error) { } } + if v, ok := service["volumes"]; ok { + volumes := v.([]any) + for i, volume := range volumes { + vol := volume.(map[string]any) + target := vol["target"].(string) + vol["target"] = path.Clean(target) + volumes[i] = vol + } + service["volumes"] = volumes + } + if n, ok := service["volumes_from"]; ok { volumesFrom := n.([]any) for _, v := range volumesFrom { @@ -123,9 +135,9 @@ func Normalize(dict map[string]any, env types.Mapping) (map[string]any, error) { } services[name] = service } + dict["services"] = services } - setNameFromKey(dict) return dict, nil diff --git a/vendor/github.com/compose-spec/compose-go/v2/loader/omitEmpty.go b/vendor/github.com/compose-spec/compose-go/v2/loader/omitEmpty.go new file mode 100644 index 00000000..bc1cb1a5 --- /dev/null +++ b/vendor/github.com/compose-spec/compose-go/v2/loader/omitEmpty.go @@ -0,0 +1,74 @@ +/* + Copyright 2020 The Compose Specification Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package loader + +import "github.com/compose-spec/compose-go/v2/tree" + +var omitempty = []tree.Path{ + "services.*.dns"} + +// OmitEmpty removes empty attributes which are irrelevant when unset +func OmitEmpty(yaml map[string]any) map[string]any { + cleaned := omitEmpty(yaml, tree.NewPath()) + return cleaned.(map[string]any) +} + +func omitEmpty(data any, p tree.Path) any { + switch v := data.(type) { + case map[string]any: + for k, e := range v { + if isEmpty(e) && mustOmit(p) { + delete(v, k) + continue + } + + v[k] = omitEmpty(e, p.Next(k)) + } + return v + case []any: + var c []any + for _, e := range v { + if isEmpty(e) && mustOmit(p) { + continue + } + + c = append(c, omitEmpty(e, p.Next("[]"))) + } + return c + default: + return data + } +} + +func mustOmit(p tree.Path) bool { + for _, pattern := range omitempty { + if p.Matches(pattern) { + return true + } + } + return false +} + +func isEmpty(e any) bool { + if e == nil { + return true + } + if v, ok := e.(string); ok && v == "" { + return true + } + return false +} diff --git a/vendor/github.com/compose-spec/compose-go/v2/loader/reset.go b/vendor/github.com/compose-spec/compose-go/v2/loader/reset.go index 2b7f04c3..213d0e8f 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/loader/reset.go +++ b/vendor/github.com/compose-spec/compose-go/v2/loader/reset.go @@ -26,13 +26,15 @@ import ( ) type ResetProcessor struct { - target interface{} - paths []tree.Path + target interface{} + paths []tree.Path + visitedNodes map[*yaml.Node]string } // UnmarshalYAML implement yaml.Unmarshaler func (p *ResetProcessor) UnmarshalYAML(value *yaml.Node) error { resolved, err := p.resolveReset(value, tree.NewPath()) + p.visitedNodes = nil if err != nil { return err } @@ -41,10 +43,28 @@ func (p *ResetProcessor) UnmarshalYAML(value *yaml.Node) error { // resolveReset detects `!reset` tag being set on yaml nodes and record position in the yaml tree func (p *ResetProcessor) resolveReset(node *yaml.Node, path tree.Path) (*yaml.Node, error) { + pathStr := path.String() // If the path contains "<<", removing the "<<" element and merging the path - if strings.Contains(path.String(), ".<<") { - path = tree.NewPath(strings.Replace(path.String(), ".<<", "", 1)) + if strings.Contains(pathStr, ".<<") { + path = tree.NewPath(strings.Replace(pathStr, ".<<", "", 1)) } + + // Check for cycle + if p.visitedNodes == nil { + p.visitedNodes = make(map[*yaml.Node]string) + } + + // Check for cycle by seeing if the node has already been visited at this path + if previousPath, found := p.visitedNodes[node]; found { + // If the current node has been visited, we have a cycle if the previous path is a prefix + if strings.HasPrefix(pathStr, previousPath) { + return nil, fmt.Errorf("cycle detected at path: %s", pathStr) + } + } + + // Mark the current node as visited + p.visitedNodes[node] = pathStr + // If the node is an alias, We need to process the alias field in order to consider the !override and !reset tags if node.Kind == yaml.AliasNode { return p.resolveReset(node.Alias, path) diff --git a/vendor/github.com/compose-spec/compose-go/v2/override/merge.go b/vendor/github.com/compose-spec/compose-go/v2/override/merge.go index 8a468dde..697dbc74 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/override/merge.go +++ b/vendor/github.com/compose-spec/compose-go/v2/override/merge.go @@ -47,7 +47,7 @@ func init() { mergeSpecials["services.*.build"] = mergeBuild mergeSpecials["services.*.build.args"] = mergeToSequence mergeSpecials["services.*.build.additional_contexts"] = mergeToSequence - mergeSpecials["services.*.build.extra_hosts"] = mergeToSequence + mergeSpecials["services.*.build.extra_hosts"] = mergeExtraHosts mergeSpecials["services.*.build.labels"] = mergeToSequence mergeSpecials["services.*.command"] = override mergeSpecials["services.*.depends_on"] = mergeDependsOn @@ -58,7 +58,7 @@ func init() { mergeSpecials["services.*.entrypoint"] = override mergeSpecials["services.*.env_file"] = mergeToSequence mergeSpecials["services.*.environment"] = mergeToSequence - mergeSpecials["services.*.extra_hosts"] = mergeToSequence + mergeSpecials["services.*.extra_hosts"] = mergeExtraHosts mergeSpecials["services.*.healthcheck.test"] = override mergeSpecials["services.*.labels"] = mergeToSequence mergeSpecials["services.*.logging"] = mergeLogging @@ -163,6 +163,22 @@ func mergeNetworks(c any, o any, path tree.Path) (any, error) { return mergeMappings(right, left, path) } +func mergeExtraHosts(c any, o any, _ tree.Path) (any, error) { + right := convertIntoSequence(c) + left := convertIntoSequence(o) + // Rewrite content of left slice to remove duplicate elements + i := 0 + for _, v := range left { + if !slices.Contains(right, v) { + left[i] = v + i++ + } + } + // keep only not duplicated elements from left slice + left = left[:i] + return append(right, left...), nil +} + func mergeToSequence(c any, o any, _ tree.Path) (any, error) { right := convertIntoSequence(c) left := convertIntoSequence(o) @@ -172,15 +188,21 @@ func mergeToSequence(c any, o any, _ tree.Path) (any, error) { func convertIntoSequence(value any) []any { switch v := value.(type) { case map[string]any: - seq := make([]any, len(v)) - i := 0 - for k, v := range v { - if v == nil { - seq[i] = k + var seq []any + for k, val := range v { + if val == nil { + seq = append(seq, k) } else { - seq[i] = fmt.Sprintf("%s=%v", k, v) + switch vl := val.(type) { + // if val is an array we need to add the key with each value one by one + case []any: + for _, vlv := range vl { + seq = append(seq, fmt.Sprintf("%s=%v", k, vlv)) + } + default: + seq = append(seq, fmt.Sprintf("%s=%v", k, val)) + } } - i++ } slices.SortFunc(seq, func(a, b any) int { return cmp.Compare(a.(string), b.(string)) diff --git a/vendor/github.com/compose-spec/compose-go/v2/schema/compose-spec.json b/vendor/github.com/compose-spec/compose-go/v2/schema/compose-spec.json index a2f5e244..b95a1498 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/schema/compose-spec.json +++ b/vendor/github.com/compose-spec/compose-go/v2/schema/compose-spec.json @@ -267,6 +267,7 @@ }, "external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, "extra_hosts": {"$ref": "#/definitions/extra_hosts"}, + "gpus": {"$ref": "#/definitions/gpus"}, "group_add": { "type": "array", "items": { @@ -370,6 +371,8 @@ }, "uniqueItems": true }, + "post_start": {"type": "array", "items": {"$ref": "#/definitions/service_hook"}}, + "pre_stop": {"type": "array", "items": {"$ref": "#/definitions/service_hook"}}, "privileged": {"type": ["boolean", "string"]}, "profiles": {"$ref": "#/definitions/list_of_strings"}, "pull_policy": {"type": "string", "enum": [ @@ -416,6 +419,7 @@ "properties": { "propagation": {"type": "string"}, "create_host_path": {"type": ["boolean", "string"]}, + "recursive": {"type": "string", "enum": ["enabled", "disabled", "writable", "readonly"]}, "selinux": {"type": "string", "enum": ["z", "Z"]} }, "additionalProperties": false, @@ -500,11 +504,11 @@ }, "additionalProperties": false, "patternProperties": {"^x-": {}} - }, - "additionalProperties": false, - "patternProperties": {"^x-": {}} + } } - } + }, + "additionalProperties": false, + "patternProperties": {"^x-": {}} }, "deployment": { "id": "#/definitions/deployment", @@ -632,6 +636,26 @@ "devices": { "id": "#/definitions/devices", "type": "array", + "items": { + "type": "object", + "properties": { + "capabilities": {"$ref": "#/definitions/list_of_strings"}, + "count": {"type": ["string", "integer"]}, + "device_ids": {"$ref": "#/definitions/list_of_strings"}, + "driver":{"type": "string"}, + "options":{"$ref": "#/definitions/list_or_dict"} + }, + "additionalProperties": false, + "patternProperties": {"^x-": {}}, + "required": [ + "capabilities" + ] + } + }, + + "gpus": { + "id": "#/definitions/gpus", + "type": "array", "items": { "type": "object", "properties": { @@ -813,6 +837,20 @@ ] }, + "service_hook": { + "id": "#/definitions/service_hook", + "type": "object", + "properties": { + "command": {"$ref": "#/definitions/command"}, + "user": {"type": "string"}, + "privileged": {"type": ["boolean", "string"]}, + "working_dir": {"type": "string"}, + "environment": {"$ref": "#/definitions/list_or_dict"} + }, + "additionalProperties": false, + "patternProperties": {"^x-": {}} + }, + "env_file": { "oneOf": [ {"type": "string"}, @@ -828,6 +866,9 @@ "path": { "type": "string" }, + "format": { + "type": "string" + }, "required": { "type": ["boolean", "string"], "default": true @@ -878,7 +919,8 @@ "patternProperties": { ".+": { "type": ["string", "array"] - } + }, + "uniqueItems": false }, "additionalProperties": false }, diff --git a/vendor/github.com/compose-spec/compose-go/v2/transform/canonical.go b/vendor/github.com/compose-spec/compose-go/v2/transform/canonical.go index a248b4be..ff5bb37d 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/transform/canonical.go +++ b/vendor/github.com/compose-spec/compose-go/v2/transform/canonical.go @@ -33,6 +33,7 @@ func init() { transformers["services.*.extends"] = transformExtends transformers["services.*.networks"] = transformServiceNetworks transformers["services.*.volumes.*"] = transformVolumeMount + transformers["services.*.dns"] = transformStringOrList transformers["services.*.devices.*"] = transformDeviceMapping transformers["services.*.secrets.*"] = transformFileMount transformers["services.*.configs.*"] = transformFileMount @@ -48,6 +49,15 @@ func init() { transformers["include.*"] = transformInclude } +func transformStringOrList(data any, _ tree.Path, _ bool) (any, error) { + switch t := data.(type) { + case string: + return []any{t}, nil + default: + return data, nil + } +} + // Canonical transforms a compose model into canonical syntax func Canonical(yaml map[string]any, ignoreParseError bool) (map[string]any, error) { canonical, err := transform(yaml, tree.NewPath(), ignoreParseError) diff --git a/vendor/github.com/compose-spec/compose-go/v2/transform/defaults.go b/vendor/github.com/compose-spec/compose-go/v2/transform/defaults.go index 96693c65..041a6897 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/transform/defaults.go +++ b/vendor/github.com/compose-spec/compose-go/v2/transform/defaults.go @@ -26,6 +26,8 @@ func init() { defaultValues["services.*.build"] = defaultBuildContext defaultValues["services.*.secrets.*"] = defaultSecretMount defaultValues["services.*.ports.*"] = portDefaults + defaultValues["services.*.deploy.resources.reservations.devices.*"] = deviceRequestDefaults + defaultValues["services.*.gpus.*"] = deviceRequestDefaults } // SetDefaultValues transforms a compose model to set default values to missing attributes diff --git a/vendor/github.com/compose-spec/compose-go/v2/transform/devices.go b/vendor/github.com/compose-spec/compose-go/v2/transform/devices.go new file mode 100644 index 00000000..3ce7fa00 --- /dev/null +++ b/vendor/github.com/compose-spec/compose-go/v2/transform/devices.go @@ -0,0 +1,36 @@ +/* + Copyright 2020 The Compose Specification Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package transform + +import ( + "fmt" + + "github.com/compose-spec/compose-go/v2/tree" +) + +func deviceRequestDefaults(data any, p tree.Path, _ bool) (any, error) { + v, ok := data.(map[string]any) + if !ok { + return data, fmt.Errorf("%s: invalid type %T for device request", p, v) + } + _, hasCount := v["count"] + _, hasIds := v["device_ids"] + if !hasCount && !hasIds { + v["count"] = "all" + } + return v, nil +} diff --git a/vendor/github.com/compose-spec/compose-go/v2/types/cpus.go b/vendor/github.com/compose-spec/compose-go/v2/types/cpus.go new file mode 100644 index 00000000..f32c6e62 --- /dev/null +++ b/vendor/github.com/compose-spec/compose-go/v2/types/cpus.go @@ -0,0 +1,48 @@ +/* + Copyright 2020 The Compose Specification Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package types + +import ( + "fmt" + "strconv" +) + +type NanoCPUs float32 + +func (n *NanoCPUs) DecodeMapstructure(a any) error { + switch v := a.(type) { + case string: + f, err := strconv.ParseFloat(v, 64) + if err != nil { + return err + } + *n = NanoCPUs(f) + case int: + *n = NanoCPUs(v) + case float32: + *n = NanoCPUs(v) + case float64: + *n = NanoCPUs(v) + default: + return fmt.Errorf("unexpected value type %T for cpus", v) + } + return nil +} + +func (n *NanoCPUs) Value() float32 { + return float32(*n) +} diff --git a/vendor/github.com/compose-spec/compose-go/v2/types/derived.gen.go b/vendor/github.com/compose-spec/compose-go/v2/types/derived.gen.go index d5d1d024..d33ae280 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/types/derived.gen.go +++ b/vendor/github.com/compose-spec/compose-go/v2/types/derived.gen.go @@ -279,7 +279,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) { } else { dst.Devices = make([]DeviceMapping, len(src.Devices)) } - copy(dst.Devices, src.Devices) + deriveDeepCopy_12(dst.Devices, src.Devices) } if src.DNS == nil { dst.DNS = nil @@ -357,7 +357,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) { } if src.Environment != nil { dst.Environment = make(map[string]*string, len(src.Environment)) - deriveDeepCopy_12(dst.Environment, src.Environment) + deriveDeepCopy_13(dst.Environment, src.Environment) } else { dst.Environment = nil } @@ -423,7 +423,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) { } if src.ExtraHosts != nil { dst.ExtraHosts = make(map[string][]string, len(src.ExtraHosts)) - deriveDeepCopy_13(dst.ExtraHosts, src.ExtraHosts) + deriveDeepCopy_14(dst.ExtraHosts, src.ExtraHosts) } else { dst.ExtraHosts = nil } @@ -445,12 +445,30 @@ func deriveDeepCopyService(dst, src *ServiceConfig) { } copy(dst.GroupAdd, src.GroupAdd) } + if src.Gpus == nil { + dst.Gpus = nil + } else { + if dst.Gpus != nil { + if len(src.Gpus) > len(dst.Gpus) { + if cap(dst.Gpus) >= len(src.Gpus) { + dst.Gpus = (dst.Gpus)[:len(src.Gpus)] + } else { + dst.Gpus = make([]DeviceRequest, len(src.Gpus)) + } + } else if len(src.Gpus) < len(dst.Gpus) { + dst.Gpus = (dst.Gpus)[:len(src.Gpus)] + } + } else { + dst.Gpus = make([]DeviceRequest, len(src.Gpus)) + } + deriveDeepCopy_15(dst.Gpus, src.Gpus) + } dst.Hostname = src.Hostname if src.HealthCheck == nil { dst.HealthCheck = nil } else { dst.HealthCheck = new(HealthCheckConfig) - deriveDeepCopy_14(dst.HealthCheck, src.HealthCheck) + deriveDeepCopy_16(dst.HealthCheck, src.HealthCheck) } dst.Image = src.Image if src.Init == nil { @@ -495,7 +513,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) { dst.Logging = nil } else { dst.Logging = new(LoggingConfig) - deriveDeepCopy_15(dst.Logging, src.Logging) + deriveDeepCopy_17(dst.Logging, src.Logging) } dst.LogDriver = src.LogDriver if src.LogOpt != nil { @@ -513,7 +531,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) { dst.NetworkMode = src.NetworkMode if src.Networks != nil { dst.Networks = make(map[string]*ServiceNetworkConfig, len(src.Networks)) - deriveDeepCopy_16(dst.Networks, src.Networks) + deriveDeepCopy_18(dst.Networks, src.Networks) } else { dst.Networks = nil } @@ -538,7 +556,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) { } else { dst.Ports = make([]ServicePortConfig, len(src.Ports)) } - deriveDeepCopy_17(dst.Ports, src.Ports) + deriveDeepCopy_19(dst.Ports, src.Ports) } dst.Privileged = src.Privileged dst.PullPolicy = src.PullPolicy @@ -567,7 +585,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) { } else { dst.Secrets = make([]ServiceSecretConfig, len(src.Secrets)) } - deriveDeepCopy_18(dst.Secrets, src.Secrets) + deriveDeepCopy_20(dst.Secrets, src.Secrets) } if src.SecurityOpt == nil { dst.SecurityOpt = nil @@ -629,7 +647,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) { dst.Tty = src.Tty if src.Ulimits != nil { dst.Ulimits = make(map[string]*UlimitsConfig, len(src.Ulimits)) - deriveDeepCopy_19(dst.Ulimits, src.Ulimits) + deriveDeepCopy_21(dst.Ulimits, src.Ulimits) } else { dst.Ulimits = nil } @@ -653,7 +671,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) { } else { dst.Volumes = make([]ServiceVolumeConfig, len(src.Volumes)) } - deriveDeepCopy_20(dst.Volumes, src.Volumes) + deriveDeepCopy_22(dst.Volumes, src.Volumes) } if src.VolumesFrom == nil { dst.VolumesFrom = nil @@ -674,6 +692,42 @@ func deriveDeepCopyService(dst, src *ServiceConfig) { copy(dst.VolumesFrom, src.VolumesFrom) } dst.WorkingDir = src.WorkingDir + if src.PostStart == nil { + dst.PostStart = nil + } else { + if dst.PostStart != nil { + if len(src.PostStart) > len(dst.PostStart) { + if cap(dst.PostStart) >= len(src.PostStart) { + dst.PostStart = (dst.PostStart)[:len(src.PostStart)] + } else { + dst.PostStart = make([]ServiceHook, len(src.PostStart)) + } + } else if len(src.PostStart) < len(dst.PostStart) { + dst.PostStart = (dst.PostStart)[:len(src.PostStart)] + } + } else { + dst.PostStart = make([]ServiceHook, len(src.PostStart)) + } + deriveDeepCopy_23(dst.PostStart, src.PostStart) + } + if src.PreStop == nil { + dst.PreStop = nil + } else { + if dst.PreStop != nil { + if len(src.PreStop) > len(dst.PreStop) { + if cap(dst.PreStop) >= len(src.PreStop) { + dst.PreStop = (dst.PreStop)[:len(src.PreStop)] + } else { + dst.PreStop = make([]ServiceHook, len(src.PreStop)) + } + } else if len(src.PreStop) < len(dst.PreStop) { + dst.PreStop = (dst.PreStop)[:len(src.PreStop)] + } + } else { + dst.PreStop = make([]ServiceHook, len(src.PreStop)) + } + deriveDeepCopy_23(dst.PreStop, src.PreStop) + } if src.Extensions != nil { dst.Extensions = make(map[string]any, len(src.Extensions)) src.Extensions.DeepCopy(dst.Extensions) @@ -698,7 +752,7 @@ func deriveDeepCopy_(dst, src map[string]NetworkConfig) { for src_key, src_value := range src { func() { field := new(NetworkConfig) - deriveDeepCopy_21(field, &src_value) + deriveDeepCopy_24(field, &src_value) dst[src_key] = *field }() } @@ -709,7 +763,7 @@ func deriveDeepCopy_1(dst, src map[string]VolumeConfig) { for src_key, src_value := range src { func() { field := new(VolumeConfig) - deriveDeepCopy_22(field, &src_value) + deriveDeepCopy_25(field, &src_value) dst[src_key] = *field }() } @@ -720,7 +774,7 @@ func deriveDeepCopy_2(dst, src map[string]SecretConfig) { for src_key, src_value := range src { func() { field := new(SecretConfig) - deriveDeepCopy_23(field, &src_value) + deriveDeepCopy_26(field, &src_value) dst[src_key] = *field }() } @@ -731,7 +785,7 @@ func deriveDeepCopy_3(dst, src map[string]ConfigObjConfig) { for src_key, src_value := range src { func() { field := new(ConfigObjConfig) - deriveDeepCopy_24(field, &src_value) + deriveDeepCopy_27(field, &src_value) dst[src_key] = *field }() } @@ -769,7 +823,7 @@ func deriveDeepCopy_5(dst, src *BuildConfig) { } if src.Args != nil { dst.Args = make(map[string]*string, len(src.Args)) - deriveDeepCopy_12(dst.Args, src.Args) + deriveDeepCopy_13(dst.Args, src.Args) } else { dst.Args = nil } @@ -843,7 +897,7 @@ func deriveDeepCopy_5(dst, src *BuildConfig) { dst.Pull = src.Pull if src.ExtraHosts != nil { dst.ExtraHosts = make(map[string][]string, len(src.ExtraHosts)) - deriveDeepCopy_13(dst.ExtraHosts, src.ExtraHosts) + deriveDeepCopy_14(dst.ExtraHosts, src.ExtraHosts) } else { dst.ExtraHosts = nil } @@ -866,7 +920,7 @@ func deriveDeepCopy_5(dst, src *BuildConfig) { } else { dst.Secrets = make([]ServiceSecretConfig, len(src.Secrets)) } - deriveDeepCopy_18(dst.Secrets, src.Secrets) + deriveDeepCopy_20(dst.Secrets, src.Secrets) } dst.ShmSize = src.ShmSize if src.Tags == nil { @@ -889,7 +943,7 @@ func deriveDeepCopy_5(dst, src *BuildConfig) { } if src.Ulimits != nil { dst.Ulimits = make(map[string]*UlimitsConfig, len(src.Ulimits)) - deriveDeepCopy_19(dst.Ulimits, src.Ulimits) + deriveDeepCopy_21(dst.Ulimits, src.Ulimits) } else { dst.Ulimits = nil } @@ -938,7 +992,7 @@ func deriveDeepCopy_6(dst, src *DevelopConfig) { } else { dst.Watch = make([]Trigger, len(src.Watch)) } - deriveDeepCopy_25(dst.Watch, src.Watch) + deriveDeepCopy_28(dst.Watch, src.Watch) } if src.Extensions != nil { dst.Extensions = make(map[string]any, len(src.Extensions)) @@ -967,7 +1021,7 @@ func deriveDeepCopy_7(dst, src *BlkioConfig) { } else { dst.WeightDevice = make([]WeightDevice, len(src.WeightDevice)) } - deriveDeepCopy_26(dst.WeightDevice, src.WeightDevice) + deriveDeepCopy_29(dst.WeightDevice, src.WeightDevice) } if src.DeviceReadBps == nil { dst.DeviceReadBps = nil @@ -985,7 +1039,7 @@ func deriveDeepCopy_7(dst, src *BlkioConfig) { } else { dst.DeviceReadBps = make([]ThrottleDevice, len(src.DeviceReadBps)) } - deriveDeepCopy_27(dst.DeviceReadBps, src.DeviceReadBps) + deriveDeepCopy_30(dst.DeviceReadBps, src.DeviceReadBps) } if src.DeviceReadIOps == nil { dst.DeviceReadIOps = nil @@ -1003,7 +1057,7 @@ func deriveDeepCopy_7(dst, src *BlkioConfig) { } else { dst.DeviceReadIOps = make([]ThrottleDevice, len(src.DeviceReadIOps)) } - deriveDeepCopy_27(dst.DeviceReadIOps, src.DeviceReadIOps) + deriveDeepCopy_30(dst.DeviceReadIOps, src.DeviceReadIOps) } if src.DeviceWriteBps == nil { dst.DeviceWriteBps = nil @@ -1021,7 +1075,7 @@ func deriveDeepCopy_7(dst, src *BlkioConfig) { } else { dst.DeviceWriteBps = make([]ThrottleDevice, len(src.DeviceWriteBps)) } - deriveDeepCopy_27(dst.DeviceWriteBps, src.DeviceWriteBps) + deriveDeepCopy_30(dst.DeviceWriteBps, src.DeviceWriteBps) } if src.DeviceWriteIOps == nil { dst.DeviceWriteIOps = nil @@ -1039,7 +1093,7 @@ func deriveDeepCopy_7(dst, src *BlkioConfig) { } else { dst.DeviceWriteIOps = make([]ThrottleDevice, len(src.DeviceWriteIOps)) } - deriveDeepCopy_27(dst.DeviceWriteIOps, src.DeviceWriteIOps) + deriveDeepCopy_30(dst.DeviceWriteIOps, src.DeviceWriteIOps) } if src.Extensions != nil { dst.Extensions = make(map[string]any, len(src.Extensions)) @@ -1054,7 +1108,7 @@ func deriveDeepCopy_8(dst, src []ServiceConfigObjConfig) { for src_i, src_value := range src { func() { field := new(ServiceConfigObjConfig) - deriveDeepCopy_28(field, &src_value) + deriveDeepCopy_31(field, &src_value) dst[src_i] = *field }() } @@ -1078,7 +1132,7 @@ func deriveDeepCopy_10(dst, src map[string]ServiceDependency) { for src_key, src_value := range src { func() { field := new(ServiceDependency) - deriveDeepCopy_29(field, &src_value) + deriveDeepCopy_32(field, &src_value) dst[src_key] = *field }() } @@ -1103,28 +1157,28 @@ func deriveDeepCopy_11(dst, src *DeployConfig) { dst.UpdateConfig = nil } else { dst.UpdateConfig = new(UpdateConfig) - deriveDeepCopy_30(dst.UpdateConfig, src.UpdateConfig) + deriveDeepCopy_33(dst.UpdateConfig, src.UpdateConfig) } if src.RollbackConfig == nil { dst.RollbackConfig = nil } else { dst.RollbackConfig = new(UpdateConfig) - deriveDeepCopy_30(dst.RollbackConfig, src.RollbackConfig) + deriveDeepCopy_33(dst.RollbackConfig, src.RollbackConfig) } func() { field := new(Resources) - deriveDeepCopy_31(field, &src.Resources) + deriveDeepCopy_34(field, &src.Resources) dst.Resources = *field }() if src.RestartPolicy == nil { dst.RestartPolicy = nil } else { dst.RestartPolicy = new(RestartPolicy) - deriveDeepCopy_32(dst.RestartPolicy, src.RestartPolicy) + deriveDeepCopy_35(dst.RestartPolicy, src.RestartPolicy) } func() { field := new(Placement) - deriveDeepCopy_33(field, &src.Placement) + deriveDeepCopy_36(field, &src.Placement) dst.Placement = *field }() dst.EndpointMode = src.EndpointMode @@ -1137,7 +1191,18 @@ func deriveDeepCopy_11(dst, src *DeployConfig) { } // deriveDeepCopy_12 recursively copies the contents of src into dst. -func deriveDeepCopy_12(dst, src map[string]*string) { +func deriveDeepCopy_12(dst, src []DeviceMapping) { + for src_i, src_value := range src { + func() { + field := new(DeviceMapping) + deriveDeepCopy_37(field, &src_value) + dst[src_i] = *field + }() + } +} + +// deriveDeepCopy_13 recursively copies the contents of src into dst. +func deriveDeepCopy_13(dst, src map[string]*string) { for src_key, src_value := range src { if src_value == nil { dst[src_key] = nil @@ -1151,8 +1216,8 @@ func deriveDeepCopy_12(dst, src map[string]*string) { } } -// deriveDeepCopy_13 recursively copies the contents of src into dst. -func deriveDeepCopy_13(dst, src map[string][]string) { +// deriveDeepCopy_14 recursively copies the contents of src into dst. +func deriveDeepCopy_14(dst, src map[string][]string) { for src_key, src_value := range src { if src_value == nil { dst[src_key] = nil @@ -1178,8 +1243,19 @@ func deriveDeepCopy_13(dst, src map[string][]string) { } } -// deriveDeepCopy_14 recursively copies the contents of src into dst. -func deriveDeepCopy_14(dst, src *HealthCheckConfig) { +// deriveDeepCopy_15 recursively copies the contents of src into dst. +func deriveDeepCopy_15(dst, src []DeviceRequest) { + for src_i, src_value := range src { + func() { + field := new(DeviceRequest) + deriveDeepCopy_38(field, &src_value) + dst[src_i] = *field + }() + } +} + +// deriveDeepCopy_16 recursively copies the contents of src into dst. +func deriveDeepCopy_16(dst, src *HealthCheckConfig) { if src.Test == nil { dst.Test = nil } else { @@ -1237,8 +1313,8 @@ func deriveDeepCopy_14(dst, src *HealthCheckConfig) { } } -// deriveDeepCopy_15 recursively copies the contents of src into dst. -func deriveDeepCopy_15(dst, src *LoggingConfig) { +// deriveDeepCopy_17 recursively copies the contents of src into dst. +func deriveDeepCopy_17(dst, src *LoggingConfig) { dst.Driver = src.Driver if src.Options != nil { dst.Options = make(map[string]string, len(src.Options)) @@ -1254,8 +1330,8 @@ func deriveDeepCopy_15(dst, src *LoggingConfig) { } } -// deriveDeepCopy_16 recursively copies the contents of src into dst. -func deriveDeepCopy_16(dst, src map[string]*ServiceNetworkConfig) { +// deriveDeepCopy_18 recursively copies the contents of src into dst. +func deriveDeepCopy_18(dst, src map[string]*ServiceNetworkConfig) { for src_key, src_value := range src { if src_value == nil { dst[src_key] = nil @@ -1264,35 +1340,35 @@ func deriveDeepCopy_16(dst, src map[string]*ServiceNetworkConfig) { dst[src_key] = nil } else { dst[src_key] = new(ServiceNetworkConfig) - deriveDeepCopy_34(dst[src_key], src_value) + deriveDeepCopy_39(dst[src_key], src_value) } } } -// deriveDeepCopy_17 recursively copies the contents of src into dst. -func deriveDeepCopy_17(dst, src []ServicePortConfig) { +// deriveDeepCopy_19 recursively copies the contents of src into dst. +func deriveDeepCopy_19(dst, src []ServicePortConfig) { for src_i, src_value := range src { func() { field := new(ServicePortConfig) - deriveDeepCopy_35(field, &src_value) + deriveDeepCopy_40(field, &src_value) dst[src_i] = *field }() } } -// deriveDeepCopy_18 recursively copies the contents of src into dst. -func deriveDeepCopy_18(dst, src []ServiceSecretConfig) { +// deriveDeepCopy_20 recursively copies the contents of src into dst. +func deriveDeepCopy_20(dst, src []ServiceSecretConfig) { for src_i, src_value := range src { func() { field := new(ServiceSecretConfig) - deriveDeepCopy_36(field, &src_value) + deriveDeepCopy_41(field, &src_value) dst[src_i] = *field }() } } -// deriveDeepCopy_19 recursively copies the contents of src into dst. -func deriveDeepCopy_19(dst, src map[string]*UlimitsConfig) { +// deriveDeepCopy_21 recursively copies the contents of src into dst. +func deriveDeepCopy_21(dst, src map[string]*UlimitsConfig) { for src_key, src_value := range src { if src_value == nil { dst[src_key] = nil @@ -1301,24 +1377,35 @@ func deriveDeepCopy_19(dst, src map[string]*UlimitsConfig) { dst[src_key] = nil } else { dst[src_key] = new(UlimitsConfig) - deriveDeepCopy_37(dst[src_key], src_value) + deriveDeepCopy_42(dst[src_key], src_value) } } } -// deriveDeepCopy_20 recursively copies the contents of src into dst. -func deriveDeepCopy_20(dst, src []ServiceVolumeConfig) { +// deriveDeepCopy_22 recursively copies the contents of src into dst. +func deriveDeepCopy_22(dst, src []ServiceVolumeConfig) { for src_i, src_value := range src { func() { field := new(ServiceVolumeConfig) - deriveDeepCopy_38(field, &src_value) + deriveDeepCopy_43(field, &src_value) dst[src_i] = *field }() } } -// deriveDeepCopy_21 recursively copies the contents of src into dst. -func deriveDeepCopy_21(dst, src *NetworkConfig) { +// deriveDeepCopy_23 recursively copies the contents of src into dst. +func deriveDeepCopy_23(dst, src []ServiceHook) { + for src_i, src_value := range src { + func() { + field := new(ServiceHook) + deriveDeepCopy_44(field, &src_value) + dst[src_i] = *field + }() + } +} + +// deriveDeepCopy_24 recursively copies the contents of src into dst. +func deriveDeepCopy_24(dst, src *NetworkConfig) { dst.Name = src.Name dst.Driver = src.Driver if src.DriverOpts != nil { @@ -1329,7 +1416,7 @@ func deriveDeepCopy_21(dst, src *NetworkConfig) { } func() { field := new(IPAMConfig) - deriveDeepCopy_39(field, &src.Ipam) + deriveDeepCopy_45(field, &src.Ipam) dst.Ipam = *field }() dst.External = src.External @@ -1355,124 +1442,124 @@ func deriveDeepCopy_21(dst, src *NetworkConfig) { } } -// deriveDeepCopy_22 recursively copies the contents of src into dst. -func deriveDeepCopy_22(dst, src *VolumeConfig) { - dst.Name = src.Name - dst.Driver = src.Driver - if src.DriverOpts != nil { - dst.DriverOpts = make(map[string]string, len(src.DriverOpts)) - deriveDeepCopy_4(dst.DriverOpts, src.DriverOpts) - } else { - dst.DriverOpts = nil - } - dst.External = src.External - if src.Labels != nil { - dst.Labels = make(map[string]string, len(src.Labels)) - deriveDeepCopy_4(dst.Labels, src.Labels) - } else { - dst.Labels = nil - } - if src.Extensions != nil { - dst.Extensions = make(map[string]any, len(src.Extensions)) - src.Extensions.DeepCopy(dst.Extensions) - } else { - dst.Extensions = nil - } -} - -// deriveDeepCopy_23 recursively copies the contents of src into dst. -func deriveDeepCopy_23(dst, src *SecretConfig) { - dst.Name = src.Name - dst.File = src.File - dst.Environment = src.Environment - dst.Content = src.Content - dst.External = src.External - if src.Labels != nil { - dst.Labels = make(map[string]string, len(src.Labels)) - deriveDeepCopy_4(dst.Labels, src.Labels) - } else { - dst.Labels = nil - } - dst.Driver = src.Driver - if src.DriverOpts != nil { - dst.DriverOpts = make(map[string]string, len(src.DriverOpts)) - deriveDeepCopy_4(dst.DriverOpts, src.DriverOpts) - } else { - dst.DriverOpts = nil - } - dst.TemplateDriver = src.TemplateDriver - if src.Extensions != nil { - dst.Extensions = make(map[string]any, len(src.Extensions)) - src.Extensions.DeepCopy(dst.Extensions) - } else { - dst.Extensions = nil - } -} - -// deriveDeepCopy_24 recursively copies the contents of src into dst. -func deriveDeepCopy_24(dst, src *ConfigObjConfig) { - dst.Name = src.Name - dst.File = src.File - dst.Environment = src.Environment - dst.Content = src.Content - dst.External = src.External - if src.Labels != nil { - dst.Labels = make(map[string]string, len(src.Labels)) - deriveDeepCopy_4(dst.Labels, src.Labels) - } else { - dst.Labels = nil - } - dst.Driver = src.Driver - if src.DriverOpts != nil { - dst.DriverOpts = make(map[string]string, len(src.DriverOpts)) - deriveDeepCopy_4(dst.DriverOpts, src.DriverOpts) - } else { - dst.DriverOpts = nil - } - dst.TemplateDriver = src.TemplateDriver - if src.Extensions != nil { - dst.Extensions = make(map[string]any, len(src.Extensions)) - src.Extensions.DeepCopy(dst.Extensions) - } else { - dst.Extensions = nil - } -} - // deriveDeepCopy_25 recursively copies the contents of src into dst. -func deriveDeepCopy_25(dst, src []Trigger) { - for src_i, src_value := range src { - func() { - field := new(Trigger) - deriveDeepCopy_40(field, &src_value) - dst[src_i] = *field - }() +func deriveDeepCopy_25(dst, src *VolumeConfig) { + dst.Name = src.Name + dst.Driver = src.Driver + if src.DriverOpts != nil { + dst.DriverOpts = make(map[string]string, len(src.DriverOpts)) + deriveDeepCopy_4(dst.DriverOpts, src.DriverOpts) + } else { + dst.DriverOpts = nil + } + dst.External = src.External + if src.Labels != nil { + dst.Labels = make(map[string]string, len(src.Labels)) + deriveDeepCopy_4(dst.Labels, src.Labels) + } else { + dst.Labels = nil + } + if src.Extensions != nil { + dst.Extensions = make(map[string]any, len(src.Extensions)) + src.Extensions.DeepCopy(dst.Extensions) + } else { + dst.Extensions = nil } } // deriveDeepCopy_26 recursively copies the contents of src into dst. -func deriveDeepCopy_26(dst, src []WeightDevice) { - for src_i, src_value := range src { - func() { - field := new(WeightDevice) - deriveDeepCopy_41(field, &src_value) - dst[src_i] = *field - }() +func deriveDeepCopy_26(dst, src *SecretConfig) { + dst.Name = src.Name + dst.File = src.File + dst.Environment = src.Environment + dst.Content = src.Content + dst.External = src.External + if src.Labels != nil { + dst.Labels = make(map[string]string, len(src.Labels)) + deriveDeepCopy_4(dst.Labels, src.Labels) + } else { + dst.Labels = nil + } + dst.Driver = src.Driver + if src.DriverOpts != nil { + dst.DriverOpts = make(map[string]string, len(src.DriverOpts)) + deriveDeepCopy_4(dst.DriverOpts, src.DriverOpts) + } else { + dst.DriverOpts = nil + } + dst.TemplateDriver = src.TemplateDriver + if src.Extensions != nil { + dst.Extensions = make(map[string]any, len(src.Extensions)) + src.Extensions.DeepCopy(dst.Extensions) + } else { + dst.Extensions = nil } } // deriveDeepCopy_27 recursively copies the contents of src into dst. -func deriveDeepCopy_27(dst, src []ThrottleDevice) { +func deriveDeepCopy_27(dst, src *ConfigObjConfig) { + dst.Name = src.Name + dst.File = src.File + dst.Environment = src.Environment + dst.Content = src.Content + dst.External = src.External + if src.Labels != nil { + dst.Labels = make(map[string]string, len(src.Labels)) + deriveDeepCopy_4(dst.Labels, src.Labels) + } else { + dst.Labels = nil + } + dst.Driver = src.Driver + if src.DriverOpts != nil { + dst.DriverOpts = make(map[string]string, len(src.DriverOpts)) + deriveDeepCopy_4(dst.DriverOpts, src.DriverOpts) + } else { + dst.DriverOpts = nil + } + dst.TemplateDriver = src.TemplateDriver + if src.Extensions != nil { + dst.Extensions = make(map[string]any, len(src.Extensions)) + src.Extensions.DeepCopy(dst.Extensions) + } else { + dst.Extensions = nil + } +} + +// deriveDeepCopy_28 recursively copies the contents of src into dst. +func deriveDeepCopy_28(dst, src []Trigger) { for src_i, src_value := range src { func() { - field := new(ThrottleDevice) - deriveDeepCopy_42(field, &src_value) + field := new(Trigger) + deriveDeepCopy_46(field, &src_value) dst[src_i] = *field }() } } -// deriveDeepCopy_28 recursively copies the contents of src into dst. -func deriveDeepCopy_28(dst, src *ServiceConfigObjConfig) { +// deriveDeepCopy_29 recursively copies the contents of src into dst. +func deriveDeepCopy_29(dst, src []WeightDevice) { + for src_i, src_value := range src { + func() { + field := new(WeightDevice) + deriveDeepCopy_47(field, &src_value) + dst[src_i] = *field + }() + } +} + +// deriveDeepCopy_30 recursively copies the contents of src into dst. +func deriveDeepCopy_30(dst, src []ThrottleDevice) { + for src_i, src_value := range src { + func() { + field := new(ThrottleDevice) + deriveDeepCopy_48(field, &src_value) + dst[src_i] = *field + }() + } +} + +// deriveDeepCopy_31 recursively copies the contents of src into dst. +func deriveDeepCopy_31(dst, src *ServiceConfigObjConfig) { dst.Source = src.Source dst.Target = src.Target dst.UID = src.UID @@ -1491,8 +1578,8 @@ func deriveDeepCopy_28(dst, src *ServiceConfigObjConfig) { } } -// deriveDeepCopy_29 recursively copies the contents of src into dst. -func deriveDeepCopy_29(dst, src *ServiceDependency) { +// deriveDeepCopy_32 recursively copies the contents of src into dst. +func deriveDeepCopy_32(dst, src *ServiceDependency) { dst.Condition = src.Condition dst.Restart = src.Restart if src.Extensions != nil { @@ -1504,8 +1591,8 @@ func deriveDeepCopy_29(dst, src *ServiceDependency) { dst.Required = src.Required } -// deriveDeepCopy_30 recursively copies the contents of src into dst. -func deriveDeepCopy_30(dst, src *UpdateConfig) { +// deriveDeepCopy_33 recursively copies the contents of src into dst. +func deriveDeepCopy_33(dst, src *UpdateConfig) { if src.Parallelism == nil { dst.Parallelism = nil } else { @@ -1525,19 +1612,19 @@ func deriveDeepCopy_30(dst, src *UpdateConfig) { } } -// deriveDeepCopy_31 recursively copies the contents of src into dst. -func deriveDeepCopy_31(dst, src *Resources) { +// deriveDeepCopy_34 recursively copies the contents of src into dst. +func deriveDeepCopy_34(dst, src *Resources) { if src.Limits == nil { dst.Limits = nil } else { dst.Limits = new(Resource) - deriveDeepCopy_43(dst.Limits, src.Limits) + deriveDeepCopy_49(dst.Limits, src.Limits) } if src.Reservations == nil { dst.Reservations = nil } else { dst.Reservations = new(Resource) - deriveDeepCopy_43(dst.Reservations, src.Reservations) + deriveDeepCopy_49(dst.Reservations, src.Reservations) } if src.Extensions != nil { dst.Extensions = make(map[string]any, len(src.Extensions)) @@ -1547,8 +1634,8 @@ func deriveDeepCopy_31(dst, src *Resources) { } } -// deriveDeepCopy_32 recursively copies the contents of src into dst. -func deriveDeepCopy_32(dst, src *RestartPolicy) { +// deriveDeepCopy_35 recursively copies the contents of src into dst. +func deriveDeepCopy_35(dst, src *RestartPolicy) { dst.Condition = src.Condition if src.Delay == nil { dst.Delay = nil @@ -1576,8 +1663,8 @@ func deriveDeepCopy_32(dst, src *RestartPolicy) { } } -// deriveDeepCopy_33 recursively copies the contents of src into dst. -func deriveDeepCopy_33(dst, src *Placement) { +// deriveDeepCopy_36 recursively copies the contents of src into dst. +func deriveDeepCopy_36(dst, src *Placement) { if src.Constraints == nil { dst.Constraints = nil } else { @@ -1612,7 +1699,7 @@ func deriveDeepCopy_33(dst, src *Placement) { } else { dst.Preferences = make([]PlacementPreferences, len(src.Preferences)) } - deriveDeepCopy_44(dst.Preferences, src.Preferences) + deriveDeepCopy_50(dst.Preferences, src.Preferences) } dst.MaxReplicas = src.MaxReplicas if src.Extensions != nil { @@ -1623,8 +1710,69 @@ func deriveDeepCopy_33(dst, src *Placement) { } } -// deriveDeepCopy_34 recursively copies the contents of src into dst. -func deriveDeepCopy_34(dst, src *ServiceNetworkConfig) { +// deriveDeepCopy_37 recursively copies the contents of src into dst. +func deriveDeepCopy_37(dst, src *DeviceMapping) { + dst.Source = src.Source + dst.Target = src.Target + dst.Permissions = src.Permissions + if src.Extensions != nil { + dst.Extensions = make(map[string]any, len(src.Extensions)) + src.Extensions.DeepCopy(dst.Extensions) + } else { + dst.Extensions = nil + } +} + +// deriveDeepCopy_38 recursively copies the contents of src into dst. +func deriveDeepCopy_38(dst, src *DeviceRequest) { + if src.Capabilities == nil { + dst.Capabilities = nil + } else { + if dst.Capabilities != nil { + if len(src.Capabilities) > len(dst.Capabilities) { + if cap(dst.Capabilities) >= len(src.Capabilities) { + dst.Capabilities = (dst.Capabilities)[:len(src.Capabilities)] + } else { + dst.Capabilities = make([]string, len(src.Capabilities)) + } + } else if len(src.Capabilities) < len(dst.Capabilities) { + dst.Capabilities = (dst.Capabilities)[:len(src.Capabilities)] + } + } else { + dst.Capabilities = make([]string, len(src.Capabilities)) + } + copy(dst.Capabilities, src.Capabilities) + } + dst.Driver = src.Driver + dst.Count = src.Count + if src.IDs == nil { + dst.IDs = nil + } else { + if dst.IDs != nil { + if len(src.IDs) > len(dst.IDs) { + if cap(dst.IDs) >= len(src.IDs) { + dst.IDs = (dst.IDs)[:len(src.IDs)] + } else { + dst.IDs = make([]string, len(src.IDs)) + } + } else if len(src.IDs) < len(dst.IDs) { + dst.IDs = (dst.IDs)[:len(src.IDs)] + } + } else { + dst.IDs = make([]string, len(src.IDs)) + } + copy(dst.IDs, src.IDs) + } + if src.Options != nil { + dst.Options = make(map[string]string, len(src.Options)) + deriveDeepCopy_4(dst.Options, src.Options) + } else { + dst.Options = nil + } +} + +// deriveDeepCopy_39 recursively copies the contents of src into dst. +func deriveDeepCopy_39(dst, src *ServiceNetworkConfig) { dst.Priority = src.Priority if src.Aliases == nil { dst.Aliases = nil @@ -1679,8 +1827,8 @@ func deriveDeepCopy_34(dst, src *ServiceNetworkConfig) { } } -// deriveDeepCopy_35 recursively copies the contents of src into dst. -func deriveDeepCopy_35(dst, src *ServicePortConfig) { +// deriveDeepCopy_40 recursively copies the contents of src into dst. +func deriveDeepCopy_40(dst, src *ServicePortConfig) { dst.Name = src.Name dst.Mode = src.Mode dst.HostIP = src.HostIP @@ -1696,8 +1844,8 @@ func deriveDeepCopy_35(dst, src *ServicePortConfig) { } } -// deriveDeepCopy_36 recursively copies the contents of src into dst. -func deriveDeepCopy_36(dst, src *ServiceSecretConfig) { +// deriveDeepCopy_41 recursively copies the contents of src into dst. +func deriveDeepCopy_41(dst, src *ServiceSecretConfig) { dst.Source = src.Source dst.Target = src.Target dst.UID = src.UID @@ -1716,8 +1864,8 @@ func deriveDeepCopy_36(dst, src *ServiceSecretConfig) { } } -// deriveDeepCopy_37 recursively copies the contents of src into dst. -func deriveDeepCopy_37(dst, src *UlimitsConfig) { +// deriveDeepCopy_42 recursively copies the contents of src into dst. +func deriveDeepCopy_42(dst, src *UlimitsConfig) { dst.Single = src.Single dst.Soft = src.Soft dst.Hard = src.Hard @@ -1729,8 +1877,8 @@ func deriveDeepCopy_37(dst, src *UlimitsConfig) { } } -// deriveDeepCopy_38 recursively copies the contents of src into dst. -func deriveDeepCopy_38(dst, src *ServiceVolumeConfig) { +// deriveDeepCopy_43 recursively copies the contents of src into dst. +func deriveDeepCopy_43(dst, src *ServiceVolumeConfig) { dst.Type = src.Type dst.Source = src.Source dst.Target = src.Target @@ -1740,19 +1888,19 @@ func deriveDeepCopy_38(dst, src *ServiceVolumeConfig) { dst.Bind = nil } else { dst.Bind = new(ServiceVolumeBind) - deriveDeepCopy_45(dst.Bind, src.Bind) + deriveDeepCopy_51(dst.Bind, src.Bind) } if src.Volume == nil { dst.Volume = nil } else { dst.Volume = new(ServiceVolumeVolume) - deriveDeepCopy_46(dst.Volume, src.Volume) + deriveDeepCopy_52(dst.Volume, src.Volume) } if src.Tmpfs == nil { dst.Tmpfs = nil } else { dst.Tmpfs = new(ServiceVolumeTmpfs) - deriveDeepCopy_47(dst.Tmpfs, src.Tmpfs) + deriveDeepCopy_53(dst.Tmpfs, src.Tmpfs) } if src.Extensions != nil { dst.Extensions = make(map[string]any, len(src.Extensions)) @@ -1762,8 +1910,45 @@ func deriveDeepCopy_38(dst, src *ServiceVolumeConfig) { } } -// deriveDeepCopy_39 recursively copies the contents of src into dst. -func deriveDeepCopy_39(dst, src *IPAMConfig) { +// deriveDeepCopy_44 recursively copies the contents of src into dst. +func deriveDeepCopy_44(dst, src *ServiceHook) { + if src.Command == nil { + dst.Command = nil + } else { + if dst.Command != nil { + if len(src.Command) > len(dst.Command) { + if cap(dst.Command) >= len(src.Command) { + dst.Command = (dst.Command)[:len(src.Command)] + } else { + dst.Command = make([]string, len(src.Command)) + } + } else if len(src.Command) < len(dst.Command) { + dst.Command = (dst.Command)[:len(src.Command)] + } + } else { + dst.Command = make([]string, len(src.Command)) + } + copy(dst.Command, src.Command) + } + dst.User = src.User + dst.Privileged = src.Privileged + dst.WorkingDir = src.WorkingDir + if src.Environment != nil { + dst.Environment = make(map[string]*string, len(src.Environment)) + deriveDeepCopy_13(dst.Environment, src.Environment) + } else { + dst.Environment = nil + } + if src.Extensions != nil { + dst.Extensions = make(map[string]any, len(src.Extensions)) + src.Extensions.DeepCopy(dst.Extensions) + } else { + dst.Extensions = nil + } +} + +// deriveDeepCopy_45 recursively copies the contents of src into dst. +func deriveDeepCopy_45(dst, src *IPAMConfig) { dst.Driver = src.Driver if src.Config == nil { dst.Config = nil @@ -1781,7 +1966,7 @@ func deriveDeepCopy_39(dst, src *IPAMConfig) { } else { dst.Config = make([]*IPAMPool, len(src.Config)) } - deriveDeepCopy_48(dst.Config, src.Config) + deriveDeepCopy_54(dst.Config, src.Config) } if src.Extensions != nil { dst.Extensions = make(map[string]any, len(src.Extensions)) @@ -1791,8 +1976,8 @@ func deriveDeepCopy_39(dst, src *IPAMConfig) { } } -// deriveDeepCopy_40 recursively copies the contents of src into dst. -func deriveDeepCopy_40(dst, src *Trigger) { +// deriveDeepCopy_46 recursively copies the contents of src into dst. +func deriveDeepCopy_46(dst, src *Trigger) { dst.Path = src.Path dst.Action = src.Action dst.Target = src.Target @@ -1822,8 +2007,8 @@ func deriveDeepCopy_40(dst, src *Trigger) { } } -// deriveDeepCopy_41 recursively copies the contents of src into dst. -func deriveDeepCopy_41(dst, src *WeightDevice) { +// deriveDeepCopy_47 recursively copies the contents of src into dst. +func deriveDeepCopy_47(dst, src *WeightDevice) { dst.Path = src.Path dst.Weight = src.Weight if src.Extensions != nil { @@ -1834,8 +2019,8 @@ func deriveDeepCopy_41(dst, src *WeightDevice) { } } -// deriveDeepCopy_42 recursively copies the contents of src into dst. -func deriveDeepCopy_42(dst, src *ThrottleDevice) { +// deriveDeepCopy_48 recursively copies the contents of src into dst. +func deriveDeepCopy_48(dst, src *ThrottleDevice) { dst.Path = src.Path dst.Rate = src.Rate if src.Extensions != nil { @@ -1846,8 +2031,8 @@ func deriveDeepCopy_42(dst, src *ThrottleDevice) { } } -// deriveDeepCopy_43 recursively copies the contents of src into dst. -func deriveDeepCopy_43(dst, src *Resource) { +// deriveDeepCopy_49 recursively copies the contents of src into dst. +func deriveDeepCopy_49(dst, src *Resource) { dst.NanoCPUs = src.NanoCPUs dst.MemoryBytes = src.MemoryBytes dst.Pids = src.Pids @@ -1867,7 +2052,7 @@ func deriveDeepCopy_43(dst, src *Resource) { } else { dst.Devices = make([]DeviceRequest, len(src.Devices)) } - deriveDeepCopy_49(dst.Devices, src.Devices) + deriveDeepCopy_15(dst.Devices, src.Devices) } if src.GenericResources == nil { dst.GenericResources = nil @@ -1885,7 +2070,7 @@ func deriveDeepCopy_43(dst, src *Resource) { } else { dst.GenericResources = make([]GenericResource, len(src.GenericResources)) } - deriveDeepCopy_50(dst.GenericResources, src.GenericResources) + deriveDeepCopy_55(dst.GenericResources, src.GenericResources) } if src.Extensions != nil { dst.Extensions = make(map[string]any, len(src.Extensions)) @@ -1895,22 +2080,23 @@ func deriveDeepCopy_43(dst, src *Resource) { } } -// deriveDeepCopy_44 recursively copies the contents of src into dst. -func deriveDeepCopy_44(dst, src []PlacementPreferences) { +// deriveDeepCopy_50 recursively copies the contents of src into dst. +func deriveDeepCopy_50(dst, src []PlacementPreferences) { for src_i, src_value := range src { func() { field := new(PlacementPreferences) - deriveDeepCopy_51(field, &src_value) + deriveDeepCopy_56(field, &src_value) dst[src_i] = *field }() } } -// deriveDeepCopy_45 recursively copies the contents of src into dst. -func deriveDeepCopy_45(dst, src *ServiceVolumeBind) { +// deriveDeepCopy_51 recursively copies the contents of src into dst. +func deriveDeepCopy_51(dst, src *ServiceVolumeBind) { dst.SELinux = src.SELinux dst.Propagation = src.Propagation dst.CreateHostPath = src.CreateHostPath + dst.Recursive = src.Recursive if src.Extensions != nil { dst.Extensions = make(map[string]any, len(src.Extensions)) src.Extensions.DeepCopy(dst.Extensions) @@ -1919,8 +2105,8 @@ func deriveDeepCopy_45(dst, src *ServiceVolumeBind) { } } -// deriveDeepCopy_46 recursively copies the contents of src into dst. -func deriveDeepCopy_46(dst, src *ServiceVolumeVolume) { +// deriveDeepCopy_52 recursively copies the contents of src into dst. +func deriveDeepCopy_52(dst, src *ServiceVolumeVolume) { dst.NoCopy = src.NoCopy dst.Subpath = src.Subpath if src.Extensions != nil { @@ -1931,8 +2117,8 @@ func deriveDeepCopy_46(dst, src *ServiceVolumeVolume) { } } -// deriveDeepCopy_47 recursively copies the contents of src into dst. -func deriveDeepCopy_47(dst, src *ServiceVolumeTmpfs) { +// deriveDeepCopy_53 recursively copies the contents of src into dst. +func deriveDeepCopy_53(dst, src *ServiceVolumeTmpfs) { dst.Size = src.Size dst.Mode = src.Mode if src.Extensions != nil { @@ -1943,42 +2129,31 @@ func deriveDeepCopy_47(dst, src *ServiceVolumeTmpfs) { } } -// deriveDeepCopy_48 recursively copies the contents of src into dst. -func deriveDeepCopy_48(dst, src []*IPAMPool) { +// deriveDeepCopy_54 recursively copies the contents of src into dst. +func deriveDeepCopy_54(dst, src []*IPAMPool) { for src_i, src_value := range src { if src_value == nil { dst[src_i] = nil } else { dst[src_i] = new(IPAMPool) - deriveDeepCopy_52(dst[src_i], src_value) + deriveDeepCopy_57(dst[src_i], src_value) } } } -// deriveDeepCopy_49 recursively copies the contents of src into dst. -func deriveDeepCopy_49(dst, src []DeviceRequest) { - for src_i, src_value := range src { - func() { - field := new(DeviceRequest) - deriveDeepCopy_53(field, &src_value) - dst[src_i] = *field - }() - } -} - -// deriveDeepCopy_50 recursively copies the contents of src into dst. -func deriveDeepCopy_50(dst, src []GenericResource) { +// deriveDeepCopy_55 recursively copies the contents of src into dst. +func deriveDeepCopy_55(dst, src []GenericResource) { for src_i, src_value := range src { func() { field := new(GenericResource) - deriveDeepCopy_54(field, &src_value) + deriveDeepCopy_58(field, &src_value) dst[src_i] = *field }() } } -// deriveDeepCopy_51 recursively copies the contents of src into dst. -func deriveDeepCopy_51(dst, src *PlacementPreferences) { +// deriveDeepCopy_56 recursively copies the contents of src into dst. +func deriveDeepCopy_56(dst, src *PlacementPreferences) { dst.Spread = src.Spread if src.Extensions != nil { dst.Extensions = make(map[string]any, len(src.Extensions)) @@ -1988,8 +2163,8 @@ func deriveDeepCopy_51(dst, src *PlacementPreferences) { } } -// deriveDeepCopy_52 recursively copies the contents of src into dst. -func deriveDeepCopy_52(dst, src *IPAMPool) { +// deriveDeepCopy_57 recursively copies the contents of src into dst. +func deriveDeepCopy_57(dst, src *IPAMPool) { dst.Subnet = src.Subnet dst.Gateway = src.Gateway dst.IPRange = src.IPRange @@ -2007,55 +2182,13 @@ func deriveDeepCopy_52(dst, src *IPAMPool) { } } -// deriveDeepCopy_53 recursively copies the contents of src into dst. -func deriveDeepCopy_53(dst, src *DeviceRequest) { - if src.Capabilities == nil { - dst.Capabilities = nil - } else { - if dst.Capabilities != nil { - if len(src.Capabilities) > len(dst.Capabilities) { - if cap(dst.Capabilities) >= len(src.Capabilities) { - dst.Capabilities = (dst.Capabilities)[:len(src.Capabilities)] - } else { - dst.Capabilities = make([]string, len(src.Capabilities)) - } - } else if len(src.Capabilities) < len(dst.Capabilities) { - dst.Capabilities = (dst.Capabilities)[:len(src.Capabilities)] - } - } else { - dst.Capabilities = make([]string, len(src.Capabilities)) - } - copy(dst.Capabilities, src.Capabilities) - } - dst.Driver = src.Driver - dst.Count = src.Count - if src.IDs == nil { - dst.IDs = nil - } else { - if dst.IDs != nil { - if len(src.IDs) > len(dst.IDs) { - if cap(dst.IDs) >= len(src.IDs) { - dst.IDs = (dst.IDs)[:len(src.IDs)] - } else { - dst.IDs = make([]string, len(src.IDs)) - } - } else if len(src.IDs) < len(dst.IDs) { - dst.IDs = (dst.IDs)[:len(src.IDs)] - } - } else { - dst.IDs = make([]string, len(src.IDs)) - } - copy(dst.IDs, src.IDs) - } -} - -// deriveDeepCopy_54 recursively copies the contents of src into dst. -func deriveDeepCopy_54(dst, src *GenericResource) { +// deriveDeepCopy_58 recursively copies the contents of src into dst. +func deriveDeepCopy_58(dst, src *GenericResource) { if src.DiscreteResourceSpec == nil { dst.DiscreteResourceSpec = nil } else { dst.DiscreteResourceSpec = new(DiscreteGenericResource) - deriveDeepCopy_55(dst.DiscreteResourceSpec, src.DiscreteResourceSpec) + deriveDeepCopy_59(dst.DiscreteResourceSpec, src.DiscreteResourceSpec) } if src.Extensions != nil { dst.Extensions = make(map[string]any, len(src.Extensions)) @@ -2065,8 +2198,8 @@ func deriveDeepCopy_54(dst, src *GenericResource) { } } -// deriveDeepCopy_55 recursively copies the contents of src into dst. -func deriveDeepCopy_55(dst, src *DiscreteGenericResource) { +// deriveDeepCopy_59 recursively copies the contents of src into dst. +func deriveDeepCopy_59(dst, src *DiscreteGenericResource) { dst.Kind = src.Kind dst.Value = src.Value if src.Extensions != nil { diff --git a/vendor/github.com/compose-spec/compose-go/v2/types/device.go b/vendor/github.com/compose-spec/compose-go/v2/types/device.go index 240e8778..5b30cc0c 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/types/device.go +++ b/vendor/github.com/compose-spec/compose-go/v2/types/device.go @@ -27,6 +27,7 @@ type DeviceRequest struct { Driver string `yaml:"driver,omitempty" json:"driver,omitempty"` Count DeviceCount `yaml:"count,omitempty" json:"count,omitempty"` IDs []string `yaml:"device_ids,omitempty" json:"device_ids,omitempty"` + Options Mapping `yaml:"options,omitempty" json:"options,omitempty"` } type DeviceCount int64 diff --git a/vendor/github.com/compose-spec/compose-go/v2/types/envfile.go b/vendor/github.com/compose-spec/compose-go/v2/types/envfile.go index f0fa7221..1348f132 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/types/envfile.go +++ b/vendor/github.com/compose-spec/compose-go/v2/types/envfile.go @@ -23,6 +23,7 @@ import ( type EnvFile struct { Path string `yaml:"path,omitempty" json:"path,omitempty"` Required bool `yaml:"required" json:"required"` + Format string `yaml:"format,omitempty" json:"format,omitempty"` } // MarshalYAML makes EnvFile implement yaml.Marshaler diff --git a/vendor/github.com/compose-spec/compose-go/v2/types/hooks.go b/vendor/github.com/compose-spec/compose-go/v2/types/hooks.go new file mode 100644 index 00000000..4c58c094 --- /dev/null +++ b/vendor/github.com/compose-spec/compose-go/v2/types/hooks.go @@ -0,0 +1,28 @@ +/* + Copyright 2020 The Compose Specification Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package types + +// ServiceHook is a command to exec inside container by some lifecycle events +type ServiceHook struct { + Command ShellCommand `yaml:"command,omitempty" json:"command"` + User string `yaml:"user,omitempty" json:"user,omitempty"` + Privileged bool `yaml:"privileged,omitempty" json:"privileged,omitempty"` + WorkingDir string `yaml:"working_dir,omitempty" json:"working_dir,omitempty"` + Environment MappingWithEquals `yaml:"environment,omitempty" json:"environment,omitempty"` + + Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"` +} diff --git a/vendor/github.com/compose-spec/compose-go/v2/types/project.go b/vendor/github.com/compose-spec/compose-go/v2/types/project.go index 7e3ef5f0..19d6e32b 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/types/project.go +++ b/vendor/github.com/compose-spec/compose-go/v2/types/project.go @@ -616,22 +616,11 @@ func (p Project) WithServicesEnvironmentResolved(discardEnvFiles bool) (*Project } for _, envFile := range service.EnvFiles { - if _, err := os.Stat(envFile.Path); os.IsNotExist(err) { - if envFile.Required { - return nil, fmt.Errorf("env file %s not found: %w", envFile.Path, err) - } - continue - } - b, err := os.ReadFile(envFile.Path) + vars, err := loadEnvFile(envFile, resolve) if err != nil { - return nil, fmt.Errorf("failed to load %s: %w", envFile.Path, err) + return nil, err } - - fileVars, err := dotenv.ParseWithLookup(bytes.NewBuffer(b), resolve) - if err != nil { - return nil, fmt.Errorf("failed to read %s: %w", envFile.Path, err) - } - environment.OverrideBy(Mapping(fileVars).ToMappingWithEquals()) + environment.OverrideBy(vars.ToMappingWithEquals()) } service.Environment = environment.OverrideBy(service.Environment) @@ -644,6 +633,31 @@ func (p Project) WithServicesEnvironmentResolved(discardEnvFiles bool) (*Project return newProject, nil } +func loadEnvFile(envFile EnvFile, resolve dotenv.LookupFn) (Mapping, error) { + if _, err := os.Stat(envFile.Path); os.IsNotExist(err) { + if envFile.Required { + return nil, fmt.Errorf("env file %s not found: %w", envFile.Path, err) + } + return nil, nil + } + file, err := os.Open(envFile.Path) + if err != nil { + return nil, err + } + defer file.Close() //nolint:errcheck + + var fileVars map[string]string + if envFile.Format != "" { + fileVars, err = dotenv.ParseWithFormat(file, envFile.Path, resolve, envFile.Format) + } else { + fileVars, err = dotenv.ParseWithLookup(file, resolve) + } + if err != nil { + return nil, err + } + return fileVars, nil +} + func (p *Project) deepCopy() *Project { if p == nil { return nil diff --git a/vendor/github.com/compose-spec/compose-go/v2/types/types.go b/vendor/github.com/compose-spec/compose-go/v2/types/types.go index bee64467..87474e45 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/types/types.go +++ b/vendor/github.com/compose-spec/compose-go/v2/types/types.go @@ -20,7 +20,6 @@ import ( "encoding/json" "fmt" "sort" - "strconv" "strings" "github.com/docker/go-connections/nat" @@ -82,6 +81,7 @@ type ServiceConfig struct { ExternalLinks []string `yaml:"external_links,omitempty" json:"external_links,omitempty"` ExtraHosts HostsList `yaml:"extra_hosts,omitempty" json:"extra_hosts,omitempty"` GroupAdd []string `yaml:"group_add,omitempty" json:"group_add,omitempty"` + Gpus []DeviceRequest `yaml:"gpus,omitempty" json:"gpus,omitempty"` Hostname string `yaml:"hostname,omitempty" json:"hostname,omitempty"` HealthCheck *HealthCheckConfig `yaml:"healthcheck,omitempty" json:"healthcheck,omitempty"` Image string `yaml:"image,omitempty" json:"image,omitempty"` @@ -132,6 +132,8 @@ type ServiceConfig struct { Volumes []ServiceVolumeConfig `yaml:"volumes,omitempty" json:"volumes,omitempty"` VolumesFrom []string `yaml:"volumes_from,omitempty" json:"volumes_from,omitempty"` WorkingDir string `yaml:"working_dir,omitempty" json:"working_dir,omitempty"` + PostStart []ServiceHook `yaml:"post_start,omitempty" json:"post_start,omitempty"` + PreStop []ServiceHook `yaml:"pre_stop,omitempty" json:"pre_stop,omitempty"` Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"` } @@ -388,30 +390,6 @@ type Resource struct { Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"` } -type NanoCPUs float32 - -func (n *NanoCPUs) DecodeMapstructure(a any) error { - switch v := a.(type) { - case string: - f, err := strconv.ParseFloat(v, 64) - if err != nil { - return err - } - *n = NanoCPUs(f) - case float32: - *n = NanoCPUs(v) - case float64: - *n = NanoCPUs(v) - default: - return fmt.Errorf("unexpected value type %T for cpus", v) - } - return nil -} - -func (n *NanoCPUs) Value() float32 { - return float32(*n) -} - // GenericResource represents a "user defined" resource which can // only be an integer (e.g: SSD=3) for a service type GenericResource struct { @@ -552,9 +530,6 @@ func (s ServiceVolumeConfig) String() string { if s.Volume != nil && s.Volume.NoCopy { options = append(options, "nocopy") } - if s.Volume != nil && s.Volume.Subpath != "" { - options = append(options, s.Volume.Subpath) - } return fmt.Sprintf("%s:%s:%s", s.Source, s.Target, strings.Join(options, ",")) } @@ -581,6 +556,7 @@ type ServiceVolumeBind struct { SELinux string `yaml:"selinux,omitempty" json:"selinux,omitempty"` Propagation string `yaml:"propagation,omitempty" json:"propagation,omitempty"` CreateHostPath bool `yaml:"create_host_path,omitempty" json:"create_host_path,omitempty"` + Recursive string `yaml:"recursive,omitempty" json:"recursive,omitempty"` Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"` } diff --git a/vendor/github.com/compose-spec/compose-go/v2/validation/validation.go b/vendor/github.com/compose-spec/compose-go/v2/validation/validation.go index e7cd6754..707f247e 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/validation/validation.go +++ b/vendor/github.com/compose-spec/compose-go/v2/validation/validation.go @@ -30,6 +30,8 @@ var checks = map[tree.Path]checkerFunc{ "configs.*": checkFileObject("file", "environment", "content"), "secrets.*": checkFileObject("file", "environment"), "services.*.develop.watch.*.path": checkPath, + "services.*.deploy.resources.reservations.devices.*": checkDeviceRequest, + "services.*.gpus.*": checkDeviceRequest, } func Validate(dict map[string]any) error { @@ -94,3 +96,13 @@ func checkPath(value any, p tree.Path) error { } return nil } + +func checkDeviceRequest(value any, p tree.Path) error { + v := value.(map[string]any) + _, hasCount := v["count"] + _, hasIds := v["device_ids"] + if hasCount && hasIds { + return fmt.Errorf(`%s: "count" and "device_ids" attributes are exclusive`, p) + } + return nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index ce943ccb..14dab55b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -128,7 +128,7 @@ github.com/cenkalti/backoff/v4 # github.com/cespare/xxhash/v2 v2.3.0 ## explicit; go 1.11 github.com/cespare/xxhash/v2 -# github.com/compose-spec/compose-go/v2 v2.2.0 +# github.com/compose-spec/compose-go/v2 v2.4.1 ## explicit; go 1.21 github.com/compose-spec/compose-go/v2/cli github.com/compose-spec/compose-go/v2/consts