From ba39ede7075ba17e059d0a19c206d2b806232cf3 Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Mon, 30 Aug 2021 10:41:52 +0200 Subject: [PATCH] run interpolation on yaml nodes Signed-off-by: Nicolas De Loof --- loader/interpolate.go | 60 ++++++++++++++++++++++++++++++++++++++----- loader/loader.go | 20 +++++---------- 2 files changed, 60 insertions(+), 20 deletions(-) diff --git a/loader/interpolate.go b/loader/interpolate.go index b45172a5..5cfa84b3 100644 --- a/loader/interpolate.go +++ b/loader/interpolate.go @@ -21,14 +21,21 @@ import ( "strings" interp "github.com/compose-spec/compose-go/interpolation" + "github.com/compose-spec/compose-go/types" "github.com/pkg/errors" ) var interpolateTypeCastMapping = map[interp.Path]interp.Cast{ servicePath("configs", interp.PathMatchList, "mode"): toInt, - servicePath("secrets", interp.PathMatchList, "mode"): toInt, - servicePath("healthcheck", "retries"): toInt, - servicePath("healthcheck", "disable"): toBoolean, + servicePath("cpu_count"): toInt64, + servicePath("cpu_percent"): toFloat, + servicePath("cpu_period"): toInt64, + servicePath("cpu_quota"): toInt64, + servicePath("cpu_rt_period"): toInt64, + servicePath("cpu_rt_runtime"): toInt64, + servicePath("cpus"): toFloat32, + servicePath("cpu_shares"): toInt64, + servicePath("init"): toBoolean, servicePath("deploy", "replicas"): toInt, servicePath("deploy", "update_config", "parallelism"): toInt, servicePath("deploy", "update_config", "max_failure_ratio"): toFloat, @@ -36,15 +43,28 @@ var interpolateTypeCastMapping = map[interp.Path]interp.Cast{ servicePath("deploy", "rollback_config", "max_failure_ratio"): toFloat, servicePath("deploy", "restart_policy", "max_attempts"): toInt, servicePath("deploy", "placement", "max_replicas_per_node"): toInt, + servicePath("healthcheck", "retries"): toInt, + servicePath("healthcheck", "disable"): toBoolean, + servicePath("mem_limit"): toUnitBytes, + servicePath("mem_reservation"): toUnitBytes, + servicePath("memswap_limit"): toUnitBytes, + servicePath("mem_swappiness"): toUnitBytes, + servicePath("oom_kill_disable"): toBoolean, + servicePath("oom_score_adj"): toInt64, + servicePath("pids_limit"): toInt64, servicePath("ports", interp.PathMatchList, "target"): toInt, servicePath("ports", interp.PathMatchList, "published"): toInt, - servicePath("ulimits", interp.PathMatchAll): toInt, - servicePath("ulimits", interp.PathMatchAll, "hard"): toInt, - servicePath("ulimits", interp.PathMatchAll, "soft"): toInt, servicePath("privileged"): toBoolean, servicePath("read_only"): toBoolean, + servicePath("scale"): toInt, + servicePath("secrets", interp.PathMatchList, "mode"): toInt, + servicePath("shm_size"): toUnitBytes, servicePath("stdin_open"): toBoolean, + servicePath("stop_grace_period"): toDuration, servicePath("tty"): toBoolean, + servicePath("ulimits", interp.PathMatchAll): toInt, + servicePath("ulimits", interp.PathMatchAll, "hard"): toInt, + servicePath("ulimits", interp.PathMatchAll, "soft"): toInt, servicePath("volumes", interp.PathMatchList, "read_only"): toBoolean, servicePath("volumes", interp.PathMatchList, "volume", "nocopy"): toBoolean, iPath("networks", interp.PathMatchAll, "external"): toBoolean, @@ -67,10 +87,38 @@ func toInt(value string) (interface{}, error) { return strconv.Atoi(value) } +func toInt64(value string) (interface{}, error) { + return strconv.ParseInt(value, 10, 64) +} + +func toUnitBytes(value string) (interface{}, error) { + i, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return nil, err + } + return types.UnitBytes(i), nil +} + +func toDuration(value string) (interface{}, error) { + i, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return nil, err + } + return types.Duration(i), nil +} + func toFloat(value string) (interface{}, error) { return strconv.ParseFloat(value, 64) } +func toFloat32(value string) (interface{}, error) { + f, err := strconv.ParseFloat(value, 32) + if err != nil { + return nil, err + } + return float32(f), nil +} + // should match http://yaml.org/type/bool.html func toBoolean(value string) (interface{}, error) { switch strings.ToLower(value) { diff --git a/loader/loader.go b/loader/loader.go index d868c722..97d7fdcf 100644 --- a/loader/loader.go +++ b/loader/loader.go @@ -23,7 +23,6 @@ import ( "path" "path/filepath" "reflect" - "regexp" "sort" "strings" "time" @@ -216,21 +215,14 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types. } func parseConfig(b []byte, opts *Options) (map[string]interface{}, error) { + yaml, err := ParseYAML(b) + if err != nil { + return nil, err + } if !opts.SkipInterpolation { - withoutFullLineComments := removeYamlComments(string(b)) - substituted, err := opts.Interpolate.Substitute(withoutFullLineComments, template.Mapping(opts.Interpolate.LookupValue)) - if err != nil { - return nil, err - } - b = []byte(substituted) + return interp.Interpolate(yaml, *opts.Interpolate) } - - return ParseYAML(b) -} - -// removeYamlComments drop all full line comments from the yaml file, so we don't try to apply string substitutions on most of the irrelevant places -func removeYamlComments(content string) string { - return regexp.MustCompile(`(?m)^[ \t]*#.*\n*`).ReplaceAllString(content, "") + return yaml, err } func groupXFieldsIntoExtensions(dict map[string]interface{}) map[string]interface{} {