summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/toaster')
-rwxr-xr-xbitbake/lib/toaster/toastergui/views.py140
1 files changed, 98 insertions, 42 deletions
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index c7a782005b..9ad2746881 100755
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -2501,11 +2501,12 @@ if True:
2501 """ 2501 """
2502 ReST API to add/remove packages to/from custom recipe. 2502 ReST API to add/remove packages to/from custom recipe.
2503 2503
2504 Entry point: /xhr_customrecipe/<recipe_id>/packages/ 2504 Entry point: /xhr_customrecipe/<recipe_id>/packages/<package_id>
2505 2505
2506 Methods: 2506 Methods:
2507 PUT - Add package to the recipe 2507 PUT - Add package to the recipe
2508 DELETE - Delete package from the recipe 2508 DELETE - Delete package from the recipe
2509 GET - Get package information
2509 2510
2510 Returns: 2511 Returns:
2511 {"error": "ok"} 2512 {"error": "ok"}
@@ -2518,53 +2519,108 @@ if True:
2518 return {"error": "Custom recipe with id=%s " 2519 return {"error": "Custom recipe with id=%s "
2519 "not found" % recipe_id} 2520 "not found" % recipe_id}
2520 2521
2521 if request.method == 'GET' and not package_id: 2522 if package_id:
2522 packages = recipe.package_set.values("id", "name", "version") 2523 try:
2523 2524 package = CustomImagePackage.objects.get(id=package_id)
2524 return {"error": "ok", 2525 except Package.DoesNotExist:
2525 "packages" : list(packages), 2526 return {"error": "Package with id=%s "
2526 "total" : len(packages) 2527 "not found" % package_id}
2527 }
2528 2528
2529 try: 2529 if request.method == 'GET':
2530 package = Package.objects.get(id=package_id) 2530 if not package_id:
2531 except Package.DoesNotExist: 2531 packages = recipe.get_all_packages().values("id",
2532 return {"error": "Package with id=%s " 2532 "name",
2533 "not found" % package_id} 2533 "version")
2534
2535 return {"error": "ok",
2536 "packages" : list(packages),
2537 "total" : len(packages)
2538 }
2539 else:
2540 all_current_packages = recipe.get_all_packages()
2541
2542 # TODO currently we ignore packgegroups as we don't have a
2543 # way to deal with them yet.
2544
2545 # Dependencies for package which aren't satisfied by the
2546 # current packages in the custom image recipe
2547 deps = package.package_dependencies_source.annotate(
2548 name=F('depends_on__name'),
2549 pk=F('depends_on__pk'),
2550 size=F('depends_on__size'),
2551 ).values("name", "pk", "size").filter(
2552 ~Q(pk__in=all_current_packages) &
2553 Q(dep_type=Package_Dependency.TYPE_TRDEPENDS)
2554 )
2555
2556 # Reverse dependencies which are needed by packages that are
2557 # in the image
2558 reverse_deps = package.package_dependencies_target.annotate(
2559 name=F('package__name'),
2560 pk=F('package__pk'),
2561 size=F('package__size'),
2562 ).values("name", "pk", "size").exclude(
2563 ~Q(pk__in=all_current_packages)
2564 )
2565
2566 total_size_deps = 0
2567 total_size_reverse_deps = 0
2568
2569 for dep in deps:
2570 dep['size_formatted'] = \
2571 filtered_filesizeformat(dep['size'])
2572 total_size_deps += dep['size']
2573
2574 for dep in reverse_deps:
2575 dep['size_formatted'] = \
2576 filtered_filesizeformat(dep['size'])
2577 total_size_reverse_deps += dep['size']
2578
2579
2580 return {"error": "ok",
2581 "id": package.pk,
2582 "name": package.name,
2583 "version": package.version,
2584 "unsatisfied_dependencies": list(deps),
2585 "unsatisfied_dependencies_size": total_size_deps,
2586 "unsatisfied_dependencies_size_formatted":
2587 filtered_filesizeformat(total_size_deps),
2588 "reverse_dependencies": list(reverse_deps),
2589 "reverse_dependencies_size": total_size_reverse_deps,
2590 "reverse_dependencies_size_formatted":
2591 filtered_filesizeformat(total_size_reverse_deps)}
2592
2593 included_packages = recipe.includes_set.values_list('pk', flat=True)
2534 2594
2535 if request.method == 'PUT': 2595 if request.method == 'PUT':
2536 # As these requests are asynchronous we need to make sure we don't 2596 # If we're adding back a package which used to be included in this
2537 # already have the package in the image recipe 2597 # image all we need to do is remove it from the excludes
2538 if recipe.package_set.filter(Q(name=package.name) & 2598 if package.pk in included_packages:
2539 Q(version=package.version)).count() > 0: 2599 try:
2540 return {"error" : "Package %s already in recipe" % 2600 recipe.excludes_set.remove(package)
2541 package.name } 2601 return {"error": "ok"}
2542 2602 except Package.DoesNotExist:
2543 # Make a copy of this package 2603 return {"error":
2544 dependencies = _get_package_dependencies(package.pk) 2604 "Package %s not found in excludes but was in "
2545 2605 "included list" % package.name}
2546 package = _copy_packge_to_recipe(recipe, package) 2606
2547 recipe.package_set.add(package) 2607 else:
2548 2608 recipe.appends_set.add(package)
2549 # Filter out dependencies already in the custom image 2609
2550 all_in_image = recipe.package_set.all().values_list('name', 2610 return {"error": "ok"}
2551 flat=True)
2552 def in_image(pkg):
2553 return pkg['name'] not in all_in_image
2554
2555 dependencies = filter(in_image, dependencies['runtime_deps'])
2556 return {"error": "ok",
2557 "dependencies_needed" : dependencies,
2558 }
2559 2611
2560 elif request.method == 'DELETE': 2612 elif request.method == 'DELETE':
2561 if package in recipe.package_set.all(): 2613 try:
2562 # note that we are infact deleting the copy of the package 2614 # If we're deleting a package which is included we need to
2563 package.delete() 2615 # Add it to the excludes list.
2616 if package.pk in included_packages:
2617 recipe.excludes_set.add(package)
2618 else:
2619 recipe.appends_set.remove(package)
2564 return {"error": "ok"} 2620 return {"error": "ok"}
2565 else: 2621 except CustomImageRecipe.DoesNotExist:
2566 return {"error": "Package '%s' is not in the recipe '%s'" % \ 2622 return {"error": "Tried to remove package that wasn't present"}
2567 (package.name, recipe.name)} 2623
2568 else: 2624 else:
2569 return {"error": "Method %s is not supported" % request.method} 2625 return {"error": "Method %s is not supported" % request.method}
2570 2626