Installation in Mass Production Line
Wird verwendet, wenn 100 bis 1000 Boxen in einer Produktionslinie verarbeitet werden. Wenn der Operator nur einen Bildschirmprompt ausfüllt, erfolgen EDGE_ID / Hostname / Anmeldedaten / Docker / cosign verify / Containerstart automatisch. 30 Sekunden pro Box.
Bei Einzelboxen / Vor-Ort-Installation (SI-Mitarbeiter) sehen Sie bitte zuerst die Seite One-Line Installation. Der Unterschied zwischen Massenproduktion und Vor-Ort-Installation liegt nur im Entry Point, das Ergebnis ist identisch.
0. Überblick
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 führt automatisch aus:
- Automatische Erkennung der LAN1 NIC MAC — Erstellung von
EDGE_<HEX6>mit den letzten 6 Stellen der MAC (z. B.EDGE_3F8A21). - Hostname-Synchronisation — Änderung von
hostnameebenfalls inedge-<hex6>(RFC 1123, Kleinbuchstaben + Bindestrich). - 5-Felder-Prompt — SITE_ID / SERVER_HOST / SERVER_API_KEY / LAN1 NIC / LAN2 NIC.
install.shDelegierung — Docker / cosign / random secret / app.properties / Containerstart.- Ausgabe von factory-label.txt — Zur Anbringung an der Box. Nach dem Drucken versiegeln.
- Append an factory-inventory.csv — Rückführung am Ende der Linie → unternehmensinterne Inventory-DB.
1. Automatische Erstellung 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
Warum MAC?
- Hostnames können sich bei jeder OS-Installation ändern (cloud-init /
hostnamectl) und es kann zu Kollisionen kommen. - Die MAC ist in der Hardware verankert und garantiert Eindeutigkeit pro Box.
- Letzte 6 Stellen (24-Bit) → ca. 16,7 Millionen Kombinationen. Bei einer Massenproduktion von 1000 Einheiten liegt die Kollisionswahrscheinlichkeit bei ~0,003 % (sicher gemäß Birthday Paradox).
Erzwingung der Domain-Regeln (CLAUDE.md im Produkt-Repository):
| Bezeichner | Regex | Beispiel |
|---|---|---|
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 + Bindestrich | edge-3f8a21 |
factory.sh führt nach der Regex-Validierung fort — bei Nichtbestehen sofortiger Abbruch.
MAC-Kollision / Box ohne NIC
- Kollisionsmöglichkeit — Wenn in
/data1/factory-inventory.csvbereits dieselbe EDGE_ID existiert, erfolgt sofortiger Abbruch (Verhinderung stiller Duplikate). Automatisierte Erkennung von Fällen, in denen dieselbe Box zweimal provisioniert wird oder eine MAC-Kollision vorliegt. - Box ohne MAC (z. B. virtuelle NIC) —
derive_edge_id_from_macschlägt fehl → install.sh nutzt Fallback basierend auf dem Hostnamen. In der Produktionslinie tritt dies fast nie auf.
2. Prompt mit 5 Feldern
Eingabe durch den Operator 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 Klicken auf y arbeitet install.sh für 5 bis 10 Minuten (einschließlich erstem Image-Pull von 3 GB) und gibt anschließend das Label aus.
3. Automatisch generierte Anmeldedaten (G2)
install.sh generiert für jede Box unterschiedliche Zufallspasswörter (Details siehe Abschnitt Passwörter / API-Schlüssel (Secrets) im heruntergeladenen plantpulse-edge-docker/README.md):
| Variable | Länge | Ort |
|---|---|---|
ADMIN_PASS (UI-Login) | zufällig 14 Zeichen + ! | /etc/kopens/credentials.txt |
API_KEY (REST) | zufällig 16 Zeichen | obige Datei + env.sh.generated |
MQTT_PASS (HiveMQ) | zufällig 14 Zeichen + ! | obige Datei |
OPCUA_PASS | zufällig 14 Zeichen + ! | obige Datei |
CERT_PASS (SSL Keystore) | zufällig 14 Zeichen + ! | obige Datei |
/etc/kopens/env.sh.generated (chmod 0600 root) dient als Sidecar, aus dem alle nachfolgenden Skripte (upgrade.sh / restart.sh) source-en — die Anmeldedaten bleiben auch nach einem Neustart identisch.
4. Verifizierung der Image-Signatur (G3)
install.sh führt die automatische Installation von cosign + Bereitstellung von cosign.pub durch und verifiziert diese automatisch unmittelbar nach dem docker pull.
[install] Installing cosign ...
[install] OK — cosign installed (cosign version 3.1.3)
[install] cosign.pub installed — image verification enabled
[install] docker pull — docker.kopens.io/pe/plantpulse-edge:2026.11-20261103-1006
[install] OK — Pull complete
[cosign] OK — signature verified for docker.kopens.io/pe/plantpulse-edge:2026.11-20261103-1006
Da die Image-Signatur im cosign 3-Format vorliegt, kann cosign 2.x die Signatur nicht finden. Wenn cosign nicht vorhanden ist oder eine Version unter 3 vorliegt, laden install.sh und upgrade.sh die Festversion 3.1.3 von github.com herunter, prüfen die Prüfsumme und installieren diese (es werden keine Distributionspakete verwendet). Wenn bereits 3.x vorhanden ist, wird diese beibehalten. Falls der Download während der Installationsphase fehlschlägt, wird lediglich eine Warnung ausgegeben; ein Upgrade jedoch nicht gestartet, wenn die Signatur nicht verifiziert werden kann.
Für die Installation wird das im Bundle enthaltene cosign (tools/cosign-linux-amd64) verwendet. Upgrades verifizieren die Signatur ohne Internetverbindung über pe upgrade --bundle <파일> [--cosign <cosign-linux-amd64>] — Air-Gap-Upgrade.
Wenn cosign.pub noch ein Platzhalter ist (Keypair wurde vom Betriebsteam noch nicht erstellt), erfolgt nur eine WARN-Meldung, die Installation wird jedoch fortgesetzt. Referenz: Abschnitt Image-Signatur (Cosign) im heruntergeladenen plantpulse-edge-docker/README.md.
5. Label + Inventar
/etc/kopens/factory-label.txt — Zur Anbringung an der Box
Nach Abschluss der Installation erfolgt die Ausgabe auf dem Bildschirm + Speicherung in der Datei chmod 0600. Der Mitarbeiter in der Linie druckt das Label mit einem Labeldrucker aus 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 — Zur Rückführung aus der Linie
Pro Box wird eine Zeile angehängt. Der Operator führt diese am Ende der Linie zusammen → Upload in die unternehmensinterne 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. Sammelrückführung 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 hinzugefügt werden, sodass die Daten zum Zeitpunkt des Einschaltens der Box automatisch an die Platform gepusht werden (Phase 1 — bei Einführung einer unternehmensinternen Provisioning REST API).
7. Häufige Fehlerquellen
| Symptom | Ursache | Maßnahme |
|---|---|---|
EDGE_ID '...' fails ^EDGE_[A-Z0-9_]{1,60}$ | MAC der LAN1 NIC ist eine virtuelle NIC (kein ASCII) | Explizite Angabe wie in NET1_IFACE=enp1s0 bash factory.sh |
already_in_inventory: EDGE_3F8A21 already provisioned | Erneutes Ausführen auf derselben Box oder MAC-Kollision | entsprechende Zeile mit vi /data1/factory-inventory.csv entfernen und erneut ausführen. Bei MAC-Kollision: Linienstopp + Meldung |
cosign verify FAILED (COSIGN_REQUIRE=1) | Image unsigniert ODER falsche cosign.pub | Überprüfung auf fehlenden Aufruf von sign-image.sh am Build-Server, Aktualisierung von cosign.pub |
hostnamectl set-hostname failed | Ausführung innerhalb eines Containers / keine Berechtigung | factory.sh erzwingt root — sudo bash factory.sh |
| Prompt erscheint nicht (Label wird nicht gedruckt) | install.sh ist mittendrin fehlgeschlagen | Überprüfung von journalctl -u plantpulse-edge.service -n 50, dann Installation Problembehebung |
8. Verwandte Dokumente
plantpulse-edge-docker/README.md— Abschnitt Betriebsszenarien (Massenproduktion / SI / CI) (im Lieferumfang enthalten)plantpulse-edge-docker/README.md— Abschnitt Image-Signatur (Cosign) (Keypair-Erstellung · Rollout · Rotation)- One-Line Installation
- Inspektion unmittelbar nach Installation
- Air-Gap-Installation