diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container_internal.go | 20 | ||||
-rw-r--r-- | libpod/container_internal_test.go | 48 | ||||
-rw-r--r-- | libpod/oci.go | 6 | ||||
-rw-r--r-- | libpod/runtime.go | 9 | ||||
-rw-r--r-- | libpod/runtime_pod_infra_linux.go | 24 |
5 files changed, 94 insertions, 13 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 08945c410..d86062e38 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -34,8 +34,8 @@ const ( ) var ( - // localeToLanguage maps from locale values to language tags. - localeToLanguage = map[string]string{ + // localeToLanguageMap maps from locale values to language tags. + localeToLanguageMap = map[string]string{ "": "und-u-va-posix", "c": "und-u-va-posix", "posix": "und-u-va-posix", @@ -1281,6 +1281,16 @@ func (c *Container) saveSpec(spec *spec.Spec) error { return nil } +// localeToLanguage translates POSIX locale strings to BCP 47 language tags. +func localeToLanguage(locale string) string { + locale = strings.Replace(strings.SplitN(locale, ".", 2)[0], "_", "-", 1) + langString, ok := localeToLanguageMap[strings.ToLower(locale)] + if !ok { + langString = locale + } + return langString +} + // Warning: precreate hooks may alter 'config' in place. func (c *Container) setupOCIHooks(ctx context.Context, config *spec.Spec) (extensionStageHooks map[string][]spec.Hook, err error) { var locale string @@ -1296,11 +1306,7 @@ func (c *Container) setupOCIHooks(ctx context.Context, config *spec.Spec) (exten } } - langString, ok := localeToLanguage[strings.ToLower(locale)] - if !ok { - langString = locale - } - + langString := localeToLanguage(locale) lang, err := language.Parse(langString) if err != nil { logrus.Warnf("failed to parse language %q: %s", langString, err) diff --git a/libpod/container_internal_test.go b/libpod/container_internal_test.go index f1e2b70a7..1654af929 100644 --- a/libpod/container_internal_test.go +++ b/libpod/container_internal_test.go @@ -17,6 +17,54 @@ import ( // hookPath is the path to an example hook executable. var hookPath string +func TestLocaleToLanguage(t *testing.T) { + for _, testCase := range []struct { + locale string + language string + }{ + { + locale: "", + language: "und-u-va-posix", + }, + { + locale: "C", + language: "und-u-va-posix", + }, + { + locale: "POSIX", + language: "und-u-va-posix", + }, + { + locale: "c", + language: "und-u-va-posix", + }, + { + locale: "en", + language: "en", + }, + { + locale: "en_US", + language: "en-US", + }, + { + locale: "en.UTF-8", + language: "en", + }, + { + locale: "en_US.UTF-8", + language: "en-US", + }, + { + locale: "does-not-exist", + language: "does-not-exist", + }, + } { + t.Run(testCase.locale, func(t *testing.T) { + assert.Equal(t, testCase.language, localeToLanguage(testCase.locale)) + }) + } +} + func TestPostDeleteHooks(t *testing.T) { ctx := context.Background() dir, err := ioutil.TempDir("", "libpod_test_") diff --git a/libpod/oci.go b/libpod/oci.go index 2cbf25699..c3b5f9af2 100644 --- a/libpod/oci.go +++ b/libpod/oci.go @@ -805,6 +805,12 @@ func (r *OCIRuntime) execContainer(c *Container, cmd, capAdd, env []string, tty execCmd.Env = append(execCmd.Env, fmt.Sprintf("XDG_RUNTIME_DIR=%s", runtimeDir)) + if preserveFDs > 0 { + for fd := 3; fd < 3+preserveFDs; fd++ { + execCmd.ExtraFiles = append(execCmd.ExtraFiles, os.NewFile(uintptr(fd), fmt.Sprintf("fd-%d", fd))) + } + } + if err := execCmd.Start(); err != nil { return nil, errors.Wrapf(err, "cannot start container %s", c.ID()) } diff --git a/libpod/runtime.go b/libpod/runtime.go index 482cd9d73..9667abfe6 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -971,9 +971,12 @@ func (r *Runtime) refreshRootless() error { // Take advantage of a command that requires a new userns // so that we are running as the root user and able to use refresh() cmd := exec.Command(os.Args[0], "info") - err := cmd.Run() - if err != nil { - return errors.Wrapf(err, "Error running %s info while refreshing state", os.Args[0]) + + if output, err := cmd.CombinedOutput(); err != nil { + if _, ok := err.(*exec.ExitError); !ok { + return errors.Wrapf(err, "Error waiting for info while refreshing state: %s", os.Args[0]) + } + return errors.Wrapf(err, "Error running %s info while refreshing state: %s", os.Args[0], output) } return nil } diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go index 4f221764a..81579db4b 100644 --- a/libpod/runtime_pod_infra_linux.go +++ b/libpod/runtime_pod_infra_linux.go @@ -4,11 +4,14 @@ package libpod import ( "context" + "strings" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/rootless" + "github.com/opencontainers/image-spec/specs-go/v1" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" + "github.com/pkg/errors" ) const ( @@ -17,7 +20,7 @@ const ( IDTruncLength = 12 ) -func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, imgID string) (*Container, error) { +func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, imgID string, config *v1.ImageConfig) (*Container, error) { // Set up generator for infra container defaults g, err := generate.New("linux") @@ -27,8 +30,23 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, imgID isRootless := rootless.IsRootless() + entryCmd := []string{r.config.InfraCommand} + // default to entrypoint in image if there is one + if len(config.Entrypoint) > 0 { + entryCmd = config.Entrypoint + } + if len(config.Env) > 0 { + for _, nameValPair := range config.Env { + nameValSlice := strings.Split(nameValPair, "=") + if len(nameValSlice) < 2 { + return nil, errors.Errorf("Invalid environment variable structure in pause image") + } + g.AddProcessEnv(nameValSlice[0], nameValSlice[1]) + } + } + g.SetRootReadonly(true) - g.SetProcessArgs([]string{r.config.InfraCommand}) + g.SetProcessArgs(entryCmd) if isRootless { g.RemoveMount("/dev/pts") @@ -79,5 +97,5 @@ func (r *Runtime) createInfraContainer(ctx context.Context, p *Pod) (*Container, imageName := newImage.Names()[0] imageID := data.ID - return r.makeInfraContainer(ctx, p, imageName, imageID) + return r.makeInfraContainer(ctx, p, imageName, imageID, newImage.Config) } |