RRS: handle downgrades

Version downgrades (or what appear to be downgrades) do occasionally
happen, and if they did then the RRS was previously simply ignoring
them, resulting in the latest version being reported incorrectly.
Allow downgrades to be recorded as an upgrade with a new 'Downgrade'
type option set, and display a label on such records in the UI.

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
This commit is contained in:
Paul Eggleton 2019-08-12 22:30:38 +12:00
parent 1a70fd497c
commit 928d19a9ab
5 changed files with 62 additions and 9 deletions

View File

@ -172,7 +172,8 @@ class RecipeDistroAdmin(admin.ModelAdmin):
class RecipeUpgradeAdmin(admin.ModelAdmin): class RecipeUpgradeAdmin(admin.ModelAdmin):
search_fields = ['recipesymbol__pn'] search_fields = ['recipesymbol__pn']
list_filter = ['recipesymbol__layerbranch__layer__name', list_filter = ['recipesymbol__layerbranch__layer__name',
('commit_date', DateFieldListFilter), 'maintainer__name'] 'upgrade_type', ('commit_date', DateFieldListFilter),
'maintainer__name']
model = RecipeUpgrade model = RecipeUpgrade
class RecipeUpstreamHistoryAdmin(admin.ModelAdmin): class RecipeUpstreamHistoryAdmin(admin.ModelAdmin):

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.22 on 2019-08-13 12:37
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('rrs', '0023_recipeupgrade_deleted'),
]
operations = [
migrations.AlterField(
model_name='recipeupgrade',
name='upgrade_type',
field=models.CharField(choices=[('U', 'Upgrade'), ('D', 'Downgrade'), ('N', 'Delete'), ('R', 'Delete (final)')], db_index=True, default='U', max_length=1),
),
]

View File

@ -432,6 +432,7 @@ class RecipeDistro(models.Model):
class RecipeUpgrade(models.Model): class RecipeUpgrade(models.Model):
UPGRADE_TYPE_CHOICES = ( UPGRADE_TYPE_CHOICES = (
('U', 'Upgrade'), ('U', 'Upgrade'),
('D', 'Downgrade'),
('N', 'Delete'), ('N', 'Delete'),
('R', 'Delete (final)'), ('R', 'Delete (final)'),
) )

View File

@ -146,7 +146,7 @@ def _save_upgrade(recipesymbol, layerbranch, pv, commit, title, info, filepath,
""" """
Create upgrade receives new recipe_data and cmp versions. Create upgrade receives new recipe_data and cmp versions.
""" """
def _create_upgrade(recipe_data, layerbranch, ct, title, info, filepath, logger, initial=False): def _create_upgrade(recipe_data, layerbranch, ct, title, info, filepath, logger, pn_recipes, initial=False):
from rrs.models import RecipeUpgrade, RecipeSymbol from rrs.models import RecipeUpgrade, RecipeSymbol
from bb.utils import vercmp_string from bb.utils import vercmp_string
@ -181,9 +181,13 @@ def _create_upgrade(recipe_data, layerbranch, ct, title, info, filepath, logger,
get_pv_type(pv)) get_pv_type(pv))
try: try:
vercmp_result = 0
if not (npv == 'git' or ppv == 'git'):
vercmp_result = vercmp_string(ppv, npv)
if npv == 'git': if npv == 'git':
logger.debug("%s: Avoiding upgrade to unversioned git." % pn) logger.debug("%s: Avoiding upgrade to unversioned git." % pn)
elif ppv == 'git' or vercmp_string(ppv, npv) == -1: elif ppv == 'git' or vercmp_result != 0:
if initial is True: if initial is True:
logger.debug("%s: Update initial upgrade ( -> %s)." % \ logger.debug("%s: Update initial upgrade ( -> %s)." % \
(pn, pv)) (pn, pv))
@ -191,9 +195,29 @@ def _create_upgrade(recipe_data, layerbranch, ct, title, info, filepath, logger,
latest_upgrade.version = pv latest_upgrade.version = pv
latest_upgrade.save() latest_upgrade.save()
else: else:
logger.debug("%s: detected upgrade (%s -> %s)" \ if len(pn_recipes) > 1:
" in ct %s." % (pn, prev_pv, pv, ct)) # Check if the "new" version is already in the database
_save_upgrade(recipesymbol, layerbranch, pv, ct, title, info, filepath, logger) if RecipeUpgrade.objects.filter(recipesymbol=recipesymbol, version=pv).exists():
for prd in pn_recipes:
if prd.getVar('FILE', True) != recipe_data.getVar('FILE', True):
lpv = prd.getVar('PV', True)
(lpvw, _, _) = get_recipe_pv_without_srcpv(lpv,
get_pv_type(lpv))
if lpvw == ppv:
# The "previous" recipe is still present, we won't call this an upgrade
logger.debug('Multiple %s recipes, ignoring apparent version change' % pn)
return
upgrade_type = 'U'
if vercmp_result == 1:
if len(pn_recipes) > 1:
logger.debug('Multiple %s recipes, ignoring apparent downgrade' % pn)
return
else:
upgrade_type = 'D'
op = {'U': 'upgrade', 'D': 'downgrade'}[upgrade_type]
logger.debug("%s: detected %s (%s -> %s)" \
" in ct %s." % (pn, op, prev_pv, pv, ct))
_save_upgrade(recipesymbol, layerbranch, pv, ct, title, info, filepath, logger, upgrade_type=upgrade_type)
except KeyboardInterrupt: except KeyboardInterrupt:
raise raise
except Exception as e: except Exception as e:
@ -351,9 +375,15 @@ def generate_history(options, layerbranch_id, commit, logger):
recordcommit = commit recordcommit = commit
fn_data = {} fn_data = {}
pn_data = {}
for recipe_data in recipes: for recipe_data in recipes:
fn = os.path.relpath(recipe_data.getVar('FILE', True), repodir) fn = os.path.relpath(recipe_data.getVar('FILE', True), repodir)
fn_data[fn] = recipe_data fn_data[fn] = recipe_data
pn = recipe_data.getVar('PN', True)
if pn in pn_data:
pn_data[pn].append(recipe_data)
else:
pn_data[pn] = [recipe_data]
seen_pns = [] seen_pns = []
try: try:
@ -381,10 +411,11 @@ def generate_history(options, layerbranch_id, commit, logger):
ru.save() ru.save()
for recipe_data in recipes: for recipe_data in recipes:
pn = recipe_data.getVar('PN', True)
filepath = os.path.relpath(recipe_data.getVar('FILE', True), repodir) filepath = os.path.relpath(recipe_data.getVar('FILE', True), repodir)
_create_upgrade(recipe_data, layerbranch, recordcommit, title, _create_upgrade(recipe_data, layerbranch, recordcommit, title,
info, filepath, logger, initial=options.initial) info, filepath, logger, pn_data[pn], initial=options.initial)
seen_pns.append(recipe_data.getVar('PN', True)) seen_pns.append(pn)
for df in deleted: for df in deleted:
rus = RecipeUpgrade.objects.filter(recipesymbol__layerbranch=layerbranch, filepath=df).order_by('-commit_date') rus = RecipeUpgrade.objects.filter(recipesymbol__layerbranch=layerbranch, filepath=df).order_by('-commit_date')

View File

@ -95,7 +95,7 @@
{% for rud in recipe_upgrade_details %} {% for rud in recipe_upgrade_details %}
<tr> <tr>
<td>{{ rud.title }}</td> <td>{{ rud.title }}</td>
<td>{% if rud.upgrade_type != 'R' %}{{ rud.version }}{% endif %}</td> <td>{% if rud.upgrade_type != 'R' %}{{ rud.version }}{% if rud.upgrade_type == 'D' %} <span class="label label-warning">downgrade</span>{% endif %}{% endif %}</td>
{% if rud.milestone_name %} {% if rud.milestone_name %}
<td> <td>
<a href="{% url 'rrs_recipes' rud.maintplan_name rud.release_name rud.milestone_name %}"> <a href="{% url 'rrs_recipes' rud.maintplan_name rud.release_name rud.milestone_name %}">