ci: almost done cleanup
diff --git a/charts/ovn/templates/bin/_ovn-controller-init.sh.tpl b/charts/ovn/templates/bin/_ovn-controller-init.sh.tpl
index aa3ff6d..54b7417 100644
--- a/charts/ovn/templates/bin/_ovn-controller-init.sh.tpl
+++ b/charts/ovn/templates/bin/_ovn-controller-init.sh.tpl
@@ -23,6 +23,58 @@
   echo ${ip}
 }
 
+function get_ip_prefix_from_interface {
+  local interface=$1
+  local prefix=$(ip -4 -o addr s "${interface}" | awk '{ print $4; exit }' | awk -F '/' '{print $2}')
+  if [ -z "${prefix}" ] ; then
+    exit 1
+  fi
+  echo ${prefix}
+}
+
+function migrate_ip_from_nic {
+  src_nic=$1
+  bridge_name=$2
+
+  # Enabling explicit error handling: We must avoid to lose the IP
+  # address in the migration process. Hence, on every error, we
+  # attempt to assign the IP back to the original NIC and exit.
+  set +e
+
+  ip=$(get_ip_address_from_interface ${src_nic})
+  prefix=$(get_ip_prefix_from_interface ${src_nic})
+
+  bridge_ip=$(get_ip_address_from_interface "${bridge_name}")
+  bridge_prefix=$(get_ip_prefix_from_interface "${bridge_name}")
+
+  ip link set ${bridge_name} up
+
+  if [[ -n "${ip}" && -n "${prefix}" ]]; then
+    ip addr flush dev ${src_nic}
+    if [ $? -ne 0 ] ; then
+      ip addr add ${ip}/${prefix} dev ${src_nic}
+      echo "Error while flushing IP from ${src_nic}."
+      exit 1
+    fi
+
+    ip addr add ${ip}/${prefix} dev "${bridge_name}"
+    if [ $? -ne 0 ] ; then
+      echo "Error assigning IP to bridge "${bridge_name}"."
+      ip addr add ${ip}/${prefix} dev ${src_nic}
+      exit 1
+    fi
+  elif [[ -n "${bridge_ip}" && -n "${bridge_prefix}" ]]; then
+    echo "Bridge '${bridge_name}' already has IP assigned. Keeping the same:: IP:[${bridge_ip}]; Prefix:[${bridge_prefix}]..."
+  elif [[ -z "${bridge_ip}" && -z "${ip}" ]]; then
+    echo "Interface and bridge have no ips configured. Leaving as is."
+  else
+    echo "Interface ${name} has invalid IP address. IP:[${ip}]; Prefix:[${prefix}]..."
+    exit 1
+  fi
+
+  set -e
+}
+
 # Detect tunnel interface
 tunnel_interface="{{- .Values.network.interface.tunnel -}}"
 if [ -z "${tunnel_interface}" ] ; then
@@ -85,5 +137,6 @@
   if [ -n "$iface" ] && [ "$iface" != "null" ]
   then
     ovs-vsctl --may-exist add-port $bridge $iface
+    migrate_ip_from_nic $iface $bridge
   fi
 done
diff --git a/charts/ovn/templates/daemonset-controller.yaml b/charts/ovn/templates/daemonset-controller.yaml
index 1c6596e..a07c5fa 100644
--- a/charts/ovn/templates/daemonset-controller.yaml
+++ b/charts/ovn/templates/daemonset-controller.yaml
@@ -50,6 +50,7 @@
 {{- tuple $envAll "ovn_controller" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }}
         - name: controller-init
 {{ tuple $envAll "ovn_controller" | include "helm-toolkit.snippets.image" | indent 10 }}
+{{ dict "envAll" $envAll "application" "ovn_controller" "container" "controller_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
           command:
             - /tmp/ovn-controller-init.sh
           volumeMounts:
diff --git a/charts/ovn/templates/statefulset-nb-db.yaml b/charts/ovn/templates/statefulset-nb-db.yaml
deleted file mode 100644
index 78d7b56..0000000
--- a/charts/ovn/templates/statefulset-nb-db.yaml
+++ /dev/null
@@ -1,85 +0,0 @@
-{{/*
-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.
-*/}}
-
-{{- if .Values.manifests.statefulset_ovn_nb_db }}
-{{- $envAll := . }}
-
-{{- $serviceAccountName := "ovn-nb-db" }}
-{{ tuple $envAll "ovn_nb_db" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }}
----
-apiVersion: apps/v1
-kind: StatefulSet
-metadata:
-  name: ovn-nb-db
-  annotations:
-    {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
-  labels:
-{{ tuple $envAll "ovn" "ovn-nb-db" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
-spec:
-  serviceName: {{ tuple "ovn-nb-db" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}
-  replicas: 1
-  selector:
-    matchLabels:
-{{ tuple $envAll "ovn" "ovn-nb-db" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }}
-  template:
-    metadata:
-      labels:
-{{ tuple $envAll "ovn" "ovn-nb-db" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
-      annotations:
-{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }}
-    spec:
-      serviceAccountName: {{ $serviceAccountName }}
-      affinity:
-{{- tuple $envAll "ovn" "ovn-nb-db" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }}
-      nodeSelector:
-        {{ .Values.labels.ovn_nb_db.node_selector_key }}: {{ .Values.labels.ovn_nb_db.node_selector_value }}
-      initContainers:
-{{- tuple $envAll "ovn_nb_db" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }}
-      containers:
-        - name: ovn-nb-db
-{{ tuple $envAll "ovn_nb_db" | include "helm-toolkit.snippets.image" | indent 10 }}
-          ports:
-            - containerPort: {{ tuple "ovn-nb-db" "internal" "db" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
-          command:
-            - /tmp/start.sh
-            - nb-ovsdb
-{{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
-          volumeMounts:
-            - name: ovn-bin
-              mountPath: /tmp/start.sh
-              subPath: ovn.sh
-              readOnly: true
-            - name: ovn-nb-db-data
-              mountPath: /var/lib/ovn
-      volumes:
-        - name: ovn-bin
-          configMap:
-            name: ovn-bin
-            defaultMode: 0555
-{{- if not .Values.volume.ovn_nb_db.enabled }}
-        - name: ovn-nb-db-data
-          emptyDir: {}
-{{- else }}
-  volumeClaimTemplates:
-    - metadata:
-        name: ovn-nb-db-data
-      spec:
-        accessModes: ["ReadWriteOnce"]
-        resources:
-          requests:
-            storage: {{ $envAll.Values.volume.ovn_nb_db.size }}
-        storageClassName: {{ $envAll.Values.volume.ovn_nb_db.class_name }}
-{{- end }}
-
-{{- end }}
diff --git a/charts/ovn/templates/statefulset-ovsdb-nb.yaml b/charts/ovn/templates/statefulset-ovsdb-nb.yaml
new file mode 100644
index 0000000..bda1ab9
--- /dev/null
+++ b/charts/ovn/templates/statefulset-ovsdb-nb.yaml
@@ -0,0 +1,102 @@
+{{/*
+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.
+*/}}
+
+{{- if .Values.manifests.statefulset_ovn_ovsdb_nb }}
+{{- $envAll := . }}
+
+{{- $serviceAccountName := "ovn-ovsdb-nb" }}
+{{ tuple $envAll "ovn_ovsdb_nb" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }}
+---
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+  name: ovn-ovsdb-nb
+  annotations:
+    {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
+  labels:
+{{ tuple $envAll "ovn" "ovn-ovsdb-nb" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
+spec:
+  serviceName: {{ tuple "ovn-ovsdb-nb" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}
+  replicas: {{ .Values.pod.replicas.ovn_ovsdb_nb }}
+  selector:
+    matchLabels:
+{{ tuple $envAll "ovn" "ovn-ovsdb-nb" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }}
+  template:
+    metadata:
+      labels:
+{{ tuple $envAll "ovn" "ovn-ovsdb-nb" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
+      annotations:
+{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }}
+        configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }}
+    spec:
+      serviceAccountName: {{ $serviceAccountName }}
+      affinity:
+{{- tuple $envAll "ovn" "ovn-ovsdb-nb" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }}
+      nodeSelector:
+        {{ .Values.labels.ovn_ovsdb_nb.node_selector_key }}: {{ .Values.labels.ovn_ovsdb_nb.node_selector_value }}
+      initContainers:
+{{- tuple $envAll "ovn_ovsdb_nb" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }}
+      containers:
+        - name: ovsdb
+{{ tuple $envAll "ovn_ovsdb_nb" | include "helm-toolkit.snippets.image" | indent 10 }}
+{{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
+          ports:
+            - containerPort: {{ tuple "ovn-ovsdb-nb" "internal" "ovsdb" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
+            - containerPort: {{ tuple "ovn-ovsdb-nb" "internal" "raft" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
+          env:
+            - name: OVS_DATABASE
+              value: nb
+            - name: OVS_PORT
+              value: "{{ tuple "ovn-ovsdb-nb" "internal" "ovsdb" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}"
+          command:
+            - /tmp/ovsdb-server.sh
+            - start
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - /tmp/ovsdb-server.sh
+                  - stop
+          volumeMounts:
+            - name: ovn-bin
+              mountPath: /tmp/ovsdb-server.sh
+              subPath: ovsdb-server.sh
+              readOnly: true
+            - name: run-openvswitch
+              mountPath: /run/openvswitch
+            - name: data
+              mountPath: /var/lib/ovn
+      volumes:
+        - name: run-openvswitch
+          emptyDir: {}
+        - name: ovn-bin
+          configMap:
+            name: ovn-bin
+            defaultMode: 0555
+{{- if not .Values.volume.ovn_ovsdb_nb.enabled }}
+        - name: data
+          emptyDir: {}
+{{- else }}
+  volumeClaimTemplates:
+    - metadata:
+        name: data
+      spec:
+        accessModes: ["ReadWriteOnce"]
+        storageClassName: {{ $envAll.Values.volume.ovn_ovsdb_nb.class_name }}
+        resources:
+          requests:
+            storage: {{ $envAll.Values.volume.ovn_ovsdb_nb.size }}
+{{- end }}
+
+{{- end }}
diff --git a/charts/ovn/templates/statefulset-ovsdb-sb.yaml b/charts/ovn/templates/statefulset-ovsdb-sb.yaml
new file mode 100644
index 0000000..3f4c6b9
--- /dev/null
+++ b/charts/ovn/templates/statefulset-ovsdb-sb.yaml
@@ -0,0 +1,102 @@
+{{/*
+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.
+*/}}
+
+{{- if .Values.manifests.statefulset_ovn_ovsdb_sb }}
+{{- $envAll := . }}
+
+{{- $serviceAccountName := "ovn-ovsdb-sb" }}
+{{ tuple $envAll "ovn_ovsdb_sb" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }}
+---
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+  name: ovn-ovsdb-sb
+  annotations:
+    {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
+  labels:
+{{ tuple $envAll "ovn" "ovn-ovsdb-sb" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
+spec:
+  serviceName: {{ tuple "ovn-ovsdb-sb" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}
+  replicas: {{ .Values.pod.replicas.ovn_ovsdb_sb }}
+  selector:
+    matchLabels:
+{{ tuple $envAll "ovn" "ovn-ovsdb-sb" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }}
+  template:
+    metadata:
+      labels:
+{{ tuple $envAll "ovn" "ovn-ovsdb-sb" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
+      annotations:
+{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }}
+        configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }}
+    spec:
+      serviceAccountName: {{ $serviceAccountName }}
+      affinity:
+{{- tuple $envAll "ovn" "ovn-ovsdb-sb" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }}
+      nodeSelector:
+        {{ .Values.labels.ovn_ovsdb_sb.node_selector_key }}: {{ .Values.labels.ovn_ovsdb_sb.node_selector_value }}
+      initContainers:
+{{- tuple $envAll "ovn_ovsdb_sb" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }}
+      containers:
+        - name: ovsdb
+{{ tuple $envAll "ovn_ovsdb_sb" | include "helm-toolkit.snippets.image" | indent 10 }}
+{{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
+          ports:
+            - containerPort: {{ tuple "ovn-ovsdb-sb" "internal" "ovsdb" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
+            - containerPort: {{ tuple "ovn-ovsdb-sb" "internal" "raft" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
+          env:
+            - name: OVS_DATABASE
+              value: sb
+            - name: OVS_PORT
+              value: "{{ tuple "ovn-ovsdb-sb" "internal" "ovsdb" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}"
+          command:
+            - /tmp/ovsdb-server.sh
+            - start
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - /tmp/ovsdb-server.sh
+                  - stop
+          volumeMounts:
+            - name: ovn-bin
+              mountPath: /tmp/ovsdb-server.sh
+              subPath: ovsdb-server.sh
+              readOnly: true
+            - name: run-openvswitch
+              mountPath: /run/openvswitch
+            - name: data
+              mountPath: /var/lib/ovn
+      volumes:
+        - name: run-openvswitch
+          emptyDir: {}
+        - name: ovn-bin
+          configMap:
+            name: ovn-bin
+            defaultMode: 0555
+{{- if not .Values.volume.ovn_ovsdb_sb.enabled }}
+        - name: data
+          emptyDir: {}
+{{- else }}
+  volumeClaimTemplates:
+    - metadata:
+        name: data
+      spec:
+        accessModes: ["ReadWriteOnce"]
+        resources:
+          requests:
+            storage: {{ $envAll.Values.volume.ovn_ovsdb_sb.size }}
+        storageClassName: {{ $envAll.Values.volume.ovn_ovsdb_sb.class_name }}
+{{- end }}
+
+{{- end }}
diff --git a/charts/ovn/templates/statefulset-sb-db.yaml b/charts/ovn/templates/statefulset-sb-db.yaml
deleted file mode 100644
index 37c2ee0..0000000
--- a/charts/ovn/templates/statefulset-sb-db.yaml
+++ /dev/null
@@ -1,85 +0,0 @@
-{{/*
-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.
-*/}}
-
-{{- if .Values.manifests.statefulset_ovn_sb_db }}
-{{- $envAll := . }}
-
-{{- $serviceAccountName := "ovn-sb-db" }}
-{{ tuple $envAll "ovn_sb_db" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }}
----
-apiVersion: apps/v1
-kind: StatefulSet
-metadata:
-  name: ovn-sb-db
-  annotations:
-    {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
-  labels:
-{{ tuple $envAll "ovn" "ovn-sb-db" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
-spec:
-  serviceName: {{ tuple "ovn-sb-db" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}
-  replicas: 1
-  selector:
-    matchLabels:
-{{ tuple $envAll "ovn" "ovn-sb-db" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }}
-  template:
-    metadata:
-      labels:
-{{ tuple $envAll "ovn" "ovn-sb-db" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
-      annotations:
-{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }}
-    spec:
-      serviceAccountName: {{ $serviceAccountName }}
-      affinity:
-{{- tuple $envAll "ovn" "ovn-sb-db" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }}
-      nodeSelector:
-        {{ .Values.labels.ovn_sb_db.node_selector_key }}: {{ .Values.labels.ovn_sb_db.node_selector_value }}
-      initContainers:
-{{- tuple $envAll "ovn_sb_db" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }}
-      containers:
-        - name: ovn-sb-db
-{{ tuple $envAll "ovn_sb_db" | include "helm-toolkit.snippets.image" | indent 10 }}
-          ports:
-            - containerPort: {{ tuple "ovn-sb-db" "internal" "db" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
-          command:
-            - /tmp/start.sh
-            - sb-ovsdb
-{{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
-          volumeMounts:
-            - name: ovn-bin
-              mountPath: /tmp/start.sh
-              subPath: ovn.sh
-              readOnly: true
-            - name: ovn-sb-db-data
-              mountPath: /var/lib/ovn
-      volumes:
-        - name: ovn-bin
-          configMap:
-            name: ovn-bin
-            defaultMode: 0555
-{{- if not .Values.volume.ovn_sb_db.enabled }}
-        - name: ovn-sb-db-data
-          emptyDir: {}
-{{- else }}
-  volumeClaimTemplates:
-    - metadata:
-        name: ovn-sb-db-data
-      spec:
-        accessModes: ["ReadWriteOnce"]
-        resources:
-          requests:
-            storage: {{ $envAll.Values.volume.ovn_sb_db.size }}
-        storageClassName: {{ $envAll.Values.volume.ovn_sb_db.class_name }}
-{{- end }}
-
-{{- end }}
diff --git a/charts/ovn/values.yaml b/charts/ovn/values.yaml
index 3e3d69d..05408fa 100644
--- a/charts/ovn/values.yaml
+++ b/charts/ovn/values.yaml
@@ -90,6 +90,9 @@
               - SYS_NICE
     ovn_controller:
       container:
+        controller_init:
+          privileged: true
+          runAsUser: 0
         controller:
           capabilities:
             add: