Skip to content

Commit 1ab9fc5

Browse files
authored
Merge pull request kubernetes-sigs#272 from nunnatsa/reflect-vm-status-to-cluster
Reflect the VM statuses to the KubeVirtCluster status
2 parents 35cc2f1 + dc8c7bd commit 1ab9fc5

File tree

13 files changed

+384
-59
lines changed

13 files changed

+384
-59
lines changed

.github/workflows/test.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
uses: golangci/golangci-lint-action@v3
5555
with:
5656
args: --timeout=5m -v
57-
version: v1.54.2
57+
version: v1.55.2
5858

5959
check-gen:
6060
runs-on: ubuntu-latest

api/v1alpha1/kubevirtmachine_types.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ type VirtualMachineBootstrapCheckSpec struct {
7171
// KubevirtMachineStatus defines the observed state of KubevirtMachine.
7272
type KubevirtMachineStatus struct {
7373
// Ready denotes that the machine is ready
74-
// +optional
74+
// +kubebuilder:default=false
7575
Ready bool `json:"ready"`
7676

7777
// LoadBalancerConfigured denotes that the machine has been
@@ -134,6 +134,8 @@ type KubevirtMachineStatus struct {
134134
// +kubebuilder:object:root=true
135135
// +kubebuilder:storageversion
136136
// +kubebuilder:subresource:status
137+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
138+
// +kubebuilder:printcolumn:name="Ready",type="boolean",JSONPath=".status.ready",description="Is machine ready"
137139

138140
// KubevirtMachine is the Schema for the kubevirtmachines API.
139141
type KubevirtMachine struct {

clusterkubevirtadm/cmd/credentials/credentials.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import (
2626
"k8s.io/apimachinery/pkg/api/errors"
2727
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2828
k8sclient "k8s.io/client-go/kubernetes"
29+
kubevirtcore "kubevirt.io/api/core"
30+
cdicore "kubevirt.io/containerized-data-importer-api/pkg/apis/core"
2931

3032
"sigs.k8s.io/cluster-api-provider-kubevirt/clusterkubevirtadm/common"
3133
)
@@ -148,10 +150,15 @@ func generateRole(cmdCtx cmdContext) *rbacv1.Role {
148150
},
149151
Rules: []rbacv1.PolicyRule{
150152
{
151-
APIGroups: []string{"kubevirt.io"},
153+
APIGroups: []string{kubevirtcore.GroupName},
152154
Resources: []string{"virtualmachines", "virtualmachineinstances"},
153155
Verbs: []string{rbacv1.VerbAll},
154156
},
157+
{
158+
APIGroups: []string{cdicore.GroupName},
159+
Resources: []string{"datavolumes"},
160+
Verbs: []string{"get", "list", "watch"},
161+
},
155162
{
156163
APIGroups: []string{""},
157164
Resources: []string{"secrets", "services"},

clusterkubevirtadm/cmd/credentials/credentials_test.go

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ package credentials
22

33
import (
44
"context"
5-
65
. "github.com/onsi/ginkgo/v2"
76
. "github.com/onsi/gomega"
87
corev1 "k8s.io/api/core/v1"
98
rbacv1 "k8s.io/api/rbac/v1"
109
"k8s.io/apimachinery/pkg/api/errors"
1110
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1211
"k8s.io/client-go/kubernetes/fake"
12+
kubevirtcore "kubevirt.io/api/core"
13+
cdicore "kubevirt.io/containerized-data-importer-api/pkg/apis/core"
1314

1415
"sigs.k8s.io/cluster-api-provider-kubevirt/clusterkubevirtadm/common"
1516
)
@@ -118,21 +119,18 @@ var _ = Describe("test credentials common function", func() {
118119
Expect(roles.Items).To(HaveLen(1))
119120

120121
Expect(roles.Items[0].Name).Should(Equal(roleName))
121-
Expect(roles.Items[0].Rules).Should(HaveLen(2))
122-
Expect(roles.Items[0].Rules[0].APIGroups).Should(HaveLen(1))
123-
Expect(roles.Items[0].Rules[0].APIGroups[0]).Should(Equal("kubevirt.io"))
124-
Expect(roles.Items[0].Rules[0].Resources).Should(HaveLen(2))
125-
Expect(roles.Items[0].Rules[0].Resources[0]).Should(Equal("virtualmachines"))
126-
Expect(roles.Items[0].Rules[0].Resources[1]).Should(Equal("virtualmachineinstances"))
127-
Expect(roles.Items[0].Rules[0].Verbs).Should(HaveLen(1))
128-
Expect(roles.Items[0].Rules[0].Verbs[0]).Should(Equal(rbacv1.VerbAll))
129-
Expect(roles.Items[0].Rules[1].APIGroups).Should(HaveLen(1))
130-
Expect(roles.Items[0].Rules[1].APIGroups[0]).Should(Equal(""))
131-
Expect(roles.Items[0].Rules[1].Resources).Should(HaveLen(2))
132-
Expect(roles.Items[0].Rules[1].Resources[0]).Should(Equal("secrets"))
133-
Expect(roles.Items[0].Rules[1].Resources[1]).Should(Equal("services"))
134-
Expect(roles.Items[0].Rules[1].Verbs).Should(HaveLen(1))
135-
Expect(roles.Items[0].Rules[1].Verbs[0]).Should(Equal(rbacv1.VerbAll))
122+
Expect(roles.Items[0].Rules).Should(HaveLen(3))
123+
Expect(roles.Items[0].Rules[0].APIGroups).Should(And(HaveLen(1), ContainElements(kubevirtcore.GroupName)))
124+
Expect(roles.Items[0].Rules[0].Resources).Should(And(HaveLen(2), ContainElements("virtualmachines", "virtualmachineinstances")))
125+
Expect(roles.Items[0].Rules[0].Verbs).Should(And(HaveLen(1), ContainElements(rbacv1.VerbAll)))
126+
127+
Expect(roles.Items[0].Rules[1].APIGroups).Should(And(HaveLen(1), ContainElements(cdicore.GroupName)))
128+
Expect(roles.Items[0].Rules[1].Resources).Should(And(HaveLen(1), ContainElements("datavolumes")))
129+
Expect(roles.Items[0].Rules[1].Verbs).Should(And(HaveLen(3), ContainElements("get", "list", "watch")))
130+
131+
Expect(roles.Items[0].Rules[2].APIGroups).Should(And(HaveLen(1), ContainElements("")))
132+
Expect(roles.Items[0].Rules[2].Resources).Should(And(HaveLen(2), ContainElements("secrets", "services")))
133+
Expect(roles.Items[0].Rules[2].Verbs).Should(And(HaveLen(1), ContainElements(rbacv1.VerbAll)))
136134
})
137135

138136
It("create should return error if the Role is already exist", func() {

config/crd/bases/infrastructure.cluster.x-k8s.io_kubevirtmachines.yaml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,15 @@ spec:
1818
singular: kubevirtmachine
1919
scope: Namespaced
2020
versions:
21-
- name: v1alpha1
21+
- additionalPrinterColumns:
22+
- jsonPath: .metadata.creationTimestamp
23+
name: Age
24+
type: date
25+
- description: Is machine ready
26+
jsonPath: .status.ready
27+
name: Ready
28+
type: boolean
29+
name: v1alpha1
2230
schema:
2331
openAPIV3Schema:
2432
description: KubevirtMachine is the Schema for the kubevirtmachines API.
@@ -4614,8 +4622,11 @@ spec:
46144622
Node of this KubevirtMachine
46154623
type: boolean
46164624
ready:
4625+
default: false
46174626
description: Ready denotes that the machine is ready
46184627
type: boolean
4628+
required:
4629+
- ready
46194630
type: object
46204631
type: object
46214632
served: true

config/rbac/role.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ rules:
4545
verbs:
4646
- delete
4747
- list
48+
- apiGroups:
49+
- cdi.kubevirt.io
50+
resources:
51+
- datavolumes
52+
verbs:
53+
- get
54+
- list
55+
- watch
4856
- apiGroups:
4957
- cluster.x-k8s.io
5058
resources:

controllers/kubevirtmachine_controller.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,13 @@ import (
2222
"regexp"
2323
"time"
2424

25-
"sigs.k8s.io/controller-runtime/pkg/builder"
26-
2725
"github.com/pkg/errors"
2826
"gopkg.in/yaml.v3"
2927
corev1 "k8s.io/api/core/v1"
3028
apierrors "k8s.io/apimachinery/pkg/api/errors"
3129
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3230
"k8s.io/apimachinery/pkg/types"
3331
utilerrors "k8s.io/apimachinery/pkg/util/errors"
34-
infrav1 "sigs.k8s.io/cluster-api-provider-kubevirt/api/v1alpha1"
35-
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/context"
36-
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/infracluster"
37-
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/kubevirt"
38-
kubevirthandler "sigs.k8s.io/cluster-api-provider-kubevirt/pkg/kubevirt"
39-
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/ssh"
40-
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/workloadcluster"
4132
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
4233
capierrors "sigs.k8s.io/cluster-api/errors"
4334
"sigs.k8s.io/cluster-api/util"
@@ -46,10 +37,19 @@ import (
4637
"sigs.k8s.io/cluster-api/util/patch"
4738
"sigs.k8s.io/cluster-api/util/predicates"
4839
ctrl "sigs.k8s.io/controller-runtime"
40+
"sigs.k8s.io/controller-runtime/pkg/builder"
4941
"sigs.k8s.io/controller-runtime/pkg/client"
5042
"sigs.k8s.io/controller-runtime/pkg/controller"
5143
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
5244
"sigs.k8s.io/controller-runtime/pkg/handler"
45+
46+
infrav1 "sigs.k8s.io/cluster-api-provider-kubevirt/api/v1alpha1"
47+
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/context"
48+
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/infracluster"
49+
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/kubevirt"
50+
kubevirthandler "sigs.k8s.io/cluster-api-provider-kubevirt/pkg/kubevirt"
51+
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/ssh"
52+
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/workloadcluster"
5353
)
5454

5555
// KubevirtMachineReconciler reconciles a KubevirtMachine object.
@@ -66,6 +66,7 @@ type KubevirtMachineReconciler struct {
6666
// +kubebuilder:rbac:groups="",resources=secrets;,verbs=get;list;watch;create;update;patch;delete
6767
// +kubebuilder:rbac:groups=kubevirt.io,resources=virtualmachines;,verbs=get;create;update;patch;delete
6868
// +kubebuilder:rbac:groups=kubevirt.io,resources=virtualmachineinstances;,verbs=get;delete
69+
// +kubebuilder:rbac:groups=cdi.kubevirt.io,resources=datavolumes;,verbs=get;list;watch
6970

7071
// Reconcile handles KubevirtMachine events.
7172
func (r *KubevirtMachineReconciler) Reconcile(goctx gocontext.Context, req ctrl.Request) (_ ctrl.Result, rerr error) {
@@ -277,6 +278,9 @@ func (r *KubevirtMachineReconciler) reconcileNormal(ctx *context.MachineContext)
277278
// Mark VMProvisionedCondition to indicate that the VM has successfully started
278279
conditions.MarkTrue(ctx.KubevirtMachine, infrav1.VMProvisionedCondition)
279280
} else {
281+
reason, message := externalMachine.GetVMNotReadyReason()
282+
conditions.MarkFalse(ctx.KubevirtMachine, infrav1.VMProvisionedCondition, reason, clusterv1.ConditionSeverityInfo, message)
283+
280284
// Waiting for VM to boot
281285
ctx.KubevirtMachine.Status.Ready = false
282286
ctx.Logger.Info("KubeVirt VM is not fully provisioned and running...")
@@ -476,7 +480,7 @@ func (r *KubevirtMachineReconciler) reconcileDelete(ctx *context.MachineContext)
476480

477481
// SetupWithManager will add watches for this controller.
478482
func (r *KubevirtMachineReconciler) SetupWithManager(goctx gocontext.Context, mgr ctrl.Manager, options controller.Options) error {
479-
clusterToKubevirtMachines, err := util.ClusterToObjectsMapper(mgr.GetClient(), &infrav1.KubevirtMachineList{}, mgr.GetScheme())
483+
clusterToKubevirtMachines, err := util.ClusterToTypedObjectsMapper(mgr.GetClient(), &infrav1.KubevirtMachineList{}, mgr.GetScheme())
480484
if err != nil {
481485
return err
482486
}

main.go

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ import (
2121
"flag"
2222
"math/rand"
2323
"os"
24-
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/webhookhandler"
25-
"sigs.k8s.io/controller-runtime/pkg/cache"
26-
"sigs.k8s.io/controller-runtime/pkg/metrics/server"
27-
"sigs.k8s.io/controller-runtime/pkg/webhook"
2824
"time"
2925

3026
"github.com/spf13/pflag"
@@ -35,23 +31,27 @@ import (
3531
"k8s.io/klog/v2"
3632
"k8s.io/klog/v2/klogr"
3733
kubevirtv1 "kubevirt.io/api/core/v1"
34+
cdiv1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1"
3835
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
3936
"sigs.k8s.io/cluster-api/feature"
4037
ctrl "sigs.k8s.io/controller-runtime"
38+
"sigs.k8s.io/controller-runtime/pkg/cache"
4139
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
4240
"sigs.k8s.io/controller-runtime/pkg/controller"
4341
"sigs.k8s.io/controller-runtime/pkg/healthz"
42+
"sigs.k8s.io/controller-runtime/pkg/metrics/server"
43+
"sigs.k8s.io/controller-runtime/pkg/webhook"
4444

4545
infrav1 "sigs.k8s.io/cluster-api-provider-kubevirt/api/v1alpha1"
4646
"sigs.k8s.io/cluster-api-provider-kubevirt/controllers"
4747
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/infracluster"
4848
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/kubevirt"
49+
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/webhookhandler"
4950
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/workloadcluster"
5051
// +kubebuilder:scaffold:imports
5152
)
5253

5354
var (
54-
myscheme = runtime.NewScheme()
5555
setupLog = ctrl.Log.WithName("setup")
5656

5757
//flags.
@@ -67,12 +67,24 @@ var (
6767

6868
func init() {
6969
klog.InitFlags(nil)
70+
}
7071

71-
_ = scheme.AddToScheme(myscheme)
72-
_ = infrav1.AddToScheme(myscheme)
73-
_ = clusterv1.AddToScheme(myscheme)
74-
_ = kubevirtv1.AddToScheme(myscheme)
75-
// +kubebuilder:scaffold:scheme
72+
func registerScheme() (*runtime.Scheme, error) {
73+
myscheme := runtime.NewScheme()
74+
75+
for _, f := range []func(*runtime.Scheme) error{
76+
scheme.AddToScheme,
77+
infrav1.AddToScheme,
78+
clusterv1.AddToScheme,
79+
kubevirtv1.AddToScheme,
80+
cdiv1.AddToScheme,
81+
// +kubebuilder:scaffold:scheme
82+
} {
83+
if err := f(myscheme); err != nil {
84+
return nil, err
85+
}
86+
}
87+
return myscheme, nil
7688
}
7789

7890
func initFlags(fs *pflag.FlagSet) {
@@ -106,6 +118,12 @@ func main() {
106118

107119
ctrl.SetLogger(klogr.New())
108120

121+
myscheme, err := registerScheme()
122+
if err != nil {
123+
setupLog.Error(err, "can't register scheme")
124+
os.Exit(1)
125+
}
126+
109127
var defaultNamespaces map[string]cache.Config
110128
if watchNamespace != "" {
111129
setupLog.Info("Watching cluster-api objects only in namespace for reconciliation", "namespace", watchNamespace)

0 commit comments

Comments
 (0)