Simplify state reconciliation and support changing Softnet settings (#364)

* Simplify state reconciliation and support changing Softnet settings

* Remove unused "updateFunc" parameter from syncOnDiskVMs()

* Don't take an address of a loop variable

* ensure → ensures

* updateVMState(): don't forget to update VMState

* Introduce TestSpecUpdateSoftnet integration test

* Update OpenAPI specification to include generation/observedGeneration
This commit is contained in:
Nikolay Edigaryev
2025-11-06 20:56:31 +04:00
committed by GitHub
parent 00d27d1fa0
commit bafcf6fac2
16 changed files with 690 additions and 166 deletions
+13 -1
View File
@@ -3,11 +3,12 @@ package client
import (
"context"
"fmt"
"github.com/cirruslabs/orchard/pkg/resource/v1"
"net"
"net/http"
"net/url"
"strconv"
"github.com/cirruslabs/orchard/pkg/resource/v1"
)
type VMsService struct {
@@ -78,6 +79,17 @@ func (service *VMsService) Update(ctx context.Context, vm v1.VM) (*v1.VM, error)
return &updatedVM, nil
}
func (service *VMsService) UpdateState(ctx context.Context, vm v1.VM) (*v1.VM, error) {
var updatedVM v1.VM
err := service.client.request(ctx, http.MethodPut, fmt.Sprintf("vms/%s/state", url.PathEscape(vm.Name)),
vm, &updatedVM, nil)
if err != nil {
return &updatedVM, err
}
return &updatedVM, nil
}
func (service *VMsService) Delete(ctx context.Context, name string) error {
err := service.client.request(ctx, http.MethodDelete, fmt.Sprintf("vms/%s", url.PathEscape(name)),
nil, nil, nil)
+14
View File
@@ -0,0 +1,14 @@
package v1_test
import (
"testing"
v1 "github.com/cirruslabs/orchard/pkg/resource/v1"
"github.com/google/go-cmp/cmp"
)
// TestVM ensures that v1.VM and its embedded structs can be compared
// using github.com/google/go-cmp/cmp without causing panics.
func TestVM(t *testing.T) {
cmp.Equal(v1.VM{}, v1.VM{})
}
+34 -14
View File
@@ -22,18 +22,17 @@ type Meta struct {
}
type VM struct {
Image string `json:"image,omitempty"`
ImagePullPolicy ImagePullPolicy `json:"imagePullPolicy,omitempty"`
CPU uint64 `json:"cpu,omitempty"`
Memory uint64 `json:"memory,omitempty"`
DiskSize uint64 `json:"diskSize,omitempty"`
NetSoftnetDeprecated bool `json:"net-softnet,omitempty"`
NetSoftnet bool `json:"netSoftnet,omitempty"`
NetSoftnetAllow []string `json:"netSoftnetAllow,omitempty"`
NetSoftnetBlock []string `json:"netSoftnetBlock,omitempty"`
NetBridged string `json:"net-bridged,omitempty"`
Headless bool `json:"headless,omitempty"`
Nested bool `json:"nested,omitempty"`
Image string `json:"image,omitempty"`
ImagePullPolicy ImagePullPolicy `json:"imagePullPolicy,omitempty"`
CPU uint64 `json:"cpu,omitempty"`
Memory uint64 `json:"memory,omitempty"`
DiskSize uint64 `json:"diskSize,omitempty"`
NetBridged string `json:"net-bridged,omitempty"`
Headless bool `json:"headless,omitempty"`
Nested bool `json:"nested,omitempty"`
VMSpec
VMState
// Status field is used to track the lifecycle of the VM associated with this resource.
Status VMStatus `json:"status,omitempty"`
@@ -88,9 +87,29 @@ type VM struct {
ScheduledAt time.Time `json:"scheduled_at,omitempty"`
StartedAt time.Time `json:"started_at,omitempty"`
// Generation is incremented by the controller each time
// the resource's specification is changed.
//
// At some point we'll move Generation field to the Metadata
// structure as it can be useful for other resources too.
Generation uint64 `json:"generation"`
Meta
}
type VMSpec struct {
NetSoftnetDeprecated bool `json:"net-softnet,omitempty"`
NetSoftnet bool `json:"netSoftnet,omitempty"`
NetSoftnetAllow []string `json:"netSoftnetAllow,omitempty"`
NetSoftnetBlock []string `json:"netSoftnetBlock,omitempty"`
}
type VMState struct {
// ObservedGeneration corresponds to the Generation of VM specification
// on which the worker had acted upon.
ObservedGeneration uint64 `json:"observedGeneration"`
}
type Event struct {
Kind EventKind `json:"kind,omitempty"`
Timestamp int64 `json:"timestamp,omitempty"`
@@ -134,8 +153,9 @@ const (
type ControllerCapability string
const (
ControllerCapabilityRPCV1 ControllerCapability = "rpc-v1"
ControllerCapabilityRPCV2 ControllerCapability = "rpc-v2"
ControllerCapabilityRPCV1 ControllerCapability = "rpc-v1"
ControllerCapabilityRPCV2 ControllerCapability = "rpc-v2"
ControllerCapabilityVMStateEndpoint ControllerCapability = "vm-state-endpoint"
)
type ControllerCapabilities []ControllerCapability