Path: blob/develop/rootfs/usr/local/lib/web/backend/vnc/state.py
387 views
from __future__ import (1absolute_import, division, print_function, with_statement2)3from os import environ4from gevent.event import Event5from gevent import subprocess as gsp6from re import search as research7from .log import log8910class State(object):11def __init__(self):12self._eid = 013self._event = Event()14self._w = self._h = self._health = None15self.size_changed_count = 01617def wait(self, eid, timeout=5):18if eid < self._eid:19return20self._event.clear()21self._event.wait(timeout)22return self._eid2324def notify(self):25self._eid += 126self._event.set()2728def _update_health(self):29health = True30output = gsp.check_output([31'supervisorctl', '-c', '/etc/supervisor/supervisord.conf',32'status'33], encoding='UTF-8')34for line in output.strip().split('\n'):35if not line.startswith('web') and line.find('RUNNING') < 0:36health = False37break38if self._health != health:39self._health = health40self.notify()41return self._health4243def to_dict(self):44self._update_health()4546state = {47'id': self._eid,48'config': {49'fixedResolution': 'RESOLUTION' in environ,50'sizeChangedCount': self.size_changed_count51}52}5354self._update_size()55state.update({56'width': self.w,57'height': self.h,58})5960return state6162def set_size(self, w, h):63gsp.check_call((64'sed -i \'s#'65'^exec /usr/bin/Xvfb.*$'66'#'67'exec /usr/bin/Xvfb :1 -screen 0 {}x{}x24'68'#\' /usr/local/bin/xvfb.sh'69).format(w, h), shell=True)70self.size_changed_count += 17172def apply_and_restart(self):73gsp.check_call([74'supervisorctl', '-c', '/etc/supervisor/supervisord.conf',75'restart', 'x:'76])77self._w = self._h = self._health = None78self.notify()7980def switch_video(self, onoff):81xenvs = {82'DISPLAY': ':1',83}84try:85cmd = 'nofb' if onoff else 'fb'86gsp.check_output(['x11vnc', '-remote', cmd], env=xenvs)87except gsp.CalledProcessError as e:88log.warn('failed to set x11vnc fb: ' + str(e))8990def _update_size(self):91if self._w is not None and self._h is not None:92return93xenvs = {94'DISPLAY': ':1',95}96try:97output = gsp.check_output([98'x11vnc', '-query', 'dpy_x,dpy_y'99], env=xenvs).decode('utf-8')100mobj = research(r'dpy_x:(\d+).*dpy_y:(\d+)', output)101if mobj is not None:102w, h = int(mobj.group(1)), int(mobj.group(2))103changed = False104if self._w != w:105changed = True106self._w = w107if self._h != h:108changed = True109self._h = h110if changed:111self.notify()112except gsp.CalledProcessError as e:113log.warn('failed to get dispaly size: ' + str(e))114115def reset_size(self):116self.size_changed_count = 0117118@property119def w(self):120return self._w121122@property123def h(self):124return self._h125126@property127def health(self):128self._update_health()129return self._health130131132state = State()133134135