From f4041de4ed51aee4dc986d77fdf1f2dc9283318b Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Mon, 8 Oct 2018 19:29:22 +0200 Subject: [PATCH] [FIX] website: use proper env in model methods Using `request.env` should be reserved for code that lies outside of model methods (typically: controllers). Model methods have to use the appropriate `self.env`. This particular case caused frequent Python-PostgreSQL undetected deadlocks during installations of website-related modules in 12.0. One way to reproduce it was to trigger the installation of both `website` and `website_form` in a single transaction, with neither pre-installed. Installing Apps that depend on both would do the job, such as `website_sale`, provided that GEOIP is available on the system. In details: During installation of `website`, new attachments creation would call get_current_website (see 602807acdf20ff4f75a1abb7f5fa1be4db3f532d and 4f6ec1cd2a9253bb0c6c17d304490c7809facf8a), using the wrong database cursor: the one from the request instead of the one for the installation, as provided by `ir.module.module._button_immediate_function`. This would acquire database locks on `res.country` and `ir.model` in the wrong transaction, later blocking alterations to `ir.model` in the installation transaction, e.g. for website_form's 'website_form_access' column. This combination of events was possible before 12.0, but more difficult to reproduce as module installations used to happen with a super-user account, ignoring ACL checks and therefore not locking `ir.model`. --- addons/website/models/website.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/website/models/website.py b/addons/website/models/website.py index cf31ce02f2d..a371d760e8e 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -462,7 +462,7 @@ class Website(models.Model): country = request.session.geoip.get('country_code') if request and request.session.geoip else False country_id = False if country: - country_id = request.env['res.country'].search([('code', '=', country)], limit=1).id + country_id = self.env['res.country'].search([('code', '=', country)], limit=1).id website_id = self._get_current_website_id(domain_name, country_id, fallback=fallback) return self.browse(website_id) @@ -644,7 +644,7 @@ class Website(models.Model): @api.multi def get_website_pages(self, domain=[], order='name', limit=None): domain += self.get_current_website().website_domain() - pages = request.env['website.page'].search(domain, order='name', limit=limit) + pages = self.env['website.page'].search(domain, order='name', limit=limit) return pages @api.multi