Initialer Commit: Kundenverwaltung (PHP/Smarty)
Bestehende Codebasis als Ausgangsstand aufgenommen. - .gitignore: Kundendaten (uploads_*), Smarty-Compile-Cache (templates_c), Laufzeit-Temp und Datenbank-Dumps ausgeschlossen; Verzeichnisstruktur ueber .gitkeep erhalten - .gitattributes: Zeilenenden normalisiert (LF im Repo), Binaerformate markiert - db-backup.php: MySQL-Zugangsdaten kommen jetzt wie im Rest der Anwendung aus der externen Konfiguration statt hartkodiert aus der Datei; Passwort wird ueber eine temporaere Optionsdatei statt per Kommandozeile uebergeben, Fehler von mysqldump/gzip werden gemeldet, Aufraeumen aelterer Backups berechnet Jahr und Monat konsistent Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+131
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/*
|
||||
* Datenbank-Backup (Cronjob).
|
||||
*
|
||||
* Die Zugangsdaten kommen - wie im Rest der Anwendung - aus der externen
|
||||
* Konfigurationsdatei (CONFIG_PATH/CONFIG_FILE, siehe incs/constants.php)
|
||||
* und stehen nicht mehr hartkodiert in dieser Datei.
|
||||
*
|
||||
* ACHTUNG: constants.php leitet CONFIG_FILE aus dem aktuellen Arbeits-
|
||||
* verzeichnis ab. Der Cronjob muss deshalb im Installationsverzeichnis
|
||||
* gestartet werden:
|
||||
*
|
||||
* cd /home/intranet/kunden && php db-backup.php
|
||||
*/
|
||||
|
||||
require_once(__DIR__."/incs/constants.php");
|
||||
require_once(__DIR__."/incs/settings.php");
|
||||
|
||||
function rrmdir($dir) {
|
||||
if (is_dir($dir)) {
|
||||
$objects = scandir($dir);
|
||||
foreach ($objects as $object) {
|
||||
if ($object != "." && $object != "..") {
|
||||
if (filetype($dir."/".$object) == "dir") rrmdir($dir."/".$object); else unlink($dir."/".$object);
|
||||
}
|
||||
}
|
||||
reset($objects);
|
||||
rmdir($dir);
|
||||
}
|
||||
}
|
||||
|
||||
/* Wert fuer eine MySQL-Optionsdatei maskieren */
|
||||
function cnfquote($val) {
|
||||
return '"'.str_replace(array("\\", '"'), array("\\\\", '\\"'), $val).'"';
|
||||
}
|
||||
|
||||
function fail($msg) {
|
||||
fwrite(STDERR, "db-backup: ".$msg."\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(readsettings() != "valid")
|
||||
fail("Konfiguration ".CONFIG_PATH.CONFIG_FILE." nicht lesbar oder unvollstaendig.");
|
||||
|
||||
$path = "/home/intranet/backup/datenbank/";
|
||||
|
||||
/* $mysql_db kommt aus der Konfiguration, "angebot" wurde hier schon
|
||||
* immer zusaetzlich gesichert. */
|
||||
$backup_dbs = array_values(array_unique(array_filter(array($mysql_db, "angebot"))));
|
||||
|
||||
/* Das Passwort nicht als Kommandozeilenargument uebergeben - es waere
|
||||
* sonst fuer jeden lokalen Benutzer in der Prozessliste sichtbar. */
|
||||
$cnf = tempnam(sys_get_temp_dir(), "dbbak");
|
||||
if($cnf === false)
|
||||
fail("Temporaere Optionsdatei konnte nicht angelegt werden.");
|
||||
chmod($cnf, 0600);
|
||||
if(file_put_contents($cnf,
|
||||
"[client]\n".
|
||||
"host = ".cnfquote($mysql_server)."\n".
|
||||
"user = ".cnfquote($mysql_user)."\n".
|
||||
"password = ".cnfquote($mysql_pw)."\n") === false)
|
||||
{
|
||||
unlink($cnf);
|
||||
fail("Temporaere Optionsdatei konnte nicht geschrieben werden.");
|
||||
}
|
||||
|
||||
$day = date("d");
|
||||
$month = date("M");
|
||||
$year = date("Y");
|
||||
$stamp = date("d-m-Y");
|
||||
|
||||
/* Verzeichnis von vor zwei Monaten aufraeumen. Monat UND Jahr aus dem
|
||||
* selben Zeitpunkt ableiten, sonst wird zum Jahreswechsel ein falscher
|
||||
* Pfad geloescht. */
|
||||
$llast = strtotime("-2 month");
|
||||
$llastdir = $path.date("Y", $llast)."-".date("M", $llast);
|
||||
|
||||
if(!is_dir($path))
|
||||
fail("Backup-Verzeichnis ".$path." existiert nicht.");
|
||||
|
||||
$target = $path.$year."-".$month."/".$day;
|
||||
if(!is_dir($target) && !mkdir($target, 0700, true))
|
||||
{
|
||||
unlink($cnf);
|
||||
fail("Zielverzeichnis ".$target." konnte nicht angelegt werden.");
|
||||
}
|
||||
|
||||
if(is_dir($llastdir) && $llastdir != $path.$year."-".$month)
|
||||
rrmdir($llastdir);
|
||||
|
||||
$dumps = array();
|
||||
$failed = 0;
|
||||
|
||||
foreach($backup_dbs as $db)
|
||||
{
|
||||
$sql = $target."/".$db."_".$stamp.".sql";
|
||||
|
||||
$cmd = "mysqldump --defaults-extra-file=".escapeshellarg($cnf).
|
||||
" --result-file=".escapeshellarg($sql)." ".escapeshellarg($db);
|
||||
exec($cmd." 2>&1", $out, $rc);
|
||||
if($rc !== 0)
|
||||
{
|
||||
fwrite(STDERR, "db-backup: mysqldump fuer '".$db."' fehlgeschlagen: ".implode(" ", $out)."\n");
|
||||
@unlink($sql);
|
||||
$failed++;
|
||||
continue;
|
||||
}
|
||||
|
||||
exec("gzip -9 -f ".escapeshellarg($sql)." 2>&1", $out2, $rc2);
|
||||
if($rc2 !== 0)
|
||||
{
|
||||
fwrite(STDERR, "db-backup: gzip fuer '".$db."' fehlgeschlagen: ".implode(" ", $out2)."\n");
|
||||
$failed++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$dumps[] = $sql.".gz";
|
||||
}
|
||||
|
||||
unlink($cnf);
|
||||
|
||||
/* "current" auf die Dumps von heute zeigen lassen */
|
||||
rrmdir($path."current");
|
||||
if(!mkdir($path."current", 0700, true))
|
||||
fail("Verzeichnis ".$path."current konnte nicht angelegt werden.");
|
||||
|
||||
foreach($dumps as $dump)
|
||||
link($dump, $path."current/".basename($dump));
|
||||
|
||||
exit($failed ? 1 : 0);
|
||||
?>
|
||||
Reference in New Issue
Block a user