merge trunk
[odoo/odoo.git] / openerp / cli / server.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22 """
23 OpenERP - Server
24 OpenERP is an ERP+CRM program for small and medium businesses.
25
26 The whole source code is distributed under the terms of the
27 GNU Public Licence.
28
29 (c) 2003-TODAY, Fabien Pinckaers - OpenERP SA
30 """
31
32 import logging
33 import os
34 import signal
35 import sys
36 import threading
37 import traceback
38 import time
39
40 import openerp
41
42 from . import Command
43
44 __author__ = openerp.release.author
45 __version__ = openerp.release.version
46
47 # Also use the `openerp` logger for the main script.
48 _logger = logging.getLogger('openerp')
49
50 def check_root_user():
51     """ Exit if the process's user is 'root' (on POSIX system)."""
52     if os.name == 'posix':
53         import pwd
54         if pwd.getpwuid(os.getuid())[0] == 'root' :
55             sys.stderr.write("Running as user 'root' is a security risk, aborting.\n")
56             sys.exit(1)
57
58 def check_postgres_user():
59     """ Exit if the configured database user is 'postgres'.
60
61     This function assumes the configuration has been initialized.
62     """
63     config = openerp.tools.config
64     if config['db_user'] == 'postgres':
65         sys.stderr.write("Using the database user 'postgres' is a security risk, aborting.")
66         sys.exit(1)
67
68 def report_configuration():
69     """ Log the server version and some configuration values.
70
71     This function assumes the configuration has been initialized.
72     """
73     config = openerp.tools.config
74     _logger.info("OpenERP version %s", __version__)
75     for name, value in [('addons paths', config['addons_path']),
76                         ('database hostname', config['db_host'] or 'localhost'),
77                         ('database port', config['db_port'] or '5432'),
78                         ('database user', config['db_user'])]:
79         _logger.info("%s: %s", name, value)
80
81 def setup_pid_file():
82     """ Create a file with the process id written in it.
83
84     This function assumes the configuration has been initialized.
85     """
86     config = openerp.tools.config
87     if config['pidfile']:
88         fd = open(config['pidfile'], 'w')
89         pidtext = "%d" % (os.getpid())
90         fd.write(pidtext)
91         fd.close()
92
93 def preload_registry(dbname):
94     """ Preload a registry, and start the cron."""
95     try:
96         update_module = True if openerp.tools.config['init'] or openerp.tools.config['update'] else False
97         openerp.modules.registry.RegistryManager.new(dbname, update_module=update_module)
98     except Exception:
99         _logger.exception('Failed to initialize database `%s`.', dbname)
100         return False
101     return True
102
103 def run_test_file(dbname, test_file):
104     """ Preload a registry, possibly run a test file, and start the cron."""
105     try:
106         config = openerp.tools.config
107         registry = openerp.modules.registry.RegistryManager.new(dbname, update_module=config['init'] or config['update'])
108         cr = registry.db.cursor()
109         _logger.info('loading test file %s', test_file)
110         openerp.tools.convert_yaml_import(cr, 'base', file(test_file), 'test', {}, 'test', True)
111         cr.rollback()
112         cr.close()
113     except Exception:
114         _logger.exception('Failed to initialize database `%s` and run test file `%s`.', dbname, test_file)
115
116 def export_translation():
117     config = openerp.tools.config
118     dbname = config['db_name']
119
120     if config["language"]:
121         msg = "language %s" % (config["language"],)
122     else:
123         msg = "new language"
124     _logger.info('writing translation file for %s to %s', msg,
125         config["translate_out"])
126
127     fileformat = os.path.splitext(config["translate_out"])[-1][1:].lower()
128     buf = file(config["translate_out"], "w")
129     registry = openerp.modules.registry.RegistryManager.new(dbname)
130     cr = registry.db.cursor()
131     openerp.tools.trans_export(config["language"],
132         config["translate_modules"] or ["all"], buf, fileformat, cr)
133     cr.close()
134     buf.close()
135
136     _logger.info('translation file written successfully')
137
138 def import_translation():
139     config = openerp.tools.config
140     context = {'overwrite': config["overwrite_existing_translations"]}
141     dbname = config['db_name']
142
143     registry = openerp.modules.registry.RegistryManager.new(dbname)
144     cr = registry.db.cursor()
145     openerp.tools.trans_load( cr, config["translate_in"], config["language"],
146         context=context)
147     cr.commit()
148     cr.close()
149
150 def main(args):
151     check_root_user()
152     openerp.tools.config.parse_config(args)
153     check_postgres_user()
154     openerp.netsvc.init_logger()
155     report_configuration()
156
157     config = openerp.tools.config
158
159     if config["test_file"]:
160         run_test_file(config['db_name'], config['test_file'])
161         sys.exit(0)
162
163     if config["translate_out"]:
164         export_translation()
165         sys.exit(0)
166
167     if config["translate_in"]:
168         import_translation()
169         sys.exit(0)
170
171     # This needs to be done now to ensure the use of the multiprocessing
172     # signaling mecanism for registries loaded with -d
173     if config['workers']:
174         openerp.multi_process = True
175
176     # preload registryies, needed for -u --stop_after_init
177     rc = 0
178     if config['db_name']:
179         for dbname in config['db_name'].split(','):
180             if not preload_registry(dbname):
181                 rc += 1
182
183     if not config["stop_after_init"]:
184         setup_pid_file()
185         openerp.service.server.start()
186         if config['pidfile']:
187             os.unlink(config['pidfile'])
188     else:
189         sys.exit(rc)
190
191     _logger.info('OpenERP server is running, waiting for connections...')
192     quit_on_signals()
193
194 class Server(Command):
195     def run(self, args):
196         main(args)
197
198 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: