Move tty configuration to Process
Now you need to call Process.NewConsole to setup console for process Signed-off-by: Alexander Morozov <lk4d4@docker.com>
This commit is contained in:
parent
f6593810da
commit
8d0b06257b
|
@ -49,9 +49,6 @@ type Config struct {
|
|||
// Hostname optionally sets the container's hostname if provided
|
||||
Hostname string `json:"hostname"`
|
||||
|
||||
// Console is the path to the console allocated to the container.
|
||||
Console string `json:"console"`
|
||||
|
||||
// Namespaces specifies the container's namespaces that it should setup when cloning the init process
|
||||
// If a namespace is not provided that namespace is shared from the container's parent process
|
||||
Namespaces Namespaces `json:"namespaces"`
|
||||
|
|
|
@ -12,9 +12,9 @@ import (
|
|||
"github.com/docker/libcontainer/label"
|
||||
)
|
||||
|
||||
// NewConsole returns an initalized console that can be used within a container by copying bytes
|
||||
// newConsole returns an initalized console that can be used within a container by copying bytes
|
||||
// from the master side to the slave that is attached as the tty for the container's init process.
|
||||
func NewConsole(uid, gid int) (Console, error) {
|
||||
func newConsole(uid, gid int) (Console, error) {
|
||||
master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -181,11 +181,12 @@ func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, parentPipe,
|
|||
|
||||
func (c *linuxContainer) newInitConfig(process *Process) *initConfig {
|
||||
return &initConfig{
|
||||
Config: c.config,
|
||||
Args: process.Args,
|
||||
Env: process.Env,
|
||||
User: process.User,
|
||||
Cwd: process.Cwd,
|
||||
Config: c.config,
|
||||
Args: process.Args,
|
||||
Env: process.Env,
|
||||
User: process.User,
|
||||
Cwd: process.Cwd,
|
||||
Console: process.consolePath,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ type initConfig struct {
|
|||
Cwd string `json:"cwd"`
|
||||
User string `json:"user"`
|
||||
Config *configs.Config `json:"config"`
|
||||
Console string `json:"console"`
|
||||
Networks []*network `json:"network"`
|
||||
}
|
||||
|
||||
|
|
|
@ -41,23 +41,11 @@ func execAction(context *cli.Context) {
|
|||
if err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
rootuid, err := config.HostUID()
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
tty, err := newTty(context, rootuid)
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
created := false
|
||||
container, err := factory.Load(context.String("id"))
|
||||
if err != nil {
|
||||
if tty.console != nil {
|
||||
config.Console = tty.console.Path()
|
||||
}
|
||||
created = true
|
||||
if container, err = factory.Create(context.String("id"), config); err != nil {
|
||||
tty.Close()
|
||||
fatal(err)
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +58,14 @@ func execAction(context *cli.Context) {
|
|||
Stdout: os.Stdout,
|
||||
Stderr: os.Stderr,
|
||||
}
|
||||
rootuid, err := config.HostUID()
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
tty, err := newTty(context, process, rootuid)
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
if err := tty.attach(process); err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@ import (
|
|||
"github.com/docker/libcontainer"
|
||||
)
|
||||
|
||||
func newTty(context *cli.Context, rootuid int) (*tty, error) {
|
||||
func newTty(context *cli.Context, p *libcontainer.Process, rootuid int) (*tty, error) {
|
||||
if context.Bool("tty") {
|
||||
console, err := libcontainer.NewConsole(rootuid, rootuid)
|
||||
console, err := p.NewConsole(rootuid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
13
process.go
13
process.go
|
@ -36,6 +36,9 @@ type Process struct {
|
|||
// Stderr is a pointer to a writer which receives the standard error stream.
|
||||
Stderr io.Writer
|
||||
|
||||
// consolePath is the path to the console allocated to the container.
|
||||
consolePath string
|
||||
|
||||
ops processOperations
|
||||
}
|
||||
|
||||
|
@ -63,3 +66,13 @@ func (p Process) Signal(sig os.Signal) error {
|
|||
}
|
||||
return p.ops.signal(sig)
|
||||
}
|
||||
|
||||
// NewConsole creates new console for process and returns it
|
||||
func (p *Process) NewConsole(rootuid int) (Console, error) {
|
||||
console, err := newConsole(rootuid, rootuid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.consolePath = console.Path()
|
||||
return console, nil
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ var baseMounts = []*configs.Mount{
|
|||
|
||||
// setupRootfs sets up the devices, mount points, and filesystems for use inside a
|
||||
// new mount namespace.
|
||||
func setupRootfs(config *configs.Config) (err error) {
|
||||
func setupRootfs(config *configs.Config, console *linuxConsole) (err error) {
|
||||
if err := prepareRoot(config); err != nil {
|
||||
return newSystemError(err)
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ func setupRootfs(config *configs.Config) (err error) {
|
|||
if err := createDevices(config); err != nil {
|
||||
return newSystemError(err)
|
||||
}
|
||||
if err := setupPtmx(config); err != nil {
|
||||
if err := setupPtmx(config, console); err != nil {
|
||||
return newSystemError(err)
|
||||
}
|
||||
// stdin, stdout and stderr could be pointing to /dev/null from parent namespace.
|
||||
|
@ -255,7 +255,7 @@ func setReadonly() error {
|
|||
return syscall.Mount("/", "/", "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, "")
|
||||
}
|
||||
|
||||
func setupPtmx(config *configs.Config) error {
|
||||
func setupPtmx(config *configs.Config, console *linuxConsole) error {
|
||||
ptmx := filepath.Join(config.Rootfs, "dev/ptmx")
|
||||
if err := os.Remove(ptmx); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
|
@ -263,8 +263,7 @@ func setupPtmx(config *configs.Config) error {
|
|||
if err := os.Symlink("pts/ptmx", ptmx); err != nil {
|
||||
return fmt.Errorf("symlink dev ptmx %s", err)
|
||||
}
|
||||
if config.Console != "" {
|
||||
console := newConsoleFromPath(config.Console)
|
||||
if console != nil {
|
||||
return console.mount(config.Rootfs, config.MountLabel, 0, 0)
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -20,9 +20,9 @@ func (l *linuxStandardInit) Init() error {
|
|||
if err := joinExistingNamespaces(l.config.Config.Namespaces); err != nil {
|
||||
return err
|
||||
}
|
||||
consolePath := l.config.Config.Console
|
||||
if consolePath != "" {
|
||||
console := newConsoleFromPath(consolePath)
|
||||
var console *linuxConsole
|
||||
if l.config.Console != "" {
|
||||
console = newConsoleFromPath(l.config.Console)
|
||||
if err := console.dupStdio(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ func (l *linuxStandardInit) Init() error {
|
|||
if _, err := syscall.Setsid(); err != nil {
|
||||
return err
|
||||
}
|
||||
if consolePath != "" {
|
||||
if console != nil {
|
||||
if err := system.Setctty(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ func (l *linuxStandardInit) Init() error {
|
|||
label.Init()
|
||||
// InitializeMountNamespace() can be executed only for a new mount namespace
|
||||
if l.config.Config.Namespaces.Contains(configs.NEWNS) {
|
||||
if err := setupRootfs(l.config.Config); err != nil {
|
||||
if err := setupRootfs(l.config.Config, console); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue