diff --git a/ChangeLog b/ChangeLog index a75c477c..aeb3e3b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24932,3 +24932,6 @@ run on Python 3.6. 2024-11-05 Fred Gleason * Added a rdautocheck(8) utility. +2024-11-05 Fred Gleason + * Modified rdautoback(8) so as to be able to take multiple mount + point arguments. diff --git a/docs/manpages/rdautoback.xml b/docs/manpages/rdautoback.xml index bd1be56e..16b7e278 100644 --- a/docs/manpages/rdautoback.xml +++ b/docs/manpages/rdautoback.xml @@ -6,7 +6,7 @@ rdautoback 8 - October 2024 + November 2024 Linux Audio Manual @@ -30,7 +30,9 @@ rdautoback - mount-pt + mount-pt1 + mount-pt2 + ... @@ -42,12 +44,12 @@ (database+audiostore) used by the Rivendell Radio Automation System. - rdautoback8 takes exactly one - argument: the name of a storage mount point that has been configured - in fstab5. Upon startup, - rdautoback8 will attempt to - mount the specified mount point and make a copy of the following - Rivendell data elements: + rdautoback8 takes one or more + arguments; each the path name of a storage mount point that has been + configured in fstab5. + Upon startup, it will attempt to mount the filesystem corresponding to + each specified mount point and make a copy of the following Rivendell + data elements: @@ -82,6 +84,14 @@ rd.conf5 + , + + rdautorest8 + + , + + rdautocheck8 + diff --git a/utils/rdautoback/rdautoback.py b/utils/rdautoback/rdautoback.py index 408c0840..df63f588 100755 --- a/utils/rdautoback/rdautoback.py +++ b/utils/rdautoback/rdautoback.py @@ -28,12 +28,80 @@ from pathlib import Path import sys import syslog -USAGE='rdbackup.py ' +def BackupMountpoint(mntpt): + # + # Mount backup device + # + Path(mntpt).mkdir(parents=True,exist_ok=True) + result=os.WEXITSTATUS(os.system(command='mount '+mntpt+" 2> /dev/null")) + if((result!=0)and(result!=64)): + print(mntpt+': [not found]') + print() + return + os.system(command='sleep 5') + syslog.syslog(syslog.LOG_INFO,'Starting Rivendell backup to "'+mntpt+'"') -if(len(sys.argv)!=2): + # + # Dump database + # + cmd='mysqldump -h '+rd_config.get('mySQL','Hostname')+' -u '+rd_config.get('mySQL','Loginname')+' -p'+rd_config.get('mySQL','Password')+' '+rd_config.get('mySQL','Database')+' | gzip > '+mntpt+'/db.sql.gz' + os.system(command=cmd) + + # + # Copy Audio Store + # + cmd='rsync -av --delete /var/snd '+mntpt + os.system(command=cmd) + + # + # Generate Info File + # + with open(mntpt+'/INFO.txt','w') as f: + f.write('[Backup]\n') + f.write('Name='+mntpt+'\n') + with os.popen('date --iso-8601=seconds',mode='r') as f1: + f.write('DateTime='+f1.read()) + f1.close() + try: + db=MySQLdb.connect(user=rd_config.get('mySQL','Loginname'), + passwd=rd_config.get('mySQL','Password'), + host=rd_config.get('mySQL','Hostname'), + database=rd_config.get('mySQL','Database'), + charset='utf8mb4') + except TypeError: + db=MySQLdb.connect(user=rd_config.get('mySQL','Loginname'), + password=rd_config.get('mySQL','Password'), + host=rd_config.get('mySQL','Hostname'), + database=rd_config.get('mySQL','Database'), + charset='utf8mb4') + cursor=db.cursor() + cursor.execute('select `REALM_NAME` from `SYSTEM`') + f.write('RealmName='+cursor.fetchone()[0]+'\n') + cursor.execute('select `DB` from `VERSION`') + f.write('DatabaseSchema='+str(cursor.fetchone()[0])+'\n') + db.close() + with os.popen('du -h '+mntpt+'/snd',mode='r') as f1: + values=f1.read().split('\t') + f.write('AudioStorage='+values[0]+'\n') + f1.close() + with os.popen('ls -1 '+mntpt+'/snd | wc -l') as f1: + f.write('AudioFiles='+f1.read()) + f1.close() + f.close() + + # + # Unmount backup device + # + os.system(command='umount '+mntpt) + os.rmdir(mntpt) + + syslog.syslog(syslog.LOG_INFO,'Completed Rivendell backup to "'+mntpt+'"') + +USAGE='rdbackup.py [] [...]' + +if(len(sys.argv)<2): print(USAGE) exit(1) -mountpoint=sys.argv[1] # # Load rd.conf(5) @@ -44,74 +112,7 @@ rd_config.read_file(open('/etc/rd.conf')) # # Open the syslog # -syslog.openlog('rdautoback.py',logoption=syslog.LOG_PID|syslog.LOG_PERROR,facility=int(rd_config.get('Identity','SyslogFacility',fallback=syslog.LOG_USER))) -syslog.syslog(syslog.LOG_INFO,'Starting Rivendell backup to "'+mountpoint+'"') +syslog.openlog('rdautoback.py',logoption=syslog.LOG_PERROR,facility=int(rd_config.get('Identity','SyslogFacility',fallback=syslog.LOG_USER))) - -# -# Mount backup device -# -result=os.system(command='findmnt '+mountpoint) -if(os.WEXITSTATUS(result)!=0): - Path(mountpoint).mkdir(parents=True,exist_ok=True) - result=os.system(command='mount '+mountpoint) - if(os.WEXITSTATUS(result)!=0): - syslog.syslog(syslog.LOG_ERR,'unable to mount backup drive') - exit(1) - os.system(command='sleep 5') - -# -# Dump database -# -cmd='mysqldump -h '+rd_config.get('mySQL','Hostname')+' -u '+rd_config.get('mySQL','Loginname')+' -p'+rd_config.get('mySQL','Password')+' '+rd_config.get('mySQL','Database')+' | gzip > '+mountpoint+'/db.sql.gz' -os.system(command=cmd) - -# -# Copy Audio Store -# -cmd='rsync -av --delete /var/snd '+mountpoint -os.system(command=cmd) - -# -# Generate Info File -# -with open(mountpoint+'/INFO.txt','w') as f: - f.write('[Backup]\n') - f.write('Name='+mountpoint+'\n') - with os.popen('date --iso-8601=seconds',mode='r') as f1: - f.write('DateTime='+f1.read()) - f1.close() - try: - db=MySQLdb.connect(user=rd_config.get('mySQL','Loginname'), - passwd=rd_config.get('mySQL','Password'), - host=rd_config.get('mySQL','Hostname'), - database=rd_config.get('mySQL','Database'), - charset='utf8mb4') - except TypeError: - db=MySQLdb.connect(user=rd_config.get('mySQL','Loginname'), - password=rd_config.get('mySQL','Password'), - host=rd_config.get('mySQL','Hostname'), - database=rd_config.get('mySQL','Database'), - charset='utf8mb4') - cursor=db.cursor() - cursor.execute('select `REALM_NAME` from `SYSTEM`') - f.write('RealmName='+cursor.fetchone()[0]+'\n') - cursor.execute('select `DB` from `VERSION`') - f.write('DatabaseSchema='+str(cursor.fetchone()[0])+'\n') - db.close() - with os.popen('du -h '+mountpoint+'/snd',mode='r') as f1: - values=f1.read().split('\t') - f.write('AudioStorage='+values[0]+'\n') - f1.close() - with os.popen('ls -1 '+mountpoint+'/snd | wc -l') as f1: - f.write('AudioFiles='+f1.read()) - f1.close() - f.close() - -# -# Unmount backup device -# -os.system(command='umount '+mountpoint) -os.rmdir(mountpoint) - -syslog.syslog(syslog.LOG_INFO,'Completed Rivendell backup to "'+mountpoint+'"') +for arg in range(1,len(sys.argv)): + BackupMountpoint(sys.argv[arg]) diff --git a/utils/rdautocheck/rdautocheck.py b/utils/rdautocheck/rdautocheck.py index be62b17c..d3a5f0dc 100755 --- a/utils/rdautocheck/rdautocheck.py +++ b/utils/rdautocheck/rdautocheck.py @@ -66,4 +66,3 @@ if(len(sys.argv)<2): exit(1) for arg in range(1,len(sys.argv)): PrintMetadata(sys.argv[arg]) -