From 44ec27e5c40910473c128926c76ee081e48312b4 Mon Sep 17 00:00:00 2001 From: ZhaoXuqiang Date: Sat, 26 Aug 2017 10:11:25 +0800 Subject: [PATCH] Enable pod support share a pod with existing container, with `--net container:xxx` get shared container by compare pid with exist running container's Pid which found from container's state file Signed-off-by: Zhang Wei Signed-off-by: ZhaoXuqiang --- cli/create.go | 46 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/cli/create.go b/cli/create.go index dcdd69cf..1ded609f 100644 --- a/cli/create.go +++ b/cli/create.go @@ -2,8 +2,10 @@ package main import ( "fmt" + "io/ioutil" "os" "path/filepath" + "regexp" "strings" "github.com/hyperhq/runv/hypervisor" @@ -95,20 +97,11 @@ func cmdCreateContainer(context *cli.Context, attach bool) error { } else { for _, ns := range spec.Linux.Namespaces { if ns.Path != "" { - if strings.Contains(ns.Path, "/") { - return fmt.Errorf("Runv doesn't support path to namespace file, it supports containers name as shared namespaces only") - } if ns.Type == "mount" { return fmt.Errorf("Runv doesn't support containers with shared mount namespace, use `runv exec` instead") } - sharedContainer = ns.Path - _, err = os.Stat(filepath.Join(root, sharedContainer, stateJSON)) - if err != nil { - return fmt.Errorf("The container %q is not existing or not ready", sharedContainer) - } - _, err = os.Stat(filepath.Join(root, sharedContainer, "namespace")) - if err != nil { - return fmt.Errorf("The container %q is not ready", sharedContainer) + if sharedContainer, err = findSharedContainer(context.GlobalString("root"), ns.Path); err != nil { + return fmt.Errorf("failed to find shared container: %v", err) } } } @@ -159,3 +152,34 @@ func checkConsole(context *cli.Context, p *specs.Process, attach bool) error { } return nil } + +func findSharedContainer(root, nsPath string) (container string, err error) { + absRoot, err := filepath.Abs(root) + if err != nil { + return "", err + } + list, err := ioutil.ReadDir(absRoot) + if err != nil { + return "", err + } + + if strings.Contains(nsPath, "/") { + pidexp := regexp.MustCompile(`/proc/(\d+)/ns/*`) + matches := pidexp.FindStringSubmatch(nsPath) + if len(matches) != 2 { + return "", fmt.Errorf("malformed ns path: %s", nsPath) + } + pid := matches[1] + + for _, item := range list { + if state, err := loadStateFile(absRoot, item.Name()); err == nil { + spid := fmt.Sprintf("%d", state.Pid) + if spid == pid { + return item.Name(), nil + } + } + } + return "", fmt.Errorf("can't find container with shim pid %s", pid) + } + return nsPath, nil +}