first commit
This commit is contained in:
commit
c5aec2da8d
54
backupME.conf
Normal file
54
backupME.conf
Normal file
@ -0,0 +1,54 @@
|
||||
### Konfiguration
|
||||
# wie soll das Verzeichnis heißen wo die Backups hin geschrieben werden
|
||||
BACKUPDIRNAME=fhem_backups
|
||||
|
||||
# Name der Backupdatei
|
||||
BACKUPFILENAME=fhem_backup
|
||||
|
||||
# Startverzeichnis wo Daten liegen zum sichern
|
||||
SOURCEPATH=/opt/fhem/backup
|
||||
|
||||
# Dateien Komma getrennt welche gesichert werden sollen. Kann auch zum Beispiel mittels *.md oder * fur alles lauten. Muss sich aber unterhalb von SOURCEPATH befinden
|
||||
FILES_TO_BACKUP=FHEM-"`date +%Y%m%d`"*.tar.gz
|
||||
|
||||
# Verzeichnis unter welches die Backupstruktur aufgebaut werden soll.
|
||||
BACKUPPATH=/home/marko/Google_Drive_Secure/pi-webapp01_BACKUPS
|
||||
|
||||
# wie viele Backups sollen aufgehoben werden.
|
||||
DAILY_DATA_BACKUPS=6
|
||||
|
||||
|
||||
|
||||
### Special Konfiguration
|
||||
# Soll bei nicht vorhanden sein des Backupverzeichnis das Skript abgebrochen werden. Sinnvoll bei encfs oder eingebundenen Netzwerkverzeichnissen. 0 nein 1 ja
|
||||
SPECIALCHECK_BACKUPPATH=1
|
||||
|
||||
# Verzeichnisse welche aufgeräumt werden sollen. Löschen aller Daten älter CLEAN_UP_DAYS Tage
|
||||
CLEAN_UP_PATHS=/opt/fhem/backup/*
|
||||
|
||||
# löschen älter X Tage
|
||||
CLEAN_UP_DAYS=4
|
||||
|
||||
# soll das Ergebnis des Backups (ok|error) in ein FHEM Dummy geschrieben werden? 0 nein 1 ja
|
||||
# telnet Instanz muss ohne SSL und Passwort vorhanden sein
|
||||
FHEMSUPPORT=1
|
||||
|
||||
# Name des FHEM Dummys für das schreiben des Ergebnisses
|
||||
FHEMDUMMY=dummyBackupScript
|
||||
|
||||
|
||||
### MySQL DB Dumps
|
||||
# soll ein MYSQL Dump erstellt werden 0 nein 1 ja
|
||||
MYSQLDUMP=0
|
||||
|
||||
# Datenbank User
|
||||
DBUSER=
|
||||
|
||||
# Datenbank User Passwort
|
||||
DBPASS=
|
||||
|
||||
# Instanzname der Datenbank
|
||||
DBNAMES=fhemLogHistory
|
||||
|
||||
# wo soll der Dump hingeschrieben werden
|
||||
DBBACKUPPATH=/opt/fhem/backup
|
310
backupME.pl
Normal file
310
backupME.pl
Normal file
@ -0,0 +1,310 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Developed with Kate
|
||||
#
|
||||
# (c) 2019 Copyright: Marko Oldenburg (marko.oldenburg at araneaconsult dot de)
|
||||
# All rights reserved
|
||||
#
|
||||
#
|
||||
# This script is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
# A copy is found in the textfile GPL.txt and important notices to the license
|
||||
# from the author is found in LICENSE.txt distributed with these scripts.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# Version 1.0.0.2
|
||||
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use POSIX;
|
||||
|
||||
use Term::ANSIColor;
|
||||
use IO::Socket::INET;
|
||||
|
||||
##################################################
|
||||
# Forward declarations
|
||||
#
|
||||
sub readConfigFile;
|
||||
sub logMessage($$);
|
||||
sub MainBackup;
|
||||
sub checkBackUpPathStructsExist($);
|
||||
sub createBackUpPathStructs($);
|
||||
sub toCleanUp($);
|
||||
sub rotateDailyBackupfiles;
|
||||
sub createDBdump;
|
||||
sub runBackup($);
|
||||
sub sendStateToFHEM($);
|
||||
|
||||
##################################################
|
||||
# Variables:
|
||||
my $self = {};
|
||||
|
||||
|
||||
|
||||
###################################################
|
||||
# Start the program
|
||||
my ($conffile,$debug,$acount);
|
||||
$debug = 0;
|
||||
$conffile = shift @ARGV if( scalar(@ARGV) > 0 );
|
||||
|
||||
unless ( defined($conffile) and $conffile ) {
|
||||
logMessage(3,'no Configfile specified');
|
||||
exit;
|
||||
}
|
||||
|
||||
unless ( -e $conffile ) {
|
||||
logMessage(3,'can\'t find Configfile');
|
||||
exit;
|
||||
}
|
||||
|
||||
$self->{config}->{TARCMDPATH} = qx(which tar);
|
||||
chomp($self->{config}->{TARCMDPATH});
|
||||
|
||||
unless ( defined($self->{config}->{TARCMDPATH}) and $self->{config}->{TARCMDPATH} ) {
|
||||
logMessage(3,'can\'t find tar command');
|
||||
exit 0;
|
||||
}
|
||||
|
||||
unless ( readConfigFile ) {
|
||||
MainBackup;
|
||||
} else { logMessage(3,'cant\'t read config file'); exit 0 };
|
||||
|
||||
|
||||
exit 0;
|
||||
|
||||
##### SUBS ####
|
||||
|
||||
sub MainBackup {
|
||||
my $fnState = 0;
|
||||
my @bckPathStructur = ('archive','daily');
|
||||
|
||||
if ( not checkBackUpPathStructsExist($self->{config}->{BACKUPPATH}) and $self->{config}->{SPECIALCHECK_BACKUPPATH} ) {
|
||||
logMessage(3,'can\'t find ' . $self->{config}->{BACKUPPATH} . '! check special mount?(encf,NFS,SMB)');
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach (@bckPathStructur) {
|
||||
createBackUpPathStructs($_) unless ( checkBackUpPathStructsExist($_) );
|
||||
}
|
||||
|
||||
if ( defined($self->{config}->{CLEAN_UP_PATHS}) and $self->{config}->{CLEAN_UP_PATHS} ) {
|
||||
logMessage(1,'Start cleanup Procedure');
|
||||
|
||||
$self->{config}->{FINDCMDPATH} = qx(which find);
|
||||
chomp($self->{config}->{FINDCMDPATH});
|
||||
|
||||
if ( defined($self->{config}->{FINDCMDPATH}) and $self->{config}->{FINDCMDPATH} ) {
|
||||
foreach (split(/,/,$self->{config}->{CLEAN_UP_PATHS})) {
|
||||
toCleanUp($_);
|
||||
}
|
||||
} else { return logMessage(3,'no find command found') }
|
||||
}
|
||||
|
||||
$fnState = rotateDailyBackupfiles unless ($fnState);
|
||||
$fnState = createDBdump() if ( $self->{config}->{MYSQLDUMP} and not $fnState );
|
||||
$fnState = runBackup(( (split(" ", localtime(time)))[0] =~ /^(Sun)$/ ? 'archiv' : 'daily' )) unless ($fnState);
|
||||
|
||||
sendStateToFHEM( ($fnState ? 'error' : 'ok') ) if ( $self->{config}->{FHEMSUPPORT} );
|
||||
}
|
||||
|
||||
sub runBackup($) {
|
||||
my $bckarchiv = shift;
|
||||
|
||||
my $state = 1;
|
||||
my $filesToBackUpString;
|
||||
foreach (split(/,/,$self->{config}->{FILES_TO_BACKUP})) {
|
||||
$filesToBackUpString .= $self->{config}->{SOURCEPATH} . '/' . $_ . ' ';
|
||||
}
|
||||
|
||||
if ( open( CMD, "$self->{config}->{TARCMDPATH} -cvjf $self->{config}->{BACKUPPATH}/$self->{config}->{BACKUPDIRNAME}/$bckarchiv/$self->{config}->{BACKUPFILENAME}.1.tar.bz2 $filesToBackUpString 2>&1 |" ) ) {
|
||||
while ( my $line = <CMD> ) {
|
||||
chomp($line);
|
||||
print qq($line\n) if ( $debug == 1 );
|
||||
|
||||
if ( $line =~ m#($self->{config}->{SOURCEPATH}.*)# ) {
|
||||
logMessage(1,'Erstelle Backup von ' . $1 . ' nach ' . $self->{config}->{BACKUPPATH}.'/'.$self->{config}->{BACKUPDIRNAME}.'/'.$bckarchiv.'/'.$self->{config}->{BACKUPFILENAME}.'.1.tar.bz2');
|
||||
$state = 0;
|
||||
}
|
||||
}
|
||||
close(CMD);
|
||||
}
|
||||
else {
|
||||
logMessage(3,"Couldn't use CMD: $!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
sub createDBdump {
|
||||
$self->{config}->{MYSQLDUMPCMDPATH} = qx(which mysqldump);
|
||||
chomp($self->{config}->{MYSQLDUMPCMDPATH});
|
||||
|
||||
return logMessage(3,'can\'t find mysqldump command') unless ( defined($self->{config}->{MYSQLDUMPCMDPATH}) and $self->{config}->{MYSQLDUMPCMDPATH} );
|
||||
|
||||
my $state;
|
||||
foreach (split(/,/,$self->{config}->{DBNAMES})) {
|
||||
$state = 1;
|
||||
if ( open( CMD, "$self->{config}->{MYSQLDUMPCMDPATH} --user=$self->{config}->{DBUSER} --password=$self->{config}->{DBPASS} -Q $_ | gzip > $self->{config}->{DBBACKUPPATH}/$_\_\"`date +%d-%m-%Y`\".sql.gz 2>&1 |" ) ) {
|
||||
logMessage(1,'Erstelle Datenbank Dump für DB '.$_);
|
||||
$state = 0;
|
||||
close(CMD);
|
||||
}
|
||||
else {
|
||||
logMessage(3,"Couldn't use CMD: $!");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
sub rotateDailyBackupfiles {
|
||||
my $count;
|
||||
my $state = 1;
|
||||
|
||||
for ($count=$self->{config}->{DAILY_DATA_BACKUPS}-1;$count>0;$count--) {
|
||||
if ( -f $self->{config}->{BACKUPPATH} . '/' . $self->{config}->{BACKUPDIRNAME} . '/daily/' . $self->{config}->{BACKUPFILENAME} . '.' . $count . '.tar.bz2' ) {
|
||||
my $countNew = $count + 1;
|
||||
if ( open( CMD, "mv -v $self->{config}->{BACKUPPATH}/$self->{config}->{BACKUPDIRNAME}/daily/$self->{config}->{BACKUPFILENAME}.$count.tar.bz2 $self->{config}->{BACKUPPATH}/$self->{config}->{BACKUPDIRNAME}/daily/$self->{config}->{BACKUPFILENAME}.$countNew.tar.bz2 2>&1 |" ) ) {
|
||||
while ( my $line = <CMD> ) {
|
||||
chomp($line);
|
||||
print qq($line\n) if ( $debug == 1 );
|
||||
|
||||
if ( $line =~ m#^\S+($self->{config}->{BACKUPFILENAME}\S+)'\s.+\s\S+($self->{config}->{BACKUPFILENAME}\S+)'$# ) {
|
||||
logMessage(1,'Räume Backupverzeichnis auf. Move Backupfile '.$1.' to '.$2);
|
||||
$state = 0;
|
||||
}
|
||||
}
|
||||
close(CMD);
|
||||
}
|
||||
else {
|
||||
logMessage(3,"Couldn't use CMD: $!");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $state
|
||||
}
|
||||
|
||||
sub toCleanUp($) {
|
||||
my $cleanUpPath = shift;
|
||||
|
||||
my $state = 1;
|
||||
if ( open( CMD, "$self->{config}->{FINDCMDPATH} $cleanUpPath -mtime +$self->{config}->{CLEAN_UP_DAYS} -exec rm -vrf {} \\; 2>&1 |" ) ) {
|
||||
|
||||
while ( my $line = <CMD> ) {
|
||||
chomp($line);
|
||||
print qq($line\n) if ( $debug == 1 );
|
||||
|
||||
if ( $line =~ m#^^'(.+)'.+entfernt$# ) {
|
||||
logMessage(1,$1.' wurde entfernt');
|
||||
$state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
close(CMD);
|
||||
return $state;
|
||||
}
|
||||
else {
|
||||
logMessage(3,"Couldn't use CMD: $!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
sub readConfigFile {
|
||||
if ( open(CF, "<$conffile") ) {
|
||||
while ( my $line = <CF> ) {
|
||||
chomp($line);
|
||||
print qq($line\n) if ( $debug == 1 );
|
||||
|
||||
if ( $line =~ m#^([A-Z]+|[A-Z]+_[A-Z]+|[A-Z]+_[A-Z]+_[A-Z]+)=(.*)$# ) {
|
||||
$self->{config}->{$1} = $2;
|
||||
}
|
||||
}
|
||||
|
||||
close(CF);
|
||||
}
|
||||
else {
|
||||
logMessage(3,"Couldn't use CF: $!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub logMessage($$) {
|
||||
my ($level,$text) = @_;
|
||||
my %levels = ( 1 => 'bright_blue on_bright_green',
|
||||
2 => '',
|
||||
3 => 'bright_blue on_bright_red',
|
||||
);
|
||||
|
||||
print colored([$levels{$level}], $text, "\n");
|
||||
}
|
||||
|
||||
sub checkBackUpPathStructsExist($) {
|
||||
my $bckDir = shift;
|
||||
|
||||
if ( $bckDir ne $self->{config}->{BACKUPPATH} ) {
|
||||
if ( -d $self->{config}->{BACKUPPATH} . '/' . $self->{config}->{BACKUPDIRNAME} . '/' . $bckDir ) { return 1 } else { return 0 }
|
||||
} elsif ( $bckDir eq $self->{config}->{BACKUPPATH} ) {
|
||||
if ( -d $bckDir ) { return 1 } else { return 0 }
|
||||
}
|
||||
}
|
||||
|
||||
sub createBackUpPathStructs($) {
|
||||
my $bckDir = shift;
|
||||
|
||||
my $state = 1;
|
||||
if ( open( CMD, "mkdir -vp $self->{config}->{BACKUPPATH}/$self->{config}->{BACKUPDIRNAME}/$bckDir 2>&1 |" ) ) {
|
||||
while ( my $line = <CMD> ) {
|
||||
chomp($line);
|
||||
print qq($line\n) if ( $debug == 1 );
|
||||
|
||||
if ( $line =~ m#^mkdir:.+\s'(.+)'\sangelegt$# ) {
|
||||
logMessage(1,'Create Backupdirectory '.$1);
|
||||
$state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
close(CMD);
|
||||
return $state;
|
||||
}
|
||||
else {
|
||||
logMessage(3,"Couldn't use CMD: $!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
sub sendStateToFHEM($) {
|
||||
my $bckState = shift;
|
||||
|
||||
my $HOSTNAME = "127.0.0.1";
|
||||
my $HOSTPORT = "7072";
|
||||
my $socket = IO::Socket::INET->new('PeerAddr' => $HOSTNAME,'PeerPort' => $HOSTPORT,'Proto' => 'tcp') ;
|
||||
|
||||
print $socket 'setreading ' . $self->{config}->{FHEMDUMMY} . ' state ' . $bckState ."\n";
|
||||
|
||||
$socket->close;
|
||||
}
|
Loading…
Reference in New Issue
Block a user