From 83a3fdc2ad7813d1bc7a29b611d57b4e12253998 Mon Sep 17 00:00:00 2001
From: John Davis <jdavcs@gmail.com>
Date: Wed, 8 Mar 2023 22:14:41 -0500
Subject: [PATCH 01/46] Fix exception fully qualified name

---
 tasks/database.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tasks/database.yml b/tasks/database.yml
index 903ea44..bc99409 100644
--- a/tasks/database.yml
+++ b/tasks/database.yml
@@ -14,6 +14,7 @@
         - current_db_version.rc != 0
         - "'migrate.exceptions.DatabaseNotControlledError' not in current_db_version.stderr"
         - "'galaxy.model.migrations.NoVersionTableError' not in current_db_version.stderr"
+        - "'galaxy.model.migrations.exceptions.NoVersionTableError' not in current_db_version.stderr"
       when: not ansible_check_mode
 
     - name: Get maximum Galaxy DB version
@@ -33,6 +34,7 @@
         - current_db_version.stdout != max_db_version.stdout
         - "'migrate.exceptions.DatabaseNotControlledError' not in current_db_version.stderr"
         - "'galaxy.model.migrations.NoVersionTableError' not in current_db_version.stderr"
+        - "'galaxy.model.migrations.exceptions.NoVersionTableError' not in current_db_version.stderr"
 
     - name: Upgrade Galaxy DB
       command: "{{ galaxy_venv_dir }}/bin/python {{ galaxy_server_dir }}/scripts/manage_db.py -c {{ galaxy_config_file }} upgrade"
@@ -43,6 +45,7 @@
         - current_db_version.stdout != max_db_version.stdout
         - "'migrate.exceptions.DatabaseNotControlledError' not in current_db_version.stderr"
         - "'galaxy.model.migrations.NoVersionTableError' not in current_db_version.stderr"
+        - "'galaxy.model.migrations.exceptions.NoVersionTableError' not in current_db_version.stderr"
 
   remote_user: "{{ galaxy_remote_users.galaxy | default(__galaxy_remote_user) }}"
   become: "{{ true if galaxy_become_users.galaxy is defined else __galaxy_become }}"

From 07e30c85a16687aecc41b9aed10d430002825123 Mon Sep 17 00:00:00 2001
From: Nate Coraor <nate@bx.psu.edu>
Date: Thu, 9 Mar 2023 14:26:57 -0500
Subject: [PATCH 02/46] Support defining a maximum node version for a given
 platform

---
 defaults/main.yml           |  7 +++++++
 tasks/_inc_node_version.yml | 14 ++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/defaults/main.yml b/defaults/main.yml
index a9d0bff..d398263 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -369,6 +369,13 @@ galaxy_client_build_steps:
     - stageLibs
     - plugins
 
+__galaxy_node_version_max:
+  "redhat7": "16.19.1"
+galaxy_node_version_max: >-
+  {{
+    (__galaxy_node_version_max[(ansible_os_family | lower) ~ ansible_distribution_major_version]) | default(galaxy_node_version)
+  }}
+
 #
 # systemd options
 #
diff --git a/tasks/_inc_node_version.yml b/tasks/_inc_node_version.yml
index 92e99e7..9af6cee 100644
--- a/tasks/_inc_node_version.yml
+++ b/tasks/_inc_node_version.yml
@@ -4,6 +4,7 @@
 # Galaxy 18.09 and older prefer 9.11.1
 # Galaxy 19.01 prefers 10.13.0
 # Galaxy 19.05 and newer provide client/.node_version
+# Galaxy 23.0 and newer on EL7 or older requires a downgrade to 16
 
 - name: Determine preferred Node.js version
   block:
@@ -17,6 +18,19 @@
       set_fact:
         galaxy_node_version: "{{ __galaxy_node_version_file['content'] | b64decode | trim }}"
 
+    - name: Report Node.js version file version
+      debug:
+        var: galaxy_node_version
+
+    - name: Override Galaxy Node.js version
+      set_fact:
+        galaxy_node_version: >-
+          {{
+            (
+             galaxy_node_version_max is version(galaxy_node_version, "<")
+            ) | ternary(galaxy_node_version_max, galaxy_node_version)
+          }}
+
     # if the client build is being executed independently, nodeenv may not be already installed.
     # If so, setup a virtualenv with nodeenv installed.
     - name: Check whether nodeenv is available

From 4f63eac98d325ac6e02243c2649739f70a07424f Mon Sep 17 00:00:00 2001
From: Nate Coraor <nate@bx.psu.edu>
Date: Thu, 9 Mar 2023 15:36:57 -0500
Subject: [PATCH 03/46] Drop 21.01 from build matrix, add 23.0

---
 .github/workflows/molecule.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/molecule.yml b/.github/workflows/molecule.yml
index 5e6568e..c2d1e31 100644
--- a/.github/workflows/molecule.yml
+++ b/.github/workflows/molecule.yml
@@ -22,9 +22,9 @@ jobs:
           - ubuntu:20.04
           - ubuntu:22.04
         galaxy-version:
-          - '21.01'
           - '22.01'
           - '22.05'
+          - '23.0'
           - 'dev'
         exclude:
           # wheels often don't exist in the combination of old package versions in older galaxy releases for newer

From e223078b31916cff1e0c5e4ff0f4e40d40fcf3f0 Mon Sep 17 00:00:00 2001
From: Nate Coraor <nate@bx.psu.edu>
Date: Mon, 6 Mar 2023 16:29:22 -0500
Subject: [PATCH 04/46] Drop modifying venv activate to set
 `$GRAVITY_STATE_DIR`

---
 tasks/dependencies.yml | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/tasks/dependencies.yml b/tasks/dependencies.yml
index d7fbd82..b02c016 100644
--- a/tasks/dependencies.yml
+++ b/tasks/dependencies.yml
@@ -46,15 +46,6 @@
         VIRTUAL_ENV: "{{ galaxy_venv_dir }}"
       when: galaxy_additional_venv_packages
 
-    - name: Configure $GRAVITY_STATE_DIR in virtualenv activate
-      blockinfile:
-        path: "{{ galaxy_venv_dir }}/bin/activate"
-        marker: "# {mark} GALAXYPROJECT.GALAXY ROLE ANSIBLE MANAGED BLOCK"
-        block: |
-          # Galaxy Gravity per-instance state directory configured by galaxyproject.galaxy Ansible role
-          GRAVITY_STATE_DIR={{ galaxy_gravity_state_dir | quote }}
-          export GRAVITY_STATE_DIR
-
   remote_user: "{{ galaxy_remote_users.privsep | default(__galaxy_remote_user) }}"
   become: "{{ true if galaxy_become_users.privsep is defined else __galaxy_become }}"
   become_user: "{{ galaxy_become_users.privsep | default(__galaxy_become_user) }}"

From d5acc7f29cc15321c9d098aa2194bbad0f971f73 Mon Sep 17 00:00:00 2001
From: Nate Coraor <nate@bx.psu.edu>
Date: Tue, 14 Mar 2023 17:40:06 -0400
Subject: [PATCH 05/46] Updates for systemd mode Gravity

---
 defaults/main.yml         |  4 ++++
 handlers/gravity_23.0.yml | 18 +++++++-----------
 handlers/main.yml         |  2 +-
 tasks/gravity.yml         | 31 ++++++++++++++++---------------
 4 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/defaults/main.yml b/defaults/main.yml
index d398263..60112e8 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -380,6 +380,10 @@ galaxy_node_version_max: >-
 # systemd options
 #
 
+__galaxy_gravity_pm: "{{ (galaxy_config_merged.gravity | default({})).process_manager | default('supervisor') }}"
+__galaxy_gravity_instance_name: "{{ (galaxy_config_merged.gravity | default({})).instance_name | default(none) }}"
+galaxy_gravity_wrapper_path: "/usr/local/bin/galaxyctl{{ __galaxy_gravity_instance_name | ternary('-' ~ __galaxy_gravity_instance_name, '') }}"
+
 # Currently `mule` (aka uWSGI) and `gravity` (runs Galaxy 22.01+ under gunicorn) are supported
 galaxy_systemd_mode: "{{ 'mule' if __galaxy_major_version is version('22.05', '<') else 'gravity' }}"
 
diff --git a/handlers/gravity_23.0.yml b/handlers/gravity_23.0.yml
index 25b5e6b..36c3d50 100644
--- a/handlers/gravity_23.0.yml
+++ b/handlers/gravity_23.0.yml
@@ -1,18 +1,14 @@
 ---
 # handlers for gravity as used in galaxy version 23.0
 
-- name: galaxy gravity restart
-  command: "{{ galaxy_venv_dir }}/bin/galaxyctl -c {{ galaxy_config_file }} graceful"
-  environment:
-    GRAVITY_STATE_DIR: "{{ galaxy_gravity_state_dir }}"
-  listen: "restart galaxy"
-  become: yes
-  become_user: "{{ __galaxy_user_name }}"
-
 - name: galaxyctl update
   command: "{{ galaxy_venv_dir }}/bin/galaxyctl -c {{ galaxy_config_file }} update"
-  environment:
-    GRAVITY_STATE_DIR: "{{ galaxy_gravity_state_dir }}"
   listen: "galaxyctl update"
   become: yes
-  become_user: "{{ __galaxy_user_name }}"
+  become_user: "{{ (__galaxy_gravity_pm == 'systemd' and galaxy_systemd_root) | ternary('root', __galaxy_user_name) }}"
+
+- name: galaxy gravity restart
+  command: "{{ galaxy_venv_dir }}/bin/galaxyctl -c {{ galaxy_config_file }} graceful"
+  listen: "restart galaxy"
+  become: yes
+  become_user: "{{ (__galaxy_gravity_pm == 'systemd' and galaxy_systemd_root) | ternary('root', __galaxy_user_name) }}"
diff --git a/handlers/main.yml b/handlers/main.yml
index 32f9495..3c98fa9 100644
--- a/handlers/main.yml
+++ b/handlers/main.yml
@@ -30,4 +30,4 @@
 - name: Include Gravity handlers (for 23.0)
   import_tasks:
     file: gravity_23.0.yml
-  when: "galaxy_systemd_mode == 'gravity' and galaxy_manage_systemd and __galaxy_major_version is version('23.0', '>=')"
+  when: "galaxy_systemd_mode == 'gravity' and __galaxy_major_version is version('23.0', '>=')"
diff --git a/tasks/gravity.yml b/tasks/gravity.yml
index c39eb5e..f14acda 100644
--- a/tasks/gravity.yml
+++ b/tasks/gravity.yml
@@ -1,29 +1,30 @@
 ---
 # Configure Gravity
 
-- name: Gravity setup
+- name: Gravity setup (Gravity < 1)
+  when: __galaxy_major_version is version('23.0', '<')
   block:
 
-    - name: Register Galaxy config with Gravity
+    - name: Register Galaxy config with Gravity (Gravity < 1)
       command: "{{ galaxy_venv_dir }}/bin/galaxyctl register {{ galaxy_config_file }}"
       args:
         creates: "{{ galaxy_gravity_state_dir }}/configstate.yaml"
-      when: __galaxy_major_version is version('23.0', '<')
-
-    - name: Update Gravity process management files
-      command: "{{ galaxy_venv_dir }}/bin/galaxyctl update"
-      args:
-        creates: "{{ galaxy_gravity_state_dir }}/supervisor/supervisord.conf.d"
-      when: __galaxy_major_version is version('23.0', '<')
-
-    - name: Update Gravity process management files
-      command: "{{ galaxy_venv_dir }}/bin/galaxyctl -c {{ galaxy_config_file }} update"
-      args:
-        creates: "{{ galaxy_gravity_state_dir }}/supervisor/supervisord.conf.d"
-      when: __galaxy_major_version is version('23.0', '>=')
 
   environment:
     GRAVITY_STATE_DIR: "{{ galaxy_gravity_state_dir }}"
   remote_user: "{{ galaxy_remote_users.galaxy | default(__galaxy_remote_user) }}"
   become: "{{ true if galaxy_become_users.galaxy is defined else __galaxy_become }}"
   become_user: "{{ galaxy_become_users.galaxy | default(__galaxy_become_user) }}"
+
+- name: Deploy galaxyctl wrapper script
+  copy:
+    content: |
+      #!/usr/bin/env sh
+      export GRAVITY_CONFIG_FILE={{ galaxy_config_file | quote }}
+      exec {{ (galaxy_venv_dir ~ '/bin/galaxyctl') | quote }} "$@"
+    dest: "{{ galaxy_gravity_wrapper_path }}"
+    mode: "0755"
+  when: galaxy_gravity_wrapper_path is not none
+  remote_user: "{{ galaxy_remote_users.root | default(__galaxy_remote_user) }}"
+  become: "{{ true if galaxy_become_users.root is defined else __galaxy_become }}"
+  become_user: "{{ galaxy_become_users.root | default(__galaxy_become_user) }}"

From a0812154f28e1c328039eabf3d1e291f2baa9514 Mon Sep 17 00:00:00 2001
From: mvdbeek <m.vandenbeek@gmail.com>
Date: Wed, 12 Apr 2023 23:55:28 +0200
Subject: [PATCH 06/46] Precreate directories

---
 tasks/static_setup.yml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/tasks/static_setup.yml b/tasks/static_setup.yml
index 90706c8..56016f6 100644
--- a/tasks/static_setup.yml
+++ b/tasks/static_setup.yml
@@ -8,6 +8,14 @@
       include_tasks: _inc_galaxy_version.yml
       when: __galaxy_major_version is undefined
 
+    - name: Create directories for config files
+      ansible.builtin.file:
+        state: directory
+        path: "{{ item }}"
+        mode: "{{ __galaxy_dir_perms }}"
+        group: "{{ __galaxy_user_group }}"
+      loop: "{{ (galaxy_config_files + galaxy_config_templates) | map(attribute='dest') | map('dirname') | unique }}"
+
     - name: Install additional Galaxy config files (static)
       copy:
         src: "{{ item.src }}"

From c79b95536caa67cc992e8fb5a4e75648cd516736 Mon Sep 17 00:00:00 2001
From: Helena Rasche <hexylena@galaxians.org>
Date: Thu, 13 Apr 2023 11:47:39 +0200
Subject: [PATCH 07/46] update workflows

---
 .github/workflows/release.yml |  6 +++---
 .github/workflows/slugger.yml | 33 ++++++++++++++++++++-------------
 2 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 8d80bc9..773c89e 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -5,7 +5,7 @@
 # See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy
 # See: https://github.com/ansible/galaxy/issues/46
 
-name: Release
+name: Release (by Tag Push)
 
 'on':
   push:
@@ -18,10 +18,10 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Check out the codebase.
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
 
       - name: Set up Python 3.
-        uses: actions/setup-python@v2
+        uses: actions/setup-python@v3
         with:
           python-version: '3.x'
 
diff --git a/.github/workflows/slugger.yml b/.github/workflows/slugger.yml
index c295cb7..2cd7b97 100644
--- a/.github/workflows/slugger.yml
+++ b/.github/workflows/slugger.yml
@@ -16,7 +16,7 @@ name: "Automatic Regular Releases"
 on:
   workflow_dispatch:
   schedule:
-    - cron:  '0 0 * * 1'
+    - cron: '0 0 * * 1'
 
 jobs:
   release:
@@ -24,12 +24,12 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Check out the codebase.
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
         with:
           fetch-depth: 0
 
       - name: Set up Python 3.
-        uses: actions/setup-python@v2
+        uses: actions/setup-python@v3
         with:
           python-version: '3.x'
 
@@ -38,28 +38,35 @@ jobs:
 
       - name: Check for changes
         run: |
-          MOST_RECENT_TAG=$(git describe --tags --abbrev=0)
-          CHANGES=$(git diff ${MOST_RECENT_TAG} --name-only | wc -l)
-          echo "Found ${CHANGES} files"
-          git diff ${MOST_RECENT_TAG} --name-only
+          LATEST_TAG=$(git describe --tags --abbrev=0)
+          echo "The last released tag was ${LATEST_TAG}"
+          CHANGES=$(git diff ${LATEST_TAG} --name-only | wc -l)
+          echo "Found ${CHANGES} changed files"
+          git diff ${LATEST_TAG} --name-only
           echo "changed_files=${CHANGES}" >> $GITHUB_ENV
 
       - name: Create a new git tag
         run: |
-          MOST_RECENT_TAG=$(git describe --tags --abbrev=0)
-          major_minor=$(echo "$MOST_RECENT_TAG" | sed 's/\(.*\..*\.\)\(.*\)/\1/')
-          patch=$(echo "$MOST_RECENT_TAG" | sed 's/\(.*\..*\.\)\(.*\)/\2/')
+          LATEST_TAG=$(git describe --tags --abbrev=0)
+          major_minor=$(echo "$LATEST_TAG" | sed 's/\(.*\..*\.\)\(.*\)/\1/')
+          patch=$(echo "$LATEST_TAG" | sed 's/\(.*\..*\.\)\(.*\)/\2/')
           newpatch=$(echo "$patch + 1" | bc)
           NEW_TAG="${major_minor}${newpatch}"
-          echo "$MOST_RECENT_TAG -> $NEW_TAG"
+          echo "$LATEST_TAG -> $NEW_TAG"
 
           git config user.name github-actions
           git config user.email github-actions@github.com
           git tag "$NEW_TAG"
           git push --tags
+          echo "Creating new tag $NEW_TAG" >> $GITHUB_STEP_SUMMARY
         if: env.changed_files > 0
 
-      # We have to do this step as GHA prevents triggering it's own actions, to prevent runaway loops.
+      # We have to do this step as GHA prevents triggering it's own actions, to
+      # prevent runaway loops.
       - name: Trigger a new import on Galaxy.
-        run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) --branch main
+        run: |
+          org=$(echo ${{ github.repository }} | cut -d/ -f1)
+          repo=$(echo ${{ github.repository }} | cut -d/ -f2)
+          key=${{ secrets.GALAXY_API_KEY }}
+          ansible-galaxy role import --api-key $key $org $repo --branch main
         if: env.changed_files > 0

From 4f24d639f45bc8b5e36bb5705791dea876aea84c Mon Sep 17 00:00:00 2001
From: Mira <86979912+mira-miracoli@users.noreply.github.com>
Date: Thu, 13 Apr 2023 13:53:09 +0200
Subject: [PATCH 08/46] Update mutable_setup.yml

---
 tasks/mutable_setup.yml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/tasks/mutable_setup.yml b/tasks/mutable_setup.yml
index d01a394..6cf5310 100644
--- a/tasks/mutable_setup.yml
+++ b/tasks/mutable_setup.yml
@@ -8,6 +8,14 @@
       include_tasks: _inc_galaxy_version.yml
       when: __galaxy_major_version is undefined
 
+    - name: Create directories for config files
+      ansible.builtin.file:
+        state: directory
+        path: "{{ item }}"
+        mode: "{{ __galaxy_dir_perms }}"
+        group: "{{ __galaxy_user_group }}"
+      loop: "{{ (galaxy_mutable_config_files + galaxy_mutable_config_templates) | map(attribute='dest') | map('dirname') | unique }}"
+
     # force: no in the following 2 tasks will not overwrite existing configs
     - name: Instantiate mutable configuration files
       copy:

From 2a9bf37125d9c4e25648b4fe691b890687281bc0 Mon Sep 17 00:00:00 2001
From: Helena Rasche <hexylena@galaxians.org>
Date: Thu, 13 Apr 2023 15:06:22 +0200
Subject: [PATCH 09/46] second attempt at fixing, must be privsep to create

---
 tasks/mutable_setup.yml | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/tasks/mutable_setup.yml b/tasks/mutable_setup.yml
index 6cf5310..e3201ad 100644
--- a/tasks/mutable_setup.yml
+++ b/tasks/mutable_setup.yml
@@ -1,21 +1,28 @@
 ---
 # Instantiate mutable config files
 
-- name: Mutable config setup
+- name: Mutable config directory setup
   block:
-
-    - name: Ensure Galaxy version is set
-      include_tasks: _inc_galaxy_version.yml
-      when: __galaxy_major_version is undefined
-
-    - name: Create directories for config files
+    - name: Create directories for mutable config files
       ansible.builtin.file:
         state: directory
         path: "{{ item }}"
         mode: "{{ __galaxy_dir_perms }}"
+        owner: "{{ __galaxy_user_name }}"
         group: "{{ __galaxy_user_group }}"
       loop: "{{ (galaxy_mutable_config_files + galaxy_mutable_config_templates) | map(attribute='dest') | map('dirname') | unique }}"
 
+  remote_user: "{{ galaxy_remote_users.privsep | default(__galaxy_remote_user) }}"
+  become: "{{ true if galaxy_become_users.privsep is defined else __galaxy_become }}"
+  become_user: "{{ galaxy_become_users.privsep | default(__galaxy_become_user) }}"
+
+- name: Mutable config setup
+  block:
+
+    - name: Ensure Galaxy version is set
+      include_tasks: _inc_galaxy_version.yml
+      when: __galaxy_major_version is undefined
+
     # force: no in the following 2 tasks will not overwrite existing configs
     - name: Instantiate mutable configuration files
       copy:

From c0c093a74bbeedf393db7ad3bf0c14a231616fe4 Mon Sep 17 00:00:00 2001
From: Nate Coraor <nate@bx.psu.edu>
Date: Thu, 13 Apr 2023 10:57:30 -0400
Subject: [PATCH 10/46] Revert "Precreate directories"

This reverts commit a0812154f28e1c328039eabf3d1e291f2baa9514.
---
 tasks/static_setup.yml | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/tasks/static_setup.yml b/tasks/static_setup.yml
index 56016f6..90706c8 100644
--- a/tasks/static_setup.yml
+++ b/tasks/static_setup.yml
@@ -8,14 +8,6 @@
       include_tasks: _inc_galaxy_version.yml
       when: __galaxy_major_version is undefined
 
-    - name: Create directories for config files
-      ansible.builtin.file:
-        state: directory
-        path: "{{ item }}"
-        mode: "{{ __galaxy_dir_perms }}"
-        group: "{{ __galaxy_user_group }}"
-      loop: "{{ (galaxy_config_files + galaxy_config_templates) | map(attribute='dest') | map('dirname') | unique }}"
-
     - name: Install additional Galaxy config files (static)
       copy:
         src: "{{ item.src }}"

From 11fd0bde90d167b3bbd261f80df69c1690c4c9df Mon Sep 17 00:00:00 2001
From: Nate Coraor <nate@bx.psu.edu>
Date: Thu, 13 Apr 2023 10:58:00 -0400
Subject: [PATCH 11/46] Revert "second attempt at fixing, must be privsep to
 create"

This reverts commit 2a9bf37125d9c4e25648b4fe691b890687281bc0.
---
 tasks/mutable_setup.yml | 21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/tasks/mutable_setup.yml b/tasks/mutable_setup.yml
index e3201ad..6cf5310 100644
--- a/tasks/mutable_setup.yml
+++ b/tasks/mutable_setup.yml
@@ -1,28 +1,21 @@
 ---
 # Instantiate mutable config files
 
-- name: Mutable config directory setup
+- name: Mutable config setup
   block:
-    - name: Create directories for mutable config files
+
+    - name: Ensure Galaxy version is set
+      include_tasks: _inc_galaxy_version.yml
+      when: __galaxy_major_version is undefined
+
+    - name: Create directories for config files
       ansible.builtin.file:
         state: directory
         path: "{{ item }}"
         mode: "{{ __galaxy_dir_perms }}"
-        owner: "{{ __galaxy_user_name }}"
         group: "{{ __galaxy_user_group }}"
       loop: "{{ (galaxy_mutable_config_files + galaxy_mutable_config_templates) | map(attribute='dest') | map('dirname') | unique }}"
 
-  remote_user: "{{ galaxy_remote_users.privsep | default(__galaxy_remote_user) }}"
-  become: "{{ true if galaxy_become_users.privsep is defined else __galaxy_become }}"
-  become_user: "{{ galaxy_become_users.privsep | default(__galaxy_become_user) }}"
-
-- name: Mutable config setup
-  block:
-
-    - name: Ensure Galaxy version is set
-      include_tasks: _inc_galaxy_version.yml
-      when: __galaxy_major_version is undefined
-
     # force: no in the following 2 tasks will not overwrite existing configs
     - name: Instantiate mutable configuration files
       copy:

From e540b09304d6d36c4973ba8def5dadf1bf807658 Mon Sep 17 00:00:00 2001
From: Nate Coraor <nate@bx.psu.edu>
Date: Thu, 13 Apr 2023 10:59:22 -0400
Subject: [PATCH 12/46] Add vars for creating extra dirs

---
 defaults/main.yml | 6 ++++++
 tasks/paths.yml   | 4 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/defaults/main.yml b/defaults/main.yml
index 60112e8..6fdd2aa 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -107,6 +107,9 @@ galaxy_dirs:
   - "{{ galaxy_tool_data_path }}"
   - "{{ galaxy_log_dir }}"
 
+# Additional directories to create as the Galaxy user, so you don't have to copy the default galaxy_dirs
+galaxy_extra_dirs: []
+
 # Directories to create as the privilege separated user if galaxy_manage_paths is enabled
 galaxy_privsep_dirs:
   - "{{ galaxy_venv_dir }}"
@@ -114,6 +117,9 @@ galaxy_privsep_dirs:
   - "{{ galaxy_config_dir }}"
   - "{{ galaxy_local_tools_dir }}"
 
+# Additional directories to create as the privilege separated user, so you don't have to copy the default galaxy_dirs
+galaxy_extra_privsep_dirs: []
+
 # Local (relative to playbook) path to local tools
 galaxy_local_tools_src_dir: files/galaxy/tools
 
diff --git a/tasks/paths.yml b/tasks/paths.yml
index 66dbe2b..0b86999 100644
--- a/tasks/paths.yml
+++ b/tasks/paths.yml
@@ -20,7 +20,7 @@
         owner: "{{ __galaxy_privsep_user_name }}"
         group: "{{ __galaxy_user_group }}" #This is set so that the galaxy_user can read the files in the priv_sep dirs. (As priv_sep dirs have defauly perms of 0640.)
         mode: "{{ __galaxy_dir_perms }}"
-      with_items: "{{ galaxy_privsep_dirs }}"
+      loop: "{{ galaxy_privsep_dirs + galaxy_extra_privsep_dirs }}"
       when: item | default(False)
 
     - name: Create additional directories
@@ -30,7 +30,7 @@
         owner: "{{ __galaxy_user_name }}"
         group: "{{ __galaxy_user_group }}"
         mode: "{{ __galaxy_dir_perms }}"
-      with_items: "{{ galaxy_dirs }}"
+      loop: "{{ galaxy_dirs + galaxy_extra_dirs }}"
 
   # TODO: for root squashing it might be useful for this to be separate from other root tasks
   remote_user: "{{ galaxy_remote_users.root | default(__galaxy_remote_user) }}"

From 0e5bc4a47bf09eddbd3e888969e088e1448d5e16 Mon Sep 17 00:00:00 2001
From: Helena Rasche <hexylena@galaxians.org>
Date: Fri, 14 Apr 2023 14:25:16 +0200
Subject: [PATCH 13/46] Maybe this works better

---
 defaults/main.yml      |  3 +++
 tasks/static_setup.yml | 11 +++++++++++
 2 files changed, 14 insertions(+)

diff --git a/defaults/main.yml b/defaults/main.yml
index 60112e8..9d37ac3 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -246,6 +246,7 @@ galaxy_app_config_section: "{{ 'galaxy' if galaxy_config_style in ('yaml', 'yml'
 
 # Galaxy configuration files will be written with these permissions (mode argument to Ansible copy/template module)
 galaxy_config_perms: 0640
+galaxy_config_perms_public: 0644
 
 # The default Galaxy configuration, ensures that Galaxy can find all of the configs if galaxy_config_dir !=
 # galaxy_server_dir
@@ -313,6 +314,8 @@ galaxy_errordocs_prefix: /error
 # templates to be installed on the managed host.
 galaxy_config_files: []
 galaxy_config_templates: []
+# Like above, except with world readable permissions
+galaxy_config_files_public: []
 
 # Default Gravity configuration
 galaxy_gravity_state_dir: "{{ (galaxy_mutable_data_dir, 'gravity') | path_join }}"
diff --git a/tasks/static_setup.yml b/tasks/static_setup.yml
index 56016f6..f83e5c4 100644
--- a/tasks/static_setup.yml
+++ b/tasks/static_setup.yml
@@ -27,6 +27,17 @@
       notify:
         - restart galaxy
 
+    - name: Install additional Galaxy config files (static, public)
+      copy:
+        src: "{{ item.src }}"
+        dest: "{{ item.dest }}"
+        backup: "{{ galaxy_backup_configfiles }}"
+        mode: "{{ galaxy_config_perms_public }}"
+        group: "{{ __galaxy_user_group }}"
+      with_items: "{{ galaxy_config_files_public }}"
+      notify:
+        - restart galaxy
+
     - name: Install additional Galaxy config files (template)
       template:
         src: "{{ item.src }}"

From 38a57334499a9876c400c393624b5c03f34343fc Mon Sep 17 00:00:00 2001
From: Nicola Soranzo <nicola.soranzo@gmail.com>
Date: Tue, 18 Apr 2023 09:15:55 +0100
Subject: [PATCH 14/46] Fix issue with jinja2 < 2.11.0

Ubuntu 20.04 LTS has jinja2 2.10.1, which doesn't support `is true` and various other `is` tests added in https://github.com/pallets/jinja/pull/824

Fix:
```
TASK [galaxyproject.galaxy : Schedule tmpclean cron job (root)] *******************************************************************************************************************************************
fatal: [gat-18.eu.galaxy.training]: FAILED! =>
  msg: |-
    An unhandled exception occurred while templating '{{ (galaxy_tmpclean_log is not true) | ternary(
        ((galaxy_tmpclean_log is none) | ternary(
            '>/dev/null',
            '>>' ~ galaxy_tmpclean_log
        )),
        ''
    ) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: template error while templating string: no test named 'true'. String: {{ (galaxy_tmpclean_log is not true) | ternary(
        ((galaxy_tmpclean_log is none) | ternary(
            '>/dev/null',
            '>>' ~ galaxy_tmpclean_log
        )),
        ''
    ) }}
```
---
 defaults/main.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/defaults/main.yml b/defaults/main.yml
index ac7c4ae..b1c88c2 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -188,7 +188,7 @@ _galaxy_tmpclean_command:
 
 galaxy_tmpclean_verbose_statement: "{{ galaxy_tmpclean_verbose | ternary(' -v', '') }}"
 galaxy_tmpclean_log_statement: >-
-  {{ (galaxy_tmpclean_log is not true) | ternary(
+  {{ (galaxy_tmpclean_log != true) | ternary(
       ((galaxy_tmpclean_log is none) | ternary(
           '>/dev/null',
           '>>' ~ galaxy_tmpclean_log

From 92e22bd00676d22ec7a1dee4938688c7b4222eee Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Fri, 28 Jul 2023 15:52:46 +0200
Subject: [PATCH 15/46] add subdomains to ansible-galaxy

---
 defaults/main.yml           | 72 +++++++++++++++++++++++++++++++++++++
 tasks/copy_static_files.yml | 18 ++++++++++
 tasks/copy_themes.yml       | 14 ++++++++
 tasks/main.yml              | 18 ++++++++++
 tasks/setup_static.yml      | 49 +++++++++++++++++++++++++
 5 files changed, 171 insertions(+)
 create mode 100644 tasks/copy_static_files.yml
 create mode 100644 tasks/copy_themes.yml
 create mode 100644 tasks/setup_static.yml

diff --git a/defaults/main.yml b/defaults/main.yml
index b1c88c2..22e49e6 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -23,6 +23,7 @@ galaxy_manage_gravity: "{{ false if __galaxy_major_version is version('22.05', '
 galaxy_manage_systemd: no # For Galaxy
 galaxy_manage_systemd_reports: no # For Reports
 galaxy_manage_cleanup: no
+galaxy_manage_themes: no
 
 
 # Control whether to output verbose task diffs (e.g. when performing a git update) when running Ansible with --diff.
@@ -295,6 +296,50 @@ galaxy_app_config_default:
   # Everything else
   visualization_plugins_directory: "config/plugins/visualizations"
 
+  # Static and themes cofiguration, will only be added if galaxy_manage_themes
+  enable_static: "{{ galaxy_manage_themes }}"
+  static_dir_by_host: >
+    { {% if galaxy_manage_static %}
+    {% for subdomain in galaxy_names_subdomains %}
+    '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/'
+    {% end for %}
+    {% end if %} }
+  static_images_dir_by_host: >
+    { {% if galaxy_manage_static %}
+    {% for subdomain in galaxy_names_subdomains %}
+    '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/images'
+    {% end for %}
+    {% end if %} }
+  static_welcome_html_by_host: >
+    { {% if galaxy_manage_static %}
+    {% for subdomain in galaxy_names_subdomains %}
+    '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/welcome.html'
+    {% end for %}
+    {% end if %} }
+  static_scripts_dir_by_host: >
+    { {% if galaxy_manage_static %}
+    {% for subdomain in galaxy_names_subdomains %}
+    '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/scripts'
+    {% end for %}
+    {% end if %} }
+  static_favicon_dir_by_host: >
+    { {% if galaxy_manage_static %}
+    {% for subdomain in galaxy_names_subdomains %}
+    '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/favicon.ico'
+    {% end for %}
+    {% end if %} }
+  static_robots_txt_by_host: >
+    { {% if galaxy_manage_static %}
+    {% for subdomain in galaxy_names_subdomains %}
+    '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/robots.txt'
+    {% end for %}
+    {% end if %} }
+  themes_dir_by_host: >
+    { {% if galaxy_manage_themes %}
+    {% for subdomain in galaxy_names_subdomains %}
+    '{{ subdomain.names  }}.{{ galaxy_themes_instance_domain}}': {{ subdomain.name }}.yml
+    {% end for %}
+    {% end if %} }
 # Need to set galaxy_config_default[galaxy_app_config_section] dynamically but Ansible/Jinja2 does not make this easy
 galaxy_config_default: "{{ {} | combine({galaxy_app_config_section: galaxy_app_config_default}) }}"
 galaxy_config_merged: "{{ galaxy_config_default | combine(galaxy_config | default({}), recursive=True) }}"
@@ -425,3 +470,30 @@ galaxy_systemd_env: []
 
 # A list of additional python packages to install into galaxy's virtual environment
 galaxy_additional_venv_packages: []
+
+# galaxy themes variables
+galaxy_themes_subdomains: {}
+# - name: assembly
+#   tool_sections:
+#     - "hicexplorer"
+#     - "graph_display_data"
+#     - "peak_calling"
+#     - "assembly"
+#     - "annotation"
+#     - "genome_diversity"
+#     - "multiple_alignments"
+#   extra_tool_labels:
+#     - "proteomics"
+galaxy_themes_static_keys:
+  static_dir: ""
+  static_images_dir: "images/"
+  static_scripts_dir: "scripts/"
+  static_welcome_html: "welcome.html/"
+  static_favicon_dir: "favicon.ico"
+  static_robots_txt: "robots.txt"
+galaxy_themes_conf_path: files/galaxy/config/themes_conf.yml
+galaxy_themes_static_path: "{{ galaxy_root }}/server"
+galaxy_themes_static_dir: "{{ galaxy_root }}/server/static"
+galaxy_themes_welcome_url_prefix: https://usegalaxy-eu.github.io/index-
+galaxy_themes_ansible_file_path: files/galaxy/static
+galaxy_themes_instance_domain: usegalaxy.eu
diff --git a/tasks/copy_static_files.yml b/tasks/copy_static_files.yml
new file mode 100644
index 0000000..0364043
--- /dev/null
+++ b/tasks/copy_static_files.yml
@@ -0,0 +1,18 @@
+---
+- name: Copy static files
+  ansible.builtin.copy:
+    src: "{{ item }}"
+    dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain }}/{{ object.value }}"
+    mode: '0644'
+    owner: "{{ __galaxy_privsep_user_name }}"
+    group: "{{ __galaxy_privsep_user_group }}"
+  with_fileglob: "{{ galaxy_themes_ansible_file_path }}/{{ subdomain }}/static/{{ object.value }}*"
+
+- name: Copy files from dist
+  ansible.builtin.copy:
+    src: "{{ item }}"
+    dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain }}/dist/"
+    mode: '0644'
+    owner: "{{ __galaxy_privsep_user_name }}"
+    group: "{{ __galaxy_privsep_user_group }}"
+  with_fileglob: "{{ galaxy_themes_ansible_file_path }}/{{ subdomain }}/static/dist/*"
diff --git a/tasks/copy_themes.yml b/tasks/copy_themes.yml
new file mode 100644
index 0000000..09108f6
--- /dev/null
+++ b/tasks/copy_themes.yml
@@ -0,0 +1,14 @@
+---
+
+- name: Copy themes files
+  ansible.builtin.copy:
+    src: "{{ galaxy_themes_ansible_file_path }}/{{ subdomain.name }}/themes/{{ subdomain.name }}.yml"
+    dest: "{{ galaxy_config_dir }}"
+    mode: '0644'
+    owner: "{{ __galaxy_privsep_user_name }}"
+    group: "{{ __galaxy_privsep_user_group }}"
+
+- name: Append themes_conf.yml to all files in galaxy/config/themes
+  ansible.builtin.blockinfile:
+    block: "{{ lookup('ansible.builtin.file', subdomains_themes_conf_path) }}"
+    path: "{{ galaxy_config_dir }}/{{ subdomain.name }}.yml"
diff --git a/tasks/main.yml b/tasks/main.yml
index dfb47b3..e351de5 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -160,3 +160,21 @@
   when: galaxy_manage_cleanup
   tags:
     - galaxy_manage_cleanup
+
+- name: Include Copy static files
+  ansible.builtin.include_tasks: setup_static.yml
+  loop: "{{ galaxy_themes_subdomains }}"
+  loop_control:
+    loop_var: subdomain
+  when: galaxy_manage_static
+  tags:
+    - galaxy_manage_static
+
+- name: Include Copy themes files
+  ansible.builtin.include_tasks: copy_themes.yml
+  loop: "{{ galaxy_themes_subdomains }}"
+  loop_control:
+    loop_var: subdomain
+  when: galaxy_manage_themes
+  tags:
+    - galaxy_manage_themes
diff --git a/tasks/setup_static.yml b/tasks/setup_static.yml
new file mode 100644
index 0000000..b66ea4d
--- /dev/null
+++ b/tasks/setup_static.yml
@@ -0,0 +1,49 @@
+---
+- name: Create static dirs
+  ansible.builtin.file:
+    state: directory
+    mode: '0755'
+    owner: "{{ __galaxy_privsep_user_name }}"
+    group: "{{ __galaxy_privsep_user_group }}"
+    path: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}"
+
+- name: Move all contents from static to parent directory
+  ansible.builtin.command: cp -r {{ galaxy_themes_static_dir }}/. {{ galaxy_themes_static_path }}/static-{{ \
+   subdomain.name }}
+  changed_when: false
+
+- name: Remove static dirs
+  ansible.builtin.file:
+    state: absent
+    mode: '0755'
+    owner: "{{ __galaxy_privsep_user_name }}"
+    group: "{{ __galaxy_privsep_user_group }}"
+    path: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/static"
+
+- name: Create welcome.html directory
+  ansible.builtin.file:
+    state: directory
+    mode: '0755'
+    owner: "{{ __galaxy_privsep_user_name }}"
+    group: "{{ __galaxy_privsep_user_group }}"
+    path: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/welcome.html"
+
+- name: Check if iframe for subdomain exists
+  ansible.builtin.uri:
+    url: "{{ galaxy_themes_welcome_url_prefix }}{{ subdomain.name }}.html"
+    return_content: true
+  register: iframe
+
+- name: Template welcome.html for subdomains
+  ansible.builtin.template:
+    src: welcome.html.j2
+    dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/welcome.html/index.html"
+    owner: "{{ __galaxy_privsep_user_name }}"
+    group: "{{ __galaxy_privsep_user_group }}"
+    mode: '0644'
+
+- name: Copy static files
+  ansible.builtin.include_tasks: copy_static_files.yml
+  loop: "{{ galaxy_themes_static_keys | dict2items }}"
+  loop_control:
+    loop_var: object

From bdeb8776419f30e10dd349e9d1800a6a4da6cbf3 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Thu, 3 Aug 2023 14:57:54 +0200
Subject: [PATCH 16/46] add global host filters

---
 defaults/main.yml                     | 52 +++++++++++++++++----
 tasks/main.yml                        |  9 +++-
 tasks/{copy_themes.yml => themes.yml} |  0
 templates/global_host_filters.py.j2   | 67 +++++++++++++++++++++++++++
 4 files changed, 118 insertions(+), 10 deletions(-)
 rename tasks/{copy_themes.yml => themes.yml} (100%)
 create mode 100644 templates/global_host_filters.py.j2

diff --git a/defaults/main.yml b/defaults/main.yml
index 22e49e6..006c9db 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -24,6 +24,7 @@ galaxy_manage_systemd: no # For Galaxy
 galaxy_manage_systemd_reports: no # For Reports
 galaxy_manage_cleanup: no
 galaxy_manage_themes: no
+galaxy_manage_host_filters: no
 
 
 # Control whether to output verbose task diffs (e.g. when performing a git update) when running Ansible with --diff.
@@ -296,47 +297,47 @@ galaxy_app_config_default:
   # Everything else
   visualization_plugins_directory: "config/plugins/visualizations"
 
-  # Static and themes cofiguration, will only be added if galaxy_manage_themes
-  enable_static: "{{ galaxy_manage_themes }}"
+  # Static and themes configuration, will only be added if galaxy_manage_themes
+  enable_static: "{{ galaxy_manage_static }}"
   static_dir_by_host: >
     { {% if galaxy_manage_static %}
-    {% for subdomain in galaxy_names_subdomains %}
+    {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/'
     {% end for %}
     {% end if %} }
   static_images_dir_by_host: >
     { {% if galaxy_manage_static %}
-    {% for subdomain in galaxy_names_subdomains %}
+    {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/images'
     {% end for %}
     {% end if %} }
   static_welcome_html_by_host: >
     { {% if galaxy_manage_static %}
-    {% for subdomain in galaxy_names_subdomains %}
+    {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/welcome.html'
     {% end for %}
     {% end if %} }
   static_scripts_dir_by_host: >
     { {% if galaxy_manage_static %}
-    {% for subdomain in galaxy_names_subdomains %}
+    {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/scripts'
     {% end for %}
     {% end if %} }
   static_favicon_dir_by_host: >
     { {% if galaxy_manage_static %}
-    {% for subdomain in galaxy_names_subdomains %}
+    {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/favicon.ico'
     {% end for %}
     {% end if %} }
   static_robots_txt_by_host: >
     { {% if galaxy_manage_static %}
-    {% for subdomain in galaxy_names_subdomains %}
+    {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/robots.txt'
     {% end for %}
     {% end if %} }
   themes_dir_by_host: >
     { {% if galaxy_manage_themes %}
-    {% for subdomain in galaxy_names_subdomains %}
+    {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.names  }}.{{ galaxy_themes_instance_domain}}': {{ subdomain.name }}.yml
     {% end for %}
     {% end if %} }
@@ -497,3 +498,36 @@ galaxy_themes_static_dir: "{{ galaxy_root }}/server/static"
 galaxy_themes_welcome_url_prefix: https://usegalaxy-eu.github.io/index-
 galaxy_themes_ansible_file_path: files/galaxy/static
 galaxy_themes_instance_domain: usegalaxy.eu
+galaxy_themes_global_host_filters_path: "{{ galaxy_root }}/server/lib/galaxy/tool_util/toolbox/filters/global_host_filters.py"
+galaxy_themes_tool_base_labels:
+    - "file_and_meta_tools"
+    - "general_text_tools"
+    - "genomic_file_manipulation"
+    - "gff"
+    - "common_genomics"
+galaxy_themes_tool_ngs_labels:
+    - "specific_genomics"
+    - "genomics_toolkits"
+
+# These sections will be displayed in the tool panel for every subdomain
+galaxy_themes_tool_base_sections:
+    - "getext"
+    - "send"
+    - "collection_operations"
+    - "textutil"
+    - "convert"
+    - "filter"
+    - "group"
+    - "expression_tools"
+
+# There sections are a collection of general NGS tools and will be used in most but not all subdomains
+galaxy_themes_tool_ngs_sections:
+    - "deeptools"
+    - "bed"
+    - "sambam"
+    - "bxops"
+    - "fastafastq"
+    - "fastq_quality_control"
+    - "picard"
+    - "mapping"
+    - "sambam"
\ No newline at end of file
diff --git a/tasks/main.yml b/tasks/main.yml
index e351de5..09bf75c 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -171,10 +171,17 @@
     - galaxy_manage_static
 
 - name: Include Copy themes files
-  ansible.builtin.include_tasks: copy_themes.yml
+  ansible.builtin.include_tasks: themes.yml
   loop: "{{ galaxy_themes_subdomains }}"
   loop_control:
     loop_var: subdomain
   when: galaxy_manage_themes
   tags:
     - galaxy_manage_themes
+
+- name: Set global host filters
+  ansible.builtin.template:
+    src: "global_host_filters.py.j2"
+    dest: "{{ galaxy_themes_global_host_filters_path }}"
+    mode: 0644
+  when: galaxy_manage_host_filters
diff --git a/tasks/copy_themes.yml b/tasks/themes.yml
similarity index 100%
rename from tasks/copy_themes.yml
rename to tasks/themes.yml
diff --git a/templates/global_host_filters.py.j2 b/templates/global_host_filters.py.j2
new file mode 100644
index 0000000..a032289
--- /dev/null
+++ b/templates/global_host_filters.py.j2
@@ -0,0 +1,67 @@
+import logging
+log = logging.getLogger( __name__ )
+
+def per_host_tool_labels( context, label ):
+    """
+    This tool section filter results in different labels being displayed based on
+    the fqdn the user is making the request to. This could allow a single Galaxy instance
+    to seem like several different instances hosting different tools based on the fqdn used
+    to access the Galxy. This can be enabled by renaming this file to examples.py and adding
+    the following to the ``app:main`` section of ``galaxy.yml``:
+
+        tool_label_filters = examples:per_host_tool_labels
+    """
+    host = context.trans.request.host
+    subdomain = host.replace('.{{ galaxy_themes_instance_domain }}', '')
+    # Core tools used by all virtual hosts.
+    valid_labels = {{ galaxy_themes_tool_base_labels }}
+    general_ngs_labels = {{ galaxy_themes_tool_ngs_labels }}
+{% if galaxy_themes_subdomains is defined %}
+{% for subsite in galaxy_themes_subdomains %}
+    if "{{ subsite.name }}.{{ galaxy_themes_instance_domain }}" in host:
+        valid_labels += general_ngs_labels
+{% if subsite.extra_tool_labels is defined %}
+        valid_labels += {{ subsite.extra_tool_labels }}
+{% endif %}
+        return label.id in valid_labels
+{% endfor %}
+{% endif %}        
+    return True
+
+BASE_SECTIONS = {{ galaxy_themes_tool_base_sections }}
+
+GENERAL_NGS_SECTIONS = {{ galaxy_themes_tool_ngs_sections }}
+
+DOMAIN_SECTIONS = {
+{% if galaxy_themes_subdomains is defined %}
+{% for subdomain in galaxy_themes_subdomains %}
+{% if subdomain.tool_sections is defined %}
+    '{{ subdomain.name }}': GENERAL_NGS_SECTIONS + {{ subdomain.tool_sections }},
+{% endif %}    
+{% endfor %}
+{% endif %}    
+}
+
+
+def per_host_tool_sections( context, section ):
+    """
+    This tool section filter results in different sections being displayed based on
+    the fqdn the user is making the request to. This could allow a single Galaxy instance
+    to seem like several different instances hosting different tools based on the fqdn used
+    to access the Galxy. This can be enabled by renaming this file to examples.py and adding
+    the following to the ``app:main`` section of ``galaxy.yml``:
+
+        tool_section_filters = examples:per_host_tool_sections
+    """
+    host = context.trans.request.host
+    subdomain = host.replace('.{{ galaxy_themes_instance_domain }}', '')
+
+    # Core tools used by all virtual hosts.
+    # HiCtools mode: published in NAR 2018
+    if host == "{{ galaxy_themesinstance_domain }}":
+        return True
+
+    if subdomain in DOMAIN_SECTIONS:
+        return section.id in DOMAIN_SECTIONS[subdomain] or section.id in BASE_SECTIONS
+    else:
+        return True
\ No newline at end of file

From 9965b6a0bde4277abdaa41f5f3beca7c96bda7dd Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Thu, 3 Aug 2023 14:59:15 +0200
Subject: [PATCH 17/46] fix names

---
 defaults/main.yml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/defaults/main.yml b/defaults/main.yml
index 006c9db..fca9cd4 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -302,43 +302,43 @@ galaxy_app_config_default:
   static_dir_by_host: >
     { {% if galaxy_manage_static %}
     {% for subdomain in galaxy_themes_subdomains %}
-    '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/'
+    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/'
     {% end for %}
     {% end if %} }
   static_images_dir_by_host: >
     { {% if galaxy_manage_static %}
     {% for subdomain in galaxy_themes_subdomains %}
-    '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/images'
+    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/images'
     {% end for %}
     {% end if %} }
   static_welcome_html_by_host: >
     { {% if galaxy_manage_static %}
     {% for subdomain in galaxy_themes_subdomains %}
-    '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/welcome.html'
+    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/welcome.html'
     {% end for %}
     {% end if %} }
   static_scripts_dir_by_host: >
     { {% if galaxy_manage_static %}
     {% for subdomain in galaxy_themes_subdomains %}
-    '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/scripts'
+    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/scripts'
     {% end for %}
     {% end if %} }
   static_favicon_dir_by_host: >
     { {% if galaxy_manage_static %}
     {% for subdomain in galaxy_themes_subdomains %}
-    '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/favicon.ico'
+    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/favicon.ico'
     {% end for %}
     {% end if %} }
   static_robots_txt_by_host: >
     { {% if galaxy_manage_static %}
     {% for subdomain in galaxy_themes_subdomains %}
-    '{{ subdomain.names }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/robots.txt'
+    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/robots.txt'
     {% end for %}
     {% end if %} }
   themes_dir_by_host: >
     { {% if galaxy_manage_themes %}
     {% for subdomain in galaxy_themes_subdomains %}
-    '{{ subdomain.names  }}.{{ galaxy_themes_instance_domain}}': {{ subdomain.name }}.yml
+    '{{ subdomain.name  }}.{{ galaxy_themes_instance_domain}}': {{ subdomain.name }}.yml
     {% end for %}
     {% end if %} }
 # Need to set galaxy_config_default[galaxy_app_config_section] dynamically but Ansible/Jinja2 does not make this easy

From 71df44f8ca62bea8d2ff6c8e4b0a472e1914f367 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Thu, 3 Aug 2023 15:19:24 +0200
Subject: [PATCH 18/46] galaxy_manage_static

---
 defaults/main.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/defaults/main.yml b/defaults/main.yml
index fca9cd4..dc7732a 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -24,6 +24,7 @@ galaxy_manage_systemd: no # For Galaxy
 galaxy_manage_systemd_reports: no # For Reports
 galaxy_manage_cleanup: no
 galaxy_manage_themes: no
+galaxy_manage_static: no
 galaxy_manage_host_filters: no
 
 

From 773ce68ac8ab9e46f018c69bd418873e77799167 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Thu, 3 Aug 2023 15:25:52 +0200
Subject: [PATCH 19/46] fix syntax

---
 defaults/main.yml | 76 +++++++++++++++++++++++------------------------
 1 file changed, 38 insertions(+), 38 deletions(-)

diff --git a/defaults/main.yml b/defaults/main.yml
index dc7732a..5882e23 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -304,44 +304,44 @@ galaxy_app_config_default:
     { {% if galaxy_manage_static %}
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/'
-    {% end for %}
-    {% end if %} }
+    {% endfor %}
+    {% endif %} }
   static_images_dir_by_host: >
     { {% if galaxy_manage_static %}
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/images'
-    {% end for %}
-    {% end if %} }
+    {% endfor %}
+    {% endif %} }
   static_welcome_html_by_host: >
     { {% if galaxy_manage_static %}
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/welcome.html'
-    {% end for %}
-    {% end if %} }
+    {% endfor %}
+    {% endif %} }
   static_scripts_dir_by_host: >
     { {% if galaxy_manage_static %}
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/scripts'
-    {% end for %}
-    {% end if %} }
+    {% endfor %}
+    {% endif %} }
   static_favicon_dir_by_host: >
     { {% if galaxy_manage_static %}
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/favicon.ico'
-    {% end for %}
-    {% end if %} }
+    {% endfor %}
+    {% endif %} }
   static_robots_txt_by_host: >
     { {% if galaxy_manage_static %}
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/robots.txt'
-    {% end for %}
-    {% end if %} }
+    {% endfor %}
+    {% endif %} }
   themes_dir_by_host: >
     { {% if galaxy_manage_themes %}
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name  }}.{{ galaxy_themes_instance_domain}}': {{ subdomain.name }}.yml
-    {% end for %}
-    {% end if %} }
+    {% endfor %}
+    {% endif %} }
 # Need to set galaxy_config_default[galaxy_app_config_section] dynamically but Ansible/Jinja2 does not make this easy
 galaxy_config_default: "{{ {} | combine({galaxy_app_config_section: galaxy_app_config_default}) }}"
 galaxy_config_merged: "{{ galaxy_config_default | combine(galaxy_config | default({}), recursive=True) }}"
@@ -501,34 +501,34 @@ galaxy_themes_ansible_file_path: files/galaxy/static
 galaxy_themes_instance_domain: usegalaxy.eu
 galaxy_themes_global_host_filters_path: "{{ galaxy_root }}/server/lib/galaxy/tool_util/toolbox/filters/global_host_filters.py"
 galaxy_themes_tool_base_labels:
-    - "file_and_meta_tools"
-    - "general_text_tools"
-    - "genomic_file_manipulation"
-    - "gff"
-    - "common_genomics"
+  - "file_and_meta_tools"
+  - "general_text_tools"
+  - "genomic_file_manipulation"
+  - "gff"
+  - "common_genomics"
 galaxy_themes_tool_ngs_labels:
-    - "specific_genomics"
-    - "genomics_toolkits"
+  - "specific_genomics"
+  - "genomics_toolkits"
 
 # These sections will be displayed in the tool panel for every subdomain
 galaxy_themes_tool_base_sections:
-    - "getext"
-    - "send"
-    - "collection_operations"
-    - "textutil"
-    - "convert"
-    - "filter"
-    - "group"
-    - "expression_tools"
+  - "getext"
+  - "send"
+  - "collection_operations"
+  - "textutil"
+  - "convert"
+  - "filter"
+  - "group"
+  - "expression_tools"
 
 # There sections are a collection of general NGS tools and will be used in most but not all subdomains
 galaxy_themes_tool_ngs_sections:
-    - "deeptools"
-    - "bed"
-    - "sambam"
-    - "bxops"
-    - "fastafastq"
-    - "fastq_quality_control"
-    - "picard"
-    - "mapping"
-    - "sambam"
\ No newline at end of file
+  - "deeptools"
+  - "bed"
+  - "sambam"
+  - "bxops"
+  - "fastafastq"
+  - "fastq_quality_control"
+  - "picard"
+  - "mapping"
+  - "sambam"

From cad8eedb2ec3419fbbfbf5d3f96372b1191480aa Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Thu, 3 Aug 2023 15:37:08 +0200
Subject: [PATCH 20/46] rename

---
 tasks/main.yml                                    | 2 +-
 tasks/{setup_static.yml => setup_static_dirs.yml} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename tasks/{setup_static.yml => setup_static_dirs.yml} (100%)

diff --git a/tasks/main.yml b/tasks/main.yml
index 09bf75c..2128858 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -162,7 +162,7 @@
     - galaxy_manage_cleanup
 
 - name: Include Copy static files
-  ansible.builtin.include_tasks: setup_static.yml
+  ansible.builtin.include_tasks: setup_static_dirs.yml
   loop: "{{ galaxy_themes_subdomains }}"
   loop_control:
     loop_var: subdomain
diff --git a/tasks/setup_static.yml b/tasks/setup_static_dirs.yml
similarity index 100%
rename from tasks/setup_static.yml
rename to tasks/setup_static_dirs.yml

From b660a3678d9d493be349e41f9a54b793c0bb8103 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Thu, 3 Aug 2023 15:54:44 +0200
Subject: [PATCH 21/46] variable name

---
 tasks/themes.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tasks/themes.yml b/tasks/themes.yml
index 09108f6..85eee2d 100644
--- a/tasks/themes.yml
+++ b/tasks/themes.yml
@@ -10,5 +10,5 @@
 
 - name: Append themes_conf.yml to all files in galaxy/config/themes
   ansible.builtin.blockinfile:
-    block: "{{ lookup('ansible.builtin.file', subdomains_themes_conf_path) }}"
+    block: "{{ lookup('ansible.builtin.file', galaxy_themes_conf_path) }}"
     path: "{{ galaxy_config_dir }}/{{ subdomain.name }}.yml"

From b828749b8ebcf9deb5099edd84876d5cc89d8900 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Thu, 3 Aug 2023 15:58:58 +0200
Subject: [PATCH 22/46] typo

---
 templates/global_host_filters.py.j2 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/global_host_filters.py.j2 b/templates/global_host_filters.py.j2
index a032289..41ec121 100644
--- a/templates/global_host_filters.py.j2
+++ b/templates/global_host_filters.py.j2
@@ -58,7 +58,7 @@ def per_host_tool_sections( context, section ):
 
     # Core tools used by all virtual hosts.
     # HiCtools mode: published in NAR 2018
-    if host == "{{ galaxy_themesinstance_domain }}":
+    if host == "{{ galaxy_themes_instance_domain }}":
         return True
 
     if subdomain in DOMAIN_SECTIONS:

From 7e1a0ff40ca23c00779f87113efc432c7bdf403b Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Thu, 3 Aug 2023 16:18:01 +0200
Subject: [PATCH 23/46] fix variable

---
 tasks/copy_static_files.yml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tasks/copy_static_files.yml b/tasks/copy_static_files.yml
index 0364043..a765719 100644
--- a/tasks/copy_static_files.yml
+++ b/tasks/copy_static_files.yml
@@ -2,17 +2,17 @@
 - name: Copy static files
   ansible.builtin.copy:
     src: "{{ item }}"
-    dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain }}/{{ object.value }}"
+    dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/{{ object.value }}"
     mode: '0644'
     owner: "{{ __galaxy_privsep_user_name }}"
     group: "{{ __galaxy_privsep_user_group }}"
-  with_fileglob: "{{ galaxy_themes_ansible_file_path }}/{{ subdomain }}/static/{{ object.value }}*"
+  with_fileglob: "{{ galaxy_themes_ansible_file_path }}/{{ subdomain.name }}/static/{{ object.value }}*"
 
 - name: Copy files from dist
   ansible.builtin.copy:
     src: "{{ item }}"
-    dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain }}/dist/"
+    dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/dist/"
     mode: '0644'
     owner: "{{ __galaxy_privsep_user_name }}"
     group: "{{ __galaxy_privsep_user_group }}"
-  with_fileglob: "{{ galaxy_themes_ansible_file_path }}/{{ subdomain }}/static/dist/*"
+  with_fileglob: "{{ galaxy_themes_ansible_file_path }}/{{ subdomain.name }}/static/dist/*"

From 9903e44245ec7c481c577f7cb1228730cbebe9e2 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Thu, 3 Aug 2023 16:31:28 +0200
Subject: [PATCH 24/46] welcome template

---
 defaults/main.yml           |  1 +
 tasks/setup_static_dirs.yml |  1 +
 templates/welcome.html.j2   | 39 +++++++++++++++++++++++++++++++++++++
 3 files changed, 41 insertions(+)
 create mode 100644 templates/welcome.html.j2

diff --git a/defaults/main.yml b/defaults/main.yml
index 5882e23..fa480c1 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -497,6 +497,7 @@ galaxy_themes_conf_path: files/galaxy/config/themes_conf.yml
 galaxy_themes_static_path: "{{ galaxy_root }}/server"
 galaxy_themes_static_dir: "{{ galaxy_root }}/server/static"
 galaxy_themes_welcome_url_prefix: https://usegalaxy-eu.github.io/index-
+galaxy_themes_default_welcome: https://galaxyproject.org
 galaxy_themes_ansible_file_path: files/galaxy/static
 galaxy_themes_instance_domain: usegalaxy.eu
 galaxy_themes_global_host_filters_path: "{{ galaxy_root }}/server/lib/galaxy/tool_util/toolbox/filters/global_host_filters.py"
diff --git a/tasks/setup_static_dirs.yml b/tasks/setup_static_dirs.yml
index b66ea4d..303dd45 100644
--- a/tasks/setup_static_dirs.yml
+++ b/tasks/setup_static_dirs.yml
@@ -33,6 +33,7 @@
     url: "{{ galaxy_themes_welcome_url_prefix }}{{ subdomain.name }}.html"
     return_content: true
   register: iframe
+  failed_when: false
 
 - name: Template welcome.html for subdomains
   ansible.builtin.template:
diff --git a/templates/welcome.html.j2 b/templates/welcome.html.j2
new file mode 100644
index 0000000..3ce522d
--- /dev/null
+++ b/templates/welcome.html.j2
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html
+	PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+
+<head>
+	<style>
+		body,
+		html {
+			width: 100%;
+			height: 100%;
+			overflow: hidden;
+		}
+
+		iframe {
+			width: 100%;
+			height: 100%;
+			border: none;
+			position: absolute;
+			top: -9999em;
+			visibility: hidden;
+		}
+	</style>
+</head>
+
+<body style="margin:0px">
+	<iframe id='center-iframe' src="" height="100%"
+		onload="this.style.position='static'; this.style.visibility='visible';"></iframe>
+	<script type="text/javascript">
+		var pseudo_rand = parseInt(Date.now() / 1000 / 60 / 10);
+		{% if iframe is defined %}
+		document.getElementById('center-iframe').src = '{{ galaxy_themes_welcome_url_prefix }}{{ subdomain }}?nonce=' + pseudo_rand + '#';
+		{% else %}
+		document.getElementById('center-iframe').src = '{{ galaxy_themes_default_welcome }}?nonce=' + pseudo_rand + '#';
+		{% endif %}
+	</script>
+</body>
+
+</html>
\ No newline at end of file

From 3dc101a4fab344ab4b00ea5bb16a21543121844b Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Thu, 3 Aug 2023 16:57:26 +0200
Subject: [PATCH 25/46] fix welcome

---
 templates/welcome.html.j2 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/welcome.html.j2 b/templates/welcome.html.j2
index 3ce522d..79ded41 100644
--- a/templates/welcome.html.j2
+++ b/templates/welcome.html.j2
@@ -29,7 +29,7 @@
 	<script type="text/javascript">
 		var pseudo_rand = parseInt(Date.now() / 1000 / 60 / 10);
 		{% if iframe is defined %}
-		document.getElementById('center-iframe').src = '{{ galaxy_themes_welcome_url_prefix }}{{ subdomain }}?nonce=' + pseudo_rand + '#';
+		document.getElementById('center-iframe').src = '{{ galaxy_themes_welcome_url_prefix }}{{ subdomain.name }}?nonce=' + pseudo_rand + '#';
 		{% else %}
 		document.getElementById('center-iframe').src = '{{ galaxy_themes_default_welcome }}?nonce=' + pseudo_rand + '#';
 		{% endif %}

From e8ffcde7d8fcedff85c50ccf1c3ed297601e9144 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Thu, 3 Aug 2023 17:06:50 +0200
Subject: [PATCH 26/46] update readme

---
 README.md | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/README.md b/README.md
index b769290..0c563a0 100644
--- a/README.md
+++ b/README.md
@@ -105,6 +105,40 @@ The handler should "listen" to the topic `"restart galaxy"`.
 
 [gravity]: https://github.com/galaxyproject/gravity
 
+From release 22.01 Galaxy can serve different static content per host (e.g. subdomain) and you can set [themes][themes] per host.
+By setting `galaxy_manage_static: yes` you enable the creation of static directories and configuration per host and by setting `galaxy_manage_themes: yes` the role will append your themes_config.yml file specified under `galaxy_themes_conf_path` to your themes files after coping them over to your galaxy server and create the respective configuration.
+In order to use this features, you need to create the following directory structure under files/ (cusomizable with the `galaxy_themes_ansible_ansible_file_path` variable):
+~~~bash
+files/galaxy/static
+├──<subdomain-name-1>
+│   ├── static
+│   │   ├── dist (optional)
+│   │   │   └── some-image.png 
+│   │   ├── images (optional)
+│   │   │   └── more-content.jpg
+│   │   └── welcome.html
+│   └── themes 
+│       └── <subdomain-name-1>.yml           
+├── <subdomain-name-2>                            
+│   ├── static
+│   │   ├── dist (optional)
+│   │   │   ├── another-static-image.svg
+│   │   │   └── more-static-content-2.svg
+│   │   └── welcome.html
+│   └── themes
+│       └── <subdomain-name-1>.yml
+... (and many more subdomains)
+~~~
+Were the <subdomain-name-1> should exactly match your subdomain's name. The subdirectories `static` and `themes` are mandatory, as well as the correctly named theme file (if you enabled `galaxy_manage_themes`), while all subdirectories in `static` are optional.  
+Which subdirectories and files are copied is managed by the `static_galaxy_themes_keys` variable.
+
+Also make sure that you set `galaxy_themes_welcome_url_prefix`, so your welcome pages are templated correctly.
+
+It is mandatory to set the variables under `galaxy_themes_subdomains` as shown in the example in [defaults/main.yml](defaults/main.yml). If you enabled the `galaxy_manage_host_filters` variable, you can also specify the tool sections that should be shown for each individual subdomain.
+
+
+
+[themes]: https://training.galaxyproject.org/training-material/topics/admin/tutorials/customization/tutorial.html
 **New options for Galaxy 18.01 and later**
 
 - `galaxy_config_style` (default: `yaml`): The type of Galaxy configuration file to write, `yaml` for the YAML format supported by uWSGI or `ini-paste` for the traditional PasteDeploy-style INI file
@@ -503,3 +537,4 @@ This role was written and contributed to by the following people:
 - [John Chilton](https://github.com/jmchilton)
 - [Nate Coraor](https://github.com/natefoo)
 - [Helena Rasche](https://github.com/hexylena)
+- [Mira Kuntz](https://github.com/mira-miracoli)
\ No newline at end of file

From b1406d14248a06ba8b9fdcb3986e7ce79d5d35a3 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Fri, 4 Aug 2023 10:51:42 +0200
Subject: [PATCH 27/46] use empty list if empty

---
 tasks/main.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tasks/main.yml b/tasks/main.yml
index 2128858..fc90095 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -163,7 +163,7 @@
 
 - name: Include Copy static files
   ansible.builtin.include_tasks: setup_static_dirs.yml
-  loop: "{{ galaxy_themes_subdomains }}"
+  loop: "{{ galaxy_themes_subdomains if galaxy_themes_subdomains|length else [] }}"
   loop_control:
     loop_var: subdomain
   when: galaxy_manage_static

From 1975185d02b75d161353107546dec2fc9e5a9143 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Fri, 4 Aug 2023 11:00:43 +0200
Subject: [PATCH 28/46] refine logic

---
 tasks/main.yml | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/tasks/main.yml b/tasks/main.yml
index fc90095..e005ca5 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -163,7 +163,9 @@
 
 - name: Include Copy static files
   ansible.builtin.include_tasks: setup_static_dirs.yml
-  loop: "{{ galaxy_themes_subdomains if galaxy_themes_subdomains|length else [] }}"
+  # fail only if enabled but dictionary is empty
+  loop: "{{ galaxy_themes_subdomains if galaxy_themes_subdomains|length or \
+    galaxy_manage_static else [] }}"
   loop_control:
     loop_var: subdomain
   when: galaxy_manage_static
@@ -172,7 +174,9 @@
 
 - name: Include Copy themes files
   ansible.builtin.include_tasks: themes.yml
-  loop: "{{ galaxy_themes_subdomains }}"
+  # fail only if enabled but dictionary is empty
+  loop: "{{ galaxy_themes_subdomains if galaxy_themes_subdomains|length or \
+    galaxy_manage_themes else [] }}"
   loop_control:
     loop_var: subdomain
   when: galaxy_manage_themes

From dda40f214840fd677734bb3091f405d4b5627349 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Tue, 17 Oct 2023 11:55:09 +0200
Subject: [PATCH 29/46] use copy module

---
 tasks/setup_static_dirs.yml | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/tasks/setup_static_dirs.yml b/tasks/setup_static_dirs.yml
index 303dd45..16748ca 100644
--- a/tasks/setup_static_dirs.yml
+++ b/tasks/setup_static_dirs.yml
@@ -8,8 +8,13 @@
     path: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}"
 
 - name: Move all contents from static to parent directory
-  ansible.builtin.command: cp -r {{ galaxy_themes_static_dir }}/. {{ galaxy_themes_static_path }}/static-{{ \
-   subdomain.name }}
+  ansible.builtin.copy: 
+    src: "{{ galaxy_themes_static_dir }}"
+    dest: "{{ galaxy_themes_static_path }}/static-{{ \
+      subdomain.name }}"
+    owner: "{{ __galaxy_privsep_user_name }}"
+    group: "{{ __galaxy_privsep_user_group }}"
+    directory_mode: true
   changed_when: false
 
 - name: Remove static dirs

From d5d94b1a79b033b89ee368f3a568389decf33d7b Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Tue, 17 Oct 2023 12:31:05 +0200
Subject: [PATCH 30/46] rename static

---
 defaults/main.yml | 16 ++++++++--------
 tasks/main.yml    |  8 ++++----
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/defaults/main.yml b/defaults/main.yml
index fa480c1..da1d0bb 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -24,7 +24,7 @@ galaxy_manage_systemd: no # For Galaxy
 galaxy_manage_systemd_reports: no # For Reports
 galaxy_manage_cleanup: no
 galaxy_manage_themes: no
-galaxy_manage_static: no
+galaxy_manage_subdomain_static: no
 galaxy_manage_host_filters: no
 
 
@@ -299,39 +299,39 @@ galaxy_app_config_default:
   visualization_plugins_directory: "config/plugins/visualizations"
 
   # Static and themes configuration, will only be added if galaxy_manage_themes
-  enable_static: "{{ galaxy_manage_static }}"
+  enable_static: "{{ galaxy_manage_subdomain_static }}"
   static_dir_by_host: >
-    { {% if galaxy_manage_static %}
+    { {% if galaxy_manage_subdomain_static %}
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/'
     {% endfor %}
     {% endif %} }
   static_images_dir_by_host: >
-    { {% if galaxy_manage_static %}
+    { {% if galaxy_manage_subdomain_static %}
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/images'
     {% endfor %}
     {% endif %} }
   static_welcome_html_by_host: >
-    { {% if galaxy_manage_static %}
+    { {% if galaxy_manage_subdomain_static %}
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/welcome.html'
     {% endfor %}
     {% endif %} }
   static_scripts_dir_by_host: >
-    { {% if galaxy_manage_static %}
+    { {% if galaxy_manage_subdomain_static %}
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/scripts'
     {% endfor %}
     {% endif %} }
   static_favicon_dir_by_host: >
-    { {% if galaxy_manage_static %}
+    { {% if galaxy_manage_subdomain_static %}
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/favicon.ico'
     {% endfor %}
     {% endif %} }
   static_robots_txt_by_host: >
-    { {% if galaxy_manage_static %}
+    { {% if galaxy_manage_subdomain_static %}
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/robots.txt'
     {% endfor %}
diff --git a/tasks/main.yml b/tasks/main.yml
index e005ca5..b80e897 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -161,18 +161,18 @@
   tags:
     - galaxy_manage_cleanup
 
-- name: Include Copy static files
+- name: Include create subdomain static dirs and copy static files
   ansible.builtin.include_tasks: setup_static_dirs.yml
   # fail only if enabled but dictionary is empty
   loop: "{{ galaxy_themes_subdomains if galaxy_themes_subdomains|length or \
     galaxy_manage_static else [] }}"
   loop_control:
     loop_var: subdomain
-  when: galaxy_manage_static
+  when: galaxy_manage_subdomain_static
   tags:
-    - galaxy_manage_static
+    - galaxy_manage_subdomain_static
 
-- name: Include Copy themes files
+- name: Include copy themes files
   ansible.builtin.include_tasks: themes.yml
   # fail only if enabled but dictionary is empty
   loop: "{{ galaxy_themes_subdomains if galaxy_themes_subdomains|length or \

From d9e9b712354c774b1a5d607f8c96d4e6a6fcbaf1 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Tue, 21 Nov 2023 16:28:34 +0100
Subject: [PATCH 31/46] fix config and copy

---
 README.md                   | 12 ++++++++----
 defaults/main.yml           | 18 +++++++++---------
 tasks/copy_static_files.yml | 21 ++++++++++++++++++++-
 tasks/main.yml              | 12 ++++++++++++
 tasks/setup_static_dirs.yml | 29 ++++++++++++-----------------
 5 files changed, 61 insertions(+), 31 deletions(-)

diff --git a/README.md b/README.md
index 0c563a0..3fb0068 100644
--- a/README.md
+++ b/README.md
@@ -106,8 +106,11 @@ The handler should "listen" to the topic `"restart galaxy"`.
 [gravity]: https://github.com/galaxyproject/gravity
 
 From release 22.01 Galaxy can serve different static content per host (e.g. subdomain) and you can set [themes][themes] per host.
-By setting `galaxy_manage_static: yes` you enable the creation of static directories and configuration per host and by setting `galaxy_manage_themes: yes` the role will append your themes_config.yml file specified under `galaxy_themes_conf_path` to your themes files after coping them over to your galaxy server and create the respective configuration.
-In order to use this features, you need to create the following directory structure under files/ (cusomizable with the `galaxy_themes_ansible_ansible_file_path` variable):
+
+By setting `galaxy_manage_subdomain_static: yes` you enable the creation of static directories and configuration per host and by setting `galaxy_manage_themes: yes` the role will append your themes_config.yml file specified under `galaxy_themes_conf_path` to your themes files after coping them over to your galaxy server and create the respective configuration.
+
+In order to use this feature, you need to create the following directory structure under files/ (customizable with the `galaxy_themes_ansible_file_path` variable):
+
 ~~~bash
 files/galaxy/static
 ├──<subdomain-name-1>
@@ -126,10 +129,11 @@ files/galaxy/static
 │   │   │   └── more-static-content-2.svg
 │   │   └── welcome.html
 │   └── themes
-│       └── <subdomain-name-1>.yml
+│       └── <subdomain-name-2>.yml
 ... (and many more subdomains)
 ~~~
-Were the <subdomain-name-1> should exactly match your subdomain's name. The subdirectories `static` and `themes` are mandatory, as well as the correctly named theme file (if you enabled `galaxy_manage_themes`), while all subdirectories in `static` are optional.  
+
+Where the <subdomain-name-1> should exactly match your subdomain's name. The subdirectories `static` and `themes` are mandatory, as well as the correctly named theme file (if you enabled `galaxy_manage_themes`), while all subdirectories in `static` are optional.  
 Which subdirectories and files are copied is managed by the `static_galaxy_themes_keys` variable.
 
 Also make sure that you set `galaxy_themes_welcome_url_prefix`, so your welcome pages are templated correctly.
diff --git a/defaults/main.yml b/defaults/main.yml
index da1d0bb..385f770 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -299,47 +299,47 @@ galaxy_app_config_default:
   visualization_plugins_directory: "config/plugins/visualizations"
 
   # Static and themes configuration, will only be added if galaxy_manage_themes
-  enable_static: "{{ galaxy_manage_subdomain_static }}"
+  static_enabled: "{{ galaxy_manage_subdomain_static }}"
   static_dir_by_host: >
     { {% if galaxy_manage_subdomain_static %}
     {% for subdomain in galaxy_themes_subdomains %}
-    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/'
+    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/',
     {% endfor %}
     {% endif %} }
   static_images_dir_by_host: >
     { {% if galaxy_manage_subdomain_static %}
     {% for subdomain in galaxy_themes_subdomains %}
-    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/images'
+    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/images',
     {% endfor %}
     {% endif %} }
   static_welcome_html_by_host: >
     { {% if galaxy_manage_subdomain_static %}
     {% for subdomain in galaxy_themes_subdomains %}
-    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/welcome.html'
+    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/welcome.html',
     {% endfor %}
     {% endif %} }
   static_scripts_dir_by_host: >
     { {% if galaxy_manage_subdomain_static %}
     {% for subdomain in galaxy_themes_subdomains %}
-    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/scripts'
+    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/scripts',
     {% endfor %}
     {% endif %} }
   static_favicon_dir_by_host: >
     { {% if galaxy_manage_subdomain_static %}
     {% for subdomain in galaxy_themes_subdomains %}
-    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/favicon.ico'
+    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}',
     {% endfor %}
     {% endif %} }
   static_robots_txt_by_host: >
     { {% if galaxy_manage_subdomain_static %}
     {% for subdomain in galaxy_themes_subdomains %}
-    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/robots.txt'
+    '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}',
     {% endfor %}
     {% endif %} }
-  themes_dir_by_host: >
+  themes_config_file_by_host: >
     { {% if galaxy_manage_themes %}
     {% for subdomain in galaxy_themes_subdomains %}
-    '{{ subdomain.name  }}.{{ galaxy_themes_instance_domain}}': {{ subdomain.name }}.yml
+    '{{ subdomain.name  }}.{{ galaxy_themes_instance_domain}}': '{{ subdomain.name }}.yml',
     {% endfor %}
     {% endif %} }
 # Need to set galaxy_config_default[galaxy_app_config_section] dynamically but Ansible/Jinja2 does not make this easy
diff --git a/tasks/copy_static_files.yml b/tasks/copy_static_files.yml
index a765719..0ccc9a4 100644
--- a/tasks/copy_static_files.yml
+++ b/tasks/copy_static_files.yml
@@ -1,5 +1,5 @@
 ---
-- name: Copy static files
+- name: Copy subdomain static files
   ansible.builtin.copy:
     src: "{{ item }}"
     dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/{{ object.value }}"
@@ -16,3 +16,22 @@
     owner: "{{ __galaxy_privsep_user_name }}"
     group: "{{ __galaxy_privsep_user_group }}"
   with_fileglob: "{{ galaxy_themes_ansible_file_path }}/{{ subdomain.name }}/static/dist/*"
+
+- name: Copy files from dist
+  ansible.builtin.copy:
+    src: "{{ item }}"
+    dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/dist/"
+    mode: '0644'
+    owner: "{{ __galaxy_privsep_user_name }}"
+    group: "{{ __galaxy_privsep_user_group }}"
+  with_fileglob: "{{ galaxy_themes_ansible_file_path }}/{{ subdomain.name }}/static/dist/*"
+
+- name: Copy custom welcome.html
+  ansible.builtin.copy:
+    src: "{{ item }}"
+    dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/welcome.html/index.html"
+    mode: '0644'
+    owner: "{{ __galaxy_privsep_user_name }}"
+    group: "{{ __galaxy_privsep_user_group }}"
+  with_fileglob: "{{ galaxy_themes_ansible_file_path }}/{{ subdomain.name }}/static/welcome.html"
+  when: custom_welcome.stat.exists
diff --git a/tasks/main.yml b/tasks/main.yml
index b80e897..bc95b99 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -161,6 +161,12 @@
   tags:
     - galaxy_manage_cleanup
 
+- name: Zip static directory
+  community.general.archive:
+    path: "{{ galaxy_themes_static_path }}/static/"
+    dest: "{{ galaxy_themes_static_path }}/static.gz"
+  when: galaxy_manage_subdomain_static
+
 - name: Include create subdomain static dirs and copy static files
   ansible.builtin.include_tasks: setup_static_dirs.yml
   # fail only if enabled but dictionary is empty
@@ -172,6 +178,12 @@
   tags:
     - galaxy_manage_subdomain_static
 
+- name: Remove static archive
+  ansible.builtin.file:
+    path: "{{ galaxy_themes_static_path }}/static.gz"
+    state: absent
+  when: galaxy_manage_subdomain_static
+
 - name: Include copy themes files
   ansible.builtin.include_tasks: themes.yml
   # fail only if enabled but dictionary is empty
diff --git a/tasks/setup_static_dirs.yml b/tasks/setup_static_dirs.yml
index 16748ca..a791da9 100644
--- a/tasks/setup_static_dirs.yml
+++ b/tasks/setup_static_dirs.yml
@@ -1,5 +1,5 @@
 ---
-- name: Create static dirs
+- name: Create subdomain static dirs
   ansible.builtin.file:
     state: directory
     mode: '0755'
@@ -7,23 +7,16 @@
     group: "{{ __galaxy_privsep_user_group }}"
     path: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}"
 
-- name: Move all contents from static to parent directory
-  ansible.builtin.copy: 
-    src: "{{ galaxy_themes_static_dir }}"
-    dest: "{{ galaxy_themes_static_path }}/static-{{ \
-      subdomain.name }}"
-    owner: "{{ __galaxy_privsep_user_name }}"
-    group: "{{ __galaxy_privsep_user_group }}"
-    directory_mode: true
-  changed_when: false
+- name: Add generic static files to subdomain static dir
+  ansible.builtin.unarchive:
+    src: "{{ galaxy_themes_static_path }}/static.gz"
+    dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}"
+    remote_src: yes
 
-- name: Remove static dirs
-  ansible.builtin.file:
-    state: absent
-    mode: '0755'
-    owner: "{{ __galaxy_privsep_user_name }}"
-    group: "{{ __galaxy_privsep_user_group }}"
-    path: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/static"
+- name: Check if welcome.html is present in files
+  ansible.builtin.stat:
+    path: "{{ galaxy_themes_ansible_file_path }}/{{ subdomain.name }}/static/welcome.html"
+  register: custom_welcome
 
 - name: Create welcome.html directory
   ansible.builtin.file:
@@ -39,6 +32,7 @@
     return_content: true
   register: iframe
   failed_when: false
+  when: not custom_welcome.stat.exists
 
 - name: Template welcome.html for subdomains
   ansible.builtin.template:
@@ -47,6 +41,7 @@
     owner: "{{ __galaxy_privsep_user_name }}"
     group: "{{ __galaxy_privsep_user_group }}"
     mode: '0644'
+  when: not custom_welcome.stat.exists
 
 - name: Copy static files
   ansible.builtin.include_tasks: copy_static_files.yml

From 06e3b246dbc310f87b383ce472a14aa812db235a Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Wed, 22 Nov 2023 12:52:39 +0100
Subject: [PATCH 32/46] make themes idempotent

---
 tasks/themes.yml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tasks/themes.yml b/tasks/themes.yml
index 85eee2d..311d201 100644
--- a/tasks/themes.yml
+++ b/tasks/themes.yml
@@ -1,4 +1,8 @@
 ---
+- name: Append themes_conf.yml to all files in galaxy/config/themes
+  ansible.builtin.blockinfile:
+    block: "{{ lookup('ansible.builtin.file', galaxy_themes_conf_path) }}"
+    path: "{{ galaxy_themes_ansible_file_path }}/{{ subdomain.name }}/themes/{{ subdomain.name }}.yml"
 
 - name: Copy themes files
   ansible.builtin.copy:
@@ -8,7 +12,3 @@
     owner: "{{ __galaxy_privsep_user_name }}"
     group: "{{ __galaxy_privsep_user_group }}"
 
-- name: Append themes_conf.yml to all files in galaxy/config/themes
-  ansible.builtin.blockinfile:
-    block: "{{ lookup('ansible.builtin.file', galaxy_themes_conf_path) }}"
-    path: "{{ galaxy_config_dir }}/{{ subdomain.name }}.yml"

From d9ebb23d2a932a3285785dc0fbe55de3f1d621ed Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Wed, 22 Nov 2023 12:53:05 +0100
Subject: [PATCH 33/46] use rsync

---
 tasks/main.yml              | 20 ++++++++++----------
 tasks/setup_static_dirs.yml | 11 ++++++-----
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/tasks/main.yml b/tasks/main.yml
index bc95b99..483dab5 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -161,11 +161,11 @@
   tags:
     - galaxy_manage_cleanup
 
-- name: Zip static directory
-  community.general.archive:
-    path: "{{ galaxy_themes_static_path }}/static/"
-    dest: "{{ galaxy_themes_static_path }}/static.gz"
-  when: galaxy_manage_subdomain_static
+#- name: Zip static directory
+#  community.general.archive:
+#    path: "{{ galaxy_themes_static_path }}/static/"
+#    dest: "{{ galaxy_themes_static_path }}/static.gz"
+#  when: galaxy_manage_subdomain_static
 
 - name: Include create subdomain static dirs and copy static files
   ansible.builtin.include_tasks: setup_static_dirs.yml
@@ -178,11 +178,11 @@
   tags:
     - galaxy_manage_subdomain_static
 
-- name: Remove static archive
-  ansible.builtin.file:
-    path: "{{ galaxy_themes_static_path }}/static.gz"
-    state: absent
-  when: galaxy_manage_subdomain_static
+#- name: Remove static archive
+#  ansible.builtin.file:
+#    path: "{{ galaxy_themes_static_path }}/static.gz"
+#    state: absent
+#  when: galaxy_manage_subdomain_static
 
 - name: Include copy themes files
   ansible.builtin.include_tasks: themes.yml
diff --git a/tasks/setup_static_dirs.yml b/tasks/setup_static_dirs.yml
index a791da9..7ff99f9 100644
--- a/tasks/setup_static_dirs.yml
+++ b/tasks/setup_static_dirs.yml
@@ -7,11 +7,12 @@
     group: "{{ __galaxy_privsep_user_group }}"
     path: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}"
 
-- name: Add generic static files to subdomain static dir
-  ansible.builtin.unarchive:
-    src: "{{ galaxy_themes_static_path }}/static.gz"
+- name: Synchronize contents from static to static-"{{ subdomain.name }}"
+  ansible.posix.synchronize:
+    src: "{{ galaxy_themes_static_path }}/static/"
     dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}"
-    remote_src: yes
+    rsync_opts: ["--ignore-existing"]
+  delegate_to: "{{ inventory_hostname }}"
 
 - name: Check if welcome.html is present in files
   ansible.builtin.stat:
@@ -43,7 +44,7 @@
     mode: '0644'
   when: not custom_welcome.stat.exists
 
-- name: Copy static files
+- name: Include copy_static_files.yml
   ansible.builtin.include_tasks: copy_static_files.yml
   loop: "{{ galaxy_themes_static_keys | dict2items }}"
   loop_control:

From f1222a6d4cd9fbf598598fed4846d2a2b1cb7a65 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Wed, 22 Nov 2023 16:24:32 +0100
Subject: [PATCH 34/46] changes for basedomain

---
 defaults/main.yml | 14 ++++++++++++++
 tasks/main.yml    | 22 +++++++++++++++++-----
 2 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/defaults/main.yml b/defaults/main.yml
index 385f770..1489c48 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -26,6 +26,7 @@ galaxy_manage_cleanup: no
 galaxy_manage_themes: no
 galaxy_manage_subdomain_static: no
 galaxy_manage_host_filters: no
+galaxy_auto_brand: no # automatically sets the subdomain name as brand
 
 
 # Control whether to output verbose task diffs (e.g. when performing a git update) when running Ansible with --diff.
@@ -302,36 +303,42 @@ galaxy_app_config_default:
   static_enabled: "{{ galaxy_manage_subdomain_static }}"
   static_dir_by_host: >
     { {% if galaxy_manage_subdomain_static %}
+    '{{ galaxy_themes_instance_domain }}': '{{ galaxy_themes_static_path }}/static/',
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/',
     {% endfor %}
     {% endif %} }
   static_images_dir_by_host: >
     { {% if galaxy_manage_subdomain_static %}
+    '{{ galaxy_themes_instance_domain }}': '{{ galaxy_themes_static_path }}/static/images',
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/images',
     {% endfor %}
     {% endif %} }
   static_welcome_html_by_host: >
     { {% if galaxy_manage_subdomain_static %}
+    '{{ galaxy_themes_instance_domain }}': '{{ galaxy_themes_static_path }}/static/welcome.html',
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/welcome.html',
     {% endfor %}
     {% endif %} }
   static_scripts_dir_by_host: >
     { {% if galaxy_manage_subdomain_static %}
+    '{{ galaxy_themes_instance_domain }}': '{{ galaxy_themes_static_path }}/static/scripts',
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/scripts',
     {% endfor %}
     {% endif %} }
   static_favicon_dir_by_host: >
     { {% if galaxy_manage_subdomain_static %}
+    '{{ galaxy_themes_instance_domain }}': '{{ galaxy_themes_static_path }}/static',
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}',
     {% endfor %}
     {% endif %} }
   static_robots_txt_by_host: >
     { {% if galaxy_manage_subdomain_static %}
+    '{{ galaxy_themes_instance_domain }}': '{{ galaxy_themes_static_path }}/static',
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name }}.{{ galaxy_themes_instance_domain}}': '{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}',
     {% endfor %}
@@ -342,6 +349,13 @@ galaxy_app_config_default:
     '{{ subdomain.name  }}.{{ galaxy_themes_instance_domain}}': '{{ subdomain.name }}.yml',
     {% endfor %}
     {% endif %} }
+  brand_by_host: >
+    { {% if galaxy_auto_brand %}
+    '{{ galaxy_themes_instance_domain }}': '{{ galaxy_themes_instance_domain }}',
+    {% for subdomain in galaxy_themes_subdomains %}
+    '{{ subdomain.name  }}.{{ galaxy_themes_instance_domain}}': '{{ subdomain.name[0]|upper }}{{ subdomain.name[1:] }}',
+    {% endfor %}
+    {% endif %} }
 # Need to set galaxy_config_default[galaxy_app_config_section] dynamically but Ansible/Jinja2 does not make this easy
 galaxy_config_default: "{{ {} | combine({galaxy_app_config_section: galaxy_app_config_default}) }}"
 galaxy_config_merged: "{{ galaxy_config_default | combine(galaxy_config | default({}), recursive=True) }}"
diff --git a/tasks/main.yml b/tasks/main.yml
index 483dab5..f6ca273 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -161,11 +161,23 @@
   tags:
     - galaxy_manage_cleanup
 
-#- name: Zip static directory
-#  community.general.archive:
-#    path: "{{ galaxy_themes_static_path }}/static/"
-#    dest: "{{ galaxy_themes_static_path }}/static.gz"
-#  when: galaxy_manage_subdomain_static
+- name: Create welcome.html directory for basedomain
+  ansible.builtin.file:
+    state: directory
+    mode: '0755'
+    owner: "{{ __galaxy_privsep_user_name }}"
+    group: "{{ __galaxy_privsep_user_group }}"
+    path: "{{ galaxy_themes_static_path }}/static/welcome.html"
+  when: galaxy_manage_subdomain_static
+
+- name: Template welcome.html for basedomain
+  ansible.builtin.template:
+    src: welcome.html.j2
+    dest: "{{ galaxy_themes_static_path }}/static/welcome.html/index.html"
+    owner: "{{ __galaxy_privsep_user_name }}"
+    group: "{{ __galaxy_privsep_user_group }}"
+    mode: '0644'
+  when: galaxy_manage_subdomain_static
 
 - name: Include create subdomain static dirs and copy static files
   ansible.builtin.include_tasks: setup_static_dirs.yml

From 4254bd8183734b1074e2ab5efc0e039a05dc9e27 Mon Sep 17 00:00:00 2001
From: Mira <86979912+mira-miracoli@users.noreply.github.com>
Date: Thu, 23 Nov 2023 10:00:07 +0100
Subject: [PATCH 35/46] Update tasks/setup_static_dirs.yml

Co-authored-by: Helena <hexylena@galaxians.org>
---
 tasks/setup_static_dirs.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tasks/setup_static_dirs.yml b/tasks/setup_static_dirs.yml
index 7ff99f9..3a305d2 100644
--- a/tasks/setup_static_dirs.yml
+++ b/tasks/setup_static_dirs.yml
@@ -31,7 +31,7 @@
   ansible.builtin.uri:
     url: "{{ galaxy_themes_welcome_url_prefix }}{{ subdomain.name }}.html"
     return_content: true
-  register: iframe
+  register: galaxy_themes_use_iframe
   failed_when: false
   when: not custom_welcome.stat.exists
 

From 54a4c3a75fbc3e607e2b8da8b4ea6a16aba8ccab Mon Sep 17 00:00:00 2001
From: Mira <86979912+mira-miracoli@users.noreply.github.com>
Date: Thu, 23 Nov 2023 10:00:18 +0100
Subject: [PATCH 36/46] Update templates/welcome.html.j2

Co-authored-by: Helena <hexylena@galaxians.org>
---
 templates/welcome.html.j2 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/welcome.html.j2 b/templates/welcome.html.j2
index 79ded41..0aa2a79 100644
--- a/templates/welcome.html.j2
+++ b/templates/welcome.html.j2
@@ -28,7 +28,7 @@
 		onload="this.style.position='static'; this.style.visibility='visible';"></iframe>
 	<script type="text/javascript">
 		var pseudo_rand = parseInt(Date.now() / 1000 / 60 / 10);
-		{% if iframe is defined %}
+		{% if galaxy_themes_use_iframe is defined %}
 		document.getElementById('center-iframe').src = '{{ galaxy_themes_welcome_url_prefix }}{{ subdomain.name }}?nonce=' + pseudo_rand + '#';
 		{% else %}
 		document.getElementById('center-iframe').src = '{{ galaxy_themes_default_welcome }}?nonce=' + pseudo_rand + '#';

From e3db5c29e3bf6983c70746984f0b51a310596b15 Mon Sep 17 00:00:00 2001
From: Mira <86979912+mira-miracoli@users.noreply.github.com>
Date: Thu, 23 Nov 2023 10:02:00 +0100
Subject: [PATCH 37/46] Update README.md

Co-authored-by: Helena <hexylena@galaxians.org>
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 3fb0068..76f18e3 100644
--- a/README.md
+++ b/README.md
@@ -119,7 +119,7 @@ files/galaxy/static
 │   │   │   └── some-image.png 
 │   │   ├── images (optional)
 │   │   │   └── more-content.jpg
-│   │   └── welcome.html
+│   │   └── welcome.html (optional, galaxyproject.org will be displayed otherwise.)
 │   └── themes 
 │       └── <subdomain-name-1>.yml           
 ├── <subdomain-name-2>                            

From a7c843f2dd89b658c99edc8afe98dc78915061ce Mon Sep 17 00:00:00 2001
From: Mira <86979912+mira-miracoli@users.noreply.github.com>
Date: Thu, 23 Nov 2023 10:02:28 +0100
Subject: [PATCH 38/46] Update README.md

Co-authored-by: Helena <hexylena@galaxians.org>
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 76f18e3..0a86bd3 100644
--- a/README.md
+++ b/README.md
@@ -127,7 +127,7 @@ files/galaxy/static
 │   │   ├── dist (optional)
 │   │   │   ├── another-static-image.svg
 │   │   │   └── more-static-content-2.svg
-│   │   └── welcome.html
+│   │   └── welcome.html (optional)
 │   └── themes
 │       └── <subdomain-name-2>.yml
 ... (and many more subdomains)

From 4cff5447e0de1b7c60c06e692fe542e651ee26c5 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Thu, 23 Nov 2023 14:33:43 +0100
Subject: [PATCH 39/46] move to separate file

---
 tasks/main.yml                                | 33 ++-----------------
 tasks/static_dirs.yml                         | 23 +++++++++++++
 ...tic_dirs.yml => static_subdomain_dirs.yml} |  0
 3 files changed, 25 insertions(+), 31 deletions(-)
 create mode 100644 tasks/static_dirs.yml
 rename tasks/{setup_static_dirs.yml => static_subdomain_dirs.yml} (100%)

diff --git a/tasks/main.yml b/tasks/main.yml
index f6ca273..0795ca5 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -161,41 +161,12 @@
   tags:
     - galaxy_manage_cleanup
 
-- name: Create welcome.html directory for basedomain
-  ansible.builtin.file:
-    state: directory
-    mode: '0755'
-    owner: "{{ __galaxy_privsep_user_name }}"
-    group: "{{ __galaxy_privsep_user_group }}"
-    path: "{{ galaxy_themes_static_path }}/static/welcome.html"
-  when: galaxy_manage_subdomain_static
-
-- name: Template welcome.html for basedomain
-  ansible.builtin.template:
-    src: welcome.html.j2
-    dest: "{{ galaxy_themes_static_path }}/static/welcome.html/index.html"
-    owner: "{{ __galaxy_privsep_user_name }}"
-    group: "{{ __galaxy_privsep_user_group }}"
-    mode: '0644'
-  when: galaxy_manage_subdomain_static
-
-- name: Include create subdomain static dirs and copy static files
-  ansible.builtin.include_tasks: setup_static_dirs.yml
-  # fail only if enabled but dictionary is empty
-  loop: "{{ galaxy_themes_subdomains if galaxy_themes_subdomains|length or \
-    galaxy_manage_static else [] }}"
-  loop_control:
-    loop_var: subdomain
+- name: Inlcude static directory setup
+  ansible.builtin.include_tasks: static_dirs.yml
   when: galaxy_manage_subdomain_static
   tags:
     - galaxy_manage_subdomain_static
 
-#- name: Remove static archive
-#  ansible.builtin.file:
-#    path: "{{ galaxy_themes_static_path }}/static.gz"
-#    state: absent
-#  when: galaxy_manage_subdomain_static
-
 - name: Include copy themes files
   ansible.builtin.include_tasks: themes.yml
   # fail only if enabled but dictionary is empty
diff --git a/tasks/static_dirs.yml b/tasks/static_dirs.yml
new file mode 100644
index 0000000..c59ab2c
--- /dev/null
+++ b/tasks/static_dirs.yml
@@ -0,0 +1,23 @@
+---
+- name: Create welcome.html directory for basedomain
+  ansible.builtin.file:
+    state: directory
+    mode: '0755'
+    owner: "{{ __galaxy_privsep_user_name }}"
+    group: "{{ __galaxy_privsep_user_group }}"
+    path: "{{ galaxy_themes_static_path }}/static/welcome.html"
+
+- name: Template welcome.html for basedomain
+  ansible.builtin.template:
+    src: welcome.html.j2
+    dest: "{{ galaxy_themes_static_path }}/static/welcome.html/index.html"
+    owner: "{{ __galaxy_privsep_user_name }}"
+    group: "{{ __galaxy_privsep_user_group }}"
+    mode: '0644'
+
+- name: Include create subdomain static dirs and copy static files
+  ansible.builtin.include_tasks: static_subdomain_dirs.yml
+  loop: "{{ galaxy_themes_subdomains if galaxy_themes_subdomains | length or \
+    galaxy_manage_static else [] }}"
+  loop_control:
+    loop_var: subdomain
diff --git a/tasks/setup_static_dirs.yml b/tasks/static_subdomain_dirs.yml
similarity index 100%
rename from tasks/setup_static_dirs.yml
rename to tasks/static_subdomain_dirs.yml

From 474f046ddb5f0ae0999613b376706a06911833a5 Mon Sep 17 00:00:00 2001
From: Helena Rasche <hexylena@galaxians.org>
Date: Thu, 23 Nov 2023 16:01:44 +0100
Subject: [PATCH 40/46] add six

---
 .github/workflows/slugger.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/slugger.yml b/.github/workflows/slugger.yml
index 2cd7b97..c9c2371 100644
--- a/.github/workflows/slugger.yml
+++ b/.github/workflows/slugger.yml
@@ -34,7 +34,7 @@ jobs:
           python-version: '3.x'
 
       - name: Install Ansible.
-        run: pip3 install ansible-base
+        run: pip3 install six ansible-base
 
       - name: Check for changes
         run: |

From d1ccc2ec92ad2e0800c9ac172c54a615f37e1f71 Mon Sep 17 00:00:00 2001
From: Mira <86979912+mira-miracoli@users.noreply.github.com>
Date: Mon, 27 Nov 2023 15:50:58 +0100
Subject: [PATCH 41/46] on localhost

---
 tasks/themes.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tasks/themes.yml b/tasks/themes.yml
index 311d201..458c9a1 100644
--- a/tasks/themes.yml
+++ b/tasks/themes.yml
@@ -3,6 +3,7 @@
   ansible.builtin.blockinfile:
     block: "{{ lookup('ansible.builtin.file', galaxy_themes_conf_path) }}"
     path: "{{ galaxy_themes_ansible_file_path }}/{{ subdomain.name }}/themes/{{ subdomain.name }}.yml"
+  delegate_to: 127.0.0.1
 
 - name: Copy themes files
   ansible.builtin.copy:

From 822d0942981dd9b9e04dcf58838a514d1b3687e4 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Tue, 28 Nov 2023 10:20:33 +0100
Subject: [PATCH 42/46] add basedomain theme

---
 defaults/main.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/defaults/main.yml b/defaults/main.yml
index 1489c48..45a09cc 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -345,6 +345,7 @@ galaxy_app_config_default:
     {% endif %} }
   themes_config_file_by_host: >
     { {% if galaxy_manage_themes %}
+    '{{ galaxy_themes_instance_domain }}': '{{ galaxy_themes_conf_path | basename }}',
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name  }}.{{ galaxy_themes_instance_domain}}': '{{ subdomain.name }}.yml',
     {% endfor %}

From 97df59c2c9bb5e3060563dba645e350088cf4894 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Tue, 28 Nov 2023 10:24:27 +0100
Subject: [PATCH 43/46] make it a variable

---
 defaults/main.yml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/defaults/main.yml b/defaults/main.yml
index 45a09cc..2d87348 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -345,7 +345,7 @@ galaxy_app_config_default:
     {% endif %} }
   themes_config_file_by_host: >
     { {% if galaxy_manage_themes %}
-    '{{ galaxy_themes_instance_domain }}': '{{ galaxy_themes_conf_path | basename }}',
+    '{{ galaxy_themes_instance_domain }}': '{{ galaxy_themes_conf_file_name }}',
     {% for subdomain in galaxy_themes_subdomains %}
     '{{ subdomain.name  }}.{{ galaxy_themes_instance_domain}}': '{{ subdomain.name }}.yml',
     {% endfor %}
@@ -501,6 +501,7 @@ galaxy_themes_subdomains: {}
 #     - "multiple_alignments"
 #   extra_tool_labels:
 #     - "proteomics"
+galaxy_themes_conf_file_name: "{{ galaxy_themes_conf_path | basename }}"
 galaxy_themes_static_keys:
   static_dir: ""
   static_images_dir: "images/"

From da154437966f9015447ad08a676750a5d6f963d6 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Fri, 1 Dec 2023 11:17:39 +0100
Subject: [PATCH 44/46] use symlinks

---
 defaults/main.yml               |  2 ++
 tasks/static_subdomain_dirs.yml | 35 ++++++++++++++++++++++++++++++++-
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/defaults/main.yml b/defaults/main.yml
index 2d87348..9da4445 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -512,6 +512,8 @@ galaxy_themes_static_keys:
 galaxy_themes_conf_path: files/galaxy/config/themes_conf.yml
 galaxy_themes_static_path: "{{ galaxy_root }}/server"
 galaxy_themes_static_dir: "{{ galaxy_root }}/server/static"
+galaxy_themes_symlinks: true
+galaxy_themes_no_symlinks_log: false # Hides extended logs for the symlink task in static/dist
 galaxy_themes_welcome_url_prefix: https://usegalaxy-eu.github.io/index-
 galaxy_themes_default_welcome: https://galaxyproject.org
 galaxy_themes_ansible_file_path: files/galaxy/static
diff --git a/tasks/static_subdomain_dirs.yml b/tasks/static_subdomain_dirs.yml
index 3a305d2..1a0b4e9 100644
--- a/tasks/static_subdomain_dirs.yml
+++ b/tasks/static_subdomain_dirs.yml
@@ -5,7 +5,40 @@
     mode: '0755'
     owner: "{{ __galaxy_privsep_user_name }}"
     group: "{{ __galaxy_privsep_user_group }}"
-    path: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}"
+    path: "{{ galaxy_themes_static_path }}/{{ item }}"
+  with_items:
+    - "static-{{ subdomain.name }}"
+    - "static-{{ subdomain.name }}/dist"
+
+- name: Register files in static/dist
+  ansible.builtin.find:
+    paths: "{{ galaxy_themes_static_path }}/static/dist"
+    file_type: file
+  when: galaxy_themes_symlinks
+  register: dist_files
+
+- name: "Symlink files static-{{ subdomain.name }}/dist to static/dist"
+  ansible.builtin.file:
+    src: "{{ item.path }}"
+    dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/dist/{{ item.path | basename }}"
+    state: link
+  when: galaxy_themes_symlinks
+  no_log: "{{ galaxy_themes_no_symlinks_log }}"
+  with_items: "{{ dist_files.files }}"
+
+- name: "Symlink directory {{ item }} from static-{{ subdomain.name }}/{{ item }} to static/{{ item }}"
+  ansible.builtin.file:
+    src: "{{ galaxy_themes_static_path }}/static/{{ item }}"
+    dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/{{ item }}"
+    state: link
+  when: galaxy_themes_symlinks
+  ignore_errors: true
+  with_items:
+    - "plugins"
+    - "patmat"
+    - "toolshed"
+    - "wymeditor"
+    - "style"
 
 - name: Synchronize contents from static to static-"{{ subdomain.name }}"
   ansible.posix.synchronize:

From aceb4eb34c22fa9b119d54cfaca295f8f7236e55 Mon Sep 17 00:00:00 2001
From: Mira Kuntz <mira.kuntz@yahoo.com>
Date: Fri, 1 Dec 2023 11:32:03 +0100
Subject: [PATCH 45/46] rename

---
 defaults/main.yml               | 2 +-
 tasks/static_subdomain_dirs.yml | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/defaults/main.yml b/defaults/main.yml
index 9da4445..2a97c12 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -513,7 +513,7 @@ galaxy_themes_conf_path: files/galaxy/config/themes_conf.yml
 galaxy_themes_static_path: "{{ galaxy_root }}/server"
 galaxy_themes_static_dir: "{{ galaxy_root }}/server/static"
 galaxy_themes_symlinks: true
-galaxy_themes_no_symlinks_log: false # Hides extended logs for the symlink task in static/dist
+galaxy_themes_symlinks_no_log: false # Hides extended logs for the symlink task in static/dist
 galaxy_themes_welcome_url_prefix: https://usegalaxy-eu.github.io/index-
 galaxy_themes_default_welcome: https://galaxyproject.org
 galaxy_themes_ansible_file_path: files/galaxy/static
diff --git a/tasks/static_subdomain_dirs.yml b/tasks/static_subdomain_dirs.yml
index 1a0b4e9..c6b3831 100644
--- a/tasks/static_subdomain_dirs.yml
+++ b/tasks/static_subdomain_dirs.yml
@@ -23,7 +23,7 @@
     dest: "{{ galaxy_themes_static_path }}/static-{{ subdomain.name }}/dist/{{ item.path | basename }}"
     state: link
   when: galaxy_themes_symlinks
-  no_log: "{{ galaxy_themes_no_symlinks_log }}"
+  no_log: "{{ galaxy_themes_symlinks_no_log }}"
   with_items: "{{ dist_files.files }}"
 
 - name: "Symlink directory {{ item }} from static-{{ subdomain.name }}/{{ item }} to static/{{ item }}"

From ff3ed7ca5057e8f52fb48dbd1f74361e6e449c69 Mon Sep 17 00:00:00 2001
From: Nate Coraor <nate@bx.psu.edu>
Date: Tue, 5 Dec 2023 10:10:53 -0600
Subject: [PATCH 46/46] Support forcing client builds even when the commit ID
 has not changed

---
 defaults/main.yml | 3 +++
 tasks/client.yml  | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/defaults/main.yml b/defaults/main.yml
index 2d87348..7c8cb95 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -429,6 +429,9 @@ galaxy_uwsgi_config_default:
 # build separately, but this is not guaranteed to work for all version of Galaxy - using `make` is the safer choice.
 galaxy_client_make_target: client-production-maps
 
+# Build the client even if it is not out of date
+galaxy_client_force_build: false
+
 # If galaxy_client_make_target is null, you can set this to `development` to build the client for development
 galaxy_client_node_env: production
 galaxy_client_build_steps:
diff --git a/tasks/client.yml b/tasks/client.yml
index 9677200..0b5ddd2 100644
--- a/tasks/client.yml
+++ b/tasks/client.yml
@@ -30,9 +30,9 @@
 
     - name: Set client build version fact
       set_fact:
-        __galaxy_client_build_version: "{{ __galaxy_client_build_version_result.content | b64decode | trim }}"
+        __galaxy_client_build_version: "{{ galaxy_client_force_build | ternary('FORCE-BUILD', __galaxy_client_build_version_result.content | b64decode | trim) }}"
 
-    - name: Set client build version fact
+    - name: Set galaxy commit ID fact
       set_fact:
         __galaxy_current_commit_id: "{{ __galaxy_git_stat_result.after if __galaxy_from_git.stat.exists else 'none' }}"
       when: __galaxy_from_git.stat.exists