diff --git a/exec.go b/exec.go index afb4c6d9..38a4153d 100644 --- a/exec.go +++ b/exec.go @@ -15,6 +15,13 @@ import ( var execCommand = cli.Command{ Name: "exec", Usage: "execute new process inside the container", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "console", + Value: "", + Usage: "specify the pty slave path for use with the container", + }, + }, Action: func(context *cli.Context) { config, err := loadProcessConfig(context.Args().First()) if err != nil { @@ -45,7 +52,7 @@ func execProcess(context *cli.Context, config *specs.Process) (int, error) { if err != nil { return -1, err } - tty, err := newTty(config.Terminal, process, rootuid) + tty, err := newTty(config.Terminal, process, rootuid, context.String("console")) if err != nil { return -1, err } diff --git a/restore.go b/restore.go index db1a0fd1..55cff56a 100644 --- a/restore.go +++ b/restore.go @@ -114,7 +114,7 @@ func restoreContainer(context *cli.Context, spec *specs.LinuxSpec, config *confi Stdout: os.Stdout, Stderr: os.Stderr, } - tty, err := newTty(spec.Process.Terminal, process, rootuid) + tty, err := newTty(spec.Process.Terminal, process, rootuid, "") if err != nil { return -1, err } diff --git a/start.go b/start.go index 802b3bf3..6c34bee1 100644 --- a/start.go +++ b/start.go @@ -26,6 +26,11 @@ var startCommand = cli.Command{ Value: "", Usage: "path to the root of the bundle directory", }, + cli.StringFlag{ + Name: "console", + Value: "", + Usage: "specify the pty slave path for use with the container", + }, }, Action: func(context *cli.Context) { bundle := context.String("bundle") @@ -44,9 +49,10 @@ var startCommand = cli.Command{ setupSdNotify(spec, rspec, notifySocket) } - listenFds := os.Getenv("LISTEN_FDS") - listenPid := os.Getenv("LISTEN_PID") - + var ( + listenFds = os.Getenv("LISTEN_FDS") + listenPid = os.Getenv("LISTEN_PID") + ) if listenFds != "" && listenPid == strconv.Itoa(os.Getpid()) { setupSocketActivation(spec, listenFds) } @@ -114,7 +120,7 @@ func startContainer(context *cli.Context, spec *specs.LinuxSpec, rspec *specs.Li process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), "")) } } - tty, err := newTty(spec.Process.Terminal, process, rootuid) + tty, err := newTty(spec.Process.Terminal, process, rootuid, context.String("console")) if err != nil { return -1, err } diff --git a/tty.go b/tty.go index ca6d8c0d..77d275af 100644 --- a/tty.go +++ b/tty.go @@ -14,9 +14,9 @@ import ( // newTty creates a new tty for use with the container. If a tty is not to be // created for the process, pipes are created so that the TTY of the parent // process are not inherited by the container. -func newTty(create bool, p *libcontainer.Process, rootuid int) (*tty, error) { +func newTty(create bool, p *libcontainer.Process, rootuid int, console string) (*tty, error) { if create { - return createTty(p, rootuid) + return createTty(p, rootuid, console) } return createStdioPipes(p, rootuid) } @@ -41,13 +41,20 @@ func createStdioPipes(p *libcontainer.Process, rootuid int) (*tty, error) { return t, nil } -func createTty(p *libcontainer.Process, rootuid int) (*tty, error) { +func createTty(p *libcontainer.Process, rootuid int, consolePath string) (*tty, error) { + if consolePath != "" { + if err := p.ConsoleFromPath(consolePath); err != nil { + return nil, err + } + return &tty{}, nil + } console, err := p.NewConsole(rootuid) if err != nil { return nil, err } go io.Copy(console, os.Stdin) go io.Copy(os.Stdout, console) + state, err := term.SetRawTerminal(os.Stdin.Fd()) if err != nil { return nil, fmt.Errorf("failed to set the terminal from the stdin: %v", err)