Fix tty and io permission for userns

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby
2016-02-11 11:23:35 -08:00
parent 20a39bce97
commit cf28969328
22 changed files with 1427 additions and 1124 deletions

View File

@@ -161,7 +161,15 @@ func (c *container) Start(checkpoint string, s Stdio) (Process, error) {
if err != nil {
return nil, err
}
p, err := newProcess(processRoot, InitProcessID, c, spec.Process, s)
config := &processConfig{
root: processRoot,
id: InitProcessID,
c: c,
stdio: s,
spec: spec,
processSpec: spec.Process,
}
p, err := newProcess(config)
if err != nil {
return nil, err
}
@@ -188,7 +196,14 @@ func (c *container) Exec(pid string, spec specs.Process, s Stdio) (Process, erro
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}
p, err := newProcess(processRoot, pid, c, spec, s)
config := &processConfig{
id: pid,
root: processRoot,
c: c,
processSpec: spec,
stdio: s,
}
p, err := newProcess(config)
if err != nil {
return nil, err
}
@@ -312,3 +327,31 @@ func (c *container) Checkpoint(cpt Checkpoint) error {
func (c *container) DeleteCheckpoint(name string) error {
return os.RemoveAll(filepath.Join(c.bundle, "checkpoints", name))
}
func getRootIDs(s *specs.LinuxSpec) (int, int, error) {
if s == nil {
return 0, 0, nil
}
var hasUserns bool
for _, ns := range s.Linux.Namespaces {
if ns.Type == specs.UserNamespace {
hasUserns = true
break
}
}
if !hasUserns {
return 0, 0, nil
}
uid := hostIDFromMap(0, s.Linux.UIDMappings)
gid := hostIDFromMap(0, s.Linux.GIDMappings)
return uid, gid, nil
}
func hostIDFromMap(id uint32, mp []specs.IDMapping) int {
for _, m := range mp {
if (id >= m.ContainerID) && (id <= (m.ContainerID + m.Size - 1)) {
return int(m.HostID + (id - m.ContainerID))
}
}
return 0
}

View File

@@ -40,32 +40,47 @@ type Process interface {
SystemPid() int
}
func newProcess(root, id string, c *container, s specs.Process, stdio Stdio) (*process, error) {
type processConfig struct {
id string
root string
processSpec specs.Process
spec *specs.LinuxSpec
c *container
stdio Stdio
}
func newProcess(config *processConfig) (*process, error) {
p := &process{
root: root,
id: id,
container: c,
spec: s,
stdio: stdio,
root: config.root,
id: config.id,
container: config.c,
spec: config.processSpec,
stdio: config.stdio,
}
f, err := os.Create(filepath.Join(root, "process.json"))
uid, gid, err := getRootIDs(config.spec)
if err != nil {
return nil, err
}
f, err := os.Create(filepath.Join(config.root, "process.json"))
if err != nil {
return nil, err
}
defer f.Close()
if err := json.NewEncoder(f).Encode(ProcessState{
Process: s,
Stdin: stdio.Stdin,
Stdout: stdio.Stdout,
Stderr: stdio.Stderr,
Process: config.processSpec,
RootUID: uid,
RootGID: gid,
Stdin: config.stdio.Stdin,
Stdout: config.stdio.Stdout,
Stderr: config.stdio.Stderr,
}); err != nil {
return nil, err
}
exit, err := getExitPipe(filepath.Join(root, ExitFile))
exit, err := getExitPipe(filepath.Join(config.root, ExitFile))
if err != nil {
return nil, err
}
control, err := getControlPipe(filepath.Join(root, ControlFile))
control, err := getControlPipe(filepath.Join(config.root, ControlFile))
if err != nil {
return nil, err
}

View File

@@ -44,9 +44,11 @@ type state struct {
type ProcessState struct {
specs.Process
Stdin string `json:"containerdStdin"`
Stdout string `json:"containerdStdout"`
Stderr string `json:"containerdStderr"`
RootUID int `json:"rootUID"`
RootGID int `json:"rootGID"`
Stdin string `json:"containerdStdin"`
Stdout string `json:"containerdStdout"`
Stderr string `json:"containerdStderr"`
}
type Stat struct {