gpustack-runtime 0.2.5.post3__tar.gz → 0.2.6__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 (161) hide show
  1. gpustack_runtime-0.2.6/.agents/skills/runtime-release/SKILL.md +100 -0
  2. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/.gitignore +4 -1
  3. gpustack_runtime-0.2.6/ADOPTERS.md +12 -0
  4. gpustack_runtime-0.2.6/AGENTS.md +87 -0
  5. gpustack_runtime-0.2.6/DCO +34 -0
  6. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/LICENSE +1 -1
  7. gpustack_runtime-0.2.6/PKG-INFO +82 -0
  8. gpustack_runtime-0.2.6/README.md +55 -0
  9. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/_version.py +2 -2
  10. gpustack_runtime-0.2.6/gpustack_runtime/_version_appendix.py +1 -0
  11. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/__init__.py +3 -1
  12. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/k8s/devicemanager/__init__.py +56 -6
  13. gpustack_runtime-0.2.5.post3/gpustack_runtime/deployer/kuberentes.py → gpustack_runtime-0.2.6/gpustack_runtime/deployer/kubernetes.py +81 -13
  14. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/mkdocs.yml +1 -1
  15. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/pyproject.toml +1 -1
  16. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/specs/2026-08-14-detector-alignment-and-workload-exit-status.md +4 -4
  17. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/test_kubernetes_status.py +1 -1
  18. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/test_logs_options.py +2 -2
  19. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/test_privileged.py +1 -1
  20. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/test_resource_injection_policy.py +1 -1
  21. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/test_runtime_class.py +1 -1
  22. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/test_termination_grace_period.py +3 -3
  23. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/test_visible_devices_ordering.py +3 -3
  24. gpustack_runtime-0.2.6/tests/gpustack_runtime/deployer/test_workload_resource_injection_policy.py +347 -0
  25. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/test_workload_status.py +2 -2
  26. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/uv.lock +52 -30
  27. gpustack_runtime-0.2.5.post3/PKG-INFO +0 -64
  28. gpustack_runtime-0.2.5.post3/README.md +0 -37
  29. gpustack_runtime-0.2.5.post3/gpustack_runtime/_version_appendix.py +0 -1
  30. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/.codespelldict +0 -0
  31. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/.codespellrc +0 -0
  32. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/.dockerignore +0 -0
  33. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/.gitattributes +0 -0
  34. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/.pre-commit-config.yaml +0 -0
  35. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/.python-version +0 -0
  36. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/Makefile +0 -0
  37. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/deploy/manifests/docker-compose.yaml +0 -0
  38. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/deploy/manifests/kubernetes.yaml +0 -0
  39. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/docs/index.md +0 -0
  40. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/docs/modules/gpustack_runtime.deployer.md +0 -0
  41. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/docs/modules/gpustack_runtime.detector.md +0 -0
  42. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/docs/modules/gpustack_runtime.md +0 -0
  43. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/__init__.py +0 -0
  44. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/__main__.py +0 -0
  45. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/_version.pyi +0 -0
  46. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/cmds/__init__.py +0 -0
  47. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/cmds/__types__.py +0 -0
  48. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/cmds/deployer.py +0 -0
  49. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/cmds/detector.py +0 -0
  50. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/cmds/images.py +0 -0
  51. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/__patches__.py +0 -0
  52. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/__types__.py +0 -0
  53. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/__utils__.py +0 -0
  54. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/cdi/__init__.py +0 -0
  55. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/cdi/__types__.py +0 -0
  56. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/cdi/__utils__.py +0 -0
  57. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/cdi/amd.py +0 -0
  58. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/cdi/ascend.py +0 -0
  59. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/cdi/hygon.py +0 -0
  60. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/cdi/iluvatar.py +0 -0
  61. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/cdi/metax.py +0 -0
  62. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/cdi/thead.py +0 -0
  63. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/docker.py +0 -0
  64. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/deployer/podman.py +0 -0
  65. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/__init__.py +0 -0
  66. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/__types__.py +0 -0
  67. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/__utils__.py +0 -0
  68. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/amd.py +0 -0
  69. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/ascend.py +0 -0
  70. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/cambricon.py +0 -0
  71. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/hygon.py +0 -0
  72. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/iluvatar.py +0 -0
  73. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/metax.py +0 -0
  74. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/mthreads.py +0 -0
  75. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/nvidia.py +0 -0
  76. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/pyamdgpu/__init__.py +0 -0
  77. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/pyamdsmi/__init__.py +0 -0
  78. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/pycndev/__init__.py +0 -0
  79. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/pydcmi/__init__.py +0 -0
  80. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/pydmi/__init__.py +0 -0
  81. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/pyhgml/__init__.py +0 -0
  82. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/pyhgml/libhgml.so +0 -0
  83. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/pyhgml/libuki.so +0 -0
  84. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/pyhsa/__init__.py +0 -0
  85. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/pyixml/__init__.py +0 -0
  86. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/pymtml/__init__.py +0 -0
  87. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/pymxsml/__init__.py +0 -0
  88. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/pynvml/__init__.py +0 -0
  89. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/pyrocmsmi/__init__.py +0 -0
  90. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/detector/thead.py +0 -0
  91. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/envs.py +0 -0
  92. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/gpustack_runtime/logging.py +0 -0
  93. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/hatch.toml +0 -0
  94. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/pack/Dockerfile +0 -0
  95. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/pack/Dockerfile.dummy +0 -0
  96. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/pytest.ini +0 -0
  97. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/ruff.toml +0 -0
  98. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/fixtures/__init__.py +0 -0
  99. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/fixtures/test_compare_versions.json +0 -0
  100. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/fixtures/test_correct_runner_image.json +0 -0
  101. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json.json +0 -0
  102. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json_multiple_jsons.json +0 -0
  103. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json_multiple_yamls.yaml +0 -0
  104. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json_single_json.json +0 -0
  105. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json_single_yaml.yaml +0 -0
  106. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/fixtures/test_nginx_entrypoint.sh +0 -0
  107. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/test_ascend_ranktable.py +0 -0
  108. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/test_docker_status.py +0 -0
  109. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/test_podman_status.py +0 -0
  110. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/deployer/test_utils.py +0 -0
  111. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/fixtures/__init__.py +0 -0
  112. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/README.md +0 -0
  113. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_amd_mi300x.json +0 -0
  114. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_amd_mi308x.json +0 -0
  115. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_amd_rx7800xt.json +0 -0
  116. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_ascend_310p3.json +0 -0
  117. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_ascend_910b2.json +0 -0
  118. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_hygon_k100ai.json +0 -0
  119. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_metax_c500.json +0 -0
  120. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_gb10.json +0 -0
  121. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_h100.json +0 -0
  122. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_h100_mig.json +0 -0
  123. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_h200.json +0 -0
  124. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_rtx4080super.json +0 -0
  125. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_rtx4090_48g.json +0 -0
  126. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_rtx4090d.json +0 -0
  127. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_rtx5090d.json +0 -0
  128. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/detect_output_thead_ppu.json +0 -0
  129. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_amd_mi300x.json +0 -0
  130. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_amd_mi308x.json +0 -0
  131. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_amd_rx7800xt.json +0 -0
  132. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_ascend_310p3.json +0 -0
  133. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_ascend_910b2.json +0 -0
  134. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_hygon_k100ai.json +0 -0
  135. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_metax_c500.json +0 -0
  136. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_mthreads_s5000.json +0 -0
  137. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_h100.json +0 -0
  138. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_h100_mig.json +0 -0
  139. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_h200.json +0 -0
  140. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_rtx4080super.json +0 -0
  141. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_rtx4090_48g.json +0 -0
  142. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_rtx4090d.json +0 -0
  143. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_rtx5090d.json +0 -0
  144. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/samples/topology_output_thead_ppu.json +0 -0
  145. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_amd.py +0 -0
  146. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_ascend.py +0 -0
  147. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_cambricon.py +0 -0
  148. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_detector_cli.py +0 -0
  149. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_detector_types.py +0 -0
  150. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_detector_utils.py +0 -0
  151. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_hygon.py +0 -0
  152. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_iluvatar.py +0 -0
  153. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_metax.py +0 -0
  154. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_mig_devices.py +0 -0
  155. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_mthreads.py +0 -0
  156. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_nvidia.py +0 -0
  157. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_pycndev.py +0 -0
  158. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_pydmi.py +0 -0
  159. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_samples.py +0 -0
  160. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/tests/gpustack_runtime/detector/test_thead.py +0 -0
  161. {gpustack_runtime-0.2.5.post3 → gpustack_runtime-0.2.6}/uv.toml +0 -0
@@ -0,0 +1,100 @@
1
+ ---
2
+ name: runtime-release
3
+ description: Cut a gpustack-runtime package release end to end (select and push the tag, monitor the release workflow, curate the GitHub Release notes).
4
+ ---
5
+
6
+ # Runtime release
7
+
8
+ One maintainer duty: cut a package release. Push a version tag; `release.yml` builds and publishes
9
+ it. Then write the GitHub Release notes.
10
+
11
+ ## Cut a package release
12
+
13
+ The git tag is the single source of truth: hatch-vcs derives the package version from it at build
14
+ time, and there is no version file to bump. Pushing a `v*.*.*` tag runs
15
+ `.github/workflows/release.yml`: build the distributions, create the GitHub Release with the
16
+ wheel/sdist assets, publish to PyPI, then verify an isolated install. Branch pushes to `main` or
17
+ `v*-dev` run the same job against TestPyPI and create no release.
18
+
19
+ Two workflow facts shape the procedure:
20
+
21
+ - The GitHub Release is a pre-release only when the tag contains `rc`. A final tag goes public and
22
+ becomes `latest` immediately. There is no promotion gate.
23
+ - The workflow generates no baseline notes. The release body starts empty, so curating the notes is
24
+ not polish; it is the entire text the reader gets.
25
+
26
+ PyPI is the irreversible step: a version once published there cannot be re-uploaded or edited.
27
+
28
+ ### Hard rules
29
+
30
+ - Tag shapes: `vX.Y.Z` final, `vX.Y.ZrcN` pre-release, `vX.Y.Z.postN` post-release. PEP 440
31
+ canonical spellings only; history contains the non-dotted `v0.2.5postN` — do not repeat it.
32
+ - A tag whose PyPI publish succeeded is burned. NEVER delete or move it; fix forward with a new
33
+ version. Delete-and-recreate is limited to a tag that never reached PyPI and is interactive-only.
34
+ - An `rc` tag stays a pre-release; never mark it latest.
35
+ - Release from `origin/main` HEAD by default. A maintenance line (`v*-dev` branch) targets that
36
+ branch's HEAD; flag the choice in the summary.
37
+ - Interactive mode confirms every mutating step (tag push, note replacement). Auto mode runs
38
+ unattended through note curation and reports the release URL.
39
+
40
+ ### 1. Preflight (read-only)
41
+
42
+ ```sh
43
+ gh auth status
44
+ git fetch origin --tags --prune
45
+ git status --porcelain # must be empty
46
+ git tag -l 'v*' --sort=-v:refname | head -5
47
+ ```
48
+
49
+ ### 2. Version and commit (confirm)
50
+
51
+ - Pick the target ref: `origin/main` by default, or the `v*-dev` branch for a maintenance line. The
52
+ steps below call it `$TARGET`; `$SHA` is its HEAD (`git rev-parse "$TARGET"`).
53
+ - Read the range since the previous tag: `git log --no-merges --oneline <last>..$TARGET`.
54
+ - Propose the bump from the Conventional Commits in range: any `feat` → minor; fixes, docs, and
55
+ chores → patch. Use `.postN` only to re-issue the same version line (packaging metadata or a
56
+ docs-only rebuild of unchanged content).
57
+ - Confirm the (version, commit) pair before tagging. A final tag publishes immediately, so this
58
+ confirmation is the only gate.
59
+
60
+ ### 3. Draft notes
61
+
62
+ Group the range by type: Features / Fixes / Docs / Other; omit empty sections. Keep highlights and
63
+ fold noisy `chore`/`ci`/`test` entries. Link PRs from `(#NNN)` subjects. Do not open the body with
64
+ a heading that repeats the tag. End with the Full Changelog compare URL
65
+ (`https://github.com/gpustack/runtime/compare/<last>...<VER>`). Write the draft to `notes.md`;
66
+ step 5 publishes that file.
67
+
68
+ ### 4. Tag and monitor (confirm, then read-only)
69
+
70
+ ```sh
71
+ git tag -a "$VER" "$SHA" -m "Release $VER"
72
+ git push origin "$VER"
73
+ gh run list --branch "$VER" --limit 5 # the release.yml run for the tag
74
+ gh run watch <run-id> --exit-status # background it; wait for the completion notification
75
+ ```
76
+
77
+ The job's own verify step installs the package from PyPI in an isolated env, but it is unpinned and
78
+ only prints the installed version. A green run proves the upload succeeded, not that PyPI already
79
+ serves the new version; read the verify log's `version =` line and confirm it equals `$VER`. On
80
+ failure read `gh run view <run-id> --log-failed`; retry the same run on transient errors. If the
81
+ failure is real and PyPI already holds the version, cut the next version instead — never re-tag.
82
+
83
+ ### 5. Curate notes (confirm)
84
+
85
+ ```sh
86
+ gh release view "$VER" --json body,isPrerelease # the body starts empty
87
+ gh release edit "$VER" --notes-file notes.md
88
+ ```
89
+
90
+ A maintenance-line final keeps `--latest=false` when a newer stable tag exists. Verify the badge
91
+ with `gh api repos/gpustack/runtime/releases/latest --jq .tag_name`. An `rc` release stays a
92
+ pre-release and needs no further action.
93
+
94
+ ## Scope
95
+
96
+ Package releases and their notes run here. No other repository document changes with a release:
97
+ the version comes from the tag, and no README or docs table tracks it. Container image builds are
98
+ `make package` (`pack/`) and deployment manifests live in `deploy/`; both are outside this skill.
99
+ Docs-only changes never trigger a release: the release workflow ignores docs paths on branch
100
+ pushes, so docs updates need no tag.
@@ -3,7 +3,10 @@
3
3
  .vscode/
4
4
  .DS_Store
5
5
  *.swp
6
- .claude/
6
+ **/.claude/*
7
+ !/.claude/skills
8
+ /.claude/skills/*
9
+ !/.claude/skills/runtime-release
7
10
 
8
11
  # Python-generated files
9
12
  _version.py
@@ -0,0 +1,12 @@
1
+ # Who's using GPUStack Runtime
2
+
3
+ GPUStack Runtime is used by a growing range of companies and projects to detect accelerator (GPU/NPU) resources and run accelerator workloads on Docker, Kubernetes and Podman.
4
+
5
+ If you are using GPUStack Runtime and your name is not on this list, please send us a PR!
6
+
7
+ ## Companies/Projects using GPUStack Runtime in production
8
+
9
+ These companies and projects are using GPUStack Runtime in production. If your company is using GPUStack Runtime, open a PR to add your company or project name and a description of how you are using GPUStack Runtime.
10
+
11
+ | Company / Project | Use Case |
12
+ | --- | --- |
@@ -0,0 +1,87 @@
1
+ # GPUStack Runtime
2
+
3
+ A Python library with a unified interface for detecting accelerator (GPU/NPU) resources and
4
+ launching and managing GPU workloads on Docker, Kubernetes and Podman.
5
+
6
+ ## Project Structure
7
+
8
+ - `gpustack_runtime/` — the library.
9
+ - `detector/` — one detector per vendor (`nvidia.py`, `amd.py`, `ascend.py`, `cambricon.py`,
10
+ `hygon.py`, `iluvatar.py`, `metax.py`, `mthreads.py`, `thead.py`), plus the `py*` packages,
11
+ ctypes bindings to vendor management libraries (`pynvml`, `pydcmi`, `pycndev`, ...).
12
+ - `deployer/` — one deployer per container runtime (`docker.py`, `kubernetes.py`, `podman.py`),
13
+ `cdi/` for vendor CDI spec handling, `k8s/` for Kubernetes helpers, and `__patches__.py` for
14
+ the vendored Podman client patch.
15
+ - `cmds/` — CLI subcommands behind the `gpustack-runtime` entrypoint (`__main__.py`).
16
+ - `envs.py` — environment variables; `logging.py` — logging helpers.
17
+ - `tests/gpustack_runtime/` — pytest suite mirroring the package; `detector/samples/` holds
18
+ captured vendor-tool outputs used as fixtures.
19
+ - `docs/` — MkDocs site; `docs/modules/` is API reference rendered from docstrings by
20
+ mkdocstrings.
21
+ - `specs/` — design records.
22
+ - `pack/` / `deploy/` — container image build and deployment manifests.
23
+
24
+ ## Architecture
25
+
26
+ Detection: each vendor detector in `gpustack_runtime/detector/` probes its vendor library through
27
+ the matching `py*` binding and reports `Device`s with topology. `detector/__init__.py` owns the
28
+ registry (`_DETECTORS`) and the aggregate entry points (`supported_list()`, `detect_devices()`).
29
+
30
+ Deployment: `deployer/__init__.py` owns the registry (`_DEPLOYERS`) and picks the first available
31
+ runtime (Docker, Kubernetes, Podman). A `WorkloadPlan` describes the desired containers; the
32
+ deployer injects vendor resources (CDI devices, environment variables, mounts) and returns a
33
+ workload handle for inspect/logs/exec/delete. Shared types live in `deployer/__types__.py`,
34
+ including the `OperationError` / `UnsupportedError` error contract.
35
+
36
+ ## Finding sources
37
+
38
+ - Confirm the checkout, branch and uncommitted changes before reasoning about behavior. The
39
+ published wheel or a merged PR may describe a different revision.
40
+ - Docstrings are the usage contract: `make docs` renders them into `site/`. Specs under
41
+ `specs/` own design rationale; current code establishes what this checkout implements. Report
42
+ disagreement rather than silently choosing one.
43
+ - For a vendor behavior claim, read the matching `py*` binding and the detector tests under
44
+ `tests/gpustack_runtime/detector/`; captured outputs live in `detector/samples/`.
45
+ - For a concrete error, search its stable text locally first. When it concerns an upstream
46
+ dependency (docker, kubernetes, podman clients), check that project's issues and pinned version
47
+ in `pyproject.toml` / `uv.lock`.
48
+
49
+ ## Development
50
+
51
+ Setup is `make install` (uv sync plus pre-commit hooks). Day-to-day targets:
52
+
53
+ - `make lint` — pre-commit on all files: ruff check/format, codespell, commitizen.
54
+ - `make test` — pytest.
55
+ - `make docs` — build the MkDocs site into `site/` (git-ignored).
56
+ - `make build` — build wheel and sdist into `dist/` (git-ignored).
57
+ - `make package` — build the container image with docker buildx; `PACKAGE_PUSH=true` pushes.
58
+
59
+ `gpustack_runtime/_version.py` is generated by hatch-vcs and `_version_appendix.py` by
60
+ `make prepare`; never hand-edit either.
61
+
62
+ Cut package releases with the [runtime-release](.agents/skills/runtime-release/SKILL.md) skill.
63
+
64
+ ### Python conventions
65
+
66
+ - Prefer clarity over cleverness to simplify long-term maintenance.
67
+ - Start every package module with `from __future__ import annotations as __future_annotations__`.
68
+ - Follow the ruff configuration in `ruff.toml`; run `make lint` whenever modifying Python source.
69
+ - Type-annotate public APIs and re-export them from the package `__init__.py` (`__all__`).
70
+ - Write Google-style docstrings; they render into the published API reference.
71
+ - Handle errors explicitly. Deployers raise `OperationError` or `UnsupportedError` from
72
+ `deployer.__types__` instead of leaking runtime-client exceptions. Detectors degrade to an
73
+ empty result and log at debug level rather than failing on a host without that vendor.
74
+ - Keep private helpers in double-underscore modules (`__types__.py`, `__utils__.py`); import them
75
+ through the package, not across subpackages.
76
+ - Keep concurrency simple, safe and justified; minimize mutable shared state.
77
+ - Keep comments plain and short: no emoji, no decorative symbols. State the point in words.
78
+
79
+ ### Testing conventions
80
+
81
+ - pytest; tests mirror the package layout under `tests/gpustack_runtime/`.
82
+ - Never require real hardware or a real container runtime. Detector tests fake the `py*` vendor
83
+ binding in the test module; deployer tests fake the runtime client.
84
+ - Reuse captured vendor outputs from `tests/gpustack_runtime/detector/samples/` and shared
85
+ fixtures from `fixtures/` instead of inventing new sample data.
86
+ - Verify one behavior or contract per test; assert observable state, not implementation details.
87
+ - Keep tests deterministic and repeatable: no wall-clock, ordering or randomness dependence.
@@ -0,0 +1,34 @@
1
+ Developer Certificate of Origin
2
+ Version 1.1
3
+
4
+ Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
5
+
6
+ Everyone is permitted to copy and distribute verbatim copies of this
7
+ license document, but changing it is not allowed.
8
+
9
+
10
+ Developer's Certificate of Origin 1.1
11
+
12
+ By making a contribution to this project, I certify that:
13
+
14
+ (a) The contribution was created in whole or in part by me and I
15
+ have the right to submit it under the open source license
16
+ indicated in the file; or
17
+
18
+ (b) The contribution is based upon previous work that, to the best
19
+ of my knowledge, is covered under an appropriate open source
20
+ license and I have the right under that license to submit that
21
+ work with modifications, whether created in whole or in part
22
+ by me, under the same open source license (unless I am
23
+ permitted to submit under a different license), as indicated
24
+ in the file; or
25
+
26
+ (c) The contribution was provided directly to me by some other
27
+ person who certified (a), (b) or (c) and I have not modified
28
+ it.
29
+
30
+ (d) I understand and agree that this project and the contribution
31
+ are public and that a record of the contribution (including all
32
+ personal information I submit with it, including my sign-off) is
33
+ maintained indefinitely and may be redistributed consistent with
34
+ this project or the open source license(s) involved.
@@ -175,7 +175,7 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
175
175
 
176
176
  END OF TERMS AND CONDITIONS
177
177
 
178
- Copyright (c) 2025 The GPUStack Authors
178
+ Copyright (c) 2026 The GPUStack Authors
179
179
 
180
180
  Licensed under the Apache License, Version 2.0 (the "License");
181
181
  you may not use this file except in compliance with the License.
@@ -0,0 +1,82 @@
1
+ Metadata-Version: 2.5
2
+ Name: gpustack-runtime
3
+ Version: 0.2.6
4
+ Summary: GPUStack Runtime is library for detecting GPU resources and launching GPU workloads.
5
+ Project-URL: Homepage, https://github.com/gpustack/runtime
6
+ Project-URL: Bug Tracker, https://github.com/gpustack/gpustack/issues
7
+ Author-email: GPUStack Authors <contact@gpustack.ai>
8
+ License-Expression: Apache-2.0
9
+ License-File: LICENSE
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Python: >=3.10
16
+ Requires-Dist: argcomplete>=3.6.3
17
+ Requires-Dist: cachetools>=5.5.2
18
+ Requires-Dist: docker>=7.1.0
19
+ Requires-Dist: gpustack-runner>=0.1.31
20
+ Requires-Dist: kubernetes>=33.1.0
21
+ Requires-Dist: mthreads-ml-py>=2.2.10
22
+ Requires-Dist: nvidia-ml-py>=13.580.65
23
+ Requires-Dist: podman==5.6.0
24
+ Requires-Dist: pyyaml
25
+ Requires-Dist: tqdm
26
+ Description-Content-Type: text/markdown
27
+
28
+ # GPUStack Runtime
29
+
30
+ [![License](https://img.shields.io/github/license/gpustack/runtime?logo=apache&label=License)](./LICENSE)
31
+ [![PyPI](https://img.shields.io/pypi/v/gpustack-runtime?logo=pypi&label=PyPI)](https://pypi.org/project/gpustack-runtime/)
32
+ [![Latest Release](https://img.shields.io/github/v/release/gpustack/runtime?logo=semanticrelease&label=Release&include_prereleases)](https://github.com/gpustack/runtime/releases/latest)
33
+ [![Docker Pulls](https://img.shields.io/docker/pulls/gpustack/runtime?logo=docker&logoColor=fff&label=Docker%20Pulls)](https://hub.docker.com/r/gpustack/runtime)
34
+ [![Ask DeepWiki](https://img.shields.io/badge/Ask_DeepWiki-purple?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAPoAAAD6AG1e1JrAAACIUlEQVRYw+2XP2gUQRTGv7d3JhYWQawkIBaCVWzETos0gmAnVoKNTSoLK0E7EQQrC20sBVFBtLPQRgTBtBaKjYgIQUSxiJq7fT+LvCGPJZdNLt4dQj5Y3u7sznzfzLw/s9IO/icANiniCujEfWdsQgBLxAbsbraPZcmBfcAt4DNwKQsZNfEUsAB8YRV12LfA6ZHuedg7AO7ed/c+UBcbQhbiu+6wXIM6EnZWkszMJe2Ke0n6I2la0v51hFeSMLN6OwIK6jJwEBdUYb2MAxRSz6sY4geiahFgLe1Hwq6YWe3us8AN4FQQU4QM64SPY69Xyr43fADgNjAPXHb3peSsD4FDQ0VLEjAHvIhBPS6AHvA1bBO9JPAXcHFbIRtJ5yzwIQZ9CZwAusDJENIkLqsG8DpNyIZJwSUk9wLHgakcesC1JCCjiHm1kYDNOEjptCxpSVK/8f73OFLxPLAYM3oCzEX7MXf/lJbc/8kWpA4HgQdpYI9IWAbeh83whi84cHXL+58EPBoQhnmm94EzwE3gZ2p/Dhzdbhg+TaRr01x7ftb4/jBwFzjXrCvDpmLW9crVLNeR9CaapoGemb2TdCERW1tNaBNQ8jktwmozqwtpqRNtdWAjARYk39IS12ZWRX7vmJmA71nQZgi36gN7gCvAj5xc3P0jcH7kx7Ik5IC73wsh14GZsZySow5002l4Jr0b6+m4eSyvpAn8lEzsx2QHo8RfUrlN+uPq4ksAAAAASUVORK5CYII=)](https://deepwiki.com/gpustack/runtime)
35
+
36
+ GPUStack Runtime offers a unified interface for detecting GPU resources and managing GPU workloads.
37
+
38
+ ## Features
39
+
40
+ - Detect a wide range of GPU and accelerator resources:
41
+
42
+ - AMD GPU
43
+ - Ascend NPU
44
+ - Cambricon MLU
45
+ - Hygon DCU
46
+ - Iluvatar GPU
47
+ - MetaX GPU
48
+ - Moore Threads GPU
49
+ - NVIDIA GPU
50
+ - T-Head PPU
51
+
52
+ - Manage GPU workloads on the following platforms:
53
+
54
+ - Docker
55
+ - Kubernetes
56
+ - Podman (>=4.9, experimental support via the `CONTAINER_HOST=http+unix:///path/to/podman/socket` environment variable)
57
+
58
+ Contributions to support additional GPU resources are welcome!
59
+
60
+ ## Installation
61
+
62
+ ```bash
63
+ pip install gpustack-runtime
64
+ ```
65
+
66
+ ## Documentation
67
+
68
+ The API reference renders from docstrings. Build the site locally with `make docs` and open
69
+ `site/index.html`.
70
+
71
+ ## Contributing
72
+
73
+ Contributions are welcome. Commits must carry a `Signed-off-by` line certifying the
74
+ [Developer Certificate of Origin](./DCO).
75
+
76
+ Using GPUStack Runtime in production? Add your company or project to [ADOPTERS.md](./ADOPTERS.md)
77
+ via pull request.
78
+
79
+ ## License
80
+
81
+ Copyright (c) 2026 The GPUStack Authors. Licensed under the
82
+ [Apache License 2.0](./LICENSE).
@@ -0,0 +1,55 @@
1
+ # GPUStack Runtime
2
+
3
+ [![License](https://img.shields.io/github/license/gpustack/runtime?logo=apache&label=License)](./LICENSE)
4
+ [![PyPI](https://img.shields.io/pypi/v/gpustack-runtime?logo=pypi&label=PyPI)](https://pypi.org/project/gpustack-runtime/)
5
+ [![Latest Release](https://img.shields.io/github/v/release/gpustack/runtime?logo=semanticrelease&label=Release&include_prereleases)](https://github.com/gpustack/runtime/releases/latest)
6
+ [![Docker Pulls](https://img.shields.io/docker/pulls/gpustack/runtime?logo=docker&logoColor=fff&label=Docker%20Pulls)](https://hub.docker.com/r/gpustack/runtime)
7
+ [![Ask DeepWiki](https://img.shields.io/badge/Ask_DeepWiki-purple?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAPoAAAD6AG1e1JrAAACIUlEQVRYw+2XP2gUQRTGv7d3JhYWQawkIBaCVWzETos0gmAnVoKNTSoLK0E7EQQrC20sBVFBtLPQRgTBtBaKjYgIQUSxiJq7fT+LvCGPJZdNLt4dQj5Y3u7sznzfzLw/s9IO/icANiniCujEfWdsQgBLxAbsbraPZcmBfcAt4DNwKQsZNfEUsAB8YRV12LfA6ZHuedg7AO7ed/c+UBcbQhbiu+6wXIM6EnZWkszMJe2Ke0n6I2la0v51hFeSMLN6OwIK6jJwEBdUYb2MAxRSz6sY4geiahFgLe1Hwq6YWe3us8AN4FQQU4QM64SPY69Xyr43fADgNjAPXHb3peSsD4FDQ0VLEjAHvIhBPS6AHvA1bBO9JPAXcHFbIRtJ5yzwIQZ9CZwAusDJENIkLqsG8DpNyIZJwSUk9wLHgakcesC1JCCjiHm1kYDNOEjptCxpSVK/8f73OFLxPLAYM3oCzEX7MXf/lJbc/8kWpA4HgQdpYI9IWAbeh83whi84cHXL+58EPBoQhnmm94EzwE3gZ2p/Dhzdbhg+TaRr01x7ftb4/jBwFzjXrCvDpmLW9crVLNeR9CaapoGemb2TdCERW1tNaBNQ8jktwmozqwtpqRNtdWAjARYk39IS12ZWRX7vmJmA71nQZgi36gN7gCvAj5xc3P0jcH7kx7Ik5IC73wsh14GZsZySow5002l4Jr0b6+m4eSyvpAn8lEzsx2QHo8RfUrlN+uPq4ksAAAAASUVORK5CYII=)](https://deepwiki.com/gpustack/runtime)
8
+
9
+ GPUStack Runtime offers a unified interface for detecting GPU resources and managing GPU workloads.
10
+
11
+ ## Features
12
+
13
+ - Detect a wide range of GPU and accelerator resources:
14
+
15
+ - AMD GPU
16
+ - Ascend NPU
17
+ - Cambricon MLU
18
+ - Hygon DCU
19
+ - Iluvatar GPU
20
+ - MetaX GPU
21
+ - Moore Threads GPU
22
+ - NVIDIA GPU
23
+ - T-Head PPU
24
+
25
+ - Manage GPU workloads on the following platforms:
26
+
27
+ - Docker
28
+ - Kubernetes
29
+ - Podman (>=4.9, experimental support via the `CONTAINER_HOST=http+unix:///path/to/podman/socket` environment variable)
30
+
31
+ Contributions to support additional GPU resources are welcome!
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ pip install gpustack-runtime
37
+ ```
38
+
39
+ ## Documentation
40
+
41
+ The API reference renders from docstrings. Build the site locally with `make docs` and open
42
+ `site/index.html`.
43
+
44
+ ## Contributing
45
+
46
+ Contributions are welcome. Commits must carry a `Signed-off-by` line certifying the
47
+ [Developer Certificate of Origin](./DCO).
48
+
49
+ Using GPUStack Runtime in production? Add your company or project to [ADOPTERS.md](./ADOPTERS.md)
50
+ via pull request.
51
+
52
+ ## License
53
+
54
+ Copyright (c) 2026 The GPUStack Authors. Licensed under the
55
+ [Apache License 2.0](./LICENSE).
@@ -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.2.5.post3'
31
- __version_tuple__ = version_tuple = (0, 2, 5, 'post3')
30
+ __version__ = version = '0.2.6'
31
+ __version_tuple__ = version_tuple = (0, 2, 6)
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 = "66c3e8f"
@@ -36,7 +36,8 @@ from .docker import (
36
36
  DockerWorkloadPlan,
37
37
  DockerWorkloadStatus,
38
38
  )
39
- from .kuberentes import (
39
+ from .k8s.devicemanager import KubernetesResourceInjectionPolicyEnum
40
+ from .kubernetes import (
40
41
  KubernetesDeployer,
41
42
  KubernetesWorkloadPlan,
42
43
  KubernetesWorkloadStatus,
@@ -595,6 +596,7 @@ __all__ = [
595
596
  "ContainerSecurity",
596
597
  "DockerWorkloadPlan",
597
598
  "DockerWorkloadStatus",
599
+ "KubernetesResourceInjectionPolicyEnum",
598
600
  "KubernetesWorkloadPlan",
599
601
  "KubernetesWorkloadStatus",
600
602
  "OperationError",
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations as __future_annotations__
2
2
 
3
3
  import stat
4
+ from enum import Enum
4
5
  from functools import lru_cache
5
6
  from pathlib import Path
6
7
  from typing import TYPE_CHECKING, Any, Literal
@@ -11,6 +12,36 @@ if TYPE_CHECKING:
11
12
  from collections.abc import Callable, Mapping
12
13
 
13
14
 
15
+ class KubernetesResourceInjectionPolicyEnum(str, Enum):
16
+ """
17
+ Device injection policies for Kubernetes workloads.
18
+ """
19
+
20
+ AUTO = "Auto"
21
+ """
22
+ Detect the policy from the target node's allocatable resources.
23
+ """
24
+ ENV = "Env"
25
+ """
26
+ Inject runtime-visible device environment variables without device-plugin requests.
27
+ """
28
+ KDP = "KDP"
29
+ """
30
+ Request device-plugin resources.
31
+ """
32
+
33
+ @classmethod
34
+ def _missing_(cls, value: object) -> KubernetesResourceInjectionPolicyEnum | None:
35
+ if isinstance(value, str):
36
+ for member in cls:
37
+ if member.value.lower() == value.lower():
38
+ return member
39
+ return None
40
+
41
+ def __str__(self) -> str:
42
+ return self.value
43
+
44
+
14
45
  def is_kubelet_socket_accessible(
15
46
  kubelet_endpoint: Path | None = None,
16
47
  ) -> bool:
@@ -79,13 +110,16 @@ def node_has_device_plugin_resources(
79
110
 
80
111
  def get_resource_injection_policy(
81
112
  probe_node_allocatable: Callable[[], Mapping[str, Any] | None] | None = None,
113
+ *,
114
+ policy: KubernetesResourceInjectionPolicyEnum | None = None,
82
115
  ) -> Literal["env", "kdp"]:
83
116
  """
84
117
  Get the resource injection policy (in lowercase) for the deployer.
85
118
 
86
- An explicit policy always wins. Under "auto" the decision belongs to the
87
- cluster, not to the process doing the deploying: the Kubernetes deployer
88
- orchestrates remotely, so whether *it* can reach a kubelet socket says
119
+ A workload policy overrides the environment setting. Under "auto" the
120
+ decision belongs to the cluster, not to the process doing the deploying:
121
+ the Kubernetes deployer orchestrates remotely, so whether *it* can reach
122
+ a kubelet socket says
89
123
  nothing about whether the *target* node runs a device plugin. So the probe
90
124
  reads that node's allocatable resources and looks for a device-plugin
91
125
  resource family there.
@@ -99,14 +133,29 @@ def get_resource_injection_policy(
99
133
  probe_node_allocatable:
100
134
  Called only under the "auto" policy, to read the target node's
101
135
  allocatable resources. Returns None when the node cannot be read.
136
+ policy:
137
+ Workload policy override. None inherits the environment setting;
138
+ Auto probes the node even if the environment selects Env or KDP.
139
+
140
+ Raises:
141
+ ValueError:
142
+ If the policy is not Auto, Env or KDP.
102
143
 
103
144
  Returns:
104
145
  The resource injection policy.
105
146
 
106
147
  """
107
- policy = envs.GPUSTACK_RUNTIME_KUBERNETES_RESOURCE_INJECTION_POLICY.lower()
108
- if policy != "auto":
109
- return policy
148
+ if policy is None:
149
+ policy = envs.GPUSTACK_RUNTIME_KUBERNETES_RESOURCE_INJECTION_POLICY
150
+ try:
151
+ policy = KubernetesResourceInjectionPolicyEnum(policy)
152
+ except ValueError as e:
153
+ msg = f"Invalid resource injection policy '{policy}'"
154
+ raise ValueError(msg) from e
155
+ if policy == KubernetesResourceInjectionPolicyEnum.ENV:
156
+ return "env"
157
+ if policy == KubernetesResourceInjectionPolicyEnum.KDP:
158
+ return "kdp"
110
159
 
111
160
  if probe_node_allocatable is None:
112
161
  return "kdp"
@@ -142,6 +191,7 @@ def cdi_kind_to_kdp_resource(
142
191
 
143
192
 
144
193
  __all__ = [
194
+ "KubernetesResourceInjectionPolicyEnum",
145
195
  "cdi_kind_to_kdp_resource",
146
196
  "get_resource_injection_policy",
147
197
  "is_kubelet_socket_accessible",