diff --git a/override/merge.go b/override/merge.go index 697dbc74..8cb0ed52 100644 --- a/override/merge.go +++ b/override/merge.go @@ -57,6 +57,7 @@ func init() { mergeSpecials["services.*.dns_search"] = mergeToSequence mergeSpecials["services.*.entrypoint"] = override mergeSpecials["services.*.env_file"] = mergeToSequence + mergeSpecials["services.*.label_file"] = mergeToSequence mergeSpecials["services.*.environment"] = mergeToSequence mergeSpecials["services.*.extra_hosts"] = mergeExtraHosts mergeSpecials["services.*.healthcheck.test"] = override diff --git a/override/uncity.go b/override/uncity.go index 3b0c63d3..6b5b8ae9 100644 --- a/override/uncity.go +++ b/override/uncity.go @@ -51,6 +51,7 @@ func init() { unique["services.*.env_file"] = envFileIndexer unique["services.*.expose"] = exposeIndexer unique["services.*.labels"] = keyValueIndexer + unique["services.*.label_file"] = labelFileIndexer unique["services.*.links"] = keyValueIndexer unique["services.*.networks.*.aliases"] = keyValueIndexer unique["services.*.networks.*.link_local_ips"] = keyValueIndexer @@ -227,3 +228,16 @@ func envFileIndexer(y any, p tree.Path) (string, error) { } return "", nil } + +func labelFileIndexer(y any, p tree.Path) (string, error) { + switch value := y.(type) { + case string: + return value, nil + case map[string]any: + if pathValue, ok := value["path"]; ok { + return pathValue.(string), nil + } + return "", fmt.Errorf("label path attribute %s is missing", p) + } + return "", nil +} diff --git a/paths/resolve.go b/paths/resolve.go index 303f39e2..0569e658 100644 --- a/paths/resolve.go +++ b/paths/resolve.go @@ -37,6 +37,7 @@ func ResolveRelativePaths(project map[string]any, base string, remotes []RemoteR "services.*.build.context": r.absContextPath, "services.*.build.additional_contexts.*": r.absContextPath, "services.*.env_file.*.path": r.absPath, + "services.*.label_file.*.path": r.absPath, "services.*.extends.file": r.absExtendsPath, "services.*.develop.watch.*.path": r.absSymbolicLink, "services.*.volumes.*": r.absVolumeMount, diff --git a/schema/compose-spec.json b/schema/compose-spec.json index b95a1498..fab1698f 100644 --- a/schema/compose-spec.json +++ b/schema/compose-spec.json @@ -240,6 +240,7 @@ "domainname": {"type": "string"}, "entrypoint": {"$ref": "#/definitions/command"}, "env_file": {"$ref": "#/definitions/env_file"}, + "label_file": {"$ref": "#/definitions/label_file"}, "environment": {"$ref": "#/definitions/list_or_dict"}, "expose": { @@ -852,6 +853,36 @@ }, "env_file": { + "oneOf": [ + {"type": "string"}, + { + "type": "array", + "items": { + "oneOf": [ + {"type": "string"}, + { + "type": "object", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "required": { + "type": ["boolean", "string"], + "default": true + } + }, + "required": [ + "path" + ] + } + ] + } + } + ] + }, + + "label_file": { "oneOf": [ {"type": "string"}, { diff --git a/transform/canonical.go b/transform/canonical.go index ff5bb37d..27d03810 100644 --- a/transform/canonical.go +++ b/transform/canonical.go @@ -30,6 +30,7 @@ func init() { transformers["services.*.build.additional_contexts"] = transformKeyValue transformers["services.*.depends_on"] = transformDependsOn transformers["services.*.env_file"] = transformEnvFile + transformers["services.*.label_file"] = transformLabelFile transformers["services.*.extends"] = transformExtends transformers["services.*.networks"] = transformServiceNetworks transformers["services.*.volumes.*"] = transformVolumeMount diff --git a/types/types.go b/types/types.go index 3cae5390..7be08c30 100644 --- a/types/types.go +++ b/types/types.go @@ -89,6 +89,7 @@ type ServiceConfig struct { Ipc string `yaml:"ipc,omitempty" json:"ipc,omitempty"` Isolation string `yaml:"isolation,omitempty" json:"isolation,omitempty"` Labels Labels `yaml:"labels,omitempty" json:"labels,omitempty"` + LabelFiles []LabelFile `yaml:"label_file,omitempty" json:"label_file,omitempty"` CustomLabels Labels `yaml:"-" json:"-"` Links []string `yaml:"links,omitempty" json:"links,omitempty"` Logging *LoggingConfig `yaml:"logging,omitempty" json:"logging,omitempty"`