Merge pull request #3997 from 11janci/jjanik-docker-env-escape
Escape systemd special chars in docker-envpull/4054/head
commit
e48fdddde9
|
@ -21,6 +21,7 @@ import (
|
|||
"fmt"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
|
@ -47,6 +48,9 @@ type BuildrootProvisioner struct {
|
|||
provision.SystemdProvisioner
|
||||
}
|
||||
|
||||
// for escaping systemd template specifiers (e.g. '%i'), which are not supported by minikube
|
||||
var systemdSpecifierEscaper = strings.NewReplacer("%", "%%")
|
||||
|
||||
func init() {
|
||||
provision.Register("Buildroot", &provision.RegisteredProvisioner{
|
||||
New: NewBuildrootProvisioner,
|
||||
|
@ -64,6 +68,17 @@ func (p *BuildrootProvisioner) String() string {
|
|||
return "buildroot"
|
||||
}
|
||||
|
||||
// escapeSystemdDirectives escapes special characters in the input variables used to create the
|
||||
// systemd unit file, which would otherwise be interpreted as systemd directives. An example
|
||||
// are template specifiers (e.g. '%i') which are predefined variables that get evaluated dynamically
|
||||
// (see systemd man pages for more info). This is not supported by minikube, thus needs to be escaped.
|
||||
func escapeSystemdDirectives(engineConfigContext *provision.EngineConfigContext) {
|
||||
// escape '%' in Environment option so that it does not evaluate into a template specifier
|
||||
engineConfigContext.EngineOptions.Env = util.ReplaceChars(engineConfigContext.EngineOptions.Env, systemdSpecifierEscaper)
|
||||
// input might contain whitespaces, wrap it in quotes
|
||||
engineConfigContext.EngineOptions.Env = util.ConcatStrings(engineConfigContext.EngineOptions.Env, "\"", "\"")
|
||||
}
|
||||
|
||||
// GenerateDockerOptions generates the *provision.DockerOptions for this provisioner
|
||||
func (p *BuildrootProvisioner) GenerateDockerOptions(dockerPort int) (*provision.DockerOptions, error) {
|
||||
var engineCfg bytes.Buffer
|
||||
|
@ -127,6 +142,8 @@ WantedBy=multi-user.target
|
|||
EngineOptions: p.EngineOptions,
|
||||
}
|
||||
|
||||
escapeSystemdDirectives(&engineConfigContext)
|
||||
|
||||
if err := t.Execute(&engineCfg, engineConfigContext); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -250,3 +250,26 @@ func TeePrefix(prefix string, r io.Reader, w io.Writer, logger func(format strin
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReplaceChars returns a copy of the src slice with each string modified by the replacer
|
||||
func ReplaceChars(src []string, replacer *strings.Replacer) []string {
|
||||
ret := make([]string, len(src))
|
||||
for i, s := range src {
|
||||
ret[i] = replacer.Replace(s)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// ConcatStrings concatenates each string in the src slice with prefix and postfix and returns a new slice
|
||||
func ConcatStrings(src []string, prefix string, postfix string) []string {
|
||||
var buf bytes.Buffer
|
||||
ret := make([]string, len(src))
|
||||
for i, s := range src {
|
||||
buf.WriteString(prefix)
|
||||
buf.WriteString(s)
|
||||
buf.WriteString(postfix)
|
||||
ret[i] = buf.String()
|
||||
buf.Reset()
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
|
|
@ -197,3 +197,43 @@ func TestTeePrefix(t *testing.T) {
|
|||
t.Errorf("log=%q, want: %q", gotLog, wantLog)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReplaceChars(t *testing.T) {
|
||||
testData := []struct {
|
||||
src []string
|
||||
replacer *strings.Replacer
|
||||
expectedRes []string
|
||||
}{
|
||||
{[]string{"abc%def", "%Y%"}, strings.NewReplacer("%", "X"), []string{"abcXdef", "XYX"}},
|
||||
}
|
||||
|
||||
for _, tt := range testData {
|
||||
res := ReplaceChars(tt.src, tt.replacer)
|
||||
for i, val := range res {
|
||||
if val != tt.expectedRes[i] {
|
||||
t.Fatalf("Expected '%s' but got '%s'", tt.expectedRes, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConcatStrings(t *testing.T) {
|
||||
testData := []struct {
|
||||
src []string
|
||||
prefix string
|
||||
postfix string
|
||||
expectedRes []string
|
||||
}{
|
||||
{[]string{"abc", ""}, "xx", "yy", []string{"xxabcyy", "xxyy"}},
|
||||
{[]string{"abc", ""}, "", "", []string{"abc", ""}},
|
||||
}
|
||||
|
||||
for _, tt := range testData {
|
||||
res := ConcatStrings(tt.src, tt.prefix, tt.postfix)
|
||||
for i, val := range res {
|
||||
if val != tt.expectedRes[i] {
|
||||
t.Fatalf("Expected '%s' but got '%s'", tt.expectedRes, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue