From a897c0c0282da134fb625c3b265d6bcc6a449845 Mon Sep 17 00:00:00 2001 From: Arie Peterson <arie@greenhost.nl> Date: Thu, 30 May 2024 11:03:08 +0200 Subject: [PATCH] Use posix IPC for signalling provisioning requests --- backend/app.py | 12 +++++++----- backend/areas/apps/apps_service.py | 3 +++ backend/areas/apps/models.py | 1 - backend/cliapp/cliapp/cli.py | 2 +- backend/helpers/threads.py | 12 ++++++++++-- backend/requirements.txt | 1 + 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/backend/app.py b/backend/app.py index e07a39d9..b5280299 100644 --- a/backend/app.py +++ b/backend/app.py @@ -141,18 +141,20 @@ def init_routines(): # We have this single "provisioning worker" so there will be only one # provisioning operation at a time. We use an Event to signal a # provisioning request. - def wait_for_provision_event(): + def provisioning_loop(): while True: - helpers.threads.provision_event.wait() - helpers.threads.provision_event.clear() + app.logger.info("Waiting for next provisioning run.") + # helpers.threads.provision_event.wait() + # helpers.threads.provision_event.clear() + helpers.threads.wait_provision() app.logger.info("Starting provisioning.") with app.app_context(): try: provisioner.reconcile() except Exception as e: - app.logger.warn(f"Exception in user provisioning:") + app.logger.warn(f"Exception during user provisioning:") app.logger.warn(traceback.format_exc()) - threading.Thread(target=wait_for_provision_event).start() + threading.Thread(target=provisioning_loop).start() # `init_routines` should only run once per dashboard instance. To enforce this # we have different behaviour for production and development mode: diff --git a/backend/areas/apps/apps_service.py b/backend/areas/apps/apps_service.py index dc88deb4..98971d8c 100644 --- a/backend/areas/apps/apps_service.py +++ b/backend/areas/apps/apps_service.py @@ -13,6 +13,7 @@ from database import db from helpers.access_control import user_has_access from helpers.kratos_user import KratosUser import helpers.kubernetes as k8s +from helpers.threads import request_provision class AppsService: @staticmethod @@ -82,3 +83,5 @@ class AppsService: ) db.session.add(app_role) db.session.commit() + ca.logger.info("Requesting user provisioning.") + request_provision() diff --git a/backend/areas/apps/models.py b/backend/areas/apps/models.py index fd89c963..e9330ab9 100644 --- a/backend/areas/apps/models.py +++ b/backend/areas/apps/models.py @@ -92,7 +92,6 @@ class App(db.Model): def install(self): """Creates a Kustomization in the Kubernetes cluster that installs this application""" # Create add-<app> kustomization - print("Creating app kustomization.") self.__create_kustomization() def uninstall(self): diff --git a/backend/cliapp/cliapp/cli.py b/backend/cliapp/cliapp/cli.py index ee588e74..38d5a20f 100644 --- a/backend/cliapp/cliapp/cli.py +++ b/backend/cliapp/cliapp/cli.py @@ -203,7 +203,7 @@ def install_app(slug): if not current_status.installed: AppsService.install_app(app) current_app.logger.info( - f"App {slug} installing... use `status` to see status") + f"App {slug} installing...") else: current_app.logger.error(f"App {slug} is already installed") diff --git a/backend/helpers/threads.py b/backend/helpers/threads.py index 4ee12c88..0a4e6ad6 100644 --- a/backend/helpers/threads.py +++ b/backend/helpers/threads.py @@ -1,8 +1,9 @@ import functools +from posix_ipc import MessageQueue, O_CREAT, BusyError import threading # Signal to provisioning loop that we want to provision now. -provision_event = threading.Event() +provisioning_queue = MessageQueue('/stackspin-dashboard-provision-queue', O_CREAT) def debounce(timeout: float): def decorator(func): @@ -17,4 +18,11 @@ def debounce(timeout: float): @debounce(1) def request_provision(): - provision_event.set() + try: + provisioning_queue.send("provision", timeout=0) + except BusyError: + # If we can't signal for some reason, silently fail. + pass + +def wait_provision(): + provisioning_queue.receive() diff --git a/backend/requirements.txt b/backend/requirements.txt index 244e4e8b..b06a9796 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -28,6 +28,7 @@ ory-kratos-client==1.0.0 ory-hydra-client==1.11.8 pathspec==0.9.0 platformdirs==2.5.1 +posix-ipc==1.1.1 pycparser==2.21 PyJWT==2.3.0 pymysql==1.0.2 -- GitLab