diff --git a/initialize/env.go b/initialize/env.go index 245fe05..e34c268 100644 --- a/initialize/env.go +++ b/initialize/env.go @@ -3,6 +3,7 @@ package initialize import ( "os" "path" + "regexp" "strings" "github.com/coreos/coreos-cloudinit/system" @@ -62,9 +63,18 @@ func (e *Environment) SetSSHKeyName(name string) { e.sshKeyName = name } +// Apply goes through the map of substitutions and replaces all instances of +// the keys with their respective values. It supports escaping substitutions +// with a leading '\'. func (e *Environment) Apply(data string) string { for key, val := range e.substitutions { - data = strings.Replace(data, key, val, -1) + matchKey := strings.Replace(key, `$`, `\$`, -1) + replKey := strings.Replace(key, `$`, `$$`, -1) + + // "key" -> "val" + data = regexp.MustCompile(`([^\\]|^)`+matchKey).ReplaceAllString(data, `${1}`+val) + // "\key" -> "key" + data = regexp.MustCompile(`\\`+matchKey).ReplaceAllString(data, replKey) } return data } diff --git a/initialize/env_test.go b/initialize/env_test.go index c45283d..ef31b82 100644 --- a/initialize/env_test.go +++ b/initialize/env_test.go @@ -55,6 +55,24 @@ ExecStop=/usr/bin/echo $unknown`, "$private_ipv4\nfoobar", "5.6.7.8\nfoobar", }, + { + // Escaping substitutions + map[string]string{"$private_ipv4": "127.0.0.1"}, + `\$private_ipv4 +$private_ipv4 +addr: \$private_ipv4 +\\$private_ipv4`, + `$private_ipv4 +127.0.0.1 +addr: $private_ipv4 +\$private_ipv4`, + }, + { + // No substitutions with escaping + nil, + "\\$test\n$test", + "\\$test\n$test", + }, } { env := NewEnvironment("./", "./", "./", "", "", tt.subs)