Grotti 3.5.0: Pagination, Logging, Deb-Paket, Makro-Doku, PLA-Match-Fix.
This commit is contained in:
1 parent
4ffe1dcfc6
commit
f1f79c2ce2
38 files changed
+1062
-75
No files matched your search
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env bash
|
||||
# Baut grotti_<version>_<arch>.deb (auf dem Zielsystem oder arm64-Container).
|
||||
# Aufruf aus dem Repo-Root: bash packaging/build-deb.sh
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
if ! command -v dpkg-deb >/dev/null 2>&1; then
|
||||
echo "dpkg-deb fehlt — bitte auf Debian/Raspberry Pi OS bauen." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION="$(python3 -c "from grotti.version import __version__; print(__version__)")"
|
||||
ARCH="$(dpkg --print-architecture)"
|
||||
PKG="grotti_${VERSION}_${ARCH}"
|
||||
DIST="$ROOT/packaging/dist"
|
||||
STAGE="$DIST/$PKG"
|
||||
|
||||
rm -rf "$STAGE"
|
||||
mkdir -p "$STAGE/DEBIAN" \
|
||||
"$STAGE/usr/lib/grotti" \
|
||||
"$STAGE/usr/bin" \
|
||||
"$STAGE/etc/grotti" \
|
||||
"$STAGE/lib/systemd/system" \
|
||||
"$STAGE/usr/share/grotti" \
|
||||
"$STAGE/usr/share/doc/grotti" \
|
||||
"$STAGE/var/lib/grotti/data/eingang" \
|
||||
"$STAGE/var/lib/grotti/slice"
|
||||
|
||||
rsync -a --delete \
|
||||
--exclude '__pycache__' --exclude '*.pyc' --exclude '.pytest_cache' \
|
||||
"$ROOT/grotti/" "$STAGE/usr/lib/grotti/grotti/"
|
||||
rsync -a --delete \
|
||||
--exclude '__pycache__' --exclude '*.pyc' \
|
||||
"$ROOT/web/" "$STAGE/usr/lib/grotti/web/"
|
||||
cp "$ROOT/server.py" "$STAGE/usr/lib/grotti/server.py"
|
||||
cp "$ROOT/requirements.txt" "$STAGE/usr/lib/grotti/requirements.txt"
|
||||
cp "$ROOT/config.example.json" "$STAGE/usr/lib/grotti/config.example.json"
|
||||
echo '[]' > "$STAGE/usr/lib/grotti/drucker.json"
|
||||
cp "$ROOT/packaging/config.pi.json" "$STAGE/usr/share/grotti/config.pi.json"
|
||||
cp "$ROOT/packaging/config.pi.json" "$STAGE/etc/grotti/config.json"
|
||||
cp "$ROOT/packaging/grotti.service" "$STAGE/lib/systemd/system/grotti.service"
|
||||
cp "$ROOT/docs/Anleitung-Installation-Pi.md" "$STAGE/usr/share/doc/grotti/"
|
||||
cp "$ROOT/CHANGELOG.md" "$STAGE/usr/share/doc/grotti/changelog"
|
||||
gzip -9 -f "$STAGE/usr/share/doc/grotti/changelog"
|
||||
|
||||
cat > "$STAGE/usr/bin/grotti" <<'EOF'
|
||||
#!/bin/sh
|
||||
export GROTTI_CONFIG="${GROTTI_CONFIG:-/etc/grotti/config.json}"
|
||||
exec /usr/lib/grotti/venv/bin/python /usr/lib/grotti/server.py "$@"
|
||||
EOF
|
||||
chmod 755 "$STAGE/usr/bin/grotti"
|
||||
|
||||
python3 -m venv "$STAGE/usr/lib/grotti/venv"
|
||||
"$STAGE/usr/lib/grotti/venv/bin/pip" install --upgrade pip wheel
|
||||
"$STAGE/usr/lib/grotti/venv/bin/pip" install -r "$ROOT/requirements.txt"
|
||||
|
||||
SIZE_KB="$(du -sk "$STAGE" | awk '{print $1}')"
|
||||
cat > "$STAGE/DEBIAN/control" <<EOF
|
||||
Package: grotti
|
||||
Version: ${VERSION}
|
||||
Section: web
|
||||
Priority: optional
|
||||
Architecture: ${ARCH}
|
||||
Maintainer: Dominic Gundel <[email protected]>
|
||||
Depends: python3 (>= 3.11), python3-venv, postgresql, adduser
|
||||
Installed-Size: ${SIZE_KB}
|
||||
Homepage: https://git.gundel.dev/dg/grotti
|
||||
Description: Farm-Manager für Moonraker-Drucker (Kobra 3 / S1)
|
||||
Grotti steuert eine 3D-Drucker-Farm über Moonraker: Wand, Warteschlange,
|
||||
Material, Abläufe und Protokoll. PostgreSQL wird lokal mit eingerichtet.
|
||||
EOF
|
||||
|
||||
cp "$ROOT/packaging/debian/conffiles" "$STAGE/DEBIAN/conffiles"
|
||||
for script in postinst prerm postrm; do
|
||||
cp "$ROOT/packaging/debian/$script" "$STAGE/DEBIAN/$script"
|
||||
chmod 755 "$STAGE/DEBIAN/$script"
|
||||
done
|
||||
|
||||
dpkg-deb --root-owner-group --build "$STAGE" "$DIST/${PKG}.deb"
|
||||
echo "Gebaut: $DIST/${PKG}.deb"
|
||||
echo "Install: sudo apt install ./packaging/dist/${PKG}.deb"
|
||||
echo "Logs: journalctl -u grotti -f"
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"host": "0.0.0.0",
|
||||
"port": 8770,
|
||||
"data_dir": "/var/lib/grotti/data",
|
||||
"watch_dir": "/var/lib/grotti/slice",
|
||||
"database_url": "postgresql:///grotti?host=/var/run/postgresql",
|
||||
"token": "",
|
||||
"secret_key": "",
|
||||
"fqdn": "",
|
||||
"log_level": "INFO",
|
||||
"auto_queue": true,
|
||||
"auto_retry": true,
|
||||
"oauth": {
|
||||
"enabled": false,
|
||||
"issuer": "",
|
||||
"client_id": "",
|
||||
"client_secret": "",
|
||||
"redirect_uri": ""
|
||||
},
|
||||
"energy": {
|
||||
"watts": 40,
|
||||
"nozzle_watts": 60,
|
||||
"bed_watts": 220,
|
||||
"euro_per_kwh": 0.35,
|
||||
"dryer_watts": 0,
|
||||
"dry_hours": 0,
|
||||
"waste_percent": 0,
|
||||
"utilization": 50,
|
||||
"tariff": {
|
||||
"ht_euro": 0.35,
|
||||
"nt_euro": 0.22,
|
||||
"nt_from": "22:00",
|
||||
"nt_to": "06:00"
|
||||
}
|
||||
},
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"bot_token": "",
|
||||
"chat_id": ""
|
||||
},
|
||||
"ntfy": {
|
||||
"enabled": false,
|
||||
"server": "https://ntfy.sh",
|
||||
"topic": "",
|
||||
"token": ""
|
||||
},
|
||||
"alerts": {
|
||||
"fertig": true,
|
||||
"fehler": true,
|
||||
"offline": true,
|
||||
"queue": true,
|
||||
"spule": true,
|
||||
"ablauf": false,
|
||||
"start": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
/etc/grotti/config.json
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
_pg() {
|
||||
if command -v runuser >/dev/null 2>&1; then
|
||||
runuser -u postgres -- "$@"
|
||||
else
|
||||
su -s /bin/sh postgres -c "$*"
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
if ! getent passwd grotti >/dev/null; then
|
||||
adduser --system --group --home /var/lib/grotti --no-create-home \
|
||||
--gecos "Grotti farm manager" grotti
|
||||
fi
|
||||
|
||||
mkdir -p /var/lib/grotti/data/eingang /var/lib/grotti/slice /etc/grotti
|
||||
chown -R grotti:grotti /var/lib/grotti
|
||||
chmod 750 /var/lib/grotti
|
||||
|
||||
if [ ! -f /etc/grotti/config.json ]; then
|
||||
cp /usr/share/grotti/config.pi.json /etc/grotti/config.json
|
||||
fi
|
||||
chmod 640 /etc/grotti/config.json
|
||||
chown root:grotti /etc/grotti/config.json
|
||||
|
||||
if getent passwd postgres >/dev/null 2>&1; then
|
||||
_pg psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='grotti'" | grep -q 1 \
|
||||
|| _pg createuser -D -R -S grotti || true
|
||||
_pg psql -tAc "SELECT 1 FROM pg_database WHERE datname='grotti'" | grep -q 1 \
|
||||
|| _pg createdb -O grotti grotti || true
|
||||
_pg psql -c "GRANT ALL PRIVILEGES ON DATABASE grotti TO grotti;" >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
systemctl daemon-reload || true
|
||||
systemctl enable grotti.service || true
|
||||
systemctl restart grotti.service || true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
purge)
|
||||
rm -f /etc/grotti/config.json
|
||||
rmdir /etc/grotti 2>/dev/null || true
|
||||
# Daten und DB bleiben absichtlich (Backup). Manuell:
|
||||
# sudo rm -rf /var/lib/grotti
|
||||
# sudo -u postgres dropdb grotti; sudo -u postgres dropuser grotti
|
||||
;;
|
||||
remove)
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
systemctl daemon-reload || true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
remove|upgrade|deconfigure)
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
systemctl stop grotti.service 2>/dev/null || true
|
||||
systemctl disable grotti.service 2>/dev/null || true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
Vendored
Whitespace-only changes.
@@ -0,0 +1,24 @@
|
||||
[Unit]
|
||||
Description=Grotti Farm-Manager
|
||||
Documentation=file:///usr/share/doc/grotti/Anleitung-Installation-Pi.md
|
||||
After=network-online.target postgresql.service
|
||||
Wants=network-online.target
|
||||
Requires=postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=grotti
|
||||
Group=grotti
|
||||
WorkingDirectory=/usr/lib/grotti
|
||||
Environment=GROTTI_CONFIG=/etc/grotti/config.json
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
ExecStart=/usr/lib/grotti/venv/bin/python /usr/lib/grotti/server.py
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
# Logs → journald (journalctl -u grotti -f)
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=grotti
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in new issue
Block a user