diff --git a/rattail_fabric/backup.py b/rattail_fabric/backup.py new file mode 100644 index 0000000..b69b4c8 --- /dev/null +++ b/rattail_fabric/backup.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2018 Lance Edgar +# +# This file is part of Rattail. +# +# Rattail 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. +# +# Rattail 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 +# Rattail. If not, see . +# +################################################################################ +""" +Fabric library for Backup app +""" + +from __future__ import unicode_literals, absolute_import + +import datetime + +from fabric.api import cd, sudo +from fabric.contrib.files import exists + +from rattail_fabric import make_deploy, mkdir, python + + +deploy_generic = make_deploy(__file__) + + +def deploy_backup_app(deploy, envname, config=None, everything=None, crontab=None, user='rattail', runat=None): + """ + Make an app which can run backups for the server. + """ + if not config: + path = '{}/rattail.conf'.format(envname) + if deploy.local_exists(path): + config = path + else: + raise ValueError("Must provide config path for backup app") + + if not runat: + runat = datetime.time(0) # defaults to midnight + + # virtualenv + python.mkvirtualenv(envname, python='/usr/bin/python3', upgrade_setuptools=False) + envpath = '/srv/envs/{}'.format(envname) + sudo('chown -R {}: {}'.format(user, envpath)) + with cd(envpath): + mkdir('src', owner=user) + sudo('bin/pip install --upgrade pip', user=user) + + # rattail + if not exists('src/rattail'): + sudo('git clone https://rattailproject.org/git/rattail.git src/rattail', user=user) + with cd('src/rattail'): + sudo('git pull', user=user) + sudo('bin/pip install --upgrade --upgrade-strategy eager --editable src/rattail', user=user) + + # TODO: this should not be necessary + sudo('bin/pip install --upgrade --upgrade-strategy eager rattail[db]', user=user) + + # config + sudo('bin/rattail make-appdir', user=user) + deploy(config, 'app/rattail.conf', owner=user, mode='0600') + sudo('bin/rattail -c app/rattail.conf make-config -T quiet -O app/', user=user) + sudo('bin/rattail -c app/rattail.conf make-config -T silent -O app/', user=user) + + # backup-everything script + everything_context = {'envname': envname} + if everything: + deploy(everything, '/usr/local/bin/backup-everything', mode='0755', context=everything_context) + else: + deploy_generic('backup/backup-everything.mako', '/usr/local/bin/backup-everything', mode='0755', + context=everything_context) + + # crontab + crontab_context = { + 'envname': envname, + 'pretty_time': runat.strftime('%I:%M %p'), + 'cron_time': runat.strftime('%M %H'), + } + if crontab: + deploy(crontab, '/etc/cron.d/backup', context=crontab_context) + else: + deploy_generic('backup/crontab.mako', '/etc/cron.d/backup', context=crontab_context) diff --git a/rattail_fabric/core.py b/rattail_fabric/core.py index ccf5b18..9ddf238 100644 --- a/rattail_fabric/core.py +++ b/rattail_fabric/core.py @@ -184,6 +184,10 @@ class Deployer(object): from rattail_fabric.apache import deploy_conf deploy_conf(self, local_path, name, **kwargs) + def backup_app(self, envname='backup', *args, **kwargs): + from rattail_fabric.backup import deploy_backup_app + deploy_backup_app(self, envname, *args, **kwargs) + def certbot_account(self, uuid, localdir='certbot/account'): """ Deploy files to establish a certbot account on target server diff --git a/rattail_fabric/deploy/backup/backup-everything.mako b/rattail_fabric/deploy/backup/backup-everything.mako new file mode 100755 index 0000000..13dbd0c --- /dev/null +++ b/rattail_fabric/deploy/backup/backup-everything.mako @@ -0,0 +1,18 @@ +#!/bin/sh -e + +if [ "$1" = "-v" -o "$1" = "--verbose" ]; then + VERBOSE='--verbose' + PROGRESS='--progress' + CONFIG='app/rattail.conf' +else + VERBOSE= + PROGRESS= + CONFIG='app/silent.conf' +fi + + +cd /srv/envs/${envname} + +RATTAIL="bin/rattail --config=$CONFIG $PROGRESS" + +$RATTAIL backup diff --git a/rattail_fabric/deploy/backup/crontab.mako b/rattail_fabric/deploy/backup/crontab.mako new file mode 100644 index 0000000..43b10e5 --- /dev/null +++ b/rattail_fabric/deploy/backup/crontab.mako @@ -0,0 +1,4 @@ +# -*- mode: conf; -*- + +# backup everything of importance at ${pretty_time} +${'' if env.server_is_live else '# '}${cron_time} * * * root /usr/local/bin/backup-everything