]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
k8s: Fix csi compatibility
authorfrancisco garcia <francisco.garcia@baculasystems.com>
Tue, 31 Oct 2023 08:35:18 +0000 (08:35 +0000)
committerEric Bollengier <eric@baculasystems.com>
Tue, 13 Feb 2024 09:36:02 +0000 (10:36 +0100)
bacula/src/plugins/fd/kubernetes-backend/baculak8s/plugins/k8sbackend/storageclass.py
bacula/src/plugins/fd/kubernetes-backend/baculak8s/plugins/k8sbackend/volumesnapshotclass.py [new file with mode: 0644]
bacula/src/plugins/fd/kubernetes-backend/baculak8s/plugins/kubernetes_plugin.py
regress/tests/kubernetes-plugin-tests

index de000cd7516492463c28be7cee2b1e96d510ca31..d9e8538303be99da740b07917e4398b3c5118102 100644 (file)
@@ -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 (file)
index 0000000..1b05cc7
--- /dev/null
@@ -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
index f37b5572b745840d230760daaf12a818ab118b26..3940c42b5e2bbbf39fbb7b96545f3904fdc731d8 100644 (file)
@@ -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)
index d868c9aa9827f02146dfa82968a6f2457eda01e8..9454fb64246e65c8621d72ea11daad7147f1d701 100755 (executable)
 #  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
 # $ 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   <none>           <none>
-# plugintest-frontend-f85pr                     1/1     Running   0          78s   10.244.10.214   test-local   <none>           <none>
-# plugintest-frontend-hg5ft                     1/1     Running   0          78s   10.244.10.211   test-local   <none>           <none>
-# plugintest-nginx-deployment-568dfdd98-bclmb   1/1     Running   0          78s   10.244.10.216   test-local   <none>           <none>
-# plugintest-nginx-deployment-568dfdd98-hbz8w   1/1     Running   0          78s   10.244.10.218   test-local   <none>           <none>
-# plugintest-nginx-deployment-568dfdd98-xxkz2   1/1     Running   0          78s   10.244.10.215   test-local   <none>           <none>
-# plugintest-nginx-web-0                        1/1     Running   0          78s   10.244.10.219   test-local   <none>           <none>
-# plugintest-nginx-web-1                        1/1     Running   0          66s   10.244.10.220   test-local   <none>           <none>
-# plugintest-nginx-web-2                        1/1     Running   0          62s   10.244.10.221   test-local   <none>           <none>
-# plugintest1                                   1/1     Running   0          78s   10.244.10.210   test-local   <none>           <none>
-# plugintest2                                   1/1     Running   0          78s   10.244.10.212   test-local   <none>           <none>
-# plugintest3                                   1/1     Running   0          78s   10.244.10.213   test-local   <none>           <none>
+# NAME                                          READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
+# plugintest-annotations-test                   0/1     Pending   0          27s   <none>        <none>       <none>           <none>
+# plugintest-frontend-2qrh6                     1/1     Running   0          40s   10.244.18.4   test-local   <none>           <none>
+# plugintest-frontend-9jpqf                     1/1     Running   0          40s   10.244.18.2   test-local   <none>           <none>
+# plugintest-frontend-bwdz4                     1/1     Running   0          40s   10.244.18.1   test-local   <none>           <none>
+# plugintest-nginx-deployment-568dfdd98-2h68n   1/1     Running   0          40s   10.244.18.7   test-local   <none>           <none>
+# plugintest-nginx-deployment-568dfdd98-ltb8v   1/1     Running   0          40s   10.244.18.6   test-local   <none>           <none>
+# plugintest-nginx-deployment-568dfdd98-lxqt9   1/1     Running   0          40s   10.244.18.5   test-local   <none>           <none>
+# plugintest-nginx-web-0                        0/1     Pending   0          40s   <none>        <none>       <none>           <none>
+# plugintest1                                   0/1     Pending   0          40s   <none>        <none>       <none>           <none>
+# plugintest2                                   1/1     Running   0          40s   10.244.18.3   test-local   <none>           <none>
+# plugintest3                                   0/1     Pending   0          40s   <none>        <none>       <none>           <none>
+
 
 # $ kubectl -n plugintest get svc -o wide
-# NAME                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE     SELECTOR
-# plugintest-nginx-service   ClusterIP   None             <none>        80/TCP     2m26s   app=plugintest-nginx-web
-# plugintest-subdomain       ClusterIP   10.100.124.195   <none>        1234/TCP   2m26s   name=plugintest
+# NAME                       TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE   SELECTOR
+# plugintest-nginx-service   ClusterIP   None           <none>        80/TCP     63s   app=plugintest-nginx-web
+# plugintest-subdomain       ClusterIP   10.97.43.130   <none>        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"