Skip to content

Commit

Permalink
Merge pull request #273 from davidvossel/add-more-failure-conditions-v1
Browse files Browse the repository at this point in the history
Add condition to KubeVirtMachine when VM Creation Fails
  • Loading branch information
k8s-ci-robot authored Dec 15, 2023
2 parents c2cd191 + e1faf70 commit 35cc2f1
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 3 deletions.
4 changes: 4 additions & 0 deletions api/v1alpha1/condition_consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ const (
// WaitingForBootstrapDataReason (Severity=Info) documents a KubevirtMachine waiting for the bootstrap
// script to be ready before starting to create the VM that provides the KubevirtMachine infrastructure.
WaitingForBootstrapDataReason = "WaitingForBootstrapData"

// VMCreateFailed (Severity=Error) documents a KubevirtMachine that is unable to create the
// corresponding VM object.
VMCreateFailedReason = "VMCreateFailed"
)

const (
Expand Down
4 changes: 3 additions & 1 deletion controllers/kubevirtmachine_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ import (
gocontext "context"
"fmt"
"regexp"
"sigs.k8s.io/controller-runtime/pkg/builder"
"time"

"sigs.k8s.io/controller-runtime/pkg/builder"

"github.com/pkg/errors"
"gopkg.in/yaml.v3"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -264,6 +265,7 @@ func (r *KubevirtMachineReconciler) reconcileNormal(ctx *context.MachineContext)
if !isTerminal && !externalMachine.Exists() {
ctx.KubevirtMachine.Status.Ready = false
if err := externalMachine.Create(ctx.Context); err != nil {
conditions.MarkFalse(ctx.KubevirtMachine, infrav1.VMProvisionedCondition, infrav1.VMCreateFailedReason, clusterv1.ConditionSeverityError, fmt.Sprintf("Failed vm creation: %v", err))
return ctrl.Result{}, errors.Wrap(err, "failed to create VM instance")
}
ctx.Logger.Info("VM Created, waiting on vm to be provisioned.")
Expand Down
48 changes: 46 additions & 2 deletions controllers/kubevirtmachine_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"

machinemocks "sigs.k8s.io/cluster-api-provider-kubevirt/pkg/kubevirt/mock"
Expand Down Expand Up @@ -318,7 +319,7 @@ var _ = Describe("reconcile a kubevirt machine", func() {

})

setupClient := func(machineFactory kubevirt.MachineFactory, objects []client.Object) {
setupClientWithInterceptors := func(machineFactory kubevirt.MachineFactory, objects []client.Object, interceptorFuncs interceptor.Funcs) {
machineContext = &context.MachineContext{
Context: gocontext.Background(),
Cluster: cluster,
Expand All @@ -328,15 +329,21 @@ var _ = Describe("reconcile a kubevirt machine", func() {
Logger: testLogger,
}

fakeClient = fake.NewClientBuilder().WithScheme(testing.SetupScheme()).WithObjects(objects...).WithStatusSubresource(objects...).Build()
fakeClient = fake.NewClientBuilder().WithScheme(testing.SetupScheme()).WithObjects(objects...).WithStatusSubresource(objects...).WithInterceptorFuncs(interceptorFuncs).Build()
kubevirtMachineReconciler = KubevirtMachineReconciler{
Client: fakeClient,
WorkloadCluster: workloadClusterMock,
InfraCluster: infraClusterMock,
MachineFactory: machineFactory,
}
}

setupClient := func(machineFactory kubevirt.MachineFactory, objects []client.Object) {

setupClientWithInterceptors(machineFactory, objects, interceptor.Funcs{})

}

AfterEach(func() {})

It("should create KubeVirt VM", func() {
Expand Down Expand Up @@ -879,6 +886,43 @@ var _ = Describe("reconcile a kubevirt machine", func() {
Expect(conditions[0].Type).To(Equal(infrav1.VMProvisionedCondition))
Expect(conditions[0].Reason).To(Equal(infrav1.WaitingForBootstrapDataReason))
})

It("adds a failed VMProvisionedCondition with reason VMCreateFailed when failng to create VM", func() {
objects := []client.Object{
cluster,
kubevirtCluster,
machine,
kubevirtMachine,
sshKeySecret,
bootstrapSecret,
}

injectErr := interceptor.Funcs{
Create: func(ctx gocontext.Context, client client.WithWatch, obj client.Object, opts ...client.CreateOption) error {

_, ok := obj.(*kubevirtv1.VirtualMachine)
if ok {
return errors.New("vm create error")
}
return nil
},
}

setupClientWithInterceptors(kubevirt.DefaultMachineFactory{}, objects, injectErr)

infraClusterMock.EXPECT().GenerateInfraClusterClient(kubevirtMachine.Spec.InfraClusterSecretRef, kubevirtMachine.Namespace, machineContext.Context).Return(fakeClient, kubevirtMachine.Namespace, nil)

_, err := kubevirtMachineReconciler.reconcileNormal(machineContext)

Expect(err).Should(HaveOccurred())

// should expect condition
conditions := machineContext.KubevirtMachine.GetConditions()
Expect(conditions[0].Type).To(Equal(infrav1.VMProvisionedCondition))
Expect(conditions[0].Status).To(Equal(corev1.ConditionFalse))
Expect(conditions[0].Reason).To(Equal(infrav1.VMCreateFailedReason))
})

It("adds a succeeded VMProvisionedCondition", func() {
vmiReadyCondition := kubevirtv1.VirtualMachineInstanceCondition{
Type: kubevirtv1.VirtualMachineInstanceReady,
Expand Down

0 comments on commit 35cc2f1

Please sign in to comment.