summaryrefslogtreecommitdiff
diff options
-rw-r--r--README.md21
-rw-r--r--config.yaml12
-rwxr-xr-xhooks/hooks.py60
-rw-r--r--revision2
-rwxr-xr-xtemplates/backup.py.tpl53
5 files changed, 147 insertions, 1 deletions
diff --git a/README.md b/README.md
index d4f812f..6e62d9d 100644
--- a/README.md
+++ b/README.md
@@ -165,6 +165,18 @@ A sample of the default settings of the config.yaml file at the time of writing
default: "none"
type: string
description: Extra options ( exactly as you would type them in the command line ) to be added via the command line to the mongodb daemon
+ backups_enabled:
+ default: False
+ type: boolean
+ description: Enable daily backups to disk.
+ backup_directory:
+ default: "/home/ubuntu/backups"
+ type: string
+ description: Where can the backups be found.
+ backup_copies_kept:
+ default: 7
+ type: int
+ description: Number of backups to keep. Keeps one week's worth by default.
### Where:
@@ -315,6 +327,15 @@ To verify that your sharded cluster is running, connect to the mongo shell and r
- run sh.status()
You should see your the hosts for your shards in the status output.
+## Backups
+
+Backups can be enabled via config. Note that destroying the service cannot
+currently remove the backup cron job so it will continue to run. There is a
+setting for the number of backups to keep, however, to prevent from filling
+disk space.
+
+To fetch the backups scp the files down from the path in the config.
+
# Troubleshooting
diff --git a/config.yaml b/config.yaml
index 969d45e..9709f88 100644
--- a/config.yaml
+++ b/config.yaml
@@ -143,3 +143,15 @@ options:
default: "none"
type: string
description: Extra options ( exactly as you would type them in the command line ) to be added via the command line to the mongodb daemon
+ backups_enabled:
+ default: False
+ type: boolean
+ description: Enable daily backups to disk.
+ backup_directory:
+ default: "/home/ubuntu/backups"
+ type: string
+ description: Where can the backups be found.
+ backup_copies_kept:
+ default: 7
+ type: int
+ description: Number of backups to keep. Keeps one week's worth by default.
diff --git a/hooks/hooks.py b/hooks/hooks.py
index 1fcaa46..a4427b9 100755
--- a/hooks/hooks.py
+++ b/hooks/hooks.py
@@ -14,6 +14,10 @@ import signal
import socket
import time
+from os import chmod
+from os import remove
+from os.path import exists
+from string import Template
###############################################################################
# Supporting functions
@@ -826,6 +830,56 @@ def restart_mongod(wait_for=default_wait_for, max_tries=default_max_tries):
is True)
+def backup_cronjob(disable=False):
+ """Generate the cronjob to backup with mongodbump."""
+ juju_log('Setting up cronjob')
+ config_data = config_get()
+ backupdir = config_data['backup_directory']
+ bind_ip = config_data['bind_ip']
+ cron_file = '/etc/cron.d/mongodb'
+ cron_runtime = '@daily'
+ cron_runtime = '*/2 * * * *'
+
+ # Disable or not remove it and regenerate it with new config data.
+ if exists(cron_file):
+ remove(cron_file)
+
+ if not disable:
+ tpl_data = {
+ 'backup_copies': config_data['backup_copies_kept'],
+ 'backup_directory': backupdir,
+ 'unique_name': os.environ.get('JUJU_UNIT_NAME', bind_ip),
+ 'bind_ip': bind_ip,
+ 'port': config_data['port'],
+ }
+
+ script_filename = '/var/lib/mongodb/cronbackup.py'
+ script_template = 'templates/backup.py.tpl'
+
+ juju_log('Writing out cronbackup.py')
+ with open(script_template) as handle:
+ template = Template(handle.read())
+ rendered = template.substitute(tpl_data)
+
+ with open(script_filename, 'w') as output:
+ output.writelines(rendered)
+ chmod(script_filename, 0755)
+
+ juju_log('Installing cron.d/mongodb')
+
+ if exists(cron_file):
+ remove(cron_file)
+
+ with open(cron_file, 'w') as output:
+ output.write("""
+SHELL=/bin/bash
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+
+%s ubuntu python %s
+
+""" % (cron_runtime, script_filename))
+
+
###############################################################################
# Hook functions
###############################################################################
@@ -835,6 +889,7 @@ def install_hook():
juju_log("Installation of mongodb failed.")
return(False)
else:
+
return(True)
@@ -860,6 +915,11 @@ def config_changed():
mongodb_config = mongodb_conf(config_data)
update_file(default_mongodb_config, mongodb_config)
+ if config_data['backups_enabled']:
+ backup_cronjob()
+ else:
+ backup_cronjob(disable=True)
+
# web_admin_ui
if config_data['web_admin_ui']:
enable_web_admin_ui(new_web_admin_ui_port)
diff --git a/revision b/revision
index 7273c0f..e85087a 100644
--- a/revision
+++ b/revision
@@ -1 +1 @@
-25
+31
diff --git a/templates/backup.py.tpl b/templates/backup.py.tpl
new file mode 100755
index 0000000..bb1f079
--- /dev/null
+++ b/templates/backup.py.tpl
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+"""Generate the cronjob to backup with mongodbump."""
+
+from os import chdir
+from os import listdir
+from os import remove
+from os.path import exists
+from os.path import join
+from datetime import datetime
+from shutil import rmtree
+import subprocess
+from tempfile import mkdtemp
+
+
+when = datetime.now()
+backupdir = '$backup_directory'
+tmpdir = mkdtemp()
+
+# Clean up any old backup copies.
+current_backups = listdir(backupdir)
+current_backups.sort()
+for file in current_backups[0:-$backup_copies]:
+ remove(join(backupdir, file))
+
+chdir(tmpdir)
+
+# Make sure the directory to stick tarballs exist.
+if not exists(backupdir):
+ subprocess.call([
+ 'mkdir',
+ '-p',
+ backupdir,
+ ])
+
+# Generate a pretty unique backup filename.
+# The unique name might have slashes in it so replace them.
+backup_filename = "%s/%s-%s.tar.gz" % (
+ backupdir,
+ '$unique_name'.replace('/', '-'),
+ when.strftime("%Y%m%d-%H%M%S"),
+)
+
+# mongodump creates a directory per db. Drop them all in a tmpdir and then
+# we'll tar it up as step 2.
+dump = '/usr/bin/mongodump --host 127.0.0.1:$port'
+subprocess.call(dump, shell=True)
+
+# Generate the ta
+tar = 'tar czvf %s dump/*' % backup_filename
+subprocess.call(tar, shell=True)
+
+# Clean up the tmpdir.
+rmtree(tmpdir)