[Bio] / Speck / Chromium.py Repository:
ViewVC logotype

View of /Speck/Chromium.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (download) (as text) (annotate) (vendor branch)
Thu Sep 9 19:54:06 2004 UTC (15 years, 2 months ago) by sheradon
Branch: init, MAIN
CVS Tags: v0, HEAD
Changes since 1.1: +0 -0 lines
Initial load to CVS

#!/usr/bin/env python

import os, sys, signal, random, time, string, tempfile, cPickle, traceback
from wxPython.wx import *
from pydot import Dot

# Figure out where Chromium lives
for path in string.split(os.environ['PATH'], os.pathsep):
	if os.path.exists(os.path.join(path, 'crappfaker')):
		crdir, tmp = os.path.split(path)
		crdir, tmp = os.path.split(crdir)
		break
else:
	print 'Could not find Chromium in your path. Aborting.'
	sys.exit(-1)	
sys.path.append(os.path.join(crdir, 'mothership/server'))
from mothership import *


class Mural:
	def __init__(self, cols, rows, width, height, tiles):
		"""A definition of a tiled display. See below for an
			example of a 3x2 mural.
			@type cols, rows, width, height: int
			@type tiles: [(string, int, int)...]
			@rtype: Mural
		"""
		self.cols, self.rows = cols, rows
		self.width, self.height = width, height
		self.tiles = tiles

# Setup for the uM2.
murals = {'uM2': Mural(3, 2, 1024, 768,
					  [('um2n1.mcs.anl.gov', 3, 680),
						('um2n2.mcs.anl.gov', 788, 679),
						('um2n3.mcs.anl.gov', 1604, 678),
						('um2n4.mcs.anl.gov', 6, 2),
						('um2n5.mcs.anl.gov', 787, 1),
						('um2n6.mcs.anl.gov', 1605, 0)])
			}


# --------------------------------------------
def display(where, canvasType, *args, **kwargs):
# --------------------------------------------
	"""The only function we care about as an outside caller.
		canvasType is the qualified python name of the canvas *class*
		you'll want to use, (relative to your pythonpath of course),
		'Speck.DotCanvas.DotCanvas' for instance. any additional parameters
		are arguments you would pass to the constructor of that canvas
		object, typically the data to display and/or some settings.
		@type where: string
		@type canvasType: string
		@type args: [any number of things] 
		@type kwargs: {anythings}
		@rtype: [doesn't return -- ends with infinite mothership loop] 
	"""
	thisfile = traceback.extract_stack()[-1][0]
	# Save the data so once we call crappfaker, we can get at it.
	picklefile = tempfile.mktemp()
	f = file(picklefile, 'w')
	cPickle.dump(canvasType, f)
	cPickle.dump(args, f)
	cPickle.dump(kwargs, f)
	f.close()

	target_app = 'python %s %s' % (thisfile, picklefile)
	local_hostname = os.uname()[1]
	mother_port = random.randint(10000, 11000)
	mural = murals[where]

	# Chromium needs this handler to exit cleanly from mothership
	def sighandler(signum, frame):
		signal.getsignal(signal.SIGINT)()
	signal.signal(signal.SIGCHLD, sighandler)

	pid = os.fork()
	if (pid == 0):	# Child process starts servers, app 
		start_servers(local_hostname, mother_port, mural)
		start_faker(local_hostname, mother_port)
	else:				# Original runs mothership
		start_mothership(target_app, mother_port, mural)


# This is what gets called with the crappfaker. It makes the window and stuff.
# ---------------------------
if __name__ == "__main__":
# ---------------------------
	"""Nobody should call this file as a standalone app; it calls itself
		because the crappfaker needs to run a separate executable, and this is it.
		It just grabs what was just temp-stored during display(), and then
		instantiates the canvas you wanted.
	"""

	picklefile = sys.argv[1]
	f = file(picklefile, 'r')
	canvasType = cPickle.load(f)
	args = cPickle.load(f)
	kwargs = cPickle.load(f)
	f.close()
	os.unlink(picklefile)

	# Make a window and instantiate the kind of canvas desired 
	app = wxPySimpleApp()
	win = wxFrame(None, wxID_ANY, 'Speck', size = (900, 500))
	period = canvasType.rfind('.')
	module, klass = canvasType[:period], canvasType[period+1:]
	try:
		exec 'from %s import %s' % (module, klass)
		exec 'c = %s(win, *args, **kwargs)' % klass
	except ImportError, NameError:
		print 'Could not load %s from module %s.' % (klass, module)
		sys.exit(-1)
	win.Show(True)
	app.MainLoop()



# ------------------------------------------------
def start_servers(local_hostname, mother_port, m):
# ------------------------------------------------
	"""Runs a Chromium server on the machine controlling each tile/projector.
		Uses SSH to go through oddball2, since that's the only one with 
		access to the uM2 machines.
		TODO: Push the uM2-specific stuff out as a specific case, and
				 allow other displays, e.g. the ActiveMural.
		@type local_hostname: string
		@type mother_port: int
		@type m: Mural
		@rtype: None
	"""

	cmd = 'crserver -mothership %s:%d' % (local_hostname, mother_port)
	servers = ['%s ' % tile[0] for tile in m.tiles]
	serversStr = ''.join(servers)
	loopcmd = 'for server in %s; do (rsh $server "export DISPLAY=:0.0; %s" &); done' % (serversStr, cmd)
	os.spawnvp(os.P_NOWAIT, 'ssh', ['ssh', 'oddball2.mcs.anl.gov', loopcmd])

# -------------------------------------------
def start_faker(local_hostname, mother_port):
# -------------------------------------------
	"""Executes the Chromium appfaker after doing some environment setup
		required to talk to the mothership.
		@type local_hostname: string
		@type mother_port: int
		@rtype: [doesn't return -- process is replaced by crappfaker] 
	"""
 
	# Environment setup for crappfaker
	faker = os.path.join(crbindir,'crappfaker')
	motherinfo = local_hostname + ':' + str(mother_port)
	ldinfo = crlibdir + ":" + os.getenv('LD_LIBRARY_PATH')
	newenv = os.environ
	newenv['CRMOTHERSHIP'] = motherinfo
	newenv['LD_LIBRARY_PATH'] = ldinfo
	try:					auth = os.environ['XAUTHORITY']
	except KeyError:	auth = os.environ['HOME'] + '/.Xauthority'
	newenv['XAUTHORITY'] = auth
	print 'DISPLAY = %s' % os.environ['DISPLAY']
	print 'Calling faker.'
	os.execve(faker, ['crappfaker'], newenv)

# -----------------------------------------------
def start_mothership(target_app, mother_port, m):
# -----------------------------------------------
	"""Runs the mothership daemon following its configuration.
		@type target_app: string
		@type mother_port: int
		@type m: Mural
		@rtype: [doesn't return -- endless loop] 
	"""
	cr = CR()
	cr.MTU(1024*1024)

	# Some SPU's...
	tilesortspu = SPU('tilesort')
	feed = SPU('feedback')
	feed.Conf('default_viewport', 1)
	SPUdir = crlibdir
 
	# Define all the servers for the mothership...
	for row in range(m.rows):
		for col in range(m.cols):
			n = row*m.cols + col
			(machine, x, y) = m.tiles[n]
			server_node = CRNetworkNode(machine)
			server_node.AddTile(x, y, m.width, m.height)
			renderspu = SPU('render')
			renderspu.Conf('window_geometry', [0, 0, m.width, m.height])
			server_node.AddSPU(renderspu)
			server_node.SPUDir('/soft/apps/packages/cr-1.4/lib/Linux')
			server_node.Conf('optimize_bucket', 0)
			cr.AddNode(server_node )
			server_port = random.randint(7100, 7300)
			tilesortspu.AddServer(server_node, protocol='tcpip', port=server_port)
	
	# Application node...
	client_node = CRApplicationNode()
	client_node.SPUDir(SPUdir)
	client_node.SetApplication(target_app)
	client_node.AddSPU(feed)
	client_node.AddSPU(tilesortspu)
	cr.AddNode(client_node)

	cr.Go(mother_port)


MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3