Files
com_r35157_nenjim-hubd-impl…/docs/Nenjim.md
T

29 KiB
Raw Blame History

#

Nenjim
Documentation

Dokumentstatus: Journal-format version 1, den immutable Java-model, den interne tekstparser, det read-only JournalService med en Hub-styret procesimplementation, den passive eksplicit refresh-baserede JournalServiceManager, den Hub-styrede JavaFxRuntimeService, første version af det centrale component Registry og den obligatoriske format 1 Hub-konfiguration er implementeret. Contexts, resolution, discovery, runtime loading og removal er fortsat fremtidig funktionalitet.

Indholdsfortegnelse:

1. Introduktion til Nenjim

Nenjim skal på sigt kunne håndtere forskellige versioner af softwareartifakter samtidigt. Det nu implementerede fundament er Journal-laget: et strengt tekstformat og en immutable model, som kan fastholde, hvad der var kendt om en artifakt på et bestemt tidspunkt. Det første Registry kan desuden katalogisere de konstruerede componenter, og Hub-konfigurationen vælger den manuelt ordnede procesmængde. Dependency-resolution, Contexts, downloading og classloading kommer senere.

2. Versionering og Afhængigheder

Nenjim beskriver moduler, artifakter, releases, relationer og versionspolitik i Journaler. Almindelig Java-kode skal ikke indbygge Nenjim- eller versionsspecifikke navne for at bruge et API. Et Context beskriver de ønskede valg, og Nenjim resolver senere disse valg og Journalernes metadata til en eksakt artifakt- og dependency-graf.

2.1 Én Journal per artifakt

En Journal beskriver præcis én artifakt. API, tests og referenceimplementation har derfor hver sin Journal; roller som API, IMPLEMENTATION og TEST gemmes ikke som et TYPE-felt. Journalens identitet udledes af metadata:

<GROUP>-<MODULE>-<ARTIFACT>

Eksempelkoordinater er com_r35157_nenjim-hubd-api, com_r35157_nenjim-hubd-tests og com_r35157_nenjim-hubd-impl_ref. En komplet release-reference tilføjer en eksakt Semantic Version:

com_r35157_nenjim-hubd-api:1.0.3

Der findes intet separat JOURNAL_ID.

2.2 Metadata og release-indhold

[METADATA] indeholder coordinate-delene og en obligatorisk single-quoted DESCRIPTION. Den valgfrie INFORMATION_URI er også single-quoted, skal være en syntaktisk gyldig absolut URI, og kan bruge enhver scheme, for eksempel https:, ftp: eller ipfs:. Nenjim åbner eller fortolker ikke URI'en automatisk.

Hver [RELEASE major.minor.patch] indeholder sin egen single-quoted LICENSE, PUBLISHED_AT, CONTENT_SIZE og mindst én CONTENT_DIGEST. Format 1 accepterer valideret sha256 og CIDv1 (cid1). Licensen er fri tekst, gemmes uden normalisering og kan være forskellig mellem releases; fremtidig licensfiltrering er ikke implementeret.

2.3 Komplette snapshots og Journal-kæden

Hver Journal-fil er et komplet immutable snapshot af al aktuel viden om artifakten og dens kendte releases. En revision er aldrig en delta og arver intet implicit. En nyere revision kan ændre metadata, policy, dependencies og selv korrigere eller fjerne tidligere kendt release-information. Et no-op snapshot er også gyldigt.

JOURNAL_VERSION er et strengt stigende UTC-timestamp med millisekundpræcision:

uuuuMMddHHmmssSSS'Z'

Genesis-revisionen udelader PREVIOUS_JOURNAL_DIGEST. Hver efterfølger refererer til SHA-256 over forgængerens komplette UTF-8-tekst præcis som leveret, inklusive whitespace og linjeskift. Manglende forgængere, forks, flere genesis-revisioner, fremmede artifaktkæder og ikke-stigende versioner afvises.

PUBLISHED_AT er release-tid og er uafhængig af Journalens publiceringstid. Historiske queries vælger et helt snapshot ud fra Journal-kæden; de filtrerer ikke det nyeste snapshot efter PUBLISHED_AT.

2.4 Version expressions

En SemanticVersion (1.0.3) er én eksakt release. En VersionExpression beskriver et sæt acceptable releases:

  • 1.0.3 og [1.0.3] er samme eksakte selector.
  • [1.0] betyder hele den stabile 1.0.x-serie, ikke eksakt 1.0.0.
  • [1.0.3-->1.0.7] inkluderer begge grænser; ) ekskluderer øvre grænse.
  • [1.0-->1.2] inkluderer hele 1.2.x; [1.0-->1.2) gør ikke.
  • [1.0--> stopper før 2.0.0; (1.0--> starter ved 1.1.0.
  • Komma adskiller en union af expressions.

Endpoints skal mindst indeholde major og minor. Matematiske operatorer som >=, prereleases, build-metadata, tomme elementer, omvendte ranges og implicitte cross-major open ranges afvises.

2.5 Dependencies

Dependencies hører til en bestemt artifaktrelease og bruger altid en explicit scheme. Format 1 implementerer kun:

DEPENDS_ON=nenjim:com_r35157_nenjim-hubd-api=[1.0-->
EXCLUDES=nenjim:com_r35157_nenjim-hubd-api=1.0.5:'Known incompatibility'
PREFERRED=nenjim:com_r35157_nenjim-hubd-api=1.0.3:'Built together'

DEPENDS_ON er basissættet. EXCLUDES er en hård relationel begrænsning. PREFERRED er kun et hint og skal være en delmængde af DEPENDS_ON - EXCLUDES. Flere exclusion/preference-linjer for samme target kombineres som union, men deres individuelle beskrivelser bevares. Ukendte schemes, herunder maven:, afvises i format 1.

2.6 Artifact policy

Den valgfrie [POLICY] bevarer individuelle regler og beskrivelser:

  • BLACKLIST er en hård global regel: matchende releases må ikke vælges.
  • DISCOURAGED er et negativt hint: releasen kan stadig vælges.
  • RECOMMENDED er et positivt hint til én eksakt release, som findes i samme snapshot.

Overlap er tilladt, og hårde regler vinder over hints. En fremtidig resolver bør søge en gyldig graf med flest muligt kompatible anbefalinger; højeste versionsnummer er fallback, ikke en ubetinget regel. Det kan senere føre til konvergens fra en højere lokal release til en lavere anbefalet release, men den adfærd er ikke implementeret nu.

2.7 Parser og immutable model

Parseren kræver FORMAT_VERSION=1 som første faktiske entry, men tillader blanke linjer og #-kommentarer. # inde i single quotes er tekst. Quoted værdier understøtter \' og \\. Ukendte, malformed, duplikerede eller forkert placerede felter/sektioner afvises med source, linjenummer og årsag. Hele dokumentet valideres før servicens state ændres. Alle publicerede modeller og collections er immutable og defensivt kopieret.

2.8 JournalService, JournalServiceManager og disk-layout

En Service er det domæne-API, som applikationer og andre services bruger i daglig drift. JournalService er en registrerbar Nenjim component, men API'et er fortsat filesystem-uafhængigt og read-only: det kan vise coordinates, kronologiske revisionslister, latest, exact og newest-at-or-before snapshots samt en eksakt release fra et valgt snapshot. Det eksponerer ikke lifecycle, filesystem paths, refresh, parser eller mutation. Queries er først tilgængelige, når Journal-processens initiale loading er lykkedes.

En ServiceManager er et separat administrationshandle, som en composition/lifecycle owner kan beholde uden at give almindelige service-consumers administrative rettigheder. JournalServiceManager er passiv og eksponerer kun den normaliserede Journal-root og explicit refresh; den har ingen start(), stop() eller service-accessor og er hverken component eller process. Hub'en konstruerer ét Journal-objekt, som både er JournalService og NenjimProcess, samt en separat manager bundet til objektets package-private admin-view.

Når Hub'en starter Journal-processen, læser referenceimplementationen komplette UTF-8-filer kronologisk og validerer placement/navne. Hele den initiale worldview publiceres først, når alle runtime-filer er accepteret; en fejl efterlader servicen utilgængelig uden partial state og samme instans kan ikke startes igen. Refresh efter vellykket startup er fortsat explicit, idempotent og per-ingestion atomisk; der er ingen watcher eller background polling.

JournalServiceImpl vedligeholder internt kæderne og udfører atomisk ingestion med exact-text SHA-256. Identisk tekst er idempotent; anderledes tekst med samme coordinate og Journal-version er en conflict. Parser, ingestion og mutable chain state er implementation details og findes ikke i public signatures. Public API-pakkerne er opdelt således:

com.r35157.nenjim.service.journal               JournalService, JournalServiceManager
com.r35157.nenjim.service.journal.model         sammensatte immutable domænemodeller
com.r35157.nenjim.service.journal.valuetypes    små værdidefinerede typer
com.r35157.nenjim.service.journal.exception     Journal-specifikke exceptions
com.r35157.nenjim.service.journal.impl.ref      referenceimplementation og interne helpers
data/nenjim/journals/
└── <artifact-coordinate>/
    ├── <journal-version>.journal
    └── <journal-version>.journal.example

Kun .journal er runtime-input. .journal.example dokumenterer formatet og indlæses ikke. Roden skal allerede eksistere og være læsbar; Journal-processen og dens manager opretter, overskriver eller sletter ikke Journal-filer.

3. Opdateringer og Sikkerhed

Det implementerede Journal-lag kan repræsentere nye sikkerhedsoplysninger som en nyere immutable revision, for eksempel via BLACKLIST eller en ændret RECOMMENDED. Automatisk synchronization, selection, reconciliation og upgrade/downgrade er fremtidigt arbejde.

4. Betalingssystem og Integration med AssetAZ

Betaling og AssetAZ-integration er langsigtet vision og er ikke en del af Journal-formatet eller denne implementation.

5. Backing Store og Fleksibilitet

Den nuværende Journal-proces læser kun det dokumenterede lokale disk-layout gennem en intern filesystem-loader. Artifact downloading, IPFS retrieval, remote Journals og andre backing stores er ikke implementeret. En ipfs:-værdi i INFORMATION_URI er metadata, ikke en retrieval-instruks.

6. Standardiseret og Automatiseret Pakkehåndtering

Journalen modellerer dependency-krav og indholdsidentiteter, men downloader ikke bytes og verificerer ikke downloadet indhold. Dependency-graph resolution, automatisk release-selection og Maven-resolution er fremtidigt arbejde.

7. Betydningen af Semantisk Versionering

Format 1 accepterer kun stabile eksakte releases med alle tre numeriske komponenter. Det forudsætter ikke, at en resolver altid vælger den numerisk højeste version: hard constraints afgrænser de gyldige valg, og policy/dependency hints kan på sigt foretrække en lavere kompatibel release.

8. Componenter og det centrale Registry

En Nenjim component er en færdigkonstrueret byggeklods, som er klar til brug. Rollen som service, applikation, algoritme eller adapter og klassifikationen som aktiv proces er uafhængige dimensioner. En service eksponerer et domain API, mens en applikation beskriver en user-facing eller orchestration-rolle. Registry-API'et bruger det fælles ord component og ikke plugin, og NenjimComponent er en ren marker interface. En component, som Hub'en kan starte og tracke, implementerer desuden den canonical com.r35157.nenjim.process.NenjimProcess, som kun lover start() og ikke en fælles stop-, restart- eller health-operation. En service- eller applikationsimplementation kan derfor også være en process; passive componenter er det ikke.

Ticker følger denne opdeling: almindelige consumers modtager TickerService med kun latest-price query, mens det samme TickerServiceImpl-objekt separat er en NenjimProcess, som Hub'en starter. Tickerens source-lifecycle er implementation-owned; PriceSource-instanser startes internt, og en fejlet Ticker-start stopper de sources, som nåede at starte. Der findes ingen almindelig Ticker-serviceoperation til start eller stop.

Evelyn IOU Burner følger samme opdeling, selv om dens nuværende domain-service-view er tomt: EvelynIOUBurnerService giver typed Registry- og dependency-identitet uden eksterne håndtag, mens det samme EvelynIOUBurnerServiceImpl-objekt separat er en Hub-styret NenjimProcess. Kun process-view'et eksponerer startup; hverken service-interfacet eller implementationen eksponerer almindelig stop eller restart.

En NenjimComponentId er registration metadata i ét Registry og er ikke en egenskab ved objektet. ID-formatet er lower-case ASCII med dot-separated segments og valgfrie interne bindestreger, f.eks. nenjim.registry.service og assetaz.price-source.raydium-pool.eve-usdt. Det samme objekt må registreres under flere forskellige ID'er, og én registration bliver automatisk synlig gennem alle component interfaces, som objektet implementerer. Registry- service- og process-view af Registry-objektet har derfor samme ID og samme object identity.

NenjimRegistryService er det read-only katalog, som almindelige consumers modtager gennem constructor injection. Det kan returnere et immutable registration-order snapshot af ID'er for et component interface eller slå ét ID op gennem et forventet interface. Et manglende ID giver null; et eksisterende ID med forkert interface er en caller programming error. Public API'et kan ikke registrere eller fjerne componenter.

NenjimHubImpl repræsenterer én kørende Nenjim runtime. Hub'en læser deployment-konfigurationen, ejer dependency wiring og lifecycle, konstruerer hele den nuværende passive component graph og konstruerer kun de processer, som er valgt til autorun. Et implementation-only Registry assembly udleverer read-only service-view, process-view af det samme Registry-objekt og en separat NenjimRegistryServiceManager. Manageren er kun Hub'ens passive registrationshandle: den er hverken component eller process, har ingen start() eller service-accessor, registreres ikke og starter aldrig en component.

Et tilsvarende implementation-only Journal assembly udleverer read-only service-view, process-view af det samme Journal-objekt og en separat passiv JournalServiceManager. Journal-manageren registreres ikke og giver kun adgang til root og refresh gennem et package-private admin-view; almindelige JournalService-consumers kan ikke udlede administrationsadgangen.

Alle moderne JavaFX-applikationer deler ét JVM-wide JavaFX toolkit. Det repræsenteres af JavaFxRuntimeService, mens samme JavaFxRuntimeServiceImpl-objekt også implementerer NenjimProcess for Hub'ens lifecycle. Når den er valgt, konstruerer og registrerer Hub'en objektet som nenjim.javafx-runtime.service; den skal stå før valgte JavaFX-applikationer i autorun-listen, så dens service-view kan injiceres efter vellykket startup. Kun processens start() må kalde Platform.startup(...); runLater(...) starter aldrig toolkit'et implicit og afviser arbejde, indtil startup er lykkedes. Startup venter på JavaFX Application Thread og sætter Platform.setImplicitExit(false). Udelades alle JavaFX-processer, konstruerer Hub'en ikke runtime-objektet og initialiserer ikke toolkittet.

Den package-private NenjimRegistryServiceAdmin er managerens interne mutationsadgang. Den må ikke gøres public, fordi almindelige consumers ellers kunne caste deres Registry-service til mutationsinterfacet og bryde det read-only service contract. Registration starter ikke et objekt, og Registry'et forbliver internt åbent for senere registration efter startup.

8.1 Obligatorisk NenjimHub.conf format 1

Hub'en læser kun conf/NenjimHub.conf. Filen skal eksistere som en læsbar regular file; en manglende eller ugyldig fil stopper startup, før Registry startes. conf/NenjimHub.conf.example er kun en versioneret copy-template: Hub'en læser, kopierer og genererer den aldrig og falder hverken tilbage til den eller til en hardcoded procesliste.

Den første faktiske entry skal være FORMAT_VERSION=1; før den må der kun stå blanke linjer og full-line #-kommentarer. Den næste faktiske entry skal være den ene eksakte [AUTO_START]-header. Hver aktiv linje i sektionen er ét NenjimComponentId, og rækkefølgen bevares præcist. Leading/trailing whitespace ignoreres, en trimmet linje som begynder med # er en kommentar, og # efter faktisk indhold starter en trailing kommentar. Inde i sektionen fortsætter en comment-only line listen, mens den første whitespace-only line afslutter sektionen; EOF kan også afslutte den. Efter afslutningen tillades kun blanke linjer og kommentarer. Formatet har ingen quoting eller escaping for #.

Hele listen valideres før første proces-start. Ugyldige, duplikerede, ukendte og passive component-ID'er afvises. Registry skal stå præcis én gang først og Journal præcis én gang som nummer to. De kendte valgbare processer er:

nenjim.registry.service
nenjim.journal.service
assetaz.ticker.default
jupiter-perps-alarm.default
evelyn.status.prod
evelyn.status.test
evelyn.iou-burner.prod
evelyn.perps.prod
evelyn.perps.test
nenjim.javafx-runtime.service
evelyn.mission-control.default
nenjim.process-manager.default

Ved opgradering erstattes evelyn.service.prod med evelyn.status.prod og evelyn.service.test med evelyn.status.test i deploymentets private conf/NenjimHub.conf, hvor de forekommer. Bevar rækkefølge og aktive/udkommenterede valg. De gamle ID'er accepteres ikke længere. Hub'en konstruerer samme navngivne Production- og Test-instanser gennem EvelynStatusServiceImpl og injicerer deres EvelynStatusService-views i Mission Control. Process Manager viser de nye ID'er fra Hub'ens startup-snapshot. Historik ligger fortsat i data/evelyn/<instance-name>/status.log med formatversion 1 og kræver ingen migration.

Mission Control kræver både evelyn.perps.prod og evelyn.perps.test før evelyn.mission-control.default i den private conf/NenjimHub.conf. Erstat den tidligere evelyn.perps.default-linje med de to nye ID'er; det gamle ID accepteres ikke længere. Hub'en konstruerer, registrerer og starter to separate EvelynPerpsServiceImpl-processer med separate hardcodede wallet-lister og tilhørende Jupiter-integrationer. Begge får desuden den fælles PhoenixPerpsService uden positionscache, som Hub'en registrerer passivt som phoenix.perps.default; den skal ikke tilføjes til [AUTO_START]. Hub'en injicerer deres read-only service-views til de tilsvarende miljøfaner i EMC. Process Manager viser begge ID'er efter vellykket startup. Den lokale udviklingskonfiguration er opdateret; andre deployments med EMC skal migreres tilsvarende. Udeladt eller forkert rækkefølge giver en tydelig konstruktionsfejl uden automatisk indsættelse. Det minimale versionsstyrede bootstrap-eksempel er uændret. Hver service ejer sit eget snapshot og opdaterer det fra Jupiter og Phoenix i baggrunden med 60 sekunders pause efter fuldførte gennemløb. Sidste vellykkede data bevares separat pr. wallet og venue. EMC-læsninger bruger kun det publicerede snapshot. Wallet-listerne fra issue #98 indeholder seks PROD-adresser og én TEST-adresse.

Hvis evelyn.iou-burner.prod vælges, skal både assetaz.ticker.default og evelyn.status.prod stå før den. Hub'en injicerer Production status-servicen til referenceprisopslag før nye buybacks; en manglende eller senere status-forgænger giver en tydelig konstruktionsfejl uden implicit oprettelse eller omordning.

Efter validering konstruerer og starter Hub'en Registry, registrerer det som nenjim.registry.service og registrerer startup-milepælen. Derefter konstrueres og registreres hele den nuværende passive graph uden at starte workers eller processer. Først herefter behandles resten af [AUTO_START] i den angivne rækkefølge, begyndende med Journal. Hver valgt proces konstrueres først, når dens linje nås, registreres før start() og tilføjes kun til Hub'ens immutable ordered snapshot, når start() returnerer. Journal er derfor stadig den anden succesfulde proces, selv om den passive graph konstrueres mellem Registry- og Journal-start.

[AUTO_START] er foreløbig deploymentets komplette, manuelt ordnede proces-dependency closure. Hub'en finder, indsætter eller omordner ikke dependencies. En krævet proces skal stå før sin consumer; eksempelvis skal nenjim.javafx-runtime.service stå før Mission Control og Process Manager. Mangler forgængeren, stopper konstruktion eller startup fail-fast uden implicit reparation. En udeladt proces bliver hverken konstrueret, registreret, startet eller vist af Process Manager. Den versionerede template vælger kun de obligatoriske Registry- og Journal-processer; alle øvrige processer skal tilføjes eksplicit til deploymentets private konfiguration.

Et minimalt headless eksempel, svarende til den versionerede template, er:

FORMAT_VERSION=1

[AUTO_START]
nenjim.registry.service
nenjim.journal.service

Tickerens egen component-konfiguration vælger fortsat eksplicit assetaz.price-source.raydium-pool.eve-usdt gennem Registry'et; den hardcodede price source er registreret, men inaktiv. Fejl under passiv konstruktion, valgt proceskonstruktion, registration eller startup stopper straks og forhindrer alle senere processer. Tidligere succeser forbliver synlige, den fejlende proces registreres ikke som startet, og der udføres ingen generic rollback. Online point og det afsluttende blocking wait nås kun efter alle konfigurerede processer er startet. Process Manager viser fortsat Hub'ens faktiske succesfulde snapshots og ikke den ønskede konfigurationsliste.

com.r35157.nenjim.hubd.Main er kun det yderste Java-bootstrap. Main.main(...) konstruerer NenjimHubImpl gennem det globale NenjimHub-interface og kalder start() præcis én gang. Hub'en ejer også det eksisterende online point og den afsluttende blocking wait. Hub'en er hverken component eller process og registreres ikke i sit eget Registry.

Det implementerede Registry er ét katalog og er ikke et authorization-system. Contexts, artifact-version semantics, resolution, classloading, automatic discovery, public runtime loading/registration, removal, persistence, events, automatic dependency construction/start-all, usage tracking og permissions er fremtidigt arbejde. Den nuværende autorun-fil er ikke Context resolution eller process discovery. Journal publishing, remote synchronization og signature validation er ligeledes ikke implementeret.

9. Integration med AssetAZ og økonomisk aktivitet

Økonomi, publicering og distribution er fremtidig vision. Format 1 beskriver alene artifaktviden; det indeholder ingen betalings-, salgs- eller transaktionsadfærd.

10. Installation af en NenjimHub

For at NenjimHub'en kan køre godt, skal den leve i et samspil med nogle andre komponenter. Dette kan sættes op på forskellige måder. Efterfølgende er et eksempel på en opsætning i en Virtuel Maskine, eller en lille fysisk host. Bemærk at ECC ram er kritisk for stabiliteten, specielt hvis NenjimHub'en skal arbejde med finansielle aktiviteter. Efterfølgende er en beskrivelse af hvordan man laver en opsætning som virker. Du kan lave specielle rettelser, hvis du forstår hvad du laver. Det vil dog være en god idé at følge en standard opsætning, så alt bliver lidt nemmere at styre.

10.1 Reference opsætning af Fysisk eller Virtuel Maskine (VM) til NenjimHub

Her beskrives hvordan man laver en standard opsætning af en NenjimHub. Denne opsætning vil også blive refereret til som reference opsætningen, sådan at man har et fælles udgangspunkt at tale ud fra.

10.1.2 Minimale system krav

Det er klart at jo mere NenjimHub'en skal lave, jo større er hardware kravene, men med en 'NenjimHub Reference Configuration', får du en opsætning der kan starte op og som du kan bygge videre fra. Derfor er kravene til opsætningen meget moderate.

  • CPU: 64bit x86
  • RAM: 2GB (Helst ECC)
  • Storage: 2x16GB (for RAID)
  • Networking: Public IPv4 access

10.1.3 Basis Operativ System installation

Hvis du installerer som en VM (Proxmox), så brug følgende:

  • Aktiver Qemu Agent
  • Virtual Machine type: q35
  • BIOS: OVMF (UEFI - med EFI disk + Pre-Enrolled keys)
  • Storage: 2 x 16GB (SSD emulation + Discard)
  • CPU: 2 CPU cores (type: x86-64-v2-AES)
  • Memory: 2GB (Minimum 1GB + Ballooning)
  • Network: Adgang til et netværk med DHCP service (Fravælg Proxmox firewall)

Installer basis Operativ System:

  • Boot installations medie for Debian-13
  • Vælg defaults med mindre andet angivet nedenfor
  • User setup:
    • Full name: System Operator
    • Username: sysop
  • Partition disks:
    • Manual
      • Lav nye tomme partitions tabeller
        • Disk 1:
          • Partition 1
            • Size: 512MB
            • Name: EFI1
            • Use as: EFI System Partition
            • Bootable: on
          • Partition 2
            • Size: 8GB
            • Name: ROOT1
            • Use as: Ext4
            • Label: ROOT
          • Partition 3
            • Size: 8.7GB (Resten af disken)
            • Name: ZFS1
            • Use as: do not use
        • Disk 2:
          • Partition 1
            • Size: 512MB
            • Name: EFI2
            • Use as: do not use
          • Partition 2
            • Size: 8GB
            • Name: ROOT2
            • Use as: do not use
          • Partition 3
            • Size: 8.7GB (Resten af disken)
            • Name: ZFS2
            • Use as: do not use
  • Acceptér ikke at opsætte swap endnu.
  • Software selection:
    • SSH server
    • standard system utilities
  • Reboot after installation

Install additional tools:

$ su -
# apt-get update; apt-get install -y htop zram-tools sudo tmux
# usermod -aG sudo sysop
(Log ud og ind igen)
# sudo bash
# vi /etc/default/zramswap
(Ret PRIORITY=1)
# sed -ri'.bak' '/^deb/ { /contrib/! s/$/ contrib/ }' /etc/apt/sources.list
# apt-get update
# mokutil --sb-state || sudo apt -y install mokutil && mokutil --sb-state
# apt install -y dkms sbsigntool shim-signed mokutil
# mokutil --import /var/lib/dkms/mok.pub
(Indtast en midlertidig adgangskode)
# apt-get install -y linux-headers-amd64 zfsutils-linux zfs-dkms zfs-zed
# reboot
(Når den blå skærm kommer, vælg 'Enroll MOK' og brug nu det password du valgte ovenover)

Opret ZFS pool:

$ sudo bash
# zpool create zfspool -O xattr=sa -o ashift=12 -O compression=lz4 -O checksum=sha512 -O dedup=on -O atime=off mirror /dev/sda3 /dev/sdb3

Opret swap:

$ sudo bash
# zfs create -V 4G -o compression=zle \
      -o logbias=throughput -o sync=always \
      -o primarycache=metadata -o secondarycache=none \
      -o com.sun:auto-snapshot=false zfspool/swap
# mkswap -f /dev/zvol/zfspool/swap
# echo /dev/zvol/zfspool/swap none swap sw,pri=0 0 0 >> /etc/fstab
# swapon -av

Installér docker (using official repository instead of Debian repository):

$ sudo bash
# apt install -y apt-transport-https ca-certificates curl gpg
# curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
# echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/debian trixie stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# apt update
# apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# usermod -aG docker sysop
(Log out and in again)

Flyt docker storage til ZFS:

$ sudo bash
# systemctl stop docker
# zfs create -V 3G zfspool/var_lib_docker
# mkfs.ext4 /dev/zvol/zfspool/var_lib_docker
# rm -rf /var/lib/docker
# mkdir /var/lib/docker
# echo "/dev/zvol/zfspool/var_lib_docker /var/lib/docker ext4 defaults 0 2" >> /etc/fstab
# systemctl daemon-reload
# mount /var/lib/docker
# chmod 710 /var/lib/docker
# systemctl enable docker ; systemctl start docker

Installer ZeroTier:

$ sudo bash

# curl -fsSL 'https://raw.githubusercontent.com/zerotier/ZeroTierOne/main/doc/contact%40zerotier.com.gpg' | gpg --import
(Importer ZeroTier's signeringsnøgle)

# gpg --fingerprint contact@zerotier.com
(Check nøglen)

#if z=$(curl -fsSL 'https://install.zerotier.com/' | gpg --decrypt); then
  echo "$z" | sudo bash
else
  echo "Signaturtjek mislykkedes – kører ikke scriptet." >&2
  exit 1
fi
(Henter og dekryperer (verificerer) install-scriptet og kører det kun hvis signaturen er OK)

Konfigurer ZeroTier net:

  • Login på 'https://my.zerotier.com'
  • Opret et nye netværk 'Create A Network' (Som skal forbinde terminaler og AssetAZHub)
  • Klik på det nye netværk
  • Basic/Name: 'assetaz-<ditid>' (f.eks 'assetaz-mortengh')
  • Vælg et IP range, f.eks 192.168.192.*
  • Forbind AssetAZHub til netværket (netværks id'et kan ses på websiden):
    • zerotier-cli join a8bea75acfa45477

  • Autoriser den nye maskine på nettet. Dette gøres ved at trykke på 'Edit' ved maskinen på websiden, som nu burde kunne se den. Autoriser den, giv den et navn og evt. en beskrivelse.
  • Tryk 'Add IP' og giv den en IP adresse inden for det range du har valgt oven over (f.eks 192.168.192.1). Tryk 'Save'
  • Se at AssetAZHub' nu kan pinge sig selv:

    ping 192.168.192.1

Forbind terminal (f.eks en Android telefon)

  • Installer ZeroTier-One
  • Forbind til det samme net som hub'en.
  • Autoriser terminalen inde på ZeroTiers web side og set terminalen ip adresse til noget kendt f.eks 192.168.192.2. (Så kører hub'en på *.1 og terminalen på *.2)

Opsæt locale

Opret Docker baby swarm cluster