github.com/manicqin/nomad@v0.9.5/plugins/drivers/utils.go (about) 1 package drivers 2 3 import ( 4 "time" 5 6 "github.com/golang/protobuf/ptypes" 7 "github.com/hashicorp/nomad/nomad/structs" 8 "github.com/hashicorp/nomad/plugins/drivers/proto" 9 ) 10 11 var taskStateToProtoMap = map[TaskState]proto.TaskState{ 12 TaskStateUnknown: proto.TaskState_UNKNOWN, 13 TaskStateRunning: proto.TaskState_RUNNING, 14 TaskStateExited: proto.TaskState_EXITED, 15 } 16 17 var taskStateFromProtoMap = map[proto.TaskState]TaskState{ 18 proto.TaskState_UNKNOWN: TaskStateUnknown, 19 proto.TaskState_RUNNING: TaskStateRunning, 20 proto.TaskState_EXITED: TaskStateExited, 21 } 22 23 func healthStateToProto(health HealthState) proto.FingerprintResponse_HealthState { 24 switch health { 25 case HealthStateUndetected: 26 return proto.FingerprintResponse_UNDETECTED 27 case HealthStateUnhealthy: 28 return proto.FingerprintResponse_UNHEALTHY 29 case HealthStateHealthy: 30 return proto.FingerprintResponse_HEALTHY 31 } 32 return proto.FingerprintResponse_UNDETECTED 33 } 34 35 func healthStateFromProto(pb proto.FingerprintResponse_HealthState) HealthState { 36 switch pb { 37 case proto.FingerprintResponse_UNDETECTED: 38 return HealthStateUndetected 39 case proto.FingerprintResponse_UNHEALTHY: 40 return HealthStateUnhealthy 41 case proto.FingerprintResponse_HEALTHY: 42 return HealthStateHealthy 43 } 44 return HealthStateUndetected 45 } 46 47 func taskConfigFromProto(pb *proto.TaskConfig) *TaskConfig { 48 if pb == nil { 49 return &TaskConfig{} 50 } 51 return &TaskConfig{ 52 ID: pb.Id, 53 JobName: pb.JobName, 54 TaskGroupName: pb.TaskGroupName, 55 Name: pb.Name, 56 Env: pb.Env, 57 DeviceEnv: pb.DeviceEnv, 58 rawDriverConfig: pb.MsgpackDriverConfig, 59 Resources: ResourcesFromProto(pb.Resources), 60 Devices: DevicesFromProto(pb.Devices), 61 Mounts: MountsFromProto(pb.Mounts), 62 User: pb.User, 63 AllocDir: pb.AllocDir, 64 StdoutPath: pb.StdoutPath, 65 StderrPath: pb.StderrPath, 66 AllocID: pb.AllocId, 67 NetworkIsolation: NetworkIsolationSpecFromProto(pb.NetworkIsolationSpec), 68 } 69 } 70 71 func taskConfigToProto(cfg *TaskConfig) *proto.TaskConfig { 72 if cfg == nil { 73 return &proto.TaskConfig{} 74 } 75 pb := &proto.TaskConfig{ 76 Id: cfg.ID, 77 JobName: cfg.JobName, 78 TaskGroupName: cfg.TaskGroupName, 79 Name: cfg.Name, 80 Env: cfg.Env, 81 DeviceEnv: cfg.DeviceEnv, 82 Resources: ResourcesToProto(cfg.Resources), 83 Devices: DevicesToProto(cfg.Devices), 84 Mounts: MountsToProto(cfg.Mounts), 85 User: cfg.User, 86 AllocDir: cfg.AllocDir, 87 MsgpackDriverConfig: cfg.rawDriverConfig, 88 StdoutPath: cfg.StdoutPath, 89 StderrPath: cfg.StderrPath, 90 AllocId: cfg.AllocID, 91 NetworkIsolationSpec: NetworkIsolationSpecToProto(cfg.NetworkIsolation), 92 } 93 return pb 94 } 95 96 func ResourcesFromProto(pb *proto.Resources) *Resources { 97 var r Resources 98 if pb == nil { 99 return &r 100 } 101 102 if pb.AllocatedResources != nil { 103 r.NomadResources = &structs.AllocatedTaskResources{} 104 105 if pb.AllocatedResources.Cpu != nil { 106 r.NomadResources.Cpu.CpuShares = pb.AllocatedResources.Cpu.CpuShares 107 } 108 109 if pb.AllocatedResources.Memory != nil { 110 r.NomadResources.Memory.MemoryMB = pb.AllocatedResources.Memory.MemoryMb 111 } 112 113 for _, network := range pb.AllocatedResources.Networks { 114 var n structs.NetworkResource 115 n.Device = network.Device 116 n.IP = network.Ip 117 n.CIDR = network.Cidr 118 n.MBits = int(network.Mbits) 119 for _, port := range network.ReservedPorts { 120 n.ReservedPorts = append(n.ReservedPorts, structs.Port{ 121 Label: port.Label, 122 Value: int(port.Value), 123 }) 124 } 125 for _, port := range network.DynamicPorts { 126 n.DynamicPorts = append(n.DynamicPorts, structs.Port{ 127 Label: port.Label, 128 Value: int(port.Value), 129 }) 130 } 131 r.NomadResources.Networks = append(r.NomadResources.Networks, &n) 132 } 133 } 134 135 if pb.LinuxResources != nil { 136 r.LinuxResources = &LinuxResources{ 137 CPUPeriod: pb.LinuxResources.CpuPeriod, 138 CPUQuota: pb.LinuxResources.CpuQuota, 139 CPUShares: pb.LinuxResources.CpuShares, 140 MemoryLimitBytes: pb.LinuxResources.MemoryLimitBytes, 141 OOMScoreAdj: pb.LinuxResources.OomScoreAdj, 142 CpusetCPUs: pb.LinuxResources.CpusetCpus, 143 CpusetMems: pb.LinuxResources.CpusetMems, 144 PercentTicks: pb.LinuxResources.PercentTicks, 145 } 146 } 147 148 return &r 149 } 150 151 func ResourcesToProto(r *Resources) *proto.Resources { 152 if r == nil { 153 return nil 154 } 155 156 var pb proto.Resources 157 if r.NomadResources != nil { 158 pb.AllocatedResources = &proto.AllocatedTaskResources{ 159 Cpu: &proto.AllocatedCpuResources{ 160 CpuShares: r.NomadResources.Cpu.CpuShares, 161 }, 162 Memory: &proto.AllocatedMemoryResources{ 163 MemoryMb: r.NomadResources.Memory.MemoryMB, 164 }, 165 Networks: make([]*proto.NetworkResource, len(r.NomadResources.Networks)), 166 } 167 168 for i, network := range r.NomadResources.Networks { 169 var n proto.NetworkResource 170 n.Device = network.Device 171 n.Ip = network.IP 172 n.Cidr = network.CIDR 173 n.Mbits = int32(network.MBits) 174 n.ReservedPorts = []*proto.NetworkPort{} 175 for _, port := range network.ReservedPorts { 176 n.ReservedPorts = append(n.ReservedPorts, &proto.NetworkPort{ 177 Label: port.Label, 178 Value: int32(port.Value), 179 }) 180 } 181 for _, port := range network.DynamicPorts { 182 n.DynamicPorts = append(n.DynamicPorts, &proto.NetworkPort{ 183 Label: port.Label, 184 Value: int32(port.Value), 185 }) 186 } 187 pb.AllocatedResources.Networks[i] = &n 188 } 189 } 190 191 if r.LinuxResources != nil { 192 pb.LinuxResources = &proto.LinuxResources{ 193 CpuPeriod: r.LinuxResources.CPUPeriod, 194 CpuQuota: r.LinuxResources.CPUQuota, 195 CpuShares: r.LinuxResources.CPUShares, 196 MemoryLimitBytes: r.LinuxResources.MemoryLimitBytes, 197 OomScoreAdj: r.LinuxResources.OOMScoreAdj, 198 CpusetCpus: r.LinuxResources.CpusetCPUs, 199 CpusetMems: r.LinuxResources.CpusetMems, 200 PercentTicks: r.LinuxResources.PercentTicks, 201 } 202 } 203 204 return &pb 205 } 206 207 func DevicesFromProto(devices []*proto.Device) []*DeviceConfig { 208 if devices == nil { 209 return nil 210 } 211 212 out := make([]*DeviceConfig, len(devices)) 213 for i, d := range devices { 214 out[i] = DeviceFromProto(d) 215 } 216 217 return out 218 } 219 220 func DeviceFromProto(device *proto.Device) *DeviceConfig { 221 if device == nil { 222 return nil 223 } 224 225 return &DeviceConfig{ 226 TaskPath: device.TaskPath, 227 HostPath: device.HostPath, 228 Permissions: device.CgroupPermissions, 229 } 230 } 231 232 func MountsFromProto(mounts []*proto.Mount) []*MountConfig { 233 if mounts == nil { 234 return nil 235 } 236 237 out := make([]*MountConfig, len(mounts)) 238 for i, m := range mounts { 239 out[i] = MountFromProto(m) 240 } 241 242 return out 243 } 244 245 func MountFromProto(mount *proto.Mount) *MountConfig { 246 if mount == nil { 247 return nil 248 } 249 250 return &MountConfig{ 251 TaskPath: mount.TaskPath, 252 HostPath: mount.HostPath, 253 Readonly: mount.Readonly, 254 } 255 } 256 257 func DevicesToProto(devices []*DeviceConfig) []*proto.Device { 258 if devices == nil { 259 return nil 260 } 261 262 out := make([]*proto.Device, len(devices)) 263 for i, d := range devices { 264 out[i] = DeviceToProto(d) 265 } 266 267 return out 268 } 269 270 func DeviceToProto(device *DeviceConfig) *proto.Device { 271 if device == nil { 272 return nil 273 } 274 275 return &proto.Device{ 276 TaskPath: device.TaskPath, 277 HostPath: device.HostPath, 278 CgroupPermissions: device.Permissions, 279 } 280 } 281 282 func MountsToProto(mounts []*MountConfig) []*proto.Mount { 283 if mounts == nil { 284 return nil 285 } 286 287 out := make([]*proto.Mount, len(mounts)) 288 for i, m := range mounts { 289 out[i] = MountToProto(m) 290 } 291 292 return out 293 } 294 295 func MountToProto(mount *MountConfig) *proto.Mount { 296 if mount == nil { 297 return nil 298 } 299 300 return &proto.Mount{ 301 TaskPath: mount.TaskPath, 302 HostPath: mount.HostPath, 303 Readonly: mount.Readonly, 304 } 305 } 306 307 func taskHandleFromProto(pb *proto.TaskHandle) *TaskHandle { 308 if pb == nil { 309 return &TaskHandle{} 310 } 311 return &TaskHandle{ 312 Version: int(pb.Version), 313 Config: taskConfigFromProto(pb.Config), 314 State: taskStateFromProtoMap[pb.State], 315 DriverState: pb.DriverState, 316 } 317 } 318 319 func taskHandleToProto(handle *TaskHandle) *proto.TaskHandle { 320 return &proto.TaskHandle{ 321 Version: int32(handle.Version), 322 Config: taskConfigToProto(handle.Config), 323 State: taskStateToProtoMap[handle.State], 324 DriverState: handle.DriverState, 325 } 326 } 327 328 func exitResultToProto(result *ExitResult) *proto.ExitResult { 329 if result == nil { 330 return &proto.ExitResult{} 331 } 332 return &proto.ExitResult{ 333 ExitCode: int32(result.ExitCode), 334 Signal: int32(result.Signal), 335 OomKilled: result.OOMKilled, 336 } 337 } 338 339 func exitResultFromProto(pb *proto.ExitResult) *ExitResult { 340 return &ExitResult{ 341 ExitCode: int(pb.ExitCode), 342 Signal: int(pb.Signal), 343 OOMKilled: pb.OomKilled, 344 } 345 } 346 347 func taskStatusToProto(status *TaskStatus) (*proto.TaskStatus, error) { 348 started, err := ptypes.TimestampProto(status.StartedAt) 349 if err != nil { 350 return nil, err 351 } 352 completed, err := ptypes.TimestampProto(status.CompletedAt) 353 if err != nil { 354 return nil, err 355 } 356 return &proto.TaskStatus{ 357 Id: status.ID, 358 Name: status.Name, 359 State: taskStateToProtoMap[status.State], 360 StartedAt: started, 361 CompletedAt: completed, 362 Result: exitResultToProto(status.ExitResult), 363 }, nil 364 } 365 366 func taskStatusFromProto(pb *proto.TaskStatus) (*TaskStatus, error) { 367 started, err := ptypes.Timestamp(pb.StartedAt) 368 if err != nil { 369 return nil, err 370 } 371 372 completed, err := ptypes.Timestamp(pb.CompletedAt) 373 if err != nil { 374 return nil, err 375 } 376 377 return &TaskStatus{ 378 ID: pb.Id, 379 Name: pb.Name, 380 State: taskStateFromProtoMap[pb.State], 381 StartedAt: started, 382 CompletedAt: completed, 383 ExitResult: exitResultFromProto(pb.Result), 384 }, nil 385 } 386 387 func TaskStatsToProto(stats *TaskResourceUsage) (*proto.TaskStats, error) { 388 timestamp, err := ptypes.TimestampProto(time.Unix(0, stats.Timestamp)) 389 if err != nil { 390 return nil, err 391 } 392 393 pids := map[string]*proto.TaskResourceUsage{} 394 for pid, ru := range stats.Pids { 395 pids[pid] = resourceUsageToProto(ru) 396 } 397 398 return &proto.TaskStats{ 399 Timestamp: timestamp, 400 AggResourceUsage: resourceUsageToProto(stats.ResourceUsage), 401 ResourceUsageByPid: pids, 402 }, nil 403 } 404 405 func TaskStatsFromProto(pb *proto.TaskStats) (*TaskResourceUsage, error) { 406 timestamp, err := ptypes.Timestamp(pb.Timestamp) 407 if err != nil { 408 return nil, err 409 } 410 411 pids := map[string]*ResourceUsage{} 412 for pid, ru := range pb.ResourceUsageByPid { 413 pids[pid] = resourceUsageFromProto(ru) 414 } 415 416 stats := &TaskResourceUsage{ 417 Timestamp: timestamp.UnixNano(), 418 ResourceUsage: resourceUsageFromProto(pb.AggResourceUsage), 419 Pids: pids, 420 } 421 422 return stats, nil 423 } 424 425 func resourceUsageToProto(ru *ResourceUsage) *proto.TaskResourceUsage { 426 cpu := &proto.CPUUsage{ 427 MeasuredFields: cpuUsageMeasuredFieldsToProto(ru.CpuStats.Measured), 428 SystemMode: ru.CpuStats.SystemMode, 429 UserMode: ru.CpuStats.UserMode, 430 TotalTicks: ru.CpuStats.TotalTicks, 431 ThrottledPeriods: ru.CpuStats.ThrottledPeriods, 432 ThrottledTime: ru.CpuStats.ThrottledTime, 433 Percent: ru.CpuStats.Percent, 434 } 435 436 memory := &proto.MemoryUsage{ 437 MeasuredFields: memoryUsageMeasuredFieldsToProto(ru.MemoryStats.Measured), 438 Rss: ru.MemoryStats.RSS, 439 Cache: ru.MemoryStats.Cache, 440 Swap: ru.MemoryStats.Swap, 441 Usage: ru.MemoryStats.Usage, 442 MaxUsage: ru.MemoryStats.MaxUsage, 443 KernelUsage: ru.MemoryStats.KernelUsage, 444 KernelMaxUsage: ru.MemoryStats.KernelMaxUsage, 445 } 446 447 return &proto.TaskResourceUsage{ 448 Cpu: cpu, 449 Memory: memory, 450 } 451 } 452 453 func resourceUsageFromProto(pb *proto.TaskResourceUsage) *ResourceUsage { 454 cpu := CpuStats{} 455 if pb.Cpu != nil { 456 cpu = CpuStats{ 457 Measured: cpuUsageMeasuredFieldsFromProto(pb.Cpu.MeasuredFields), 458 SystemMode: pb.Cpu.SystemMode, 459 UserMode: pb.Cpu.UserMode, 460 TotalTicks: pb.Cpu.TotalTicks, 461 ThrottledPeriods: pb.Cpu.ThrottledPeriods, 462 ThrottledTime: pb.Cpu.ThrottledTime, 463 Percent: pb.Cpu.Percent, 464 } 465 } 466 467 memory := MemoryStats{} 468 if pb.Memory != nil { 469 memory = MemoryStats{ 470 Measured: memoryUsageMeasuredFieldsFromProto(pb.Memory.MeasuredFields), 471 RSS: pb.Memory.Rss, 472 Cache: pb.Memory.Cache, 473 Swap: pb.Memory.Swap, 474 Usage: pb.Memory.Usage, 475 MaxUsage: pb.Memory.MaxUsage, 476 KernelUsage: pb.Memory.KernelUsage, 477 KernelMaxUsage: pb.Memory.KernelMaxUsage, 478 } 479 } 480 481 return &ResourceUsage{ 482 CpuStats: &cpu, 483 MemoryStats: &memory, 484 } 485 } 486 487 func BytesToMB(bytes int64) int64 { 488 return bytes / (1024 * 1024) 489 } 490 491 var cpuUsageMeasuredFieldToProtoMap = map[string]proto.CPUUsage_Fields{ 492 "System Mode": proto.CPUUsage_SYSTEM_MODE, 493 "User Mode": proto.CPUUsage_USER_MODE, 494 "Total Ticks": proto.CPUUsage_TOTAL_TICKS, 495 "Throttled Periods": proto.CPUUsage_THROTTLED_PERIODS, 496 "Throttled Time": proto.CPUUsage_THROTTLED_TIME, 497 "Percent": proto.CPUUsage_PERCENT, 498 } 499 500 var cpuUsageMeasuredFieldFromProtoMap = map[proto.CPUUsage_Fields]string{ 501 proto.CPUUsage_SYSTEM_MODE: "System Mode", 502 proto.CPUUsage_USER_MODE: "User Mode", 503 proto.CPUUsage_TOTAL_TICKS: "Total Ticks", 504 proto.CPUUsage_THROTTLED_PERIODS: "Throttled Periods", 505 proto.CPUUsage_THROTTLED_TIME: "Throttled Time", 506 proto.CPUUsage_PERCENT: "Percent", 507 } 508 509 func cpuUsageMeasuredFieldsToProto(fields []string) []proto.CPUUsage_Fields { 510 r := make([]proto.CPUUsage_Fields, 0, len(fields)) 511 512 for _, f := range fields { 513 if v, ok := cpuUsageMeasuredFieldToProtoMap[f]; ok { 514 r = append(r, v) 515 } 516 } 517 518 return r 519 } 520 521 func cpuUsageMeasuredFieldsFromProto(fields []proto.CPUUsage_Fields) []string { 522 r := make([]string, 0, len(fields)) 523 524 for _, f := range fields { 525 if v, ok := cpuUsageMeasuredFieldFromProtoMap[f]; ok { 526 r = append(r, v) 527 } 528 } 529 530 return r 531 } 532 533 var memoryUsageMeasuredFieldToProtoMap = map[string]proto.MemoryUsage_Fields{ 534 "RSS": proto.MemoryUsage_RSS, 535 "Cache": proto.MemoryUsage_CACHE, 536 "Swap": proto.MemoryUsage_SWAP, 537 "Usage": proto.MemoryUsage_USAGE, 538 "Max Usage": proto.MemoryUsage_MAX_USAGE, 539 "Kernel Usage": proto.MemoryUsage_KERNEL_USAGE, 540 "Kernel Max Usage": proto.MemoryUsage_KERNEL_MAX_USAGE, 541 } 542 543 var memoryUsageMeasuredFieldFromProtoMap = map[proto.MemoryUsage_Fields]string{ 544 proto.MemoryUsage_RSS: "RSS", 545 proto.MemoryUsage_CACHE: "Cache", 546 proto.MemoryUsage_SWAP: "Swap", 547 proto.MemoryUsage_USAGE: "Usage", 548 proto.MemoryUsage_MAX_USAGE: "Max Usage", 549 proto.MemoryUsage_KERNEL_USAGE: "Kernel Usage", 550 proto.MemoryUsage_KERNEL_MAX_USAGE: "Kernel Max Usage", 551 } 552 553 func memoryUsageMeasuredFieldsToProto(fields []string) []proto.MemoryUsage_Fields { 554 r := make([]proto.MemoryUsage_Fields, 0, len(fields)) 555 556 for _, f := range fields { 557 if v, ok := memoryUsageMeasuredFieldToProtoMap[f]; ok { 558 r = append(r, v) 559 } 560 } 561 562 return r 563 } 564 565 func memoryUsageMeasuredFieldsFromProto(fields []proto.MemoryUsage_Fields) []string { 566 r := make([]string, 0, len(fields)) 567 568 for _, f := range fields { 569 if v, ok := memoryUsageMeasuredFieldFromProtoMap[f]; ok { 570 r = append(r, v) 571 } 572 } 573 574 return r 575 } 576 577 func netIsolationModeToProto(mode NetIsolationMode) proto.NetworkIsolationSpec_NetworkIsolationMode { 578 switch mode { 579 case NetIsolationModeHost: 580 return proto.NetworkIsolationSpec_HOST 581 case NetIsolationModeGroup: 582 return proto.NetworkIsolationSpec_GROUP 583 case NetIsolationModeTask: 584 return proto.NetworkIsolationSpec_TASK 585 case NetIsolationModeNone: 586 return proto.NetworkIsolationSpec_NONE 587 default: 588 return proto.NetworkIsolationSpec_HOST 589 } 590 } 591 592 func netIsolationModeFromProto(pb proto.NetworkIsolationSpec_NetworkIsolationMode) NetIsolationMode { 593 switch pb { 594 case proto.NetworkIsolationSpec_HOST: 595 return NetIsolationModeHost 596 case proto.NetworkIsolationSpec_GROUP: 597 return NetIsolationModeGroup 598 case proto.NetworkIsolationSpec_TASK: 599 return NetIsolationModeTask 600 case proto.NetworkIsolationSpec_NONE: 601 return NetIsolationModeNone 602 default: 603 return NetIsolationModeHost 604 } 605 } 606 607 func NetworkIsolationSpecToProto(spec *NetworkIsolationSpec) *proto.NetworkIsolationSpec { 608 if spec == nil { 609 return nil 610 } 611 return &proto.NetworkIsolationSpec{ 612 Path: spec.Path, 613 Labels: spec.Labels, 614 Mode: netIsolationModeToProto(spec.Mode), 615 } 616 } 617 618 func NetworkIsolationSpecFromProto(pb *proto.NetworkIsolationSpec) *NetworkIsolationSpec { 619 if pb == nil { 620 return nil 621 } 622 return &NetworkIsolationSpec{ 623 Path: pb.Path, 624 Labels: pb.Labels, 625 Mode: netIsolationModeFromProto(pb.Mode), 626 } 627 }