Seed fuer EspoCRM-Kunden-VMs unter espocrm/ ergaenzt

Quelle ist espoCRM/espo-fleet-ops (autoinstall/user-data); hier abgelegt, weil
der Installer ohne Anmeldung abruft und die Organisation espoCRM nicht
oeffentlich sichtbar ist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
gordon.zimm 2026-09-22 16:49:18 +02:00
parent 0cd9fc6f91
commit db0fd0887e
4 changed files with 158 additions and 1 deletions

View File

@ -14,4 +14,13 @@ Passwort: ubuntu
Passwort ändern mit:
passwd
passwd
---
## Varianten
| Verzeichnis | Zweck | Boot-Parameter |
|---|---|---|
| (Wurzel) | allgemeine Ubuntu-VM | `autoinstall ds=nocloud-net;s=https://gitea.subcura.net/gordon.zimm/ubuntu-autoinstall/raw/branch/main/` |
| `espocrm/` | EspoCRM-Kunden-VM (Projekt espo-fleet-ops) | `autoinstall ds=nocloud-net;s=https://gitea.subcura.net/gordon.zimm/ubuntu-autoinstall/raw/branch/main/espocrm/` |

22
espocrm/README.md Normal file
View File

@ -0,0 +1,22 @@
# EspoCRM-Kunden-VM – Autoinstall-Seed
Dieser Seed gehört zum Projekt **espo-fleet-ops** (Gitea: `espoCRM/espo-fleet-ops`). Dort liegen die Quelle,
die Architekturentscheidungen und die Begründung zu jeder Einstellung:
`docs/decisions/`, `docs/entwuerfe/plattenlayout-erlaeuterung.md`.
Er liegt **hier**, weil der Installer die Dateien ohne Anmeldung abruft und die Organisation `espoCRM` nicht öffentlich
sichtbar ist. Der Seed enthält bewusst **keine Geheimnisse** (kein benutzbares Passwort, kein RMM-Token).
**Änderungen immer zuerst in `espoCRM/espo-fleet-ops/autoinstall/user-data` und von dort hierher kopieren.**
## Verwendung
Ubuntu-Server-24.04-ISO booten, im GRUB-Menü `e` drücken, vor `---` einfügen:
```
autoinstall ds=nocloud-net;s=https://gitea.subcura.net/gordon.zimm/ubuntu-autoinstall/raw/branch/main/espocrm/
```
Strg+X. Die Installation läuft ohne Rückfragen durch und **schaltet die VM am Ende aus**; vor dem nächsten Start das ISO
trennen. Die drei Schritte der Erstinbetriebnahme (Passwort ändern, RMM-Agent installieren, Hinweiszeile entfernen) liegen
danach als `/root/ERSTINBETRIEBNAHME.txt` auf der VM.

0
espocrm/meta-data Normal file
View File

126
espocrm/user-data Normal file
View File

@ -0,0 +1,126 @@
#cloud-config
# Autoinstall-Seed für die EspoCRM-Kunden-VM (Ubuntu Server 24.04 LTS auf Hyper-V).
# Stand 2026-09-22, abgeleitet aus gitea gordon.zimm/ubuntu-autoinstall (Commit 0cd9fc6).
# ERSTE FASSUNG – auf einer Test-VM noch nicht durchgelaufen; Abweichungen bitte hier einpflegen.
#
# Grundsätze:
# * Der Seed wird per NoCloud über HTTP geladen und kann sich nicht authentisieren
# -> er enthält KEIN Geheimnis: kein benutzbares Passwort, kein RMM-Token.
# * Die ISO richtet nur das Minimum ein. Docker, Härtung, Logrotation, Firewall, Hostname und
# Instanz kommen reproduzierbar über RMM-Tasks ("alles Weitere erfolgt über ConnectWise RMM").
autoinstall:
version: 1
source:
id: ubuntu-server
updates: all
locale: de_DE.UTF-8
keyboard:
layout: de
timezone: Europe/Berlin
# Schnittstellennamen nicht festnageln: Hyper-V meldet je nach Kernel eth0 oder enp*.
network:
version: 2
ethernets:
primary:
match:
name: "e*"
dhcp4: true
dhcp6: false
identity:
realname: administrator
username: administrator
hostname: unkonfiguriert # setzt der RMM-Baseline-Task auf crm-<site>
# Hash eines einmalig erzeugten 48-Zeichen-Zufallspassworts; der Klartext wurde nirgends abgelegt.
# Das Konto ist damit faktisch gesperrt, bis die late-commands je VM ein Initialpasswort setzen.
password: '$6$KDLfMzLPV6wWtwA4$9VnUET9kFWUVp07z2hkN9Kv9.WjgdIPGLmm7zb4Te47Ms7lyrw/9Ewpqf759xVfXcOfAkWJSFrxUClfeyxeuI0'
ssh:
install-server: true
allow-pw: true
authorized-keys: []
packages:
- linux-cloud-tools-virtual # hv_kvp_daemon, hv_vss_daemon, hv_fcopy_daemon
- curl # Voraussetzung des RMM-Agenten (libcurl4 kommt mit)
- bzip2 # der .run-Installer entpackt sich damit
# kein linux-azure: der Azure-Kernel ist für Azure gebaut. Soll er trotzdem bleiben,
# gehört linux-cloud-tools-azure dazu, sonst fehlen die Hyper-V-Integrationsdienste.
# Explizite Aufteilung: klein für das Betriebssystem, groß für die Nutzdaten.
# `layout: {name: lvm, sizing-policy: scaled}` wäre kürzer, gibt aber rund die Hälfte der Platte an "/" –
# auf einer reinen Docker-VM ist das an der falschen Stelle.
storage:
config:
- {type: disk, id: disk0, ptable: gpt, match: {size: largest}, wipe: superblock-recursive, preserve: false, grub_device: false}
- {type: partition, id: part-esp, device: disk0, size: 1G, flag: boot, grub_device: true, preserve: false}
- {type: format, id: fmt-esp, volume: part-esp, fstype: fat32, preserve: false}
- {type: mount, id: mnt-esp, device: fmt-esp, path: /boot/efi}
- {type: partition, id: part-boot, device: disk0, size: 2G, preserve: false}
- {type: format, id: fmt-boot, volume: part-boot, fstype: ext4, preserve: false}
- {type: mount, id: mnt-boot, device: fmt-boot, path: /boot}
- {type: partition, id: part-pv, device: disk0, size: -1, flag: lvm, preserve: false}
- {type: lvm_volgroup, id: vg0, name: ubuntu-vg, devices: [part-pv], preserve: false}
# Betriebssystem, RMM-Agent, Logs – 20 GiB sind reichlich (Bedarf real 8–12 GiB)
- {type: lvm_partition, id: lv-root, name: root-lv, volgroup: vg0, size: 20G, preserve: false}
- {type: format, id: fmt-root, volume: lv-root, fstype: ext4, preserve: false}
- {type: mount, id: mnt-root, device: fmt-root, path: /}
# Sollte der Installer `path: none` für Swap nicht annehmen: diese drei Zeilen entfernen und
# stattdessen `swap: {size: 4G}` als eigenen Abschnitt setzen (Swapdatei auf /).
- {type: lvm_partition, id: lv-swap, name: swap-lv, volgroup: vg0, size: 4G, preserve: false}
- {type: format, id: fmt-swap, volume: lv-swap, fstype: swap, preserve: false}
- {type: mount, id: mnt-swap, device: fmt-swap, path: none}
# Images, Container, Container-Logs – reproduzierbar, wird nicht gesichert
- {type: lvm_partition, id: lv-docker, name: docker-lv, volgroup: vg0, size: 20G, preserve: false}
- {type: format, id: fmt-docker, volume: lv-docker, fstype: ext4, preserve: false}
- {type: mount, id: mnt-docker, device: fmt-docker, path: /var/lib/docker}
# /srv (Nutzdaten) wird in late-commands anteilig angelegt, damit der Seed für jede Plattengröße passt.
late-commands:
# 1. /srv bekommt 80 % des verbliebenen Platzes; ~20 % bleiben unbelegt als Reserve und für LVM-Snapshots.
# Beispiel 128-GiB-Platte: / 20, swap 4, docker 20, /srv ~65, frei ~16 GiB.
- lvcreate -y -l 80%FREE -n srv-lv ubuntu-vg
- mkfs.ext4 -q -L srv /dev/ubuntu-vg/srv-lv
- mkdir -p /target/srv
- printf '/dev/ubuntu-vg/srv-lv /srv ext4 defaults 0 2\n' >> /target/etc/fstab
# 2. Je VM zufälliges Initialpasswort, am Konsolen-Login sichtbar, Wechsel beim ersten Anmelden erzwungen.
- >-
PW=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 20);
echo "administrator:$PW" | curtin in-target -- chpasswd;
curtin in-target -- chage -d 0 administrator;
printf '\n Initialpasswort administrator: %s\n (beim ersten Anmelden ändern, danach diese Zeile aus /etc/issue entfernen)\n' "$PW" >> /target/etc/issue
# 3. Hyper-V-Integrationsdienste (Zeit/IP-Meldung, Dateisystem-Quiesce für Veeam).
# Normalerweise startet udev sie selbst; enable schadet nicht und darf fehlschlagen.
- curtin in-target -- systemctl enable hv-kvp-daemon.service hv-vss-daemon.service || true
# 4. Kurze Anleitung für den einen Handgriff nach dem ersten Start (Passwort + RMM-Agent).
- >-
printf '%s\n'
'# Erstinbetriebnahme dieser VM (Entscheidung 2026-09-22: Registrierung im RMM von Hand)'
'# 1. Initialpasswort steht am Konsolen-Login (/etc/issue), Wechsel wird erzwungen.'
'# Neues Passwort im Secure Information Store der Site hinterlegen.'
'# 2. RMM-Agent installieren (Token aus: Endpoints > Devices > Manage > Download Agent):'
'# curl -fsSL -o /tmp/ITSPlatform.run https://setup.euplatform.connectwise.com/linux/BareboneAgent/64/ITSagent/RUN/setup'
'# chmod +x /tmp/ITSPlatform.run && sudo TOKEN=<Site-Token> /tmp/ITSPlatform.run && rm -f /tmp/ITSPlatform.run'
'# 3. Zeile mit dem Initialpasswort aus /etc/issue entfernen.'
'# Alles Weitere erledigt der Baseline-Task, den der Trigger "First check-in" anstoesst.'
> /target/root/ERSTINBETRIEBNAHME.txt
# 5. Zum Schluss alles auf den neuesten Stand bringen. `updates: all` deckt den Stand zu Beginn der
# Installation ab; dieser Durchgang holt, was währenddessen dazugekommen ist, und räumt auf.
# NEEDRESTART_SUSPEND verhindert Dienst-Neustarts im chroot.
- curtin in-target -- sh -c 'DEBIAN_FRONTEND=noninteractive NEEDRESTART_SUSPEND=1 apt-get update'
- curtin in-target -- sh -c 'DEBIAN_FRONTEND=noninteractive NEEDRESTART_SUSPEND=1 apt-get -y -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef full-upgrade'
- curtin in-target -- sh -c 'DEBIAN_FRONTEND=noninteractive apt-get -y autoremove --purge'
- curtin in-target -- sh -c 'apt-get clean'
shutdown: poweroff