summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Kanavin <alex@linutronix.de>2024-07-17 20:22:15 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-07-22 16:53:06 +0100
commit3d98aafc43bf6d14aac997137348fe503efed04e (patch)
tree99c4454f140b999447c3e6325bca7eca5030e346
parentbd18497110796c5d86cef202dc37798478c84cd2 (diff)
downloadpoky-3d98aafc43bf6d14aac997137348fe503efed04e.tar.gz
recipeutils/get_recipe_upgrade_status: group recipes when they need to be upgraded together
This will allow 'lockstep upgrades' of such recipes, improving success rates in automated version updating process. devtool check-upgrade-status now prints: These recipes need to be upgraded together { glib-2.0 2.80.2 2.80.4 Anuj Mittal <anuj.mittal@intel.com> glib-2.0-initial 2.80.2 2.80.4 Anuj Mittal <anuj.mittal@intel.com> } These recipes need to be upgraded together { util-linux 2.39.3 2.40.2 Chen Qi <Qi.Chen@windriver.com> util-linux-libuuid 2.39.3 2.40.2 Chen Qi <Qi.Chen@windriver.com> } These recipes need to be upgraded together { cmake 3.29.3 3.30.0 Unassigned <unassigned@yoctoproject.org> cmake-native 3.29.3 3.30.0 Unassigned <unassigned@yoctoproject.org> } etc. (From OE-Core rev: 7874aea5c62be3e8dbd19e04fce5389c5ed7aab6) Signed-off-by: Alexander Kanavin <alex@linutronix.de> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/lib/oe/recipeutils.py23
-rw-r--r--meta/lib/oeqa/selftest/cases/distrodata.py6
-rw-r--r--scripts/lib/devtool/upgrade.py28
3 files changed, 44 insertions, 13 deletions
diff --git a/meta/lib/oe/recipeutils.py b/meta/lib/oe/recipeutils.py
index 7586332fe0..56be75dc9c 100644
--- a/meta/lib/oe/recipeutils.py
+++ b/meta/lib/oe/recipeutils.py
@@ -1154,6 +1154,7 @@ def get_recipe_upgrade_status(recipes=None):
1154 if not recipes: 1154 if not recipes:
1155 recipes = tinfoil.all_recipe_files(variants=False) 1155 recipes = tinfoil.all_recipe_files(variants=False)
1156 1156
1157 recipeincludes = {}
1157 for fn in recipes: 1158 for fn in recipes:
1158 try: 1159 try:
1159 if fn.startswith("/"): 1160 if fn.startswith("/"):
@@ -1178,11 +1179,13 @@ def get_recipe_upgrade_status(recipes=None):
1178 1179
1179 data_copy_list.append(data_copy) 1180 data_copy_list.append(data_copy)
1180 1181
1182 recipeincludes[data.getVar('FILE')] = {'bbincluded':data.getVar('BBINCLUDED').split(),'pn':data.getVar('PN')}
1183
1181 from concurrent.futures import ProcessPoolExecutor 1184 from concurrent.futures import ProcessPoolExecutor
1182 with ProcessPoolExecutor(max_workers=utils.cpu_count()) as executor: 1185 with ProcessPoolExecutor(max_workers=utils.cpu_count()) as executor:
1183 pkgs_list = executor.map(_get_recipe_upgrade_status, data_copy_list) 1186 pkgs_list = executor.map(_get_recipe_upgrade_status, data_copy_list)
1184 1187
1185 return pkgs_list 1188 return _group_recipes(pkgs_list, _get_common_include_recipes(recipeincludes))
1186 1189
1187def get_common_include_recipes(): 1190def get_common_include_recipes():
1188 with bb.tinfoil.Tinfoil() as tinfoil: 1191 with bb.tinfoil.Tinfoil() as tinfoil:
@@ -1220,3 +1223,21 @@ def _get_common_include_recipes(recipeincludes_all):
1220 recipes_with_shared_includes.append(recipeset) 1223 recipes_with_shared_includes.append(recipeset)
1221 1224
1222 return recipes_with_shared_includes 1225 return recipes_with_shared_includes
1226
1227def _group_recipes(recipes, groups):
1228 recipedict = {}
1229 for r in recipes:
1230 recipedict[r['pn']] = r
1231
1232 recipegroups = []
1233 for g in groups:
1234 recipeset = []
1235 for r in g:
1236 if r in recipedict.keys():
1237 recipeset.append(recipedict[r])
1238 del recipedict[r]
1239 recipegroups.append(recipeset)
1240
1241 for r in recipedict.values():
1242 recipegroups.append([r])
1243 return recipegroups
diff --git a/meta/lib/oeqa/selftest/cases/distrodata.py b/meta/lib/oeqa/selftest/cases/distrodata.py
index bc56160522..bd37552364 100644
--- a/meta/lib/oeqa/selftest/cases/distrodata.py
+++ b/meta/lib/oeqa/selftest/cases/distrodata.py
@@ -20,10 +20,10 @@ class Distrodata(OESelftestTestCase):
20 feature = 'LICENSE_FLAGS_ACCEPTED += " commercial"\n' 20 feature = 'LICENSE_FLAGS_ACCEPTED += " commercial"\n'
21 self.write_config(feature) 21 self.write_config(feature)
22 22
23 pkgs = oe.recipeutils.get_recipe_upgrade_status() 23 pkggroups = oe.recipeutils.get_recipe_upgrade_status()
24 24
25 regressed_failures = [pkg['pn'] for pkg in pkgs if pkg['status'] == 'UNKNOWN_BROKEN'] 25 regressed_failures = [pkg['pn'] for pkgs in pkggroups for pkg in pkgs if pkg['status'] == 'UNKNOWN_BROKEN']
26 regressed_successes = [pkg['pn'] for pkg in pkgs if pkg['status'] == 'KNOWN_BROKEN'] 26 regressed_successes = [pkg['pn'] for pkgs in pkggroups for pkg in pkgs if pkg['status'] == 'KNOWN_BROKEN']
27 msg = "" 27 msg = ""
28 if len(regressed_failures) > 0: 28 if len(regressed_failures) > 0:
29 msg = msg + """ 29 msg = msg + """
diff --git a/scripts/lib/devtool/upgrade.py b/scripts/lib/devtool/upgrade.py
index 10b4f8b5ee..4c268af3a7 100644
--- a/scripts/lib/devtool/upgrade.py
+++ b/scripts/lib/devtool/upgrade.py
@@ -654,18 +654,28 @@ def latest_version(args, config, basepath, workspace):
654 return 0 654 return 0
655 655
656def check_upgrade_status(args, config, basepath, workspace): 656def check_upgrade_status(args, config, basepath, workspace):
657 def _print_status(recipe):
658 print("{:25} {:15} {:15} {} {} {}".format( recipe['pn'],
659 recipe['cur_ver'],
660 recipe['status'] if recipe['status'] != 'UPDATE' else (recipe['next_ver'] if not recipe['next_ver'].endswith("new-commits-available") else "new commits"),
661 recipe['maintainer'],
662 recipe['revision'] if recipe['revision'] != 'N/A' else "",
663 "cannot be updated due to: %s" %(recipe['no_upgrade_reason']) if recipe['no_upgrade_reason'] else ""))
657 if not args.recipe: 664 if not args.recipe:
658 logger.info("Checking the upstream status for all recipes may take a few minutes") 665 logger.info("Checking the upstream status for all recipes may take a few minutes")
659 results = oe.recipeutils.get_recipe_upgrade_status(args.recipe) 666 results = oe.recipeutils.get_recipe_upgrade_status(args.recipe)
660 for result in results: 667 for recipegroup in results:
661 # pn, update_status, current, latest, maintainer, latest_commit, no_update_reason 668 upgrades = [r for r in recipegroup if r['status'] != 'MATCH']
662 if args.all or result['status'] != 'MATCH': 669 currents = [r for r in recipegroup if r['status'] == 'MATCH']
663 print("{:25} {:15} {:15} {} {} {}".format( result['pn'], 670 if len(upgrades) > 1:
664 result['cur_ver'], 671 print("These recipes need to be upgraded together {")
665 result['status'] if result['status'] != 'UPDATE' else (result['next_ver'] if not result['next_ver'].endswith("new-commits-available") else "new commits"), 672 for r in upgrades:
666 result['maintainer'], 673 _print_status(r)
667 result['revision'] if result['revision'] != 'N/A' else "", 674 if len(upgrades) > 1:
668 "cannot be updated due to: %s" %(result['no_upgrade_reason']) if result['no_upgrade_reason'] else "")) 675 print("}")
676 for r in currents:
677 if args.all:
678 _print_status(r)
669 679
670def register_commands(subparsers, context): 680def register_commands(subparsers, context):
671 """Register devtool subcommands from this plugin""" 681 """Register devtool subcommands from this plugin"""