Merge pull request #407 from LK4D4/move_console_to_process

Move tty configuration to Process
This commit is contained in:
Mrunal Patel 2015-02-25 15:08:47 -08:00
commit b19b8a9677
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 optionally sets the container's hostname if provided
Hostname string `json:"hostname"` 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 // 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 // If a namespace is not provided that namespace is shared from the container's parent process
Namespaces Namespaces `json:"namespaces"` Namespaces Namespaces `json:"namespaces"`

View File

@ -12,9 +12,9 @@ import (
"github.com/docker/libcontainer/label" "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. // 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) master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -186,6 +186,7 @@ func (c *linuxContainer) newInitConfig(process *Process) *initConfig {
Env: process.Env, Env: process.Env,
User: process.User, User: process.User,
Cwd: process.Cwd, Cwd: process.Cwd,
Console: process.consolePath,
} }
} }

View File

@ -45,6 +45,7 @@ type initConfig struct {
Cwd string `json:"cwd"` Cwd string `json:"cwd"`
User string `json:"user"` User string `json:"user"`
Config *configs.Config `json:"config"` Config *configs.Config `json:"config"`
Console string `json:"console"`
Networks []*network `json:"network"` Networks []*network `json:"network"`
} }

View File

@ -41,23 +41,11 @@ func execAction(context *cli.Context) {
if err != nil { if err != nil {
fatal(err) fatal(err)
} }
rootuid, err := config.HostUID()
if err != nil {
fatal(err)
}
tty, err := newTty(context, rootuid)
if err != nil {
fatal(err)
}
created := false created := false
container, err := factory.Load(context.String("id")) container, err := factory.Load(context.String("id"))
if err != nil { if err != nil {
if tty.console != nil {
config.Console = tty.console.Path()
}
created = true created = true
if container, err = factory.Create(context.String("id"), config); err != nil { if container, err = factory.Create(context.String("id"), config); err != nil {
tty.Close()
fatal(err) fatal(err)
} }
} }
@ -70,6 +58,14 @@ func execAction(context *cli.Context) {
Stdout: os.Stdout, Stdout: os.Stdout,
Stderr: os.Stderr, 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 { if err := tty.attach(process); err != nil {
fatal(err) fatal(err)
} }

View File

@ -9,9 +9,9 @@ import (
"github.com/docker/libcontainer" "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") { if context.Bool("tty") {
console, err := libcontainer.NewConsole(rootuid, rootuid) console, err := p.NewConsole(rootuid)
if err != nil { if err != nil {
return nil, err 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 is a pointer to a writer which receives the standard error stream.
Stderr io.Writer Stderr io.Writer
// consolePath is the path to the console allocated to the container.
consolePath string
ops processOperations ops processOperations
} }
@ -63,3 +66,13 @@ func (p Process) Signal(sig os.Signal) error {
} }
return p.ops.signal(sig) 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 // setupRootfs sets up the devices, mount points, and filesystems for use inside a
// new mount namespace. // 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 { if err := prepareRoot(config); err != nil {
return newSystemError(err) return newSystemError(err)
} }
@ -53,7 +53,7 @@ func setupRootfs(config *configs.Config) (err error) {
if err := createDevices(config); err != nil { if err := createDevices(config); err != nil {
return newSystemError(err) return newSystemError(err)
} }
if err := setupPtmx(config); err != nil { if err := setupPtmx(config, console); err != nil {
return newSystemError(err) return newSystemError(err)
} }
// stdin, stdout and stderr could be pointing to /dev/null from parent namespace. // 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, "") 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") ptmx := filepath.Join(config.Rootfs, "dev/ptmx")
if err := os.Remove(ptmx); err != nil && !os.IsNotExist(err) { if err := os.Remove(ptmx); err != nil && !os.IsNotExist(err) {
return err return err
@ -263,8 +263,7 @@ func setupPtmx(config *configs.Config) error {
if err := os.Symlink("pts/ptmx", ptmx); err != nil { if err := os.Symlink("pts/ptmx", ptmx); err != nil {
return fmt.Errorf("symlink dev ptmx %s", err) return fmt.Errorf("symlink dev ptmx %s", err)
} }
if config.Console != "" { if console != nil {
console := newConsoleFromPath(config.Console)
return console.mount(config.Rootfs, config.MountLabel, 0, 0) return console.mount(config.Rootfs, config.MountLabel, 0, 0)
} }
return nil return nil

View File

@ -20,9 +20,9 @@ func (l *linuxStandardInit) Init() error {
if err := joinExistingNamespaces(l.config.Config.Namespaces); err != nil { if err := joinExistingNamespaces(l.config.Config.Namespaces); err != nil {
return err return err
} }
consolePath := l.config.Config.Console var console *linuxConsole
if consolePath != "" { if l.config.Console != "" {
console := newConsoleFromPath(consolePath) console = newConsoleFromPath(l.config.Console)
if err := console.dupStdio(); err != nil { if err := console.dupStdio(); err != nil {
return err return err
} }
@ -30,7 +30,7 @@ func (l *linuxStandardInit) Init() error {
if _, err := syscall.Setsid(); err != nil { if _, err := syscall.Setsid(); err != nil {
return err return err
} }
if consolePath != "" { if console != nil {
if err := system.Setctty(); err != nil { if err := system.Setctty(); err != nil {
return err return err
} }
@ -47,7 +47,7 @@ func (l *linuxStandardInit) Init() error {
label.Init() label.Init()
// InitializeMountNamespace() can be executed only for a new mount namespace // InitializeMountNamespace() can be executed only for a new mount namespace
if l.config.Config.Namespaces.Contains(configs.NEWNS) { 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 return err
} }
} }