Add managed Lab 3 browser terminal deployment
This commit is contained in:
@@ -18,9 +18,12 @@ courseware_unsloth_home: "{{ courseware_state_dir }}/unsloth-home"
|
||||
courseware_ollama_models_dir: "{{ courseware_models_dir }}/ollama"
|
||||
courseware_node_runtime_dir: "{{ courseware_tools_dir }}/node-runtime"
|
||||
courseware_node_runtime_bin_dir: "{{ courseware_node_runtime_dir }}/node_modules/node/bin"
|
||||
courseware_wetty_dir: "{{ courseware_tools_dir }}/wetty"
|
||||
courseware_promptfoo_dir: "{{ courseware_lab6_dir }}"
|
||||
courseware_wiki_repo_dir: "{{ courseware_repos_dir }}/LLM-Labs"
|
||||
courseware_wiki_runtime_config_path: "{{ courseware_wiki_repo_dir }}/public/courseware-runtime.json"
|
||||
courseware_llama_cpp_bin_dir: "{{ courseware_repos_dir }}/llama.cpp/build/bin"
|
||||
courseware_lab3_dir: "/home/student/lab3"
|
||||
|
||||
courseware_bind_host: "0.0.0.0"
|
||||
courseware_url_host: "127.0.0.1"
|
||||
@@ -33,6 +36,7 @@ courseware_ports:
|
||||
unsloth: 8888
|
||||
promptfoo: 15500
|
||||
wiki: 80
|
||||
wetty: 7681
|
||||
|
||||
courseware_transformerlab_install_mode: "single-user-pinned"
|
||||
courseware_transformerlab_version: "v0.28.2"
|
||||
@@ -63,7 +67,11 @@ courseware_chunkviz_commit: "a891eacafda1f28a12373ad3b00102e68f07c57f"
|
||||
courseware_promptfoo_version: "0.119.0"
|
||||
courseware_kiln_release_tag: "v0.18.1"
|
||||
courseware_node_runtime_version: "20.20.2"
|
||||
courseware_wetty_spec: "wetty@2.5.0"
|
||||
courseware_wetty_base_path: "/wetty"
|
||||
courseware_wiki_repo: "https://git.zuccaro.me/bzuccaro/LLM-Labs.git"
|
||||
courseware_student_username: "student"
|
||||
courseware_student_password_hash: "{{ lookup('env', 'COURSEWARE_STUDENT_PASSWORD_HASH') | default('', true) }}"
|
||||
|
||||
courseware_open_webui_spec: "open-webui"
|
||||
courseware_embedding_atlas_spec: "embedding-atlas"
|
||||
@@ -151,3 +159,4 @@ courseware_services:
|
||||
- "unsloth"
|
||||
- "promptfoo"
|
||||
- "wiki"
|
||||
- "wetty"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
- packages
|
||||
- lab_assets
|
||||
- node_runtime
|
||||
- { role: terminal, when: ansible_system == "Linux" }
|
||||
- llama_cpp
|
||||
- transformerlab
|
||||
- open_webui
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
- name: Fail when student password hash is not configured
|
||||
fail:
|
||||
msg: >-
|
||||
Set COURSEWARE_STUDENT_PASSWORD_HASH in the environment before running ./labctl up.
|
||||
Example:
|
||||
export COURSEWARE_STUDENT_PASSWORD_HASH="$(openssl passwd -6 'student-password')"
|
||||
when: courseware_student_password_hash | trim | length == 0
|
||||
|
||||
- name: Install terminal prerequisites
|
||||
become: true
|
||||
apt:
|
||||
name:
|
||||
- openssh-server
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Ensure sshd drop-in directory exists
|
||||
become: true
|
||||
file:
|
||||
path: /etc/ssh/sshd_config.d
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Configure courseware loopback-only sshd policy
|
||||
become: true
|
||||
template:
|
||||
src: sshd-courseware-terminal.conf.j2
|
||||
dest: /etc/ssh/sshd_config.d/50-courseware-terminal.conf
|
||||
mode: "0644"
|
||||
register: courseware_terminal_sshd_config
|
||||
|
||||
- name: Validate sshd configuration
|
||||
become: true
|
||||
command:
|
||||
argv:
|
||||
- /usr/sbin/sshd
|
||||
- -t
|
||||
- -f
|
||||
- /etc/ssh/sshd_config
|
||||
changed_when: false
|
||||
|
||||
- name: Ensure sshd runtime directory exists
|
||||
become: true
|
||||
file:
|
||||
path: /run/sshd
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Start and enable sshd with systemd when available
|
||||
become: true
|
||||
systemd:
|
||||
name: ssh
|
||||
state: started
|
||||
enabled: true
|
||||
when: ansible_service_mgr == "systemd"
|
||||
|
||||
- name: Check for running sshd when systemd is unavailable
|
||||
become: true
|
||||
command: pgrep -x sshd
|
||||
register: courseware_terminal_sshd_pid
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
when: ansible_service_mgr != "systemd"
|
||||
|
||||
- name: Reload running sshd when config changed outside systemd
|
||||
become: true
|
||||
command: pkill -HUP -x sshd
|
||||
when:
|
||||
- ansible_service_mgr != "systemd"
|
||||
- courseware_terminal_sshd_pid.rc == 0
|
||||
- courseware_terminal_sshd_config.changed
|
||||
|
||||
- name: Start sshd when it is not already running outside systemd
|
||||
become: true
|
||||
command:
|
||||
argv:
|
||||
- /usr/sbin/sshd
|
||||
when:
|
||||
- ansible_service_mgr != "systemd"
|
||||
- courseware_terminal_sshd_pid.rc != 0
|
||||
|
||||
- name: Ensure managed terminal user exists
|
||||
become: true
|
||||
user:
|
||||
name: "{{ courseware_student_username }}"
|
||||
password: "{{ courseware_student_password_hash }}"
|
||||
shell: /bin/bash
|
||||
create_home: true
|
||||
state: present
|
||||
|
||||
- name: Ensure lab 3 workspace root exists
|
||||
become: true
|
||||
file:
|
||||
path: "{{ courseware_lab3_dir }}"
|
||||
state: directory
|
||||
owner: "{{ courseware_student_username }}"
|
||||
group: "{{ courseware_student_username }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Ensure lab 3 WhiteRabbitNeo workspace exists
|
||||
become: true
|
||||
file:
|
||||
path: "{{ courseware_lab3_dir }}/WhiteRabbitNeo"
|
||||
state: directory
|
||||
owner: "{{ courseware_student_username }}"
|
||||
group: "{{ courseware_student_username }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Write lab 3 workspace README
|
||||
become: true
|
||||
template:
|
||||
src: lab3-workspace-readme.txt.j2
|
||||
dest: "{{ courseware_lab3_dir }}/README.txt"
|
||||
owner: "{{ courseware_student_username }}"
|
||||
group: "{{ courseware_student_username }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: Check for repo-local WhiteRabbitNeo base repo
|
||||
stat:
|
||||
path: "{{ courseware_root }}/assets/lab2/WhiteRabbitNeo-V3-7B"
|
||||
register: courseware_lab3_base_repo_stat
|
||||
|
||||
- name: Check for repo-local WhiteRabbitNeo GGUF directory
|
||||
stat:
|
||||
path: "{{ courseware_root }}/assets/lab2/WhiteRabbitNeo_WhiteRabbitNeo-V3-7B-GGUF"
|
||||
register: courseware_lab3_gguf_repo_stat
|
||||
|
||||
- name: Link WhiteRabbitNeo base repo into the student workspace when repo-local assets exist
|
||||
become: true
|
||||
file:
|
||||
src: "{{ courseware_root }}/assets/lab2/WhiteRabbitNeo-V3-7B"
|
||||
dest: "{{ courseware_lab3_dir }}/WhiteRabbitNeo/WhiteRabbitNeo-V3-7B"
|
||||
state: link
|
||||
force: true
|
||||
owner: "{{ courseware_student_username }}"
|
||||
group: "{{ courseware_student_username }}"
|
||||
when: courseware_lab3_base_repo_stat.stat.exists
|
||||
|
||||
- name: Link WhiteRabbitNeo GGUF directory into the student workspace when repo-local assets exist
|
||||
become: true
|
||||
file:
|
||||
src: "{{ courseware_root }}/assets/lab2/WhiteRabbitNeo_WhiteRabbitNeo-V3-7B-GGUF"
|
||||
dest: "{{ courseware_lab3_dir }}/WhiteRabbitNeo/WhiteRabbitNeo_WhiteRabbitNeo-V3-7B-GGUF"
|
||||
state: link
|
||||
force: true
|
||||
owner: "{{ courseware_student_username }}"
|
||||
group: "{{ courseware_student_username }}"
|
||||
when: courseware_lab3_gguf_repo_stat.stat.exists
|
||||
|
||||
- name: Link WhiteRabbitNeo download helper into the student workspace
|
||||
become: true
|
||||
file:
|
||||
src: "{{ courseware_lab2_dir }}/download_whiterabbitneo-gguf.sh"
|
||||
dest: "{{ courseware_lab3_dir }}/download_whiterabbitneo-gguf.sh"
|
||||
state: link
|
||||
force: true
|
||||
owner: "{{ courseware_student_username }}"
|
||||
group: "{{ courseware_student_username }}"
|
||||
|
||||
- name: Create contained WeTTY directory
|
||||
file:
|
||||
path: "{{ courseware_wetty_dir }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Install contained WeTTY runtime
|
||||
command:
|
||||
argv:
|
||||
- npm
|
||||
- install
|
||||
- "{{ courseware_wetty_spec }}"
|
||||
args:
|
||||
chdir: "{{ courseware_wetty_dir }}"
|
||||
creates: "{{ courseware_wetty_dir }}/node_modules/.bin/wetty"
|
||||
environment:
|
||||
PATH: "{{ courseware_node_runtime_bin_dir }}:{{ ansible_env.PATH }}"
|
||||
|
||||
- name: Check loopback sshd listener
|
||||
become: true
|
||||
command: ss -ltn
|
||||
register: courseware_terminal_ss_listeners
|
||||
changed_when: false
|
||||
|
||||
- name: Assert sshd is loopback-only
|
||||
assert:
|
||||
that:
|
||||
- "'127.0.0.1:22' in courseware_terminal_ss_listeners.stdout"
|
||||
- "'0.0.0.0:22' not in courseware_terminal_ss_listeners.stdout"
|
||||
- "'[::]:22' not in courseware_terminal_ss_listeners.stdout"
|
||||
fail_msg: "sshd must listen only on 127.0.0.1:22 for the browser terminal deployment."
|
||||
|
||||
- name: Assert WeTTY binary exists
|
||||
stat:
|
||||
path: "{{ courseware_wetty_dir }}/node_modules/.bin/wetty"
|
||||
register: courseware_wetty_bin_stat
|
||||
|
||||
- name: Fail when WeTTY installation is incomplete
|
||||
fail:
|
||||
msg: "WeTTY was not installed under {{ courseware_wetty_dir }}."
|
||||
when: not courseware_wetty_bin_stat.stat.exists
|
||||
@@ -0,0 +1,14 @@
|
||||
This workspace is managed for the Lab 3 browser terminal.
|
||||
|
||||
You should log in as:
|
||||
- username: {{ courseware_student_username }}
|
||||
|
||||
Start here:
|
||||
- working directory: {{ courseware_lab3_dir }}
|
||||
|
||||
Helpful paths:
|
||||
- WhiteRabbitNeo helper: {{ courseware_lab3_dir }}/download_whiterabbitneo-gguf.sh
|
||||
- repo-local base repo symlink: {{ courseware_lab3_dir }}/WhiteRabbitNeo/WhiteRabbitNeo-V3-7B
|
||||
- repo-local GGUF symlink: {{ courseware_lab3_dir }}/WhiteRabbitNeo/WhiteRabbitNeo_WhiteRabbitNeo-V3-7B-GGUF
|
||||
|
||||
Some symlinks only appear after the corresponding repo-local lab assets are present.
|
||||
@@ -0,0 +1,12 @@
|
||||
# Managed by Local Courseware Deployment.
|
||||
ListenAddress 127.0.0.1
|
||||
AddressFamily inet
|
||||
PermitRootLogin no
|
||||
PasswordAuthentication yes
|
||||
KbdInteractiveAuthentication no
|
||||
ChallengeResponseAuthentication no
|
||||
UsePAM yes
|
||||
AllowUsers {{ courseware_student_username }}
|
||||
AllowTcpForwarding no
|
||||
X11Forwarding no
|
||||
PrintMotd no
|
||||
@@ -36,6 +36,12 @@
|
||||
environment:
|
||||
PATH: "{{ courseware_node_runtime_bin_dir }}:{{ ansible_env.PATH }}"
|
||||
|
||||
- name: Render wiki runtime config
|
||||
template:
|
||||
src: courseware-runtime.json.j2
|
||||
dest: "{{ courseware_wiki_runtime_config_path }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: Stat wiki build output
|
||||
stat:
|
||||
path: "{{ courseware_wiki_repo_dir }}/.next/BUILD_ID"
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"lab3TerminalUrl": "http://{{ courseware_url_host }}:{{ courseware_ports.wetty }}{{ courseware_wetty_base_path }}",
|
||||
"lab3Username": "{{ courseware_student_username }}",
|
||||
"lab3WorkingDirectory": "{{ courseware_lab3_dir }}"
|
||||
}
|
||||
@@ -11,9 +11,12 @@ COURSEWARE_EMBEDDING_ATLAS_PORT="{{ courseware_ports.embedding_atlas }}"
|
||||
COURSEWARE_UNSLOTH_PORT="{{ courseware_ports.unsloth }}"
|
||||
COURSEWARE_PROMPTFOO_PORT="{{ courseware_ports.promptfoo }}"
|
||||
COURSEWARE_WIKI_PORT="{{ courseware_ports.wiki }}"
|
||||
COURSEWARE_WETTY_PORT="{{ courseware_ports.wetty }}"
|
||||
OLLAMA_BIN="{{ courseware_ollama_bin }}"
|
||||
OLLAMA_MODELS_DIR="{{ courseware_ollama_models_dir }}"
|
||||
NODE_RUNTIME_BIN_DIR="{{ courseware_node_runtime_bin_dir }}"
|
||||
WETTY_BIN="{{ courseware_wetty_dir }}/node_modules/.bin/wetty"
|
||||
COURSEWARE_WETTY_BASE_PATH="{{ courseware_wetty_base_path }}"
|
||||
OPEN_WEBUI_VENV="{{ courseware_venvs_dir }}/open-webui"
|
||||
OPEN_WEBUI_DATA_DIR="{{ courseware_state_dir }}/open-webui"
|
||||
CHUNKVIZ_DIR="{{ courseware_repos_dir }}/ChunkViz"
|
||||
@@ -25,10 +28,13 @@ TRANSFORMERLAB_DEFAULT_USER_EMAIL="{{ courseware_transformerlab_default_user_ema
|
||||
TRANSFORMERLAB_DEFAULT_USER_PASSWORD="{{ courseware_transformerlab_default_user_password }}"
|
||||
TRANSFORMERLAB_DEFAULT_USER_FIRST_NAME="{{ courseware_transformerlab_default_user_first_name }}"
|
||||
TRANSFORMERLAB_DEFAULT_USER_LAST_NAME="{{ courseware_transformerlab_default_user_last_name }}"
|
||||
COURSEWARE_STUDENT_USERNAME="{{ courseware_student_username }}"
|
||||
COURSEWARE_LAB3_DIR="{{ courseware_lab3_dir }}"
|
||||
UNSLOTH_BIN="{{ ansible_env.HOME }}/.local/bin/unsloth"
|
||||
PROMPTFOO_DIR="{{ courseware_promptfoo_dir }}"
|
||||
PROMPTFOO_BIN="{{ courseware_tools_dir }}/promptfoo/node_modules/.bin/promptfoo"
|
||||
WIKI_DIR="{{ courseware_wiki_repo_dir }}"
|
||||
WIKI_RUNTIME_CONFIG_PATH="{{ courseware_wiki_runtime_config_path }}"
|
||||
LLAMA_CPP_BIN_DIR="{{ courseware_llama_cpp_bin_dir }}"
|
||||
KILN_LINUX_BIN="{{ courseware_apps_dir }}/kiln/Kiln"
|
||||
KILN_MAC_APP="{{ courseware_apps_dir }}/Kiln.app"
|
||||
|
||||
Reference in New Issue
Block a user