Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.11.0"
".": "0.12.0"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 37
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-88202634e62d08a99d4a0975b8ce26158ec1694ee2639167ad40c06780b6c270.yml
openapi_spec_hash: 93b690dd5d65ac2eaea08c81339414fe
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-d5ce7bbc5163c13d0ef49a4edc04d3186e7ba7d040726c149a218000faf3c1ce.yml
openapi_spec_hash: cb4fac9f74fdd0a33d554e6630f8547b
config_hash: d452c139da1e46a44a68b91e8a40de72
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# Changelog

## 0.12.0 (2026-02-26)

Full Changelog: [v0.11.0...v0.12.0](https://github.com/kernel/hypeman-go/compare/v0.11.0...v0.12.0)

### Features

* add metadata and state filtering to GET /instances ([8149c9f](https://github.com/kernel/hypeman-go/commit/8149c9fe5e9b36aa5709767e7f3986d6778bd432))
* Disable default hotplug memory allocation ([4c65d5c](https://github.com/kernel/hypeman-go/commit/4c65d5c271ac3a620da549b47ece553e1860aaf6))


### Bug Fixes

* allow canceling a request while it is waiting to retry ([daa2281](https://github.com/kernel/hypeman-go/commit/daa2281e6e9833ae4dba2b9b6870014ceb0b2fff))
* send query params for NewFromArchive ([a8c45a6](https://github.com/kernel/hypeman-go/commit/a8c45a69e83c96137c772d999a115972f0e6a003))


### Chores

* **internal:** move custom custom `json` tags to `api` ([d04f6ed](https://github.com/kernel/hypeman-go/commit/d04f6ed70c95357f323aa4e76b3a6ad8ebd12ec3))
* **internal:** remove mock server code ([b511676](https://github.com/kernel/hypeman-go/commit/b51167627fc0cd0f947633cb8694f4ee0756c268))
* update mock server docs ([d2ae478](https://github.com/kernel/hypeman-go/commit/d2ae478d46fb67550a3b35d4261218f9368709f0))

## 0.11.0 (2026-02-15)

Full Changelog: [v0.10.0...v0.11.0](https://github.com/kernel/hypeman-go/compare/v0.10.0...v0.11.0)
Expand Down
7 changes: 0 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,6 @@ $ go mod edit -replace github.com/kernel/hypeman-go=/path/to/hypeman-go

## Running tests

Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests.

```sh
# you will need npm installed
$ npx prism mock path/to/your/openapi.yml
```

```sh
$ ./scripts/test
```
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Or to pin the version:
<!-- x-release-please-start-version -->

```sh
go get -u 'github.com/kernel/hypeman-go@v0.11.0'
go get -u 'github.com/kernel/hypeman-go@v0.12.0'
```

<!-- x-release-please-end -->
Expand Down
2 changes: 1 addition & 1 deletion api.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Response Types:
Methods:

- <code title="post /instances">client.Instances.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceService.New">New</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, body <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceNewParams">InstanceNewParams</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#Instance">Instance</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /instances">client.Instances.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceService.List">List</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>) (\*[]<a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#Instance">Instance</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /instances">client.Instances.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceService.List">List</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, query <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceListParams">InstanceListParams</a>) (\*[]<a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#Instance">Instance</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="delete /instances/{id}">client.Instances.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceService.Delete">Delete</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) <a href="https://pkg.go.dev/builtin#error">error</a></code>
- <code title="get /instances/{id}">client.Instances.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceService.Get">Get</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#Instance">Instance</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /instances/{id}/logs">client.Instances.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceService.Logs">Logs</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, query <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceLogsParams">InstanceLogsParams</a>) (\*<a href="https://pkg.go.dev/builtin#string">string</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
Expand Down
28 changes: 14 additions & 14 deletions build.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,30 +110,30 @@ func (r *BuildService) Get(ctx context.Context, id string, opts ...option.Reques

type Build struct {
// Build job identifier
ID string `json:"id,required"`
ID string `json:"id" api:"required"`
// Build creation timestamp
CreatedAt time.Time `json:"created_at,required" format:"date-time"`
CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"`
// Build job status
//
// Any of "queued", "building", "pushing", "ready", "failed", "cancelled".
Status BuildStatus `json:"status,required"`
Status BuildStatus `json:"status" api:"required"`
// Instance ID of the builder VM (for debugging)
BuilderInstanceID string `json:"builder_instance_id,nullable"`
BuilderInstanceID string `json:"builder_instance_id" api:"nullable"`
// Build completion timestamp
CompletedAt time.Time `json:"completed_at,nullable" format:"date-time"`
CompletedAt time.Time `json:"completed_at" api:"nullable" format:"date-time"`
// Build duration in milliseconds
DurationMs int64 `json:"duration_ms,nullable"`
DurationMs int64 `json:"duration_ms" api:"nullable"`
// Error message (only when status is failed)
Error string `json:"error,nullable"`
Error string `json:"error" api:"nullable"`
// Digest of built image (only when status is ready)
ImageDigest string `json:"image_digest,nullable"`
ImageDigest string `json:"image_digest" api:"nullable"`
// Full image reference (only when status is ready)
ImageRef string `json:"image_ref,nullable"`
ImageRef string `json:"image_ref" api:"nullable"`
Provenance BuildProvenance `json:"provenance"`
// Position in build queue (only when status is queued)
QueuePosition int64 `json:"queue_position,nullable"`
QueuePosition int64 `json:"queue_position" api:"nullable"`
// Build start timestamp
StartedAt time.Time `json:"started_at,nullable" format:"date-time"`
StartedAt time.Time `json:"started_at" api:"nullable" format:"date-time"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
ID respjson.Field
Expand Down Expand Up @@ -161,11 +161,11 @@ func (r *Build) UnmarshalJSON(data []byte) error {

type BuildEvent struct {
// Event timestamp
Timestamp time.Time `json:"timestamp,required" format:"date-time"`
Timestamp time.Time `json:"timestamp" api:"required" format:"date-time"`
// Event type
//
// Any of "log", "status", "heartbeat".
Type BuildEventType `json:"type,required"`
Type BuildEventType `json:"type" api:"required"`
// Log line content (only for type=log)
Content string `json:"content"`
// New build status (only for type=status)
Expand Down Expand Up @@ -241,7 +241,7 @@ const (

type BuildNewParams struct {
// Source tarball (tar.gz) containing application code and optionally a Dockerfile
Source io.Reader `json:"source,omitzero,required" format:"binary"`
Source io.Reader `json:"source,omitzero" api:"required" format:"binary"`
// Optional pinned base image digest
BaseImageDigest param.Opt[string] `json:"base_image_digest,omitzero"`
// Tenant-specific cache key prefix
Expand Down
8 changes: 4 additions & 4 deletions build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
)

func TestBuildNewWithOptionalParams(t *testing.T) {
t.Skip("Prism tests are disabled")
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
Expand Down Expand Up @@ -49,7 +49,7 @@ func TestBuildNewWithOptionalParams(t *testing.T) {
}

func TestBuildList(t *testing.T) {
t.Skip("Prism tests are disabled")
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
Expand All @@ -72,7 +72,7 @@ func TestBuildList(t *testing.T) {
}

func TestBuildCancel(t *testing.T) {
t.Skip("Prism tests are disabled")
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
Expand All @@ -95,7 +95,7 @@ func TestBuildCancel(t *testing.T) {
}

func TestBuildGet(t *testing.T) {
t.Skip("Prism tests are disabled")
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
Expand Down
30 changes: 15 additions & 15 deletions device.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,15 @@ func (r *DeviceService) ListAvailable(ctx context.Context, opts ...option.Reques

type AvailableDevice struct {
// PCI device ID (hex)
DeviceID string `json:"device_id,required"`
DeviceID string `json:"device_id" api:"required"`
// IOMMU group number
IommuGroup int64 `json:"iommu_group,required"`
IommuGroup int64 `json:"iommu_group" api:"required"`
// PCI address
PciAddress string `json:"pci_address,required"`
PciAddress string `json:"pci_address" api:"required"`
// PCI vendor ID (hex)
VendorID string `json:"vendor_id,required"`
VendorID string `json:"vendor_id" api:"required"`
// Currently bound driver (null if none)
CurrentDriver string `json:"current_driver,nullable"`
CurrentDriver string `json:"current_driver" api:"nullable"`
// Human-readable device name
DeviceName string `json:"device_name"`
// Human-readable vendor name
Expand All @@ -122,31 +122,31 @@ func (r *AvailableDevice) UnmarshalJSON(data []byte) error {

type Device struct {
// Auto-generated unique identifier (CUID2 format)
ID string `json:"id,required"`
ID string `json:"id" api:"required"`
// Whether the device is currently bound to the vfio-pci driver, which is required
// for VM passthrough.
//
// - true: Device is bound to vfio-pci and ready for (or currently in use by) a VM.
// The device's native driver has been unloaded.
// - false: Device is using its native driver (e.g., nvidia) or no driver. Hypeman
// will automatically bind to vfio-pci when attaching to an instance.
BoundToVfio bool `json:"bound_to_vfio,required"`
BoundToVfio bool `json:"bound_to_vfio" api:"required"`
// Registration timestamp (RFC3339)
CreatedAt time.Time `json:"created_at,required" format:"date-time"`
CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"`
// PCI device ID (hex)
DeviceID string `json:"device_id,required"`
DeviceID string `json:"device_id" api:"required"`
// IOMMU group number
IommuGroup int64 `json:"iommu_group,required"`
IommuGroup int64 `json:"iommu_group" api:"required"`
// PCI address
PciAddress string `json:"pci_address,required"`
PciAddress string `json:"pci_address" api:"required"`
// Type of PCI device
//
// Any of "gpu", "pci".
Type DeviceType `json:"type,required"`
Type DeviceType `json:"type" api:"required"`
// PCI vendor ID (hex)
VendorID string `json:"vendor_id,required"`
VendorID string `json:"vendor_id" api:"required"`
// Instance ID if attached
AttachedTo string `json:"attached_to,nullable"`
AttachedTo string `json:"attached_to" api:"nullable"`
// Device name (user-provided or auto-generated from PCI address)
Name string `json:"name"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
Expand Down Expand Up @@ -182,7 +182,7 @@ const (

type DeviceNewParams struct {
// PCI address of the device (required, e.g., "0000:a2:00.0")
PciAddress string `json:"pci_address,required"`
PciAddress string `json:"pci_address" api:"required"`
// Optional globally unique device name. If not provided, a name is auto-generated
// from the PCI address (e.g., "pci-0000-a2-00-0")
Name param.Opt[string] `json:"name,omitzero"`
Expand Down
10 changes: 5 additions & 5 deletions device_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
)

func TestDeviceNewWithOptionalParams(t *testing.T) {
t.Skip("Prism tests are disabled")
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
Expand All @@ -40,7 +40,7 @@ func TestDeviceNewWithOptionalParams(t *testing.T) {
}

func TestDeviceGet(t *testing.T) {
t.Skip("Prism tests are disabled")
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
Expand All @@ -63,7 +63,7 @@ func TestDeviceGet(t *testing.T) {
}

func TestDeviceList(t *testing.T) {
t.Skip("Prism tests are disabled")
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
Expand All @@ -86,7 +86,7 @@ func TestDeviceList(t *testing.T) {
}

func TestDeviceDelete(t *testing.T) {
t.Skip("Prism tests are disabled")
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
Expand All @@ -109,7 +109,7 @@ func TestDeviceDelete(t *testing.T) {
}

func TestDeviceListAvailable(t *testing.T) {
t.Skip("Prism tests are disabled")
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
Expand Down
2 changes: 1 addition & 1 deletion health.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (r *HealthService) Check(ctx context.Context, opts ...option.RequestOption)

type HealthCheckResponse struct {
// Any of "ok".
Status HealthCheckResponseStatus `json:"status,required"`
Status HealthCheckResponseStatus `json:"status" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Status respjson.Field
Expand Down
2 changes: 1 addition & 1 deletion health_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
)

func TestHealthCheck(t *testing.T) {
t.Skip("Prism tests are disabled")
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
Expand Down
22 changes: 11 additions & 11 deletions image.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,29 +79,29 @@ func (r *ImageService) Get(ctx context.Context, name string, opts ...option.Requ

type Image struct {
// Creation timestamp (RFC3339)
CreatedAt time.Time `json:"created_at,required" format:"date-time"`
CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"`
// Resolved manifest digest
Digest string `json:"digest,required"`
Digest string `json:"digest" api:"required"`
// Normalized OCI image reference (tag or digest)
Name string `json:"name,required"`
Name string `json:"name" api:"required"`
// Build status
//
// Any of "pending", "pulling", "converting", "ready", "failed".
Status ImageStatus `json:"status,required"`
Status ImageStatus `json:"status" api:"required"`
// CMD from container metadata
Cmd []string `json:"cmd,nullable"`
Cmd []string `json:"cmd" api:"nullable"`
// Entrypoint from container metadata
Entrypoint []string `json:"entrypoint,nullable"`
Entrypoint []string `json:"entrypoint" api:"nullable"`
// Environment variables from container metadata
Env map[string]string `json:"env"`
// Error message if status is failed
Error string `json:"error,nullable"`
Error string `json:"error" api:"nullable"`
// Position in build queue (null if not queued)
QueuePosition int64 `json:"queue_position,nullable"`
QueuePosition int64 `json:"queue_position" api:"nullable"`
// Disk size in bytes (null until ready)
SizeBytes int64 `json:"size_bytes,nullable"`
SizeBytes int64 `json:"size_bytes" api:"nullable"`
// Working directory from container metadata
WorkingDir string `json:"working_dir,nullable"`
WorkingDir string `json:"working_dir" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
CreatedAt respjson.Field
Expand Down Expand Up @@ -139,7 +139,7 @@ const (

type ImageNewParams struct {
// OCI image reference (e.g., docker.io/library/nginx:latest)
Name string `json:"name,required"`
Name string `json:"name" api:"required"`
paramObj
}

Expand Down
8 changes: 4 additions & 4 deletions image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
)

func TestImageNew(t *testing.T) {
t.Skip("Prism tests are disabled")
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
Expand All @@ -39,7 +39,7 @@ func TestImageNew(t *testing.T) {
}

func TestImageList(t *testing.T) {
t.Skip("Prism tests are disabled")
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
Expand All @@ -62,7 +62,7 @@ func TestImageList(t *testing.T) {
}

func TestImageDelete(t *testing.T) {
t.Skip("Prism tests are disabled")
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
Expand All @@ -85,7 +85,7 @@ func TestImageDelete(t *testing.T) {
}

func TestImageGet(t *testing.T) {
t.Skip("Prism tests are disabled")
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
Expand Down
Loading