3.8 KiB
Design Rationale — gitea-reports
Miksi gitea-reports on rakennettu näin. Periaatteet, jotka pitävät arkkitehtuurin koossa. Teknologiavalinnat ovat näiden periaatteiden seurauksia — eivät erillisiä preferenssejä.
Tämä dokumentti on normatiivinen. Arkkitehtuurin tulee noudattaa sen periaatteita. Ehdotus, joka on ristiriidassa dokumentin kanssa, on konflikti — ei hiljainen ohitus.
The problem this solves
CI-testiajoista syntyy HTML-raportteja. Gitea ei tarjoa web-selaimella selattavaa arkistoa näille raporteille.
Vaihtoehdot eivät sovi:
- Gitea Actions artifactit: vain ZIP-lataus — HTML ei renderöidy selaimessa
- Gitea pages-branch: yksi branch per repo; rinnakkaiset buildit törmäävät
- Gitea Releases: sotkee julkaisuhistorian sadoilla CI-buildien raporteilla
How this is solved
Yksi klusteri, yksi apex-host, monta Gitea-repoa. URL on suoraan FS-polku:
/{owner}/{repo}/{branch}/{sha8}/{suite}/. Ei rewritea, ei subdomain-per-owner,
ei slugia.
Palvelu on read/write -jaettu: luku ja julkaisu eri sovelluksilla, eri porteilla, eri Traefik-säännöillä.
Why selvä URL + Gitea-yhteensopiva polku
Repo tunnistetaan polusta /{owner}/{repo}/..., ei hostista. Kaikki URL-taso
(branch, sha8, suite) on suoraan FS-polku. Tämä mahdollistaa yhden TLS-sertifikaatin,
yhden IngressRouten ja URL:n, joka on suoraan kopioitavissa commit-statusiin ilman
rewritea.
Hylätty: subdomain-per-owner ({owner}.pages...). Vaati per-owner Traefik-
rewritea ja wildcard-TLS:ää. Julkaisu-URL ja luku-URL olivat eri muodossa — kehittäjälle
vaikea ymmärtää ja debugata.
Why luku ja kirjoitus eri sovelluksilla
Yksi binary, joka palvelee sekä lukua että kirjoitusta samassa prosessissa, on yksinkertainen mutta yhdistää kaksi eri asiaa. Tässä arkkitehtuurissa nginx palvelee staattisia tiedostoja; Python-skripti purkaa tar.gz-julkaisun PV:lle. Ne eivät tiedä toisistaan.
Luku ei tarvitse julkaisulogiikkaa. Julkaisu ei tarvitse optimoitua staattista palvelua. Erottamalla ne kumpikin voidaan valita parhaaseen tarkoitukseensa.
Why security klusterin reunalla — ei sovelluksessa
Sovellus on "tyhmä": se palvelee mitä PV:llä on ja kirjoittaa mitä sille annetaan. Valtuutus tapahtuu yksinomaan Traefik BasicAuth -middlewaressa.
Tämä mahdollistaa:
- Julkaisu- ja lukuoikeuksien erillisen hallinnan eri Traefik-säännöillä
- Sovelluksen vaihtamisen ilman turvallisuusauditointia
- Token-rotaation ilman sovelluksen uudelleenkäynnistystä
Hylätty: sovelluksen sisäinen forge-auth (Gitea PAT, DNS TXT -haaste).
Sitoo sovelluksen tiettyyn autentikointimekanismiin ja vaatii laajat oikeudet
(write:repository) pelkkää raporttijulkaisua varten.
Why retention erillisenä CronJobina
Retention ei tarvitse olla aina käynnissä — se ajetaan kerran vuorokaudessa. CronJob lukee PV:tä suoraan (find, ls, stat), ei HTTP API:n kautta. Tämä pitää retention poissa podin kriittiseltä polulta (luku/julkaisu).
Hylätty: sidecar samassa podissa. Sidecar kuluttaa resursseja aina, ja retention-logiikka sekoittuu julkaisu- ja lukukoodiin.
Why yksi token, kaksi säilöä
Sama plaintext-arvo: htpasswd-hashina K8s Secretissä (Traefik lukee), plaintextina Gitea Actions Secretissä (julkaisija lukee). Yksi rotaatio päivittää molemmat.
Token antaa vain julkaisuoikeuden tähän palveluun — ei Gitea PAT:ia eikä
write:repository-oikeutta.
Why PVC suoraan FS-muodossa
Ei objektivarastoa, ei HTTP API:a retentionille. Sisältö on suoraan luettavissa kubectl exec + ls/find. Yksinkertaisin mahdollinen tallennusmuoto. Yksi replica, ei synkronointia.
References
- architecture.md — komponentit ja vuokaavio
- tech-stack.md — teknologiavalinnat listana
- secrets.md — secret-arkkitehtuuri ja käyttöönotto