github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/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 DNS: dnsConfigFromProto(pb.Dns), 69 } 70 } 71 72 func taskConfigToProto(cfg *TaskConfig) *proto.TaskConfig { 73 if cfg == nil { 74 return &proto.TaskConfig{} 75 } 76 pb := &proto.TaskConfig{ 77 Id: cfg.ID, 78 JobName: cfg.JobName, 79 TaskGroupName: cfg.TaskGroupName, 80 Name: cfg.Name, 81 Env: cfg.Env, 82 DeviceEnv: cfg.DeviceEnv, 83 Resources: ResourcesToProto(cfg.Resources), 84 Devices: DevicesToProto(cfg.Devices), 85 Mounts: MountsToProto(cfg.Mounts), 86 User: cfg.User, 87 AllocDir: cfg.AllocDir, 88 MsgpackDriverConfig: cfg.rawDriverConfig, 89 StdoutPath: cfg.StdoutPath, 90 StderrPath: cfg.StderrPath, 91 AllocId: cfg.AllocID, 92 NetworkIsolationSpec: NetworkIsolationSpecToProto(cfg.NetworkIsolation), 93 Dns: dnsConfigToProto(cfg.DNS), 94 } 95 return pb 96 } 97 98 func ResourcesFromProto(pb *proto.Resources) *Resources { 99 var r Resources 100 if pb == nil { 101 return &r 102 } 103 104 if pb.AllocatedResources != nil { 105 r.NomadResources = &structs.AllocatedTaskResources{} 106 107 if pb.AllocatedResources.Cpu != nil { 108 r.NomadResources.Cpu.CpuShares = pb.AllocatedResources.Cpu.CpuShares 109 } 110 111 if pb.AllocatedResources.Memory != nil { 112 r.NomadResources.Memory.MemoryMB = pb.AllocatedResources.Memory.MemoryMb 113 r.NomadResources.Memory.MemoryMaxMB = pb.AllocatedResources.Memory.MemoryMaxMb 114 } 115 116 for _, network := range pb.AllocatedResources.Networks { 117 var n structs.NetworkResource 118 n.Device = network.Device 119 n.IP = network.Ip 120 n.CIDR = network.Cidr 121 n.MBits = int(network.Mbits) 122 for _, port := range network.ReservedPorts { 123 n.ReservedPorts = append(n.ReservedPorts, structs.Port{ 124 Label: port.Label, 125 Value: int(port.Value), 126 }) 127 } 128 for _, port := range network.DynamicPorts { 129 n.DynamicPorts = append(n.DynamicPorts, structs.Port{ 130 Label: port.Label, 131 Value: int(port.Value), 132 }) 133 } 134 r.NomadResources.Networks = append(r.NomadResources.Networks, &n) 135 } 136 } 137 138 if pb.LinuxResources != nil { 139 r.LinuxResources = &LinuxResources{ 140 CPUPeriod: pb.LinuxResources.CpuPeriod, 141 CPUQuota: pb.LinuxResources.CpuQuota, 142 CPUShares: pb.LinuxResources.CpuShares, 143 MemoryLimitBytes: pb.LinuxResources.MemoryLimitBytes, 144 OOMScoreAdj: pb.LinuxResources.OomScoreAdj, 145 CpusetCpus: pb.LinuxResources.CpusetCpus, 146 CpusetCgroupPath: pb.LinuxResources.CpusetCgroup, 147 PercentTicks: pb.LinuxResources.PercentTicks, 148 } 149 } 150 151 if pb.Ports != nil { 152 ports := structs.AllocatedPorts(make([]structs.AllocatedPortMapping, len(pb.Ports))) 153 for i, port := range pb.Ports { 154 ports[i] = structs.AllocatedPortMapping{ 155 Label: port.Label, 156 Value: int(port.Value), 157 To: int(port.To), 158 HostIP: port.HostIp, 159 } 160 } 161 r.Ports = &ports 162 } 163 164 return &r 165 } 166 167 func ResourcesToProto(r *Resources) *proto.Resources { 168 if r == nil { 169 return nil 170 } 171 172 var pb proto.Resources 173 if r.NomadResources != nil { 174 pb.AllocatedResources = &proto.AllocatedTaskResources{ 175 Cpu: &proto.AllocatedCpuResources{ 176 CpuShares: r.NomadResources.Cpu.CpuShares, 177 }, 178 Memory: &proto.AllocatedMemoryResources{ 179 MemoryMb: r.NomadResources.Memory.MemoryMB, 180 MemoryMaxMb: r.NomadResources.Memory.MemoryMaxMB, 181 }, 182 Networks: make([]*proto.NetworkResource, len(r.NomadResources.Networks)), 183 } 184 185 for i, network := range r.NomadResources.Networks { 186 var n proto.NetworkResource 187 n.Device = network.Device 188 n.Ip = network.IP 189 n.Cidr = network.CIDR 190 n.Mbits = int32(network.MBits) 191 n.ReservedPorts = []*proto.NetworkPort{} 192 for _, port := range network.ReservedPorts { 193 n.ReservedPorts = append(n.ReservedPorts, &proto.NetworkPort{ 194 Label: port.Label, 195 Value: int32(port.Value), 196 }) 197 } 198 for _, port := range network.DynamicPorts { 199 n.DynamicPorts = append(n.DynamicPorts, &proto.NetworkPort{ 200 Label: port.Label, 201 Value: int32(port.Value), 202 }) 203 } 204 pb.AllocatedResources.Networks[i] = &n 205 } 206 } 207 208 if r.LinuxResources != nil { 209 pb.LinuxResources = &proto.LinuxResources{ 210 CpuPeriod: r.LinuxResources.CPUPeriod, 211 CpuQuota: r.LinuxResources.CPUQuota, 212 CpuShares: r.LinuxResources.CPUShares, 213 MemoryLimitBytes: r.LinuxResources.MemoryLimitBytes, 214 OomScoreAdj: r.LinuxResources.OOMScoreAdj, 215 CpusetCpus: r.LinuxResources.CpusetCpus, 216 CpusetCgroup: r.LinuxResources.CpusetCgroupPath, 217 PercentTicks: r.LinuxResources.PercentTicks, 218 } 219 } 220 221 if r.Ports != nil { 222 ports := make([]*proto.PortMapping, len(*r.Ports)) 223 for i, port := range *r.Ports { 224 ports[i] = &proto.PortMapping{ 225 Label: port.Label, 226 Value: int32(port.Value), 227 To: int32(port.To), 228 HostIp: port.HostIP, 229 } 230 } 231 232 pb.Ports = ports 233 } 234 235 return &pb 236 } 237 238 func DevicesFromProto(devices []*proto.Device) []*DeviceConfig { 239 if devices == nil { 240 return nil 241 } 242 243 out := make([]*DeviceConfig, len(devices)) 244 for i, d := range devices { 245 out[i] = DeviceFromProto(d) 246 } 247 248 return out 249 } 250 251 func DeviceFromProto(device *proto.Device) *DeviceConfig { 252 if device == nil { 253 return nil 254 } 255 256 return &DeviceConfig{ 257 TaskPath: device.TaskPath, 258 HostPath: device.HostPath, 259 Permissions: device.CgroupPermissions, 260 } 261 } 262 263 func MountsFromProto(mounts []*proto.Mount) []*MountConfig { 264 if mounts == nil { 265 return nil 266 } 267 268 out := make([]*MountConfig, len(mounts)) 269 for i, m := range mounts { 270 out[i] = MountFromProto(m) 271 } 272 273 return out 274 } 275 276 func MountFromProto(mount *proto.Mount) *MountConfig { 277 if mount == nil { 278 return nil 279 } 280 281 return &MountConfig{ 282 TaskPath: mount.TaskPath, 283 HostPath: mount.HostPath, 284 Readonly: mount.Readonly, 285 PropagationMode: mount.PropagationMode, 286 } 287 } 288 289 func DevicesToProto(devices []*DeviceConfig) []*proto.Device { 290 if devices == nil { 291 return nil 292 } 293 294 out := make([]*proto.Device, len(devices)) 295 for i, d := range devices { 296 out[i] = DeviceToProto(d) 297 } 298 299 return out 300 } 301 302 func DeviceToProto(device *DeviceConfig) *proto.Device { 303 if device == nil { 304 return nil 305 } 306 307 return &proto.Device{ 308 TaskPath: device.TaskPath, 309 HostPath: device.HostPath, 310 CgroupPermissions: device.Permissions, 311 } 312 } 313 314 func MountsToProto(mounts []*MountConfig) []*proto.Mount { 315 if mounts == nil { 316 return nil 317 } 318 319 out := make([]*proto.Mount, len(mounts)) 320 for i, m := range mounts { 321 out[i] = MountToProto(m) 322 } 323 324 return out 325 } 326 327 func MountToProto(mount *MountConfig) *proto.Mount { 328 if mount == nil { 329 return nil 330 } 331 332 return &proto.Mount{ 333 TaskPath: mount.TaskPath, 334 HostPath: mount.HostPath, 335 Readonly: mount.Readonly, 336 PropagationMode: mount.PropagationMode, 337 } 338 } 339 340 func taskHandleFromProto(pb *proto.TaskHandle) *TaskHandle { 341 if pb == nil { 342 return &TaskHandle{} 343 } 344 return &TaskHandle{ 345 Version: int(pb.Version), 346 Config: taskConfigFromProto(pb.Config), 347 State: taskStateFromProtoMap[pb.State], 348 DriverState: pb.DriverState, 349 } 350 } 351 352 func taskHandleToProto(handle *TaskHandle) *proto.TaskHandle { 353 return &proto.TaskHandle{ 354 Version: int32(handle.Version), 355 Config: taskConfigToProto(handle.Config), 356 State: taskStateToProtoMap[handle.State], 357 DriverState: handle.DriverState, 358 } 359 } 360 361 func exitResultToProto(result *ExitResult) *proto.ExitResult { 362 if result == nil { 363 return &proto.ExitResult{} 364 } 365 return &proto.ExitResult{ 366 ExitCode: int32(result.ExitCode), 367 Signal: int32(result.Signal), 368 OomKilled: result.OOMKilled, 369 } 370 } 371 372 func exitResultFromProto(pb *proto.ExitResult) *ExitResult { 373 return &ExitResult{ 374 ExitCode: int(pb.ExitCode), 375 Signal: int(pb.Signal), 376 OOMKilled: pb.OomKilled, 377 } 378 } 379 380 func taskStatusToProto(status *TaskStatus) (*proto.TaskStatus, error) { 381 started, err := ptypes.TimestampProto(status.StartedAt) 382 if err != nil { 383 return nil, err 384 } 385 completed, err := ptypes.TimestampProto(status.CompletedAt) 386 if err != nil { 387 return nil, err 388 } 389 return &proto.TaskStatus{ 390 Id: status.ID, 391 Name: status.Name, 392 State: taskStateToProtoMap[status.State], 393 StartedAt: started, 394 CompletedAt: completed, 395 Result: exitResultToProto(status.ExitResult), 396 }, nil 397 } 398 399 func taskStatusFromProto(pb *proto.TaskStatus) (*TaskStatus, error) { 400 started, err := ptypes.Timestamp(pb.StartedAt) 401 if err != nil { 402 return nil, err 403 } 404 405 completed, err := ptypes.Timestamp(pb.CompletedAt) 406 if err != nil { 407 return nil, err 408 } 409 410 return &TaskStatus{ 411 ID: pb.Id, 412 Name: pb.Name, 413 State: taskStateFromProtoMap[pb.State], 414 StartedAt: started, 415 CompletedAt: completed, 416 ExitResult: exitResultFromProto(pb.Result), 417 }, nil 418 } 419 420 func TaskStatsToProto(stats *TaskResourceUsage) (*proto.TaskStats, error) { 421 timestamp, err := ptypes.TimestampProto(time.Unix(0, stats.Timestamp)) 422 if err != nil { 423 return nil, err 424 } 425 426 pids := map[string]*proto.TaskResourceUsage{} 427 for pid, ru := range stats.Pids { 428 pids[pid] = resourceUsageToProto(ru) 429 } 430 431 return &proto.TaskStats{ 432 Timestamp: timestamp, 433 AggResourceUsage: resourceUsageToProto(stats.ResourceUsage), 434 ResourceUsageByPid: pids, 435 }, nil 436 } 437 438 func TaskStatsFromProto(pb *proto.TaskStats) (*TaskResourceUsage, error) { 439 timestamp, err := ptypes.Timestamp(pb.Timestamp) 440 if err != nil { 441 return nil, err 442 } 443 444 pids := map[string]*ResourceUsage{} 445 for pid, ru := range pb.ResourceUsageByPid { 446 pids[pid] = resourceUsageFromProto(ru) 447 } 448 449 stats := &TaskResourceUsage{ 450 Timestamp: timestamp.UnixNano(), 451 ResourceUsage: resourceUsageFromProto(pb.AggResourceUsage), 452 Pids: pids, 453 } 454 455 return stats, nil 456 } 457 458 func resourceUsageToProto(ru *ResourceUsage) *proto.TaskResourceUsage { 459 cpu := &proto.CPUUsage{ 460 MeasuredFields: cpuUsageMeasuredFieldsToProto(ru.CpuStats.Measured), 461 SystemMode: ru.CpuStats.SystemMode, 462 UserMode: ru.CpuStats.UserMode, 463 TotalTicks: ru.CpuStats.TotalTicks, 464 ThrottledPeriods: ru.CpuStats.ThrottledPeriods, 465 ThrottledTime: ru.CpuStats.ThrottledTime, 466 Percent: ru.CpuStats.Percent, 467 } 468 469 memory := &proto.MemoryUsage{ 470 MeasuredFields: memoryUsageMeasuredFieldsToProto(ru.MemoryStats.Measured), 471 Rss: ru.MemoryStats.RSS, 472 Cache: ru.MemoryStats.Cache, 473 Swap: ru.MemoryStats.Swap, 474 Usage: ru.MemoryStats.Usage, 475 MaxUsage: ru.MemoryStats.MaxUsage, 476 KernelUsage: ru.MemoryStats.KernelUsage, 477 KernelMaxUsage: ru.MemoryStats.KernelMaxUsage, 478 } 479 480 return &proto.TaskResourceUsage{ 481 Cpu: cpu, 482 Memory: memory, 483 } 484 } 485 486 func resourceUsageFromProto(pb *proto.TaskResourceUsage) *ResourceUsage { 487 cpu := CpuStats{} 488 if pb.Cpu != nil { 489 cpu = CpuStats{ 490 Measured: cpuUsageMeasuredFieldsFromProto(pb.Cpu.MeasuredFields), 491 SystemMode: pb.Cpu.SystemMode, 492 UserMode: pb.Cpu.UserMode, 493 TotalTicks: pb.Cpu.TotalTicks, 494 ThrottledPeriods: pb.Cpu.ThrottledPeriods, 495 ThrottledTime: pb.Cpu.ThrottledTime, 496 Percent: pb.Cpu.Percent, 497 } 498 } 499 500 memory := MemoryStats{} 501 if pb.Memory != nil { 502 memory = MemoryStats{ 503 Measured: memoryUsageMeasuredFieldsFromProto(pb.Memory.MeasuredFields), 504 RSS: pb.Memory.Rss, 505 Cache: pb.Memory.Cache, 506 Swap: pb.Memory.Swap, 507 Usage: pb.Memory.Usage, 508 MaxUsage: pb.Memory.MaxUsage, 509 KernelUsage: pb.Memory.KernelUsage, 510 KernelMaxUsage: pb.Memory.KernelMaxUsage, 511 } 512 } 513 514 return &ResourceUsage{ 515 CpuStats: &cpu, 516 MemoryStats: &memory, 517 } 518 } 519 520 func BytesToMB(bytes int64) int64 { 521 return bytes / (1024 * 1024) 522 } 523 524 var cpuUsageMeasuredFieldToProtoMap = map[string]proto.CPUUsage_Fields{ 525 "System Mode": proto.CPUUsage_SYSTEM_MODE, 526 "User Mode": proto.CPUUsage_USER_MODE, 527 "Total Ticks": proto.CPUUsage_TOTAL_TICKS, 528 "Throttled Periods": proto.CPUUsage_THROTTLED_PERIODS, 529 "Throttled Time": proto.CPUUsage_THROTTLED_TIME, 530 "Percent": proto.CPUUsage_PERCENT, 531 } 532 533 var cpuUsageMeasuredFieldFromProtoMap = map[proto.CPUUsage_Fields]string{ 534 proto.CPUUsage_SYSTEM_MODE: "System Mode", 535 proto.CPUUsage_USER_MODE: "User Mode", 536 proto.CPUUsage_TOTAL_TICKS: "Total Ticks", 537 proto.CPUUsage_THROTTLED_PERIODS: "Throttled Periods", 538 proto.CPUUsage_THROTTLED_TIME: "Throttled Time", 539 proto.CPUUsage_PERCENT: "Percent", 540 } 541 542 func cpuUsageMeasuredFieldsToProto(fields []string) []proto.CPUUsage_Fields { 543 r := make([]proto.CPUUsage_Fields, 0, len(fields)) 544 545 for _, f := range fields { 546 if v, ok := cpuUsageMeasuredFieldToProtoMap[f]; ok { 547 r = append(r, v) 548 } 549 } 550 551 return r 552 } 553 554 func cpuUsageMeasuredFieldsFromProto(fields []proto.CPUUsage_Fields) []string { 555 r := make([]string, 0, len(fields)) 556 557 for _, f := range fields { 558 if v, ok := cpuUsageMeasuredFieldFromProtoMap[f]; ok { 559 r = append(r, v) 560 } 561 } 562 563 return r 564 } 565 566 var memoryUsageMeasuredFieldToProtoMap = map[string]proto.MemoryUsage_Fields{ 567 "RSS": proto.MemoryUsage_RSS, 568 "Cache": proto.MemoryUsage_CACHE, 569 "Swap": proto.MemoryUsage_SWAP, 570 "Usage": proto.MemoryUsage_USAGE, 571 "Max Usage": proto.MemoryUsage_MAX_USAGE, 572 "Kernel Usage": proto.MemoryUsage_KERNEL_USAGE, 573 "Kernel Max Usage": proto.MemoryUsage_KERNEL_MAX_USAGE, 574 } 575 576 var memoryUsageMeasuredFieldFromProtoMap = map[proto.MemoryUsage_Fields]string{ 577 proto.MemoryUsage_RSS: "RSS", 578 proto.MemoryUsage_CACHE: "Cache", 579 proto.MemoryUsage_SWAP: "Swap", 580 proto.MemoryUsage_USAGE: "Usage", 581 proto.MemoryUsage_MAX_USAGE: "Max Usage", 582 proto.MemoryUsage_KERNEL_USAGE: "Kernel Usage", 583 proto.MemoryUsage_KERNEL_MAX_USAGE: "Kernel Max Usage", 584 } 585 586 func memoryUsageMeasuredFieldsToProto(fields []string) []proto.MemoryUsage_Fields { 587 r := make([]proto.MemoryUsage_Fields, 0, len(fields)) 588 589 for _, f := range fields { 590 if v, ok := memoryUsageMeasuredFieldToProtoMap[f]; ok { 591 r = append(r, v) 592 } 593 } 594 595 return r 596 } 597 598 func memoryUsageMeasuredFieldsFromProto(fields []proto.MemoryUsage_Fields) []string { 599 r := make([]string, 0, len(fields)) 600 601 for _, f := range fields { 602 if v, ok := memoryUsageMeasuredFieldFromProtoMap[f]; ok { 603 r = append(r, v) 604 } 605 } 606 607 return r 608 } 609 610 func netIsolationModeToProto(mode NetIsolationMode) proto.NetworkIsolationSpec_NetworkIsolationMode { 611 switch mode { 612 case NetIsolationModeHost: 613 return proto.NetworkIsolationSpec_HOST 614 case NetIsolationModeGroup: 615 return proto.NetworkIsolationSpec_GROUP 616 case NetIsolationModeTask: 617 return proto.NetworkIsolationSpec_TASK 618 case NetIsolationModeNone: 619 return proto.NetworkIsolationSpec_NONE 620 default: 621 return proto.NetworkIsolationSpec_HOST 622 } 623 } 624 625 func netIsolationModeFromProto(pb proto.NetworkIsolationSpec_NetworkIsolationMode) NetIsolationMode { 626 switch pb { 627 case proto.NetworkIsolationSpec_HOST: 628 return NetIsolationModeHost 629 case proto.NetworkIsolationSpec_GROUP: 630 return NetIsolationModeGroup 631 case proto.NetworkIsolationSpec_TASK: 632 return NetIsolationModeTask 633 case proto.NetworkIsolationSpec_NONE: 634 return NetIsolationModeNone 635 default: 636 return NetIsolationModeHost 637 } 638 } 639 640 func networkCreateRequestFromProto(pb *proto.CreateNetworkRequest) *NetworkCreateRequest { 641 if pb == nil { 642 return nil 643 } 644 return &NetworkCreateRequest{ 645 Hostname: pb.GetHostname(), 646 } 647 } 648 649 func NetworkIsolationSpecToProto(spec *NetworkIsolationSpec) *proto.NetworkIsolationSpec { 650 if spec == nil { 651 return nil 652 } 653 return &proto.NetworkIsolationSpec{ 654 Path: spec.Path, 655 Labels: spec.Labels, 656 Mode: netIsolationModeToProto(spec.Mode), 657 HostsConfig: hostsConfigToProto(spec.HostsConfig), 658 } 659 } 660 661 func NetworkIsolationSpecFromProto(pb *proto.NetworkIsolationSpec) *NetworkIsolationSpec { 662 if pb == nil { 663 return nil 664 } 665 return &NetworkIsolationSpec{ 666 Path: pb.Path, 667 Labels: pb.Labels, 668 Mode: netIsolationModeFromProto(pb.Mode), 669 HostsConfig: hostsConfigFromProto(pb.HostsConfig), 670 } 671 } 672 673 func hostsConfigToProto(cfg *HostsConfig) *proto.HostsConfig { 674 if cfg == nil { 675 return nil 676 } 677 678 return &proto.HostsConfig{ 679 Hostname: cfg.Hostname, 680 Address: cfg.Address, 681 } 682 } 683 684 func hostsConfigFromProto(pb *proto.HostsConfig) *HostsConfig { 685 if pb == nil { 686 return nil 687 } 688 689 return &HostsConfig{ 690 Hostname: pb.Hostname, 691 Address: pb.Address, 692 } 693 } 694 695 func dnsConfigToProto(dns *DNSConfig) *proto.DNSConfig { 696 if dns == nil { 697 return nil 698 } 699 700 return &proto.DNSConfig{ 701 Servers: dns.Servers, 702 Searches: dns.Searches, 703 Options: dns.Options, 704 } 705 } 706 707 func dnsConfigFromProto(pb *proto.DNSConfig) *DNSConfig { 708 if pb == nil { 709 return nil 710 } 711 712 return &DNSConfig{ 713 Servers: pb.Servers, 714 Searches: pb.Searches, 715 Options: pb.Options, 716 } 717 }