From 8b68252da4383020fda612ab17fae64d9583c59e Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 7 Sep 2012 16:41:02 +0200 Subject: [PATCH] [WIP] restart server + update of server via apps bzr revid: chs@openerp.com-20120907144102-qi35brwee3wh9fwb --- openerp-server | 16 +++++++++--- openerp/addons/base/module/module.py | 38 ++++++++++++++++++---------- openerp/service/__init__.py | 34 ++++++++++++++++++++----- 3 files changed, 66 insertions(+), 22 deletions(-) diff --git a/openerp-server b/openerp-server index be0710cbce9..bff23d4c4e0 100755 --- a/openerp-server +++ b/openerp-server @@ -203,13 +203,23 @@ def quit_on_signals(): try: while quit_signals_received == 0: time.sleep(60) - except KeyboardInterrupt, e: + except KeyboardInterrupt: pass + openerp.service.stop_services() + + if getattr(openerp, 'phoenix', False): + # like the phoenix, reborn from ashes... + strip_args = ['-d', '-u'] + a = sys.argv[:] + args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] + + time.sleep(0.5) # wait end of sockets... + os.execv(sys.executable, [sys.executable] + args) + return + if config['pidfile']: os.unlink(config['pidfile']) - - openerp.service.stop_services() sys.exit(0) def configure_babel_localedata_path(): diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 79fbac8eb7f..93ad9cef4a2 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -26,7 +26,6 @@ import logging import os import re import shutil -import sys import tempfile import urllib import zipfile @@ -39,6 +38,7 @@ except ImportError: import requests +import openerp from openerp import modules, pooler, release, tools, addons from openerp.tools.parse_version import parse_version from openerp.tools.translate import _ @@ -640,33 +640,45 @@ class module(osv.osv): assert os.path.isdir(os.path.join(tmp, module_name)) for module_name in urls: + if module_name == 'base': + continue # special case. handled below module_path = modules.get_module_path(module_name, downloaded=True, display_warning=False) bck = backup(module_path, False) shutil.move(os.path.join(tmp, module_name), module_path) if bck: shutil.rmtree(bck) + if urls.get('base', None): + # base is a special case. it containt the server and the base module. + # extract path is not the same + + # TODO copy all modules in the SERVER/openerp/addons directory to the new "base" module (exceptbase itself) + # then replace the server by the new "base" module + base_path = os.path.dirname(modules.get_module_path('base')) + + for d in os.listdir(base_path): + if d != 'base' and os.path.isdir(os.path.join(base_path, d)): + destdir = os.path.join(tmp, 'base', 'addons', d) # XXX 'openerp' + shutil.copytree(os.path.join(base_path, d), destdir) + + server_dir = openerp.tools.config['root_path'] # XXX or dirname() + bck = backup(server_dir) + shutil.move(os.path.join(tmp, 'base'), server_dir) + #if bck: + # shutil.rmtree(bck) + self.update_list(cr, uid, context=context) ids = self.search(cr, uid, [('name', 'in', urls.keys())], context=context) if self.search_count(cr, uid, [('id', 'in', ids), ('state', '=', 'installed')], context=context): # if any to update - return self.restart_server(cr, uid, context) # in fact will never return... + cr.commit() + openerp.service.restart_server() + return False return self.button_immediate_install(cr, uid, ids, context=context) finally: shutil.rmtree(tmp) - def restart_server(self, cr, uid, context=None): - raise NotImplementedError('# FIXME') - # TODO send a signal to will wait all threads (include us) like ctrl-c - # catch the case of gunicorn and force all workers to die... - - strip_args = ['-d', '-u'] - a = sys.argv[:] - args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] - - os.execv(sys.executable, [sys.executable] + args) - def _update_dependencies(self, cr, uid, mod_browse, depends=None): if depends is None: depends = [] diff --git a/openerp/service/__init__.py b/openerp/service/__init__.py index 511d62c5862..72f807a5d69 100644 --- a/openerp/service/__init__.py +++ b/openerp/service/__init__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ############################################################################## -# +# # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). # @@ -15,11 +15,14 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# along with this program. If not, see . # ############################################################################## import logging +import os +import signal +import sys import threading import time @@ -83,24 +86,43 @@ def stop_services(): openerp.netsvc.Server.quitAll() openerp.wsgi.core.stop_server() - config = openerp.tools.config _logger.info("Initiating shutdown") _logger.info("Hit CTRL-C again or send a second signal to force the shutdown.") - logging.shutdown() # Manually join() all threads before calling sys.exit() to allow a second signal # to trigger _force_quit() in case some non-daemon threads won't exit cleanly. # threading.Thread.join() should not mask signals (at least in python 2.5). + me = threading.currentThread() + _logger.debug('current thread: %r', me) for thread in threading.enumerate(): - if thread != threading.currentThread() and not thread.isDaemon(): + _logger.debug('process %r (%r)', thread, thread.isDaemon()) + if thread != me and not thread.isDaemon(): while thread.isAlive(): + _logger.debug('join and sleep') # Need a busyloop here as thread.join() masks signals # and would prevent the forced shutdown. thread.join(0.05) time.sleep(0.05) + _logger.debug('--') openerp.modules.registry.RegistryManager.delete_all() + logging.shutdown() +def restart_server(): + pid = openerp.wsgi.core.arbiter_pid + if pid: + os.kill(pid, signal.SIGHUP) + else: + openerp.phoenix = True + signame = 'CTRL_C_EVENT' if os.name == 'nt' else 'SIGINT' + sig = getattr(signal, signame) + os.kill(os.getpid(), sig) + + #strip_args = ['-d', '-u'] + #a = sys.argv[:] + #args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] + + #stop_services() + #os.execv(sys.executable, [sys.executable] + args) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: -