diff --git a/go.mod b/go.mod index a418ebdc..38e73227 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.1 github.com/aws/aws-sdk-go-v2/config v1.26.6 - github.com/compose-spec/compose-go/v2 v2.1.0 + github.com/compose-spec/compose-go/v2 v2.1.1 github.com/containerd/console v1.0.4 github.com/containerd/containerd v1.7.15 github.com/containerd/continuity v0.4.3 diff --git a/go.sum b/go.sum index 27844b31..ac7a9827 100644 --- a/go.sum +++ b/go.sum @@ -84,8 +84,8 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+g github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 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.1.0 h1:qdW2qISQlCQG8v1O2TChcdxgAWTUGgUX/CPSO+ES9+E= -github.com/compose-spec/compose-go/v2 v2.1.0/go.mod h1:bEPizBkIojlQ20pi2vNluBa58tevvj0Y18oUSHPyfdc= +github.com/compose-spec/compose-go/v2 v2.1.1 h1:tKuYJwAVgxIryRrsvWJSf1kNviVOQVVqwyHsV6YoIUc= +github.com/compose-spec/compose-go/v2 v2.1.1/go.mod h1:bEPizBkIojlQ20pi2vNluBa58tevvj0Y18oUSHPyfdc= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro= 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 78e2242a..cd8f281a 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 @@ -328,19 +328,11 @@ func loadModelWithContext(ctx context.Context, configDetails *types.ConfigDetail return nil, errors.New("No files specified") } - err := projectName(*configDetails, opts) + err := projectName(configDetails, opts) if err != nil { return nil, err } - // TODO(milas): this should probably ALWAYS set (overriding any existing) - if _, ok := configDetails.Environment[consts.ComposeProjectName]; !ok && opts.projectName != "" { - if configDetails.Environment == nil { - configDetails.Environment = map[string]string{} - } - configDetails.Environment[consts.ComposeProjectName] = opts.projectName - } - return load(ctx, *configDetails, opts, nil) } @@ -595,10 +587,14 @@ func InvalidProjectNameErr(v string) error { // projectName determines the canonical name to use for the project considering // the loader Options as well as `name` fields in Compose YAML fields (which // also support interpolation). -// -// TODO(milas): restructure loading so that we don't need to re-parse the YAML -// here, as it's both wasteful and makes this code error-prone. -func projectName(details types.ConfigDetails, opts *Options) error { +func projectName(details *types.ConfigDetails, opts *Options) error { + defer func() { + if details.Environment == nil { + details.Environment = map[string]string{} + } + details.Environment[consts.ComposeProjectName] = opts.projectName + }() + if opts.projectNameImperativelySet { if NormalizeProjectName(opts.projectName) != opts.projectName { return InvalidProjectNameErr(opts.projectName) diff --git a/vendor/github.com/compose-spec/compose-go/v2/override/uncity.go b/vendor/github.com/compose-spec/compose-go/v2/override/uncity.go index 057b2f28..7819015e 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/override/uncity.go +++ b/vendor/github.com/compose-spec/compose-go/v2/override/uncity.go @@ -198,12 +198,15 @@ func portIndexer(y any, p tree.Path) (string, error) { return "", nil } -func envFileIndexer(y any, _ tree.Path) (string, error) { +func envFileIndexer(y any, p tree.Path) (string, error) { switch value := y.(type) { case string: return value, nil case map[string]any: - return value["path"].(string), nil + if pathValue, ok := value["path"]; ok { + return pathValue.(string), nil + } + return "", fmt.Errorf("environment path attribut %s is missing", p) } return "", nil } 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 cbe51db7..33a79e9b 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 @@ -296,6 +296,12 @@ "ipv6_address": {"type": "string"}, "link_local_ips": {"$ref": "#/definitions/list_of_strings"}, "mac_address": {"type": "string"}, + "driver_opts": { + "type": "object", + "patternProperties": { + "^.+$": {"type": ["string", "number"]} + } + }, "priority": {"type": "number"} }, "additionalProperties": false, diff --git a/vendor/github.com/compose-spec/compose-go/v2/template/template.go b/vendor/github.com/compose-spec/compose-go/v2/template/template.go index 0d9c17ef..d9483cbd 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/template/template.go +++ b/vendor/github.com/compose-spec/compose-go/v2/template/template.go @@ -271,102 +271,6 @@ func Substitute(template string, mapping Mapping) (string, error) { return SubstituteWith(template, mapping, DefaultPattern) } -// ExtractVariables returns a map of all the variables defined in the specified -// composefile (dict representation) and their default value if any. -func ExtractVariables(configDict map[string]interface{}, pattern *regexp.Regexp) map[string]Variable { - if pattern == nil { - pattern = DefaultPattern - } - return recurseExtract(configDict, pattern) -} - -func recurseExtract(value interface{}, pattern *regexp.Regexp) map[string]Variable { - m := map[string]Variable{} - - switch value := value.(type) { - case string: - if values, is := extractVariable(value, pattern); is { - for _, v := range values { - m[v.Name] = v - } - } - case map[string]interface{}: - for _, elem := range value { - submap := recurseExtract(elem, pattern) - for key, value := range submap { - m[key] = value - } - } - - case []interface{}: - for _, elem := range value { - if values, is := extractVariable(elem, pattern); is { - for _, v := range values { - m[v.Name] = v - } - } - } - } - - return m -} - -type Variable struct { - Name string - DefaultValue string - PresenceValue string - Required bool -} - -func extractVariable(value interface{}, pattern *regexp.Regexp) ([]Variable, bool) { - sValue, ok := value.(string) - if !ok { - return []Variable{}, false - } - matches := pattern.FindAllStringSubmatch(sValue, -1) - if len(matches) == 0 { - return []Variable{}, false - } - values := []Variable{} - for _, match := range matches { - groups := matchGroups(match, pattern) - if escaped := groups[groupEscaped]; escaped != "" { - continue - } - val := groups[groupNamed] - if val == "" { - val = groups[groupBraced] - } - name := val - var defaultValue string - var presenceValue string - var required bool - switch { - case strings.Contains(val, ":?"): - name, _ = partition(val, ":?") - required = true - case strings.Contains(val, "?"): - name, _ = partition(val, "?") - required = true - case strings.Contains(val, ":-"): - name, defaultValue = partition(val, ":-") - case strings.Contains(val, "-"): - name, defaultValue = partition(val, "-") - case strings.Contains(val, ":+"): - name, presenceValue = partition(val, ":+") - case strings.Contains(val, "+"): - name, presenceValue = partition(val, "+") - } - values = append(values, Variable{ - Name: name, - DefaultValue: defaultValue, - PresenceValue: presenceValue, - Required: required, - }) - } - return values, len(values) > 0 -} - // Soft default (fall back if unset or empty) func defaultWhenEmptyOrUnset(substitution string, mapping Mapping) (string, bool, error) { return withDefaultWhenAbsence(substitution, mapping, true) diff --git a/vendor/github.com/compose-spec/compose-go/v2/template/variables.go b/vendor/github.com/compose-spec/compose-go/v2/template/variables.go new file mode 100644 index 00000000..fb32f9c3 --- /dev/null +++ b/vendor/github.com/compose-spec/compose-go/v2/template/variables.go @@ -0,0 +1,155 @@ +/* + 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 template + +import ( + "regexp" + "strings" +) + +type Variable struct { + Name string + DefaultValue string + PresenceValue string + Required bool +} + +// ExtractVariables returns a map of all the variables defined in the specified +// compose file (dict representation) and their default value if any. +func ExtractVariables(configDict map[string]interface{}, pattern *regexp.Regexp) map[string]Variable { + if pattern == nil { + pattern = DefaultPattern + } + return recurseExtract(configDict, pattern) +} + +func recurseExtract(value interface{}, pattern *regexp.Regexp) map[string]Variable { + m := map[string]Variable{} + + switch value := value.(type) { + case string: + if values, is := extractVariable(value, pattern); is { + for _, v := range values { + m[v.Name] = v + } + } + case map[string]interface{}: + for _, elem := range value { + submap := recurseExtract(elem, pattern) + for key, value := range submap { + m[key] = value + } + } + + case []interface{}: + for _, elem := range value { + if values, is := extractVariable(elem, pattern); is { + for _, v := range values { + m[v.Name] = v + } + } + } + } + + return m +} + +func extractVariable(value interface{}, pattern *regexp.Regexp) ([]Variable, bool) { + sValue, ok := value.(string) + if !ok { + return []Variable{}, false + } + matches := pattern.FindAllStringSubmatch(sValue, -1) + if len(matches) == 0 { + return []Variable{}, false + } + values := []Variable{} + for _, match := range matches { + groups := matchGroups(match, pattern) + if escaped := groups[groupEscaped]; escaped != "" { + continue + } + val := groups[groupNamed] + if val == "" { + val = groups[groupBraced] + s := match[0] + i := getFirstBraceClosingIndex(s) + if i > 0 { + val = s[2:i] + if len(s) > i { + if v, b := extractVariable(s[i+1:], pattern); b { + values = append(values, v...) + } + } + } + } + name := val + var defaultValue string + var presenceValue string + var required bool + i := strings.IndexFunc(val, func(r rune) bool { + if r >= 'a' && r <= 'z' { + return false + } + if r >= 'A' && r <= 'Z' { + return false + } + if r == '_' { + return false + } + return true + }) + + if i > 0 { + name = val[:i] + rest := val[i:] + switch { + case strings.HasPrefix(rest, ":?"): + required = true + case strings.HasPrefix(rest, "?"): + required = true + case strings.HasPrefix(rest, ":-"): + defaultValue = rest[2:] + case strings.HasPrefix(rest, "-"): + defaultValue = rest[1:] + case strings.HasPrefix(rest, ":+"): + presenceValue = rest[2:] + case strings.HasPrefix(rest, "+"): + presenceValue = rest[1:] + } + } + + values = append(values, Variable{ + Name: name, + DefaultValue: defaultValue, + PresenceValue: presenceValue, + Required: required, + }) + + if defaultValue != "" { + if v, b := extractVariable(defaultValue, pattern); b { + values = append(values, v...) + } + } + if presenceValue != "" { + if v, b := extractVariable(presenceValue, pattern); b { + values = append(values, v...) + } + } + } + return values, len(values) > 0 +} 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 b86a563f..6f049e98 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 @@ -659,12 +659,12 @@ func (p *Project) WithServicesTransform(fn func(name string, s ServiceConfig) (S name string service ServiceConfig } - resultCh := make(chan result) + expect := len(p.Services) + resultCh := make(chan result, expect) newProject := p.deepCopy() eg, ctx := errgroup.WithContext(context.Background()) eg.Go(func() error { - expect := len(newProject.Services) s := Services{} for expect > 0 { select { diff --git a/vendor/github.com/compose-spec/compose-go/v2/types/stringOrList.go b/vendor/github.com/compose-spec/compose-go/v2/types/stringOrList.go index 059043fb..a6720df0 100644 --- a/vendor/github.com/compose-spec/compose-go/v2/types/stringOrList.go +++ b/vendor/github.com/compose-spec/compose-go/v2/types/stringOrList.go @@ -28,7 +28,11 @@ func (l *StringList) DecodeMapstructure(value interface{}) error { case []interface{}: list := make([]string, len(v)) for i, e := range v { - list[i] = e.(string) + val, ok := e.(string) + if !ok { + return fmt.Errorf("invalid type %T for string list", value) + } + list[i] = val } *l = list default: 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 466454c4..00b1ac13 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 @@ -453,6 +453,7 @@ type ServiceNetworkConfig struct { Ipv6Address string `yaml:"ipv6_address,omitempty" json:"ipv6_address,omitempty"` LinkLocalIPs []string `yaml:"link_local_ips,omitempty" json:"link_local_ips,omitempty"` MacAddress string `yaml:"mac_address,omitempty" json:"mac_address,omitempty"` + DriverOpts Options `yaml:"driver_opts,omitempty" json:"driver_opts,omitempty"` Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"` } diff --git a/vendor/modules.txt b/vendor/modules.txt index 325d937d..8d6551d4 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -131,7 +131,7 @@ github.com/cenkalti/backoff/v4 # github.com/cespare/xxhash/v2 v2.2.0 ## explicit; go 1.11 github.com/cespare/xxhash/v2 -# github.com/compose-spec/compose-go/v2 v2.1.0 +# github.com/compose-spec/compose-go/v2 v2.1.1 ## explicit; go 1.21 github.com/compose-spec/compose-go/v2/cli github.com/compose-spec/compose-go/v2/consts