diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8935e93..b8dda9b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.28.0" + ".": "0.29.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ed65ca..40a92af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## [0.29.0](https://github.com/kernel/hypeman-python/compare/v0.28.0...v0.29.0) (2026-10-21) + + +### Features + +* Add Windows hypervisor primitives ([5c037b9](https://github.com/kernel/hypeman-python/commit/5c037b9f9c5926025ba9e5852bea964b4e1ace7c)) +* Integrate vendor VFIO vGPUs into the instance lifecycle ([24934bb](https://github.com/kernel/hypeman-python/commit/24934bb5e6f4a2ab636e0d893d056276ce2fd3dd)) +* Place vGPU profiles the driver hides from creatable lists ([3578ec1](https://github.com/kernel/hypeman-python/commit/3578ec14db5cf79817e7e8606c9e260865deafd3)) +* Update Hypeman build toolchains to Go 1.26.10 ([6a79c69](https://github.com/kernel/hypeman-python/commit/6a79c6927c90a1b35c971dcb749d1cddc0ecf8e3)) + ## [0.28.0](https://github.com/kernel/hypeman-python/compare/v0.27.0...v0.28.0) (2026-09-01) diff --git a/pyproject.toml b/pyproject.toml index 510aa2f..5eca9c0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "hypeman" -version = "0.28.0" +version = "0.29.0" description = "The official Python library for the hypeman API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/hypeman/_version.py b/src/hypeman/_version.py index 8b63c5a..2605750 100644 --- a/src/hypeman/_version.py +++ b/src/hypeman/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "hypeman" -__version__ = "0.28.0" # x-release-please-version +__version__ = "0.29.0" # x-release-please-version diff --git a/src/hypeman/resources/instances/instances.py b/src/hypeman/resources/instances/instances.py index 513e422..503e060 100644 --- a/src/hypeman/resources/instances/instances.py +++ b/src/hypeman/resources/instances/instances.py @@ -200,16 +200,19 @@ def create( network: Network configuration for the instance - overlay_size: Writable overlay disk size (human-readable format like "10GB", "50G") + overlay_size: Writable overlay disk size (human-readable format like "10GB", "50G"). Omit this + field for macOS guests, which clone the image's complete boot disk instead. - platform: Target platform as os/arch[/variant] (e.g. "linux/amd64"), matching Docker - --platform. Omit for the host platform. Not a fixed enum: the os/arch[/variant] - grammar is validated server-side and invalid values return 400 invalid_platform. - Only os "linux" with arch amd64 or arm64 is accepted today. + platform: Target platform as os/arch[/variant]. Linux container guests support amd64 and + arm64. Experimental darwin/arm64 guests require an offline-imported macOS disk + image and vz on Apple silicon. Omit to use the cached native image or host + platform. restart_policy: Whole-instance restart supervision policy. - size: Base memory size (human-readable format like "1GB", "512MB", "2G") + size: Base memory size (human-readable format like "1GB", "512MB", "2G"). macOS guests + default to their image's memory; explicit sizes must be at least 4 GiB in whole + MiB and within VZ host limits. skip_guest_agent: Skip guest-agent installation during boot. When true, the exec and stat APIs will not work for this instance. The instance will still run, but remote command @@ -230,7 +233,8 @@ def create( omit both expiration fields to disable automatic expiration. Mutually exclusive with expires_at. - vcpus: Number of virtual CPUs + vcpus: Number of virtual CPUs. macOS guests default to their image's vCPUs; explicit + counts must be at least 2 and within VZ host limits. volumes: Volumes to attach to the instance at creation time @@ -536,7 +540,7 @@ def logs( id: str, *, follow: bool | Omit = omit, - source: Literal["app", "vmm", "hypeman"] | Omit = omit, + source: Literal["app", "vmm", "hypeman", "swtpm"] | Omit = omit, tail: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -1022,16 +1026,19 @@ async def create( network: Network configuration for the instance - overlay_size: Writable overlay disk size (human-readable format like "10GB", "50G") + overlay_size: Writable overlay disk size (human-readable format like "10GB", "50G"). Omit this + field for macOS guests, which clone the image's complete boot disk instead. - platform: Target platform as os/arch[/variant] (e.g. "linux/amd64"), matching Docker - --platform. Omit for the host platform. Not a fixed enum: the os/arch[/variant] - grammar is validated server-side and invalid values return 400 invalid_platform. - Only os "linux" with arch amd64 or arm64 is accepted today. + platform: Target platform as os/arch[/variant]. Linux container guests support amd64 and + arm64. Experimental darwin/arm64 guests require an offline-imported macOS disk + image and vz on Apple silicon. Omit to use the cached native image or host + platform. restart_policy: Whole-instance restart supervision policy. - size: Base memory size (human-readable format like "1GB", "512MB", "2G") + size: Base memory size (human-readable format like "1GB", "512MB", "2G"). macOS guests + default to their image's memory; explicit sizes must be at least 4 GiB in whole + MiB and within VZ host limits. skip_guest_agent: Skip guest-agent installation during boot. When true, the exec and stat APIs will not work for this instance. The instance will still run, but remote command @@ -1052,7 +1059,8 @@ async def create( omit both expiration fields to disable automatic expiration. Mutually exclusive with expires_at. - vcpus: Number of virtual CPUs + vcpus: Number of virtual CPUs. macOS guests default to their image's vCPUs; explicit + counts must be at least 2 and within VZ host limits. volumes: Volumes to attach to the instance at creation time @@ -1358,7 +1366,7 @@ async def logs( id: str, *, follow: bool | Omit = omit, - source: Literal["app", "vmm", "hypeman"] | Omit = omit, + source: Literal["app", "vmm", "hypeman", "swtpm"] | Omit = omit, tail: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. diff --git a/src/hypeman/types/gpu_profile.py b/src/hypeman/types/gpu_profile.py index 109beb3..d55a9d2 100644 --- a/src/hypeman/types/gpu_profile.py +++ b/src/hypeman/types/gpu_profile.py @@ -9,7 +9,11 @@ class GPUProfile(BaseModel): """Available vGPU profile""" available: int - """Number of instances that can be created with this profile""" + """ + Number of additional instances of this profile the host can take if only this + profile is added. Counts for different profiles are not additive: an instance of + one profile can reduce availability of others on the same GPU. + """ framebuffer_mb: int """Frame buffer size in MB""" diff --git a/src/hypeman/types/gpu_resource_status.py b/src/hypeman/types/gpu_resource_status.py index e3e9b26..d39268e 100644 --- a/src/hypeman/types/gpu_resource_status.py +++ b/src/hypeman/types/gpu_resource_status.py @@ -13,17 +13,40 @@ class GPUResourceStatus(BaseModel): """GPU resource status. Null if no GPUs available.""" + allocatable_slots: int + """ + Free slots eligible for placement, matching admission control (excludes + quarantined VFs; 0 while VF health state is unavailable) + """ + mode: Literal["vgpu", "passthrough"] """GPU mode (vgpu for SR-IOV/mdev, passthrough for whole GPU)""" + quarantined_slots: int + """VFs quarantined after guest driver init failures (vGPU mode only). + + May overlap used_slots until the affected instance releases its VF. + """ + total_slots: int """Total slots (VFs for vGPU, physical GPUs for passthrough)""" used_slots: int - """Slots currently in use""" + """Slots currently in use. + + Includes quarantined VFs that are still assigned, so this can overlap + quarantined_slots. + """ devices: Optional[List[PassthroughDevice]] = None """Physical GPUs (only in passthrough mode)""" + placement_disabled_reason: Optional[str] = None + """ + Present when allocatable_slots is 0 because the VF health state could not be + read or written rather than because the host is full. vGPU placement is refused + until the state file is repaired or the next write succeeds. + """ + profiles: Optional[List[GPUProfile]] = None """Available vGPU profiles (only in vGPU mode)""" diff --git a/src/hypeman/types/instance.py b/src/hypeman/types/instance.py index 254db1b..fc5d857 100644 --- a/src/hypeman/types/instance.py +++ b/src/hypeman/types/instance.py @@ -19,8 +19,11 @@ class GPU(BaseModel): """GPU information attached to the instance""" + device_path: Optional[str] = None + """sysfs path of the assigned vGPU device""" + mdev_uuid: Optional[str] = None - """mdev device UUID""" + """mdev device UUID (mdev hosts only)""" profile: Optional[str] = None """vGPU profile name""" diff --git a/src/hypeman/types/instance_create_params.py b/src/hypeman/types/instance_create_params.py index 9938f15..f7f9215 100644 --- a/src/hypeman/types/instance_create_params.py +++ b/src/hypeman/types/instance_create_params.py @@ -108,22 +108,29 @@ class InstanceCreateParams(TypedDict, total=False): """Network configuration for the instance""" overlay_size: str - """Writable overlay disk size (human-readable format like "10GB", "50G")""" + """Writable overlay disk size (human-readable format like "10GB", "50G"). + + Omit this field for macOS guests, which clone the image's complete boot disk + instead. + """ platform: str - """Target platform as os/arch[/variant] (e.g. + """Target platform as os/arch[/variant]. - "linux/amd64"), matching Docker --platform. Omit for the host platform. Not a - fixed enum: the os/arch[/variant] grammar is validated server-side and invalid - values return 400 invalid_platform. Only os "linux" with arch amd64 or arm64 is - accepted today. + Linux container guests support amd64 and arm64. Experimental darwin/arm64 guests + require an offline-imported macOS disk image and vz on Apple silicon. Omit to + use the cached native image or host platform. """ restart_policy: RestartPolicyParam """Whole-instance restart supervision policy.""" size: str - """Base memory size (human-readable format like "1GB", "512MB", "2G")""" + """Base memory size (human-readable format like "1GB", "512MB", "2G"). + + macOS guests default to their image's memory; explicit sizes must be at least 4 + GiB in whole MiB and within VZ host limits. + """ skip_guest_agent: bool """ @@ -158,7 +165,11 @@ class InstanceCreateParams(TypedDict, total=False): """ vcpus: int - """Number of virtual CPUs""" + """Number of virtual CPUs. + + macOS guests default to their image's vCPUs; explicit counts must be at least 2 + and within VZ host limits. + """ volumes: Iterable[VolumeMountParam] """Volumes to attach to the instance at creation time""" diff --git a/src/hypeman/types/instance_logs_params.py b/src/hypeman/types/instance_logs_params.py index a56923f..e016411 100644 --- a/src/hypeman/types/instance_logs_params.py +++ b/src/hypeman/types/instance_logs_params.py @@ -11,7 +11,7 @@ class InstanceLogsParams(TypedDict, total=False): follow: bool """Continue streaming new lines after initial output""" - source: Literal["app", "vmm", "hypeman"] + source: Literal["app", "vmm", "hypeman", "swtpm"] """Log source to stream: - app: Guest application logs (serial console output) diff --git a/src/hypeman/types/instance_stats.py b/src/hypeman/types/instance_stats.py index 905e3fb..70b5560 100644 --- a/src/hypeman/types/instance_stats.py +++ b/src/hypeman/types/instance_stats.py @@ -32,7 +32,10 @@ class InstanceStats(BaseModel): """Virtual Memory Size - total virtual memory allocated in bytes""" network_rx_bytes: int - """Total network bytes received by the VM (from TAP interface)""" + """Total network bytes received by the VM (from TAP interface). + + Always 0 for macOS guests, which use NAT with no per-instance interface. + """ network_tx_bytes: int """Total network bytes transmitted by the VM (from TAP interface)"""