diff --git a/Makefile b/Makefile index 736bd1e0..a2275f0c 100644 --- a/Makefile +++ b/Makefile @@ -37,18 +37,12 @@ install-tools: $(OAPI_CODEGEN) $(AIR) $(WIRE) $(XCADDY) # Download Cloud Hypervisor binaries download-ch-binaries: @echo "Downloading Cloud Hypervisor binaries..." - @mkdir -p lib/vmm/binaries/cloud-hypervisor/v48.0/{x86_64,aarch64} - @mkdir -p lib/vmm/binaries/cloud-hypervisor/v49.0/{x86_64,aarch64} - @echo "Downloading v48.0..." - @curl -L -o lib/vmm/binaries/cloud-hypervisor/v48.0/x86_64/cloud-hypervisor \ - https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/v48.0/cloud-hypervisor-static - @curl -L -o lib/vmm/binaries/cloud-hypervisor/v48.0/aarch64/cloud-hypervisor \ - https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/v48.0/cloud-hypervisor-static-aarch64 - @echo "Downloading v49.0..." - @curl -L -o lib/vmm/binaries/cloud-hypervisor/v49.0/x86_64/cloud-hypervisor \ - https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/v49.0/cloud-hypervisor-static - @curl -L -o lib/vmm/binaries/cloud-hypervisor/v49.0/aarch64/cloud-hypervisor \ - https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/v49.0/cloud-hypervisor-static-aarch64 + @mkdir -p lib/vmm/binaries/cloud-hypervisor/v50.1/{x86_64,aarch64} + @echo "Downloading v50.1..." + @curl -L -o lib/vmm/binaries/cloud-hypervisor/v50.1/x86_64/cloud-hypervisor \ + https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/v50.1/cloud-hypervisor-static + @curl -L -o lib/vmm/binaries/cloud-hypervisor/v50.1/aarch64/cloud-hypervisor \ + https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/v50.1/cloud-hypervisor-static-aarch64 @chmod +x lib/vmm/binaries/cloud-hypervisor/v*/*/cloud-hypervisor @echo "Binaries downloaded successfully" @@ -116,7 +110,7 @@ download-ch-spec: @echo "Downloading Cloud Hypervisor API spec..." @mkdir -p specs/cloud-hypervisor/api-v0.3.0 @curl -L -o specs/cloud-hypervisor/api-v0.3.0/cloud-hypervisor.yaml \ - https://raw.githubusercontent.com/cloud-hypervisor/cloud-hypervisor/refs/tags/v48.0/vmm/src/api/openapi/cloud-hypervisor.yaml + https://raw.githubusercontent.com/cloud-hypervisor/cloud-hypervisor/refs/tags/v50.1/vmm/src/api/openapi/cloud-hypervisor.yaml @echo "API spec downloaded" # Generate Go code from OpenAPI spec @@ -168,7 +162,7 @@ ensure-ch-binaries: else \ echo "Unsupported architecture: $$ARCH"; exit 1; \ fi; \ - if [ ! -f lib/vmm/binaries/cloud-hypervisor/v48.0/$$CH_ARCH/cloud-hypervisor ]; then \ + if [ ! -f lib/vmm/binaries/cloud-hypervisor/v50.1/$$CH_ARCH/cloud-hypervisor ]; then \ echo "Cloud Hypervisor binaries not found, downloading..."; \ $(MAKE) download-ch-binaries; \ fi diff --git a/lib/hypervisor/cloudhypervisor/config.go b/lib/hypervisor/cloudhypervisor/config.go index d728036b..5325a966 100644 --- a/lib/hypervisor/cloudhypervisor/config.go +++ b/lib/hypervisor/cloudhypervisor/config.go @@ -43,7 +43,8 @@ func ToVMConfig(cfg hypervisor.VMConfig) vmm.VmConfig { disks := make([]vmm.DiskConfig, 0, len(cfg.Disks)) for _, d := range cfg.Disks { disk := vmm.DiskConfig{ - Path: ptr(d.Path), + Path: ptr(d.Path), + ImageType: ptr(vmm.Raw), } if d.Readonly { disk.Readonly = ptr(true) diff --git a/lib/hypervisor/cloudhypervisor/process.go b/lib/hypervisor/cloudhypervisor/process.go index 0618de43..3359a996 100644 --- a/lib/hypervisor/cloudhypervisor/process.go +++ b/lib/hypervisor/cloudhypervisor/process.go @@ -55,7 +55,7 @@ func (s *Starter) GetBinaryPath(p *paths.Paths, version string) (string, error) // GetVersion returns the latest supported Cloud Hypervisor version. // Cloud Hypervisor binaries are embedded, so we return the latest known version. func (s *Starter) GetVersion(p *paths.Paths) (string, error) { - return string(vmm.V49_0), nil + return string(vmm.V50_1), nil } // StartVM launches Cloud Hypervisor, configures the VM, and boots it. diff --git a/lib/instances/manager_test.go b/lib/instances/manager_test.go index 169237b6..d351827c 100644 --- a/lib/instances/manager_test.go +++ b/lib/instances/manager_test.go @@ -1254,7 +1254,7 @@ func TestStorageOperations(t *testing.T) { Env: map[string]string{"TEST": "value"}, CreatedAt: time.Now(), HypervisorType: hypervisor.TypeCloudHypervisor, - HypervisorVersion: string(vmm.V49_0), + HypervisorVersion: string(vmm.V50_1), SocketPath: "/tmp/test.sock", DataDir: paths.New(tmpDir).InstanceDir("test-123"), } diff --git a/lib/instances/types.go b/lib/instances/types.go index 56243a0d..aa73768c 100644 --- a/lib/instances/types.go +++ b/lib/instances/types.go @@ -111,7 +111,7 @@ type StoredMetadata struct { // Hypervisor configuration HypervisorType hypervisor.Type // Hypervisor type (e.g., "cloud-hypervisor") - HypervisorVersion string // Hypervisor version (e.g., "v49.0") + HypervisorVersion string // Hypervisor version (e.g., "v50.1") HypervisorPID *int // Hypervisor process ID (may be stale after host restart) // Paths diff --git a/lib/system/README.md b/lib/system/README.md index 2f5c012c..6e3892d9 100644 --- a/lib/system/README.md +++ b/lib/system/README.md @@ -37,8 +37,8 @@ Manages versioned kernel and initrd files for Cloud Hypervisor VMs. **Snapshots require exact matches:** ``` -Standby: kernel ch-6.12.8-kernel-1.2-20251213, CH v49.0 -Restore: kernel ch-6.12.8-kernel-1.2-20251213, CH v49.0 (MUST match) +Standby: kernel ch-6.12.8-kernel-1.2-20251213, CH v50.1 +Restore: kernel ch-6.12.8-kernel-1.2-20251213, CH v50.1 (MUST match) ``` **Maintenance upgrades (shutdown → boot):** diff --git a/lib/vmm/README.md b/lib/vmm/README.md index 84dfd21d..9e7bab16 100644 --- a/lib/vmm/README.md +++ b/lib/vmm/README.md @@ -38,7 +38,7 @@ dataDir := "/var/lib/hypeman" socketPath := "/tmp/vmm.sock" // Start Cloud Hypervisor VMM (extracts binary if needed) -err := vmm.StartProcess(ctx, dataDir, vmm.V48_0, socketPath) +err := vmm.StartProcess(ctx, dataDir, vmm.V50_1, socketPath) if err != nil { log.Fatal(err) } @@ -60,9 +60,9 @@ resp, err := client.GetVmmPingWithResponse(ctx) ### Check Binary Version ```go -binaryPath, _ := vmm.GetBinaryPath(dataDir, vmm.V48_0) +binaryPath, _ := vmm.GetBinaryPath(dataDir, vmm.V50_1) version, err := vmm.ParseVersion(binaryPath) -fmt.Println(version) // "v48.0" +fmt.Println(version) // "v50.1" ``` ## Architecture @@ -75,10 +75,7 @@ lib/vmm/ ├── version.go # Version parsing utilities ├── binaries/ # Embedded Cloud Hypervisor binaries │ └── cloud-hypervisor/ -│ ├── v48.0/ -│ │ ├── x86_64/cloud-hypervisor (4.5MB) -│ │ └── aarch64/cloud-hypervisor (3.3MB) -│ └── v49.0/ +│ └── v50.1/ │ ├── x86_64/cloud-hypervisor (4.5MB) │ └── aarch64/cloud-hypervisor (3.3MB) | # There will be additional versions in the future... @@ -87,8 +84,7 @@ lib/vmm/ ## Supported Versions -- Cloud Hypervisor v48.0 (API v0.3.0) -- Cloud Hypervisor v49.0 (API v0.3.0) +- Cloud Hypervisor v50.1 (API v0.3.0) There may be additional versions in the future. Cloud hypervisor versions may update frequently, while the API updates less frequently. diff --git a/lib/vmm/binaries_darwin.go b/lib/vmm/binaries_darwin.go index 370c027c..d9cf1309 100644 --- a/lib/vmm/binaries_darwin.go +++ b/lib/vmm/binaries_darwin.go @@ -12,8 +12,7 @@ import ( type CHVersion string const ( - V48_0 CHVersion = "v48.0" - V49_0 CHVersion = "v49.0" + V50_1 CHVersion = "v50.1" ) // SupportedVersions lists supported Cloud Hypervisor versions. diff --git a/lib/vmm/binaries_linux.go b/lib/vmm/binaries_linux.go index b827ad41..cac8fcbf 100644 --- a/lib/vmm/binaries_linux.go +++ b/lib/vmm/binaries_linux.go @@ -13,20 +13,17 @@ import ( "github.com/kernel/hypeman/lib/paths" ) -//go:embed binaries/cloud-hypervisor/v48.0/x86_64/cloud-hypervisor -//go:embed binaries/cloud-hypervisor/v48.0/aarch64/cloud-hypervisor -//go:embed binaries/cloud-hypervisor/v49.0/x86_64/cloud-hypervisor -//go:embed binaries/cloud-hypervisor/v49.0/aarch64/cloud-hypervisor +//go:embed binaries/cloud-hypervisor/v50.1/x86_64/cloud-hypervisor +//go:embed binaries/cloud-hypervisor/v50.1/aarch64/cloud-hypervisor var binaryFS embed.FS type CHVersion string const ( - V48_0 CHVersion = "v48.0" - V49_0 CHVersion = "v49.0" + V50_1 CHVersion = "v50.1" ) -var SupportedVersions = []CHVersion{V48_0, V49_0} +var SupportedVersions = []CHVersion{V50_1} // ExtractBinary extracts the embedded Cloud Hypervisor binary to the data directory func ExtractBinary(p *paths.Paths, version CHVersion) (string, error) { diff --git a/lib/vmm/client_test.go b/lib/vmm/client_test.go index 33febedb..99c1b4fc 100644 --- a/lib/vmm/client_test.go +++ b/lib/vmm/client_test.go @@ -16,8 +16,8 @@ import ( func TestExtractBinary(t *testing.T) { tmpDir := t.TempDir() - // Test extraction for v48.0 - binaryPath, err := ExtractBinary(paths.New(tmpDir), V48_0) + // Test extraction for v50.1 + binaryPath, err := ExtractBinary(paths.New(tmpDir), V50_1) require.NoError(t, err) // Verify file exists @@ -30,14 +30,13 @@ func TestExtractBinary(t *testing.T) { assert.Equal(t, os.FileMode(0755), info.Mode().Perm()) // Test idempotency - second extraction should succeed and return same path - binaryPath2, err := ExtractBinary(paths.New(tmpDir), V48_0) + binaryPath2, err := ExtractBinary(paths.New(tmpDir), V50_1) require.NoError(t, err) assert.Equal(t, binaryPath, binaryPath2) } func TestIsVersionSupported(t *testing.T) { - assert.True(t, IsVersionSupported(V48_0)) - assert.True(t, IsVersionSupported(V49_0)) + assert.True(t, IsVersionSupported(V50_1)) assert.False(t, IsVersionSupported("v1.0")) } @@ -45,13 +44,13 @@ func TestParseVersion(t *testing.T) { tmpDir := t.TempDir() // Extract binary - binaryPath, err := ExtractBinary(paths.New(tmpDir), V48_0) + binaryPath, err := ExtractBinary(paths.New(tmpDir), V50_1) require.NoError(t, err) // Parse version version, err := ParseVersion(binaryPath) require.NoError(t, err) - assert.Equal(t, V48_0, version) + assert.Equal(t, V50_1, version) } func TestStartProcessAndShutdown(t *testing.T) { @@ -60,7 +59,7 @@ func TestStartProcessAndShutdown(t *testing.T) { ctx := context.Background() // Start VMM process - pid, err := StartProcess(ctx, paths.New(tmpDir), V48_0, socketPath) + pid, err := StartProcess(ctx, paths.New(tmpDir), V50_1, socketPath) require.NoError(t, err) assert.Greater(t, pid, 0, "PID should be positive") @@ -95,12 +94,12 @@ func TestStartProcessSocketInUse(t *testing.T) { ctx := context.Background() // Start first VMM - pid, err := StartProcess(ctx, paths.New(tmpDir), V48_0, socketPath) + pid, err := StartProcess(ctx, paths.New(tmpDir), V50_1, socketPath) require.NoError(t, err) assert.Greater(t, pid, 0) // Try to start second VMM on same socket - should fail - _, err = StartProcess(ctx, paths.New(tmpDir), V48_0, socketPath) + _, err = StartProcess(ctx, paths.New(tmpDir), V50_1, socketPath) require.Error(t, err) assert.Contains(t, err.Error(), "socket already in use") @@ -118,8 +117,7 @@ func TestMultipleVersions(t *testing.T) { name string version CHVersion }{ - {"v48.0", V48_0}, - {"v49.0", V49_0}, + {"v50.1", V50_1}, } for _, tt := range tests { @@ -159,7 +157,7 @@ func TestStartProcessCreatesLogFiles(t *testing.T) { ctx := context.Background() // Start VMM process with verbose logging to ensure output is written - pid, err := StartProcessWithArgs(ctx, paths.New(tmpDir), V48_0, socketPath, []string{"-v"}) + pid, err := StartProcessWithArgs(ctx, paths.New(tmpDir), V50_1, socketPath, []string{"-v"}) require.NoError(t, err) assert.Greater(t, pid, 0) diff --git a/lib/vmm/version.go b/lib/vmm/version.go index f2d256aa..8ccff261 100644 --- a/lib/vmm/version.go +++ b/lib/vmm/version.go @@ -20,11 +20,8 @@ func ParseVersion(binaryPath string) (CHVersion, error) { versionStr := strings.TrimSpace(string(output)) // Try to match known versions - if strings.Contains(versionStr, "v48.0") { - return V48_0, nil - } - if strings.Contains(versionStr, "v49.0") { - return V49_0, nil + if strings.Contains(versionStr, "v50.1") { + return V50_1, nil } return "", fmt.Errorf("unsupported version: %s", versionStr) diff --git a/lib/vmm/vmm.go b/lib/vmm/vmm.go index ad328206..ba113c05 100644 --- a/lib/vmm/vmm.go +++ b/lib/vmm/vmm.go @@ -33,6 +33,14 @@ const ( DebugConsoleConfigModeTty DebugConsoleConfigMode = "Tty" ) +// Defines values for DiskConfigImageType. +const ( + FixedVhd DiskConfigImageType = "FixedVhd" + Qcow2 DiskConfigImageType = "Qcow2" + Raw DiskConfigImageType = "Raw" + Vhdx DiskConfigImageType = "Vhdx" +) + // Defines values for VmInfoState. const ( Created VmInfoState = "Created" @@ -89,6 +97,7 @@ type CpusConfig struct { KvmHyperv *bool `json:"kvm_hyperv,omitempty"` MaxPhysBits *int `json:"max_phys_bits,omitempty"` MaxVcpus int `json:"max_vcpus"` + Nested *bool `json:"nested,omitempty"` Topology *CpuTopology `json:"topology,omitempty"` } @@ -121,8 +130,10 @@ type DeviceNode struct { // DiskConfig defines model for DiskConfig. type DiskConfig struct { + BackingFiles *bool `json:"backing_files,omitempty"` Direct *bool `json:"direct,omitempty"` Id *string `json:"id,omitempty"` + ImageType *DiskConfigImageType `json:"image_type,omitempty"` Iommu *bool `json:"iommu,omitempty"` NumQueues *int `json:"num_queues,omitempty"` Path *string `json:"path,omitempty"` @@ -139,6 +150,9 @@ type DiskConfig struct { VhostUser *bool `json:"vhost_user,omitempty"` } +// DiskConfigImageType defines model for DiskConfig.ImageType. +type DiskConfigImageType string + // FsConfig defines model for FsConfig. type FsConfig struct { Id *string `json:"id,omitempty"` @@ -196,11 +210,14 @@ type NetConfig struct { Mac *string `json:"mac,omitempty"` // Mask Must be a valid IPv4 netmask if ip is an IPv4 address or a valid IPv6 netmask if ip is an IPv6 address. - Mask *string `json:"mask,omitempty"` - Mtu *int `json:"mtu,omitempty"` - NumQueues *int `json:"num_queues,omitempty"` - PciSegment *int16 `json:"pci_segment,omitempty"` - QueueSize *int `json:"queue_size,omitempty"` + Mask *string `json:"mask,omitempty"` + Mtu *int `json:"mtu,omitempty"` + NumQueues *int `json:"num_queues,omitempty"` + OffloadCsum *bool `json:"offload_csum,omitempty"` + OffloadTso *bool `json:"offload_tso,omitempty"` + OffloadUfo *bool `json:"offload_ufo,omitempty"` + PciSegment *int16 `json:"pci_segment,omitempty"` + QueueSize *int `json:"queue_size,omitempty"` // RateLimiterConfig Defines an IO rate limiter with independent bytes/s and ops/s limits. Limits are defined by configuring each of the _bandwidth_ and _ops_ token buckets. RateLimiterConfig *RateLimiterConfig `json:"rate_limiter_config,omitempty"` @@ -413,6 +430,15 @@ type VmResize struct { DesiredVcpus *int `json:"desired_vcpus,omitempty"` } +// VmResizeDisk defines model for VmResizeDisk. +type VmResizeDisk struct { + // DesiredSize desired disk size in bytes + DesiredSize *int64 `json:"desired_size,omitempty"` + + // Id disk identifier + Id *string `json:"id,omitempty"` +} + // VmResizeZone defines model for VmResizeZone. type VmResizeZone struct { // DesiredRam desired memory zone size in bytes @@ -484,6 +510,9 @@ type PutVmRemoveDeviceJSONRequestBody = VmRemoveDevice // PutVmResizeJSONRequestBody defines body for PutVmResize for application/json ContentType. type PutVmResizeJSONRequestBody = VmResize +// PutVmResizeDiskJSONRequestBody defines body for PutVmResizeDisk for application/json ContentType. +type PutVmResizeDiskJSONRequestBody = VmResizeDisk + // PutVmResizeZoneJSONRequestBody defines body for PutVmResizeZone for application/json ContentType. type PutVmResizeZoneJSONRequestBody = VmResizeZone @@ -655,6 +684,11 @@ type ClientInterface interface { PutVmResize(ctx context.Context, body PutVmResizeJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // PutVmResizeDiskWithBody request with any body + PutVmResizeDiskWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PutVmResizeDisk(ctx context.Context, body PutVmResizeDiskJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // PutVmResizeZoneWithBody request with any body PutVmResizeZoneWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -1087,6 +1121,30 @@ func (c *Client) PutVmResize(ctx context.Context, body PutVmResizeJSONRequestBod return c.Client.Do(req) } +func (c *Client) PutVmResizeDiskWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPutVmResizeDiskRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) PutVmResizeDisk(ctx context.Context, body PutVmResizeDiskJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPutVmResizeDiskRequest(c.Server, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) PutVmResizeZoneWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewPutVmResizeZoneRequestWithBody(c.Server, contentType, body) if err != nil { @@ -1952,6 +2010,46 @@ func NewPutVmResizeRequestWithBody(server string, contentType string, body io.Re return req, nil } +// NewPutVmResizeDiskRequest calls the generic PutVmResizeDisk builder with application/json body +func NewPutVmResizeDiskRequest(server string, body PutVmResizeDiskJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPutVmResizeDiskRequestWithBody(server, "application/json", bodyReader) +} + +// NewPutVmResizeDiskRequestWithBody generates requests for PutVmResizeDisk with any type of body +func NewPutVmResizeDiskRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/vm.resize-disk") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PUT", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + // NewPutVmResizeZoneRequest calls the generic PutVmResizeZone builder with application/json body func NewPutVmResizeZoneRequest(server string, body PutVmResizeZoneJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader @@ -2376,6 +2474,11 @@ type ClientWithResponsesInterface interface { PutVmResizeWithResponse(ctx context.Context, body PutVmResizeJSONRequestBody, reqEditors ...RequestEditorFn) (*PutVmResizeResponse, error) + // PutVmResizeDiskWithBodyWithResponse request with any body + PutVmResizeDiskWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PutVmResizeDiskResponse, error) + + PutVmResizeDiskWithResponse(ctx context.Context, body PutVmResizeDiskJSONRequestBody, reqEditors ...RequestEditorFn) (*PutVmResizeDiskResponse, error) + // PutVmResizeZoneWithBodyWithResponse request with any body PutVmResizeZoneWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PutVmResizeZoneResponse, error) @@ -2842,6 +2945,27 @@ func (r PutVmResizeResponse) StatusCode() int { return 0 } +type PutVmResizeDiskResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r PutVmResizeDiskResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PutVmResizeDiskResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type PutVmResizeZoneResponse struct { Body []byte HTTPResponse *http.Response @@ -3316,6 +3440,23 @@ func (c *ClientWithResponses) PutVmResizeWithResponse(ctx context.Context, body return ParsePutVmResizeResponse(rsp) } +// PutVmResizeDiskWithBodyWithResponse request with arbitrary body returning *PutVmResizeDiskResponse +func (c *ClientWithResponses) PutVmResizeDiskWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PutVmResizeDiskResponse, error) { + rsp, err := c.PutVmResizeDiskWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePutVmResizeDiskResponse(rsp) +} + +func (c *ClientWithResponses) PutVmResizeDiskWithResponse(ctx context.Context, body PutVmResizeDiskJSONRequestBody, reqEditors ...RequestEditorFn) (*PutVmResizeDiskResponse, error) { + rsp, err := c.PutVmResizeDisk(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePutVmResizeDiskResponse(rsp) +} + // PutVmResizeZoneWithBodyWithResponse request with arbitrary body returning *PutVmResizeZoneResponse func (c *ClientWithResponses) PutVmResizeZoneWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PutVmResizeZoneResponse, error) { rsp, err := c.PutVmResizeZoneWithBody(ctx, contentType, body, reqEditors...) @@ -3849,6 +3990,22 @@ func ParsePutVmResizeResponse(rsp *http.Response) (*PutVmResizeResponse, error) return response, nil } +// ParsePutVmResizeDiskResponse parses an HTTP response from a PutVmResizeDiskWithResponse call +func ParsePutVmResizeDiskResponse(rsp *http.Response) (*PutVmResizeDiskResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PutVmResizeDiskResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + // ParsePutVmResizeZoneResponse parses an HTTP response from a PutVmResizeZoneWithResponse call func ParsePutVmResizeZoneResponse(rsp *http.Response) (*PutVmResizeZoneResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) diff --git a/specs/cloud-hypervisor/api-v0.3.0/cloud-hypervisor.yaml b/specs/cloud-hypervisor/api-v0.3.0/cloud-hypervisor.yaml index e4a76f6b..1bd0ba50 100644 --- a/specs/cloud-hypervisor/api-v0.3.0/cloud-hypervisor.yaml +++ b/specs/cloud-hypervisor/api-v0.3.0/cloud-hypervisor.yaml @@ -163,6 +163,22 @@ paths: 429: description: The VM instance could not be resized because a cpu removal is still pending. + /vm.resize-disk: + put: + summary: Resize a disk + requestBody: + description: Resizes a disk attached to the VM + content: + application/json: + schema: + $ref: "#/components/schemas/VmResizeDisk" + required: true + responses: + 204: + description: The disk was successfully resized. + 500: + description: The disk could not be resized. + /vm.resize-zone: put: summary: Resize a memory zone @@ -687,6 +703,9 @@ components: default: false max_phys_bits: type: integer + nested: + type: boolean + default: true affinity: type: array items: @@ -922,6 +941,17 @@ components: type: array items: $ref: "#/components/schemas/VirtQueueAffinity" + backing_files: + type: boolean + default: false + image_type: + type: string + enum: + - FixedVhd + - Qcow2 + - Raw + - Vhdx + NetConfig: type: object @@ -966,6 +996,15 @@ components: format: int16 rate_limiter_config: $ref: "#/components/schemas/RateLimiterConfig" + offload_tso: + type: boolean + default: true + offload_ufo: + type: boolean + default: true + offload_csum: + type: boolean + default: true RngConfig: required: @@ -1194,6 +1233,17 @@ components: type: integer format: int64 + VmResizeDisk: + type: object + properties: + id: + description: disk identifier + type: string + desired_size: + description: desired disk size in bytes + type: integer + format: int64 + VmResizeZone: type: object properties: