Zum Hauptinhalt springen

Serienfertigungslinie – Installation (factory.sh)

Wird verwendet, wenn in der Fertigungslinie 100 bis 1000 Boxen abgearbeitet werden. Der Bediener füllt nur einen Prompt-Bildschirm aus — EDGE_ID / Hostname / Zugangsdaten / Docker / cosign verify / Containerstart laufen automatisch. 30 Sekunden pro Box.

Diese Seite ist die SOP für die Serienfertigungslinie

Bei einer einzelnen Box bzw. einer Vor-Ort-Installation (SI-Mitarbeiter) lesen Sie zuerst die Seite Schnellinstallation (Einzeiler). Serienfertigungslinie und Vor-Ort-Installation unterscheiden sich nur im Einstiegspunkt, das Ergebnis ist identisch.


0. Auf einen Blick

sudo -i
mkdir -p /home/kopens
curl -fsSL https://product.kopens.io/plantpulse-edge/plantpulse-edge-docker.tar.gz \
| tar xz -C /home/kopens
cd /home/kopens/plantpulse-edge-docker/bin
sudo bash factory.sh

factory.sh erledigt automatisch:

  1. Automatische Erkennung der LAN1-NIC-MAC — erzeugt EDGE_<HEX6> aus den letzten 6 Stellen der MAC (z. B. EDGE_3F8A21).
  2. Hostname-Abgleich — auch hostname wird auf edge-<hex6> (RFC 1123, Kleinbuchstaben + Bindestrich) geändert.
  3. Prompt mit 5 Feldern — SITE_ID / SERVER_HOST / SERVER_API_KEY / LAN1 NIC / LAN2 NIC.
  4. Delegation an install.sh — Docker / cosign / random secret / app.properties / Containerstart.
  5. Ausgabe von factory-label.txt — zum Aufkleben auf die Box. Nach dem Druck versiegeln.
  6. Append an factory-inventory.csv — am Ende der Linie einsammeln → interne Inventory-DB.

1. Automatische Erzeugung von ID / Hostname

EDGE_ID — EDGE_<HEX6>

LAN1 NIC eth1 MAC = 00:1a:2b:3f:8a:21
─────
마지막 6 자 (HEX6) = 3F8A21
EDGE_ID = EDGE_3F8A21
hostname = edge-3f8a21

Why MAC?

  • Der Hostname kann sich bei jeder OS-Installation ändern (cloud-init / hostnamectl) und kollidieren
  • Die MAC ist fest in der Hardware hinterlegt und garantiert Eindeutigkeit pro Box
  • Letzte 6 Stellen der 24 Bit → ca. 16,7 Mio. Kombinationen. Bei 1000 Boxen Serienfertigung liegt die Kollisionswahrscheinlichkeit bei ~0,003 % (nach Geburtstagsparadoxon sicher)

Die Domänenregeln (CLAUDE.md im Produkt-Repository) werden erzwungen:

BezeichnerRegexBeispiel
EDGE_ID^EDGE_[A-Z0-9_]{1,60}$EDGE_3F8A21
SITE_ID^SITE_[A-Z0-9_]{1,60}$SITE_FAB1_042
hostname (RFC 1123)Kleinbuchstaben + Bindestrichedge-3f8a21

factory.sh fährt erst nach Prüfung der obigen Regex fort — schlägt die Prüfung fehl, wird sofort abgebrochen.

MAC-Kollision / Box ohne NIC

  • Kollisionsmöglichkeit — existiert dieselbe EDGE_ID bereits in /data1/factory-inventory.csv, wird sofort abgebrochen (verhindert stille Duplikate). Doppeltes Provisioning derselben Box oder MAC-Kollisionen werden automatisch erkannt.
  • Box ohne MAC (z. B. virtuelle NIC)derive_edge_id_from_mac schlägt fehl → install.sh weicht auf einen Hostname-basierten Fallback aus. In der Linie tritt das praktisch nie auf.

2. Prompt mit 5 Feldern

Eingabe durch den Bediener in der Linie:

══════════════════════════════════════════════════════════════════════
PlantPulse Edge — Factory Provisioning
══════════════════════════════════════════════════════════════════════
Detected NIC eth1 MAC : 00:1a:2b:3f:8a:21
Auto EDGE_ID : EDGE_3F8A21
Auto hostname : edge-3f8a21
══════════════════════════════════════════════════════════════════════
Site ID (^SITE_[A-Z0-9_]+) [SITE_00001]: SITE_FAB1_042
Platform server host [192.168.0.41]: 10.10.0.5
Platform API key []: kFa7bGz8pQrN3xMv9wT2sLcEjY1uV6oH
LAN1 NIC (PLC) [eth1]: ← Enter = default
LAN2 NIC (WAN) [eth2]: ← Enter = default
══════════════════════════════════════════════════════════════════════
Summary
EDGE_ID : EDGE_3F8A21
hostname : edge-3f8a21
SITE_ID : SITE_FAB1_042
SERVER_HOST : 10.10.0.5
SERVER_API_KEY : kFa7…(32 chars)
LAN1 NIC (PLC) : eth1
LAN2 NIC (WAN) : eth2
══════════════════════════════════════════════════════════════════════
Proceed with install.sh? [y/N]

Nach Drücken von y läuft install.sh 5 bis 10 Minuten (inkl. erstem Image-Pull von 3 GB) und gibt anschließend das Label aus.


3. Automatisch erzeugte Zugangsdaten (G2)

install.sh erzeugt für jede Box ein anderes Zufallspasswort (Details im heruntergeladenen plantpulse-edge-docker/README.md, Abschnitt Secrets):

VariableLängeAblageort
ADMIN_PASS (UI-Login)14 Zeichen zufällig +!/etc/kopens/credentials.txt
API_KEY (REST)16 Zeichen zufälligObige Datei + env.sh.generated
MQTT_PASS (HiveMQ)14 Zeichen zufällig +!Obige Datei
OPCUA_PASS14 Zeichen zufällig +!Obige Datei
CERT_PASS (SSL keystore)14 Zeichen zufällig +!Obige Datei

/etc/kopens/env.sh.generated (chmod 0600 root) ist das Sidecar, das alle nachfolgenden Skripte (upgrade.sh / restart.sh) sourcen — die Zugangsdaten bleiben auch nach einem Neustart identisch.


4. Verifikation der Image-Signatur (G3)

install.sh installiert cosign automatisch, legt cosign.pub ab und verifiziert unmittelbar nach dem docker pull automatisch.

[install] Installing cosign ...
[install] OK — cosign installed (cosign version 2.4.1)
[install] cosign.pub installed — image verification enabled
[install] docker pull — docker.kopens.io/pe/plantpulse-edge:2026-20260523
[install] OK — Pull complete
[cosign] OK — signature verified for docker.kopens.io/pe/plantpulse-edge:2026-20260523

Ist cosign.pub noch ein Platzhalter (das Betriebsteam hat noch kein Keypair erzeugt), erfolgt nur eine WARN-Meldung, die Installation läuft weiter. Siehe den Abschnitt Cosign im heruntergeladenen plantpulse-edge-docker/README.md.


5. Label + Inventar

/etc/kopens/factory-label.txt — zum Aufkleben auf die Box

Nach Abschluss der Installation erfolgt die Ausgabe am Bildschirm sowie die Speicherung in der Datei chmod 0600. Der Linienmitarbeiter druckt das Label auf dem Etikettendrucker und versiegelt die Box:

══════════════════════════════════════════════════════════════════════
PlantPulse Edge — Factory Label
══════════════════════════════════════════════════════════════════════
EDGE_ID : EDGE_3F8A21
hostname : edge-3f8a21
SITE_ID : SITE_FAB1_042
build_date : 2026-05-19 14:25:33
──────────────────────────────────────────────────────────────────────
LAN1 (PLC) : eth1 MAC=00:1a:2b:3f:8a:21
LAN2 (WAN) : eth2 MAC=00:1a:2b:3f:8a:22
──────────────────────────────────────────────────────────────────────
UI admin : admin / aBcD1234EfGh!
REST API : kFa7bGz8pQrN3xMv9wT2sLcEjY1uV6oH
(full credentials → /etc/kopens/credentials.txt — root only)
══════════════════════════════════════════════════════════════════════

/data1/factory-inventory.csv — zum Einsammeln in der Linie

Pro Box wird eine Zeile angehängt. Am Ende der Linie sammelt der Bediener sie ein → Upload in die interne Inventory-DB:

edge_id,hostname,site_id,server_host,lan1_iface,lan1_mac,lan2_iface,lan2_mac,build_date,iso8601
EDGE_3F8A21,edge-3f8a21,SITE_FAB1_042,10.10.0.5,eth1,00:1a:2b:3f:8a:21,eth2,00:1a:2b:3f:8a:22,2026-05-19 14:25:33,2026-05-19T05:25:33Z
EDGE_5B7C03,edge-5b7c03,SITE_FAB1_043,10.10.0.5,eth1,00:1a:2b:5b:7c:03,eth2,00:1a:2b:5b:7c:04,2026-05-19 14:28:12,2026-05-19T05:28:12Z

6. Sammelerfassung am Linienende

# 라인 마지막 박스 처리 후 회수 워크스테이션에서
scp root@edge-3f8a21:/data1/factory-inventory.csv ./inventory-line1-$(date +%F).csv

# 회수한 CSV 들을 사내 inventory DB 로 업로드 (예: scripts/import-inventory.py)
python3 import-inventory.py inventory-line1-2026-05-19.csv

Alternativ kann ein Hook ergänzt werden, der beim Einschalten der Box automatisch an die Platform pusht (Phase 1 — bei Einführung der internen Provisioning-REST API).


7. Häufige Stolperfallen

SymptomUrsacheMaßnahme
EDGE_ID '...' fails ^EDGE_[A-Z0-9_]{1,60}$Die MAC der LAN1-NIC ist eine virtuelle NIC ohne ASCII-WertExplizit angeben, z. B. LAN1_IFACE=enp1s0 bash factory.sh
already_in_inventory: EDGE_3F8A21 already provisionedErneuter Lauf derselben Box oder MAC-KollisionBetreffende Zeile mit vi /data1/factory-inventory.csv entfernen und erneut ausführen. Bei MAC-Kollision Linie stoppen + melden
cosign verify FAILED (COSIGN_REQUIRE=1)Image unsigniert ODER falsche cosign.pubPrüfen, ob der Aufruf von sign-image.sh auf dem Build-Server fehlt; cosign.pub aktualisieren
hostnamectl set-hostname failedAusführung innerhalb eines Containers / fehlende Rechtefactory.sh erzwingt root — sudo bash factory.sh
Prompt nicht sichtbar (Label wird nicht gedruckt)install.sh ist mittendrin fehlgeschlagenjournalctl -u plantpulse-edge.service -n 50 prüfen, dann Troubleshooting

8. Verwandte Dokumente