vendor: update compose-go to v2.4.8

Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax
2025-03-11 14:56:19 +01:00
parent b88423be50
commit 67d3ed34e4
13 changed files with 126 additions and 73 deletions

View File

@ -26,6 +26,7 @@ import (
"strings"
"github.com/sirupsen/logrus"
"gopkg.in/yaml.v3"
"github.com/compose-spec/compose-go/v2/consts"
"github.com/compose-spec/compose-go/v2/dotenv"
@ -482,8 +483,27 @@ func (o *ProjectOptions) prepare(ctx context.Context) (*types.ConfigDetails, err
return configDetails, err
}
isNamed := false
if o.Name == "" {
type named struct {
Name string `yaml:"name,omitempty"`
}
// if any of the compose file is named, this is equivalent to user passing --project-name
for _, cfg := range configDetails.ConfigFiles {
var n named
err = yaml.Unmarshal(cfg.Content, &n)
if err != nil {
return nil, err
}
if n.Name != "" {
isNamed = true
break
}
}
}
o.loadOptions = append(o.loadOptions,
withNamePrecedenceLoad(defaultDir, o),
withNamePrecedenceLoad(defaultDir, isNamed, o),
withConvertWindowsPaths(o),
withListeners(o))
@ -496,13 +516,13 @@ func ProjectFromOptions(ctx context.Context, options *ProjectOptions) (*types.Pr
return options.LoadProject(ctx)
}
func withNamePrecedenceLoad(absWorkingDir string, options *ProjectOptions) func(*loader.Options) {
func withNamePrecedenceLoad(absWorkingDir string, namedInYaml bool, options *ProjectOptions) func(*loader.Options) {
return func(opts *loader.Options) {
if options.Name != "" {
opts.SetProjectName(options.Name, true)
} else if nameFromEnv, ok := options.Environment[consts.ComposeProjectName]; ok && nameFromEnv != "" {
opts.SetProjectName(nameFromEnv, true)
} else {
} else if !namedInYaml {
dirname := filepath.Base(absWorkingDir)
symlink, err := filepath.EvalSymlinks(absWorkingDir)
if err == nil && filepath.Base(symlink) != dirname {

View File

@ -27,10 +27,6 @@ import (
"github.com/compose-spec/compose-go/v2/types"
)
// as we use another service definition by `extends`, we must exclude attributes which creates dependency to another service
// see https://github.com/compose-spec/compose-spec/blob/main/05-services.md#restrictions
var exclusions = []string{"depends_on", "volumes_from"}
func ApplyExtends(ctx context.Context, dict map[string]any, opts *Options, tracker *cycleTracker, post ...PostProcessor) error {
a, ok := dict["services"]
if !ok {
@ -123,9 +119,6 @@ func applyServiceExtends(ctx context.Context, name string, services map[string]a
},
})
}
for _, exclusion := range exclusions {
delete(source, exclusion)
}
merged, err := override.ExtendService(source, service)
if err != nil {
return nil, err

View File

@ -64,6 +64,7 @@ var interpolateTypeCastMapping = map[tree.Path]interp.Cast{
iPath("networks", tree.PathMatchAll, "external"): toBoolean,
iPath("networks", tree.PathMatchAll, "internal"): toBoolean,
iPath("networks", tree.PathMatchAll, "attachable"): toBoolean,
iPath("networks", tree.PathMatchAll, "enable_ipv4"): toBoolean,
iPath("networks", tree.PathMatchAll, "enable_ipv6"): toBoolean,
iPath("volumes", tree.PathMatchAll, "external"): toBoolean,
iPath("secrets", tree.PathMatchAll, "external"): toBoolean,

View File

@ -28,7 +28,7 @@ import (
// checkConsistency validate a compose model is consistent
func checkConsistency(project *types.Project) error {
for _, s := range project.Services {
for name, s := range project.Services {
if s.Build == nil && s.Image == "" {
return fmt.Errorf("service %q has neither an image nor a build context specified: %w", s.Name, errdefs.ErrInvalid)
}
@ -38,6 +38,18 @@ func checkConsistency(project *types.Project) error {
return fmt.Errorf("service %q declares mutualy exclusive dockerfile and dockerfile_inline: %w", s.Name, errdefs.ErrInvalid)
}
for add, c := range s.Build.AdditionalContexts {
if target, ok := strings.CutPrefix(c, types.ServicePrefix); ok {
t, err := project.GetService(target)
if err != nil {
return fmt.Errorf("service %q declares unknown service %q as additional contexts %s", name, target, add)
}
if t.Build == nil {
return fmt.Errorf("service %q declares non-buildable service %q as additional contexts %s", name, target, add)
}
}
}
if len(s.Build.Platforms) > 0 && s.Platform != "" {
var found bool
for _, platform := range s.Build.Platforms {

View File

@ -16,13 +16,20 @@
package paths
import "strings"
import (
"strings"
"github.com/compose-spec/compose-go/v2/types"
)
func (r *relativePathsResolver) absContextPath(value any) (any, error) {
v := value.(string)
if strings.Contains(v, "://") { // `docker-image://` or any builder specific context type
return v, nil
}
if strings.HasPrefix(v, types.ServicePrefix) { // `docker-image://` or any builder specific context type
return v, nil
}
if isRemoteContext(v) {
return v, nil
}

View File

@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2019-09/schema#",
"id": "compose_spec.json",
"$schema": "https://json-schema.org/draft-07/schema",
"$id": "compose_spec.json",
"type": "object",
"title": "Compose Specification",
"description": "The Compose file is a YAML file defining a multi-containers based application.",
@ -25,7 +25,6 @@
},
"services": {
"id": "#/properties/services",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
@ -36,7 +35,6 @@
},
"networks": {
"id": "#/properties/networks",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
@ -46,7 +44,6 @@
},
"volumes": {
"id": "#/properties/volumes",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
@ -57,7 +54,6 @@
},
"secrets": {
"id": "#/properties/secrets",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
@ -68,7 +64,6 @@
},
"configs": {
"id": "#/properties/configs",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
@ -85,7 +80,6 @@
"definitions": {
"service": {
"id": "#/definitions/service",
"type": "object",
"properties": {
@ -246,8 +240,7 @@
"expose": {
"type": "array",
"items": {
"type": ["string", "number"],
"format": "expose"
"type": ["string", "number"]
},
"uniqueItems": true
},
@ -327,7 +320,8 @@
"^.+$": {"type": ["string", "number"]}
}
},
"priority": {"type": "number"}
"priority": {"type": "number"},
"gw_priority": {"type": "number"}
},
"additionalProperties": false,
"patternProperties": {"^x-": {}}
@ -469,7 +463,6 @@
},
"healthcheck": {
"id": "#/definitions/healthcheck",
"type": "object",
"properties": {
"disable": {"type": ["boolean", "string"]},
@ -489,7 +482,6 @@
"patternProperties": {"^x-": {}}
},
"development": {
"id": "#/definitions/development",
"type": ["object", "null"],
"properties": {
"watch": {
@ -513,7 +505,6 @@
"patternProperties": {"^x-": {}}
},
"deployment": {
"id": "#/definitions/deployment",
"type": ["object", "null"],
"properties": {
"mode": {"type": "string"},
@ -615,7 +606,6 @@
},
"generic_resources": {
"id": "#/definitions/generic_resources",
"type": "array",
"items": {
"type": "object",
@ -636,7 +626,6 @@
},
"devices": {
"id": "#/definitions/devices",
"type": "array",
"items": {
"type": "object",
@ -656,24 +645,26 @@
},
"gpus": {
"id": "#/definitions/gpus",
"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-": {}}
}
"oneOf": [
{"type": "string", "enum": ["all"]},
{"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-": {}}
}
]
},
"include": {
"id": "#/definitions/include",
"oneOf": [
{"type": "string"},
{
@ -689,7 +680,6 @@
},
"network": {
"id": "#/definitions/network",
"type": ["object", "null"],
"properties": {
"name": {"type": "string"},
@ -743,6 +733,7 @@
"patternProperties": {"^x-": {}}
},
"internal": {"type": ["boolean", "string"]},
"enable_ipv4": {"type": ["boolean", "string"]},
"enable_ipv6": {"type": ["boolean", "string"]},
"attachable": {"type": ["boolean", "string"]},
"labels": {"$ref": "#/definitions/list_or_dict"}
@ -752,7 +743,6 @@
},
"volume": {
"id": "#/definitions/volume",
"type": ["object", "null"],
"properties": {
"name": {"type": "string"},
@ -781,7 +771,6 @@
},
"secret": {
"id": "#/definitions/secret",
"type": "object",
"properties": {
"name": {"type": "string"},
@ -808,7 +797,6 @@
},
"config": {
"id": "#/definitions/config",
"type": "object",
"properties": {
"name": {"type": "string"},
@ -840,7 +828,6 @@
},
"service_hook": {
"id": "#/definitions/service_hook",
"type": "object",
"properties": {
"command": {"$ref": "#/definitions/command"},
@ -1005,20 +992,6 @@
]
}
}
},
"constraints": {
"service": {
"id": "#/definitions/constraints/service",
"anyOf": [
{"required": ["build"]},
{"required": ["image"]}
],
"properties": {
"build": {
"required": ["context"]
}
}
}
}
}
}

View File

@ -32,6 +32,7 @@ func init() {
transformers["services.*.env_file"] = transformEnvFile
transformers["services.*.label_file"] = transformStringOrList
transformers["services.*.extends"] = transformExtends
transformers["services.*.gpus"] = transformGpus
transformers["services.*.networks"] = transformServiceNetworks
transformers["services.*.volumes.*"] = transformVolumeMount
transformers["services.*.dns"] = transformStringOrList

View File

@ -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 transform
import (
"fmt"
"github.com/compose-spec/compose-go/v2/tree"
)
func transformGpus(data any, p tree.Path, ignoreParseError bool) (any, error) {
switch v := data.(type) {
case []any:
return transformSequence(v, p, ignoreParseError)
case string:
return []any{
map[string]any{
"count": "all",
},
}, nil
default:
return data, fmt.Errorf("%s: invalid type %T for gpus", p, v)
}
}

View File

@ -1452,6 +1452,12 @@ func deriveDeepCopy_24(dst, src *NetworkConfig) {
} else {
dst.CustomLabels = nil
}
if src.EnableIPv4 == nil {
dst.EnableIPv4 = nil
} else {
dst.EnableIPv4 = new(bool)
*dst.EnableIPv4 = *src.EnableIPv4
}
if src.EnableIPv6 == nil {
dst.EnableIPv6 = nil
} else {

View File

@ -438,13 +438,14 @@ type PlacementPreferences struct {
// ServiceNetworkConfig is the network configuration for a service
type ServiceNetworkConfig struct {
Priority int `yaml:"priority,omitempty" json:"priority,omitempty"`
Aliases []string `yaml:"aliases,omitempty" json:"aliases,omitempty"`
Ipv4Address string `yaml:"ipv4_address,omitempty" json:"ipv4_address,omitempty"`
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"`
Priority int `yaml:"priority,omitempty" json:"priority,omitempty"`
GatewayPriority int `yaml:"gw_priority,omitempty" json:"gw_priority,omitempty"`
Aliases []string `yaml:"aliases,omitempty" json:"aliases,omitempty"`
Ipv4Address string `yaml:"ipv4_address,omitempty" json:"ipv4_address,omitempty"`
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:"-"`
}
@ -688,6 +689,7 @@ type NetworkConfig struct {
Attachable bool `yaml:"attachable,omitempty" json:"attachable,omitempty"`
Labels Labels `yaml:"labels,omitempty" json:"labels,omitempty"`
CustomLabels Labels `yaml:"-" json:"-"`
EnableIPv4 *bool `yaml:"enable_ipv4,omitempty" json:"enable_ipv4,omitempty"`
EnableIPv6 *bool `yaml:"enable_ipv6,omitempty" json:"enable_ipv6,omitempty"`
Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
}