-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup_notes_sqlite.sh
More file actions
316 lines (257 loc) · 11.2 KB
/
Copy pathsetup_notes_sqlite.sh
File metadata and controls
316 lines (257 loc) · 11.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
#!/bin/bash
# Root-Rechte prüfen
if [ "$EUID" -ne 0 ]; then
echo "FEHLER: Bitte führe dieses Skript als Root (z.B. sudo) aus!"
exit 1
fi
BASE_DIR="/opt"
# Suche nach bestehenden Instanzen
mapfile -t INSTANCES < <(find $BASE_DIR -maxdepth 1 -type d -name "notiz-*" 2>/dev/null)
echo "================================================================="
echo " 📝 Notiz-Tool Setup & Instanz-Manager"
echo "================================================================="
echo ""
if [ ${#INSTANCES[@]} -gt 0 ]; then
echo "Gefundene Instanzen auf diesem Server:"
for i in "${!INSTANCES[@]}"; do
DISP_NAME=$(basename "${INSTANCES[$i]}" | sed 's/notiz-//')
echo " - $DISP_NAME (Port wird automatisch verwaltet)"
done
echo ""
echo "Was möchtest du tun?"
echo "[1] Eine NEUE Instanz anlegen"
echo "[2] Alle bestehenden Instanzen AKTUALISIEREN (Code-Update einspielen)"
echo "[3] Eine bestehende Instanz LÖSCHEN (Restlos deinstallieren)"
read -p "Deine Auswahl (1, 2 oder 3) [Standard: 1]: " ACTION
ACTION=${ACTION:-1}
else
echo "Willkommen! Es wurden keine bestehenden Instanzen gefunden."
echo "Wir starten nun mit der Neuinstallation der ersten Instanz."
ACTION="1"
fi
# ==========================================
# FUNKTION: Code von GitHub herunterladen
# ==========================================
write_app_code() {
local TARGET_DIR=$1
echo "Lade Code und Assets von GitHub herunter..."
# Ordnerstruktur vorbereiten
mkdir -p "$TARGET_DIR/static"
mkdir -p "$TARGET_DIR/templates"
mkdir -p "$TARGET_DIR/uploads/contacts"
mkdir -p "$TARGET_DIR/backups"
apt-get install -y unzip wget > /dev/null 2>&1
wget -qO /tmp/notizen-static.zip https://github.com/ipod86/Notes/archive/refs/heads/main.zip
unzip -qo /tmp/notizen-static.zip -d /tmp/notizen-extract
# Prüfen ob Download erfolgreich war
if [ ! -d "/tmp/notizen-extract/Notes-main" ]; then
echo "❌ FEHLER: Download von GitHub fehlgeschlagen!"
rm -rf /tmp/notizen-static.zip /tmp/notizen-extract
exit 1
fi
# 1. Inhalt von 'app' direkt ins Hauptverzeichnis
cp -r /tmp/notizen-extract/Notes-main/app/. "$TARGET_DIR/"
# 2. Den GESAMTEN Inhalt von 'static' (Ordner + Dateien) kopieren
cp -r /tmp/notizen-extract/Notes-main/static/. "$TARGET_DIR/static/"
# 3. Den Inhalt von 'templates' kopieren
cp -r /tmp/notizen-extract/Notes-main/templates/. "$TARGET_DIR/templates/"
# Cleanup
rm -rf /tmp/notizen-static.zip /tmp/notizen-extract
chmod +x "$TARGET_DIR/backup.sh" 2>/dev/null || true
echo "✅ Code erfolgreich heruntergeladen."
}
# ==========================================
# AKTIONEN
# ==========================================
if [ "$ACTION" == "1" ]; then
# --- NEUE INSTANZ ANLEGEN ---
echo ""
echo "================================================================="
echo " 🏢 Schritt 1: Name der Instanz"
echo "================================================================="
echo "Wie soll deine neue Notiz-Instanz heißen?"
echo "Dieser Name wird für den Ordner (z.B. /opt/notiz-firma) und den"
echo "Systemd-Service (notizen-firma.service) verwendet."
echo "Bitte verwende nur Kleinbuchstaben und keine Leerzeichen."
read -p "Name der Instanz [Standard: main]: " INSTANCE_NAME
if [ -z "$INSTANCE_NAME" ]; then
INSTANCE_NAME="main"
fi
INSTALL_DIR="$BASE_DIR/notiz-$INSTANCE_NAME"
SERVICE_NAME="notizen-$INSTANCE_NAME.service"
CRON_FILE="/etc/cron.d/notizen-$INSTANCE_NAME"
# Prüfen, ob die Instanz bereits existiert
if [ -d "$INSTALL_DIR" ]; then
echo ""
echo "❌ FEHLER: Eine Instanz mit dem Namen '$INSTANCE_NAME' existiert bereits!"
echo "Bitte wähle im Hauptmenü Option [2] für ein Update oder [3] zum Löschen."
exit 1
fi
echo ""
echo "================================================================="
echo " 🔌 Schritt 2: Port-Konfiguration"
echo "================================================================="
echo "Über welchen Port soll diese Instanz erreichbar sein?"
echo "Wenn du z.B. 8081 wählst, erreichst du sie lokal unter http://IP:8081"
# Intelligenter Port-Check
while true; do
read -p "Gewünschter Port [Standard: 8080]: " USER_PORT
if [ -z "$USER_PORT" ]; then USER_PORT=8080; fi
if grep -q "FLASK_PORT=$USER_PORT" /etc/systemd/system/notizen*.service 2>/dev/null; then
echo "❌ FEHLER: Der Port $USER_PORT ist bereits für eine andere Notiz-Instanz reserviert! Bitte wähle einen anderen."
elif ss -tuln | grep -q ":$USER_PORT "; then
echo "❌ FEHLER: Der Port $USER_PORT wird gerade von einem anderen Programm auf dem Server verwendet! Bitte wähle einen anderen."
else
break
fi
done
echo ""
echo "================================================================="
echo " 🌐 Schritt 3: Webserver-Konfiguration"
echo "================================================================="
echo "Ist diese Instanz von außen (über das Internet) erreichbar?"
echo "Bei 'Ja' wird Gunicorn als professioneller Webserver installiert."
echo "Bei 'Nein' wird der Flask-Entwicklungsserver verwendet (reicht für lokales Netz)."
read -p "Öffentlich erreichbar? [y/N] [Standard: N]: " USE_GUNICORN
USE_GUNICORN=${USE_GUNICORN:-N}
echo ""
echo "================================================================="
echo " 💾 Schritt 4: Automatisches Backup"
echo "================================================================="
echo "Möchtest du, dass das System jede Nacht automatisch ein komprimiertes"
echo "Backup (.tar.gz) deiner Datenbank und Bilder anlegt?"
read -p "Backup aktivieren? [Y/n] [Standard: Y]: " BACKUP_CONFIRM
BACKUP_CONFIRM=${BACKUP_CONFIRM:-Y}
echo ""
echo "--- Starte Setup für $INSTALL_DIR auf Port $USER_PORT ---"
apt update && apt install -y python3 python3-pip python3-venv cron sqlite3
mkdir -p "$INSTALL_DIR"
python3 -m venv "$INSTALL_DIR/venv"
"$INSTALL_DIR/venv/bin/python3" -m pip install flask werkzeug requests
if [[ "$USE_GUNICORN" =~ ^[Yy]$ ]]; then
"$INSTALL_DIR/venv/bin/python3" -m pip install gunicorn
fi
write_app_code "$INSTALL_DIR"
if ! id -u notizen > /dev/null 2>&1; then
useradd -r -s /bin/false notizen
fi
chown -R notizen:notizen "$INSTALL_DIR"
find "$INSTALL_DIR" -type d -exec chmod 750 {} \;
find "$INSTALL_DIR" -type f -not -path "*/venv/*" -exec chmod 640 {} \;
chmod +x "$INSTALL_DIR/app.py"
chmod +x "$INSTALL_DIR/venv/bin/"* 2>/dev/null
if [[ "$USE_GUNICORN" =~ ^[Yy]$ ]]; then
EXEC_START="$INSTALL_DIR/venv/bin/gunicorn --workers 3 --bind 0.0.0.0:$USER_PORT --chdir $INSTALL_DIR app:app"
else
EXEC_START="$INSTALL_DIR/venv/bin/python $INSTALL_DIR/app.py"
fi
cat << SVCEOF > /etc/systemd/system/$SERVICE_NAME
[Unit]
Description=Notizen ($INSTANCE_NAME)
After=network.target
[Service]
User=notizen
Group=notizen
WorkingDirectory=$INSTALL_DIR
Environment="FLASK_PORT=$USER_PORT"
ExecStart=$EXEC_START
Restart=always
[Install]
WantedBy=multi-user.target
SVCEOF
systemctl daemon-reload
systemctl enable "$SERVICE_NAME"
systemctl start "$SERVICE_NAME"
# Eigene Cron-Datei für diese Instanz
echo "0 3 * * * notizen /usr/bin/python3 $INSTALL_DIR/cleanup.py" > "$CRON_FILE"
if [[ "$BACKUP_CONFIRM" =~ ^[Yy]$ ]]; then
echo "0 4 * * * notizen $INSTALL_DIR/backup.sh" >> "$CRON_FILE"
fi
chmod 644 "$CRON_FILE"
echo ""
if [[ "$USE_GUNICORN" =~ ^[Yy]$ ]]; then
echo "--- ✅ Instanz '$INSTANCE_NAME' auf Port $USER_PORT mit Gunicorn installiert! ---"
else
echo "--- ✅ Instanz '$INSTANCE_NAME' auf Port $USER_PORT installiert! ---"
fi
elif [ "$ACTION" == "2" ]; then
# --- BESTEHENDE INSTANZEN AKTUALISIEREN ---
echo ""
echo "Starte Update aller gefundenen Instanzen..."
for DIR in "${INSTANCES[@]}"; do
INSTANCE_NAME=$(basename "$DIR" | sed 's/notiz-//')
# Abwärtskompatibilität für das allererste Skript
if [ "$INSTANCE_NAME" == "tool" ]; then
SERVICE_NAME="notizen.service"
else
SERVICE_NAME="notizen-$INSTANCE_NAME.service"
fi
echo "-----------------------------------"
echo "Aktualisiere: $DIR (Service: $SERVICE_NAME)"
systemctl stop "$SERVICE_NAME" 2>/dev/null
write_app_code "$DIR"
chown -R notizen:notizen "$DIR"
chmod +x "$DIR/app.py"
chmod +x "$DIR/backup.sh"
chmod +x "$DIR/venv/bin/"* 2>/dev/null
systemctl start "$SERVICE_NAME"
echo "Fertig: $INSTANCE_NAME aktualisiert und neugestartet."
done
echo "-----------------------------------"
echo "--- ✅ Alle Instanzen sind auf dem neuesten Stand! ---"
elif [ "$ACTION" == "3" ]; then
# --- BESTEHENDE INSTANZ LÖSCHEN ---
echo ""
echo "================================================================="
echo " 🗑️ Instanz löschen"
echo "================================================================="
echo "Welche Instanz möchtest du restlos vom Server entfernen?"
echo ""
for i in "${!INSTANCES[@]}"; do
DISP_NAME=$(basename "${INSTANCES[$i]}" | sed 's/notiz-//')
echo " [$((i+1))] $DISP_NAME (${INSTANCES[$i]})"
done
echo " [0] Abbrechen und zurück"
echo ""
read -p "Bitte gib die Nummer der Instanz ein, die du löschen willst: " DEL_SELECTION
if [[ "$DEL_SELECTION" == "0" ]]; then
echo "Abbruch. Es wird nichts gelöscht."
exit 0
fi
if [[ "$DEL_SELECTION" =~ ^[0-9]+$ ]] && [ "$DEL_SELECTION" -gt 0 ] && [ "$DEL_SELECTION" -le "${#INSTANCES[@]}" ]; then
SELECTED_INDEX=$((DEL_SELECTION-1))
DEL_DIR="${INSTANCES[$SELECTED_INDEX]}"
DEL_NAME=$(basename "$DEL_DIR" | sed 's/notiz-//')
echo ""
echo "⚠️ ACHTUNG: Du bist dabei, die Instanz '$DEL_NAME' komplett zu löschen!"
echo "Das beinhaltet alle Notizen (data.db), Bilder, Skizzen, Backups und Einstellungen."
read -p "Bist du absolut sicher? (tippe 'ja' zum Löschen): " CONFIRM_DEL
if [ "$CONFIRM_DEL" == "ja" ]; then
if [ "$DEL_NAME" == "tool" ]; then
SERVICE_NAME="notizen.service"
CRON_NAME="notizen-tool"
else
SERVICE_NAME="notizen-$DEL_NAME.service"
CRON_NAME="notizen-$DEL_NAME"
fi
echo "Stoppe und entferne Service $SERVICE_NAME..."
systemctl stop "$SERVICE_NAME" 2>/dev/null
systemctl disable "$SERVICE_NAME" 2>/dev/null
rm -f "/etc/systemd/system/$SERVICE_NAME"
echo "Entferne Cronjobs..."
rm -f "/etc/cron.d/$CRON_NAME"
echo "Lösche Verzeichnis $DEL_DIR..."
rm -rf "$DEL_DIR"
systemctl daemon-reload
echo "✅ Instanz '$DEL_NAME' wurde restlos und sauber vom Server entfernt."
else
echo "Abbruch. Es wurde nichts gelöscht."
fi
else
echo "Ungültige Eingabe. Skript wird beendet."
exit 1
fi
else
echo "Ungültige Eingabe. Skript wird beendet."
exit 1
fi