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:
Alexander Morozov 2015-02-25 14:31:39 -08:00
parent f6593810da
commit 8d0b06257b
9 changed files with 41 additions and 34 deletions

View File

@ -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"`

View File

@ -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

View File

@ -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,
}
}

View File

@ -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"`
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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
}
}