RV Launcher

Repo rv-launcher zawiera narzędzie do pracy ze wspólnym workspace EDU. W pierwszej kolejności służy ono do zarządzania tokenami; pozostałe funkcje obejmują pracę z kartami pracy i uruchamianie środowiska kontenerowego.

Właściwym skryptem CLI jest wykonywalny plik rvctl.py. To on implementuje zarządzanie tokenami, listowanie serii i kart, przygotowanie repo odpowiedzi i start kontenera.

Publicznym entrypointem dla użytkownika jest krótki wrapper rvctl:

./rvctl

Wrapper uruchamia:

python3 rvctl.py "$@"

rvctl.py można też uruchomić bezpośrednio:

./rvctl.py

Lokalne ścieżki i domyślne ustawienia są trzymane w workspace.json. Publiczny opis wspólnego workspace, czyli serie, karty i wersje repozytoriów, jest w osobnym repo edu-workspace/workspace-info.

Co robi narzędzie

rvctl porządkuje pracę w trzech obszarach.

  1. Zarządzanie tokenami

    Narzędzie obsługuje lokalny store tokens/tokens.json, porównuje go z git remotes i potrafi synchronizować token w obie strony. Szczegóły modelu, format pliku i opis komend są w doc/tokens.md.

  2. Listowanie i pobieranie kart pracy

    rvctl czyta serie i karty z meta/workspace-info, zadania z pobranych kart, pomaga wybrać materiał do pracy oraz przygotowuje remotes potrzebne do repo odpowiedzi. Docelowy model namespace series, cards i tasks jest w doc/series.md.

  3. Uruchamianie środowiska programistycznego w kontenerach

    Dla wybranej karty i zadania rvctl uruchamia osobne profile kontenerów: rv32i dla Hazard3/RISC-V oraz host dla natywnego debugowania C. Oba profile opierają się na nvim, tmux i debuggerze. Model komend jest w doc/containers.md.

Model katalogów

Podstawowym miejscem pracy użytkownika jest workspace:

~/dev/workspace/rv

Najpierw utwórz tylko katalog bazowy workspace i wejdź do niego:

mkdir -p ~/dev/workspace/rv
cd ~/dev/workspace/rv

Po tym kroku workspace istnieje, ale nie ma jeszcze katalogów narzędzi, tokenów ani kart:

~/dev/workspace/rv

Potem wybierz jedną z dwóch dróg startu.

Bez tokens.json

Ten wariant jest dla sytuacji, w której token jest podany w URL-u git remota, a plik tokens.json ma powstać dopiero lokalnie.

Etap 1: utwórz katalog launchera i wejdź do niego:

mkdir -p ~/dev/workspace/rv/tools/rv-launcher
cd ~/dev/workspace/rv/tools/rv-launcher

Etap 2: utwórz puste repo, dodaj remote r1 z tokenem, pobierz branch i ustaw lokalny main:

git init
git remote add r1 http://u1:TOKEN@77.90.8.171:3001/edu-tools/rv-launcher.git
git fetch r1 main
git switch --track -c main r1/main

r1 jest nazwą remota, z którego startujemy. --track ustawia lokalny branch main tak, aby śledził r1/main, dzięki czemu późniejsze git pull i git push wiedzą, z którym branchem zdalnym pracują.

Po tym kroku w workspace jest już repo launchera:

~/dev/workspace/rv
└── tools
    └── rv-launcher

Repo workspace-info nie jest częścią tools. rvctl pobierze je automatycznie do meta/workspace-info przy pierwszej komendzie zależnej od manifestu, na przykład series list.

Etap 3: wczytaj token z remota do lokalnego store:

cd ~/dev/workspace/rv/tools/rv-launcher
./rvctl tokens sync remote r1
./rvctl tokens update r1

tokens sync remote r1 przepisuje token z URL-a remota r1 do lokalnego store. tokens update r1 odpytuje Gitea API i uzupełnia metadane tokena: ważność, zakresy oraz uprawnienia w organizacji i repo.

rvctl sam tworzy katalog ~/dev/workspace/rv/tokens, jeżeli jeszcze go nie ma. Plik tokens.json dostaje prawa 600, a katalog store prawa 700.

Po tym kroku workspace ma już tokens.json:

~/dev/workspace/rv
├── tools
│   └── rv-launcher
└── tokens
    └── tokens.json

Etap 4: sprawdź, czy git remote i lokalny store widzą ten sam token:

./rvctl tokens compare

Przykładowy wydruk:

tokens
item  server  proto  host                org        repo         user  remote  token_ref  token         valid    scope      org     repo
----  ------  -----  ------------------  ---------  -----------  ----  ------  ---------  ------------  -------  ---------  ------  ------
1     gitea   http   77.90.8.171:3001    edu-tools  rv-launcher  u1    r1      r1      *  e59cc...13be  forever  wwwwwwwww  +++++   ++++

Najważniejsze pola:

  • remote - nazwa git remota, tutaj r1
  • token_ref - lokalna nazwa tokena i marker zgodności po prawej stronie
  • * - token w remote i w tokens.json jest zgodny
  • S - token jest tylko w tokens.json; to jest normalne w trybie store-only
  • R - token jest tylko w git remote
  • token - zamaskowany sekret; rvctl nie wypisuje całego tokena
  • valid, scope, org, repo - metadane i uprawnienia pobrane przez tokens update

Pełny opis tabeli tokenów jest w doc/tokens.md.

Z tokens.json

Ten wariant jest dla sytuacji, w której masz już gotowy plik tokens.json.

Etap 1: skopiuj token store do workspace:

mkdir -p ~/dev/workspace/rv/tokens
cd ~/dev/workspace/rv
cp /ścieżka/do/tokens.json tokens/tokens.json
chmod 600 tokens/tokens.json

Po tym kroku workspace ma store tokenów, ale nie ma jeszcze launchera:

~/dev/workspace/rv
└── tokens
    └── tokens.json

Etap 2: wejdź do katalogu narzędzi i sklonuj rv-launcher:

mkdir -p ~/dev/workspace/rv/tools
cd ~/dev/workspace/rv/tools
git clone http://77.90.8.171:3001/edu-tools/rv-launcher.git
cd rv-launcher

Po git clone workspace wygląda tak:

~/dev/workspace/rv
├── tools
│   └── rv-launcher
└── tokens
    └── tokens.json

Etap 3: sprawdź store i wpisz credentials ze store do remota r1:

./rvctl tokens list store
./rvctl tokens sync store r1

tokens list store sprawdza, czy skopiowany tokens.json zawiera wpis dla remota r1. tokens sync store r1 bierze token ze store i wpisuje credentials do git remota r1, tak aby kolejne operacje Git mogły używać tego tokena. Jeżeli po git clone repo ma tylko remote origin wskazujący to samo repo, rvctl automatycznie przemianuje go na r1.

list store powinien pokazać token ze store:

tokens
item  source  kind  server  proto  host              org        repo         user  remote  token         valid
----  ------  ----  ------  -----  ----------------  ---------  -----------  ----  ------  ------------  -------
1     store   auth  gitea   http   77.90.8.171:3001  edu-tools  rv-launcher  u1    r1      e59cc...13be  forever

sync store r1 wpisuje credentials do git remota:

repo_root  /home/user/dev/workspace/rv/tools/rv-launcher
remote     r1
renamed_from  origin
server     http://77.90.8.171:3001
user       u1
id         r1
status     updated
url        http://77.90.8.171:3001/edu-tools/rv-launcher.git

Etap 4: odśwież metadane tokena i porównaj store z remote:

./rvctl tokens update r1
./rvctl tokens compare

tokens update r1 odpytuje Gitea API dla tokena ze store i odświeża jego metadane: ważność, zakresy oraz uprawnienia w organizacji i repo. tokens compare sprawdza potem, czy store i git remote wskazują ten sam token.

compare powinien pokazać * przy r1, jeżeli remote i tokens.json są zgodne:

tokens
item  server  proto  host              org        repo         user  remote  token_ref  token         valid
----  ------  -----  ----------------  ---------  -----------  ----  ------  ---------  ------------  -------
1     gitea   http   77.90.8.171:3001  edu-tools  rv-launcher  u1    r1      r1      *  e59cc...13be  forever

Etap 5: po operacjach Git możesz usunąć sekret z .git/config, zostawiając token tylko w store:

./rvctl tokens rm remote r1
./rvctl tokens compare

Po usunięciu remota compare pokazuje marker S, czyli token jest tylko w store:

tokens
item  server  proto  host              org        repo         user  remote  token_ref  token         valid
----  ------  -----  ----------------  ---------  -----------  ----  ------  ---------  ------------  -------
1     gitea   http   77.90.8.171:3001  edu-tools  rv-launcher  u1    r1      r1      S  e59cc...13be  forever

Kolejny krok: serie i karty pracy

Po konfiguracji tokenów następnym elementem jest publiczny manifest wspólnego workspace. rvctl szuka go lokalnie w:

~/dev/workspace/rv/meta/workspace-info

Manifest zawiera listę serii, kart, repozytoriów źródłowych, repozytoriów odpowiedzi i branchy. Nie zawiera tokenów ani lokalnych plików ucznia.

Nie musisz pobierać go ręcznie. Pierwsza komenda zależna od manifestu, na przykład series list, automatycznie sklonuje repo edu-workspace/workspace-info, jeżeli lokalnej kopii jeszcze nie ma:

./rvctl series list

Jeżeli chcesz jawnie odświeżyć istniejący manifest, użyj:

./rvctl workspace sync

Przed pobieraniem kart warto jeszcze sprawdzić stan tokenów:

./rvctl tokens compare

Przykładowy wynik:

fiz  3  0
inf  3  0

Po wybraniu serii inf wylistuj karty:

./rvctl series cards list inf

Przykładowy wynik zawiera krótką nazwę karty, pełną nazwę repo, status i tytuł:

bss  lab-rv32i-strlen-bss-data-stack  source  rv32i-c / bss-data-stack

Przykładowa karta bss odpowiada repo lab-rv32i-strlen-bss-data-stack. Pobierz ją do workspace:

./rvctl series cards fetch inf bss

Karty trafiają do series w workspace:

~/dev/workspace/rv
├── meta
│   └── workspace-info
├── tools
│   └── rv-launcher
├── tokens
│   └── tokens.json
└── series
    └── inf
        └── lab-rv32i-strlen-bss-data-stack

rvctl pracuje na kartach z series_root, czyli na katalogu ~/dev/workspace/rv/series.

Po pobraniu karty rvctl przygotowuje też remote odpowiedzi r1a. Remote powstaje z tokena r1 i wskazuje na repo pracy:

answer_remote  r1a
answer_org     c2025-1a-inf
answer_repo    lab-rv32i-strlen-bss-data-stack
answer_url     http://77.90.8.171:3001/c2025-1a-inf/lab-rv32i-strlen-bss-data-stack.git

Następnie wylistuj zadania w karcie. Skrót tasks działa na domyślnej serii i karcie z workspace.json, czyli tutaj na inf bss:

./rvctl tasks list

Przykładowy wynik:

inf  bss  task1_bss           ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task1_bss.c
inf  bss  task2_data          ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task2_data.c
inf  bss  task3_stack_unused  ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task3_stack_unused.c
inf  bss  task4_stack_strlen  ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task4_stack_strlen.c

Przełącz się na wybrane zadanie. rvctl bierze login ucznia ze store tokenów, tworzy branch pracy w formacie <login>T<numer_zadania>a i ustawia mu upstream na r1a/<branch>:

./rvctl tasks switch 4

Dla użytkownika u1 i zadania task4_stack_strlen branch będzie miał nazwę:

u1T4a

Kolejny krok: kontenery i debugowanie

Kontenery są potrzebne dopiero po pobraniu karty pracy, kiedy chcesz uruchomić albo debugować konkretne zadanie. rvctl korzysta z narzędzia rv32i-hazard3-student-env, które trafia do workspace pod:

~/dev/workspace/rv/tools/rv32i-hazard3-student-env

Najpierw sprawdź dostępne profile i pobierz albo odśwież repo środowiska:

./rvctl env list
./rvctl env sync

Po synchronizacji workspace ma dodatkowe narzędzie pod tools:

~/dev/workspace/rv
├── meta
│   └── workspace-info
├── tools
│   ├── rv-launcher
│   └── rv32i-hazard3-student-env
├── tokens
│   └── tokens.json
└── series
    └── inf
        └── lab-rv32i-strlen-bss-data-stack

Środowisko ma dwa profile:

  • rv32i - Hazard3/RISC-V, gdb-multiarch, nvim i tmux,
  • host - natywne uruchamianie i debugowanie C przez clang albo gcc, gdb, nvim i tmux.

Zbuduj potrzebne obrazy:

./rvctl env build rv32i
./rvctl env build host

Dla pobranej karty inf bss możesz uruchomić debugowanie w obu profilach:

./rvctl debug rv32i 4
./rvctl debug host 4

Profil host ma też szybkie uruchomienie bez sesji debuggera:

./rvctl run host 4

Szczegóły komend, warianty --dry-run, --instance, --editor i ograniczenia profili są w doc/containers.md.

Dokumentacja

  • doc/rvctl.md - techniczna dokumentacja CLI: wszystkie komendy, argumenty i przełączniki
  • doc/tokens.md - model tokenów, format tokens/tokens.json i synchronizacja remote <-> store
  • doc/series.md - docelowy model komend dla serii i kart pracy
  • doc/containers.md - docelowy model komend dla środowisk kontenerowych
  • doc/agents.md - wnioski i plan późniejszej integracji agentów z kontenerami
  • doc/workspace.md - krótki opis konfiguracji workspace

README jest tylko mapą projektu. Szczegóły operacyjne trzymamy w doc/, żeby nie dublować instrukcji w kilku miejscach.

S
Description
stemctl workspace, container and lesson session control plane
Readme 279 KiB
Languages
Python 99.9%
Shell 0.1%