This is an old revision of the document!
Tema 2 - Yellow Submarine
* Publicare:
* Termen de predare:
* Changelog:
Obiective
construirea unei distribuții Linux complete (cu aplicații)
build workflow cu Yocto
folosirea layerelor, adăugarea de pachete necesare unei aplicații concrete
configurări de bază pentru o rețea
scripting și folosirea utilitarelor dintr-un sistem Linux
optimizări de spațiu folosit (opțional)
TLDR: Am pus pus la dispoziție o
mașină virtuală cu build-ul de Yocto finalizat pentru imaginea de bază.
Dimensiune arhivă de descărcat:
~19GB
; dimensiune dezarhivată:
32GB
(țineți cont: unele utilitare de dezarhivare folosesc un director temporar pe partiția
OS-ului!).
De preferat ar fi să o descărcați cât mai curând, chiar dacă nu vă apucați acum de temă, deoarece va consuma timp ;)
Story / Enunț
Suntem într-un submarin (galben, OFC) în căutarea unor artefacte pierdute ale Elfilor lui Moș Crăciun (this year's Advent of Code :P ).
Presupunem că acesta este dirijat de un sistem embedded ce rulează Linux (sorry, Santa) ce primește comenzi de pe un dispozitiv mobil printr-o interfață RESTful și afișează date de la senzorii de locație / radar pe o consolă serială (pe bază de texte ASCII și codificări de terminal ANSI).
Va trebui să realizați un sistem embedded Linux folosind Yocto ce va expune un server HTTP cu API REST-ful (detalii / specificație mai jos) pentru primirea de comenzi / date de la senzori și va afișa planșa cu starea curentă pe o consolă serială.
Pentru aceasta, dorim să creați o interfață cât mai prietenoasă care să permită afișarea unor grafice ASCII Art cu poziția submarinului și alte obiecte detectate (e.g., artefacte, pești, mine) de către senzorii interni (ipotetic).
Un exemplu de interfață și interacțiune prin HTTP poate fi văzut în captura de mai jos (asciinema):
Cerințe
Imaginea Linux de bază:
-
Sistemul trebuie să ruleze în QEMU, folosind
un kernel compatibil (ori obținut prin Yocto pentru machine type
qemuarm
);
Sistemul trebuie să aibă un utilizator root
cu parola labsi
(obligatoriu!!);
Sistemul trebuie să aibă hostname-ul tema2
;
Sistemul trebuie să își configureze automat IP-ul folosind DHCP pe singura interfață disponibilă;
Sistemul trebuie să ruleze SSH pe portul 22;
Sistemul trebuie să ruleze daemon-ul Avahi/mDNS și să răspundă la numele tema2.local
.
RESTful HTTP endpoint:
Sistemul va trebui să ruleze un server http (pachet la alegere) ce să asculte după cereri HTTP bine definite de manipulare a obiectelor lumii virtuale (specificate mai jos);
Puteți folosi orice limbaj de programare / scripting / framework pentru a construi acest endpoint; exemple:
-
-
PHP: well… cam e făcut pentru așa ceva, dar va trebui să faceți
URL rewriting pe serverul http :P;
Golang:
net/http (aici nu se justifică să descărcați altceva);
Rust:
http (built in, baby!);
-
Alegeți ceva ce doriți să învățați sau ce vă este cel mai familiar și căutați-i layerul / pachetul de Yocto pentru instalare facilă ;)
Display daemon:
Pe lângă serviciul web, va trebui să dezvoltați un program responsabil să afișese textual pe o consolă serială conectată la tty0
(emulată, conectată la stdout-ul qemu);
Programul va afișa în mod dinamic (timp real, însă e OK și la 1 fps) o artă
ASCII de îndată ce aceasta este încărcată și să o afișeze în consola.
La fel ca la serviciul web, puteți folosi orice limbaj + biblioteci de desenare pe consolă doriți, exemple:
Este recomandat ca programul de afișare să ruleze ca proces separat față de endpointul web (altfel vă veți confrunta cu probleme de sincronizare între threaduri în majoritatea limbajelor). Puteți face comunicarea între cele 2 procese prin orice mecanism vă pune Linux / limbajul la dispoziție (hint: tmp file system FTW);
Nu uitați să faceți acest program să pornească la startup (i.e., daemon sau serviciu de init) și să afișeze la consola tty0
(e.g., să redirectați file descriptorii standard)!
Folosiți culori distincte pentru desenarea obiectelor pe planșă; și să scoateți cursorul…
Cât despre design-ul obiectelor, aveți libertate deplină (cât timp se înțelege ce este :D); fără obscenități, though (puteți să le faceți easter egg ;) )!
Contract (API)
Sistemul va gestiona o serie de obiecte prezente pe planșa de detecție:
1 submarin (fix o instanță);
animale acvatice (fish) - listă de maxim 5 obiecte;
cel mult un artefact special (poate să lipsească, desigur);
Fiecare obiect are o poziție dată de x
(coloana) și y
(linia din terminal). Atenție: se folosește convenția lui ncurses
, adică sistemul de coordonate pornește cu (0, 0)
din colțul stânga-sus al consolei!
Astfel, se definesc următoarele endpointuri RESTful HTTP (atenție: API-ul este strict!):
GET /api/submarine
: va returna un JSON cu poziția actuală a submarinului (e.g., {“x”: 1, “y”: 5}
);
POST /api/submarine/move
: va comanda submarinul să-și schimbe poziția cu un obiect delta. Formatul este JSON: {“x”: deltaX, “y”: deltaY}
); atenție: se pot primi și valori negative (e.g., {“x”: -1}
va muta submarinul la stânga 1 poziție);
GET /api/fish
: va returna un JSON cu lista actuală de pești detectați (e.g., [{“x”: 10, “y”: 3}, {“x”: 20, “y”: 10}]
);
POST /api/fish/add
: va adăuga un nou pește la listă; format JSON: {“x”: posX, “y”: posY}
); atenție: dacă lista ajunge să aibe mai mult de 5 elemente, ștergeți-l pe cel mai vechi!
GET /api/artifact
: va returna poziția artefactului curent (e.g., {“x”: 10, “y”: 3}
sau {}
dacă nu este definită);
POST /api/artifact/update
: înlocuiește poziția artefactului curent; format clasic: {“x”: posX, “y”: posY}
sau {}
(i.e., nici unul pe raza actuală de detecție);
Toate cererile vor folosi formatul Content-Type: application/json
atât la input (pentru cererile POST
), cât și la răspuns.
Tema va fi testată în QEMU (v5.0+ sau v2.12+ pe Ubuntu 18.04) pentru placa versatilepb
sau virt
(pentru build-urile Yocto cu machine type qemuarm
).
Pentru ușurința navigării pachetelor puteți folosi interfața grafică Toaster pentru a construi imaginea. Puteți pleca de la imaginea de bază pentru RaspberryPi (core-image-base
).
Helpers + Mașină virtuală
Ca și punct de pornire, puteți descărca un schelet inițial cu scripturi + structură recomandate (v0.1).
Aceasta conține:
script de make pentru generarea arhivelor cerute;
script de rulare qemu recomandat;
script de configurat virbr0
pentru qemu;
un kas.yml
de pornire;
un script de testat soluția folosind curl (test.sh
);
un README pe care ar fi util să-l citiți ;)
un director gata creat tema2
pentru layerul de Yocto custom, pentru a vă scuti de efortul unui mkdir
în plus ;)
alte fișiere ce trebuiesc completate și incluse în arhiva cu sursele!
Important: citiți codul sursă al scripturilor și verificați (e.g., căile) să fie adecvate setup-ului vostru!
Dacă aveți setup-ul funcțional din cadrul laboratorului de Yocto, puteți să folosiți distribuția compilată de atunci. Atenție la kas.yml
(dacă doriți să-l păstrați pe cel din laborator, să nu îl înlocuiți!).
Notă: dacă optați pentru varianta cu VM-ul descărcat de mai jos, va trebui să adăugați manual scripturile și acolo (deoarece nu au fost incluse) + câteva apt install
-uri (s-au uitat :D).
Pentru orice VM: dacă doriți să folosiți bridging cu interfața virtuală spre stația fizică, va trebui să activați Promiscuous Mode pentru adaptorul de rețea folosit (e.g., VMWare NAT / Bridge). Soluția pentru a face asta, din păcate, diferă în funcție de hipervizor / sistem de operare, deci Google-first apoi întrebați un asistent :D
As always, se recomandă să folosiți ultima versiune de VMWare Workstation (dacă aveți nevoie de snapshot-uri) pe care îl puteți descărca cu
licență din partea facultății ;)
Dacă nu ați reușit să compilați Yocto la laborator, puteți folosi, ca punct de plecare, un VM pus la dispoziție de noi (precizare: trebuie descărcat și rulat):
-
spațiul ocupat în interiorul VM-ului este de 25GB
, deci tot ce este ocupat acum ar fi suficient și în timpul compilării layere adiționale Yocto
Autentificare pe VM: user student
, parolă student
;
Fișierele Yocto (working directory-ul) le găsiți în /home/student/yocto
.
Nu mai este necesar Docker, (aproape :D) toate utilitarele fiind instalate direct în VM!
de asemenea, aveți creat un snapshot la VM cu starea lui inițială, folosiți dacă stricați ceva (NU UITAȚI să vă faceți backup la sursele soluției voastre înainte!).
Atenție: unele utilitare de dezarhivare (mai ales pe Windows) folosesc director temporar pentru a decompresa imaginea mai întâi pe partiția unde e instalat
OS-ul, așadar asigurați-vă că aveți suficient spațiu liber și acolo (apoi va fi mutat).
Se recomandă folosirea unui SSD ca mediu de stocare al VM-ului (pentru viteză sporită).
Trimitere
Soluția temei va fi trimisă în două moduri:
arhivă cu codul sursă + Readme + hash și alte metainformații (vedeți mai jos) → pe Moodle
arhivă cu binarele rulabile → pe orice platformă de hosting doriți (ex: Dropbox, Google Drive, WeTransfer etc.)
Arhiva cu binarele (.tar.gz
pls) trebuie să conțină (de preferat să folosiți strict aceste denumiri de fișiere):
rootfs.img
: imaginea partiției rootfs în format RAW utilizabil de qemu (ori partiția ext4, ori disk image);
kernel-*
: imaginile kernel-ului compatibil cu QEMU (scheletul îl folosește pe cel din Yocto);
versatile-pb.dtb
sau orice alt device tree blob (dacă sunt necesare pentru rulare în Qemu);
launch.sh
: script de pornire QEMU (vedeți scheletul dat);
Dacă doriți să ne prezentați alt scenariu demonstrativ (decât cel inclus în schelet), includeți un script numit test.sh
.
NU INCLUDEȚI: directorul build cache al yocto (yep, acela de > 20GB!);
Această arhivă nu ar trebui să depășească 500MB
(și asta în cazuri extreme).
Arhiva cu fișierele sursă (.zip
pls) este OBLIGATORIU să conțină:
scripturile proprii de Yocto (layer, rețete, configurații) + sursele aplicației (în orice limbaje ați ales);
fișier README
cu explicații referitoare la funcționarea soluției, opțiuni speciale de configurare/optimizare folosite etc.
fișier
URL
(fără extensie!) cu
URL către arhiva
.tar.gz a binarelor;
fișier CHECKSUM
(fără extensie!) care să conțină hash-ul SHA256 al arhivei cu binarele (obținut cu sha256sum
); ATENȚIE: verificați și re-verificați (de încă 2 ori) conținutul fișierului la încărcare pe Moodle cu hash-ul real deoarece tema nu va fi punctată dacă diferă!
NU INCLUDEȚI: fișiere sursă ale Poky / alte layere Yocto / biblioteci / frameworkuri descărcabile de pe Internet (menționați în Readme ce ați folosit); puteți include bblayers.conf și local.conf dacă le-ați modificat manual (în afara kas
).
Această arhivă nu ar trebui să depășească 1MB
(aveți restricție pe Moodle).
Un Makefile pentru generarea arhivelor este prezent și în arhiva cu scheletul inițial recomandat al temei, însă se recomandă verificarea manuală a arhivelor!
Nu vor fi punctate temele care nu au hash-ul SHA256 al arhivei încărcat pe Moodle sau cele al căror hash nu corespunde cu arhiva downloadată de pe platforma de hosting la momentul corectării!
Notare
Din 100p total, aveți:
Bonus:
(10p) Optimizări deosebite de spațiu ale imaginii finale (cele mai mici 5 imagini primite, doar dintre cele care implementează toate funcționalitățile);
(5-10p) Extra features / good practice (design plăcut, eleganță în implementare etc.);
Precizări
Tema are deadline HARD (nu mai sunt admise soluții după expirare), așadar se recomandă să vă apucați din timp de rezolvarea acesteia!
Compilarea unei imagini cu Yocto necesită 40GB+ spațiu liber pe disk;
Prima compilare poate dura intre 0.5 si 10 ore în funcție de performanța calculatorului (procesor + I/O) + viteza rețelei (un SSD ajută enorm!);
Compilările ulterioare vor refolosi majoritatea pachetelor generate (cache) și vor dura mult mai puțin (1 - 30min, depinde de ce layere noi se adaugă în plus);
ATENȚIE: orice formă de plagiat nu va fi permisă și va duce la depunctare totală / restanță /
that which must not be named, the E-word!
Pe Moodle găsiți și
un forum ;) La fel pe Teams, avem un canal de discuții.
Resurse