mongodb_backup 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #!/usr/bin/python3
  2. # mongodb backup script
  3. # Copyright (C) 2021 Philipp Fromme
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. import ast
  18. import datetime, time
  19. import os, sys, pwd
  20. import string
  21. import subprocess
  22. import configparser
  23. config_file = '/etc/mongodb_backup.conf'
  24. config = configparser.ConfigParser()
  25. if os.path.exists(config_file):
  26. config.read(config_file)
  27. # Set variables from config file if available, otherwise default
  28. mdb_conf = config['mongodb-backup']
  29. BAKDIR = mdb_conf.get('BAKDIR', '/var/mongodb_bak')
  30. MAXAGE = mdb_conf.getint('MAXAGE', 1)
  31. MONGODB_OPT = mdb_conf.get('MONGODB_OPT')
  32. CLEANUPBEFORE = mdb_conf.getboolean('CLEANUPBEFORE', False)
  33. USERNAME = mdb_conf.get('USERNAME')
  34. PASSWORD = mdb_conf.get('PASSWORD')
  35. QUIET = mdb_conf.getboolean('QUIET', True)
  36. DB_IGNORE = dict(config.items('db_ignore'))
  37. DB_IGNORE_LIST = []
  38. for key, db in DB_IGNORE.items():
  39. DB_IGNORE_LIST.append(db)
  40. CURDIR = str(datetime.date.today())
  41. def backup(databases):
  42. dest_dir = os.path.join(BAKDIR, CURDIR)
  43. mongodump_cmd = ['/usr/bin/mongodump', '--out', dest_dir]
  44. if MONGODB_OPT:
  45. mongodump_cmd += [MONGODB_OPT]
  46. if QUIET:
  47. mongodump_cmd += ['--quiet']
  48. if USERNAME:
  49. mongodump_cmd += ['--username=' + USERNAME]
  50. if PASSWORD:
  51. mongodump_cmd += ['--password=' + PASSWORD]
  52. for db in databases:
  53. if db not in DB_IGNORE_LIST:
  54. db_arg = '--db=' + db
  55. mongodump_cmd += [db_arg]
  56. subprocess.run(mongodump_cmd)
  57. def cleanup():
  58. if not QUIET:
  59. print('Cleaning up backup directory.')
  60. for directory in os.listdir(BAKDIR):
  61. if os.path.isdir(directory) and not directory == 'current':
  62. if os.path.getmtime(directory) < time.time() - (MAXAGE * 24 * 3600):
  63. # if backup is older than MAXAGE. delete it.
  64. dirpath = os.path.join(BAKDIR, directory)
  65. for root, dirs, files in os.walk(dirpath, topdown=False):
  66. for f in files:
  67. rm_file = os.path.join(root, f)
  68. if not QUIET:
  69. print('removing file %s' % rm_file)
  70. os.remove(rm_file)
  71. for d in dirs:
  72. rm_dir = os.path.join(root, d)
  73. if not QUIET:
  74. print('removing directory %s' % rm_dir)
  75. os.rmdir(rm_dir)
  76. if not QUIET:
  77. print('removing directory %s' % dirpath)
  78. os.rmdir(dirpath)
  79. else:
  80. if not QUIET:
  81. print('skip directory %s' % directory)
  82. if os.path.islink('current'):
  83. os.remove('current')
  84. os.symlink(CURDIR, 'current')
  85. def main():
  86. # get databases
  87. get_db_cmd = ['mongo', '--quiet', '--eval', 'db.getMongo().getDBNames()']
  88. if USERNAME:
  89. get_db_cmd += ['--username=' + USERNAME]
  90. if PASSWORD:
  91. get_db_cmd += ['--password=' + PASSWORD]
  92. get_db_output = subprocess.check_output(get_db_cmd)
  93. db_list = ast.literal_eval(get_db_output.decode().strip())
  94. if not os.path.exists(BAKDIR):
  95. os.makedirs(BAKDIR)
  96. os.chmod(BAKDIR, mode=0o700)
  97. os.umask(0o177)
  98. os.chdir(BAKDIR)
  99. if not QUIET:
  100. print('Backup directory is %s' % (os.path.join(BAKDIR, CURDIR)))
  101. if CLEANUPBEFORE:
  102. cleanup()
  103. if not os.path.exists(CURDIR):
  104. os.mkdir(CURDIR)
  105. elif not QUIET:
  106. print('Folder already exists. Overwriting old backup from same day')
  107. if CLEANUPBEFORE:
  108. backup(db_list)
  109. else:
  110. backup(db_list)
  111. cleanup()
  112. if __name__ == '__main__':
  113. main()