mirror of https://github.com/docker/buildx.git
Merge pull request #2692 from glours/bump-compose-go-v2.2.0
bump compose-go to v2.2.0
This commit is contained in:
commit
e950b2e478
2
go.mod
2
go.mod
|
@ -6,7 +6,7 @@ require (
|
||||||
github.com/Masterminds/semver/v3 v3.2.1
|
github.com/Masterminds/semver/v3 v3.2.1
|
||||||
github.com/Microsoft/go-winio v0.6.2
|
github.com/Microsoft/go-winio v0.6.2
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.26.6
|
github.com/aws/aws-sdk-go-v2/config v1.26.6
|
||||||
github.com/compose-spec/compose-go/v2 v2.1.6
|
github.com/compose-spec/compose-go/v2 v2.2.0
|
||||||
github.com/containerd/console v1.0.4
|
github.com/containerd/console v1.0.4
|
||||||
github.com/containerd/containerd v1.7.21
|
github.com/containerd/containerd v1.7.21
|
||||||
github.com/containerd/continuity v0.4.3
|
github.com/containerd/continuity v0.4.3
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -84,8 +84,8 @@ github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/P
|
||||||
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM=
|
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM=
|
||||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
|
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/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
|
||||||
github.com/compose-spec/compose-go/v2 v2.1.6 h1:d0Cs0DffmOwmSzs0YPHwKCskknGq2jfGg4uGowlEpps=
|
github.com/compose-spec/compose-go/v2 v2.2.0 h1:VsQosGhuO+H9wh5laiIiAe4TVd73kQ5NWwmNrdm0HRA=
|
||||||
github.com/compose-spec/compose-go/v2 v2.1.6/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
|
github.com/compose-spec/compose-go/v2 v2.2.0/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
|
||||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
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/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
||||||
github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
|
github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
|
||||||
|
|
|
@ -403,7 +403,7 @@ func (o *ProjectOptions) GetWorkingDir() (string, error) {
|
||||||
return os.Getwd()
|
return os.Getwd()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *ProjectOptions) GeConfigFiles() ([]types.ConfigFile, error) {
|
func (o *ProjectOptions) GetConfigFiles() ([]types.ConfigFile, error) {
|
||||||
configPaths, err := o.getConfigPaths()
|
configPaths, err := o.getConfigPaths()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -466,7 +466,7 @@ func (o *ProjectOptions) LoadModel(ctx context.Context) (map[string]any, error)
|
||||||
|
|
||||||
// prepare converts ProjectOptions into loader's types.ConfigDetails and configures default load options
|
// prepare converts ProjectOptions into loader's types.ConfigDetails and configures default load options
|
||||||
func (o *ProjectOptions) prepare() (types.ConfigDetails, error) {
|
func (o *ProjectOptions) prepare() (types.ConfigDetails, error) {
|
||||||
configs, err := o.GeConfigFiles()
|
configs, err := o.GetConfigFiles()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.ConfigDetails{}, err
|
return types.ConfigDetails{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ loop:
|
||||||
offset = i + 1
|
offset = i + 1
|
||||||
inherited = rune == '\n'
|
inherited = rune == '\n'
|
||||||
break loop
|
break loop
|
||||||
case '_', '.', '-', '[', ']':
|
case '_', '.', '[', ']':
|
||||||
default:
|
default:
|
||||||
// variable name should match [A-Za-z0-9_.-]
|
// variable name should match [A-Za-z0-9_.-]
|
||||||
if unicode.IsLetter(rune) || unicode.IsNumber(rune) {
|
if unicode.IsLetter(rune) || unicode.IsNumber(rune) {
|
||||||
|
|
|
@ -79,7 +79,7 @@ func resolveSecretsEnvironment(dict map[string]any, environment types.Mapping) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if found, ok := environment[env]; ok {
|
if found, ok := environment[env]; ok {
|
||||||
secret["content"] = found
|
secret[types.SecretConfigXValue] = found
|
||||||
}
|
}
|
||||||
secrets[name] = secret
|
secrets[name] = secret
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,8 +163,15 @@ func getExtendsBaseFromFile(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
services := source["services"].(map[string]any)
|
m, ok := source["services"]
|
||||||
_, ok := services[ref]
|
if !ok {
|
||||||
|
return nil, nil, fmt.Errorf("cannot extend service %q in %s: no services section", name, local)
|
||||||
|
}
|
||||||
|
services, ok := m.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, fmt.Errorf("cannot extend service %q in %s: services must be a mapping", name, local)
|
||||||
|
}
|
||||||
|
_, ok = services[ref]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil, fmt.Errorf(
|
return nil, nil, fmt.Errorf(
|
||||||
"cannot extend service %q in %s: service %q not found in %s",
|
"cannot extend service %q in %s: service %q not found in %s",
|
||||||
|
|
|
@ -118,7 +118,9 @@ services:
|
||||||
- "a 7:* rmw"
|
- "a 7:* rmw"
|
||||||
|
|
||||||
devices:
|
devices:
|
||||||
- "/dev/ttyUSB0:/dev/ttyUSB0"
|
- source: /dev/ttyUSB0
|
||||||
|
target: /dev/ttyUSB0
|
||||||
|
permissions: rwm
|
||||||
|
|
||||||
# String or list
|
# String or list
|
||||||
# dns: 8.8.8.8
|
# dns: 8.8.8.8
|
||||||
|
|
|
@ -738,7 +738,9 @@ func Transform(source interface{}, target interface{}) error {
|
||||||
DecodeHook: mapstructure.ComposeDecodeHookFunc(
|
DecodeHook: mapstructure.ComposeDecodeHookFunc(
|
||||||
nameServices,
|
nameServices,
|
||||||
decoderHook,
|
decoderHook,
|
||||||
cast),
|
cast,
|
||||||
|
secretConfigDecoderHook,
|
||||||
|
),
|
||||||
Result: target,
|
Result: target,
|
||||||
TagName: "yaml",
|
TagName: "yaml",
|
||||||
Metadata: &data,
|
Metadata: &data,
|
||||||
|
@ -764,6 +766,28 @@ func nameServices(from reflect.Value, to reflect.Value) (interface{}, error) {
|
||||||
return from.Interface(), nil
|
return from.Interface(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func secretConfigDecoderHook(from, to reflect.Type, data interface{}) (interface{}, error) {
|
||||||
|
// 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 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the original data so the rest is handled by default mapstructure logic
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
// keys need to be converted to strings for jsonschema
|
// keys need to be converted to strings for jsonschema
|
||||||
func convertToStringKeysRecursive(value interface{}, keyPrefix string) (interface{}, error) {
|
func convertToStringKeysRecursive(value interface{}, keyPrefix string) (interface{}, error) {
|
||||||
if mapping, ok := value.(map[string]interface{}); ok {
|
if mapping, ok := value.(map[string]interface{}); ok {
|
||||||
|
|
|
@ -36,7 +36,6 @@ func init() {
|
||||||
unique["services.*.annotations"] = keyValueIndexer
|
unique["services.*.annotations"] = keyValueIndexer
|
||||||
unique["services.*.build.args"] = keyValueIndexer
|
unique["services.*.build.args"] = keyValueIndexer
|
||||||
unique["services.*.build.additional_contexts"] = keyValueIndexer
|
unique["services.*.build.additional_contexts"] = keyValueIndexer
|
||||||
unique["services.*.build.extra_hosts"] = keyValueIndexer
|
|
||||||
unique["services.*.build.platform"] = keyValueIndexer
|
unique["services.*.build.platform"] = keyValueIndexer
|
||||||
unique["services.*.build.tags"] = keyValueIndexer
|
unique["services.*.build.tags"] = keyValueIndexer
|
||||||
unique["services.*.build.labels"] = keyValueIndexer
|
unique["services.*.build.labels"] = keyValueIndexer
|
||||||
|
@ -51,7 +50,6 @@ func init() {
|
||||||
unique["services.*.environment"] = keyValueIndexer
|
unique["services.*.environment"] = keyValueIndexer
|
||||||
unique["services.*.env_file"] = envFileIndexer
|
unique["services.*.env_file"] = envFileIndexer
|
||||||
unique["services.*.expose"] = exposeIndexer
|
unique["services.*.expose"] = exposeIndexer
|
||||||
unique["services.*.extra_hosts"] = keyValueIndexer
|
|
||||||
unique["services.*.labels"] = keyValueIndexer
|
unique["services.*.labels"] = keyValueIndexer
|
||||||
unique["services.*.links"] = keyValueIndexer
|
unique["services.*.links"] = keyValueIndexer
|
||||||
unique["services.*.networks.*.aliases"] = keyValueIndexer
|
unique["services.*.networks.*.aliases"] = keyValueIndexer
|
||||||
|
@ -62,6 +60,7 @@ func init() {
|
||||||
unique["services.*.sysctls"] = keyValueIndexer
|
unique["services.*.sysctls"] = keyValueIndexer
|
||||||
unique["services.*.tmpfs"] = keyValueIndexer
|
unique["services.*.tmpfs"] = keyValueIndexer
|
||||||
unique["services.*.volumes"] = volumeIndexer
|
unique["services.*.volumes"] = volumeIndexer
|
||||||
|
unique["services.*.devices"] = deviceMappingIndexer
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnforceUnicity removes redefinition of elements declared in a sequence
|
// EnforceUnicity removes redefinition of elements declared in a sequence
|
||||||
|
@ -108,16 +107,16 @@ func enforceUnicity(value any, p tree.Path) (any, error) {
|
||||||
return value, nil
|
return value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func keyValueIndexer(y any, p tree.Path) (string, error) {
|
func keyValueIndexer(v any, p tree.Path) (string, error) {
|
||||||
switch value := y.(type) {
|
switch value := v.(type) {
|
||||||
case string:
|
case string:
|
||||||
key, _, found := strings.Cut(value, "=")
|
key, _, found := strings.Cut(value, "=")
|
||||||
if !found {
|
if found {
|
||||||
return value, nil
|
return key, nil
|
||||||
}
|
}
|
||||||
return key, nil
|
return value, nil
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf("%s: unexpected type %T", p, y)
|
return "", fmt.Errorf("%s: unexpected type %T", p, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,6 +138,24 @@ func volumeIndexer(y any, p tree.Path) (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deviceMappingIndexer(y any, p tree.Path) (string, error) {
|
||||||
|
switch value := y.(type) {
|
||||||
|
case map[string]any:
|
||||||
|
target, ok := value["target"].(string)
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("service device %s is missing a mount target", p)
|
||||||
|
}
|
||||||
|
return target, nil
|
||||||
|
case string:
|
||||||
|
arr := strings.Split(value, ":")
|
||||||
|
if len(arr) == 1 {
|
||||||
|
return arr[0], nil
|
||||||
|
}
|
||||||
|
return arr[1], nil
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
func exposeIndexer(a any, path tree.Path) (string, error) {
|
func exposeIndexer(a any, path tree.Path) (string, error) {
|
||||||
switch v := a.(type) {
|
switch v := a.(type) {
|
||||||
case string:
|
case string:
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
"include": {
|
"include": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/include"
|
"$ref": "#/definitions/include"
|
||||||
},
|
},
|
||||||
"description": "compose sub-projects to be included."
|
"description": "compose sub-projects to be included."
|
||||||
|
@ -115,7 +114,7 @@
|
||||||
"pull": {"type": ["boolean", "string"]},
|
"pull": {"type": ["boolean", "string"]},
|
||||||
"target": {"type": "string"},
|
"target": {"type": "string"},
|
||||||
"shm_size": {"type": ["integer", "string"]},
|
"shm_size": {"type": ["integer", "string"]},
|
||||||
"extra_hosts": {"$ref": "#/definitions/list_or_dict"},
|
"extra_hosts": {"$ref": "#/definitions/extra_hosts"},
|
||||||
"isolation": {"type": "string"},
|
"isolation": {"type": "string"},
|
||||||
"privileged": {"type": ["boolean", "string"]},
|
"privileged": {"type": ["boolean", "string"]},
|
||||||
"secrets": {"$ref": "#/definitions/service_config_or_secret"},
|
"secrets": {"$ref": "#/definitions/service_config_or_secret"},
|
||||||
|
@ -216,7 +215,25 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"device_cgroup_rules": {"$ref": "#/definitions/list_of_strings"},
|
"device_cgroup_rules": {"$ref": "#/definitions/list_of_strings"},
|
||||||
"devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
|
"devices": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"oneOf": [
|
||||||
|
{"type": "string"},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": ["source"],
|
||||||
|
"properties": {
|
||||||
|
"source": {"type": "string"},
|
||||||
|
"target": {"type": "string"},
|
||||||
|
"permissions": {"type": "string"}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"patternProperties": {"^x-": {}}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"dns": {"$ref": "#/definitions/string_or_list"},
|
"dns": {"$ref": "#/definitions/string_or_list"},
|
||||||
"dns_opt": {"type": "array","items": {"type": "string"}, "uniqueItems": true},
|
"dns_opt": {"type": "array","items": {"type": "string"}, "uniqueItems": true},
|
||||||
"dns_search": {"$ref": "#/definitions/string_or_list"},
|
"dns_search": {"$ref": "#/definitions/string_or_list"},
|
||||||
|
@ -249,7 +266,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
|
"external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
|
||||||
"extra_hosts": {"$ref": "#/definitions/list_or_dict"},
|
"extra_hosts": {"$ref": "#/definitions/extra_hosts"},
|
||||||
"group_add": {
|
"group_add": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
|
@ -854,6 +871,21 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"extra_hosts": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".+": {
|
||||||
|
"type": ["string", "array"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{"type": "array", "items": {"type": "string"}, "uniqueItems": true}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
"blkio_limit": {
|
"blkio_limit": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -33,6 +33,7 @@ func init() {
|
||||||
transformers["services.*.extends"] = transformExtends
|
transformers["services.*.extends"] = transformExtends
|
||||||
transformers["services.*.networks"] = transformServiceNetworks
|
transformers["services.*.networks"] = transformServiceNetworks
|
||||||
transformers["services.*.volumes.*"] = transformVolumeMount
|
transformers["services.*.volumes.*"] = transformVolumeMount
|
||||||
|
transformers["services.*.devices.*"] = transformDeviceMapping
|
||||||
transformers["services.*.secrets.*"] = transformFileMount
|
transformers["services.*.secrets.*"] = transformFileMount
|
||||||
transformers["services.*.configs.*"] = transformFileMount
|
transformers["services.*.configs.*"] = transformFileMount
|
||||||
transformers["services.*.ports"] = transformPorts
|
transformers["services.*.ports"] = transformPorts
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
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"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/compose-spec/compose-go/v2/tree"
|
||||||
|
)
|
||||||
|
|
||||||
|
func transformDeviceMapping(data any, p tree.Path, ignoreParseError bool) (any, error) {
|
||||||
|
switch v := data.(type) {
|
||||||
|
case map[string]any:
|
||||||
|
return v, nil
|
||||||
|
case string:
|
||||||
|
src := ""
|
||||||
|
dst := ""
|
||||||
|
permissions := "rwm"
|
||||||
|
arr := strings.Split(v, ":")
|
||||||
|
switch len(arr) {
|
||||||
|
case 3:
|
||||||
|
permissions = arr[2]
|
||||||
|
fallthrough
|
||||||
|
case 2:
|
||||||
|
dst = arr[1]
|
||||||
|
fallthrough
|
||||||
|
case 1:
|
||||||
|
src = arr[0]
|
||||||
|
default:
|
||||||
|
if !ignoreParseError {
|
||||||
|
return nil, fmt.Errorf("confusing device mapping, please use long syntax: %s", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if dst == "" {
|
||||||
|
dst = src
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"source": src,
|
||||||
|
"target": dst,
|
||||||
|
"permissions": permissions,
|
||||||
|
}, nil
|
||||||
|
default:
|
||||||
|
return data, fmt.Errorf("%s: invalid type %T for service volume mount", p, v)
|
||||||
|
}
|
||||||
|
}
|
|
@ -271,13 +271,13 @@ func deriveDeepCopyService(dst, src *ServiceConfig) {
|
||||||
if cap(dst.Devices) >= len(src.Devices) {
|
if cap(dst.Devices) >= len(src.Devices) {
|
||||||
dst.Devices = (dst.Devices)[:len(src.Devices)]
|
dst.Devices = (dst.Devices)[:len(src.Devices)]
|
||||||
} else {
|
} else {
|
||||||
dst.Devices = make([]string, len(src.Devices))
|
dst.Devices = make([]DeviceMapping, len(src.Devices))
|
||||||
}
|
}
|
||||||
} else if len(src.Devices) < len(dst.Devices) {
|
} else if len(src.Devices) < len(dst.Devices) {
|
||||||
dst.Devices = (dst.Devices)[:len(src.Devices)]
|
dst.Devices = (dst.Devices)[:len(src.Devices)]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dst.Devices = make([]string, len(src.Devices))
|
dst.Devices = make([]DeviceMapping, len(src.Devices))
|
||||||
}
|
}
|
||||||
copy(dst.Devices, src.Devices)
|
copy(dst.Devices, src.Devices)
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,9 +36,9 @@ func NewHostsList(hosts []string) (HostsList, error) {
|
||||||
if ok {
|
if ok {
|
||||||
// Mapping found with this separator, stop here.
|
// Mapping found with this separator, stop here.
|
||||||
if ips, ok := list[host]; ok {
|
if ips, ok := list[host]; ok {
|
||||||
list[host] = append(ips, ip)
|
list[host] = append(ips, strings.Split(ip, ",")...)
|
||||||
} else {
|
} else {
|
||||||
list[host] = []string{ip}
|
list[host] = strings.Split(ip, ",")
|
||||||
}
|
}
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
|
@ -89,7 +89,18 @@ func (h *HostsList) DecodeMapstructure(value interface{}) error {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
e = ""
|
e = ""
|
||||||
}
|
}
|
||||||
list[i] = []string{fmt.Sprint(e)}
|
switch t := e.(type) {
|
||||||
|
case string:
|
||||||
|
list[i] = []string{t}
|
||||||
|
case []any:
|
||||||
|
hosts := make([]string, len(t))
|
||||||
|
for j, h := range t {
|
||||||
|
hosts[j] = fmt.Sprint(h)
|
||||||
|
}
|
||||||
|
list[i] = hosts
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unexpected value type %T for extra_hosts entry", value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
err := list.cleanup()
|
err := list.cleanup()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -109,7 +120,7 @@ func (h *HostsList) DecodeMapstructure(value interface{}) error {
|
||||||
*h = list
|
*h = list
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unexpected value type %T for mapping", value)
|
return fmt.Errorf("unexpected value type %T for extra_hosts", value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ type ServiceConfig struct {
|
||||||
DependsOn DependsOnConfig `yaml:"depends_on,omitempty" json:"depends_on,omitempty"`
|
DependsOn DependsOnConfig `yaml:"depends_on,omitempty" json:"depends_on,omitempty"`
|
||||||
Deploy *DeployConfig `yaml:"deploy,omitempty" json:"deploy,omitempty"`
|
Deploy *DeployConfig `yaml:"deploy,omitempty" json:"deploy,omitempty"`
|
||||||
DeviceCgroupRules []string `yaml:"device_cgroup_rules,omitempty" json:"device_cgroup_rules,omitempty"`
|
DeviceCgroupRules []string `yaml:"device_cgroup_rules,omitempty" json:"device_cgroup_rules,omitempty"`
|
||||||
Devices []string `yaml:"devices,omitempty" json:"devices,omitempty"`
|
Devices []DeviceMapping `yaml:"devices,omitempty" json:"devices,omitempty"`
|
||||||
DNS StringList `yaml:"dns,omitempty" json:"dns,omitempty"`
|
DNS StringList `yaml:"dns,omitempty" json:"dns,omitempty"`
|
||||||
DNSOpts []string `yaml:"dns_opt,omitempty" json:"dns_opt,omitempty"`
|
DNSOpts []string `yaml:"dns_opt,omitempty" json:"dns_opt,omitempty"`
|
||||||
DNSSearch StringList `yaml:"dns_search,omitempty" json:"dns_search,omitempty"`
|
DNSSearch StringList `yaml:"dns_search,omitempty" json:"dns_search,omitempty"`
|
||||||
|
@ -239,6 +239,10 @@ const (
|
||||||
NetworkModeContainerPrefix = ContainerPrefix
|
NetworkModeContainerPrefix = ContainerPrefix
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SecretConfigXValue = "x-#value"
|
||||||
|
)
|
||||||
|
|
||||||
// GetDependencies retrieves all services this service depends on
|
// GetDependencies retrieves all services this service depends on
|
||||||
func (s ServiceConfig) GetDependencies() []string {
|
func (s ServiceConfig) GetDependencies() []string {
|
||||||
var dependencies []string
|
var dependencies []string
|
||||||
|
@ -301,6 +305,14 @@ type BlkioConfig struct {
|
||||||
Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
|
Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DeviceMapping struct {
|
||||||
|
Source string `yaml:"source,omitempty" json:"source,omitempty"`
|
||||||
|
Target string `yaml:"target,omitempty" json:"target,omitempty"`
|
||||||
|
Permissions string `yaml:"permissions,omitempty" json:"permissions,omitempty"`
|
||||||
|
|
||||||
|
Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
// WeightDevice is a structure that holds device:weight pair
|
// WeightDevice is a structure that holds device:weight pair
|
||||||
type WeightDevice struct {
|
type WeightDevice struct {
|
||||||
Path string
|
Path string
|
||||||
|
|
|
@ -128,7 +128,7 @@ github.com/cenkalti/backoff/v4
|
||||||
# github.com/cespare/xxhash/v2 v2.2.0
|
# github.com/cespare/xxhash/v2 v2.2.0
|
||||||
## explicit; go 1.11
|
## explicit; go 1.11
|
||||||
github.com/cespare/xxhash/v2
|
github.com/cespare/xxhash/v2
|
||||||
# github.com/compose-spec/compose-go/v2 v2.1.6
|
# github.com/compose-spec/compose-go/v2 v2.2.0
|
||||||
## explicit; go 1.21
|
## explicit; go 1.21
|
||||||
github.com/compose-spec/compose-go/v2/cli
|
github.com/compose-spec/compose-go/v2/cli
|
||||||
github.com/compose-spec/compose-go/v2/consts
|
github.com/compose-spec/compose-go/v2/consts
|
||||||
|
|
Loading…
Reference in New Issue