Skip to content

Commit

Permalink
Add new RunStrategyOnce option to VM spec
Browse files Browse the repository at this point in the history
Signed-off-by: David Vossel <[email protected]>
  • Loading branch information
davidvossel committed Feb 11, 2022
1 parent 2d8bc49 commit 62bbcd4
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 8 deletions.
13 changes: 8 additions & 5 deletions pkg/virt-api/rest/subresource.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ func (app *SubresourceAPIApp) RestartVMRequestHandler(request *restful.Request,
// RunStrategyManual -> send restart request
// RunStrategyAlways -> send restart request
// RunStrategyRerunOnFailure -> send restart request
// RunStrategyOnce -> doesn't make sense
name := request.PathParameter("name")
namespace := request.PathParameter("namespace")

Expand Down Expand Up @@ -356,8 +357,8 @@ func (app *SubresourceAPIApp) RestartVMRequestHandler(request *restful.Request,
writeError(errors.NewInternalError(err), response)
return
}
if runStrategy == v1.RunStrategyHalted {
writeError(errors.NewConflict(v1.Resource("virtualmachine"), name, fmt.Errorf("%v does not support manual restart requests", v1.RunStrategyHalted)), response)
if runStrategy == v1.RunStrategyHalted || runStrategy == v1.RunStrategyOnce {
writeError(errors.NewConflict(v1.Resource("virtualmachine"), name, fmt.Errorf("%v does not support manual restart requests", runStrategy)), response)
return
}

Expand Down Expand Up @@ -499,6 +500,7 @@ func (app *SubresourceAPIApp) StartVMRequestHandler(request *restful.Request, re
// RunStrategyManual -> send start request
// RunStrategyAlways -> doesn't make sense
// RunStrategyRerunOnFailure -> doesn't make sense
// RunStrategyOnce -> doesn't make sense
switch runStrategy {
case v1.RunStrategyHalted:
pausedStartStrategy := v1.StartStrategyPaused
Expand Down Expand Up @@ -546,8 +548,8 @@ func (app *SubresourceAPIApp) StartVMRequestHandler(request *restful.Request, re
}
log.Log.Object(vm).V(4).Infof(patchingVMStatusFmt, bodyString)
patchErr = app.statusUpdater.PatchStatus(vm, types.JSONPatchType, []byte(bodyString), &k8smetav1.PatchOptions{DryRun: bodyStruct.DryRun})
case v1.RunStrategyAlways:
writeError(errors.NewConflict(v1.Resource("virtualmachine"), name, fmt.Errorf("%v does not support manual start requests", v1.RunStrategyAlways)), response)
case v1.RunStrategyAlways, v1.RunStrategyOnce:
writeError(errors.NewConflict(v1.Resource("virtualmachine"), name, fmt.Errorf("%v does not support manual start requests", runStrategy)), response)
return
}

Expand All @@ -568,6 +570,7 @@ func (app *SubresourceAPIApp) StopVMRequestHandler(request *restful.Request, res
// RunStrategyManual -> send stop request
// RunStrategyAlways -> spec.running = false
// RunStrategyRerunOnFailure -> spec.running = false
// RunStrategyOnce -> spec.running = false

name := request.PathParameter("name")
namespace := request.PathParameter("namespace")
Expand Down Expand Up @@ -641,7 +644,7 @@ func (app *SubresourceAPIApp) StopVMRequestHandler(request *restful.Request, res
}
log.Log.Object(vm).V(4).Infof(patchingVMStatusFmt, bodyString)
patchErr = app.statusUpdater.PatchStatus(vm, patchType, []byte(bodyString), &k8smetav1.PatchOptions{DryRun: bodyStruct.DryRun})
case v1.RunStrategyRerunOnFailure, v1.RunStrategyAlways:
case v1.RunStrategyRerunOnFailure, v1.RunStrategyAlways, v1.RunStrategyOnce:
bodyString := getRunningJson(vm, false)
log.Log.Object(vm).V(4).Infof(patchingVMFmt, bodyString)
_, patchErr = app.virtCli.VirtualMachine(namespace).Patch(vm.GetName(), patchType, []byte(bodyString), &k8smetav1.PatchOptions{DryRun: bodyStruct.DryRun})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import (
virtconfig "kubevirt.io/kubevirt/pkg/virt-config"
)

var validRunStrategies = []v1.VirtualMachineRunStrategy{v1.RunStrategyHalted, v1.RunStrategyManual, v1.RunStrategyAlways, v1.RunStrategyRerunOnFailure}
var validRunStrategies = []v1.VirtualMachineRunStrategy{v1.RunStrategyHalted, v1.RunStrategyManual, v1.RunStrategyAlways, v1.RunStrategyRerunOnFailure, v1.RunStrategyOnce}

type CloneAuthFunc func(pvcNamespace, pvcName, saNamespace, saName string) (bool, string, error)

Expand Down
22 changes: 20 additions & 2 deletions pkg/virt-controller/watch/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,17 @@ func (c *VMController) startStop(vm *virtv1.VirtualMachine, vmi *virtv1.VirtualM
log.Log.Object(vm).Infof("%s with VMI in phase %s due to runStrategy: %s", stoppingVmMsg, vmi.Status.Phase, runStrategy)
err := c.stopVMI(vm, vmi)
return &syncErrorImpl{fmt.Errorf(failureDeletingVmiErrFormat, err), VMIFailedDeleteReason}
case virtv1.RunStrategyOnce:
if vmi == nil {
log.Log.Object(vm).Infof("%s due to start request and runStrategy: %s", startingVmMsg, runStrategy)

err := c.startVMI(vm)
if err != nil {
return &syncErrorImpl{fmt.Errorf(startingVMIFailureFmt, err), FailedCreateReason}
}
}

return nil
default:
return &syncErrorImpl{fmt.Errorf("unknown runstrategy: %s", runStrategy), FailedCreateReason}
}
Expand Down Expand Up @@ -787,6 +798,11 @@ func isSetToStart(vm *virtv1.VirtualMachine, vmi *virtv1.VirtualMachineInstance)
return vmi.Status.Phase != virtv1.Succeeded
}
return true
case virtv1.RunStrategyOnce:
if vmi == nil {
return true
}
return false
default:
// Shouldn't ever be here, but...
return false
Expand Down Expand Up @@ -908,7 +924,9 @@ func shouldClearStartFailure(vm *virtv1.VirtualMachine, vmi *virtv1.VirtualMachi
return false
}

if runStrategy != virtv1.RunStrategyAlways && runStrategy != virtv1.RunStrategyRerunOnFailure {
if runStrategy != virtv1.RunStrategyAlways &&
runStrategy != virtv1.RunStrategyRerunOnFailure &&
runStrategy != virtv1.RunStrategyOnce {
return true
}

Expand Down Expand Up @@ -1663,7 +1681,7 @@ func (c *VMController) isVirtualMachineStatusCrashLoopBackOff(vm *virtv1.Virtual

if vm.Status.StartFailure != nil &&
vm.Status.StartFailure.ConsecutiveFailCount > 0 &&
(runStrategy == virtv1.RunStrategyAlways || runStrategy == virtv1.RunStrategyRerunOnFailure) {
(runStrategy == virtv1.RunStrategyAlways || runStrategy == virtv1.RunStrategyRerunOnFailure || runStrategy == virtv1.RunStrategyOnce) {
return true
}

Expand Down
3 changes: 3 additions & 0 deletions staging/src/kubevirt.io/api/core/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,9 @@ const (
// VMI will initially be running--and restarted if a failure occurs.
// It will not be restarted upon successful completion.
RunStrategyRerunOnFailure VirtualMachineRunStrategy = "RerunOnFailure"
// VMI will run once and not be restarted upon completion regardless
// if the completion is of phase Failure or Success
RunStrategyOnce VirtualMachineRunStrategy = "Once"
)

// VirtualMachineSpec describes how the proper VirtualMachine
Expand Down

0 comments on commit 62bbcd4

Please sign in to comment.