Browse Source

mongodb: Add backup script

Philipp Fromme 2 years ago
parent
commit
860fa02baa
4 changed files with 155 additions and 0 deletions
  1. 17 0
      mongodb/init.sls
  2. 130 0
      mongodb/mongodb_backup
  3. 7 0
      mongodb/mongodb_backup.conf
  4. 1 0
      mongodb/mongodb_backup.cron

+ 17 - 0
mongodb/init.sls

@@ -15,3 +15,20 @@ mongodb:
   service.running:
     - name: mongod
     - enable: True
+
+# Install cronjob, backup script and corresponding config file
+/etc/cron.d/mongodb_backup:
+  file.managed:
+    - source: salt://mongodb/mongodb_backup.cron
+
+/usr/local/sbin/mongodb_backup:
+  file.managed:
+    - source: salt://mongodb/mongodb_backup
+    - mode: 755
+
+/etc/mongodb_backup.conf:
+  file.managed:
+    - source: salt://mongodb/mongodb_backup.conf
+    - mode: 600
+    - user: root
+    - group: root

+ 130 - 0
mongodb/mongodb_backup

@@ -0,0 +1,130 @@
+#!/usr/bin/python3
+# mongodb backup script
+# Copyright (C) 2021 Philipp Fromme
+#
+# This program 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+import ast
+import datetime, time
+import os, sys, pwd
+import string
+import subprocess
+import configparser
+
+config_file = '/etc/mongodb_backup.conf'
+
+config = configparser.ConfigParser()
+if os.path.exists(config_file):
+    config.read(config_file)
+
+# Set variables from config file if available, otherwise default
+mdb_conf = config['mongodb-backup']
+BAKDIR = mdb_conf.get('BAKDIR', '/var/mongodb_bak')
+MAXAGE = mdb_conf.getint('MAXAGE', 1)
+MONGODB_OPT = mdb_conf.get('MONGODB_OPT')
+CLEANUPBEFORE = mdb_conf.getboolean('CLEANUPBEFORE', False)
+USERNAME = mdb_conf.get('USERNAME')
+PASSWORD = mdb_conf.get('PASSWORD')
+QUIET = mdb_conf.getboolean('QUIET', True)
+
+DB_IGNORE = dict(config.items('db_ignore'))
+DB_IGNORE_LIST = []
+for key, db in DB_IGNORE.items():
+    DB_IGNORE_LIST.append(db)
+
+CURDIR = str(datetime.date.today())
+
+def backup(databases):
+    dest_dir = os.path.join(BAKDIR, CURDIR)
+    mongodump_cmd = ['/usr/bin/mongodump', '--out', dest_dir]
+    if MONGODB_OPT:
+        mongodump_cmd += [MONGODB_OPT]
+    if QUIET:
+        mongodump_cmd += ['--quiet']
+    if USERNAME:
+        mongodump_cmd += ['--username=' + USERNAME]
+    if PASSWORD:
+        mongodump_cmd += ['--password=' + PASSWORD]
+    for db in databases:
+        if db not in DB_IGNORE_LIST:
+            db_arg = '--db=' + db
+            mongodump_cmd += [db_arg]
+            subprocess.run(mongodump_cmd)
+
+def cleanup():
+    if not QUIET:
+        print('Cleaning up backup directory.')
+    for directory in os.listdir(BAKDIR):
+        if os.path.isdir(directory) and not directory == 'current':
+            if os.path.getmtime(directory) < time.time() - (MAXAGE * 24 * 3600):
+                # if backup is older than MAXAGE. delete it.
+                dirpath = os.path.join(BAKDIR, directory)
+                for root, dirs, files in os.walk(dirpath, topdown=False):
+                    for f in files:
+                        rm_file = os.path.join(root, f)
+                        if not QUIET:
+                            print('removing file %s' % rm_file)
+                        os.remove(rm_file)
+                    for d in dirs:
+                        rm_dir = os.path.join(root, d)
+                        if not QUIET:
+                            print('removing directory %s' % rm_dir)
+                        os.rmdir(rm_dir)
+                if not QUIET:
+                    print('removing directory %s' % dirpath)
+                os.rmdir(dirpath)
+            else:
+                if not QUIET:
+                    print('skip directory %s' % directory)
+    if os.path.islink('current'):
+        os.remove('current')
+    os.symlink(CURDIR, 'current')
+
+def main():
+    # get databases
+    get_db_cmd = ['mongo', '--quiet', '--eval', 'db.getMongo().getDBNames()']
+    if USERNAME:
+        get_db_cmd += ['--username=' + USERNAME]
+    if PASSWORD:
+        get_db_cmd += ['--password=' + PASSWORD]
+    get_db_output = subprocess.check_output(get_db_cmd)
+    db_list = ast.literal_eval(get_db_output.decode().strip())
+
+    if not os.path.exists(BAKDIR):
+        os.makedirs(BAKDIR)
+        os.chmod(BAKDIR, mode=0o700)
+
+    os.umask(0o177)
+
+    os.chdir(BAKDIR)
+
+    if not QUIET:
+        print('Backup directory is %s' % (os.path.join(BAKDIR, CURDIR)))
+
+    if CLEANUPBEFORE:
+        cleanup()
+
+    if not os.path.exists(CURDIR):
+        os.mkdir(CURDIR)
+    elif not QUIET:
+        print('Folder already exists. Overwriting old backup from same day')
+
+    if CLEANUPBEFORE:
+        backup(db_list)
+    else:
+        backup(db_list)
+        cleanup()
+
+if __name__ == '__main__':
+    main()

+ 7 - 0
mongodb/mongodb_backup.conf

@@ -0,0 +1,7 @@
+[mongodb-backup]
+BAKDIR=/srv/backup/mongodb_bak
+MAXAGE=3
+QUIET=True
+
+[db_ignore]
+db1=local

+ 1 - 0
mongodb/mongodb_backup.cron

@@ -0,0 +1 @@
+0 23  * * * root /usr/local/sbin/mongodb_backup