summaryrefslogtreecommitdiffstats
path: root/linhes/linhes-system/lh_system_backup_job
blob: 6d16596449276548efa89dd79e34c27b00365693 (plain)
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
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
#!/bin/bash
#process that uses this system backup script
# - lh_mtc.py

MYTH_RUN_STATUS="1"
. /etc/profile
. /etc/systemconfig
PLEXDIR=/var/lib/plex
KeepBackups=14
DATE=`date +%F_%H-%M`
backup_status=0
MYTHHOME=`lh_home_check.sh`
MYTHSHUTDOWN="/usr/bin/mythshutdown"

#find primary backup location
for dir in /data/storage/disk*
do
    if [ $dir == /data/storage/disk0 ]; then
        continue
    fi
    TESTDIR=`readlink $dir`
    if [ -n $TESTDIR ]; then
        BACKUPLINK=$dir
        BACKUPDISK=$TESTDIR
        BACKUPDIR=$TESTDIR/backup/system_backups
        break
    fi
done

if [ `mountpoint -q $BACKUPDISK 2> /dev/null` ]; then
    echo "    The system doesn't have a second drive. Backup skipped."
    exit $backup_status
fi


#find secondary backup location
for dir in /data/storage/disk*
do
    if [[ $dir == /data/storage/disk0 || $dir == $BACKUPLINK ]]; then
        continue
    fi
    TESTDIR=`readlink $dir`
    if [ -n $TESTDIR ]; then
        SECBACKUPLINK=$dir
        SECBACKUPDISK=$TESTDIR
        SECBACKUPDIR=$TESTDIR/backup/system_backups
        break
    fi
done

function lock_myth(){
    $MYTHSHUTDOWN --lock
}

function unlock_myth(){
    $MYTHSHUTDOWN --unlock
}

function backup_status_check(){
    if [ $1 -ne 0 ]
    then
        backup_status=1
    fi
}


function backup(){

    echo
    echo "Starting Backup"
    echo "Backup Directory: $BACKUPLINK --> $BACKUPDIR"
    echo "Secondary Backup Directory: $SECBACKUPLINK --> $SECBACKUPDIR"
    echo
    mkdir -p $BACKUPDIR/$DATE

    #backup database
    if [ $SystemType = MasterBackend -o $SystemType = Standalone ]
    then
        echo
        echo "Backup mariadb databases"
        pacman -Q mysql 2>/dev/null
        if [ $? = 0 ]
        then
            echo "    mythconverg  (mythtv database)"
            /usr/bin/mariadb-dump -x mythconverg > $BACKUPDIR/$DATE/mythconverg
            backup_status_check $?

            #this is everything
            echo "    All databases in one file"
            /usr/bin/mariadb-dump -x --all-databases > $BACKUPDIR/$DATE/all_databases
            backup_status_check $?
        fi
    fi

    echo "Backup saved settings"
    if [ -e  /usr/MythVantage/templates/settings ]
    then
        cp -rp  /usr/MythVantage/templates/settings $BACKUPDIR/$DATE/settings
        backup_status_check $?
    fi

    echo "Backup etc"
    cp -rp /etc  $BACKUPDIR/$DATE/etc

    echo "Backup Plex Media Server databases and preferences"
    if [ -e $PLEXDIR/Plex\ Media\ Server/Plug-in\ Support ]
    then
        mkdir $BACKUPDIR/$DATE/plex
        backup_status_check $?
    fi
    if [ -e  $PLEXDIR/Plex\ Media\ Server/Plug-in\ Support/Databases ]
    then
        mkdir -p $BACKUPDIR/$DATE/plex/Databases/
        backup_status_check $?
        cp -rp $PLEXDIR/Plex\ Media\ Server/Plug-in\ Support/Databases/*.db $BACKUPDIR/$DATE/plex/Databases/
        backup_status_check $?
        cp -rp $PLEXDIR/Plex\ Media\ Server/Plug-in\ Support/Databases/*.db-wal $BACKUPDIR/$DATE/plex/Databases/
        backup_status_check $?
        cp -rp $PLEXDIR/Plex\ Media\ Server/Plug-in\ Support/Databases/*.db-shm $BACKUPDIR/$DATE/plex/Databases/
        backup_status_check $?
    fi
    if [ -e  $PLEXDIR/Plex\ Media\ Server/Plug-in\ Support/Preferences ]
    then
        cp -rp $PLEXDIR/Plex\ Media\ Server/Plug-in\ Support/Preferences $BACKUPDIR/$DATE/plex/Preferences
        backup_status_check $?
    fi

    #create default backup_exclude.txt
    if [ ! -f $MYTHHOME/backup_config/backup_exclude.txt ]
    then
        mkdir -p $MYTHHOME/backup_config/
        touch $MYTHHOME/backup_config/backup_exclude.txt
        chmod 777 $MYTHHOME/backup_config/backup_exclude.txt
    fi

    for i in ".mythtv/cache" ".mythtv/themecache" ".mythtv/remotecache" ".mythtv/Cache-myth*" ".cache" "tmp" ".vnc/*log" ".vnc/*pid" ".plexht/userdata/Thumbnails" ".plexht/userdata/ThemeMusicCache" ".kodi/userdata/Thumbnails"
    do
        grep -qF "$i" $MYTHHOME/backup_config/backup_exclude.txt
        rc=$?
        if [ $rc != 0 ]
        then
            echo "$i" >> $MYTHHOME/backup_config/backup_exclude.txt
        fi
    done

    echo "Backup home dirs"
    HOMEDIRS=""
    tar -I pigz -cf $BACKUPDIR/$DATE/home_dir.tar.gz -X $MYTHHOME/backup_config/backup_exclude.txt  $MYTHHOME $HOMEDIRS

    if [ -f $MYTHHOME/backup_config/backup_include.txt ]
    then
        echo
        echo "Backup items from $MYTHHOME/backup_config/backup_include.txt"
        tar -I pigz -cf $BACKUPDIR/$DATE/other.tar.gz -T $MYTHHOME/backup_config/backup_include.txt
        backup_status_check $?
    fi

    echo "Compress backup file"
    cd $BACKUPDIR
    tar -I pigz -cf $BACKUPDIR/backup.$DATE.tgz  $DATE
    backup_status_check $?
    if [ -d $BACKUPDIR/$DATE ]
    then
        rm -rf $BACKUPDIR/$DATE
    fi

    if [ $backup_status -eq 0 ]
    then
        BACKUPPATH=$BACKUPDIR/backup.$DATE.tgz
    else
        echo "Backup had an error"
        mkdir $BACKUPDIR/errored_backups
        mv $BACKUPDIR/backup.$DATE.tgz $BACKUPDIR/errored_backups/backup.$DATE.tgz
        BACKUPPATH=$BACKUPDIR/errored_backups/backup.$DATE.tgz
    fi

    if [ -f /home/xymon/server/ext/hbnotes.py ]
    then
        /home/xymon/server/ext/hbnotes.py
        chown nobody:nobody /data/srv/httpd/htdocs/hobbit/notes/* 2> /dev/null >/dev/null
    fi
    echo
    echo "Created backup file:"
    echo "    $BACKUPPATH"
}

function update_backup_status(){
    echo
    # Add Last backup status to menu item
    #if description not in the backup xml file, add it
    if [ $rc=0 ]
    then
        COMPLETE_MSG="Last backup completed `date '+%D %-I:%M %p'`"
    else
        COMPLETE_MSG="Last backup FAILED `date '+%D %-I:%M %p'`"
    fi
    echo "Updating menu with:"
    echo "    $COMPLETE_MSG"
    xmlfile="/usr/share/mythtv/themes/defaultmenu/mythbackup.xml"

    grep  -q "<description>" $xmlfile >/dev/null
    desc_check=$?

    if [ $desc_check = 0 ]
    then
        sed -i "0,/<description\>.*\<description\>/s||\<description\>$COMPLETE_MSG<\/description|" $xmlfile
        #sed -i "0,/\<description\>.*\<description\>/s//\<description\>$COMPLETE_MSG\<\/description/" $xmlfile
    else
        sed -i " /NONE/ i\     \<description\>$COMPLETE_MSG\<\/description\>" $xmlfile
    fi
}

function remove_old_backups(){
    #remove old backups
    NumBackups=`ls $BACKUPDIR/backup*.tgz|wc -l`
    if [[ $NumBackups -gt  $KeepBackups ]]; then
        numdel=$(($NumBackups-$KeepBackups))
        rm -f `ls $BACKUPDIR/backup*.tgz -tr1|head -$numdel`
    fi
}


function remote_backup(){
    echo
    echo "Remote backup"
    #Remote copy
    if [ x$RemoteBackup = x1 ]
    then
        localRemoteCheck=`echo $RemoteBackupDir | cut -d: -f1`
        if [  x$localRemoteCheck =  xdir ]
        then
            localRemotedir=`echo $RemoteBackupDir | cut -d: -f2`
            echo "    copying $BACKUPDIR/backup.$DATE.tgz to  $localRemotedir  "
            cp $BACKUPDIR/backup.$DATE.tgz  $localRemotedir
        else
            /usr/bin/func  ${RemoteBackupDir}  ping| grep -q "FAILED"
            rc=$?
            if [ $rc = 0 ]
            then
                #this is here to mark failed copy of the backup.
                #There is a cron.hourly job that will attempt to retransfer the file
                echo "    Remote backup failed to ${RemoteBackupDir}"
                echo backup.$DATE.tgz >> $BACKUPDIR/remote_backup_failed.txt
            else
                echo "    copying $BACKUPDIR/backup.$DATE.tgz to  ${RemoteBackupDir}:$BACKUPDIR/MBE_$DATE.tgz"
                /usr/bin/func  ${RemoteBackupDir} copyfile  -f  $BACKUPDIR/backup.$DATE.tgz  --remotepath $BACKUPDIR/MBE_$DATE.tgz
            fi
        fi
    else  #do local copy to SECBACKUPLINK
        echo "    Remote backup is not enabled, copying backup to another drive on this system."

        if [ -n "$SECBACKUPDISK" ]; then
            SECBACKUP=$SECBACKUPDISK/backup
            if [ ! `mountpoint -q $SECBACKUPDISK 2> /dev/null` ]; then
                if [ ! -d "$SECBACKUPDIR" ]; then
                    mkdir -p -m 775 $SECBACKUPDIR
                    echo "    Created $SECBACKUPDIR"
                    chown mythtv:users $SECBACKUPDIR
                fi
                echo "    Copying system backups to $SECBACKUPDIR"
                rsync -au --delete $BACKUPDIR/ $SECBACKUPDIR/
            else
                echo "    $SECBACKUPDISK isn't mounted."
            fi
        else
            echo "    Could not find another drive on this system."
        fi
    fi
}

function remote_transfer(){
    transfer_file=${1}
    echo $transfer_file
    /usr/bin/func  ${RemoteBackupDir}  ping| grep -q "FAILED"
    rc=$?
    if [ $rc = 0 ]
    then
        #this is here to mark a failed copy of the backup.
        #There is a cron.hourly job that will attempt to retransfer the file
        echo "    Remote backup failed to ${RemoteBackupDir}"
        echo $transfer_file >> $BACKUPDIR/remote_backup_failed.txt
    else
        echo "    copying $BACKUPDIR/$transfer_file to  ${RemoteBackupDir}:$BACKUPDIR/MBE_$transfer_file"
        /usr/bin/func  ${RemoteBackupDir} copyfile  -f  $BACKUPDIR/$transfer_file  --remotepath $BACKUPDIR/MBE_$transfer_file
    fi
}

function add_link(){
    if [ -f $BACKUPDIR/remote_backup_failed.txt ]
    then
        RETRYFILE="/etc/cron.hourly/lh_backup_retry.sh"
        echo "#!/bin/bash" > $RETRYFILE
        echo "#This file was autogenerated and will be removed by lh_system_backup_job" >> $RETRYFILE
        echo "MYTH_RUN_STATUS=1">> $RETRYFILE
        echo ". /etc/profile">> $RETRYFILE
        echo "lh_system_backup_job retry">> $RETRYFILE
        chmod 755 $RETRYFILE
    fi
}

function remove_link(){
    RETRYFILE="/etc/cron.hourly/lh_backup_retry.sh"
    if [ ! -f $BACKUPDIR/remote_backup_failed.txt ]
    then
        rm -f $RETRYFILE
    fi
}


#------------------------------------
lock_myth
if [ "x$1" = "x" ]
then
    backup
    #update_backup_status
    #only remove old backups if there was no problems
    if [ $backup_status -eq 0 ]
    then
        remove_old_backups
    fi
    remote_backup
    add_link
else
    #this is where we attempt to transfer again as part of the cronjob
    if [ -f $BACKUPDIR/remote_backup_failed.txt ]
    then
        mv -f $BACKUPDIR/remote_backup_failed.txt /tmp
        while read line
        do
            echo $line
            remote_transfer $line
        done < /tmp/remote_backup_failed.txt
        rm -f /tmp/remote_backup_failed.txt
    fi
    remove_link
fi
unlock_myth
echo $backup_status > /var/run/systembackup.rc
exit $backup_status