From 0766bb41626960cb814b089861561cdff5a21b47 Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Thu, 3 Jul 2025 09:39:35 +0200 Subject: [PATCH] Implemented new run_after logic --- cli/generate_playbook.py | 23 +----- roles/docker-akaunting/meta/main.yml | 6 +- roles/docker-attendize/meta/main.yml | 4 + roles/docker-baserow/meta/main.yml | 5 +- roles/docker-bluesky/meta/main.yml | 4 + roles/docker-friendica/meta/main.yml | 4 +- roles/docker-funkwhale/meta/main.yml | 3 + roles/docker-fusiondirectory/meta/main.yml | 4 + roles/docker-gitea/meta/main.yml | 4 + roles/docker-gitlab/meta/main.yml | 4 + roles/docker-joomla/meta/main.yml | 4 + roles/docker-listmonk/meta/main.yml | 6 +- roles/docker-matrix/meta/main.yml | 4 + roles/docker-mediawiki/meta/main.yml | 6 +- roles/docker-mobilizon/meta/main.yml | 6 +- roles/docker-mybb/meta/main.yml | 6 +- roles/docker-snipe-it/meta/main.yml | 4 + tests/unit/test_generate_playbook.py | 85 ++++++++++++++++++++++ 18 files changed, 153 insertions(+), 29 deletions(-) create mode 100644 tests/unit/test_generate_playbook.py diff --git a/cli/generate_playbook.py b/cli/generate_playbook.py index d0e636bf..7102d5cc 100644 --- a/cli/generate_playbook.py +++ b/cli/generate_playbook.py @@ -105,32 +105,13 @@ def print_dependency_tree(graph): def generate_playbook_entries(roles_dir, prefix=None): """Generate playbook entries based on the sorted order.""" - # Build dependency graph graph, in_degree, roles = build_dependency_graph(roles_dir, prefix) - # Print and collect roles in tree order - tree_sorted_roles = print_dependency_tree(graph) - - # Topologically sort the roles + # Detect cycles and get correct topological order sorted_role_names = topological_sort(graph, in_degree) - # Ensure that roles that appear in the tree come first - final_sorted_roles = [role for role in tree_sorted_roles if role in sorted_role_names] - - # Include the remaining unsorted roles - final_sorted_roles += [role for role in sorted_role_names if role not in final_sorted_roles] - - # Remove duplicates, keeping only the first occurrence to preserve dependency order - seen = set() - deduplicated_roles = [] - for role in final_sorted_roles: - if role not in seen: - deduplicated_roles.append(role) - seen.add(role) - - # Generate the playbook entries entries = [] - for role_name in deduplicated_roles: + for role_name in sorted_role_names: role = roles[role_name] entries.append( f"- name: setup {role['application_id']}\n" diff --git a/roles/docker-akaunting/meta/main.yml b/roles/docker-akaunting/meta/main.yml index 0b0ea4f3..af6cc708 100644 --- a/roles/docker-akaunting/meta/main.yml +++ b/roles/docker-akaunting/meta/main.yml @@ -18,4 +18,8 @@ galaxy_info: issue_tracker_url: https://s.veen.world/cymaisissues documentation: https://s.veen.world/cymais logo: - class: "fa-solid fa-file-invoice-dollar" \ No newline at end of file + class: "fa-solid fa-file-invoice-dollar" + run_after: + - docker-matomo + - docker-keycloak + - docker-mailu \ No newline at end of file diff --git a/roles/docker-attendize/meta/main.yml b/roles/docker-attendize/meta/main.yml index 94f7c718..c7804bbc 100644 --- a/roles/docker-attendize/meta/main.yml +++ b/roles/docker-attendize/meta/main.yml @@ -19,4 +19,8 @@ galaxy_info: documentation: https://s.veen.world/cymais logo: class: "fa-solid fa-calendar-check" + run_after: + - docker-matomo + - docker-keycloak + - docker-mailu dependencies: [] diff --git a/roles/docker-baserow/meta/main.yml b/roles/docker-baserow/meta/main.yml index ba89665e..dc37ca4e 100644 --- a/roles/docker-baserow/meta/main.yml +++ b/roles/docker-baserow/meta/main.yml @@ -18,4 +18,7 @@ galaxy_info: documentation: https://s.veen.world/cymais logo: class: "fa-solid fa-table" -dependencies: [] + run_after: + - docker-matomo + - docker-keycloak + - docker-mailu diff --git a/roles/docker-bluesky/meta/main.yml b/roles/docker-bluesky/meta/main.yml index ebbc1177..8fdeb0d3 100644 --- a/roles/docker-bluesky/meta/main.yml +++ b/roles/docker-bluesky/meta/main.yml @@ -18,4 +18,8 @@ galaxy_info: documentation: https://s.veen.world/cymais logo: class: "fa-solid fa-sun" + run_after: + - docker-matomo + - docker-keycloak + - docker-mailu dependencies: [] diff --git a/roles/docker-friendica/meta/main.yml b/roles/docker-friendica/meta/main.yml index 7f43512a..2bf530fe 100644 --- a/roles/docker-friendica/meta/main.yml +++ b/roles/docker-friendica/meta/main.yml @@ -18,4 +18,6 @@ galaxy_info: documentation: https://s.veen.world/cymais logo: class: "fa-solid fa-users" -dependencies: [] + run_after: + - docker-matomo + - docker-keycloak diff --git a/roles/docker-funkwhale/meta/main.yml b/roles/docker-funkwhale/meta/main.yml index d25049a1..c6515dac 100644 --- a/roles/docker-funkwhale/meta/main.yml +++ b/roles/docker-funkwhale/meta/main.yml @@ -19,4 +19,7 @@ galaxy_info: logo: class: "fa-solid fa-music" run_after: + - docker-matomo + - docker-keycloak + - docker-mailu - docker-ldap \ No newline at end of file diff --git a/roles/docker-fusiondirectory/meta/main.yml b/roles/docker-fusiondirectory/meta/main.yml index 5dc7e49e..870baba8 100644 --- a/roles/docker-fusiondirectory/meta/main.yml +++ b/roles/docker-fusiondirectory/meta/main.yml @@ -19,3 +19,7 @@ galaxy_info: repository: "https://s.veen.world/cymais" issue_tracker_url: "https://s.veen.world/cymaisissues" documentation: "https://s.veen.world/cymais" + run_after: + - docker-matomo + - docker-keycloak + - docker-mailu diff --git a/roles/docker-gitea/meta/main.yml b/roles/docker-gitea/meta/main.yml index 58417b2f..235f119c 100644 --- a/roles/docker-gitea/meta/main.yml +++ b/roles/docker-gitea/meta/main.yml @@ -19,4 +19,8 @@ galaxy_info: documentation: https://s.veen.world/cymais logo: class: "fa-solid fa-code" + run_after: + - docker-matomo + - docker-keycloak + - docker-mailu dependencies: [] diff --git a/roles/docker-gitlab/meta/main.yml b/roles/docker-gitlab/meta/main.yml index 37d0f8e2..53946903 100644 --- a/roles/docker-gitlab/meta/main.yml +++ b/roles/docker-gitlab/meta/main.yml @@ -19,4 +19,8 @@ galaxy_info: documentation: https://s.veen.world/cymais logo: class: "fa-solid fa-code-branch" + run_after: + - docker-matomo + - docker-keycloak + - docker-mailu dependencies: [] diff --git a/roles/docker-joomla/meta/main.yml b/roles/docker-joomla/meta/main.yml index a3046751..fce519b5 100644 --- a/roles/docker-joomla/meta/main.yml +++ b/roles/docker-joomla/meta/main.yml @@ -19,4 +19,8 @@ galaxy_info: documentation: https://s.veen.world/cymais logo: class: "fa-solid fa-sitemap" + run_after: + - docker-matomo + - docker-keycloak + - docker-mailu dependencies: [] \ No newline at end of file diff --git a/roles/docker-listmonk/meta/main.yml b/roles/docker-listmonk/meta/main.yml index 3895d735..47516353 100644 --- a/roles/docker-listmonk/meta/main.yml +++ b/roles/docker-listmonk/meta/main.yml @@ -19,5 +19,7 @@ galaxy_info: documentation: "https://s.veen.world/cymais" logo: class: "fa-solid fa-list" -dependencies: - - docker-mailu \ No newline at end of file + run_after: + - docker-matomo + - docker-keycloak + - docker-mailu \ No newline at end of file diff --git a/roles/docker-matrix/meta/main.yml b/roles/docker-matrix/meta/main.yml index d557de2a..e5fe4ecd 100644 --- a/roles/docker-matrix/meta/main.yml +++ b/roles/docker-matrix/meta/main.yml @@ -20,4 +20,8 @@ galaxy_info: documentation: "https://s.veen.world/cymais" logo: class: "fa-solid fa-satellite-dish" + run_after: + - docker-matomo + - docker-keycloak + - docker-mailu dependencies: [] diff --git a/roles/docker-mediawiki/meta/main.yml b/roles/docker-mediawiki/meta/main.yml index c41bd3cb..a72535dd 100644 --- a/roles/docker-mediawiki/meta/main.yml +++ b/roles/docker-mediawiki/meta/main.yml @@ -18,4 +18,8 @@ galaxy_info: issue_tracker_url: "https://s.veen.world/cymaisissues" documentation: "https://s.veen.world/cymais" logo: - class: "fa-solid fa-book" \ No newline at end of file + class: "fa-solid fa-book" + run_after: + - docker-matomo + - docker-keycloak + - docker-mailu \ No newline at end of file diff --git a/roles/docker-mobilizon/meta/main.yml b/roles/docker-mobilizon/meta/main.yml index f5e7f88a..472730d2 100644 --- a/roles/docker-mobilizon/meta/main.yml +++ b/roles/docker-mobilizon/meta/main.yml @@ -19,4 +19,8 @@ galaxy_info: logo: class: "fa-solid fa-calendar-days" run_after: - - "docker-postgres" + - docker-matomo + - docker-keycloak + - docker-mailu + - docker-ldap + - docker-postgres diff --git a/roles/docker-mybb/meta/main.yml b/roles/docker-mybb/meta/main.yml index 0b2b4452..7012a24c 100644 --- a/roles/docker-mybb/meta/main.yml +++ b/roles/docker-mybb/meta/main.yml @@ -19,5 +19,9 @@ galaxy_info: documentation: "https://s.veen.world/cymais" logo: class: "fa-solid fa-comments" + run_after: + - docker-matomo + - docker-keycloak + - docker-mailu dependencies: - - nginx-docker-reverse-proxy + - nginx-docker-reverse-proxy \ No newline at end of file diff --git a/roles/docker-snipe-it/meta/main.yml b/roles/docker-snipe-it/meta/main.yml index 527bd5b8..8bf1fea4 100644 --- a/roles/docker-snipe-it/meta/main.yml +++ b/roles/docker-snipe-it/meta/main.yml @@ -26,5 +26,9 @@ galaxy_info: documentation: "https://s.veen.world/cymais" logo: class: "fa-solid fa-box" + run_after: + - docker-matomo + - docker-keycloak + - docker-mailu dependencies: [] diff --git a/tests/unit/test_generate_playbook.py b/tests/unit/test_generate_playbook.py new file mode 100644 index 00000000..03d52539 --- /dev/null +++ b/tests/unit/test_generate_playbook.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +import os +import sys +import unittest +import tempfile +import shutil +import yaml + +# Adjust path to include cli/ folder +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../..", "cli"))) + +from generate_playbook import build_dependency_graph, topological_sort, generate_playbook_entries + +class TestGeneratePlaybook(unittest.TestCase): + def setUp(self): + # Create a temporary directory to simulate roles + self.temp_dir = tempfile.mkdtemp() + + # Define mock roles and dependencies + self.roles = { + 'role-a': {'run_after': [], 'application_id': 'a'}, + 'role-b': {'run_after': ['role-a'], 'application_id': 'b'}, + 'role-c': {'run_after': ['role-b'], 'application_id': 'c'}, + 'role-d': {'run_after': [], 'application_id': 'd'}, + } + + for role_name, meta in self.roles.items(): + role_path = os.path.join(self.temp_dir, role_name) + os.makedirs(os.path.join(role_path, 'meta'), exist_ok=True) + os.makedirs(os.path.join(role_path, 'vars'), exist_ok=True) + + meta_file = { + 'galaxy_info': { + 'run_after': meta['run_after'] + } + } + + vars_file = { + 'application_id': meta['application_id'] + } + + with open(os.path.join(role_path, 'meta', 'main.yml'), 'w') as f: + yaml.dump(meta_file, f) + + with open(os.path.join(role_path, 'vars', 'main.yml'), 'w') as f: + yaml.dump(vars_file, f) + + def tearDown(self): + # Clean up the temporary directory + shutil.rmtree(self.temp_dir) + + def test_dependency_graph_and_sort(self): + graph, in_degree, roles = build_dependency_graph(self.temp_dir) + + self.assertIn('role-a', graph) + self.assertIn('role-b', graph) + self.assertEqual(graph['role-a'], ['role-b']) + self.assertEqual(graph['role-b'], ['role-c']) + self.assertEqual(graph['role-c'], []) + self.assertEqual(in_degree['role-c'], 1) + self.assertEqual(in_degree['role-b'], 1) + self.assertEqual(in_degree['role-a'], 0) + self.assertEqual(in_degree['role-d'], 0) + + sorted_roles = topological_sort(graph, in_degree) + # The expected order must be a → b → c, d can be anywhere before or after + self.assertTrue(sorted_roles.index('role-a') < sorted_roles.index('role-b') < sorted_roles.index('role-c')) + + def test_generate_playbook_entries(self): + entries = generate_playbook_entries(self.temp_dir) + + text = ''.join(entries) + self.assertIn("setup a", text) + self.assertIn("setup b", text) + self.assertIn("setup c", text) + self.assertIn("setup d", text) + + # Order must preserve run_after + a_index = text.index("setup a") + b_index = text.index("setup b") + c_index = text.index("setup c") + self.assertTrue(a_index < b_index < c_index) + +if __name__ == '__main__': + unittest.main()