Source code for calML.restart_servers
#############################################################################
# Author: A. Silenzi, S. Hauf
# Created on September, 2018, 11:04 AM
# Copyright (C) European XFEL GmbH Hamburg. All rights reserved.
#############################################################################
from json import loads
from karabo.middlelayer import (AccessMode, Device, Slot, State, String,
VectorString, background, sleep)
from requests import get, put
[docs]class RestartCalServers(Device):
""" A device for reliably restarting calibration servers.
This device is to be used to initiate a "blank slate" restart
of the calibration pipeline.
"""
status = String(accessMode=AccessMode.READONLY)
host_template = String(displayedName='Server host templ.',
accessMode=AccessMode.INITONLY,
defaultValue='http://spb-br-sys-cal-{}:8080')
server_insets = VectorString(displayedName='Server insets',
accessMode=AccessMode.INITONLY,
defaultValue=[str(i) for i in range(8)])
omit = VectorString(displayedName="Omit from restart",
accessMode=AccessMode.RECONFIGURABLE)
def onInitialization(self):
self.state = State.ACTIVE
def get_json(self, url):
r = get(url)
if r.status_code != 200:
self.state = State.ERROR
rstat = r.status_code
self.status = f"could not connect to {url} error {rstat}"
return False
return r.json()
def put_json(self, url, json):
r = put(url, json=json)
if r.status_code != 200:
self.state = State.ERROR
rstat = r.status_code
self.status = f"could not connect to {url} error {rstat}"
return False
return r.json()
def is_up(self, url):
d = self.get_json(url)
if not d:
return False
return all(
[sd.get('status', '').startswith('up') for sd in d['servers']])
def stop(self, url, name):
json = {'server': {'name': name, 'command': 'group'}}
ret = self.put_json(url, json)
if not ret:
return False
json = {'server': {'name': name, 'command': 'down'}}
return self.put_json(url, json)
def start(self, url, name):
json = {'server': {'name': name, 'command': 'up'}}
return self.put_json(url, json)
@Slot(displayedName="Restart servers")
def restartServers(self):
background(self._restart_servers)
def _restart_servers(self):
""" Perform a server restart.
"""
services = {}
self.status = "Restarting..."
self.state = State.STOPPING
for i in self.server_insets:
host = self.host_template.format(i)
dic = self.get_json(f'{host}/api/servers.json')
if not dic:
break
for s_dic in dic['servers']:
name = s_dic['name']
this_service = self.serverId.lower().replace("/", "_")
dont_kill = ['webserver', this_service]
if self.omit:
dont_kill += list({name for s in self.omit if s in name})
if name not in dont_kill:
if name in services:
msg = 'warning service name not unique: {}'.\
format(name)
self.status = msg
services[name] = f'{host}/api/servers/{name}.json'
for name, url in services.items():
# stop
if not self.stop(url, name)['success']:
self.status = f"problem stopping {name}"
else:
self.status = f"sucessfully stopped {name}"
sleep(1)
for name, url in services.items():
# wait for service to be down.
while self.is_up(url):
nap_time = 0.5
sleep(nap_time)
# restart
if not self.start(url, name)['success']:
self.status = f"problem starting {name}"
else:
# sleep here to prevent users from being too trigger happy
self.status = f"successfully restarted {name}"
sleep(1)
self.state = State.ACTIVE
self.status = "All servers restarted!"