Merge pull request #115 from vexxhost/k8s-lock

Using K8s lease for lock
diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml
index 193eabe..6745ffe 100644
--- a/.github/workflows/linters.yaml
+++ b/.github/workflows/linters.yaml
@@ -1,5 +1,5 @@
 name: linters
-on: push 
+on: push
 
 jobs:
   super-lint:
@@ -11,5 +11,6 @@
           DEFAULT_BRANCH: main
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           VALIDATE_ALL_CODEBASE: true
+          VALIDATE_DOCKERFILE_HADOLINT: false
           VALIDATE_PYTHON_MYPY: false
           VALIDATE_JSCPD: false
diff --git a/.hadolint.yaml b/.hadolint.yaml
new file mode 100644
index 0000000..f09cb61
--- /dev/null
+++ b/.hadolint.yaml
@@ -0,0 +1,3 @@
+---
+ignored:
+  - DL3020
diff --git a/requirements.txt b/requirements.txt
index 8a52b2b..32d5e37 100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -18,5 +18,6 @@
 pymysql
 parse
 tooz # Apache-2.0
+sherlock>=0.4.1 # MIT
 # email
 # smtplib
diff --git a/staffeln/common/lock.py b/staffeln/common/lock.py
index 5568bfe..d5d6134 100644
--- a/staffeln/common/lock.py
+++ b/staffeln/common/lock.py
@@ -6,6 +6,7 @@
 import uuid
 from typing import Optional  # noqa: H301
 
+import sherlock
 from oslo_log import log
 from staffeln import conf, exception
 from tooz import coordination
@@ -16,7 +17,10 @@
 
 class LockManager(object):
     def __init__(self):
-        self.coordinator = COORDINATOR
+        backend_url = CONF.coordination.backend_url
+        # This is for now using to check if any backend_url setup
+        # for tooz backends as K8s should not need one.any
+        self.coordinator = COORDINATOR if backend_url else K8SCOORDINATOR
 
     def __enter__(self):
         self.coordinator.start()
@@ -132,4 +136,43 @@
                     _err(file_name, exc)
 
 
+class K8sCoordinator(object):
+    """Sherlock kubernetes coordination wrapper.
+
+    :param int expire: Set lock expire seconds
+    :param int timeout: Set lock acquire action timeout seconds
+    :param str namespace: Set lock namespace.
+    """
+
+    def __init__(
+        self, expire: int = 3600, timeout: int = 10, namespace: str = "staffeln"
+    ):
+        self.timeout = timeout
+        self.expire = expire
+        self.namespace = namespace
+        self.started = False
+
+    def start(self) -> None:
+        if self.started:
+            return
+        sherlock.configure(expire=self.expire, timeout=self.timeout)
+        self.started = True
+
+    def stop(self) -> None:
+        """Disconnect from coordination backend and stop heartbeat."""
+        pass
+
+    def get_lock(self, name: str):
+        """Return a kubernetes lease lock.
+
+        :param str name: The lock name that is used to identify it
+            across all nodes.
+        """
+        return sherlock.KubernetesLock(name, self.namespace)
+
+    def remove_lock(self, glob_name):
+        pass
+
+
 COORDINATOR = Coordinator(prefix="staffeln-")
+K8SCOORDINATOR = K8sCoordinator()