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!"