[WIP] restart server + update of server via apps

bzr revid: chs@openerp.com-20120907144102-qi35brwee3wh9fwb
This commit is contained in:
Christophe Simonis 2012-09-07 16:41:02 +02:00
parent f633c116e2
commit 8b68252da4
3 changed files with 66 additions and 22 deletions

View File

@ -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():

View File

@ -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 = []

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
@ -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 <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
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: