Skip to content

Commit

Permalink
Merge pull request deis#4394 from krancour/publish-etcd-keys-at-contr…
Browse files Browse the repository at this point in the history
…oller-start

feat(controller): publish etcd keys at controller start
  • Loading branch information
krancour committed Sep 16, 2015
2 parents 4a5606f + 2077ab7 commit ff221e4
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 38 deletions.
Empty file.
Empty file.
16 changes: 16 additions & 0 deletions controller/api/management/commands/load_db_state_to_etcd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from django.core.management.base import BaseCommand

from api.models import Key, App, Domain, Certificate, Config


class Command(BaseCommand):
"""Management command for publishing Deis platform state from the database
to etcd.
"""
def handle(self, *args, **options):
"""Publishes Deis platform state from the database to etcd."""
print "Publishing DB state to etcd..."
for model in (Key, App, Domain, Certificate, Config):
for obj in model.objects.all():
obj.save()
print "Done Publishing DB state to etcd."
42 changes: 22 additions & 20 deletions controller/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1081,9 +1081,10 @@ def _log_config_updated(**kwargs):


def _log_domain_added(**kwargs):
domain = kwargs['instance']
msg = "domain {} added".format(domain)
log_event(domain.app, msg)
if kwargs.get('created'):
domain = kwargs['instance']
msg = "domain {} added".format(domain)
log_event(domain.app, msg)


def _log_domain_removed(**kwargs):
Expand All @@ -1093,8 +1094,9 @@ def _log_domain_removed(**kwargs):


def _log_cert_added(**kwargs):
cert = kwargs['instance']
logger.info("cert {} added".format(cert))
if kwargs.get('created'):
cert = kwargs['instance']
logger.info("cert {} added".format(cert))


def _log_cert_removed(**kwargs):
Expand Down Expand Up @@ -1127,10 +1129,13 @@ def _etcd_purge_user(**kwargs):
pass


def _etcd_create_app(**kwargs):
def _etcd_publish_app(**kwargs):
appname = kwargs['instance']
if kwargs['created']:
try:
_etcd_client.write('/deis/services/{}'.format(appname), None, dir=True)
except KeyError:
# Ignore error when the directory already exists.
pass


def _etcd_purge_app(**kwargs):
Expand All @@ -1143,9 +1148,8 @@ def _etcd_purge_app(**kwargs):

def _etcd_publish_cert(**kwargs):
cert = kwargs['instance']
if kwargs['created']:
_etcd_client.write('/deis/certs/{}/cert'.format(cert), cert.certificate)
_etcd_client.write('/deis/certs/{}/key'.format(cert), cert.key)
_etcd_client.write('/deis/certs/{}/cert'.format(cert), cert.certificate)
_etcd_client.write('/deis/certs/{}/key'.format(cert), cert.key)


def _etcd_purge_cert(**kwargs):
Expand All @@ -1167,13 +1171,12 @@ def _etcd_publish_config(**kwargs):
prevExist=True, dir=True, recursive=True)
except KeyError:
pass
if kwargs['created']:
for k, v in config.values.iteritems():
_etcd_client.write(
'/deis/config/{}/{}'.format(
config.app,
unicode(k).encode('utf-8').lower()),
unicode(v).encode('utf-8'))
for k, v in config.values.iteritems():
_etcd_client.write(
'/deis/config/{}/{}'.format(
config.app,
unicode(k).encode('utf-8').lower()),
unicode(v).encode('utf-8'))


def _etcd_purge_config(**kwargs):
Expand All @@ -1187,8 +1190,7 @@ def _etcd_purge_config(**kwargs):

def _etcd_publish_domains(**kwargs):
domain = kwargs['instance']
if kwargs['created']:
_etcd_client.write('/deis/domains/{}'.format(domain), domain.app)
_etcd_client.write('/deis/domains/{}'.format(domain), domain.app)


def _etcd_purge_domains(**kwargs):
Expand Down Expand Up @@ -1226,7 +1228,7 @@ def create_auth_token(sender, instance=None, created=False, **kwargs):
post_delete.connect(_etcd_purge_user, sender=get_user_model(), dispatch_uid='api.models')
post_save.connect(_etcd_publish_domains, sender=Domain, dispatch_uid='api.models')
post_delete.connect(_etcd_purge_domains, sender=Domain, dispatch_uid='api.models')
post_save.connect(_etcd_create_app, sender=App, dispatch_uid='api.models')
post_save.connect(_etcd_publish_app, sender=App, dispatch_uid='api.models')
post_delete.connect(_etcd_purge_app, sender=App, dispatch_uid='api.models')
post_save.connect(_etcd_publish_cert, sender=Certificate, dispatch_uid='api.models')
post_delete.connect(_etcd_purge_cert, sender=Certificate, dispatch_uid='api.models')
Expand Down
2 changes: 2 additions & 0 deletions controller/bin/boot
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ sudo -E -u deis ./manage.py syncdb --migrate --noinput
# spawn a gunicorn server in the background
sudo -E -u deis gunicorn -c deis/gconf.py deis.wsgi &

./manage.py load_db_state_to_etcd

# smart shutdown on SIGTERM (SIGINT is handled by gunicorn)
function on_exit() {
GUNICORN_PID=$(cat /tmp/gunicorn.pid)
Expand Down
20 changes: 2 additions & 18 deletions docs/managing_deis/backing_up_data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -197,24 +197,8 @@ Finishing up

Now that the data is restored, the rest of the cluster should come up normally with a ``deisctl start platform``.

The last task is to instruct the controller to re-write user keys, application data, and domains to etcd.
Log into the machine which runs deis-controller and run the following. Note that the IP address to
use in the ``export`` command should correspond to the IP of the host machine which runs this container.

.. code-block:: console
$ nse deis-controller
$ cd /app
$ export ETCD=172.17.8.100:4001
./manage.py shell <<EOF
from api.models import *
[k.save() for k in Key.objects.all()]
[a.save() for a in App.objects.all()]
[d.save() for d in Domain.objects.all()]
[c.save() for c in Certificate.objects.all()]
[c.save() for c in Config.objects.all()]
EOF
$ exit
The controller will automatically re-write user keys, application data, and domains from the
restored database to etcd.

That's it! The cluster should be fully restored.

Expand Down

0 comments on commit ff221e4

Please sign in to comment.