// orderNamespacePaths sorts namespace paths into a list of paths that we // can setns in order. func (c *linuxContainer) orderNamespacePaths(namespaces map[configs.NamespaceType]string) ([]string, error) { paths := []string{} nsTypes := []configs.NamespaceType{ configs.NEWIPC, configs.NEWUTS, configs.NEWNET, configs.NEWPID, configs.NEWNS, } // join userns if the init process explicitly requires NEWUSER if c.config.Namespaces.Contains(configs.NEWUSER) { nsTypes = append(nsTypes, configs.NEWUSER) } for _, nsType := range nsTypes { if p, ok := namespaces[nsType]; ok && p != "" { // check if the requested namespace is supported if !configs.IsNamespaceSupported(nsType) { return nil, newSystemError(fmt.Errorf("namespace %s is not supported", nsType)) } // only set to join this namespace if it exists if _, err := os.Lstat(p); err != nil { return nil, newSystemErrorWithCausef(err, "running lstat on namespace path %q", p) } // do not allow namespace path with comma as we use it to separate // the namespace paths if strings.ContainsRune(p, ',') { return nil, newSystemError(fmt.Errorf("invalid path %s", p)) } paths = append(paths, p) } } return paths, nil }
func (c *linuxContainer) currentState() (*State, error) { var ( startTime string externalDescriptors []string pid = -1 ) if c.initProcess != nil { pid = c.initProcess.pid() startTime, _ = c.initProcess.startTime() externalDescriptors = c.initProcess.externalDescriptors() } state := &State{ BaseState: BaseState{ ID: c.ID(), Config: *c.config, InitProcessPid: pid, InitProcessStartTime: startTime, Created: c.created, }, CgroupPaths: c.cgroupManager.GetPaths(), NamespacePaths: make(map[configs.NamespaceType]string), ExternalDescriptors: externalDescriptors, } if pid > 0 { for _, ns := range c.config.Namespaces { state.NamespacePaths[ns.Type] = ns.GetPath(pid) } for _, nsType := range configs.NamespaceTypes() { if !configs.IsNamespaceSupported(nsType) { continue } if _, ok := state.NamespacePaths[nsType]; !ok { ns := configs.Namespace{Type: nsType} state.NamespacePaths[ns.Type] = ns.GetPath(pid) } } } return state, nil }
// orderNamespacePaths sorts namespace paths into a list of paths that we // can setns in order. func (c *linuxContainer) orderNamespacePaths(namespaces map[configs.NamespaceType]string) ([]string, error) { paths := []string{} order := []configs.NamespaceType{ // The user namespace *must* be done first. configs.NEWUSER, configs.NEWIPC, configs.NEWUTS, configs.NEWNET, configs.NEWPID, configs.NEWNS, } // Remove namespaces that we don't need to join. var nsTypes []configs.NamespaceType for _, ns := range order { if c.config.Namespaces.Contains(ns) { nsTypes = append(nsTypes, ns) } } for _, nsType := range nsTypes { if p, ok := namespaces[nsType]; ok && p != "" { // check if the requested namespace is supported if !configs.IsNamespaceSupported(nsType) { return nil, newSystemError(fmt.Errorf("namespace %s is not supported", nsType)) } // only set to join this namespace if it exists if _, err := os.Lstat(p); err != nil { return nil, newSystemErrorWithCausef(err, "running lstat on namespace path %q", p) } // do not allow namespace path with comma as we use it to separate // the namespace paths if strings.ContainsRune(p, ',') { return nil, newSystemError(fmt.Errorf("invalid path %s", p)) } paths = append(paths, fmt.Sprintf("%s:%s", configs.NsName(nsType), p)) } } return paths, nil }