def run(self): if not self.isRunning(): if self.makeInstance(): self.proc = PopenPty([ '/usr/bin/sudo', os.path.join(self.installdir, Gameinstace.OPSCRIPT), u'run', self.rundir ]) self.running = True
class Gameinstace(object): '''Manages game instances.''' BUFFER_LENGH = 256 INSTALL_DIR = ur'/home/patxi/workspace/gserver/test_apps_install' DATA_DIR = ur'/home/patxi/workspace/gserver/test_apps_data' RUN_DIR = ur'/home/patxi/workspace/gserver/test_apps_run' OPSCRIPT = ur'operation.sh' EXTRACT_NAME = re.compile(ur'\s*#?\s*APP_NAME\s*=\s*(.*)') EXTRACT_QUIT = re.compile(ur'\s*#?\s*APP_QUIT\s*=\s*(.*)') def __init__(self, installed_app, instance_name): ''' Constructor ''' self.installed = installed_app self.instance = instance_name self.proc = None self.data = [] self.ridx = 0 self.widx = 0 self.running = False self.name = u'' self.qcmd = u'' scrname = os.path.join(Gameinstace.INSTALL_DIR, installed_app, Gameinstace.OPSCRIPT) if os.path.isfile(scrname): with open(scrname) as scr: for ln in scr: line = ln.decode('utf-8').strip() if Gameinstace.EXTRACT_NAME.match(line): self.name = Gameinstace.EXTRACT_NAME.sub(ur'\1', line).strip() if self.qcmd: break elif Gameinstace.EXTRACT_NAME.match(line): self.qcmd = Gameinstace.EXTRACT_QUIT.sub(ur'\1', line).strip() if self.name: break else: pass gevent.sleep(0) gevent.spawn(self._gthread_loop) def getinstalldir(self): return os.path.join(Gameinstace.INSTALL_DIR, self.installed) installdir = property(getinstalldir) def getdatadir(self): return os.path.join(Gameinstace.DATA_DIR, self.instance) datadir = property(getdatadir) def getrundir(self): return os.path.join(Gameinstace.RUN_DIR, self.instance) rundir = property(getrundir) def exists(self): return exists(self.instance) def makeInstance(self): if not self.exists(): scrpt = os.path.join(self.installdir, Gameinstace.OPSCRIPT) return 0 == call([scrpt, u'instance', self.datadir, self.rundir]) return True def removeInstance(self): if self.exists(): self.stop() scrpt = os.path.join(self.installdir, Gameinstace.OPSCRIPT) return 0 == call([scrpt, u'remove', self.datadir, self.rundir]) return True def isRunning(self): return not self.proc is None and not self.proc.poll() is None def run(self): if not self.isRunning(): if self.makeInstance(): self.proc = PopenPty([ '/usr/bin/sudo', os.path.join(self.installdir, Gameinstace.OPSCRIPT), u'run', self.rundir ]) self.running = True def stop(self): if self.isRunning(): self.proc.terminate() gevent.sleep(10) if self.isRunning(): self.proc.kill() def _custom_process_in_gthread(self, data): pass def _gthread_loop(self): while True: if not self.proc is None: poll = self.proc.poll() if not poll is None and self.running: if self.widx < Gameinstace.BUFFER_LENGH: self.data.append(u'Command exited with code %d' % poll) else: self.data[self.widx % Gameinstace.BUFFER_LENGH] = u'Command exited with code %d' % poll self.ridx += 1 self.widx += 1 self.running = False self.proc.wait() self.proc = None gevent.sleep(0.1) elif poll is None: data = self.proc.stdout.readline().decode('utf-8').strip() self._custom_process_in_gthread(data) if self.widx < Gameinstace.BUFFER_LENGH: self.data.append(data) else: self.data[self.widx % Gameinstace.BUFFER_LENGH] = data self.ridx += 1 self.widx += 1 else: gevent.sleep(0.1) else: gevent.sleep(0.1) def __len__(self): if self.empty: return 0 elif self.widx > self.ridx: return self.widx - self.ridx else: return Gameinstace.BUFFER_LENGH def __getitem__(self, idx): if not isinstance(idx, (int, long)): raise TypeError("Not an integer index") if idx < 0: raise IndexError("Out of index") idx %= Gameinstace.BUFFER_LENGH return self.data[idx] def sendCmd(self, cmd): if self.isRunning(): self.proc.stdin.write(cmd + u'\n')