@@ -2,8 +2,10 @@ package main
22
33import (
44"fmt"
5+ "io/ioutil"
56"os"
67"path/filepath"
8+ "regexp"
79"strings"
810
911"github.com/hyperhq/runv/hypervisor"
@@ -95,20 +97,11 @@ func cmdCreateContainer(context *cli.Context, attach bool) error {
9597} else {
9698for _ , ns := range spec .Linux .Namespaces {
9799if ns .Path != "" {
98- if strings .Contains (ns .Path , "/" ) {
99- return fmt .Errorf ("Runv doesn't support path to namespace file, it supports containers name as shared namespaces only" )
100- }
101100if ns .Type == "mount" {
102101return fmt .Errorf ("Runv doesn't support containers with shared mount namespace, use `runv exec` instead" )
103102}
104- sharedContainer = ns .Path
105- _ , err = os .Stat (filepath .Join (root , sharedContainer , stateJSON ))
106- if err != nil {
107- return fmt .Errorf ("The container %q is not existing or not ready" , sharedContainer )
108- }
109- _ , err = os .Stat (filepath .Join (root , sharedContainer , "namespace" ))
110- if err != nil {
111- return fmt .Errorf ("The container %q is not ready" , sharedContainer )
103+ if sharedContainer , err = findSharedContainer (context .GlobalString ("root" ), ns .Path ); err != nil {
104+ return fmt .Errorf ("failed to find shared container: %v" , err )
112105}
113106}
114107}
@@ -159,3 +152,34 @@ func checkConsole(context *cli.Context, p *specs.Process, attach bool) error {
159152}
160153return nil
161154}
155+
156+ func findSharedContainer (root , nsPath string ) (container string , err error ) {
157+ absRoot , err := filepath .Abs (root )
158+ if err != nil {
159+ return "" , err
160+ }
161+ list , err := ioutil .ReadDir (absRoot )
162+ if err != nil {
163+ return "" , err
164+ }
165+
166+ if strings .Contains (nsPath , "/" ) {
167+ pidexp := regexp .MustCompile (`/proc/(\d+)/ns/*` )
168+ matches := pidexp .FindStringSubmatch (nsPath )
169+ if len (matches ) != 2 {
170+ return "" , fmt .Errorf ("malformed ns path: %s" , nsPath )
171+ }
172+ pid := matches [1 ]
173+
174+ for _ , item := range list {
175+ if state , err := loadStateFile (absRoot , item .Name ()); err == nil {
176+ spid := fmt .Sprintf ("%d" , state .Pid )
177+ if spid == pid {
178+ return item .Name (), nil
179+ }
180+ }
181+ }
182+ return "" , fmt .Errorf ("can't find container with shim pid %s" , pid )
183+ }
184+ return nsPath , nil
185+ }
0 commit comments