github.com/stackdocker/rkt@v0.10.1-0.20151109095037-1aa827478248/common/common.go (about) 1 // Copyright 2014 The rkt Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package common defines values shared by different parts 16 // of rkt (e.g. stage0 and stage1) 17 package common 18 19 import ( 20 "bufio" 21 "fmt" 22 "net" 23 "os" 24 "os/exec" 25 "path/filepath" 26 "strconv" 27 "strings" 28 29 "github.com/coreos/rkt/Godeps/_workspace/src/github.com/appc/spec/aci" 30 "github.com/coreos/rkt/Godeps/_workspace/src/github.com/appc/spec/schema/types" 31 ) 32 33 const ( 34 sharedVolumesDir = "/sharedVolumes" 35 stage1Dir = "/stage1" 36 stage2Dir = "/opt/stage2" 37 AppsInfoDir = "/appsinfo" 38 39 EnvLockFd = "RKT_LOCK_FD" 40 EnvSELinuxContext = "RKT_SELINUX_CONTEXT" 41 Stage1TreeStoreIDFilename = "stage1TreeStoreID" 42 AppTreeStoreIDFilename = "treeStoreID" 43 OverlayPreparedFilename = "overlay-prepared" 44 PrivateUsersPreparedFilename = "private-users-prepared" 45 46 PrepareLock = "prepareLock" 47 48 MetadataServicePort = 18112 49 MetadataServiceRegSock = "/run/rkt/metadata-svc.sock" 50 51 APIServiceListenClientURL = "localhost:15441" 52 53 DefaultLocalConfigDir = "/etc/rkt" 54 DefaultSystemConfigDir = "/usr/lib/rkt" 55 ) 56 57 // Stage1ImagePath returns the path where the stage1 app image (unpacked ACI) is rooted, 58 // (i.e. where its contents are extracted during stage0). 59 func Stage1ImagePath(root string) string { 60 return filepath.Join(root, stage1Dir) 61 } 62 63 // Stage1RootfsPath returns the path to the stage1 rootfs 64 func Stage1RootfsPath(root string) string { 65 return filepath.Join(Stage1ImagePath(root), aci.RootfsDir) 66 } 67 68 // Stage1ManifestPath returns the path to the stage1's manifest file inside the expanded ACI. 69 func Stage1ManifestPath(root string) string { 70 return filepath.Join(Stage1ImagePath(root), aci.ManifestFile) 71 } 72 73 // PodManifestPath returns the path in root to the Pod Manifest 74 func PodManifestPath(root string) string { 75 return filepath.Join(root, "pod") 76 } 77 78 // AppsPath returns the path where the apps within a pod live. 79 func AppsPath(root string) string { 80 return filepath.Join(Stage1RootfsPath(root), stage2Dir) 81 } 82 83 // AppPath returns the path to an app's rootfs. 84 func AppPath(root string, appName types.ACName) string { 85 return filepath.Join(AppsPath(root), appName.String()) 86 } 87 88 // AppRootfsPath returns the path to an app's rootfs. 89 func AppRootfsPath(root string, appName types.ACName) string { 90 return filepath.Join(AppPath(root, appName), aci.RootfsDir) 91 } 92 93 // RelAppPath returns the path of an app relative to the stage1 chroot. 94 func RelAppPath(appName types.ACName) string { 95 return filepath.Join(stage2Dir, appName.String()) 96 } 97 98 // RelAppRootfsPath returns the path of an app's rootfs relative to the stage1 chroot. 99 func RelAppRootfsPath(appName types.ACName) string { 100 return filepath.Join(RelAppPath(appName), aci.RootfsDir) 101 } 102 103 // ImageManifestPath returns the path to the app's manifest file of a pod. 104 func ImageManifestPath(root string, appName types.ACName) string { 105 return filepath.Join(AppPath(root, appName), aci.ManifestFile) 106 } 107 108 // AppsInfoPath returns the path to the appsinfo directory of a pod. 109 func AppsInfoPath(root string) string { 110 return filepath.Join(root, AppsInfoDir) 111 } 112 113 // AppInfoPath returns the path to the app's appsinfo directory of a pod. 114 func AppInfoPath(root string, appName types.ACName) string { 115 return filepath.Join(AppsInfoPath(root), appName.String()) 116 } 117 118 // AppTreeStoreIDPath returns the path to the app's treeStoreID file of a pod. 119 func AppTreeStoreIDPath(root string, appName types.ACName) string { 120 return filepath.Join(AppInfoPath(root, appName), AppTreeStoreIDFilename) 121 } 122 123 // AppImageManifestPath returns the path to the app's ImageManifest file 124 func AppInfoImageManifestPath(root string, appName types.ACName) string { 125 return filepath.Join(AppInfoPath(root, appName), aci.ManifestFile) 126 } 127 128 // SharedVolumesPath returns the path to the shared (empty) volumes of a pod. 129 func SharedVolumesPath(root string) string { 130 return filepath.Join(root, sharedVolumesDir) 131 } 132 133 // MetadataServicePublicURL returns the public URL used to host the metadata service 134 func MetadataServicePublicURL(ip net.IP, token string) string { 135 return fmt.Sprintf("http://%v:%v/%v", ip, MetadataServicePort, token) 136 } 137 138 func GetRktLockFD() (int, error) { 139 if v := os.Getenv(EnvLockFd); v != "" { 140 fd, err := strconv.ParseUint(v, 10, 32) 141 if err != nil { 142 return -1, err 143 } 144 return int(fd), nil 145 } 146 return -1, fmt.Errorf("%v env var is not set", EnvLockFd) 147 } 148 149 // SupportsOverlay returns whether the system supports overlay filesystem 150 func SupportsOverlay() bool { 151 exec.Command("modprobe", "overlay").Run() 152 153 f, err := os.Open("/proc/filesystems") 154 if err != nil { 155 fmt.Println("error opening /proc/filesystems") 156 return false 157 } 158 defer f.Close() 159 160 s := bufio.NewScanner(f) 161 for s.Scan() { 162 if s.Text() == "nodev\toverlay" { 163 return true 164 } 165 } 166 return false 167 } 168 169 // SupportsUserNS returns whether the kernel has CONFIG_USER_NS set 170 func SupportsUserNS() bool { 171 if _, err := os.Stat("/proc/self/uid_map"); err == nil { 172 return true 173 } 174 175 return false 176 } 177 178 // NetList implements the flag.Value interface to allow specification of --net with and without values 179 // Example: --net="all,net1:k1=v1;k2=v2,net2:l1=w1" 180 type NetList struct { 181 mapping map[string]string 182 } 183 184 func (l *NetList) String() string { 185 return strings.Join(l.Strings(), ",") 186 } 187 188 func (l *NetList) Set(value string) error { 189 if l.mapping == nil { 190 l.mapping = make(map[string]string) 191 } 192 for _, s := range strings.Split(value, ",") { 193 netArgsPair := strings.Split(s, ":") 194 netName := netArgsPair[0] 195 196 if netName == "" { 197 return fmt.Errorf("netname must not be empty") 198 } 199 200 if _, duplicate := l.mapping[netName]; duplicate { 201 return fmt.Errorf("found duplicate netname %q", netName) 202 } 203 204 switch { 205 case len(netArgsPair) == 1: 206 l.mapping[netName] = "" 207 case len(netArgsPair) == 2: 208 if netName == "all" || 209 netName == "host" { 210 return fmt.Errorf("arguments are not supported by special netname %q", netName) 211 } 212 l.mapping[netName] = netArgsPair[1] 213 case len(netArgsPair) > 2: 214 return fmt.Errorf("network %q provided with invalid arguments: %v", netName, netArgsPair[1:]) 215 default: 216 return fmt.Errorf("unexpected case when processing network %q", s) 217 } 218 } 219 return nil 220 } 221 222 func (l *NetList) Type() string { 223 return "netList" 224 } 225 226 func (l *NetList) Strings() []string { 227 if len(l.mapping) == 0 { 228 return []string{"default"} 229 } 230 231 var list []string 232 for k, v := range l.mapping { 233 if v == "" { 234 list = append(list, k) 235 } else { 236 list = append(list, fmt.Sprintf("%s:%s", k, v)) 237 } 238 } 239 return list 240 } 241 242 func (l *NetList) StringsOnlyNames() []string { 243 var list []string 244 for k, _ := range l.mapping { 245 list = append(list, k) 246 } 247 return list 248 } 249 250 // Check if host networking has been requested 251 func (l *NetList) Host() bool { 252 return l.Specific("host") 253 } 254 255 // Check if 'none' (loopback only) networking has been requested 256 func (l *NetList) None() bool { 257 return l.Specific("none") 258 } 259 260 // Check if the container needs to be put in a separate network namespace 261 func (l *NetList) Contained() bool { 262 return !l.Host() && len(l.mapping) > 0 263 } 264 265 func (l *NetList) Specific(net string) bool { 266 _, exists := l.mapping[net] 267 return exists 268 } 269 270 func (l *NetList) SpecificArgs(net string) string { 271 return l.mapping[net] 272 } 273 274 func (l *NetList) All() bool { 275 return l.Specific("all") 276 }