Beispiel #1
0
// 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
}
Beispiel #2
0
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
}
Beispiel #3
0
// 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
}