# # # patch "www/viewmtn/mtn.py" # from [841033a1a4de47d51405d0f9a10c2743ec7933b7] # to [de4f2d6e37972a1382bf71b3da3787bd02b70635] # # patch "www/viewmtn.diff" # from [f068709d25426720218355b05afc835627bf45f2] # to [fcd5a87e9591d7f8d10dc366ddd233fca0a7d282] # ============================================================ --- www/viewmtn/mtn.py 841033a1a4de47d51405d0f9a10c2743ec7933b7 +++ www/viewmtn/mtn.py de4f2d6e37972a1382bf71b3da3787bd02b70635 @@ -65,12 +65,10 @@ class Automate(object): If an error occurs, the monotone process may need to be stopped and a new one created. """ - def __init__(self, monotone, database, **kwargs): - self.database = database - self.command = [monotone, "automate", "stdio", "--db=%s" % pipes.quote(database)] + def __init__(self, monotone, host, **kwargs): + self.command = [monotone, "automate", "remote_stdio", pipes.quote(host)] self.lock = threading.Lock() self.process = None - self.running_mtime = None def stop(self): if not self.process: @@ -78,19 +76,10 @@ class Automate(object): terminate_popen3(self.process) self.process = None - def database_mtime(self): - return os.stat(self.database).st_mtime - - def check_current(self): - if self.process != None and self.database_mtime() > self.running_mtime: - debug("stopped process, database has changed.") - self.stop() - def __process_required(self): '''returns whether it started a process''' if self.process != None: return False - self.running_mtime = self.database_mtime() self.process = popen2.Popen3(self.command, capturestderr=True) map (set_nonblocking, [ self.process.fromchild, self.process.tochild, ============================================================ --- www/viewmtn.diff f068709d25426720218355b05afc835627bf45f2 +++ www/viewmtn.diff fcd5a87e9591d7f8d10dc366ddd233fca0a7d282 @@ -80,191 +80,6 @@ Only in viewmtn-0.10: _MTN # if you don't have this available, just comment # the "highlight_command" line out Only in viewmtn-0.10: _MTN -diff -ru viewmtn-0.10/mtn.py webhost/www/viewmtn/mtn.py ---- viewmtn-0.10/mtn.py 2010-02-28 16:32:01.097407097 -0600 -+++ webhost/www/viewmtn/mtn.py 2010-02-27 23:48:09.325401327 -0600 -@@ -13,6 +13,7 @@ - import fcntl - import pipes - import select -+import socket - import threading - import popen2 - from common import set_nonblocking, terminate_popen3 -@@ -55,12 +56,11 @@ - self.obj_type = "author" - - class Runner(object): -- def __init__(self, monotone, database): -+ def __init__(self, stdio_addr, database): - self.database = database -- self.base_command = [monotone, "--db=%s" % pipes.quote(database)] -+ self.stdio_addr = stdio_addr - - packet_header_re = re.compile(r'^(\d+):(\d+):([lm]):(\d+):') --import web - - class Automate(Runner): - """Runs commands via a particular monotone process. This -@@ -74,32 +74,26 @@ - def __init__(self, *args, **kwargs): - Runner.__init__(*[self] + list(args), **kwargs) - self.lock = threading.Lock() -- self.process = None -- self.running_mtime = None -+ self.sock = None - - def stop(self): -- if not self.process: -+ if not self.sock: - return -- terminate_popen3(self.process) -- self.process = None -+ self.sock.close() -+ self.sock = None - - def database_mtime(self): - return os.stat(self.database).st_mtime - - def check_current(self): -- if self.process != None and self.database_mtime() > self.running_mtime: -- debug("stopped process, database has changed.") -- self.stop() -+ pass - - def __process_required(self): -- if self.process != None: -+ if self.sock != None: - return -- to_run = self.base_command + ['automate', 'stdio'] -- self.running_mtime = self.database_mtime() -- self.process = popen2.Popen3(to_run, capturestderr=True) -- map (set_nonblocking, [ self.process.fromchild, -- self.process.tochild, -- self.process.childerr ]) -+ self.sock = socket.socket() -+ self.sock.connect((self.stdio_addr[0], int(self.stdio_addr[1]))) -+ self.sock.send(self.database + "\n") - - def run(self, *args, **kwargs): - #debug(("automate is running:", args, kwargs)) -@@ -140,19 +134,16 @@ - - return CleanRequest(self.__run(*args, **kwargs)) - -- def __run(self, command, args, **kwargs): -+ def __run(self, command, args, opts = []): - def str_with_len(l, s): - l.append(str(len(s))) - l.append(":") - l.append(s) - parts = [] -- for k in kwargs: -- # can't use a '-' as a named function argument -- kd = k.replace('_', '-') -- parts.append("o") -- str_with_len(parts, kd) -- str_with_len(parts, kwargs[k]) -- parts.append("e") -+ parts.append("o") -+ for x in opts: # I don't think **kwargs allows duplicates? -+ str_with_len(parts, x) -+ parts.append("e") - parts.append("l") - str_with_len(parts, command) - for x in args: -@@ -164,23 +155,22 @@ - for i in xrange(2): - self.__process_required() - try: -- self.process.tochild.write(enc) -- self.process.tochild.flush() -+ self.sock.send(enc) - break - except: - # mtn has died underneath the automate; restart it -- debug("exception writing to child process; attempting restart: %s" % format_exc()) -+ debug("exception writing to automation server; attempting restart: %s" % format_exc()) - self.stop() - - def read_result_packets(): - buffer = "" - while True: -- r_stdin, r_stdout, r_stderr = select.select([self.process.fromchild], [], [], None) -+ r_stdin, r_stdout, r_stderr = select.select([self.sock], [], [], None) - if not r_stdin and not r_stdout and not r_stderr: - break - -- if self.process.fromchild in r_stdin: -- data = self.process.fromchild.read() -+ if self.sock in r_stdin: -+ data = self.sock.recv(4096) - if data == "": - break - buffer += data -@@ -230,25 +220,6 @@ - if code_max > 0: - raise MonotoneException("error code %d in automate packet." % (code_max)) - --class Standalone(Runner): -- """Runs commands by running monotone. One monotone process -- per command""" -- -- def run(self, command, args): -- # as we pass popen3 as sequence, it executes monotone with these -- # arguments - and does not pass them through the shell according -- # to help(os.popen3) --# debug(("standalone is running:", command, args)) -- to_run = self.base_command + [command] + args -- process = popen2.Popen3(to_run, capturestderr=True) -- for line in process.fromchild: -- yield line -- stderr_data = process.childerr.read() -- if len(stderr_data) > 0: -- raise MonotoneException("data on stderr for command '%s': %s" % (command, -- stderr_data)) -- terminate_popen3(process) -- - class MtnObject(object): - def __init__(self, obj_type): - self.obj_type = obj_type -@@ -370,11 +341,10 @@ - - class Operations(object): - def __init__(self, runner_args): -- self.standalone = apply(Standalone, runner_args) - self.automate = apply(Automate, runner_args) - - def per_request(self): -- """"Call this method every distinct request, to allow Operations to do any -+ """Call this method every distinct request, to allow Operations to do any - cleanup operations. - """ - self.automate.check_current() -@@ -392,7 +362,7 @@ - yield Revision(revision_id) - - def branches(self): -- for line in (t.strip() for t in self.automate.run('branches', [], ignore_suspend_certs="")): -+ for line in (t.strip() for t in self.automate.run('branches', [], ['ignore-suspend-certs', ""])): - if not line: - continue - yield apply(Branch, (line,)) -@@ -452,8 +422,12 @@ - yield stanza - - def diff(self, revision_from, revision_to, files=[]): -- args = ['-r', revision_from, '-r', revision_to] + files -- for line in self.standalone.run('diff', args): -+ for line in self.automate.run('content_diff', -+ files, -+ ['with-header', '', -+ 'revision', revision_from, -+ 'revision', revision_to]): -+ - yield line - - ### diff -ru viewmtn-0.10/viewmtn.py webhost/www/viewmtn/viewmtn.py --- viewmtn-0.10/viewmtn.py 2010-02-28 16:32:01.106065059 -0600 +++ webhost/www/viewmtn/viewmtn.py 2010-02-27 23:48:09.337400710 -0600 @@ -317,12 +132,3 @@ diff -ru viewmtn-0.10/viewmtn.py webhost def runfcgi_apache(func): web.wsgi.runfcgi(func, None) -@@ -156,7 +159,7 @@ - lambda f: nodefault_closure(f())) - urls += assemble('d', - perdb_urls, -- lambda u: r'^/([A-Za-z]+/)?' + u, -+ lambda u: r'^/([-A-Za-z0-9]+/)?' + u, - lambda f: per_db_closure(f())) - - # import pprint