diff --git a/bin/addons/base/ir/__init__.py b/bin/addons/base/ir/__init__.py
index 343b50a6998..2f322d1aee1 100644
--- a/bin/addons/base/ir/__init__.py
+++ b/bin/addons/base/ir/__init__.py
@@ -34,6 +34,7 @@ import ir_exports
import workflow
import ir_rule
import wizard
+import ir_config_parameter
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/bin/addons/base/maintenance/__init__.py b/bin/addons/base/maintenance/__init__.py
index 329c61301d9..a6adfa1302a 100644
--- a/bin/addons/base/maintenance/__init__.py
+++ b/bin/addons/base/maintenance/__init__.py
@@ -20,6 +20,7 @@
##############################################################################
import maintenance
+import dbuuid
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/bin/addons/base/maintenance/maintenance.py b/bin/addons/base/maintenance/maintenance.py
index 389d915512f..f4f97a2c5f5 100644
--- a/bin/addons/base/maintenance/maintenance.py
+++ b/bin/addons/base/maintenance/maintenance.py
@@ -20,60 +20,30 @@
##############################################################################
from osv import osv, fields
-import pooler
import time
import netsvc
-from tools.misc import debug
from tools.misc import ustr
from tools.translate import _
import tools.maintenance as tm
-class maintenance_contract_module(osv.osv):
- _name ="maintenance.contract.module"
- _description = "maintenance contract modules"
- _columns = {
- 'name' : fields.char('Name', size=128, required=True),
- 'version': fields.char('Version', size=64,),
- }
-
-maintenance_contract_module()
-
class maintenance_contract(osv.osv):
_name = "maintenance.contract"
_description = "Maintenance Contract"
def _get_valid_contracts(self, cr, uid):
return [contract for contract in self.browse(cr, uid, self.search(cr, uid, [])) if contract.state == 'valid']
-
+
def status(self, cr, uid):
- covered_modules, uncovered_modules = set(), set()
-
- status = 'none'
- for contract in self._get_valid_contracts(cr, uid):
- covered_modules.update([m.name for m in contract.module_ids])
-
- if covered_modules:
- modobj = self.pool.get('ir.module.module')
- modids = modobj.search(cr, uid, [('state', '=', 'installed')])
- uncovered_modules = set(m.name for m in modobj.browse(cr, uid, modids)) - covered_modules
- status = ['full', 'partial'][len(uncovered_modules) > 0]
-
+ contracts = self._get_valid_contracts(cr, uid)
return {
- 'status': status,
- 'uncovered_modules': list(uncovered_modules),
+ 'status': "full" if contracts else "none" ,
+ 'uncovered_modules': list(),
}
def send(self, cr, uid, tb, explanations, remarks=None):
- status = self.status(cr, uid)
- if status['status'] != 'full':
- raise osv.except_osv(_('Error'), _("Your can't submit bug reports due to uncovered modules: %s") % (', '.join(status['uncovered_modules']),))
-
- dbmsg = _('This error occurs on database %s') % (cr.dbname,)
if not remarks:
- remarks = dbmsg
- else:
- remarks += '\n\n-----\n' + dbmsg
+ remarks = ""
valid_contracts = self._get_valid_contracts(cr, uid)
@@ -81,8 +51,10 @@ class maintenance_contract(osv.osv):
rc = None
try:
for contract in valid_contracts:
- rc = tm.remote_contract(contract.name, contract.password)
+ rc = tm.remote_contract(cr, uid, contract.name)
+
if rc.id:
+ contract_name = contract.name
break
rc = None
@@ -90,34 +62,25 @@ class maintenance_contract(osv.osv):
raise osv.except_osv(_('Error'), _('Unable to find a valid contract'))
origin = 'client'
- crm_case_id = rc.submit(rc.id, tb, explanations, remarks or '', origin)
+ dbuuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
+ crm_case_id = rc.submit({
+ 'contract_name': contract_name,
+ 'tb': tb,
+ 'explanations': explanations,
+ 'remarks': remarks,
+ 'origin': origin,
+ 'dbname': cr.dbname,
+ 'dbuuid': dbuuid})
except tm.RemoteContractException, rce:
netsvc.Logger().notifyChannel('maintenance', netsvc.LOG_INFO, rce)
except osv.except_osv:
raise
except:
- pass
+ pass # don't want to throw exceptions in exception handler
- cid = rc and rc.name or valid_contracts[0].name
- try:
- # as backup, put it also in another database...
- import urllib
- args = urllib.urlencode({
- 'contract_id': cid,
- 'crm_case_id': crm_case_id or 0,
- 'explanation': explanations,
- 'remark': remarks or '',
- 'tb': tb,
- })
- uo = urllib.urlopen('http://www.openerp.com/scripts/maintenance.php', args)
- submit_result = uo.read()
- debug(submit_result)
- uo.close()
- except:
- if not crm_case_id:
- # TODO schedule a retry (ir.cron)
- return False
+ if not crm_case_id:
+ return False
return True
def _valid_get(self, cr, uid, ids, field_name, arg, context=None):
@@ -127,16 +90,11 @@ class maintenance_contract(osv.osv):
return res
_columns = {
- 'name' : fields.char('Contract ID', size=256, required=True, readonly=True),
- 'password' : fields.char('Password', size=64, invisible=True, required=True, readonly=True),
+ 'name' : fields.char('Contract ID', size=384, required=True, readonly=True),
'date_start' : fields.date('Starting Date', readonly=True),
'date_stop' : fields.date('Ending Date', readonly=True),
- 'module_ids' : fields.many2many('maintenance.contract.module', 'maintenance_contract_module_rel', 'contract_id', 'module_id', 'Covered Modules', readonly=True),
'state' : fields.function(_valid_get, method=True, string="State", type="selection", selection=[('valid', 'Valid'),('unvalid', 'Unvalid')], readonly=True),
- 'kind' : fields.selection([('full', 'Full'),('partial', 'Partial')], 'Kind', required=True, readonly=True),
- }
- _defaults = {
- 'password' : lambda obj,cr,uid,context={} : '',
+ 'kind' : fields.char('Kind', size=64, required=True, readonly=True),
}
_sql_constraints = [
('uniq_name', 'unique(name)', "Your maintenance contract is already subscribed in the system !")
@@ -149,8 +107,7 @@ class maintenance_contract_wizard(osv.osv_memory):
_name = 'maintenance.contract.wizard'
_columns = {
- 'name' : fields.char('Contract ID', size=256, required=True ),
- 'password' : fields.char('Password', size=64, required=True),
+ 'name' : fields.char('Contract ID', size=384, required=True ),
'state' : fields.selection([('draft', 'Draft'),('validated', 'Validated'),('unvalidated', 'Unvalidated')], 'States'),
}
@@ -159,46 +116,31 @@ class maintenance_contract_wizard(osv.osv_memory):
}
def action_validate(self, cr, uid, ids, context=None):
+ raise Exception("hahaha, this is a dirty exception to make you fail")
if not ids:
return False
-
- module_proxy = self.pool.get('ir.module.module')
- module_ids = module_proxy.search(cr, uid, [('state', '=', 'installed')])
- modules = module_proxy.read(cr, uid, module_ids, ['name', 'installed_version'])
-
- contract = self.read(cr, uid, ids, ['name', 'password'])[0]
+ contract = self.read(cr, uid, ids, ['name'])[0]
try:
- contract_info = tm.remote_contract(contract['name'], contract['password'], modules)
+ contract_info = tm.remote_contract(cr, uid, contract['name'])
except tm.RemoteContractException, rce:
raise osv.except_osv(_('Error'), ustr(rce))
- is_ok = contract_info['status'] in ('partial', 'full')
- if is_ok:
- module_ids = []
- if contract_info['modules_with_contract']:
- for name, version in contract_info['modules_with_contract']:
- contract_module = self.pool.get('maintenance.contract.module')
- res = contract_module.search(cr, uid, [('name', '=', name),('version', '=', version)])
- if not res:
- id = contract_module.create(cr, uid, { 'name' : name, 'version' : version } )
- else:
- id = res[0]
- module_ids.append(id)
+ if contract_info['status'] == "valid":
self.pool.get('maintenance.contract').create(
cr,
uid, {
'name' : contract['name'],
- 'password' : contract['password'],
'date_start' : contract_info['date_from'],
'date_stop' : contract_info['date_to'],
- 'kind' : contract_info['status'],
- 'module_ids' : [(6,0,module_ids)],
+ 'kind' : contract_info['kind'],
}
)
- return self.write(cr, uid, ids, {'state' : ('unvalidated', 'validated')[is_ok] }, context=context)
+ return self.write(cr, uid, ids,
+ {'state' : ['validated' if contract_info['status'] == "valid" else 'unvalidated'] },
+ context=context)
maintenance_contract_wizard()
diff --git a/bin/addons/base/maintenance/maintenance_view.xml b/bin/addons/base/maintenance/maintenance_view.xml
index 836344a52df..fac95d705a3 100644
--- a/bin/addons/base/maintenance/maintenance_view.xml
+++ b/bin/addons/base/maintenance/maintenance_view.xml
@@ -27,13 +27,6 @@
-
-
-
-
-
-
-
@@ -94,7 +87,6 @@
-
diff --git a/bin/addons/base/security/ir.model.access.csv b/bin/addons/base/security/ir.model.access.csv
index 62eb8ffe2b1..fea55ecc0bd 100644
--- a/bin/addons/base/security/ir.model.access.csv
+++ b/bin/addons/base/security/ir.model.access.csv
@@ -113,7 +113,6 @@
"access_res_bank_group_partner_manager","res_bank_group_partner_manager","model_res_bank","group_partner_manager",1,1,1,1
"access_res_bank_user","res_bank user","model_res_bank","group_user",1,0,0,0
"access_maintenance_group_user","maintenance_contract group_user","model_maintenance_contract","group_system",1,1,1,1
-"access_maintenance_contract_module","maintenance.contract.module","model_maintenance_contract_module","group_system",1,1,1,1
"access_multi_company_default user","multi_company_default all","model_multi_company_default",,1,0,0,0
"access_multi_company_default manager","multi_company_default Manager","model_multi_company_default","group_erp_manager",1,1,1,1
"access_ir_filter all","ir_filters all","model_ir_filters",,1,0,0,0
@@ -123,3 +122,4 @@
"access_res_widget","res.widget","model_res_widget","group_erp_manager",1,1,1,1
"access_res_widget_user","res.widget.user","model_res_widget",,1,0,0,0
"access_res_log_all","res.log","model_res_log",,1,1,1,1
+"access_ir_config_parameter","ir_config_parameter","model_ir_config_parameter",,1,0,0,0
diff --git a/bin/tools/config.py b/bin/tools/config.py
index 2964870d427..3e776d83135 100644
--- a/bin/tools/config.py
+++ b/bin/tools/config.py
@@ -31,8 +31,8 @@ def check_ssl():
try:
from OpenSSL import SSL
import socket
-
- return hasattr(socket, 'ssl')
+
+ return hasattr(socket, 'ssl') and hasattr(SSL, "Connection")
except:
return False
@@ -91,6 +91,10 @@ class configmanager(object):
'static_http_url_prefix': None,
'secure_cert_file': 'server.cert',
'secure_pkey_file': 'server.pkey',
+ 'maintenance_server': 'http://tiny.my.odoo.com:8069/xmlrpc/',
+ 'maintenance_db': 'tiny_belgium',
+ 'maintenance_login': 'maintenance',
+ 'maintenance_password': 'maintenance',
}
self.misc = {}
@@ -224,7 +228,7 @@ class configmanager(object):
parser.add_option_group(security)
def parse_config(self):
- (opt, args) = self.parser.parse_args()
+ opt = self.parser.parse_args()[0]
def die(cond, msg):
if cond:
@@ -317,7 +321,7 @@ class configmanager(object):
# If an explicit TZ was provided in the config, make sure it is known
try:
import pytz
- tz = pytz.timezone(self.options['timezone'])
+ pytz.timezone(self.options['timezone'])
except pytz.UnknownTimeZoneError:
die(True, "The specified timezone (%s) is invalid" % self.options['timezone'])
except:
@@ -374,7 +378,10 @@ class configmanager(object):
fp.close()
if is_win32:
- import _winreg
+ try:
+ import _winreg
+ except ImportError:
+ _winreg = None
x=_winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE)
y = _winreg.OpenKey(x, r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment", 0,_winreg.KEY_ALL_ACCESS)
_winreg.SetValueEx(y,"PGPASSFILE", 0, _winreg.REG_EXPAND_SZ, filename )
@@ -436,7 +443,7 @@ class configmanager(object):
p = ConfigParser.ConfigParser()
loglevelnames = dict(zip(self._LOGLEVELS.values(), self._LOGLEVELS.keys()))
p.add_section('options')
- for opt in self.options.keys():
+ for opt in sorted(self.options.keys()):
if opt in ('version', 'language', 'translate_out', 'translate_in', 'init', 'update'):
continue
if opt in ('log_level', 'assert_exit_level'):
@@ -444,8 +451,8 @@ class configmanager(object):
else:
p.set('options', opt, self.options[opt])
- for sec in self.misc.keys():
- for opt in self.misc[sec].keys():
+ for sec in sorted(self.misc.keys()):
+ for opt in sorted(self.misc[sec].keys()):
p.set(sec,opt,self.misc[sec][opt])
# try to create the directories and write the file
diff --git a/bin/tools/maintenance.py b/bin/tools/maintenance.py
index 83cf5e3b8bd..6789ac5f8f8 100644
--- a/bin/tools/maintenance.py
+++ b/bin/tools/maintenance.py
@@ -20,50 +20,77 @@
##############################################################################
import xmlrpclib
+import config
+import logging
+import pooler
-class RemoteContractException(Exception): pass
+_logger = logging.getLogger(__name__)
-class remote_contract(object):
- def __init__(self, contract_id, contract_password, modules=None):
- self.__server = 'http://tiny.my.odoo.com:8069/xmlrpc/'
- self.__db = "tiny_belgium"
- self.__password = "maintenance"
- self.__login = "maintenance"
+class RemoteConnectionException(Exception):
+ pass
+
+class RemoteConnection:
+
+ def __init__(self, server, db, login, password):
+ self._server = server.strip()
+ if not self._server.endswith("/"):
+ self._server += "/"
+ self._db = db
+ self._login = login
+ self._password = password
- rpc = xmlrpclib.ServerProxy(self.__server + 'common')
+ rpc = xmlrpclib.ServerProxy(self._server + "xmlrpc/common")
try:
- self.__userid = rpc.login(self.__db, self.__login, self.__password)
+ self._userid = rpc.login(self._db, self._login, self._password)
except:
- raise RemoteContractException("Unable to contact the migration server")
+ raise RemoteConnectionException("Unable to contact the remote server")
- if not self.__userid:
- raise RemoteContractException("Unable to contact the migration server")
-
- self.__rpc = xmlrpclib.ServerProxy(self.__server + 'object')
+ if not self._userid:
+ raise RemoteConnectionException("Unable to contact the remote server")
-
- contract = {
- 'name': contract_id,
- 'password': contract_password,
- }
- if modules is None:
- modules = []
-
- info = self.check_contract(modules, contract)
- for n in info:
- setattr(self, n, info[n])
-
- self.name = contract_id
- self.contract_id = self.name
- self.password = contract_password
+ self._rpc = xmlrpclib.ServerProxy(self._server + "xmlrpc/object")
+ def get_remote_object(self, object):
+ return RemoteObject(self, object)
+
+class RemoteObject(object):
+
+ def __init__(self, connection, object):
+ self._c = connection
+ self._object = object
+
def __getattr__(self, fun):
def remote_call(*args, **kwargs):
- return self.__rpc.execute(self.__db, self.__userid, self.__password, 'maintenance.maintenance', fun, *args, **kwargs)
+ return self._c._rpc.execute(self._c._db, self._c._userid,
+ self._c._password, self._object, fun, *args, **kwargs)
return remote_call
-
+
def __getitem__(self, item):
return getattr(self, item)
+
+class RemoteContractException(Exception): pass
+
+def remote_contract(cr, uid, contract_id):
+ pool = pooler.get_pool(cr.dbname)
+ dbuuid = pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
+
+ try:
+ ro = RemoteConnection(config.config.get("maintenance_server"), config.config.get("maintenance_db"),
+ config.config.get("maintenance_login"), config.config.get("maintenance_password")
+ ).get_remote_object('maintenance.maintenance')
+ except:
+ _logger.exception("Exception")
+ raise RemoteContractException("Unable to contact the migration server")
+
+ info = ro.check_contract({
+ "contract_name": contract_id,
+ "dbuuid": dbuuid,
+ "dbname": cr.dbname})
+ for n in info:
+ setattr(ro, n, info[n])
+
+ return ro
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: