Add page for configuring datasync
experimental! until proven worthy..
This commit is contained in:
parent
bb0666b77d
commit
8aff5d519d
3 changed files with 954 additions and 15 deletions
|
@ -26,12 +26,18 @@ DataSync Views
|
|||
|
||||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
import getpass
|
||||
import subprocess
|
||||
import logging
|
||||
|
||||
import sqlalchemy as sa
|
||||
|
||||
from rattail.db import model
|
||||
from rattail.datasync.config import load_profiles
|
||||
from rattail.datasync.util import get_lastrun
|
||||
|
||||
from tailbone.views import MasterView
|
||||
from tailbone.util import csrf_token
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -78,30 +84,197 @@ class DataSyncChangeView(MasterView):
|
|||
return kwargs
|
||||
|
||||
def restart(self):
|
||||
# TODO: Add better validation (e.g. CSRF) here?
|
||||
if self.request.method == 'POST':
|
||||
cmd = self.rattail_config.getlist('tailbone', 'datasync.restart', default='/bin/sleep 3') # simulate by default
|
||||
log.debug("attempting datasync restart with command: {}".format(cmd))
|
||||
result = subprocess.call(cmd)
|
||||
if result == 0:
|
||||
self.request.session.flash("DataSync daemon has been restarted.")
|
||||
else:
|
||||
self.request.session.flash("DataSync daemon could not be restarted; result was: {}".format(result), 'error')
|
||||
cmd = self.rattail_config.getlist('tailbone', 'datasync.restart',
|
||||
# nb. simulate by default
|
||||
default='/bin/sleep 3')
|
||||
log.debug("attempting datasync restart with command: %s", cmd)
|
||||
result = subprocess.call(cmd)
|
||||
if result == 0:
|
||||
self.request.session.flash("DataSync daemon has been restarted.")
|
||||
else:
|
||||
self.request.session.flash("DataSync daemon could not be restarted; result was: {}".format(result), 'error')
|
||||
return self.redirect(self.request.get_referrer(default=self.request.route_url('datasyncchanges')))
|
||||
|
||||
def configure(self):
|
||||
"""
|
||||
View for configuring the DataSync daemon.
|
||||
"""
|
||||
if self.request.method == 'POST':
|
||||
data = self.request.json_body
|
||||
self.save_settings(data)
|
||||
self.request.session.flash("Settings have been saved. "
|
||||
"You should probably restart DataSync now.")
|
||||
return self.json_response({'success': True})
|
||||
|
||||
profiles = load_profiles(self.rattail_config,
|
||||
include_disabled=True,
|
||||
ignore_problems=True)
|
||||
|
||||
profiles_data = []
|
||||
for profile in sorted(profiles.values(), key=lambda p: p.key):
|
||||
data = {
|
||||
'key': profile.key,
|
||||
'watcher_spec': profile.watcher_spec,
|
||||
'watcher_dbkey': profile.watcher.dbkey,
|
||||
'watcher_delay': profile.watcher.delay,
|
||||
'watcher_retry_attempts': profile.watcher.retry_attempts,
|
||||
'watcher_retry_delay': profile.watcher.retry_delay,
|
||||
'watcher_default_runas': profile.watcher.default_runas,
|
||||
'watcher_consumes_self': profile.watcher.consumes_self,
|
||||
# 'notes': None, # TODO
|
||||
'enabled': profile.enabled,
|
||||
}
|
||||
|
||||
consumers = []
|
||||
if profile.watcher.consumes_self:
|
||||
pass
|
||||
else:
|
||||
for consumer in sorted(profile.consumers, key=lambda c: c.key):
|
||||
consumers.append({
|
||||
'key': consumer.key,
|
||||
'consumer_spec': consumer.spec,
|
||||
'consumer_dbkey': consumer.dbkey,
|
||||
'consumer_runas': getattr(consumer, 'runas', None),
|
||||
'consumer_delay': consumer.delay,
|
||||
'consumer_retry_attempts': consumer.retry_attempts,
|
||||
'consumer_retry_delay': consumer.retry_delay,
|
||||
'enabled': consumer.enabled,
|
||||
})
|
||||
data['consumers_data'] = consumers
|
||||
profiles_data.append(data)
|
||||
|
||||
return {
|
||||
'master': self,
|
||||
# TODO: really only buefy themes are supported here
|
||||
'use_buefy': self.get_use_buefy(),
|
||||
'index_title': "DataSync Changes",
|
||||
'index_url': self.get_index_url(),
|
||||
'profiles': profiles,
|
||||
'profiles_data': profiles_data,
|
||||
'restart_command': self.rattail_config.get('tailbone', 'datasync.restart'),
|
||||
'system_user': getpass.getuser(),
|
||||
}
|
||||
|
||||
def save_settings(self, data):
|
||||
model = self.model
|
||||
|
||||
# collect new settings
|
||||
settings = []
|
||||
watch = []
|
||||
for profile in data['profiles']:
|
||||
pkey = profile['key']
|
||||
if profile['enabled']:
|
||||
watch.append(pkey)
|
||||
settings.extend([
|
||||
{'name': 'rattail.datasync.{}.watcher'.format(pkey),
|
||||
'value': profile['watcher_spec']},
|
||||
{'name': 'rattail.datasync.{}.watcher.db'.format(pkey),
|
||||
'value': profile['watcher_dbkey']},
|
||||
{'name': 'rattail.datasync.{}.watcher.delay'.format(pkey),
|
||||
'value': profile['watcher_delay']},
|
||||
{'name': 'rattail.datasync.{}.watcher.retry_attempts'.format(pkey),
|
||||
'value': profile['watcher_retry_attempts']},
|
||||
{'name': 'rattail.datasync.{}.watcher.retry_delay'.format(pkey),
|
||||
'value': profile['watcher_retry_delay']},
|
||||
{'name': 'rattail.datasync.{}.consumers.runas'.format(pkey),
|
||||
'value': profile['watcher_default_runas']},
|
||||
])
|
||||
consumers = []
|
||||
if profile['watcher_consumes_self']:
|
||||
consumers = ['self']
|
||||
else:
|
||||
for consumer in profile['consumers_data']:
|
||||
ckey = consumer['key']
|
||||
if consumer['enabled']:
|
||||
consumers.append(ckey)
|
||||
settings.extend([
|
||||
{'name': 'rattail.datasync.{}.consumer.{}'.format(pkey, ckey),
|
||||
'value': consumer['consumer_spec']},
|
||||
{'name': 'rattail.datasync.{}.consumer.{}.db'.format(pkey, ckey),
|
||||
'value': consumer['consumer_dbkey']},
|
||||
{'name': 'rattail.datasync.{}.consumer.{}.delay'.format(pkey, ckey),
|
||||
'value': consumer['consumer_delay']},
|
||||
{'name': 'rattail.datasync.{}.consumer.{}.retry_attempts'.format(pkey, ckey),
|
||||
'value': consumer['consumer_retry_attempts']},
|
||||
{'name': 'rattail.datasync.{}.consumer.{}.retry_delay'.format(pkey, ckey),
|
||||
'value': consumer['consumer_retry_delay']},
|
||||
{'name': 'rattail.datasync.{}.consumer.{}.runas'.format(pkey, ckey),
|
||||
'value': consumer['consumer_runas']},
|
||||
])
|
||||
settings.extend([
|
||||
{'name': 'rattail.datasync.{}.consumers'.format(pkey),
|
||||
'value': ', '.join(consumers)},
|
||||
])
|
||||
settings.extend([
|
||||
{'name': 'rattail.datasync.watch',
|
||||
'value': ', '.join(watch)},
|
||||
{'name': 'tailbone.datasync.restart',
|
||||
'value': data['restart_command']},
|
||||
])
|
||||
|
||||
# delete all current settings
|
||||
self.delete_settings()
|
||||
|
||||
# create all new settings
|
||||
for setting in settings:
|
||||
self.Session.add(model.Setting(name=setting['name'],
|
||||
value=setting['value']))
|
||||
|
||||
def delete_settings(self):
|
||||
model = self.model
|
||||
|
||||
to_delete = [
|
||||
'rattail.datasync.watch',
|
||||
'tailbone.datasync.restart',
|
||||
]
|
||||
for setting in to_delete:
|
||||
setting = self.Session.query(model.Setting).get(setting)
|
||||
if setting:
|
||||
self.Session.delete(setting)
|
||||
|
||||
self.Session.query(model.Setting)\
|
||||
.filter(sa.or_(
|
||||
model.Setting.name.like('rattail.datasync.%.watcher'),
|
||||
model.Setting.name.like('rattail.datasync.%.watcher.db'),
|
||||
model.Setting.name.like('rattail.datasync.%.watcher.delay'),
|
||||
model.Setting.name.like('rattail.datasync.%.watcher.retry_attempts'),
|
||||
model.Setting.name.like('rattail.datasync.%.watcher.retry_delay'),
|
||||
model.Setting.name.like('rattail.datasync.%.consumers'),
|
||||
model.Setting.name.like('rattail.datasync.%.consumers.runas'),
|
||||
model.Setting.name.like('rattail.datasync.%.consumer.%')))\
|
||||
.delete(synchronize_session=False)
|
||||
|
||||
@classmethod
|
||||
def defaults(cls, config):
|
||||
rattail_config = config.registry.settings.get('rattail_config')
|
||||
cls._defaults(config)
|
||||
cls._datasync_defaults(config)
|
||||
|
||||
@classmethod
|
||||
def _datasync_defaults(cls, config):
|
||||
permission_prefix = cls.get_permission_prefix()
|
||||
|
||||
# fix permission group title
|
||||
config.add_tailbone_permission_group('datasync', label="DataSync")
|
||||
config.add_tailbone_permission_group(permission_prefix, label="DataSync")
|
||||
|
||||
# restart datasync
|
||||
config.add_tailbone_permission('datasync', 'datasync.restart', label="Restart DataSync Daemon")
|
||||
config.add_route('datasync.restart', '/datasync/restart')
|
||||
config.add_view(cls, attr='restart', route_name='datasync.restart', permission='datasync.restart')
|
||||
config.add_tailbone_permission(permission_prefix,
|
||||
'{}.restart'.format(permission_prefix),
|
||||
label="Restart the DataSync daemon")
|
||||
config.add_route('datasync.restart', '/datasync/restart',
|
||||
request_method='POST')
|
||||
config.add_view(cls, attr='restart',
|
||||
route_name='datasync.restart',
|
||||
permission='{}.restart'.format(permission_prefix))
|
||||
|
||||
cls._defaults(config)
|
||||
# configure datasync
|
||||
config.add_tailbone_permission(permission_prefix,
|
||||
'{}.configure'.format(permission_prefix),
|
||||
label="Configure the DataSync daemon")
|
||||
config.add_route('datasync.configure', '/datasync/configure')
|
||||
config.add_view(cls, attr='configure',
|
||||
route_name='datasync.configure',
|
||||
permission='{}.configure'.format(permission_prefix),
|
||||
renderer='/datasync/configure.mako')
|
||||
|
||||
# TODO: deprecate / remove this
|
||||
DataSyncChangesView = DataSyncChangeView
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue