From: francisco garcia Date: Tue, 31 Oct 2023 08:35:18 +0000 (+0000) Subject: k8s: Fix csi compatibility X-Git-Tag: Beta-15.0.1~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1975345453f21b2d433220d2aba8316c9bba62cb;p=thirdparty%2Fbacula.git k8s: Fix csi compatibility --- diff --git a/bacula/src/plugins/fd/kubernetes-backend/baculak8s/plugins/k8sbackend/storageclass.py b/bacula/src/plugins/fd/kubernetes-backend/baculak8s/plugins/k8sbackend/storageclass.py index de000cd75..d9e853830 100644 --- a/bacula/src/plugins/fd/kubernetes-backend/baculak8s/plugins/k8sbackend/storageclass.py +++ b/bacula/src/plugins/fd/kubernetes-backend/baculak8s/plugins/k8sbackend/storageclass.py @@ -90,6 +90,12 @@ def storageclass_list_all_names(storagev1api): return sclist +def get_provisioner(storagev1api, storage_name: str): + storageclass = storagev1api.patch_storage_class(storage_name, {}) + if storageclass is not None: + return storageclass.provisioner + return None + """ {'allow_volume_expansion': True, 'allowed_topologies': None, diff --git a/bacula/src/plugins/fd/kubernetes-backend/baculak8s/plugins/k8sbackend/volumesnapshotclass.py b/bacula/src/plugins/fd/kubernetes-backend/baculak8s/plugins/k8sbackend/volumesnapshotclass.py new file mode 100644 index 000000000..1b05cc77f --- /dev/null +++ b/bacula/src/plugins/fd/kubernetes-backend/baculak8s/plugins/k8sbackend/volumesnapshotclass.py @@ -0,0 +1,55 @@ +# -*- coding: UTF-8 -*- +# +# Bacula(R) - The Network Backup Solution +# +# Copyright (C) 2000-2023 Kern Sibbald +# +# The original author of Bacula is Kern Sibbald, with contributions +# from many others, a complete list can be found in the file AUTHORS. +# +# You may use this file and others of this release according to the +# license defined in the LICENSE file, which includes the Affero General +# Public License, v3.0 ("AGPLv3") and some additional permissions and +# terms pursuant to its AGPLv3 Section 7. +# +# This notice must be preserved when any source code is +# conveyed and/or propagated. +# +# Bacula(R) is a registered trademark of Kern Sibbald. +# +# Author: Francisco Manuel Garcia Botella, francisco.garcia@baculasystems.com. +# + +import logging +import pathlib + +K8SOBJ_SNAPSHOT_GROUP = 'snapshot.storage.k8s.io' +K8SOBJ_SNAPSHOT_VERSION = 'v1beta1' +K8SOBJ_SNAPSHOT_PLURAL = 'volumesnapshotclasses' + +def volumesnapshotclass_list_all(custom_api, filter_names=None): + vol_snap_list = {} + volume_snapshot_classes = custom_api.list_cluster_custom_object(K8SOBJ_SNAPSHOT_GROUP, K8SOBJ_SNAPSHOT_VERSION, K8SOBJ_SNAPSHOT_PLURAL, watch=False) + + for vol_snap in volume_snapshot_classes.get('items'): + if filter_names is not None and len(filter_names) > 0: + logging.debug("filter_names-glob-for: {}".format(vol_snap.get('metadata').get('name'))) + found = False + for vol_glob in filter_names: + logging.debug("checking vol_glob: {}".format(vol_glob)) + if pathlib.Path(vol_snap.get('metadata').get('name')).match(vol_glob): + found = True + logging.debug('Found volSnap.') + break + if not found: + continue + vol_snap_list[vol_snap.get('metadata').get('name')] = vol_snap + return vol_snap_list + +def get_snapshot_drivers_compatible(custom_api): + compatible_drivers = [] + volume_snapshot_classes = volumesnapshotclass_list_all(custom_api) + + for vol_snap_name in volume_snapshot_classes: + compatible_drivers.append(volume_snapshot_classes[vol_snap_name].get('driver')) + return compatible_drivers diff --git a/bacula/src/plugins/fd/kubernetes-backend/baculak8s/plugins/kubernetes_plugin.py b/bacula/src/plugins/fd/kubernetes-backend/baculak8s/plugins/kubernetes_plugin.py index f37b5572b..3940c42b5 100644 --- a/bacula/src/plugins/fd/kubernetes-backend/baculak8s/plugins/kubernetes_plugin.py +++ b/bacula/src/plugins/fd/kubernetes-backend/baculak8s/plugins/kubernetes_plugin.py @@ -52,6 +52,7 @@ from baculak8s.plugins.k8sbackend.service import * from baculak8s.plugins.k8sbackend.serviceaccounts import * from baculak8s.plugins.k8sbackend.statefulset import * from baculak8s.plugins.k8sbackend.storageclass import * +from baculak8s.plugins.k8sbackend.volumesnapshotclass import get_snapshot_drivers_compatible from baculak8s.plugins.plugin import * from baculak8s.util.date_util import gmt_to_unix_timestamp from baculak8s.util.lambda_util import wait_until_resource_is_ready @@ -191,7 +192,6 @@ class KubernetesPlugin(Plugin): logging.getLogger(client.rest.__package__).setLevel(logging.ERROR) urllib3.disable_warnings() logging.captureWarnings(True) - response = self.__execute(lambda: self.coreapi.get_api_versions(), check_connection=False) if isinstance(response, dict) and "error" in response: logging.debug("ERROR response:{}".format(response)) @@ -534,7 +534,13 @@ class KubernetesPlugin(Plugin): # TODO: export/move all checks into k8sbackend def check_storage_compatibility_with_vsnapshot(self, storage_class_name): - return SNAPSHOT_DRIVER_COMPATIBLE in storage_class_name + logging.debug("Check Storage compatibility. {}".format(storage_class_name)) + storage_provisioner = get_provisioner(self.storagev1api, storage_class_name) + logging.debug("Provisioner {}".format(storage_provisioner)) + logging.debug('Compatible Drivers: {} '.format(get_snapshot_drivers_compatible(self.crd_api))) + if storage_provisioner in get_snapshot_drivers_compatible(self.crd_api): + return True + return False def check_pvc_compatiblity_with_vsnapshot(self, namespace, pvc_name): pvc = self.get_pvcdata_namespaced(namespace, pvc_name) diff --git a/regress/tests/kubernetes-plugin-tests b/regress/tests/kubernetes-plugin-tests index d868c9aa9..9454fb642 100755 --- a/regress/tests/kubernetes-plugin-tests +++ b/regress/tests/kubernetes-plugin-tests @@ -12,6 +12,11 @@ # resources to handle test and a available "plugintest" namespace. # +# +# I used minikube server with csi addon +# minikube -p test-local stop && minikube -p test-local start && minikube -p test-local addons enable volumesnapshots && minikube -p test-local addons enable csi-hostpath-driver +# + # $ kubectl apply -f kubernetes-plugintest.yaml # namespace/plugintest created # secret/plugintest-secrets created @@ -30,44 +35,58 @@ # $ kubectl apply -f kubernetes-plugintest-csi-driver.yaml # storageclass.storage.k8s.io/csi-hostpath-sc configured # persistentvolumeclaim/plugintest-persistent-volume-claim-csi created +# persistentvolumeclaim/plugintest-persistent-volume-claim-csi-2 created +# pod/plugintest-annotations-test created # $ kubectl -n plugintest get pods -o wide -# NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES -# plugintest-frontend-4mpdj 1/1 Running 0 78s 10.244.10.217 test-local -# plugintest-frontend-f85pr 1/1 Running 0 78s 10.244.10.214 test-local -# plugintest-frontend-hg5ft 1/1 Running 0 78s 10.244.10.211 test-local -# plugintest-nginx-deployment-568dfdd98-bclmb 1/1 Running 0 78s 10.244.10.216 test-local -# plugintest-nginx-deployment-568dfdd98-hbz8w 1/1 Running 0 78s 10.244.10.218 test-local -# plugintest-nginx-deployment-568dfdd98-xxkz2 1/1 Running 0 78s 10.244.10.215 test-local -# plugintest-nginx-web-0 1/1 Running 0 78s 10.244.10.219 test-local -# plugintest-nginx-web-1 1/1 Running 0 66s 10.244.10.220 test-local -# plugintest-nginx-web-2 1/1 Running 0 62s 10.244.10.221 test-local -# plugintest1 1/1 Running 0 78s 10.244.10.210 test-local -# plugintest2 1/1 Running 0 78s 10.244.10.212 test-local -# plugintest3 1/1 Running 0 78s 10.244.10.213 test-local +# NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +# plugintest-annotations-test 0/1 Pending 0 27s +# plugintest-frontend-2qrh6 1/1 Running 0 40s 10.244.18.4 test-local +# plugintest-frontend-9jpqf 1/1 Running 0 40s 10.244.18.2 test-local +# plugintest-frontend-bwdz4 1/1 Running 0 40s 10.244.18.1 test-local +# plugintest-nginx-deployment-568dfdd98-2h68n 1/1 Running 0 40s 10.244.18.7 test-local +# plugintest-nginx-deployment-568dfdd98-ltb8v 1/1 Running 0 40s 10.244.18.6 test-local +# plugintest-nginx-deployment-568dfdd98-lxqt9 1/1 Running 0 40s 10.244.18.5 test-local +# plugintest-nginx-web-0 0/1 Pending 0 40s +# plugintest1 0/1 Pending 0 40s +# plugintest2 1/1 Running 0 40s 10.244.18.3 test-local +# plugintest3 0/1 Pending 0 40s + # $ kubectl -n plugintest get svc -o wide -# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR -# plugintest-nginx-service ClusterIP None 80/TCP 2m26s app=plugintest-nginx-web -# plugintest-subdomain ClusterIP 10.100.124.195 1234/TCP 2m26s name=plugintest +# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR +# plugintest-nginx-service ClusterIP None 80/TCP 63s app=plugintest-nginx-web +# plugintest-subdomain ClusterIP 10.97.43.130 1234/TCP 63s name=plugintest # $ kubectl -n plugintest get pvc -o wide # NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE -# plugintest-persistent-volume-claim Bound pvc-781fa285-9cc4-449c-b3e2-850c704aabe4 1Gi RWO standard 2m59s Filesystem -# plugintest-persistent-volume-claim-csi Bound pvc-47265f3d-68ca-4fd7-9c55-af93f31f8a72 1Gi RWO csi-hostpath-sc 2m41s Filesystem -# plugintest-www-data-plugintest-nginx-web-0 Bound pvc-60dd219e-4259-4149-befe-3b2230eb4dba 1Gi RWO standard 2m59s Filesystem -# plugintest-www-data-plugintest-nginx-web-1 Bound pvc-5b666e3b-f728-41d2-a13c-2a31667b9136 1Gi RWO standard 2m47s Filesystem -# plugintest-www-data-plugintest-nginx-web-2 Bound pvc-58464dd1-7884-4985-9ee8-6c9591f45d3c 1Gi RWO standard 2m43s Filesystem -# plugintest3-persistent-volume-claim Bound pvc-4dc9815f-f736-42fd-ae3e-3569ecb83e86 1Gi RWO standard 2m59s Filesystem +# plugintest-persistent-volume-claim Bound pvc-3381c472-5b3e-4b74-a999-24f3f7031a61 1Gi RWO standard 4m20s Filesystem +# plugintest-persistent-volume-claim-csi Bound pvc-9aecf542-5e7a-47c7-b9db-57a3b092bcf1 1Gi RWO csi-hostpath-sc 4m7s Filesystem +# plugintest-persistent-volume-claim-csi-2 Bound pvc-9c38ea52-e9fd-48c2-a45b-2cba5908ae8c 1Gi RWO csi-hostpath-sc 4m7s Filesystem +# plugintest-www-data-plugintest-nginx-web-0 Bound pvc-5c6ac739-fe67-476b-9711-282d8a376aa6 1Gi RWO standard 4m20s Filesystem +# plugintest-www-data-plugintest-nginx-web-1 Bound pvc-0cd78b05-b0c8-433d-8533-b270c8cc685b 1Gi RWO standard 101s Filesystem +# plugintest-www-data-plugintest-nginx-web-2 Bound pvc-ebdeac73-ff33-498c-8cd6-1d6c96b2c346 1Gi RWO standard 93s Filesystem +# plugintest3-persistent-volume-claim Bound pvc-7b906501-5bc6-469c-9e9f-87ee5db4fc07 1Gi RWO standard 4m20s Filesystem # $ kubectl -n plugintest get rs -o wide # NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR -# plugintest-frontend 3 3 3 3m21s plugintest-frontend-test gcr.io/google_samples/gb-frontend:v3 tier=frontend -# plugintest-nginx-deployment-568dfdd98 3 3 3 3m21s plugintest-nginx nginx:latest app=plugintest-deployment,pod-template-hash=568dfdd98 +# plugintest-frontend 3 3 3 4m41s plugintest-frontend-test gcr.io/google_samples/gb-frontend:v3 tier=frontend +# plugintest-nginx-deployment-568dfdd98 3 3 3 4m41s plugintest-nginx nginx:latest app=plugintest-deployment,pod-template-hash=568dfdd98 + # $ kubectl -n plugintest get sts -o wide # NAME READY AGE CONTAINERS IMAGES -# plugintest-nginx-web 3/3 3m48s plugintest-nginx-web k8s.gcr.io/nginx-slim:0.8 +# plugintest-nginx-web 3/3 4m55s plugintest-nginx-web k8s.gcr.io/nginx-slim:0.8 + +# $ kubectl -n plugintest get storageclass -o wide +# NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE +# csi-hostpath-sc hostpath.csi.k8s.io Delete Immediate false 94d +# standard (default) k8s.io/minikube-hostpath Delete Immediate false 94d + +# $ kubectl -n plugintest get volumesnapshotclasses -o wide +# NAME DRIVER DELETIONPOLICY AGE +# csi-hostpath-snapclass hostpath.csi.k8s.io Delete 94d + TestName="kubernetes-plugin-test" JobName="PluginKubernetesTest"