gpustack-runtime 0.1.41__tar.gz → 0.1.41.post1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/PKG-INFO +1 -1
  2. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/_version.py +2 -2
  3. gpustack_runtime-0.1.41.post1/gpustack_runtime/_version_appendix.py +1 -0
  4. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/cdi/__init__.py +1 -0
  5. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/cdi/__utils__.py +2 -0
  6. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/k8s/deviceplugin/__init__.py +87 -2
  7. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/k8s/deviceplugin/__types__.py +1 -1
  8. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/k8s/deviceplugin/plugin.py +9 -5
  9. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/kuberentes.py +20 -7
  10. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/envs.py +11 -9
  11. gpustack_runtime-0.1.41/gpustack_runtime/_version_appendix.py +0 -1
  12. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/.codespelldict +0 -0
  13. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/.codespellrc +0 -0
  14. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/.dockerignore +0 -0
  15. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/.gitattributes +0 -0
  16. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/.gitignore +0 -0
  17. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/.pre-commit-config.yaml +0 -0
  18. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/.python-version +0 -0
  19. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/LICENSE +0 -0
  20. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/Makefile +0 -0
  21. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/README.md +0 -0
  22. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/buf.gen.yaml +0 -0
  23. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/buf.lock +0 -0
  24. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/buf.yaml +0 -0
  25. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/deploy/manifests/docker-compose.yaml +0 -0
  26. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/deploy/manifests/kubernetes.yaml +0 -0
  27. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/docs/index.md +0 -0
  28. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/docs/modules/gpustack_runtime.deployer.md +0 -0
  29. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/docs/modules/gpustack_runtime.detector.md +0 -0
  30. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/docs/modules/gpustack_runtime.md +0 -0
  31. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/__init__.py +0 -0
  32. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/__main__.py +0 -0
  33. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/_version.pyi +0 -0
  34. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/cmds/__init__.py +0 -0
  35. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/cmds/__types__.py +0 -0
  36. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/cmds/deployer.py +0 -0
  37. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/cmds/detector.py +0 -0
  38. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/cmds/images.py +0 -0
  39. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/__init__.py +0 -0
  40. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/__patches__.py +0 -0
  41. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/__types__.py +0 -0
  42. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/__utils__.py +0 -0
  43. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/cdi/__types__.py +0 -0
  44. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/cdi/amd.py +0 -0
  45. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/cdi/ascend.py +0 -0
  46. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/cdi/hygon.py +0 -0
  47. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/cdi/iluvatar.py +0 -0
  48. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/cdi/metax.py +0 -0
  49. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/cdi/thead.py +0 -0
  50. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/docker.py +0 -0
  51. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/k8s/types/kubelet/deviceplugin/v1beta1/__init__.py +0 -0
  52. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/k8s/types/kubelet/deviceplugin/v1beta1/api.proto +0 -0
  53. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/k8s/types/kubelet/deviceplugin/v1beta1/api_pb2.py +0 -0
  54. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/k8s/types/kubelet/deviceplugin/v1beta1/api_pb2.pyi +0 -0
  55. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/k8s/types/kubelet/deviceplugin/v1beta1/api_pb2_grpc.py +0 -0
  56. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/k8s/types/kubelet/deviceplugin/v1beta1/constants.py +0 -0
  57. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/deployer/podman.py +0 -0
  58. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/__init__.py +0 -0
  59. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/__types__.py +0 -0
  60. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/__utils__.py +0 -0
  61. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/amd.py +0 -0
  62. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/ascend.py +0 -0
  63. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/cambricon.py +0 -0
  64. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/hygon.py +0 -0
  65. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/iluvatar.py +0 -0
  66. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/metax.py +0 -0
  67. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/mthreads.py +0 -0
  68. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/nvidia.py +0 -0
  69. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/pyacl/__init__.py +0 -0
  70. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/pyamdgpu/__init__.py +0 -0
  71. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/pyamdsmi/__init__.py +0 -0
  72. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/pycuda/__init__.py +0 -0
  73. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/pydcmi/__init__.py +0 -0
  74. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/pyhgml/__init__.py +0 -0
  75. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/pyhgml/libhgml.so +0 -0
  76. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/pyhgml/libuki.so +0 -0
  77. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/pyhsa/__init__.py +0 -0
  78. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/pyixml/__init__.py +0 -0
  79. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/pymxsml/__init__.py +0 -0
  80. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/pyrocmcore/__init__.py +0 -0
  81. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/pyrocmsmi/__init__.py +0 -0
  82. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/detector/thead.py +0 -0
  83. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/gpustack_runtime/logging.py +0 -0
  84. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/hatch.toml +0 -0
  85. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/mkdocs.yml +0 -0
  86. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/pack/Dockerfile +0 -0
  87. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/pack/Dockerfile.dummy +0 -0
  88. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/pyproject.toml +0 -0
  89. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/pytest.ini +0 -0
  90. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/ruff.toml +0 -0
  91. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/deployer/fixtures/__init__.py +0 -0
  92. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/deployer/fixtures/test_compare_versions.json +0 -0
  93. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/deployer/fixtures/test_correct_runner_image.json +0 -0
  94. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json.json +0 -0
  95. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json_multiple_jsons.json +0 -0
  96. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json_multiple_yamls.yaml +0 -0
  97. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json_single_json.json +0 -0
  98. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json_single_yaml.yaml +0 -0
  99. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/deployer/fixtures/test_nginx_entrypoint.sh +0 -0
  100. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/deployer/test_utils.py +0 -0
  101. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/fixtures/__init__.py +0 -0
  102. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/README.md +0 -0
  103. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/detect_output_amd_mi300x.json +0 -0
  104. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/detect_output_amd_mi308x.json +0 -0
  105. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/detect_output_amd_rx7800xt.json +0 -0
  106. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/detect_output_ascend_310p3.json +0 -0
  107. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/detect_output_ascend_910b2.json +0 -0
  108. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/detect_output_hygon_k100ai.json +0 -0
  109. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/detect_output_metax_c500.json +0 -0
  110. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_gb10.json +0 -0
  111. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_h100.json +0 -0
  112. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_h200.json +0 -0
  113. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_rtx4080super.json +0 -0
  114. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_rtx4090d.json +0 -0
  115. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_rtx5090d.json +0 -0
  116. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/detect_output_thead_ppu.json +0 -0
  117. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/topology_output_amd_mi300x.json +0 -0
  118. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/topology_output_amd_mi308x.json +0 -0
  119. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/topology_output_amd_rx7800xt.json +0 -0
  120. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/topology_output_ascend_310p3.json +0 -0
  121. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/topology_output_ascend_910b2.json +0 -0
  122. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/topology_output_hygon_k100ai.json +0 -0
  123. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/topology_output_metax_c500.json +0 -0
  124. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/topology_output_mthreads_s5000.json +0 -0
  125. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_h100.json +0 -0
  126. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_h200.json +0 -0
  127. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_rtx4080super.json +0 -0
  128. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_rtx4090d.json +0 -0
  129. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_rtx5090d.json +0 -0
  130. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/samples/topology_output_thead_ppu.json +0 -0
  131. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/test_amd.py +0 -0
  132. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/test_ascend.py +0 -0
  133. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/test_cambricon.py +0 -0
  134. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/test_hygon.py +0 -0
  135. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/test_iluvatar.py +0 -0
  136. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/test_metax.py +0 -0
  137. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/test_mthreads.py +0 -0
  138. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/tests/gpustack_runtime/detector/test_nvidia.py +0 -0
  139. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/uv.lock +0 -0
  140. {gpustack_runtime-0.1.41 → gpustack_runtime-0.1.41.post1}/uv.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gpustack-runtime
3
- Version: 0.1.41
3
+ Version: 0.1.41.post1
4
4
  Summary: GPUStack Runtime is library for detecting GPU resources and launching GPU workloads.
5
5
  Project-URL: Homepage, https://github.com/gpustack/runtime
6
6
  Project-URL: Bug Tracker, https://github.com/gpustack/gpustack/issues
@@ -27,8 +27,8 @@ version_tuple: VERSION_TUPLE
27
27
  __commit_id__: COMMIT_ID
28
28
  commit_id: COMMIT_ID
29
29
 
30
- __version__ = version = '0.1.41'
31
- __version_tuple__ = version_tuple = (0, 1, 41)
30
+ __version__ = version = '0.1.41.post1'
31
+ __version_tuple__ = version_tuple = (0, 1, 41, 'post1')
32
32
  try:
33
33
  from ._version_appendix import git_commit
34
34
  __commit_id__ = commit_id = git_commit
@@ -0,0 +1 @@
1
+ git_commit = "8671a00"
@@ -151,6 +151,7 @@ def available_backends() -> list[str]:
151
151
 
152
152
 
153
153
  __all__ = [
154
+ "Config",
154
155
  "available_backends",
155
156
  "available_manufacturers",
156
157
  "dump_config",
@@ -68,6 +68,8 @@ def linux_device_from_path(path: Path | str | None) -> LinuxDevice | None:
68
68
  return None
69
69
 
70
70
  path_stat = path.lstat()
71
+ if not path_stat:
72
+ return None
71
73
 
72
74
  dev_mode = stat.S_IFMT(path_stat.st_mode)
73
75
  match dev_mode:
@@ -4,12 +4,16 @@ import asyncio
4
4
  import contextlib
5
5
  import logging
6
6
  import signal
7
+ import stat
7
8
  import threading
8
- from typing import TYPE_CHECKING
9
+ from functools import lru_cache
10
+ from typing import TYPE_CHECKING, Literal
9
11
 
10
12
  from .... import envs
11
13
  from ....deployer.cdi import dump_config as cdi_dump_config
12
14
  from ....detector import ManufacturerEnum, detect_devices, supported_manufacturers
15
+ from ...cdi import Config, manufacturer_to_cdi_kind
16
+ from ..types.kubelet.deviceplugin.v1beta1 import KubeletSocket
13
17
  from .__types__ import GroupedError, PluginServer
14
18
  from .plugin import SharableDevicePlugin, cdi_kind_to_kdp_resource
15
19
 
@@ -61,9 +65,19 @@ async def serve_async(
61
65
  if not devices:
62
66
  continue
63
67
 
68
+ allocation_policy = _get_device_allocation_policy(manu)
69
+ logger.info(
70
+ "Using device allocation policy '%s' for manufacturer '%s'",
71
+ allocation_policy,
72
+ manu,
73
+ )
74
+
64
75
  # Also works if the manufacturer does not have a CDI generator,
65
76
  # which means we are relying on other tools to generate CDI specs.
66
- if envs.GPUSTACK_RUNTIME_KUBERNETES_KDP_CDI_SPECS_GENERATE:
77
+ if (
78
+ allocation_policy == "cdi"
79
+ and envs.GPUSTACK_RUNTIME_KUBERNETES_KDP_CDI_SPECS_GENERATE
80
+ ):
67
81
  generated_content, generated_path = cdi_dump_config(
68
82
  manufacturer=manu,
69
83
  output=cdi_generation_output,
@@ -95,6 +109,7 @@ async def serve_async(
95
109
  SharableDevicePlugin(
96
110
  device=dev,
97
111
  id_by="index" if manu == ManufacturerEnum.ASCEND else "uuid",
112
+ allocation_policy=allocation_policy,
98
113
  ),
99
114
  )
100
115
 
@@ -104,6 +119,9 @@ async def serve_async(
104
119
  logger.info("Stop event triggered, shutting down...")
105
120
  return
106
121
 
122
+ if not kubelet_endpoint:
123
+ kubelet_endpoint = KubeletSocket
124
+
107
125
  # Create tasks to start all servers.
108
126
  serve_tasks = [
109
127
  asyncio.create_task(
@@ -233,8 +251,75 @@ def serve(
233
251
  pass
234
252
 
235
253
 
254
+ def is_kubelet_socket_accessible(
255
+ kubelet_endpoint: Path | None = None,
256
+ ) -> bool:
257
+ """
258
+ Check if the kubelet socket is accessible.
259
+
260
+ Args:
261
+ kubelet_endpoint:
262
+ The path to the kubelet endpoint.
263
+
264
+ Returns:
265
+ True if the socket is accessible, False otherwise.
266
+
267
+ """
268
+ if not kubelet_endpoint:
269
+ kubelet_endpoint = KubeletSocket
270
+
271
+ if kubelet_endpoint.exists():
272
+ path_stat = kubelet_endpoint.lstat()
273
+ if path_stat and stat.S_ISSOCK(path_stat.st_mode):
274
+ return True
275
+ return False
276
+
277
+
278
+ @lru_cache
279
+ def _get_device_allocation_policy(
280
+ manufacturer: ManufacturerEnum,
281
+ ) -> Literal["env", "cdi", "opaque"]:
282
+ """
283
+ Get the device allocation policy (in lowercase) for the device plugin.
284
+
285
+ Args:
286
+ manufacturer:
287
+ The manufacturer of the device.
288
+
289
+ Returns:
290
+ The device allocation policy.
291
+
292
+ """
293
+ policy = envs.GPUSTACK_RUNTIME_KUBERNETES_KDP_DEVICE_ALLOCATION_POLICY.lower()
294
+ if policy != "auto":
295
+ return policy
296
+
297
+ cdi_kind = manufacturer_to_cdi_kind(manufacturer)
298
+
299
+ cdi_dir = envs.GPUSTACK_RUNTIME_DEPLOY_CDI_SPECS_DIRECTORY
300
+ for suffix in ["*.yaml", "*.yml", "*.json"]:
301
+ for file in cdi_dir.glob(suffix):
302
+ with contextlib.suppress(Exception):
303
+ config = Config.from_file(file)
304
+ if config and config.kind == cdi_kind:
305
+ return "cdi"
306
+
307
+ if manufacturer in [
308
+ ManufacturerEnum.AMD,
309
+ # ManufacturerEnum.ASCEND, # Prioritize using Env policy for Ascend.
310
+ ManufacturerEnum.HYGON,
311
+ ManufacturerEnum.ILUVATAR,
312
+ ManufacturerEnum.METAX,
313
+ ManufacturerEnum.THEAD,
314
+ ]:
315
+ return "opaque"
316
+
317
+ return "env"
318
+
319
+
236
320
  __all__ = [
237
321
  "cdi_kind_to_kdp_resource",
322
+ "is_kubelet_socket_accessible",
238
323
  "serve",
239
324
  "serve_async",
240
325
  ]
@@ -107,7 +107,7 @@ class PluginServer(ABC):
107
107
  async def serve(
108
108
  self,
109
109
  stop_event: asyncio.Event,
110
- kubelet_endpoint: Path | None = None,
110
+ kubelet_endpoint: Path,
111
111
  start_timeout: int = 5,
112
112
  register_timeout: int = 5,
113
113
  ):
@@ -31,7 +31,6 @@ from ..types.kubelet.deviceplugin.v1beta1 import (
31
31
  DeviceSpec,
32
32
  Empty,
33
33
  Healthy,
34
- KubeletSocket,
35
34
  ListAndWatchResponse,
36
35
  Mount,
37
36
  NUMANode,
@@ -110,6 +109,10 @@ class SharableDevicePlugin(PluginServer, DevicePluginServicer):
110
109
  """
111
110
  Controls how the device IDs of the Kubernetes Device Plugin are generated.
112
111
  """
112
+ _allocation_policy: Literal["env", "cdi", "opaque"]
113
+ """
114
+ Controls the device allocation policy.
115
+ """
113
116
  _max_allocations: int
114
117
  """
115
118
  Controls the maximum shards per underlying device.
@@ -131,6 +134,7 @@ class SharableDevicePlugin(PluginServer, DevicePluginServicer):
131
134
  self,
132
135
  device: Device,
133
136
  id_by: Literal["uuid", "index"] = "uuid",
137
+ allocation_policy: Literal["env", "cdi", "opaque"] = "cdi",
134
138
  max_allocations: int | None = None,
135
139
  ):
136
140
  """
@@ -142,6 +146,8 @@ class SharableDevicePlugin(PluginServer, DevicePluginServicer):
142
146
  id_by:
143
147
  Controls how the device IDs of the Kubernetes Device Plugin are generated.
144
148
  Either "uuid" or "index". Default is "uuid".
149
+ allocation_policy:
150
+ Controls the device allocation policy.
145
151
  max_allocations:
146
152
  Controls the maximum allocations per underlying device.
147
153
  If None, uses the environment variable `GPUSTACK_RUNTIME_KUBERNETES_KDP_PER_DEVICE_MAX_ALLOCATIONS`.
@@ -149,6 +155,7 @@ class SharableDevicePlugin(PluginServer, DevicePluginServicer):
149
155
  """
150
156
  self._device = device
151
157
  self._id_by = id_by
158
+ self._allocation_policy = allocation_policy
152
159
  self._max_allocations = max_allocations
153
160
  if not self._max_allocations:
154
161
  self._max_allocations = (
@@ -229,7 +236,7 @@ class SharableDevicePlugin(PluginServer, DevicePluginServicer):
229
236
  async def serve(
230
237
  self,
231
238
  stop_event: asyncio.Event,
232
- kubelet_endpoint: Path | None = None,
239
+ kubelet_endpoint: Path,
233
240
  start_timeout: int = 5,
234
241
  register_timeout: int = 5,
235
242
  ):
@@ -247,9 +254,6 @@ class SharableDevicePlugin(PluginServer, DevicePluginServicer):
247
254
  The timeout in seconds for registering the device plugin.
248
255
 
249
256
  """
250
- if not kubelet_endpoint:
251
- kubelet_endpoint = KubeletSocket
252
-
253
257
  resource_name = self._kdp_resource
254
258
  endpoint = kubelet_endpoint.parent / f"{resource_name.replace('/', '.')}.sock"
255
259
 
@@ -7,9 +7,9 @@ import operator
7
7
  import os
8
8
  from dataclasses import dataclass, field
9
9
  from enum import Enum
10
- from functools import reduce
10
+ from functools import lru_cache, reduce
11
11
  from pathlib import Path
12
- from typing import TYPE_CHECKING
12
+ from typing import TYPE_CHECKING, Literal
13
13
 
14
14
  import kubernetes
15
15
  import kubernetes.stream.ws_client
@@ -43,7 +43,7 @@ from .__utils__ import (
43
43
  sensitive_env_var,
44
44
  validate_rfc1123_domain_name,
45
45
  )
46
- from .k8s.deviceplugin import cdi_kind_to_kdp_resource
46
+ from .k8s.deviceplugin import cdi_kind_to_kdp_resource, is_kubelet_socket_accessible
47
47
 
48
48
  if TYPE_CHECKING:
49
49
  from collections.abc import Callable, Generator
@@ -381,6 +381,22 @@ class KubernetesDeployer(EndoscopicDeployer):
381
381
 
382
382
  return wrapper
383
383
 
384
+ @staticmethod
385
+ @lru_cache
386
+ def _get_resource_injection_policy() -> Literal["env", "kdp"]:
387
+ """
388
+ Get the resource injection policy (in lowercase) for the deployer.
389
+
390
+ Returns:
391
+ The resource injection policy.
392
+
393
+ """
394
+ policy = envs.GPUSTACK_RUNTIME_KUBERNETES_RESOURCE_INJECTION_POLICY.lower()
395
+ if policy != "auto":
396
+ return policy
397
+
398
+ return "kdp" if is_kubelet_socket_accessible() else "env"
399
+
384
400
  def _create_ephemeral_configmaps(
385
401
  self,
386
402
  workload: KubernetesWorkloadPlan,
@@ -992,10 +1008,7 @@ class KubernetesDeployer(EndoscopicDeployer):
992
1008
 
993
1009
  # Parameterize resources
994
1010
  if c.resources:
995
- kdp = (
996
- envs.GPUSTACK_RUNTIME_KUBERNETES_RESOURCE_INJECTION_POLICY.lower()
997
- == "kdp"
998
- )
1011
+ kdp = self._get_resource_injection_policy() == "kdp"
999
1012
 
1000
1013
  resources: dict[str, str] = {}
1001
1014
  r_k_runtime_env = workload.resource_key_runtime_env_mapping or {}
@@ -280,7 +280,8 @@ if TYPE_CHECKING:
280
280
  """
281
281
  GPUSTACK_RUNTIME_KUBERNETES_RESOURCE_INJECTION_POLICY: str | None = None
282
282
  """
283
- Resource injection policy for the Kubernetes deployer (e.g., Env, KDP).
283
+ Resource injection policy for the Kubernetes deployer (e.g., Auto, Env, KDP).
284
+ `Auto`: Automatically choose the resource injection policy based on the environment.
284
285
  `Env`: Injects resources using standard environment variable, depends on underlying Container Toolkit, based on `GPUSTACK_RUNTIME_DEPLOY_RESOURCE_KEY_MAP_RUNTIME_VISIBLE_DEVICES`.
285
286
  `KDP`: Injects resources using Kubernetes Device Plugin, based on `GPUSTACK_RUNTIME_DEPLOY_RESOURCE_KEY_MAP_CDI`.
286
287
  """
@@ -292,8 +293,9 @@ if TYPE_CHECKING:
292
293
  GPUSTACK_RUNTIME_KUBERNETES_KDP_DEVICE_ALLOCATION_POLICY: str | None = None
293
294
  """
294
295
  Device allocation policy for the Kubernetes Device Plugin (e.g., CDI, Env, Opaque).
295
- `CDI`: Allocates devices using generated CDI specifications, making it easy to debug and troubleshoot; requires `GPUSTACK_RUNTIME_DEPLOY_CDI_SPECS_DIRECTORY` to exist.
296
+ `Auto`: Automatically choose the device allocation policy based on the environment.
296
297
  `Env`: Allocates devices using runtime-visible environment variables; requires Container Toolkit support.
298
+ `CDI`: Allocates devices using generated CDI specifications, making it easy to debug and troubleshoot; requires `GPUSTACK_RUNTIME_DEPLOY_CDI_SPECS_DIRECTORY` to exist.
297
299
  `Opaque`: Uses internal logic for allocation, which is convenient for deployment but difficult to troubleshoot.
298
300
  """
299
301
  GPUSTACK_RUNTIME_KUBERNETES_KDP_CDI_SPECS_GENERATE: bool = True
@@ -685,8 +687,8 @@ variables: dict[str, Callable[[], Any]] = {
685
687
  getenv(
686
688
  "GPUSTACK_RUNTIME_KUBERNETES_RESOURCE_INJECTION_POLICY",
687
689
  ),
688
- options=["Env", "KDP"],
689
- default="Env",
690
+ options=["Auto", "Env", "KDP"],
691
+ default="Auto",
690
692
  ),
691
693
  "GPUSTACK_RUNTIME_KUBERNETES_KDP_PER_DEVICE_MAX_ALLOCATIONS": lambda: to_int(
692
694
  getenv(
@@ -698,12 +700,12 @@ variables: dict[str, Callable[[], Any]] = {
698
700
  getenv(
699
701
  "GPUSTACK_RUNTIME_KUBERNETES_KDP_DEVICE_ALLOCATION_POLICY",
700
702
  ),
701
- options=["CDI", "Env", "Opaque"],
702
- default="CDI",
703
+ options=["Auto", "Env", "CDI", "Opaque"],
704
+ default="Auto",
703
705
  ),
704
706
  "GPUSTACK_RUNTIME_KUBERNETES_KDP_CDI_SPECS_GENERATE": lambda: ternary(
705
707
  lambda: (
706
- getenv("GPUSTACK_RUNTIME_KUBERNETES_RESOURCE_INJECTION_POLICY", "Env")
708
+ getenv("GPUSTACK_RUNTIME_KUBERNETES_RESOURCE_INJECTION_POLICY", "Auto")
707
709
  == "Env"
708
710
  ),
709
711
  lambda: False,
@@ -711,9 +713,9 @@ variables: dict[str, Callable[[], Any]] = {
711
713
  lambda: (
712
714
  getenv(
713
715
  "GPUSTACK_RUNTIME_KUBERNETES_KDP_DEVICE_ALLOCATION_POLICY",
714
- "Opaque",
716
+ "Auto",
715
717
  )
716
- == "Opaque"
718
+ not in ["Auto", "CDI"]
717
719
  ),
718
720
  lambda: False,
719
721
  lambda: to_bool(
@@ -1 +0,0 @@
1
- git_commit = "f706cfd"