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):
search_fields = ['recipesymbol__pn']
list_filter = ['recipesymbol__layerbranch__layer__name',
('commit_date', DateFieldListFilter), 'maintainer__name']
'upgrade_type', ('commit_date', DateFieldListFilter),
'maintainer__name']
model = RecipeUpgrade
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):
UPGRADE_TYPE_CHOICES = (
('U', 'Upgrade'),
('D', 'Downgrade'),
('N', 'Delete'),
('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.
"""
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 bb.utils import vercmp_string
@ -181,9 +181,13 @@ def _create_upgrade(recipe_data, layerbranch, ct, title, info, filepath, logger,
get_pv_type(pv))
try:
vercmp_result = 0
if not (npv == 'git' or ppv == 'git'):
vercmp_result = vercmp_string(ppv, npv)
if npv == 'git':
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:
logger.debug("%s: Update initial upgrade ( -> %s)." % \
(pn, pv))
@ -191,9 +195,29 @@ def _create_upgrade(recipe_data, layerbranch, ct, title, info, filepath, logger,
latest_upgrade.version = pv
latest_upgrade.save()
else:
logger.debug("%s: detected upgrade (%s -> %s)" \
" in ct %s." % (pn, prev_pv, pv, ct))
_save_upgrade(recipesymbol, layerbranch, pv, ct, title, info, filepath, logger)
if len(pn_recipes) > 1:
# Check if the "new" version is already in the database
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:
raise
except Exception as e:
@ -351,9 +375,15 @@ def generate_history(options, layerbranch_id, commit, logger):
recordcommit = commit
fn_data = {}
pn_data = {}
for recipe_data in recipes:
fn = os.path.relpath(recipe_data.getVar('FILE', True), repodir)
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 = []
try:
@ -381,10 +411,11 @@ def generate_history(options, layerbranch_id, commit, logger):
ru.save()
for recipe_data in recipes:
pn = recipe_data.getVar('PN', True)
filepath = os.path.relpath(recipe_data.getVar('FILE', True), repodir)
_create_upgrade(recipe_data, layerbranch, recordcommit, title,
info, filepath, logger, initial=options.initial)
seen_pns.append(recipe_data.getVar('PN', True))
info, filepath, logger, pn_data[pn], initial=options.initial)
seen_pns.append(pn)
for df in deleted:
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 %}
<tr>
<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 %}
<td>
<a href="{% url 'rrs_recipes' rud.maintplan_name rud.release_name rud.milestone_name %}">