From 30b919c0b9b304c644b5afa79232942b7910c495 Mon Sep 17 00:00:00 2001 From: c4ch3c4d3 <23181631+c4ch3c4d3@users.noreply.github.com> Date: Wed, 1 Apr 2026 17:09:27 -0600 Subject: [PATCH] v1.3 --- README.md | 25 ++++- ansible/group_vars/all.yml | 38 +++++++ ansible/roles/llama_cpp/tasks/main.yml | 83 ++++++++++++--- ansible/roles/packages/tasks/linux.yml | 133 +++++++++++++++++++++---- ansible/roles/preflight/tasks/main.yml | 88 ++++++++-------- ansible/templates/runtime.env.j2 | 1 + labctl | 49 ++++++--- 7 files changed, 328 insertions(+), 89 deletions(-) diff --git a/README.md b/README.md index dfb7a25..17dfa45 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,19 @@ This project builds a student-friendly local lab environment for the courseware - Kiln Desktop - Course-specific support assets for lab 2 and lab 4 -## Supported Baselines +## Supported Host Profiles This build intentionally avoids the reference VM's hardware workarounds. - macOS: Apple Silicon only, with at least 16 GB unified memory. -- Linux: Debian/Ubuntu-family only, with an NVIDIA GPU visible to `nvidia-smi` and at least 8 GB VRAM. -- WSL: treated as Linux, so the NVIDIA GPU must be exposed into WSL. +- Native Debian/Ubuntu: Debian-family Linux with an NVIDIA GPU visible to `nvidia-smi` and at least 8 GB VRAM. +- WSL: Debian/Ubuntu-family Linux running under WSL, with the NVIDIA GPU exposed into the distro. + +The launcher and Ansible preflight now classify the host dynamically and apply different setup behavior for: + +- `macos` +- `native-debian-ubuntu` +- `wsl` ## WSL Check @@ -56,6 +62,18 @@ If the automatic bootstrap still fails, verify: For non-Ubuntu WSL distros, install the CUDA toolkit manually before running the deploy script. +## Native Debian/Ubuntu CUDA Behavior + +On native Debian/Ubuntu hosts, the installer now handles three CUDA-toolkit cases: + +- If the toolkit is already usable, it reuses the existing install instead of forcing a reinstall. +- If the distro exposes `nvidia-cuda-toolkit`, it installs that package. +- If the distro package is unavailable, it bootstraps NVIDIA's official CUDA network repository for supported native Debian/Ubuntu releases and installs the toolkit from there. + +If `apt` starts in a broken dependency state, the installer now attempts `dpkg --configure -a` and `apt-get --fix-broken install` before retrying package installation. + +If CUDA is already mounted or preinstalled outside `PATH`, the installer now detects standard locations such as `/usr/local/cuda/bin/nvcc` and `/usr/local/cuda-*/bin/nvcc`. + ## Standard Assumptions - The host-side install path assumes modern local tooling, but TransformerLab itself is provisioned from a pinned classic single-user layout. @@ -69,6 +87,7 @@ For non-Ubuntu WSL distros, install the CUDA toolkit manually before running the - TransformerLab and Unsloth homes are redirected into this project's `state/` tree via symlinks. - Managed web services bind for access from both Linux and the Windows side of WSL, while `labctl urls` still reports localhost-friendly URLs. - The local Ansible bootstrap in `.venv-ansible/` is machine-specific and will be recreated automatically if the folder is copied between hosts. +- `llama.cpp` now uses a conservative, memory-aware build parallelism setting instead of an unbounded `-j` build, which avoids OOM failures on smaller Linux and WSL hosts. ## Lab URLs diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index 55b9c15..0dad747 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -98,6 +98,44 @@ courseware_wsl_cuda_installer_filename: "cuda-repo-wsl-ubuntu-13-2-local_13.2.0- courseware_wsl_cuda_installer_local_path: "/tmp/cuda-repo-wsl-ubuntu-13-2-local_13.2.0-1_amd64.deb" courseware_wsl_cuda_repo_dir: "/var/cuda-repo-wsl-ubuntu-13-2-local" courseware_wsl_cuda_toolkit_package: "cuda-toolkit-13-2" +courseware_native_cuda_keyring_version: "1.1-1" +courseware_native_cuda_repo_slug: >- + {{ + ('debian' ~ ansible_distribution_major_version) + if ansible_distribution == 'Debian' + else ( + 'ubuntu' ~ (ansible_distribution_version | replace('.', '')) + if ansible_distribution == 'Ubuntu' + else '' + ) + }} +courseware_native_cuda_repo_arch: >- + {{ + 'x86_64' + if ansible_architecture in ['x86_64', 'amd64'] + else ( + 'arm64' + if ansible_architecture in ['arm64', 'aarch64'] + else '' + ) + }} +courseware_native_cuda_repo_supported: >- + {{ + ( + ansible_distribution == 'Debian' + and ansible_distribution_major_version in ['12', '13'] + and courseware_native_cuda_repo_arch == 'x86_64' + ) + or + ( + ansible_distribution == 'Ubuntu' + and (ansible_distribution_version | replace('.', '')) in ['2204', '2404'] + and courseware_native_cuda_repo_arch in ['x86_64', 'arm64'] + ) + }} +courseware_native_cuda_keyring_url: "https://developer.download.nvidia.com/compute/cuda/repos/{{ courseware_native_cuda_repo_slug }}/{{ courseware_native_cuda_repo_arch }}/cuda-keyring_{{ courseware_native_cuda_keyring_version }}_all.deb" +courseware_native_cuda_keyring_local_path: "{{ courseware_downloads_dir }}/cuda-keyring-{{ courseware_native_cuda_repo_slug }}-{{ courseware_native_cuda_repo_arch }}.deb" +courseware_native_cuda_toolkit_package: "cuda-toolkit" courseware_unsloth_installer_url: "https://unsloth.ai/install.sh" courseware_unsloth_installer_path: "{{ courseware_downloads_dir }}/unsloth-install.sh" courseware_unsloth_python_version: "3.12" diff --git a/ansible/roles/llama_cpp/tasks/main.yml b/ansible/roles/llama_cpp/tasks/main.yml index 5cffeed..b312074 100644 --- a/ansible/roles/llama_cpp/tasks/main.yml +++ b/ansible/roles/llama_cpp/tasks/main.yml @@ -12,6 +12,22 @@ failed_when: false when: ansible_system == "Linux" +- name: Check for CUDA compiler in standard install locations + shell: | + for candidate in /usr/local/cuda/bin/nvcc /usr/local/cuda-*/bin/nvcc; do + if [ -x "$candidate" ]; then + printf '%s\n' "$candidate" + exit 0 + fi + done + exit 1 + args: + executable: /bin/bash + register: courseware_llama_nvcc_fallback + changed_when: false + failed_when: false + when: ansible_system == "Linux" + - name: Check for CUDA runtime header on Linux stat: path: "{{ item }}" @@ -48,24 +64,63 @@ ls /usr/local/cuda/include/cuda_runtime.h when: - ansible_system == "Linux" - - courseware_llama_nvcc.rc != 0 or (courseware_llama_cuda_headers.results | selectattr('stat.exists', 'equalto', true) | list | length == 0) + - courseware_llama_nvcc.rc != 0 + - courseware_llama_nvcc_fallback.rc != 0 + - (courseware_llama_cuda_headers.results | selectattr('stat.exists', 'equalto', true) | list | length == 0) + +- name: Set CUDA compiler path for llama.cpp builds + set_fact: + courseware_llama_cuda_compiler: "{{ (courseware_llama_nvcc.stdout | trim) if courseware_llama_nvcc.rc == 0 else (courseware_llama_nvcc_fallback.stdout | trim) }}" + courseware_llama_cuda_bin_dir: "{{ ((courseware_llama_nvcc.stdout | trim) if courseware_llama_nvcc.rc == 0 else (courseware_llama_nvcc_fallback.stdout | trim)) | dirname }}" + when: + - ansible_system == "Linux" + - courseware_llama_nvcc.rc == 0 or courseware_llama_nvcc_fallback.rc == 0 - name: Set llama.cpp backend flag set_fact: courseware_llama_backend_flag: "{{ '-DGGML_METAL=ON' if ansible_system == 'Darwin' else '-DGGML_CUDA=ON' }}" +- name: Set llama.cpp build parallelism + set_fact: + courseware_llama_build_jobs: >- + {{ + [ + 1, + [ + ansible_processor_vcpus | default(ansible_processor_nproc | default(1)) | int, + ((ansible_memtotal_mb | int) // 8192) | int, + 4 + ] | min + ] | max + }} + +- name: Build llama.cpp CMake configure arguments + set_fact: + courseware_llama_cmake_configure_argv: >- + {{ + [ + 'cmake', + '-S', + courseware_repos_dir ~ '/llama.cpp', + '-B', + courseware_repos_dir ~ '/llama.cpp/build', + '-DCMAKE_BUILD_TYPE=Release', + courseware_llama_backend_flag + ] + + + ( + ['-DCMAKE_CUDA_COMPILER=' ~ courseware_llama_cuda_compiler] + if ansible_system == 'Linux' and (courseware_llama_cuda_compiler | default('') | length > 0) + else [] + ) + }} + - name: Configure llama.cpp command: - argv: - - cmake - - -S - - "{{ courseware_repos_dir }}/llama.cpp" - - -B - - "{{ courseware_repos_dir }}/llama.cpp/build" - - -DCMAKE_BUILD_TYPE=Release - - "{{ courseware_llama_backend_flag }}" - args: - creates: "{{ courseware_repos_dir }}/llama.cpp/build/CMakeCache.txt" + argv: "{{ courseware_llama_cmake_configure_argv }}" + environment: + PATH: "{{ (courseware_llama_cuda_bin_dir ~ ':' ~ ansible_env.PATH) if ansible_system == 'Linux' and (courseware_llama_cuda_bin_dir | default('') | length > 0) else ansible_env.PATH }}" + CUDACXX: "{{ courseware_llama_cuda_compiler | default(omit) }}" - name: Build llama.cpp tools command: @@ -73,12 +128,16 @@ - cmake - --build - "{{ courseware_repos_dir }}/llama.cpp/build" + - --parallel + - "{{ courseware_llama_build_jobs }}" - --target - llama-cli - llama-quantize - llama-perplexity - llama-server - - -j + environment: + PATH: "{{ (courseware_llama_cuda_bin_dir ~ ':' ~ ansible_env.PATH) if ansible_system == 'Linux' and (courseware_llama_cuda_bin_dir | default('') | length > 0) else ansible_env.PATH }}" + CUDACXX: "{{ courseware_llama_cuda_compiler | default(omit) }}" - name: Check system PATH slots for llama.cpp tools stat: diff --git a/ansible/roles/packages/tasks/linux.yml b/ansible/roles/packages/tasks/linux.yml index 378aac5..ce8ccc7 100644 --- a/ansible/roles/packages/tasks/linux.yml +++ b/ansible/roles/packages/tasks/linux.yml @@ -1,7 +1,6 @@ -- name: Install Debian/Ubuntu prerequisites - become: true - apt: - name: +- name: Define Debian/Ubuntu prerequisite packages + set_fact: + courseware_linux_prereq_packages: - build-essential - ca-certificates - cmake @@ -18,8 +17,47 @@ - python3-venv - unzip - zstd - state: present - update_cache: true + +- name: Install Debian/Ubuntu prerequisites + block: + - name: Install Debian/Ubuntu prerequisite packages + become: true + apt: + name: "{{ courseware_linux_prereq_packages }}" + state: present + update_cache: true + rescue: + - name: Repair interrupted dpkg state before retrying prerequisites + become: true + command: + argv: + - dpkg + - --configure + - -a + register: courseware_dpkg_repair + changed_when: false + failed_when: false + + - name: Repair broken apt dependencies before retrying prerequisites + become: true + command: + argv: + - apt-get + - -y + - --fix-broken + - install + environment: + DEBIAN_FRONTEND: noninteractive + register: courseware_apt_fix_broken + changed_when: >- + '0 upgraded, 0 newly installed, 0 to remove' not in courseware_apt_fix_broken.stdout + + - name: Retry Debian/Ubuntu prerequisite package install + become: true + apt: + name: "{{ courseware_linux_prereq_packages }}" + state: present + update_cache: true - name: Query CUDA toolkit apt candidate command: apt-cache policy nvidia-cuda-toolkit @@ -66,31 +104,88 @@ nvcc --version ls /usr/local/cuda/include/cuda_runtime.h when: - - not courseware_is_wsl + - courseware_host_profile == "native-debian-ubuntu" - courseware_cuda_toolkit_package_available - - courseware_nvcc_check.rc != 0 + - not courseware_cuda_toolkit_ready -- name: Fail with CUDA toolkit guidance when no apt candidate exists +- name: Fail when native CUDA network repository bootstrap is unsupported fail: msg: | - CUDA Toolkit is not available from this distro's current apt sources. + This native {{ ansible_distribution }} {{ ansible_distribution_version }} host does not match the CUDA network-repository variants this installer knows how to bootstrap automatically. - This installer needs the Linux-side CUDA toolkit for llama.cpp, not just a working `nvidia-smi`. + Supported native CUDA repo bootstrap targets currently match NVIDIA's documented Debian/Ubuntu paths: + - Debian 12 and Debian 13 on x86_64 + - Ubuntu 22.04 and Ubuntu 24.04 on x86_64 or arm64 - On WSL this usually means: - - Windows side: the NVIDIA driver is installed correctly - - Linux side: the CUDA toolkit repository is still missing - - Add NVIDIA's CUDA repository for your Debian/Ubuntu release, install the toolkit, then rerun: - bash deploy-courseware.sh + Install the Linux-side CUDA toolkit manually for this host, then rerun: + ./labctl up Verify with: nvcc --version ls /usr/local/cuda/include/cuda_runtime.h when: - - not courseware_is_wsl + - courseware_host_profile == "native-debian-ubuntu" - not courseware_cuda_toolkit_package_available - - courseware_nvcc_check.rc != 0 + - not courseware_cuda_toolkit_ready + - not courseware_native_cuda_repo_supported + +- name: Bootstrap NVIDIA CUDA network repository for native Debian/Ubuntu + block: + - name: Download NVIDIA CUDA keyring package + get_url: + url: "{{ courseware_native_cuda_keyring_url }}" + dest: "{{ courseware_native_cuda_keyring_local_path }}" + mode: "0644" + force: false + + - name: Install NVIDIA CUDA keyring package + become: true + apt: + deb: "{{ courseware_native_cuda_keyring_local_path }}" + state: present + + - name: Install CUDA toolkit from NVIDIA network repository + become: true + apt: + name: "{{ courseware_native_cuda_toolkit_package }}" + state: present + update_cache: true + rescue: + - name: Repair interrupted dpkg state before retrying CUDA repository install + become: true + command: + argv: + - dpkg + - --configure + - -a + changed_when: false + failed_when: false + + - name: Repair broken apt dependencies before retrying CUDA repository install + become: true + command: + argv: + - apt-get + - -y + - --fix-broken + - install + environment: + DEBIAN_FRONTEND: noninteractive + register: courseware_cuda_repo_fix_broken + changed_when: >- + '0 upgraded, 0 newly installed, 0 to remove' not in courseware_cuda_repo_fix_broken.stdout + + - name: Retry CUDA toolkit install from NVIDIA network repository + become: true + apt: + name: "{{ courseware_native_cuda_toolkit_package }}" + state: present + update_cache: true + when: + - courseware_host_profile == "native-debian-ubuntu" + - not courseware_cuda_toolkit_package_available + - not courseware_cuda_toolkit_ready + - courseware_native_cuda_repo_supported - name: Check for Ollama binary command: which ollama diff --git a/ansible/roles/preflight/tasks/main.yml b/ansible/roles/preflight/tasks/main.yml index 95d9a4f..b98497b 100644 --- a/ansible/roles/preflight/tasks/main.yml +++ b/ansible/roles/preflight/tasks/main.yml @@ -1,6 +1,10 @@ -- name: Detect WSL +- name: Classify supported host profile set_fact: + courseware_is_macos: "{{ ansible_system == 'Darwin' }}" + courseware_is_linux: "{{ ansible_system == 'Linux' }}" courseware_is_wsl: "{{ 'microsoft' in ansible_kernel | lower or 'wsl' in ansible_kernel | lower }}" + courseware_is_native_linux: "{{ ansible_system == 'Linux' and not ('microsoft' in ansible_kernel | lower or 'wsl' in ansible_kernel | lower) }}" + courseware_host_profile: "{{ 'macos' if ansible_system == 'Darwin' else ('wsl' if ('microsoft' in ansible_kernel | lower or 'wsl' in ansible_kernel | lower) else ('native-debian-ubuntu' if ansible_system == 'Linux' and ansible_os_family == 'Debian' else 'unsupported')) }}" - name: Fail on unsupported operating systems fail: @@ -52,7 +56,7 @@ fail: msg: "This installer currently supports Debian and Ubuntu only." when: - - ansible_system == "Linux" + - courseware_is_linux - ansible_os_family != "Debian" - name: Query NVIDIA GPU memory @@ -60,27 +64,27 @@ register: courseware_gpu_memory changed_when: false failed_when: false - when: ansible_system == "Linux" + when: courseware_is_linux - name: Query NVIDIA GPU names command: nvidia-smi --query-gpu=name --format=csv,noheader register: courseware_gpu_names changed_when: false failed_when: false - when: ansible_system == "Linux" + when: courseware_is_linux - name: Fail when no supported NVIDIA GPU is visible fail: msg: "Linux/WSL requires an NVIDIA GPU visible to nvidia-smi." when: - - ansible_system == "Linux" + - courseware_is_linux - courseware_gpu_memory.rc != 0 - name: Fail when GPU VRAM is below baseline fail: msg: "This build assumes at least 8 GB of VRAM on Linux/WSL." when: - - ansible_system == "Linux" + - courseware_is_linux - (courseware_gpu_memory.stdout_lines | map('int') | max) < 8192 - name: Check for CUDA compiler on Linux @@ -88,7 +92,23 @@ register: courseware_preflight_nvcc changed_when: false failed_when: false - when: ansible_system == "Linux" + when: courseware_is_linux + +- name: Check for CUDA compiler in standard install locations + shell: | + for candidate in /usr/local/cuda/bin/nvcc /usr/local/cuda-*/bin/nvcc; do + if [ -x "$candidate" ]; then + printf '%s\n' "$candidate" + exit 0 + fi + done + exit 1 + args: + executable: /bin/bash + register: courseware_preflight_nvcc_fallback + changed_when: false + failed_when: false + when: courseware_is_linux - name: Check for CUDA runtime header on Linux stat: @@ -97,16 +117,17 @@ - /usr/local/cuda/include/cuda_runtime.h - /usr/include/cuda_runtime.h register: courseware_preflight_cuda_headers - when: ansible_system == "Linux" + when: courseware_is_linux - name: Set CUDA toolkit readiness set_fact: courseware_cuda_toolkit_ready: >- {{ courseware_preflight_nvcc.rc == 0 + or courseware_preflight_nvcc_fallback.rc == 0 or (courseware_preflight_cuda_headers.results | selectattr('stat.exists', 'equalto', true) | list | length > 0) }} - when: ansible_system == "Linux" + when: courseware_is_linux - name: Query distro CUDA toolkit apt candidate command: apt-cache policy nvidia-cuda-toolkit @@ -114,7 +135,7 @@ changed_when: false failed_when: false when: - - ansible_system == "Linux" + - courseware_is_linux - ansible_os_family == "Debian" - name: Set distro CUDA toolkit package availability @@ -125,15 +146,14 @@ and 'Candidate: (none)' not in courseware_preflight_cuda_toolkit_policy.stdout }} when: - - ansible_system == "Linux" + - courseware_is_linux - ansible_os_family == "Debian" - name: Fail when automatic WSL CUDA bootstrap is unsupported fail: msg: "Automatic CUDA bootstrap currently supports Ubuntu x86_64 on WSL only. For other WSL distros, install the CUDA toolkit manually before rerunning." when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution != "Ubuntu" or ansible_architecture not in ["x86_64", "amd64"] @@ -144,8 +164,7 @@ state: present update_cache: true when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution == "Ubuntu" - ansible_architecture in ["x86_64", "amd64"] @@ -157,8 +176,7 @@ changed_when: false failed_when: false when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution == "Ubuntu" - ansible_architecture in ["x86_64", "amd64"] @@ -172,8 +190,7 @@ - /usr/include/cuda_runtime.h register: courseware_preflight_cuda_headers_after_distro_install when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution == "Ubuntu" - ansible_architecture in ["x86_64", "amd64"] @@ -187,8 +204,7 @@ or (courseware_preflight_cuda_headers_after_distro_install.results | selectattr('stat.exists', 'equalto', true) | list | length > 0) }} when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution == "Ubuntu" - ansible_architecture in ["x86_64", "amd64"] @@ -201,8 +217,7 @@ changed_when: courseware_wsl_cuda_apt_key_delete.rc == 0 failed_when: false when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution == "Ubuntu" - ansible_architecture in ["x86_64", "amd64"] @@ -215,8 +230,7 @@ mode: "0644" force: true when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution == "Ubuntu" - ansible_architecture in ["x86_64", "amd64"] @@ -228,8 +242,7 @@ mode: "0644" force: false when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution == "Ubuntu" - ansible_architecture in ["x86_64", "amd64"] @@ -240,8 +253,7 @@ deb: "{{ courseware_wsl_cuda_installer_local_path }}" state: present when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution == "Ubuntu" - ansible_architecture in ["x86_64", "amd64"] @@ -254,8 +266,7 @@ file_type: file register: courseware_wsl_cuda_keyring when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution == "Ubuntu" - ansible_architecture in ["x86_64", "amd64"] @@ -264,8 +275,7 @@ fail: msg: "The NVIDIA WSL CUDA repository package was installed, but its keyring file was not found under {{ courseware_wsl_cuda_repo_dir }}." when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution == "Ubuntu" - ansible_architecture in ["x86_64", "amd64"] @@ -279,8 +289,7 @@ remote_src: true mode: "0644" when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution == "Ubuntu" - ansible_architecture in ["x86_64", "amd64"] @@ -293,8 +302,7 @@ state: present update_cache: true when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution == "Ubuntu" - ansible_architecture in ["x86_64", "amd64"] @@ -305,8 +313,7 @@ changed_when: false failed_when: false when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution == "Ubuntu" - ansible_architecture in ["x86_64", "amd64"] @@ -315,8 +322,7 @@ fail: msg: "The NVIDIA WSL CUDA toolkit install completed, but `nvcc` is still missing. Verify the repository package and rerun the installer." when: - - ansible_system == "Linux" - - courseware_is_wsl + - courseware_host_profile == "wsl" - not courseware_cuda_toolkit_ready - ansible_distribution == "Ubuntu" - ansible_architecture in ["x86_64", "amd64"] diff --git a/ansible/templates/runtime.env.j2 b/ansible/templates/runtime.env.j2 index 2bd4a37..f87febf 100644 --- a/ansible/templates/runtime.env.j2 +++ b/ansible/templates/runtime.env.j2 @@ -1,3 +1,4 @@ +COURSEWARE_HOST_PROFILE="{{ courseware_host_profile | trim }}" COURSEWARE_ROOT="{{ courseware_root }}" COURSEWARE_STATE_DIR="{{ courseware_state_dir }}" COURSEWARE_BIND_HOST="{{ courseware_bind_host }}" diff --git a/labctl b/labctl index f27b63b..a66a38d 100755 --- a/labctl +++ b/labctl @@ -112,16 +112,39 @@ host_is_wsl() { [ "$(uname -s)" = "Linux" ] && uname -r | grep -qiE 'microsoft|wsl' } -host_is_arm_mac() { - [ "$(uname -s)" = "Darwin" ] && [ "$(uname -m)" = "arm64" ] +host_is_macos() { + [ "$(uname -s)" = "Darwin" ] } -check_wsl_gpu_readiness() { - if host_is_arm_mac; then +host_is_linux() { + [ "$(uname -s)" = "Linux" ] +} + +host_is_arm_mac() { + host_is_macos && [ "$(uname -m)" = "arm64" ] +} + +host_profile() { + if host_is_wsl; then + printf '%s\n' "wsl" return fi - if ! host_is_wsl; then + if host_is_macos; then + printf '%s\n' "macos" + return + fi + + if host_is_linux && host_is_debian_family; then + printf '%s\n' "native-debian-ubuntu" + return + fi + + printf '%s\n' "unsupported" +} + +check_wsl_gpu_readiness() { + if [ "$(host_profile)" != "wsl" ]; then return fi @@ -153,6 +176,12 @@ EOF linux_cuda_toolkit_is_ready() { command -v nvcc >/dev/null 2>&1 && return 0 + [ -x /usr/local/cuda/bin/nvcc ] && return 0 + for candidate in /usr/local/cuda-*/bin/nvcc; do + if [ -x "$candidate" ]; then + return 0 + fi + done [ -f /usr/local/cuda/include/cuda_runtime.h ] && return 0 [ -f /usr/include/cuda_runtime.h ] && return 0 return 1 @@ -213,15 +242,7 @@ EOF } check_linux_cuda_toolkit() { - if host_is_arm_mac; then - return - fi - - if [ "$(uname -s)" != "Linux" ]; then - return - fi - - if host_is_wsl; then + if [ "$(host_profile)" != "native-debian-ubuntu" ]; then return fi