Fix tty and io permission for userns
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user