def run(self): "Run the server and never return" from trytond.backend import Database from trytond.pool import Pool from trytond.monitor import monitor update = bool(CONFIG['init'] or CONFIG['update']) init = {} signal.signal(signal.SIGINT, lambda *a: self.stop()) signal.signal(signal.SIGTERM, lambda *a: self.stop()) if hasattr(signal, 'SIGQUIT'): signal.signal(signal.SIGQUIT, lambda *a: self.stop()) if hasattr(signal, 'SIGUSR1'): signal.signal(signal.SIGUSR1, lambda *a: self.restart()) if CONFIG['pidfile']: with open(CONFIG['pidfile'], 'w') as fd_pid: fd_pid.write("%d" % (os.getpid())) if CONFIG['psyco']: import psyco psyco.full() if not CONFIG["db_name"] \ and bool(CONFIG['init'] or CONFIG['update']): raise Exception('Missing database option!') if not update: self.start_servers() for db_name in CONFIG["db_name"]: init[db_name] = False database = Database(db_name).connect() cursor = database.cursor() try: if CONFIG['init']: if not cursor.test(): self.logger.info("init db") Database.init(cursor) init[db_name] = True cursor.commit() elif not cursor.test(): raise Exception("'%s' is not a Tryton database!" % db_name) finally: cursor.close() for db_name in CONFIG["db_name"]: if update: cursor = Database(db_name).connect().cursor() try: if not cursor.test(): raise Exception("'%s' is not a Tryton database!" % db_name) cursor.execute('SELECT code FROM ir_lang ' \ 'WHERE translatable') lang = [x[0] for x in cursor.fetchall()] finally: cursor.close() else: lang = None Pool(db_name).init(update=update, lang=lang) for kind in ('init', 'update'): CONFIG[kind] = {} for db_name in CONFIG['db_name']: if init[db_name]: while True: password = getpass('Admin Password for %s: ' % db_name) password2 = getpass('Admin Password Confirmation: ') if password != password2: sys.stderr.write('Admin Password Confirmation ' \ 'doesn\'t match Admin Password!\n') continue if not password: sys.stderr.write('Admin Password is required!\n') continue break database = Database(db_name).connect() cursor = database.cursor() try: salt = ''.join(random.sample( string.letters + string.digits, 8)) password += salt if hashlib: password = hashlib.sha1(password).hexdigest() else: password = sha.new(password).hexdigest() cursor.execute('UPDATE res_user ' \ 'SET password = %s, salt = %s ' \ 'WHERE login = \'admin\'', (password, salt)) cursor.commit() finally: cursor.close() if update: self.logger.info('Update/Init succeed!') logging.shutdown() sys.exit(0) threads = {} while True: if CONFIG['cron']: for dbname in Pool.database_list(): thread = threads.get(dbname) if thread and thread.is_alive(): continue pool = Pool(dbname) if not pool.lock.acquire(0): continue try: if 'ir.cron' not in pool.object_name_list(): continue cron_obj = pool.get('ir.cron') finally: pool.lock.release() thread = threading.Thread( target=cron_obj.run, args=(dbname,), kwargs={}) thread.start() threads[dbname] = thread if CONFIG['auto_reload']: for _ in range(60): if monitor(): self.restart() time.sleep(1) else: time.sleep(60)
class TrytonServer(object): def __init__(self, options): config.update_etc(options.configfile) if options.logconf: logging.config.fileConfig(options.logconf) logging.getLogger('server').info( 'using %s as logging ' 'configuration file', options.logconf) else: logformat = ('%(process)s %(thread)s [%(asctime)s] ' '%(levelname)s %(name)s %(message)s') if options.verbose: if options.dev: level = logging.DEBUG else: level = logging.INFO else: level = logging.ERROR logging.basicConfig(level=level, format=logformat) self.logger = logging.getLogger(__name__) if options.configfile: self.logger.info('using %s as configuration file', options.configfile) else: self.logger.info('using default configuration') self.logger.info('initialising distributed objects services') self.xmlrpcd = [] self.jsonrpcd = [] self.webdavd = [] self.options = options if time.tzname[0] != 'UTC': self.logger.error('timezone is not set to UTC') def run(self): "Run the server and never return" init = {} signal.signal(signal.SIGINT, lambda *a: self.stop()) signal.signal(signal.SIGTERM, lambda *a: self.stop()) if hasattr(signal, 'SIGQUIT'): signal.signal(signal.SIGQUIT, lambda *a: self.stop()) if hasattr(signal, 'SIGUSR1'): signal.signal(signal.SIGUSR1, lambda *a: self.restart()) if self.options.pidfile: with open(self.options.pidfile, 'w') as fd_pid: fd_pid.write("%d" % (os.getpid())) if not self.options.update: self.start_servers() for db_name in self.options.database_names: init[db_name] = False try: with Transaction().start(db_name, 0) as transaction: cursor = transaction.cursor if self.options.update: if not cursor.test(): self.logger.info("init db") backend.get('Database').init(cursor) init[db_name] = True cursor.commit() elif not cursor.test(): raise Exception("'%s' is not a Tryton database!" % db_name) except Exception: self.stop(False) raise for db_name in self.options.database_names: if self.options.update: with Transaction().start(db_name, 0) as transaction: cursor = transaction.cursor if not cursor.test(): raise Exception("'%s' is not a Tryton database!" % db_name) cursor.execute('SELECT code FROM ir_lang ' 'WHERE translatable') lang = [x[0] for x in cursor.fetchall()] else: lang = None Pool(db_name).init(update=self.options.update, lang=lang) for db_name in self.options.database_names: if init[db_name]: # try to read password from environment variable # TRYTONPASSFILE, empty TRYTONPASSFILE ignored passpath = os.getenv('TRYTONPASSFILE') password = '' if passpath: try: with open(passpath) as passfile: password = passfile.readline()[:-1] except Exception, err: sys.stderr.write('Can not read password ' 'from "%s": "%s"\n' % (passpath, err)) if not password: while True: password = getpass('Admin Password for %s: ' % db_name) password2 = getpass('Admin Password Confirmation: ') if password != password2: sys.stderr.write( 'Admin Password Confirmation ' 'doesn\'t match Admin Password!\n') continue if not password: sys.stderr.write('Admin Password is required!\n') continue break with Transaction().start(db_name, 0) as transaction: pool = Pool() User = pool.get('res.user') admin, = User.search([('login', '=', 'admin')]) User.write([admin], { 'password': password, }) transaction.cursor.commit() if self.options.update: self.logger.info('Update/Init succeed!') logging.shutdown() sys.exit(0) threads = {} while True: if self.options.cron: for dbname in Pool.database_list(): thread = threads.get(dbname) if thread and thread.is_alive(): continue pool = Pool(dbname) if not pool.lock.acquire(0): continue try: try: Cron = pool.get('ir.cron') except KeyError: continue finally: pool.lock.release() thread = threading.Thread(target=Cron.run, args=(dbname, ), kwargs={}) thread.start() threads[dbname] = thread if self.options.dev: for _ in range(60): if monitor([self.options.configfile] if self.options. configfile else []): self.restart() time.sleep(1) else: time.sleep(60)
if not pool.lock.acquire(0): continue try: if 'ir.cron' not in pool.object_name_list(): continue Cron = pool.get('ir.cron') finally: pool.lock.release() thread = threading.Thread( target=Cron.run, args=(dbname,), kwargs={}) thread.start() threads[dbname] = thread if CONFIG['auto_reload']: for _ in range(60): if monitor(): self.restart() time.sleep(1) else: time.sleep(60) def start_servers(self): # Launch Server if CONFIG['jsonrpc']: from trytond.protocols.jsonrpc import JSONRPCDaemon for hostname, port in CONFIG['jsonrpc']: self.jsonrpcd.append(JSONRPCDaemon(hostname, port, CONFIG['ssl_jsonrpc'])) self.logger.info("starting JSON-RPC%s protocol on %s:%d" % (CONFIG['ssl_jsonrpc'] and ' SSL' or '', hostname or '*', port))