Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 54 additions & 6 deletions loader/interpolate.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,50 @@ 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,
servicePath("deploy", "rollback_config", "parallelism"): toInt,
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,
Expand All @@ -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) {
Expand Down
20 changes: 6 additions & 14 deletions loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"path"
"path/filepath"
"reflect"
"regexp"
"sort"
"strings"
"time"
Expand Down Expand Up @@ -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{} {
Expand Down