diff --git a/pkg/virt-operator/BUILD.bazel b/pkg/virt-operator/BUILD.bazel index a2691f083481..76dfa2ec1488 100644 --- a/pkg/virt-operator/BUILD.bazel +++ b/pkg/virt-operator/BUILD.bazel @@ -16,8 +16,6 @@ go_library( "//pkg/log:go_default_library", "//pkg/service:go_default_library", "//pkg/util:go_default_library", - "//pkg/virt-operator/creation:go_default_library", - "//pkg/virt-operator/deletion:go_default_library", "//pkg/virt-operator/install-strategy:go_default_library", "//pkg/virt-operator/util:go_default_library", "//vendor/github.com/prometheus/client_golang/prometheus/promhttp:go_default_library", diff --git a/pkg/virt-operator/creation/BUILD.bazel b/pkg/virt-operator/creation/BUILD.bazel index 91b18968d4dd..e69de29bb2d1 100644 --- a/pkg/virt-operator/creation/BUILD.bazel +++ b/pkg/virt-operator/creation/BUILD.bazel @@ -1,15 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["all.go"], - importpath = "kubevirt.io/kubevirt/pkg/virt-operator/creation", - visibility = ["//visibility:public"], - deps = [ - "//pkg/api/v1:go_default_library", - "//pkg/kubecli:go_default_library", - "//pkg/log:go_default_library", - "//pkg/virt-operator/install-strategy:go_default_library", - "//pkg/virt-operator/util:go_default_library", - ], -) diff --git a/pkg/virt-operator/creation/all.go b/pkg/virt-operator/creation/all.go deleted file mode 100644 index ca4c0485d7aa..000000000000 --- a/pkg/virt-operator/creation/all.go +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of the KubeVirt project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright 2018 Red Hat, Inc. - * - */ - -package creation - -import ( - "kubevirt.io/kubevirt/pkg/api/v1" - "kubevirt.io/kubevirt/pkg/kubecli" - "kubevirt.io/kubevirt/pkg/log" - "kubevirt.io/kubevirt/pkg/virt-operator/install-strategy" - "kubevirt.io/kubevirt/pkg/virt-operator/util" -) - -func Create(kv *v1.KubeVirt, stores util.Stores, clientset kubecli.KubevirtClient, expectations *util.Expectations, strategy *installstrategy.InstallStrategy) (int, error) { - - objectsAdded, err := installstrategy.CreateAll(kv, strategy, stores, clientset, expectations) - - if err != nil { - return objectsAdded, err - } - - err = util.UpdateScc(clientset, stores.SCCCache, kv, true) - if err != nil { - return objectsAdded, err - } - - log.Log.Object(kv).Infof("Created %d objects this round", objectsAdded) - return objectsAdded, nil -} diff --git a/pkg/virt-operator/deletion/BUILD.bazel b/pkg/virt-operator/deletion/BUILD.bazel deleted file mode 100644 index 32678d121bb2..000000000000 --- a/pkg/virt-operator/deletion/BUILD.bazel +++ /dev/null @@ -1,20 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["all.go"], - importpath = "kubevirt.io/kubevirt/pkg/virt-operator/deletion", - visibility = ["//visibility:public"], - deps = [ - "//pkg/api/v1:go_default_library", - "//pkg/controller:go_default_library", - "//pkg/kubecli:go_default_library", - "//pkg/log:go_default_library", - "//pkg/virt-operator/util:go_default_library", - "//vendor/k8s.io/api/apps/v1:go_default_library", - "//vendor/k8s.io/api/core/v1:go_default_library", - "//vendor/k8s.io/api/rbac/v1:go_default_library", - "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - ], -) diff --git a/pkg/virt-operator/deletion/all.go b/pkg/virt-operator/deletion/all.go deleted file mode 100644 index 2a961b1883bf..000000000000 --- a/pkg/virt-operator/deletion/all.go +++ /dev/null @@ -1,240 +0,0 @@ -/* - * This file is part of the KubeVirt project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright 2018 Red Hat, Inc. - * - */ - -package deletion - -import ( - "fmt" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - extv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "kubevirt.io/kubevirt/pkg/api/v1" - "kubevirt.io/kubevirt/pkg/controller" - "kubevirt.io/kubevirt/pkg/kubecli" - "kubevirt.io/kubevirt/pkg/log" - "kubevirt.io/kubevirt/pkg/virt-operator/util" -) - -func Delete(kv *v1.KubeVirt, clientset kubecli.KubevirtClient, stores util.Stores, expectations *util.Expectations) error { - - kvkey, err := controller.KeyFunc(kv) - if err != nil { - /// XXX this is not correct, we can't even process this object in the cache, we should do nothing - return err - } - - gracePeriod := int64(0) - deleteOptions := &metav1.DeleteOptions{ - GracePeriodSeconds: &gracePeriod, - } - - // first delete CRDs only - ext := clientset.ExtensionsClient() - objects := stores.CrdCache.List() - for _, obj := range objects { - if crd, ok := obj.(*extv1beta1.CustomResourceDefinition); ok && crd.DeletionTimestamp == nil { - if key, err := controller.KeyFunc(crd); err == nil { - expectations.Crd.AddExpectedDeletion(kvkey, key) - err := ext.ApiextensionsV1beta1().CustomResourceDefinitions().Delete(crd.Name, deleteOptions) - if err != nil { - expectations.Crd.DeletionObserved(kvkey, key) - log.Log.Errorf("Failed to delete crd %+v: %v", crd, err) - return err - } - } - } else if !ok { - log.Log.Errorf("Cast failed! obj: %+v", obj) - return nil - } - - } - if !util.IsStoreEmpty(stores.CrdCache) { - // wait until CRDs are gone - return nil - } - - // delete handler daemonset - obj, exists, err := stores.DaemonSetCache.GetByKey(fmt.Sprintf("%s/%s", kv.Namespace, "virt-handler")) - if err != nil { - log.Log.Errorf("Failed to get virt-handler: %v", err) - return err - } else if exists { - if ds, ok := obj.(*appsv1.DaemonSet); ok && ds.DeletionTimestamp == nil { - if key, err := controller.KeyFunc(ds); err == nil { - expectations.DaemonSet.AddExpectedDeletion(kvkey, key) - err := clientset.AppsV1().DaemonSets(kv.Namespace).Delete("virt-handler", deleteOptions) - if err != nil { - expectations.DaemonSet.DeletionObserved(kvkey, key) - log.Log.Errorf("Failed to delete virt-handler: %v", err) - return err - } - } - } else if !ok { - log.Log.Errorf("Cast failed! obj: %+v", obj) - return nil - } - } - - // delete controller and apiserver deployment - for _, name := range []string{"virt-controller", "virt-api"} { - obj, exists, err := stores.DeploymentCache.GetByKey(fmt.Sprintf("%s/%s", kv.Namespace, name)) - if err != nil { - log.Log.Errorf("Failed to get %v: %v", name, err) - return err - } else if exists { - if depl, ok := obj.(*appsv1.Deployment); ok && depl.DeletionTimestamp == nil { - if key, err := controller.KeyFunc(depl); err == nil { - expectations.Deployment.AddExpectedDeletion(kvkey, key) - err := clientset.AppsV1().Deployments(kv.Namespace).Delete(name, deleteOptions) - if err != nil { - expectations.Deployment.DeletionObserved(kvkey, key) - log.Log.Errorf("Failed to delete virt-handler: %v", err) - return err - } - } - } else if !ok { - log.Log.Errorf("Cast failed! obj: %+v", obj) - return nil - } - } - } - - // delete services - objects = stores.ServiceCache.List() - for _, obj := range objects { - if svc, ok := obj.(*corev1.Service); ok && svc.DeletionTimestamp == nil { - if key, err := controller.KeyFunc(svc); err == nil { - expectations.Service.AddExpectedDeletion(kvkey, key) - err := clientset.CoreV1().Services(kv.Namespace).Delete(svc.Name, deleteOptions) - if err != nil { - expectations.Service.DeletionObserved(kvkey, key) - log.Log.Errorf("Failed to delete service %+v: %v", svc, err) - return err - } - } - } else if !ok { - log.Log.Errorf("Cast failed! obj: %+v", obj) - return nil - } - } - - // delete RBAC - objects = stores.ClusterRoleBindingCache.List() - for _, obj := range objects { - if crb, ok := obj.(*rbacv1.ClusterRoleBinding); ok && crb.DeletionTimestamp == nil { - if key, err := controller.KeyFunc(crb); err == nil { - expectations.ClusterRoleBinding.AddExpectedDeletion(kvkey, key) - err := clientset.RbacV1().ClusterRoleBindings().Delete(crb.Name, deleteOptions) - if err != nil { - expectations.ClusterRoleBinding.DeletionObserved(kvkey, key) - log.Log.Errorf("Failed to delete crb %+v: %v", crb, err) - return err - } - } - } else if !ok { - log.Log.Errorf("Cast failed! obj: %+v", obj) - return nil - } - } - - objects = stores.ClusterRoleCache.List() - for _, obj := range objects { - if cr, ok := obj.(*rbacv1.ClusterRole); ok && cr.DeletionTimestamp == nil { - if key, err := controller.KeyFunc(cr); err == nil { - expectations.ClusterRole.AddExpectedDeletion(kvkey, key) - err := clientset.RbacV1().ClusterRoles().Delete(cr.Name, deleteOptions) - if err != nil { - expectations.ClusterRole.DeletionObserved(kvkey, key) - log.Log.Errorf("Failed to delete cr %+v: %v", cr, err) - return err - } - } - } else if !ok { - log.Log.Errorf("Cast failed! obj: %+v", obj) - return nil - } - } - - objects = stores.RoleBindingCache.List() - for _, obj := range objects { - if rb, ok := obj.(*rbacv1.RoleBinding); ok && rb.DeletionTimestamp == nil { - if key, err := controller.KeyFunc(rb); err == nil { - expectations.RoleBinding.AddExpectedDeletion(kvkey, key) - err := clientset.RbacV1().RoleBindings(kv.Namespace).Delete(rb.Name, deleteOptions) - if err != nil { - expectations.RoleBinding.DeletionObserved(kvkey, key) - log.Log.Errorf("Failed to delete rb %+v: %v", rb, err) - return err - } - } - } else if !ok { - log.Log.Errorf("Cast failed! obj: %+v", obj) - return nil - } - } - - objects = stores.RoleCache.List() - for _, obj := range objects { - if role, ok := obj.(*rbacv1.Role); ok && role.DeletionTimestamp == nil { - if key, err := controller.KeyFunc(role); err == nil { - expectations.Role.AddExpectedDeletion(kvkey, key) - err := clientset.RbacV1().Roles(kv.Namespace).Delete(role.Name, deleteOptions) - if err != nil { - expectations.Role.DeletionObserved(kvkey, key) - log.Log.Errorf("Failed to delete role %+v: %v", role, err) - return err - } - } - } else if !ok { - log.Log.Errorf("Cast failed! obj: %+v", obj) - return nil - } - } - - objects = stores.ServiceAccountCache.List() - for _, obj := range objects { - if sa, ok := obj.(*corev1.ServiceAccount); ok && sa.DeletionTimestamp == nil { - if key, err := controller.KeyFunc(sa); err == nil { - expectations.ServiceAccount.AddExpectedDeletion(kvkey, key) - err := clientset.CoreV1().ServiceAccounts(kv.Namespace).Delete(sa.Name, deleteOptions) - if err != nil { - expectations.ServiceAccount.DeletionObserved(kvkey, key) - log.Log.Errorf("Failed to delete serviceaccount %+v: %v", sa, err) - return err - } - } - } else if !ok { - log.Log.Errorf("Cast failed! obj: %+v", obj) - return nil - } - } - - err = util.UpdateScc(clientset, stores.SCCCache, kv, false) - if err != nil { - log.Log.Errorf("Failed to update SCC: %v", err) - return err - } - - return nil - -} diff --git a/pkg/virt-operator/install-strategy/BUILD.bazel b/pkg/virt-operator/install-strategy/BUILD.bazel index a53bd18260ca..ca0f4ed0134f 100644 --- a/pkg/virt-operator/install-strategy/BUILD.bazel +++ b/pkg/virt-operator/install-strategy/BUILD.bazel @@ -16,6 +16,7 @@ go_library( "//pkg/virt-operator/util:go_default_library", "//tools/util:go_default_library", "//vendor/github.com/ghodss/yaml:go_default_library", + "//vendor/github.com/openshift/api/security/v1:go_default_library", "//vendor/k8s.io/api/apps/v1:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/api/rbac/v1:go_default_library", diff --git a/pkg/virt-operator/kubevirt.go b/pkg/virt-operator/kubevirt.go index ee750b656326..10a89cd7df86 100644 --- a/pkg/virt-operator/kubevirt.go +++ b/pkg/virt-operator/kubevirt.go @@ -38,8 +38,6 @@ import ( "kubevirt.io/kubevirt/pkg/controller" "kubevirt.io/kubevirt/pkg/kubecli" "kubevirt.io/kubevirt/pkg/log" - "kubevirt.io/kubevirt/pkg/virt-operator/creation" - "kubevirt.io/kubevirt/pkg/virt-operator/deletion" "kubevirt.io/kubevirt/pkg/virt-operator/install-strategy" "kubevirt.io/kubevirt/pkg/virt-operator/util" ) @@ -707,7 +705,7 @@ func (c *KubeVirtController) syncDeployment(kv *v1.KubeVirt) error { c.garbageCollectInstallStrategyJobs() // deploy - objectsAdded, err := creation.Create(kv, c.stores, c.clientset, &c.kubeVirtExpectations, strategy) + objectsAdded, err := installstrategy.CreateAll(kv, strategy, c.stores, c.clientset, &c.kubeVirtExpectations) if err != nil { // deployment failed @@ -775,6 +773,16 @@ func (c *KubeVirtController) syncDeletion(kv *v1.KubeVirt) error { logger := log.Log.Object(kv) logger.Info("Handling deletion") + strategy, pending, err := c.loadInstallStrategy(kv) + if err != nil { + return err + } + + // we're waiting on the job to finish and the config map to be created + if pending { + return nil + } + // set phase to deleting kv.Status.Phase = v1.KubeVirtPhaseDeleting @@ -782,24 +790,24 @@ func (c *KubeVirtController) syncDeletion(kv *v1.KubeVirt) error { util.RemoveCondition(kv, v1.KubeVirtConditionCreated) util.RemoveCondition(kv, v1.KubeVirtConditionReady) - err := deletion.Delete(kv, c.clientset, c.stores, &c.kubeVirtExpectations) + err = installstrategy.DeleteAll(kv, strategy, c.stores, c.clientset, &c.kubeVirtExpectations) if err != nil { // deletion failed util.UpdateCondition(kv, v1.KubeVirtConditionSynchronized, k8sv1.ConditionFalse, ConditionReasonDeletionFailedError, fmt.Sprintf("An error occurred during deletion: %v", err)) return err } - err = c.deleteAllInstallStrategy() - if err != nil { - // garbage collection of install strategies failed - util.UpdateCondition(kv, v1.KubeVirtConditionSynchronized, k8sv1.ConditionFalse, ConditionReasonDeletionFailedError, fmt.Sprintf("An error occurred during deletion: %v", err)) - return err - } - util.RemoveCondition(kv, v1.KubeVirtConditionSynchronized) if c.stores.AllEmpty() { + err = c.deleteAllInstallStrategy() + if err != nil { + // garbage collection of install strategies failed + util.UpdateCondition(kv, v1.KubeVirtConditionSynchronized, k8sv1.ConditionFalse, ConditionReasonDeletionFailedError, fmt.Sprintf("An error occurred during deletion: %v", err)) + return err + } + // deletion successful kv.Status.Phase = v1.KubeVirtPhaseDeleted diff --git a/pkg/virt-operator/kubevirt_test.go b/pkg/virt-operator/kubevirt_test.go index 8a2ce5011b9d..4a464d15608f 100644 --- a/pkg/virt-operator/kubevirt_test.go +++ b/pkg/virt-operator/kubevirt_test.go @@ -679,7 +679,7 @@ var _ = Describe("KubeVirt Operator", func() { } Context("On valid KubeVirt object", func() { - It("should do nothing if KubeVirt object is deleted", func(done Done) { + It("should delete install strategy configmap once kubevirt install is deleted", func(done Done) { defer close(done) kv := &v1.KubeVirt{ @@ -693,7 +693,10 @@ var _ = Describe("KubeVirt Operator", func() { } kv.DeletionTimestamp = now() + shouldExpectInstallStrategyDeletion() + addKubeVirt(kv) + addInstallStrategy() controller.Execute() }, 15)