From 9b520a08ada5c8d004fdab1e2325f2cbfa8f0226 Mon Sep 17 00:00:00 2001 From: Yann Soubeyrand Date: Fri, 15 May 2020 21:27:14 +0200 Subject: [PATCH] Allow specifying user shell at toolbox creation When creating a toolbox the user shell can be specified and this shell will be used when entering the toolbox. Signed-off-by: Yann Soubeyrand --- src/cmd/create.go | 26 ++++++++++++++++++++++---- src/cmd/enter.go | 18 +++--------------- src/cmd/run.go | 42 +++++++++++++++++------------------------- src/pkg/utils/utils.go | 1 - 4 files changed, 42 insertions(+), 45 deletions(-) diff --git a/src/cmd/create.go b/src/cmd/create.go index c48698bc3..e68cdc341 100644 --- a/src/cmd/create.go +++ b/src/cmd/create.go @@ -45,6 +45,7 @@ var ( container string image string release string + shell string } createToolboxShMounts = []struct { @@ -83,6 +84,12 @@ func init() { "", "Create a toolbox container for a different operating system release than the host") + flags.StringVarP(&createFlags.shell, + "shell", + "s", + "", + "Specify the shell to use in the toolbox.") + createCmd.SetHelpFunc(createHelp) rootCmd.AddCommand(createCmd) } @@ -143,14 +150,23 @@ func create(cmd *cobra.Command, args []string) error { return err } - if err := createContainer(container, image, release, true); err != nil { + var userShell string + if createFlags.shell != "" { + userShell = createFlags.shell + if !filepath.IsAbs(userShell) { + return fmt.Errorf("Invalid shell '%s': must be an absolute path", userShell) + } + userShell = filepath.Clean(userShell) + } + + if err := createContainer(container, image, release, userShell, true); err != nil { return err } return nil } -func createContainer(container, image, release string, showCommandToEnter bool) error { +func createContainer(container, image, release string, userShell string, showCommandToEnter bool) error { if container == "" { panic("container not specified") } @@ -345,9 +361,11 @@ func createContainer(container, image, release string, showCommandToEnter bool) logLevelString := podman.LogLevel.String() - userShell := os.Getenv("SHELL") if userShell == "" { - return errors.New("failed to get the current user's default shell") + userShell = os.Getenv("SHELL") + if userShell == "" { + return errors.New("failed to get the current user's default shell") + } } entryPoint := []string{ diff --git a/src/cmd/enter.go b/src/cmd/enter.go index 6763d5eee..0a01a5283 100644 --- a/src/cmd/enter.go +++ b/src/cmd/enter.go @@ -114,13 +114,6 @@ func enter(cmd *cobra.Command, args []string) error { return err } - userShell := os.Getenv("SHELL") - if userShell == "" { - return errors.New("failed to get the current user's default shell") - } - - command := []string{userShell, "-l"} - hostID, err := utils.GetHostID() if err != nil { return errors.New("failed to get the host ID") @@ -137,18 +130,13 @@ func enter(cmd *cobra.Command, args []string) error { emitEscapeSequence = true } - if err := runCommand(container, + return runCommand(container, !nonDefaultContainer, image, release, - command, + nil, emitEscapeSequence, - true, - false); err != nil { - return err - } - - return nil + false) } func enterHelp(cmd *cobra.Command, args []string) { diff --git a/src/cmd/run.go b/src/cmd/run.go index 054465b3f..9b3209c80 100644 --- a/src/cmd/run.go +++ b/src/cmd/run.go @@ -120,25 +120,20 @@ func run(cmd *cobra.Command, args []string) error { return err } - if err := runCommand(container, + return runCommand(container, !nonDefaultContainer, image, release, command, false, - false, - true); err != nil { - return err - } - - return nil + true) } func runCommand(container string, defaultContainer bool, image, release string, command []string, - emitEscapeSequence, fallbackToBash, pedantic bool) error { + emitEscapeSequence, pedantic bool) error { if !pedantic { if image == "" { panic("image not specified") @@ -188,7 +183,7 @@ func runCommand(container string, return nil } - if err := createContainer(container, image, release, false); err != nil { + if err := createContainer(container, image, release, "", false); err != nil { return err } } else if containersCount == 1 && defaultContainer { @@ -258,18 +253,15 @@ func runCommand(container string, logrus.Debugf("Container %s is initialized", container) - if _, err := isCommandPresent(container, command[0]); err != nil { - if fallbackToBash { - fmt.Fprintf(os.Stderr, - "Error: command %s not found in container %s\n", - command[0], - container) - fmt.Fprintf(os.Stderr, "Using /bin/bash instead.\n") + commandLauncher := "export SHELL=\"$(getent passwd \"$(whoami)\" | cut -d : -f 7)\"; " - command = []string{"/bin/bash", "-l"} - } else { + if command != nil { + if _, err := isCommandPresent(container, command[0]); err != nil { return fmt.Errorf("command %s not found in container %s", command[0], container) } + commandLauncher += "exec \"$@\"" + } else { + commandLauncher += "exec -l \"$SHELL\"" } logrus.Debug("Checking if 'podman exec' supports disabling the detach keys") @@ -302,10 +294,14 @@ func runCommand(container string, execArgs = append(execArgs, []string{ container, - "capsh", "--caps=", "--", "-c", "exec \"$@\"", "/bin/sh", + "capsh", "--caps=", "--", "-c", commandLauncher, "toolbox", }...) - execArgs = append(execArgs, command...) + if command != nil { + execArgs = append(execArgs, command...) + } else { + command = []string{"\"$SHELL\""} + } if emitEscapeSequence { fmt.Printf("\033]777;container;push;%s;toolbox;%s\033\\", container, currentUser.Uid) @@ -342,11 +338,7 @@ func runCommand(container string, err = nil } - if err != nil { - return err - } - - return nil + return err } func runHelp(cmd *cobra.Command, args []string) { diff --git a/src/pkg/utils/utils.go b/src/pkg/utils/utils.go index 5e2e8efbe..00c282df4 100644 --- a/src/pkg/utils/utils.go +++ b/src/pkg/utils/utils.go @@ -60,7 +60,6 @@ var ( "DESKTOP_SESSION", "DISPLAY", "LANG", - "SHELL", "SSH_AUTH_SOCK", "TERM", "TOOLBOX_PATH",