github.com/ranjib/nomad@v0.1.1-0.20160225204057-97751b02f70b/client/driver/env/env.go (about) 1 package env 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 hargs "github.com/hashicorp/nomad/helper/args" 9 "github.com/hashicorp/nomad/nomad/structs" 10 ) 11 12 // A set of environment variables that are exported by each driver. 13 const ( 14 // The path to the alloc directory that is shared across tasks within a task 15 // group. 16 AllocDir = "NOMAD_ALLOC_DIR" 17 18 // The path to the tasks local directory where it can store data that is 19 // persisted to the alloc is removed. 20 TaskLocalDir = "NOMAD_TASK_DIR" 21 22 // The tasks memory limit in MBs. 23 MemLimit = "NOMAD_MEMORY_LIMIT" 24 25 // The tasks limit in MHz. 26 CpuLimit = "NOMAD_CPU_LIMIT" 27 28 // Prefix for passing both dynamic and static port allocations to 29 // tasks. 30 // E.g. $NOMAD_IP_1=127.0.0.1:1 or $NOMAD_IP_http=127.0.0.1:80 31 AddrPrefix = "NOMAD_ADDR_" 32 33 // Prefix for passing the host port when a portmap is specified. 34 HostPortPrefix = "NOMAD_HOST_PORT_" 35 36 // Prefix for passing task meta data. 37 MetaPrefix = "NOMAD_META_" 38 ) 39 40 // The node values that can be interpreted. 41 const ( 42 nodeIdKey = "node.unique.id" 43 nodeDcKey = "node.datacenter" 44 nodeNameKey = "node.unique.name" 45 nodeClassKey = "node.class" 46 47 // Prefixes used for lookups. 48 nodeAttributePrefix = "attr." 49 nodeMetaPrefix = "meta." 50 ) 51 52 // TaskEnvironment is used to expose information to a task via environment 53 // variables and provide interpolation of Nomad variables. 54 type TaskEnvironment struct { 55 Env map[string]string 56 Meta map[string]string 57 AllocDir string 58 TaskDir string 59 CpuLimit int 60 MemLimit int 61 Node *structs.Node 62 Networks []*structs.NetworkResource 63 PortMap map[string]int 64 65 // taskEnv is the variables that will be set in the tasks environment 66 TaskEnv map[string]string 67 68 // nodeValues is the values that are allowed for interprolation from the 69 // node. 70 NodeValues map[string]string 71 } 72 73 func NewTaskEnvironment(node *structs.Node) *TaskEnvironment { 74 return &TaskEnvironment{Node: node} 75 } 76 77 // ParseAndReplace takes the user supplied args replaces any instance of an 78 // environment variable or nomad variable in the args with the actual value. 79 func (t *TaskEnvironment) ParseAndReplace(args []string) []string { 80 replaced := make([]string, len(args)) 81 for i, arg := range args { 82 replaced[i] = hargs.ReplaceEnv(arg, t.TaskEnv, t.NodeValues) 83 } 84 85 return replaced 86 } 87 88 // ReplaceEnv takes an arg and replaces all occurences of environment variables 89 // and nomad variables. If the variable is found in the passed map it is 90 // replaced, otherwise the original string is returned. 91 func (t *TaskEnvironment) ReplaceEnv(arg string) string { 92 return hargs.ReplaceEnv(arg, t.TaskEnv, t.NodeValues) 93 } 94 95 // Build must be called after all the tasks environment values have been set. 96 func (t *TaskEnvironment) Build() *TaskEnvironment { 97 t.NodeValues = make(map[string]string) 98 t.TaskEnv = make(map[string]string) 99 100 // Build the task metadata 101 for k, v := range t.Meta { 102 t.TaskEnv[fmt.Sprintf("%s%s", MetaPrefix, strings.ToUpper(k))] = v 103 } 104 105 // Build the ports 106 for _, network := range t.Networks { 107 for label, value := range network.MapLabelToValues(t.PortMap) { 108 IPPort := fmt.Sprintf("%s:%d", network.IP, value) 109 t.TaskEnv[fmt.Sprintf("%s%s", AddrPrefix, label)] = IPPort 110 111 // Pass an explicit port mapping to the environment 112 if port, ok := t.PortMap[label]; ok { 113 t.TaskEnv[fmt.Sprintf("%s%s", HostPortPrefix, label)] = strconv.Itoa(port) 114 } 115 } 116 } 117 118 // Build the directories 119 if t.AllocDir != "" { 120 t.TaskEnv[AllocDir] = t.AllocDir 121 } 122 if t.TaskDir != "" { 123 t.TaskEnv[TaskLocalDir] = t.TaskDir 124 } 125 126 // Build the resource limits 127 if t.MemLimit != 0 { 128 t.TaskEnv[MemLimit] = strconv.Itoa(t.MemLimit) 129 } 130 if t.CpuLimit != 0 { 131 t.TaskEnv[CpuLimit] = strconv.Itoa(t.CpuLimit) 132 } 133 134 // Build the node 135 if t.Node != nil { 136 // Set up the node values. 137 t.NodeValues[nodeIdKey] = t.Node.ID 138 t.NodeValues[nodeDcKey] = t.Node.Datacenter 139 t.NodeValues[nodeNameKey] = t.Node.Name 140 t.NodeValues[nodeClassKey] = t.Node.NodeClass 141 142 // Set up the attributes. 143 for k, v := range t.Node.Attributes { 144 t.NodeValues[fmt.Sprintf("%s%s", nodeAttributePrefix, k)] = v 145 } 146 147 // Set up the meta. 148 for k, v := range t.Node.Meta { 149 t.NodeValues[fmt.Sprintf("%s%s", nodeMetaPrefix, k)] = v 150 } 151 } 152 153 // Interpret the environment variables 154 interpreted := make(map[string]string, len(t.Env)) 155 for k, v := range t.Env { 156 interpreted[k] = hargs.ReplaceEnv(v, t.NodeValues, t.TaskEnv) 157 } 158 159 for k, v := range interpreted { 160 t.TaskEnv[k] = v 161 } 162 163 return t 164 } 165 166 // EnvList returns a list of strings with NAME=value pairs. 167 func (t *TaskEnvironment) EnvList() []string { 168 env := []string{} 169 for k, v := range t.TaskEnv { 170 env = append(env, fmt.Sprintf("%s=%s", k, v)) 171 } 172 173 return env 174 } 175 176 // EnvMap returns a copy of the tasks environment variables. 177 func (t *TaskEnvironment) EnvMap() map[string]string { 178 m := make(map[string]string, len(t.TaskEnv)) 179 for k, v := range t.TaskEnv { 180 m[k] = v 181 } 182 183 return m 184 } 185 186 // Builder methods to build the TaskEnvironment 187 func (t *TaskEnvironment) SetAllocDir(dir string) *TaskEnvironment { 188 t.AllocDir = dir 189 return t 190 } 191 192 func (t *TaskEnvironment) ClearAllocDir() *TaskEnvironment { 193 t.AllocDir = "" 194 return t 195 } 196 197 func (t *TaskEnvironment) SetTaskLocalDir(dir string) *TaskEnvironment { 198 t.TaskDir = dir 199 return t 200 } 201 202 func (t *TaskEnvironment) ClearTaskLocalDir() *TaskEnvironment { 203 t.TaskDir = "" 204 return t 205 } 206 207 func (t *TaskEnvironment) SetMemLimit(limit int) *TaskEnvironment { 208 t.MemLimit = limit 209 return t 210 } 211 212 func (t *TaskEnvironment) ClearMemLimit() *TaskEnvironment { 213 t.MemLimit = 0 214 return t 215 } 216 217 func (t *TaskEnvironment) SetCpuLimit(limit int) *TaskEnvironment { 218 t.CpuLimit = limit 219 return t 220 } 221 222 func (t *TaskEnvironment) ClearCpuLimit() *TaskEnvironment { 223 t.CpuLimit = 0 224 return t 225 } 226 227 func (t *TaskEnvironment) SetNetworks(networks []*structs.NetworkResource) *TaskEnvironment { 228 t.Networks = networks 229 return t 230 } 231 232 func (t *TaskEnvironment) clearNetworks() *TaskEnvironment { 233 t.Networks = nil 234 return t 235 } 236 237 func (t *TaskEnvironment) SetPortMap(portMap map[string]int) *TaskEnvironment { 238 t.PortMap = portMap 239 return t 240 } 241 242 func (t *TaskEnvironment) clearPortMap() *TaskEnvironment { 243 t.PortMap = nil 244 return t 245 } 246 247 // Takes a map of meta values to be passed to the task. The keys are capatilized 248 // when the environent variable is set. 249 func (t *TaskEnvironment) SetMeta(m map[string]string) *TaskEnvironment { 250 t.Meta = m 251 return t 252 } 253 254 func (t *TaskEnvironment) ClearMeta() *TaskEnvironment { 255 t.Meta = nil 256 return t 257 } 258 259 func (t *TaskEnvironment) SetEnvvars(m map[string]string) *TaskEnvironment { 260 t.Env = m 261 return t 262 } 263 264 // Appends the given environment variables. 265 func (t *TaskEnvironment) AppendEnvvars(m map[string]string) *TaskEnvironment { 266 if t.Env == nil { 267 t.Env = make(map[string]string, len(m)) 268 } 269 270 for k, v := range m { 271 t.Env[k] = v 272 } 273 return t 274 } 275 276 func (t *TaskEnvironment) ClearEnvvars() *TaskEnvironment { 277 t.Env = nil 278 return t 279 }