Пример #1
0
	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
Пример #2
0
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')