Better state syncing and other improvements (#24)

This commit is contained in:
Fedor Korotkov
2023-03-01 11:42:16 -05:00
committed by GitHub
parent 8df31f7c2d
commit 165662bb0a
24 changed files with 276 additions and 128 deletions
+46 -10
View File
@@ -4,12 +4,14 @@ import (
"context"
"fmt"
"github.com/cirruslabs/orchard/pkg/resource/v1"
"go.uber.org/zap"
"strconv"
"sync"
)
type VM struct {
id string
vmResource *v1.VM
id string
Resource v1.VM
ctx context.Context
cancel context.CancelFunc
@@ -17,12 +19,12 @@ type VM struct {
wg *sync.WaitGroup
}
func NewVM(vmResource *v1.VM) *VM {
func NewVM(vmResource v1.VM, logger *zap.SugaredLogger) *VM {
ctx, cancel := context.WithCancel(context.Background())
vm := &VM{
id: fmt.Sprintf("orchard-%s-%s", vmResource.Name, vmResource.UID),
vmResource: vmResource,
id: fmt.Sprintf("orchard-%s-%s", vmResource.Name, vmResource.UID),
Resource: vmResource,
ctx: ctx,
cancel: cancel,
@@ -35,8 +37,13 @@ func NewVM(vmResource *v1.VM) *VM {
go func() {
defer vm.wg.Done()
// Optimistic set the status to running. Will be synced later by the worker loop.
vm.Resource.Status = v1.VMStatusRunning
if err := vm.run(vm.ctx); err != nil {
vmResource.Status = v1.VMStatusFailed
logger.Errorf("VM %s failed: %v", vm.id, err)
vm.Resource.Status = v1.VMStatusFailed
} else {
vm.Resource.Status = v1.VMStatusStopped
}
}()
@@ -44,12 +51,37 @@ func NewVM(vmResource *v1.VM) *VM {
}
func (vm *VM) run(ctx context.Context) error {
_, _, err := Tart(ctx, "clone", vm.vmResource.Image, vm.id)
_, _, err := Tart(ctx, "clone", vm.Resource.Image, vm.id)
if err != nil {
return err
}
_, _, err = Tart(ctx, "run", vm.id)
if vm.Resource.Memory != 0 {
_, _, err = Tart(ctx, "set", "--memory", strconv.FormatUint(vm.Resource.Memory, 10), vm.id)
if err != nil {
return err
}
}
if vm.Resource.CPU != 0 {
_, _, err = Tart(ctx, "set", "--cpu", strconv.FormatUint(vm.Resource.CPU, 10), vm.id)
if err != nil {
return err
}
}
var runArgs = []string{"run"}
if vm.Resource.Softnet {
runArgs = append(runArgs, "--net-softnet")
}
if vm.Resource.Headless {
runArgs = append(runArgs, "--no-graphics")
}
runArgs = append(runArgs, vm.id)
_, _, err = Tart(ctx, runArgs...)
if err != nil {
return err
}
@@ -57,13 +89,17 @@ func (vm *VM) run(ctx context.Context) error {
return nil
}
func (vm *VM) Close() error {
_, _, _ = Tart(context.Background(), "stop", "--timeout", "5", vm.id)
func (vm *VM) Stop() error {
_, _, _ = Tart(context.Background(), "stop", vm.id)
vm.cancel()
vm.wg.Wait()
return nil
}
func (vm *VM) Delete() error {
_, _, err := Tart(context.Background(), "delete", vm.id)
if err != nil {
return fmt.Errorf("%w: failed to delete VM %s: %v", ErrFailed, vm.id, err)
+26 -6
View File
@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
v1 "github.com/cirruslabs/orchard/pkg/resource/v1"
"go.uber.org/zap"
)
var ErrFailed = errors.New("VM manager failed")
@@ -18,13 +19,13 @@ func New() *VMManager {
}
}
func (vmm *VMManager) Exists(vmResource *v1.VM) bool {
func (vmm *VMManager) Exists(vmResource v1.VM) bool {
_, ok := vmm.vms[vmResource.UID]
return ok
}
func (vmm *VMManager) Get(vmResource *v1.VM) (*VM, error) {
func (vmm *VMManager) Get(vmResource v1.VM) (*VM, error) {
managedVM, ok := vmm.vms[vmResource.UID]
if !ok {
return nil, fmt.Errorf("%w: VM does not exist", ErrFailed)
@@ -33,25 +34,34 @@ func (vmm *VMManager) Get(vmResource *v1.VM) (*VM, error) {
return managedVM, nil
}
func (vmm *VMManager) Create(vmResource *v1.VM) (*VM, error) {
func (vmm *VMManager) Create(vmResource v1.VM, logger *zap.SugaredLogger) (*VM, error) {
if _, ok := vmm.vms[vmResource.UID]; ok {
return nil, fmt.Errorf("%w: VM already exists", ErrFailed)
}
managedVM := NewVM(vmResource)
managedVM := NewVM(vmResource, logger)
vmm.vms[vmResource.UID] = managedVM
return managedVM, nil
}
func (vmm *VMManager) Delete(vmResource *v1.VM) error {
func (vmm *VMManager) Stop(vmResource v1.VM) error {
managedVM, ok := vmm.vms[vmResource.UID]
if !ok {
return fmt.Errorf("%w: VM does not exist", ErrFailed)
}
if err := managedVM.Close(); err != nil {
return managedVM.Stop()
}
func (vmm *VMManager) Delete(vmResource v1.VM) error {
managedVM, ok := vmm.vms[vmResource.UID]
if !ok {
return fmt.Errorf("%w: VM does not exist", ErrFailed)
}
if err := managedVM.Delete(); err != nil {
return err
}
@@ -59,3 +69,13 @@ func (vmm *VMManager) Delete(vmResource *v1.VM) error {
return nil
}
func (vmm *VMManager) List() []*VM {
var vms []*VM
for _, vm := range vmm.vms {
vms = append(vms, vm)
}
return vms
}