Programozás - kezdő

Jenkins, Kubernetes kérdés

N Jenkins munkával, M párhuzamosra generált Jenkins stage-ekben helm chart csoportok telepítése avagy létezik-e kubernetes shared queue?

Sziasztok!

Egy érdekes problémába futottam bele Kubernetes, Jenkins, helm chart témakörben.

Adott egy szoftver ami microservice-ekké lett átalakítva, a különböző egységei mind különböző helm chart-ok.

Egy teszt-automatizálási rendszert készítettem - Adott sok-sok yaml amely tulajdonképpen a termék különböző lehetőségeit tartalmazza, a rendszer gyakorlatilag ezekből a változókból generál values file-okat a helm chart-ok részére telepítés céljából.

Egy teszt nem más, mint egy csoportja a helm chart-ok telepítésének (majd további teendőket végez), nyilván a változóknak megfelelően beállított telepítést eredményezve. Mindegyik "helm chart csoport" multi-tenant jelleggel, különböző namespace-ekbe kerül, így nem különösebben zavarják egymást.

Jenkins, amikor ezt a teszt-automatizálási feladatot lefuttatja, sajnos mivel nincs végtelen erőforrás, nem telepíthet párhuzamosan "végtelen" tesztet, azaz a helm chart-ok csoportját.

Mivel a Jenkins-ben a parallel stage nem korlátozható könnyedén, én ezt a feladatot egyelőre (később majd automatizálom) konkrét számú (úgyis 99%-ban egyelőre X erőforrás kell nekik szóval később ráér számolgatni), egy LinkedBlockingQueue-val oldottam meg, amelynek segítségével igaz, hogy 1 Jenkins munkafeladat 200 tesztet szeretne futtatni, egy időben a LinkedBlockingQueue miatt, csak Integer maxParallel-t fog egy időben telepíteni, tekintve, hogy nem szeretném hogy a telepítések a sorrendbeli telepítés miatt úgymond "deadlock"-oljanak. Ilyen deadlock lenne, ha mondjuk 200-szor próbálja telepíteni a helm chart csoport első elemét, és tegyük fel épp a 147-ig jut el, mire kifogy az erőforrásból, és hát az első 147 nem tudja folytatni a második chart telepítésével, a többi pedig az előző befejezésére vár hogy az elsőt telepítse - itt pedig a deadlock, egymásra várnak. Tehát ezt ezzel a LinkedBlockingQueue-val sikerült megoldani, viszont ez csak az egyik fele a problémának.

Nyilván van az az eset, hogy nem 1 Jenkins munka kér 200 tesztet, hanem mondjuk 200 kér 300-at, azaz N Jenkins feladat kér M tesztet.

A probléma viszont az, hogy adott Jenkins feladatnak fogalma sincs hogy az épp előtte sorban álló (vagy épp konkurrensen futó többinek) még mennyi terve van hogy telepítsen és abból is, mennyi helm chart-ot. Erre jönne jól, ha nem a Jenkins feladat uralná a queue-t, hanem mondjuk a kubernetes, azaz, hogy ha a Kubernetes-ben lenne egy úgymond shared queue, ahol a tesztek nevei és a Jenkins munkák kezdeti időpontjai hogy a sorrend különböző branch-ekből meghívásra is választ adva működjön (JobId nem lenne szerencsés ugye).

Ergo oké, hogy a LinkedBlockingQueue adott Jenkins-ben működik, csak hát a Jenkins feladatok egymás között kellene hogy ismerjék a Queue-t.

A "helmfile" nem megoldás;

Egy Kubernetes-ben létrehozott "locking megoldás" addig amíg egy adott feladat a queue-t lekérdezi hogy hány névtér került már létrehozásra (pl. ezzel ki lehetne szűrni hogy hány teszt fut épp) szintén elég gáz megoldás lenne több szempontból is.

Egyelőre lehet tekerni az erőforrásokon: megfelezem adott Jenkins feladat queue-ját és 2 párhuzamos feladatot engedek be Jenkins-el. Ez viszont nem igazából skálázható, nem is natív és ráadásul elég problémás ha egy adott teszt időben túl hosszú ideig fut és emiatt az adott queue üresen áll, miközben a többi pedig rá vár.

Ennél még a Jenkins node-ok is jobban teljesítenek, igaz, ott a queue-t a Jenkins maga uralja, ahol az adott Node-ok Executor-okkal oldják ezt meg.

Arra is gondoltam, hogy a Kubernetes-t nem "Cloud"-ként állítom be, hanem Node-ként és "hadd SSH-zzon bele aztán futtasson PodMan-el egy konténert", de ezt "talán inkább hagyjuk".

Rátaláltam a Kueue-ra, ezzel kapcsolatban az jutott eszembe, hogy lehet hogy egy meta-helm-chart-ot kellene generálnom ami függ az adott csoport tagjaitól, ergo ha a termék adott konfigurációja 5 chart-ot akar telepíteni, hozzak létre egy meta-helm-chart-ot amelyben a deployment-ek resource-ai listázva vannak és "egyként" adjam deployment-ként oda Kueue-nak.

Azt viszont látom hogy a kueue-t alapvetően "Job"-ra tervezték és nem helm chart-ra. Az is elég sajnálatos, hogy a Jenkins támogatása a Kubernetes pluginnal hírül sem olyan korrekt mint a Node-ok esetében.

Valakinek van erre ötlete?

[ Megoldva ] ZX-81 Load rutin értelmezése

ZX-81 ROM kódjából próbáltam megérteni, hogyan tölt be egy bájtot kazettáról, de nem sikerült. A kérdéses résznek az egy bit beolvasásának itt az assembly kódja:

;; GET-BIT
L0385:  PUSH    DE              ; save the.
        LD      E,$94           ; timing value.

;; TRAILER
L0388:  LD      B,$1A           ; counter to twenty six.

;; COUNTER
L038A:  DEC     E               ; decrement the measuring timer.
        IN      A,($FE)         ; read the
        RLA                     ;
        BIT     7,E             ; <<< Kérdéses: minek ez? A Z flag úgyis eltűnik, nem kerül felhasználásra
        LD      A,E             ;
        JR      C,L0388         ; loop back with carry to TRAILER

        DJNZ    L038A           ; to COUNTER

        POP     DE              ;
        JR      NZ,L039C        ; to BIT-DONE <<< Kérdéses: Ez sosem ugorhat el, mivel Z=1 akkor minek?

        CP      $56             ;
        JR      NC,L034E        ; to NEXT-BIT <<< Kérdéses: Ha ez elugrik, nem kerül C-be a beolvasott bit. Ha nem, akkor meg csak 0 kerüleht majd a C-be. Akkor hogyan kerület 1-es bit a C-be?

;; BIT-DONE
L039C:  CCF                     ; complement carry flag
        RL      C               ;
        JR      NC,L034E        ; to NEXT-BIT

        RET                     ; return with full byte.

A kód elvileg a C-ben gyűjti a biteket. ZX-81 alatt minden bit előtt van egy hosszú bevezető szünet a kazettán, a NEXT-BIT azt ugorja át, majd jön ide a konkrét bit beolvasásához. A bitek betöltése csak ebben a kiemelt kódrészletben kellene, hogy megtörténjen.

A legfőbb kérdés, hogy hogyan kerül 1-es bit a C-be? (Szerintem sehogy, de a valóságban mégis.) A másik két kérdés csak olyan utasításokra vonatkozik, amiket nem értek, mit keresnek ott.

A kérdéseket jelöltem a forrásban is.

Ha valaki el tudná magyarázni a kód működését pontosan, annak örülnék, mert én nem értem.

A teljes forrás több helyen is megtalálható a neten. A teljes LOAD parancs kódja a 0x0340 címtől kezdődik.

Megoldás: A DJNZ nem állítja a Z flaget.

[ Megoldva ] Arduino: gzip olvasása a teljes fájl kitömörítése nélkül

Miután az AI mondott három - egymásnak természetesen ellentmondó - megoldást, és egyikkel sem sikerült, valamint az általam talált programok példái is csak a teljes fájlok kicsomagolását tartalmazták, remélem, van itt valaki, aki már csinált ilyet, és el tudja mondani, hogyan is kellene.

Ha jól tudom, a gzip pont ilyen tömörítő, ami kisebb csomagokban röptében írható és olvasható is.

Alternatív megoldásként szóba jöhet más, nem egzotikus tömörítés is, amivel ezt könnyen el lehet játszani.

[ Megoldva ] Flock és fork pontos működése?

Készítettem egy scriptet, ami az aktuális mappában létrehoz egy lock fájlt, és egy -TERM szignálig nyitva is tartja, majd lezárja és letörli. Az elindított script megpróbálja létrehozni a lock fájl. Ha sikerül neki, kiírja a PID értékét, amit a kill parancsnak meg kell adni a zárolás feloldásához, és visszatér 0 értékkel. Ha TIMEOUT másodpercig nem sikerül, akkor visszatér 1 értékkel.

Parancssorból futtatva jól működik, de egy másik bash scriptből hívva a scipt futását megállítja. Pontosabban, ha úgy hívom meg, hogy a visszaadott PID értékét elteszem egy változóba, akkor fagy csak be. Azaz V=$(script) vagy V=`script` soroknál. A lock fájl ugyan  létrejön, de a script futása megáll legelső futtatásra is.

#!/bin/bash
TIMEOUT=3
LOCKFILE="./file.lock"

function wait_for_signal() {
    trap "rm $LOCKFILE" SIGTERM
    until false ; do
        sleep 1
    done
}

touch $LOCKFILE
exec {FD}<>$LOCKFILE
if ! flock -x -w $TIMEOUT $FD; then
    exit 1
else # Lock acquired
    wait_for_signal &
    echo $!
    exit 0
fi

Megírtam ez a scriptet perl-ben is, a perl saját lock-jával és forkjával, és pont ugyanígy működik.

Ezek szerint nem értem pontosan a lock és/vagy a fork működését, vagy valamit nem tudok.

Tudtok segíteni benne, mi a hiba, mitől fagy be egy scriptbe ágyazva a programom, és hogyan tudnám elérni, hogy scriptből hívva ugyanúgy jól működjön, mint parancssorból?

( Kérem az AI-copy válaszok mellőzését, azon már túl vagyok. )

[ Megoldva ] OpenScad nagyon lokális változók?

A következő openscad kódnak 100 kockát kellene kirajzolni, de csak tízet rajzol ki. Miért?

module teszt() {
    for( y = [ 0 : 9 ] ) {
        center_y = y * 11;
        center_x = 0;
        for( x = [ 0 : 9 ] ) {
            translate( [ center_x, center_y, 0 ] ) cube( [ 10, 10, 10 ], center=true );
            center_x = center_x + 11;
        }
    }
}

teszt();

Nem arra keresem a választ, hogy hogyan tudnék 100 kockát kirajzolni, hanem arra, hogy ez a kód miért csak tízet rajzol ki?

Ráadásul az X=11 oszlopban, függetlenül attól, hogy az összeadás a cube előtt vagy után van.

keresek valamit a böngésző előzményekben

Időnként előfordul, hogy valami olyan weboldalt szeretnék megnézni megint, amit valamikor korábban már megnéztem, de nem emlékszem a nevére. Eddig egy módszerem van erre: megnyitom a böngészőben a history-t, ami kilistázza időrendben, hogy miket néztem meg. Ez néha elég, ha pl. tudom, hogy melyik napon, vagy néhány napon nézhettem meg azt, amit keresek, de vacakolós, mert egy csomó minden szemét is benne van.

Most jutottam el arra a pontra, hogy szeretnék valami eszközt, amivel hatékonyabbá tehetem a keresgélést.

Ha van valami kész megoldásotok, amit ilyesmire használtok, nyugodtan mondjátok.

Ha nincs, akkor segítsetek, információval.

Pl. nézzük a mostani keresést: egy szülinapi bulin (2024 június vége) a fiamnak valaki mesélt egy olyan weboldalról, amit programozók közössége rakott össze, ingyenes, és alapoktól programozni tanít. Valamikor azóta egyszer rákerestem a névre. Megnyitottam, láttam, hogy weboldal összerakásával kezd, CSS-re meg Javascriptre emlékszem, aztán voltak más feladatok, más programnyelvek, kb. a leckék 3/4-énél pl. láttam Python-t és valami adat feldolgozásféle dolgot. Azt is írták, hogy a feladatok sikeres megoldása után ingyenes tanúsítványokat lehet szerezni, ami egy pályakezdőnek, mint a fiam, jól jönne. Azóta elfelejtettük a weboldal nevét.

Gondoltam, hátha a böngészőbe beírva a code szót, majd feldobja a Firefox az előzményeket. De amit feldobott, azok között nem volt semmi hasznos. Chrome-ban is próbáltam, az a címsorba írva nem kínál előzményeket, szóval zsákutca. Javasoltak többet is, code camp, freecodecamp, code academy, és ezek hasonlónak tűnnek, de egyik sem az, amit korábban néztem. (Lehet, hogy teljesen jók, nem néztem meg annyira, azt láttam, hogy a code academy pl. ingyen ad pár tanfolyamot, de pl. tanúsítványokat nem).

Szóval arra gondoltam, hogy ha a Firefox* history-t valahol elérem (feltételezem, hogy lemezen tárolja valamilyen olvasható és elemezhető formában), akkor fel lehetne dolgozni valami scripttel. Pl. keresni szűrni dátumokra, kiszűrni az ismétlődéseket (egy csomó olyan oldal van, ami minden nap bekerül a history-ba, részben emiatt igen nehézkes szabad szemmel keresni), kiszűrni azokat a mintákat, amik biztos nem jók és sok van belőlük, pl. nem youtube.com, hup.hu, gmail.com, stb.

Szóval ha valaki tudja, hogy 1) hol van a history eltárolva, 2) hogyan kell olvasni/értelmezni a fájlt (ha fájl), 3) esetleg a sima sed, grep, sort, uniq, és hasonló parancsokon kívül mivel tudnám hatékonyabban feldolgozni, az írja meg!

4) ha tudjátok, mi az a weboldal, amit elfelejtettünk, azt is megírhatjátok, de azért a módszert szeretném tudni, mert nem akarok legközelebb is írni.

* Chrome-ra ugyanez jó lenne, bár sokkal kevesebbet használom, de nem lehet kizárni, hogy épp abban nyitottam meg valamit.

Unicredit bank tranzakciók

A céges számla a CIB-nél volt évekig. A bejövő utalások automata könyvelését úgy oldottam meg, hogy a telefonomon be volt kapcsolva az értesítés minden jóváírásról. A CIB app notification-jeit egy Automate script kiszedte, és http-n postolta egy szervernek, ami meg csinálta amit kell (beírta saját nyilvántartásba, kiegyenlítette a számlát a számlázó adatbázisában, illetve küldött emailt az ügyfélnek a lekönyvelt összegekről és kiegyenlített számlákról). Fine.

Váltottunk Unicredit-re. A probléma, hogy itt a jóváírás push notification-ben nincs semmi infó, csak annyi hogy incoming transaction, se összeg, se komment, így ezzel nem tudok mit kezdeni. Néztem az Unicredit API-ját (https://developer.unicredit.eu/apis-catalog), ehhez egyrészt kevésnek érzem magam, másrészt azt sem tudom, hogy ez működik-e az én esetemben (nem kell-e hozzá valami spéci szerződés, vagy csak nagyoknak jár, stb).... Valaki esetleg csinált már ehhez bármilyen interfész? Valami egyszerű példát tudtok adni?

Vagy más egyéb kerülő (az eredetihez hasonló), de működő megoldás? :)

[ Megoldva ] Tinkercad típusú script nyelv létezik?

Nem vagyok jártas a CAD programokban, de egyszerűbb 3D objektumok összerakásához a tinkercad megközelítése nekem kezdőnek is nagyon jól használható. Egyszerű alap objektumokból, mint hasáb, gömb, gúla, méretezéssel, összeolvasztással és kivágással már egészen jó tárgyakat sikerült létrehoznom.

Olyannyira kezelhetőnek látszik ez a megközelítés, hogy nem lepne meg, ha már létezne egy ilyen script nyelv is, amin ugyanezzel a módszerrel leprogramozhatnék tárgyakat. Kerestem ilyen nyelvet, de sajnos még nem találtam. A tinkercad oldalán vizuálisan még programot is lehet készíteni, ami generál 3d objektumokat, de csak a végeredmény tölthető le.

Létezik egyáltalán 3D objektumokat ilyen módon generáló script nyelv?

ESP8266 http POST kérés nem megy...

Sziasztok!

Csináltam egy ESP8266 alapon egy 5 csatornás hőmérsékletmérő eszközt, ami WiFi-n HTTP POST-al tolná
föl az adatokat egy szerverre. (Arduino framework, Platform.IO)
Nem értem, a válasz a POST kérésnek:
"HTTP Response code: 400" - tehát valami szintaktikai hiba lehet?! Már a szemem kifolyik, nem találom
a hibám.
Ez a programrész:

bool puthttp() {
    bool result = false;
    long rssi = WiFi.RSSI();
    String localip = WiFi.localIP().toString();
    WiFiClient client;
    HTTPClient http;

    char jsonstr[400];
    char jsonstr2[100];
    char jsonstr3[30];

    Serial.println(serverstr);

    snprintf(jsonstr, sizeof(jsonstr), "{\"device_id\":%d, \"ip_address\":\"%s\", \"ssid\":\"%s\", \"rssi\":%d, ",didx,localip.c_str(),ssidstr,rssi);
    snprintf(jsonstr2, sizeof(jsonstr2), "\"value_1\":%.1f, \"value_2\":%.1f, \"value_3\":%.1f, \"value_4\":%.1f, \"value_5\":%.1f, ",hom1,hom2,hom3,hom4,hom5);
    snprintf(jsonstr3, sizeof(jsonstr3), "\"timestamp\":%ld}", helyiUTC);
    strncat(jsonstr, jsonstr2, sizeof(jsonstr2));
    strncat(jsonstr, jsonstr3, sizeof(jsonstr3));

    Serial.println(jsonstr);

    // Your Domain name with URL path or IP address with path
    Serial.print("http.begin:");
    bool mi = http.begin(client, serverstr);
    
    Serial.println(mi);
    http.addHeader("Content-Type", "application/json");

    int httpResponseCode = http.POST(jsonstr);
    //int httpResponseCode = http.POST("{\"value\": 20 }");
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    http.end();
    if (httpResponseCode == 200) result = true;
    return result;
}

És ez a készített "jsonstr":
{"device_id":10170, "ip_address":"192.168.3.162", "ssid":"gentoom", "rssi":-62, "value_1":22.8, "value_2":-100.0,
"value_3":-100.0, "value_4":-100.0, "value_5":-100.0, "timestamp":1709045163}

Köszönöm!
Roland

Amatő C-program építő jellegű kritizálása

Sziasztok !

Én soha nem tanultam programozni semmilyen iskolában, mégis érdekel. Készítettem magamnak egy kis programot, amit egy megszerzett, régi kocsmai zenegépen használok. Nincs teljesen kész de működik.

Azt szeretném kérni, ha van egy kis időtök, nézzétek meg milyen ordas hibák vannak benne :-)

https://mega.nz/folder/r8shyDxY#g3DSqrBaedWYvK0Vqdicig

 

Előre is köszönöm.