Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REF] module_auto_update: Deprecate buggy features, add new API #1190

Merged
merged 3 commits into from
Mar 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 49 additions & 15 deletions module_auto_update/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,69 @@
Module Auto Update
==================

This module will automatically check for and apply module upgrades on a schedule.

Upgrade checking is accomplished by comparing the SHA1 checksums of currently-installed modules to the checksums of corresponding modules in the addons directories.

Installation
============

Prior to installing this module, you need to:

#. Install checksumdir with `pip install checksumdir`
#. Ensure all installed modules are up-to-date. When installed, this module will assume the versions found in the addons directories are currently installed.
This addon provides mechanisms to compute sha1 hashes of installed addons,
and save them in the database. It also provides a method that exploits these
mechanisms to update a database by upgrading only the modules for which the
hash has changed since the last successful upgrade.

Configuration
=============

The default time for checking and applying upgrades is 3:00 AM (UTC). To change this schedule, modify the "Perform Module Upgrades" scheduled action.
This module supports the following system parameters:

This module will ignore .pyc and .pyo file extensions by default. To modify this, create a module_auto_update.checksum_excluded_extensions system parameter with the desired extensions listed as comma-separated values.
* ``module_auto_update.exclude_patterns``: comma-separated list of file
name patterns to ignore when computing addon checksums. Defaults to
``*.pyc,*.pyo,i18n/*.pot,i18n_extra/*.pot,static/*``.
Filename patterns must be compatible with the python ``fnmatch`` function.

In addition to the above pattern, .po files corresponding to languages that
are not installed in the Odoo database are ignored when computing checksums.

Usage
=====

Modules scheduled for upgrade can be viewed by clicking the "Updates" menu item in the Apps sidebar.
The main method provided by this module is ``upgrade_changed_checksum``
on ``ir.module.module``. It runs a database upgrade for all installed
modules for which the hash has changed since the last successful
run of this method. On success it saves the hashes in the database.

The first time this method is invoked after installing the module, it
runs an upgrade of all modules, because it has not saved the hashes yet.
This is by design, priviledging safety. Should this be an issue,
the method ``_save_installed_checksums`` can be invoked in a situation
where one is sure all modules on disk are installed and up-to-date in the
database.

An easy way to invoke this upgrade mechanism is by issuing the following
in an Odoo shell session::

To perform upgrades manually, click the "Apply Scheduled Upgrades" menu item in the Apps sidebar.
env['ir.module.module'].upgrade_changed_checksum()

.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/149/9.0

Known issues / Roadmap
======================

* Since version ``2.0.0``, some features have been deprecated.
When you upgrade from previous versions, these features will be kept for
backwards compatibility, but beware! They are buggy!

If you install this addon from scratch, these features are disabled by
default.

To force enabling or disabling the deprecated features, set a configuration
parameter called ``module_auto_update.enable_deprecated`` to either ``1``
or ``0``. It is recommended that you disable them.

Keep in mind that from this version, all upgrades are assumed to run in a
separate odoo instance, dedicated exclusively to upgrade Odoo.

* When migrating the addon to new versions, the deprecated features should be
removed. To make it simple all deprecated features are found in files
suffixed with ``_deprecated``.

Bug Tracker
===========

Expand All @@ -58,6 +91,7 @@ Contributors
* Brent Hughes <[email protected]>
* Juan José Scarafía <[email protected]>
* Jairo Llopis <[email protected]>
* Stéphane Bidoul <[email protected]> (https://acsone.eu)

Do not contact contributors directly about support or help with technical issues.

Expand Down
2 changes: 1 addition & 1 deletion module_auto_update/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

from . import models
from . import wizards
from .hooks import post_init_hook
from .hooks import uninstall_hook
15 changes: 5 additions & 10 deletions module_auto_update/__openerp__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,22 @@
{
'name': 'Module Auto Update',
'summary': 'Automatically update Odoo modules',
'version': '9.0.1.0.2',
'version': '9.0.2.0.0',
'category': 'Extra Tools',
'website': 'https://odoo-community.org/',
'website': 'https://github.com/OCA/server-tools',
'author': 'LasLabs, '
'Juan José Scarafía, '
'Tecnativa, '
'ACSONE SA/NV, '
'Odoo Community Association (OCA)',
'license': 'LGPL-3',
'application': False,
'installable': True,
'post_init_hook': 'post_init_hook',
'external_dependencies': {
'python': [
'checksumdir',
],
},
'uninstall_hook': 'uninstall_hook',
'depends': [
'base',
],
'data': [
'views/module_views.xml',
'data/cron_data.xml',
'data/cron_data_deprecated.xml',
],
}
45 changes: 45 additions & 0 deletions module_auto_update/addon_hash.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
# Copyright 2018 ACSONE SA/NV.
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from fnmatch import fnmatch
import hashlib
import os


def _fnmatch(filename, patterns):
for pattern in patterns:
if fnmatch(filename, pattern):
return True
return False


def _walk(top, exclude_patterns, keep_langs):
keep_langs = {l.split('_')[0] for l in keep_langs}
for dirpath, dirnames, filenames in os.walk(top):
dirnames.sort()
reldir = os.path.relpath(dirpath, top)
if reldir == '.':
reldir = ''
for filename in sorted(filenames):
filepath = os.path.join(reldir, filename)
if _fnmatch(filepath, exclude_patterns):
continue
if keep_langs and reldir in {'i18n', 'i18n_extra'}:
basename, ext = os.path.splitext(filename)
if ext == '.po':
if basename.split('_')[0] not in keep_langs:
continue
yield filepath


def addon_hash(top, exclude_patterns, keep_langs):
"""Compute a sha1 digest of file contents."""
m = hashlib.sha1()
for filepath in _walk(top, exclude_patterns, keep_langs):
# hash filename so empty files influence the hash
m.update(filepath.encode('utf-8'))
# hash file content
with open(os.path.join(top, filepath), 'rb') as f:
m.update(f.read())
return m.hexdigest()
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<odoo noupdate="1">
<record model="ir.cron" id="module_check_upgrades_cron">
<field name="name">Perform Module Upgrades</field>
<field name="active" eval="True"/>
<field name="active" eval="False"/>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
Expand Down
16 changes: 10 additions & 6 deletions module_auto_update/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@

from openerp import SUPERUSER_ID, api

from .models.module import PARAM_INSTALLED_CHECKSUMS
from .models.module_deprecated import PARAM_DEPRECATED

def post_init_hook(cr, registry):

def uninstall_hook(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {})
installed_modules = env['ir.module.module'].search([
('state', '=', 'installed'),
])
for r in installed_modules:
r.checksum_installed = r.checksum_dir
env["ir.config_parameter"].set_param(PARAM_INSTALLED_CHECKSUMS, False)
# TODO Remove from here when removing deprecated features
env["ir.config_parameter"].set_param(PARAM_DEPRECATED, False)
prefix = "module_auto_update.field_ir_module_module_checksum_%s"
fields = env.ref(prefix % "dir") | env.ref(prefix % "installed")
fields.with_context(_force_unlink=True).unlink()
23 changes: 23 additions & 0 deletions module_auto_update/migrations/9.0.2.0.0/pre-migrate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Copyright 2018 Tecnativa - Jairo Llopis
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
import logging
from psycopg2 import IntegrityError
from openerp.addons.module_auto_update.models.module_deprecated import \
PARAM_DEPRECATED

_logger = logging.getLogger(__name__)


def migrate(cr, version):
"""Autoenable deprecated behavior."""
try:
cr.execute(
"INSERT INTO ir_config_parameter (key, value) VALUES (%s, '1')",
(PARAM_DEPRECATED,)
)
_logger.warn("Deprecated features have been autoenabled, see "
"addon's README to know how to upgrade to the new "
"supported autoupdate mechanism.")
except IntegrityError:
_logger.info("Deprecated features setting exists, not autoenabling")
1 change: 1 addition & 0 deletions module_auto_update/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from . import module
from . import module_deprecated
Loading