mirror of
https://github.com/containers/podman.git
synced 2025-06-23 02:18:13 +08:00
Merge pull request #20256 from Luap99/revert-env
Revert --env-file changes
This commit is contained in:
@ -4,8 +4,4 @@
|
|||||||
####> are applicable to all of those.
|
####> are applicable to all of those.
|
||||||
#### **--env-file**=*file*
|
#### **--env-file**=*file*
|
||||||
|
|
||||||
Read the environment variables from the file, supporting prefix matching: `KEY*`, as well as multiline values in double quotes and single quotes, but not multiline values in backticks.
|
Read in a line-delimited file of environment variables.
|
||||||
The env-file will ignore comments and empty lines. And spaces or tabs before and after the KEY.
|
|
||||||
If an invalid value is encountered, such as only an `=` sign, it will be skipped. If it is a prefix match (`KEY*`), all environment variables starting with KEY on the host machine will be loaded.
|
|
||||||
If it is only KEY (`KEY`), the KEY environment variable on the host machine will be loaded.
|
|
||||||
Compatible with the `export` syntax in **dotenv**, such as: `export KEY=bar`.
|
|
||||||
|
144
pkg/env/env.go
vendored
144
pkg/env/env.go
vendored
@ -1,29 +1,13 @@
|
|||||||
|
// Package for processing environment variables.
|
||||||
package env
|
package env
|
||||||
|
|
||||||
|
// TODO: we need to add tests for this package.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/storage/pkg/regexp"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// Form: https://github.com/motdotla/dotenv/blob/aa03dcad1002027390dac1e8d96ac236274de354/lib/main.js#L9C76-L9C76
|
|
||||||
// (?:export\s+)?([\w.-]+) match key
|
|
||||||
// ([\w.%-]+)(\s*[=|*]\s*?|:\s+?) match separator
|
|
||||||
// Remaining match value
|
|
||||||
// e.g. KEY=VALUE => KEY, =, VALUE
|
|
||||||
//
|
|
||||||
// KEY= => KEY, =, ""
|
|
||||||
// KEY* => KEY, *, ""
|
|
||||||
// KEY*=1 => KEY, *, =1
|
|
||||||
lineRegexp = regexp.Delayed(
|
|
||||||
`(?m)(?:^|^)\s*(?:export\s+)?([\w.%-]+)(\s*[=|*]\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*` +
|
|
||||||
"`(?:\\`|[^`])*`" + `|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)`,
|
|
||||||
)
|
|
||||||
onlyKeyRegexp = regexp.Delayed(`^[\w.-]+$`)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const whiteSpaces = " \t"
|
const whiteSpaces = " \t"
|
||||||
@ -95,120 +79,26 @@ func ParseFile(path string) (_ map[string]string, err error) {
|
|||||||
}
|
}
|
||||||
defer fh.Close()
|
defer fh.Close()
|
||||||
|
|
||||||
content, err := io.ReadAll(fh)
|
scanner := bufio.NewScanner(fh)
|
||||||
if err != nil {
|
for scanner.Scan() {
|
||||||
|
// trim the line from all leading whitespace first
|
||||||
|
line := strings.TrimLeft(scanner.Text(), whiteSpaces)
|
||||||
|
// line is not empty, and not starting with '#'
|
||||||
|
if len(line) > 0 && !strings.HasPrefix(line, "#") {
|
||||||
|
if err := parseEnv(env, line); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// replace all \r\n and \r with \n
|
}
|
||||||
text := strings.NewReplacer("\r\n", "\n", "\r", "\n").Replace(string(content))
|
return env, scanner.Err()
|
||||||
if err := parseEnv(env, text); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return env, nil
|
func parseEnv(env map[string]string, line string) error {
|
||||||
}
|
data := strings.SplitN(line, "=", 2)
|
||||||
|
|
||||||
// parseEnv parse the given content into env format
|
|
||||||
//
|
|
||||||
// @example: parseEnv(env, "#comment") => nil
|
|
||||||
// @example: parseEnv(env, "") => nil
|
|
||||||
// @example: parseEnv(env, "KEY=FOO") => nil
|
|
||||||
// @example: parseEnv(env, "KEY") => nil
|
|
||||||
func parseEnv(env map[string]string, content string) error {
|
|
||||||
m := envMatch(content)
|
|
||||||
|
|
||||||
for _, match := range m {
|
|
||||||
key := match[1]
|
|
||||||
separator := strings.Trim(match[2], whiteSpaces)
|
|
||||||
value := match[3]
|
|
||||||
|
|
||||||
if strings.Contains(value, "\n") {
|
|
||||||
if strings.HasPrefix(value, "`") {
|
|
||||||
return fmt.Errorf("only support multi-line environment variables surrounded by "+
|
|
||||||
"double quotation marks or single quotation marks. invalid variable: %q", match[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
// In the case of multi-line values, we need to remove the surrounding " '
|
|
||||||
value = strings.Trim(value, "\"'")
|
|
||||||
}
|
|
||||||
|
|
||||||
// KEY*=1 => KEY, *, =1 => KEY*, =, 1
|
|
||||||
if separator == "*" && strings.HasPrefix(value, "=") {
|
|
||||||
key += "*"
|
|
||||||
separator = "="
|
|
||||||
value = strings.TrimPrefix(value, "=")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch separator {
|
|
||||||
case "=":
|
|
||||||
// KEY=
|
|
||||||
if value == "" {
|
|
||||||
if val, ok := os.LookupEnv(key); ok {
|
|
||||||
env[key] = val
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
env[key] = value
|
|
||||||
}
|
|
||||||
case "*":
|
|
||||||
for _, e := range os.Environ() {
|
|
||||||
part := strings.SplitN(e, "=", 2)
|
|
||||||
if len(part) < 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(part[0], key) {
|
|
||||||
env[part[0]] = part[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func envMatch(content string) [][]string {
|
|
||||||
m := lineRegexp.FindAllStringSubmatch(content, -1)
|
|
||||||
|
|
||||||
// KEY => KEY, =, ""
|
|
||||||
// Due to the above regex pattern, it will skip cases where only KEY is present (e.g., foo).
|
|
||||||
// However, in our requirement, this situation is equivalent to foo=(i.e., "foo" == "foo=").
|
|
||||||
// Therefore, we need to perform additional processing.
|
|
||||||
// The reason for needing to support this scenario is that we need to consider: `podman run -e CI -e USERNAME`.
|
|
||||||
{
|
|
||||||
noMatched := lineRegexp.ReplaceAllString(content, "")
|
|
||||||
nl := strings.Split(noMatched, "\n")
|
|
||||||
for _, key := range nl {
|
|
||||||
key := strings.Trim(key, whiteSpaces)
|
|
||||||
if key == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if onlyKeyRegexp.MatchString(key) {
|
|
||||||
m = append(m, []string{key, key, "=", ""})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseEnvWithSlice parsing a set of Env variables from a slice of strings
|
|
||||||
// because the majority of shell interpreters discard double quotes and single quotes,
|
|
||||||
// for example: podman run -e K='V', when passed into a program, it will become: K=V.
|
|
||||||
// This can lead to unexpected issues, as discussed in this link: https://github.com/containers/podman/pull/19096#issuecomment-1670164724.
|
|
||||||
//
|
|
||||||
// parseEnv method will discard all comments (#) that are not wrapped in quotation marks,
|
|
||||||
// so it cannot be used to parse env variables obtained from the command line.
|
|
||||||
//
|
|
||||||
// @example: parseEnvWithSlice(env, "KEY=FOO") => KEY: FOO
|
|
||||||
// @example: parseEnvWithSlice(env, "KEY") => KEY: ""
|
|
||||||
// @example: parseEnvWithSlice(env, "KEY=") => KEY: ""
|
|
||||||
// @example: parseEnvWithSlice(env, "KEY=FOO=BAR") => KEY: FOO=BAR
|
|
||||||
// @example: parseEnvWithSlice(env, "KEY=FOO#BAR") => KEY: FOO#BAR
|
|
||||||
func parseEnvWithSlice(env map[string]string, content string) error {
|
|
||||||
data := strings.SplitN(content, "=", 2)
|
|
||||||
|
|
||||||
// catch invalid variables such as "=" or "=A"
|
// catch invalid variables such as "=" or "=A"
|
||||||
if data[0] == "" {
|
if data[0] == "" {
|
||||||
return fmt.Errorf("invalid variable: %q", content)
|
return fmt.Errorf("invalid variable: %q", line)
|
||||||
}
|
}
|
||||||
// trim the front of a variable, but nothing else
|
// trim the front of a variable, but nothing else
|
||||||
name := strings.TrimLeft(data[0], whiteSpaces)
|
name := strings.TrimLeft(data[0], whiteSpaces)
|
||||||
|
317
pkg/env/env_test.go
vendored
317
pkg/env/env_test.go
vendored
@ -1,8 +1,6 @@
|
|||||||
package env
|
package env
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -101,312 +99,63 @@ func TestJoin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTmpFile(content string) (string, error) {
|
func Test_parseEnv(t *testing.T) {
|
||||||
tmpfile, err := os.CreateTemp(os.TempDir(), "podman-test-parse-env-")
|
good := make(map[string]string)
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := tmpfile.WriteString(content); err != nil {
|
type args struct {
|
||||||
return "", err
|
env map[string]string
|
||||||
}
|
|
||||||
if err := tmpfile.Close(); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return tmpfile.Name(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_ParseFile(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
key string
|
|
||||||
separator string // = or *
|
|
||||||
value string
|
|
||||||
|
|
||||||
// environment variable
|
|
||||||
envKey string
|
|
||||||
envValue string
|
|
||||||
|
|
||||||
expectedKey string
|
|
||||||
expectedValue string
|
|
||||||
success bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "Good",
|
|
||||||
key: "Key",
|
|
||||||
separator: "=",
|
|
||||||
value: "Value1",
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "HasDoubleQuotesWithSingleLine",
|
|
||||||
key: "Key2",
|
|
||||||
separator: "=",
|
|
||||||
value: `"Value2"`,
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "HasSingleQuotesWithSingleLine",
|
|
||||||
key: "Key3",
|
|
||||||
separator: "=",
|
|
||||||
value: `'Value3'`,
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "KeepValueSpace",
|
|
||||||
key: "Key4",
|
|
||||||
separator: "=",
|
|
||||||
value: " Value4 ",
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "RemoveKeySpace",
|
|
||||||
key: " Key5 ",
|
|
||||||
separator: "=",
|
|
||||||
expectedKey: "Key5",
|
|
||||||
value: "Value5",
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "NoValue",
|
|
||||||
key: "Key6",
|
|
||||||
separator: "=",
|
|
||||||
value: "",
|
|
||||||
envValue: "Value6",
|
|
||||||
expectedValue: "Value6",
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "FromEnv",
|
|
||||||
key: "Key7",
|
|
||||||
separator: "=",
|
|
||||||
value: "",
|
|
||||||
envValue: "Value7",
|
|
||||||
expectedValue: "Value7",
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "OnlyKey",
|
|
||||||
key: "Key8",
|
|
||||||
separator: "",
|
|
||||||
value: "",
|
|
||||||
envValue: "Value8",
|
|
||||||
expectedValue: "Value8",
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GlobKey",
|
|
||||||
key: "Key9",
|
|
||||||
separator: "*",
|
|
||||||
value: "",
|
|
||||||
envKey: "Key9999",
|
|
||||||
envValue: "Value9",
|
|
||||||
expectedKey: "Key9999",
|
|
||||||
expectedValue: "Value9",
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "InvalidGlobKey",
|
|
||||||
key: "Key10*",
|
|
||||||
separator: "=",
|
|
||||||
value: "1",
|
|
||||||
envKey: "Key1010",
|
|
||||||
envValue: "Value10",
|
|
||||||
expectedKey: "Key10*",
|
|
||||||
expectedValue: "1",
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "MultilineWithDoubleQuotes",
|
|
||||||
key: "Key11",
|
|
||||||
separator: "=",
|
|
||||||
value: "\"First line1\nlast line1\"",
|
|
||||||
expectedValue: "First line1\nlast line1",
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "MultilineWithSingleQuotes",
|
|
||||||
key: "Key12",
|
|
||||||
separator: "=",
|
|
||||||
value: "'First line2\nlast line2'",
|
|
||||||
expectedValue: "First line2\nlast line2",
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Has%",
|
|
||||||
key: "BASH_FUNC__fmt_ctx%%",
|
|
||||||
separator: "=",
|
|
||||||
value: "() { echo 1; }",
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Export syntax",
|
|
||||||
key: "export Key13",
|
|
||||||
separator: "=",
|
|
||||||
value: "Value13",
|
|
||||||
expectedKey: "Key13",
|
|
||||||
expectedValue: "Value13",
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "NoValueAndNoEnv",
|
|
||||||
key: "Key14",
|
|
||||||
separator: "=",
|
|
||||||
value: "",
|
|
||||||
success: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "OnlyValue",
|
|
||||||
key: "",
|
|
||||||
separator: "=",
|
|
||||||
value: "Value",
|
|
||||||
success: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "OnlyDelim",
|
|
||||||
key: "",
|
|
||||||
separator: "=",
|
|
||||||
value: "",
|
|
||||||
success: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Comment",
|
|
||||||
key: "#aaaa",
|
|
||||||
separator: "",
|
|
||||||
value: "",
|
|
||||||
success: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
content := ""
|
|
||||||
for _, tt := range tests {
|
|
||||||
content += fmt.Sprintf("%s%s%s\n", tt.key, tt.separator, tt.value)
|
|
||||||
|
|
||||||
if tt.envValue != "" {
|
|
||||||
key := tt.key
|
|
||||||
if tt.envKey != "" {
|
|
||||||
key = tt.envKey
|
|
||||||
}
|
|
||||||
t.Setenv(key, tt.envValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tFile, err := createTmpFile(content)
|
|
||||||
defer os.Remove(tFile)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
env, err := ParseFile(tFile)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
key := tt.key
|
|
||||||
if tt.expectedKey != "" {
|
|
||||||
key = tt.expectedKey
|
|
||||||
}
|
|
||||||
val, ok := env[key]
|
|
||||||
if ok && !tt.success {
|
|
||||||
t.Errorf("not should set key:%s ", tt.key)
|
|
||||||
return
|
|
||||||
} else if !ok && tt.success {
|
|
||||||
t.Errorf("should set key:%s ", tt.key)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if tt.success {
|
|
||||||
value := tt.value
|
|
||||||
if tt.expectedValue != "" {
|
|
||||||
value = tt.expectedValue
|
|
||||||
}
|
|
||||||
assert.Equal(t, value, val, "value should be equal")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_parseEnvWithSlice(t *testing.T) {
|
|
||||||
type result struct {
|
|
||||||
key string
|
|
||||||
value string
|
|
||||||
hasErr bool
|
|
||||||
}
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
line string
|
line string
|
||||||
want result
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Good",
|
name: "Good",
|
||||||
|
args: args{
|
||||||
|
env: good,
|
||||||
line: "apple=red",
|
line: "apple=red",
|
||||||
want: result{
|
|
||||||
key: "apple",
|
|
||||||
value: "red",
|
|
||||||
},
|
},
|
||||||
|
wantErr: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "NoValue",
|
name: "GoodNoValue",
|
||||||
line: "google=",
|
args: args{
|
||||||
want: result{
|
env: good,
|
||||||
key: "google",
|
line: "apple=",
|
||||||
value: "",
|
|
||||||
},
|
},
|
||||||
|
wantErr: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OnlyKey",
|
name: "GoodNoKeyNoValue",
|
||||||
line: "redhat",
|
args: args{
|
||||||
want: result{
|
env: good,
|
||||||
key: "redhat",
|
|
||||||
value: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "NoKey",
|
|
||||||
line: "=foobar",
|
|
||||||
want: result{
|
|
||||||
hasErr: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "OnlyDelim",
|
|
||||||
line: "=",
|
line: "=",
|
||||||
want: result{
|
|
||||||
hasErr: true,
|
|
||||||
},
|
},
|
||||||
|
wantErr: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Has#",
|
name: "BadNoKey",
|
||||||
line: "facebook=red#blue",
|
args: args{
|
||||||
want: result{
|
env: good,
|
||||||
key: "facebook",
|
line: "=foobar",
|
||||||
value: "red#blue",
|
|
||||||
},
|
},
|
||||||
|
wantErr: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Has\\n",
|
name: "BadOnlyDelim",
|
||||||
// twitter="foo
|
args: args{
|
||||||
// bar"
|
env: good,
|
||||||
line: "twitter=\"foo\nbar\"",
|
line: "=",
|
||||||
want: result{
|
|
||||||
key: "twitter",
|
|
||||||
value: `"foo` + "\n" + `bar"`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "MultilineWithBackticksQuotes",
|
|
||||||
line: "github=`First line\nlast line`",
|
|
||||||
want: result{
|
|
||||||
key: "github",
|
|
||||||
value: "`First line\nlast line`",
|
|
||||||
},
|
},
|
||||||
|
wantErr: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
envs := make(map[string]string)
|
if err := parseEnv(tt.args.env, tt.args.line); (err != nil) != tt.wantErr {
|
||||||
if err := parseEnvWithSlice(envs, tt.line); (err != nil) != tt.want.hasErr {
|
t.Errorf("parseEnv() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
t.Errorf("parseEnv() error = %v, want has Err %v", err, tt.want.hasErr)
|
|
||||||
} else if envs[tt.want.key] != tt.want.value {
|
|
||||||
t.Errorf("parseEnv() result = map[%v:%v], but got %v", tt.want.key, tt.want.value, envs)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
2
pkg/env/env_unix.go
vendored
2
pkg/env/env_unix.go
vendored
@ -8,7 +8,7 @@ package env
|
|||||||
func ParseSlice(s []string) (map[string]string, error) {
|
func ParseSlice(s []string) (map[string]string, error) {
|
||||||
env := make(map[string]string, len(s))
|
env := make(map[string]string, len(s))
|
||||||
for _, e := range s {
|
for _, e := range s {
|
||||||
if err := parseEnvWithSlice(env, e); err != nil {
|
if err := parseEnv(env, e); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
pkg/env/env_windows.go
vendored
2
pkg/env/env_windows.go
vendored
@ -17,7 +17,7 @@ func ParseSlice(s []string) (map[string]string, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := parseEnvWithSlice(env, e); err != nil {
|
if err := parseEnv(env, e); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,18 +154,8 @@ EOF
|
|||||||
--env-file $envfile2 \
|
--env-file $envfile2 \
|
||||||
$IMAGE sh -c 'env -0 >/envresults'
|
$IMAGE sh -c 'env -0 >/envresults'
|
||||||
|
|
||||||
# FIXME FIXME FIXME #19565, exceptions
|
expect[withnl]=$'"line1'
|
||||||
#
|
expect[weird*na#me!]=$weirdname
|
||||||
# FIXME FIXME FIXME #19565, octothorpe not handled in envariable values
|
|
||||||
# FIXME FIXME FIXME: this should be fixed, and the line below removed
|
|
||||||
expect[special]="bcd"
|
|
||||||
|
|
||||||
# FIXME FIXME FIXME #19565, what should multi-line strings be?
|
|
||||||
# FIXME FIXME FIXME: For docker compat, this should be >>>"line1<<<
|
|
||||||
expect[withnl]=$'line1\nline2'
|
|
||||||
|
|
||||||
# FIXME FIXME FIXME uncomment this once octothorpe parsing is fixed
|
|
||||||
#expect[weird*na#me!]=$weirdname
|
|
||||||
|
|
||||||
_check_env $resultsfile
|
_check_env $resultsfile
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user