1package configs 2 3import ( 4 "fmt" 5 "os" 6 "sync" 7) 8 9const ( 10 NEWNET NamespaceType = "NEWNET" 11 NEWPID NamespaceType = "NEWPID" 12 NEWNS NamespaceType = "NEWNS" 13 NEWUTS NamespaceType = "NEWUTS" 14 NEWIPC NamespaceType = "NEWIPC" 15 NEWUSER NamespaceType = "NEWUSER" 16 NEWCGROUP NamespaceType = "NEWCGROUP" 17) 18 19var ( 20 nsLock sync.Mutex 21 supportedNamespaces = make(map[NamespaceType]bool) 22) 23 24// NsName converts the namespace type to its filename 25func NsName(ns NamespaceType) string { 26 switch ns { 27 case NEWNET: 28 return "net" 29 case NEWNS: 30 return "mnt" 31 case NEWPID: 32 return "pid" 33 case NEWIPC: 34 return "ipc" 35 case NEWUSER: 36 return "user" 37 case NEWUTS: 38 return "uts" 39 case NEWCGROUP: 40 return "cgroup" 41 } 42 return "" 43} 44 45// IsNamespaceSupported returns whether a namespace is available or 46// not 47func IsNamespaceSupported(ns NamespaceType) bool { 48 nsLock.Lock() 49 defer nsLock.Unlock() 50 supported, ok := supportedNamespaces[ns] 51 if ok { 52 return supported 53 } 54 nsFile := NsName(ns) 55 // if the namespace type is unknown, just return false 56 if nsFile == "" { 57 return false 58 } 59 _, err := os.Stat(fmt.Sprintf("/proc/self/ns/%s", nsFile)) 60 // a namespace is supported if it exists and we have permissions to read it 61 supported = err == nil 62 supportedNamespaces[ns] = supported 63 return supported 64} 65 66func NamespaceTypes() []NamespaceType { 67 return []NamespaceType{ 68 NEWUSER, // Keep user NS always first, don't move it. 69 NEWIPC, 70 NEWUTS, 71 NEWNET, 72 NEWPID, 73 NEWNS, 74 NEWCGROUP, 75 } 76} 77 78// Namespace defines configuration for each namespace. It specifies an 79// alternate path that is able to be joined via setns. 80type Namespace struct { 81 Type NamespaceType `json:"type"` 82 Path string `json:"path"` 83} 84 85func (n *Namespace) GetPath(pid int) string { 86 return fmt.Sprintf("/proc/%d/ns/%s", pid, NsName(n.Type)) 87} 88 89func (n *Namespaces) Remove(t NamespaceType) bool { 90 i := n.index(t) 91 if i == -1 { 92 return false 93 } 94 *n = append((*n)[:i], (*n)[i+1:]...) 95 return true 96} 97 98func (n *Namespaces) Add(t NamespaceType, path string) { 99 i := n.index(t) 100 if i == -1 { 101 *n = append(*n, Namespace{Type: t, Path: path}) 102 return 103 } 104 (*n)[i].Path = path 105} 106 107func (n *Namespaces) index(t NamespaceType) int { 108 for i, ns := range *n { 109 if ns.Type == t { 110 return i 111 } 112 } 113 return -1 114} 115 116func (n *Namespaces) Contains(t NamespaceType) bool { 117 return n.index(t) != -1 118} 119 120func (n *Namespaces) PathOf(t NamespaceType) string { 121 i := n.index(t) 122 if i == -1 { 123 return "" 124 } 125 return (*n)[i].Path 126} 127