code: def gather_node_details(
      band_slot_infos: Dict[str, List[WorkerSlotInfo]] = None,
      band_quota_infos: Dict[str, QuotaInfo] = None,
      disk_infos: List[DiskInfo] = None,
      band_storage_infos: Dict[
          str, Dict[StorageLevel, StorageInfo]
      ] = None,
  ):
      disk_io_usage = mars_resource.disk_io_usage()
      net_io_usage = mars_resource.net_io_usage()
      res = {
          "disk": dict(zip(("reads", "writes"), disk_io_usage))
          if disk_io_usage
          else dict(),
          "network": dict(zip(("receives", "sends"), net_io_usage))
          if net_io_usage
          else dict(),
          "iowait": mars_resource.iowait(),
      }
  
      if disk_infos:
          part_dict = dict()
          for info in disk_infos:
              part_dev = mars_resource.get_path_device(info.path)
              if part_dev in part_dict:
                  continue
  
              disk_usage_result = mars_resource.disk_usage(info.path)
              io_usage_result = mars_resource.disk_io_usage(info.path)
              part_dict[part_dev] = disk_info = {
                  "size_limit": info.limit_size,
                  "size_used": disk_usage_result.used,
                  "size_total": disk_usage_result.total,
              }
              if io_usage_result is not None:
                  disk_info.update(
                      {
                          "reads": io_usage_result.reads
                          if io_usage_result
                          else None,
                          "writes": io_usage_result.writes
                          if io_usage_result
                          else None,
                      }
                  )
              if not sys.platform.startswith("win"):
                  in_usage_result = os.statvfs(info.path)
                  disk_info.update(
                      {
                          "inode_used": in_usage_result.f_files
                          - in_usage_result.f_favail,
                          "inode_total": in_usage_result.f_files,
                      }
                  )
          res["disk"]["partitions"] = part_dict
  
      band_slot_infos = band_slot_infos or dict()
      res["slot"] = {
          band: [
              {
                  "slot_id": slot_info.slot_id,
                  "session_id": slot_info.session_id,
                  "subtask_id": slot_info.subtask_id,
                  "processor_usage": slot_info.processor_usage,
              }
              for slot_info in slot_infos
          ]
          for band, slot_infos in band_slot_infos.items()
      }
  
      band_quota_infos = band_quota_infos or dict()
      res["quota"] = {
          band: {
              "quota_size": quota_info.quota_size,
              "allocated_size": quota_info.allocated_size,
              "hold_size": quota_info.hold_size,
          }
          for band, quota_info in band_quota_infos.items()
      }
  
      band_storage_infos = band_storage_infos or dict()
      res["storage"] = {
          band: {
              level.name.lower(): {
                  "size_used": storage_info.used_size,
                  "size_total": storage_info.total_size,
                  "size_pinned": storage_info.pinned_size,
              }
              for level, storage_info in storage_infos.items()
          }
          for band, storage_infos in band_storage_infos.items()
      }
      return res
  
file_path: mars/mars/services/cluster/gather.py
imports: import logging
  import os
  import platform
  import socket
  import sys
  from typing import Dict, List
  import numpy
  import pandas
  from ...resource import Resource, ZeroResource
  from ...None import resource
  from ...config import options
  from ...utils import git_info, lazy_import
  from ...storage import StorageLevel
  from .core import WorkerSlotInfo, QuotaInfo, DiskInfo, StorageInfo
label_desc: Use image node_id 3 for calling a global function with example usage: gather_node_details(band_slot_infos, band_quota_infos, disk_infos, band_storage_infos) and returns: res