Skip to content

Commit

Permalink
Make the temporary directory settable from the command line and from …
Browse files Browse the repository at this point in the history
…the config file.
  • Loading branch information
Jason Grout committed Sep 12, 2013
1 parent 0ad8758 commit 1d575cc
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 21 deletions.
5 changes: 3 additions & 2 deletions config_default.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@
max_kernel_timeout = 60*10 # 10 minutes, for interacts
pid_file = 'sagecell.pid'
permalink_pid_file = 'sagecell_permalink_server.pid'
computers = []
tmp_dir = "/tmp/sagecell"

computers = []
_default_config = {"host": "localhost",
"username": None,
"python": sage + " -python",
Expand All @@ -49,7 +50,7 @@
# The log file will be in the home directory of the untrusted account
"log_file": "sagecell.log",
"max_kernels": 10,
"preforked_kernels": 5,
"preforked_kernels": 3,
# These set paramaters for a heartbeat channel checking whether a given kernel is alive.
# Setting first_beat lower than 1.0 may cause javascript errors.
"beat_interval": 0.5,
Expand Down
6 changes: 3 additions & 3 deletions forking_kernel_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ class KernelError(Exception):

class ForkingKernelManager(object):
""" A class for managing multiple kernels and forking on the untrusted side. """
def __init__(self, filename, ip, update_function=None):
def __init__(self, filename, ip, update_function=None, tmp_dir = None):
self.kernels = {}
self.ip = ip
self.filename = filename
self.update_function = update_function

self.dir = '/tmp/sagecell'
self.dir = tmp_dir
makedirs(self.dir)

def fork_kernel(self, config, pipe, resource_limits, logfile):
""" A function to be set as the target for the new kernel processes forked in ForkingKernelManager.start_kernel. This method forks and initializes a new kernel, uses the update_function to update the kernel's namespace, sets resource limits for the kernel, and sends kernel connection information through the Pipe object.
Expand Down
10 changes: 6 additions & 4 deletions receiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from misc import Timer

class Receiver(object):
def __init__(self, filename, ip):
def __init__(self, filename, ip, tmp_dir):
self.context = zmq.Context()
self.dealer = self.context.socket(zmq.DEALER)
self.port = self.dealer.bind_to_random_port("tcp://%s" % ip)
Expand All @@ -15,7 +15,7 @@ def __init__(self, filename, ip):
print self.sage_mode
sys.stdout.flush()
self.km = UntrustedMultiKernelManager(filename, ip,
update_function=self.update_dict_with_sage)
update_function=self.update_dict_with_sage, tmp_dir=tmp_dir)
self.filename = filename
self.timer = Timer("", reset=True)

Expand Down Expand Up @@ -323,6 +323,7 @@ def start_kernel(self, msg_content):
reply_content = self.km.start_kernel(resource_limits=resource_limits)
return self._form_message(reply_content)
except Exception as e:
logging.exception("Error starting kernel")
return self._form_message(str(e), error=True)

def kill_kernel(self, msg_content):
Expand Down Expand Up @@ -367,13 +368,14 @@ def remove_computer(self, msg_content):


if __name__ == '__main__':
ip = sys.argv[1]
filename = sys.argv[2]
comp_id = sys.argv[3]
tmp_dir = sys.argv[4]
import logging
import uuid
logging.basicConfig(filename=filename,format=comp_id[:4]+': %(asctime)s %(message)s',level=logging.DEBUG)
logging.debug('started')
ip = sys.argv[1]
receiver = Receiver(filename, ip)
receiver = Receiver(filename, ip, tmp_dir)
receiver.start()
logging.debug('ended')
9 changes: 5 additions & 4 deletions trusted_kernel_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
class TrustedMultiKernelManager(object):
""" A class for managing multiple kernels on the trusted side. """
def __init__(self, computers = None, default_computer_config = None,
kernel_timeout = None):
kernel_timeout = None, tmp_dir = None):

self._kernel_queue = Queue()

Expand All @@ -37,7 +37,8 @@ def __init__(self, computers = None, default_computer_config = None,
self.kernel_timeout = kernel_timeout
if kernel_timeout is None:
self.kernel_timeout = 0.0

self.tmp_dir = tmp_dir

if computers is not None:
for comp in computers:
comp_id = self.add_computer(comp)
Expand Down Expand Up @@ -90,7 +91,7 @@ def _setup_ssh_connection(self, host, username):
def _ssh_untrusted(self, cfg, client, comp_id):
logfile = cfg.get("log_file", os.devnull)
ip = socket.gethostbyname(cfg["host"])
code = "%s '%s/receiver.py' '%s' '%s' '%s'"%(cfg["python"], cfg["location"], ip, logfile, comp_id)
code = "%s '%s/receiver.py' '%s' '%s' '%s' '%s'"%(cfg["python"], cfg["location"], ip, logfile, comp_id, self.tmp_dir)
logger.debug(code)
ssh_stdin, ssh_stdout, ssh_stderr = client.exec_command(code)
stdout_channel = ssh_stdout.channel
Expand Down Expand Up @@ -245,7 +246,7 @@ def cb(reply):
self._kernel_queue.put((kernel_id, comp_id))
logger.info("Started preforked kernel on %s: %s", comp_id[:4], kernel_id)
else:
logger.error("Error starting prefork kernel on computer %s", comp_id)
logger.error("Error starting prefork kernel on computer %s: %s", comp_id, reply)
logger.info("Trying to start kernel on %s", comp_id[:4])
self._sender.send_msg_async({"type":"start_kernel", "content": {"resource_limits": resource_limits}}, comp_id, callback=cb)

Expand Down
4 changes: 2 additions & 2 deletions untrusted_kernel_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import logging

class UntrustedMultiKernelManager(object):
def __init__(self, filename, ip, update_function=None):
def __init__(self, filename, ip, update_function=None, tmp_dir=None):
self.filename = filename
self.fkm = ForkingKernelManager(self.filename, ip, update_function)
self.fkm = ForkingKernelManager(self.filename, ip, update_function, tmp_dir=tmp_dir)
self._kernels = set()

def start_kernel(self, resource_limits=None):
Expand Down
16 changes: 10 additions & 6 deletions web_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

class SageCellServer(tornado.web.Application):
def __init__(self, baseurl=""):
self.config = misc.Config()
baseurl = baseurl.rstrip('/')
handlers_list = [
(r"/", handlers.RootHandler),
Expand All @@ -41,7 +42,7 @@ def __init__(self, baseurl=""):
(r"/kernel/%s" % _kernel_id_regex, handlers.KernelHandler),
(r"/kernel/%s/iopub" % _kernel_id_regex, handlers.IOPubWebHandler),
(r"/kernel/%s/shell" % _kernel_id_regex, handlers.ShellWebHandler),
(r"/kernel/%s/files/(?P<file_path>.*)" % _kernel_id_regex, handlers.FileHandler, {"path": "/tmp/sagecell/"}),
(r"/kernel/%s/files/(?P<file_path>.*)" % _kernel_id_regex, handlers.FileHandler, {"path": tmp_dir}),
(r"/permalink", permalink.PermalinkHandler),
(r"/service", handlers.ServiceHandler),
] + handlers.KernelRouter.urls
Expand All @@ -52,14 +53,12 @@ def __init__(self, baseurl=""):
static_url_prefix = baseurl+"/static/",
static_handler_class = handlers.StaticHandler
)
self.config = misc.Config()

initial_comps = self.config.get_config("computers")
default_comp = self.config.get_default_config("_default_config")
kernel_timeout = self.config.get_config("max_kernel_timeout")

self.km = TMKM(computers=initial_comps, default_computer_config=default_comp,
kernel_timeout=kernel_timeout)
kernel_timeout=kernel_timeout, tmp_dir = tmp_dir)
db = __import__('db_'+self.config.get_config('db'))
self.db = db.DB(self.config.get_config('db_config')['uri'])
self.ioloop = ioloop.IOLoop.instance()
Expand All @@ -85,6 +84,8 @@ def get_ip_address(ifname):


if __name__ == "__main__":
config = misc.Config()

import argparse
parser = argparse.ArgumentParser(description='Launch a SageCell web server',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
Expand All @@ -93,17 +94,20 @@ def get_ip_address(ifname):
parser.add_argument('-d', '--debug', action='store_true', help='debug messages')
parser.add_argument('-b', '--baseurl', default="", help="base url")
parser.add_argument('--interface', default=None, help="interface to listen on (default all)")
parser.add_argument('--tmp_dir', default=config.get_config("tmp_dir"), help="temporary directory for calculations")

args = parser.parse_args()
if args.debug:
logger.setLevel(logging.DEBUG)
logging.getLogger("tornado.access").setLevel(logging.DEBUG)
logging.getLogger("tornado.application").setLevel(logging.DEBUG)
logging.getLogger("tornado.general").setLevel(logging.DEBUG)
logger.info("starting tornado web server")

tmp_dir = args.tmp_dir

logger.info("starting tornado web server")
import lockfile
from lockfile.pidlockfile import PIDLockFile
config = misc.Config()
pidfile_path = config.get_config('pid_file')
pidlock = PIDLockFile(pidfile_path)
if pidlock.is_locked():
Expand Down

0 comments on commit 1d575cc

Please sign in to comment.