- name: Bootstrap TransformerLab release files shell: | set -euo pipefail cd "{{ courseware_transformerlab_home }}" curl -L "https://github.com/transformerlab/transformerlab-app/archive/refs/tags/{{ courseware_transformerlab_version }}.tar.gz" -o transformerlab.tar.gz tar -xzf transformerlab.tar.gz rm -f transformerlab.tar.gz rm -rf src mv "transformerlab-app-{{ courseware_transformerlab_version_dir }}/api" src echo "{{ courseware_transformerlab_version }}" > src/LATEST_VERSION curl -L "https://github.com/transformerlab/transformerlab-app/releases/download/{{ courseware_transformerlab_version }}/transformerlab_web.tar.gz" -o transformerlab_web.tar.gz rm -rf webapp mkdir -p webapp tar -xzf transformerlab_web.tar.gz -C webapp rm -f transformerlab_web.tar.gz args: executable: /bin/bash creates: "{{ courseware_transformerlab_home }}/src/install.sh" - name: Add TransformerLab Miniforge Python path for space-safe bootstrap replace: path: "{{ courseware_transformerlab_home }}/src/install.sh" regexp: 'CONDA_BIN=\$\{MINIFORGE_ROOT\}/bin/conda\n' replace: | CONDA_BIN=${MINIFORGE_ROOT}/bin/conda CONDA_PYTHON_BIN=${MINIFORGE_ROOT}/bin/python when: "' ' in courseware_transformerlab_home" - name: Inject space-safe TransformerLab conda runner blockinfile: path: "{{ courseware_transformerlab_home }}/src/install.sh" insertbefore: '^check_conda\(\) \{$' marker: '# {mark} courseware conda runner' block: | conda_direct_exec_works() { "${CONDA_BIN}" --version >/dev/null 2>&1 } run_conda() { if conda_direct_exec_works; then "${CONDA_BIN}" "$@" else "${CONDA_PYTHON_BIN}" "${CONDA_BIN}" "$@" fi } when: "' ' in courseware_transformerlab_home" - name: Rewrite TransformerLab installer to use the space-safe conda runner replace: path: "{{ courseware_transformerlab_home }}/src/install.sh" regexp: 'eval "\$\(\$\{CONDA_BIN\} shell\.bash hook\)"' replace: 'eval "$(run_conda shell.bash hook)"' when: "' ' in courseware_transformerlab_home" - name: Rewrite TransformerLab doctor output to use the space-safe conda runner replace: path: "{{ courseware_transformerlab_home }}/src/install.sh" regexp: '\$\(\$\{CONDA_BIN\} --version\)' replace: '$(run_conda --version)' when: "' ' in courseware_transformerlab_home" - name: Install TransformerLab shell: | set -euo pipefail ./src/install.sh 2>&1 | tee "{{ courseware_logs_dir }}/transformerlab_install.log" touch "{{ courseware_transformerlab_home }}/.courseware-managed" args: executable: /bin/bash chdir: "{{ courseware_transformerlab_home }}" creates: "{{ courseware_transformerlab_home }}/miniforge3/bin/conda" - name: Rewrite TransformerLab Miniforge entrypoints to a space-safe shebang path shell: | set -euo pipefail actual_prefix="{{ courseware_transformerlab_home }}/miniforge3/bin/" safe_prefix="{{ ansible_env.HOME }}/.transformerlab/miniforge3/bin/" find "{{ courseware_transformerlab_home }}/miniforge3/bin" -maxdepth 1 -type f -print0 | while IFS= read -r -d '' file; do first_line=$(head -n 1 "$file" || true) case "$first_line" in "#!${actual_prefix}"*) suffix=${first_line#\#!} suffix=${suffix#"${actual_prefix}"} replacement="#!${safe_prefix}${suffix}" tmp_file=$(mktemp) { printf '%s\n' "$replacement" tail -n +2 "$file" } >"$tmp_file" chmod --reference="$file" "$tmp_file" mv "$tmp_file" "$file" ;; esac done args: executable: /bin/bash when: "' ' in courseware_transformerlab_home" - name: Install TransformerLab multiuser dependencies shell: | set -euo pipefail ./src/install.sh multiuser_setup 2>&1 | tee "{{ courseware_logs_dir }}/transformerlab_multiuser_setup.log" touch "{{ courseware_transformerlab_home }}/.courseware-managed" args: executable: /bin/bash chdir: "{{ courseware_transformerlab_home }}" creates: "{{ courseware_transformerlab_home }}/envs/general-uv/bin/python" - name: Check TransformerLab general uv environment stat: path: "{{ courseware_transformerlab_home }}/envs/general-uv/bin/python" register: courseware_transformerlab_general_uv - name: Retry TransformerLab multiuser setup after source refresh shell: | set -euo pipefail ./src/install.sh multiuser_setup 2>&1 | tee "{{ courseware_logs_dir }}/transformerlab_multiuser_setup_retry.log" args: executable: /bin/bash chdir: "{{ courseware_transformerlab_home }}" when: not courseware_transformerlab_general_uv.stat.exists - name: Recheck TransformerLab general uv environment stat: path: "{{ courseware_transformerlab_home }}/envs/general-uv/bin/python" register: courseware_transformerlab_general_uv - name: Mark TransformerLab multiuser setup complete file: path: "{{ courseware_transformerlab_home }}/.multiuser_setup_complete" state: touch mode: "0644" when: courseware_transformerlab_general_uv.stat.exists - name: Fail if TransformerLab general uv environment is missing fail: msg: "TransformerLab multiuser setup completed without creating {{ courseware_transformerlab_home }}/envs/general-uv/bin/python." when: not courseware_transformerlab_general_uv.stat.exists