diff options
-rw-r--r-- | bitbake/lib/toaster/bldcontrol/localhostbecontroller.py | 29 | ||||
-rwxr-xr-x | bitbake/lib/toaster/toastergui/views.py | 90 |
2 files changed, 90 insertions, 29 deletions
diff --git a/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py b/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py index 2dd48d454a..8acf013476 100644 --- a/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py +++ b/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py | |||
@@ -240,23 +240,22 @@ class LocalhostBEController(BuildEnvironmentController): | |||
240 | conf.write('BBPATH .= ":${LAYERDIR}"\nBBFILES += "${LAYERDIR}/recipes/*.bb"\n') | 240 | conf.write('BBPATH .= ":${LAYERDIR}"\nBBFILES += "${LAYERDIR}/recipes/*.bb"\n') |
241 | 241 | ||
242 | # create recipe | 242 | # create recipe |
243 | recipe = os.path.join(layerpath, "recipes", "%s.bb" % target.target) | 243 | recipe_path = \ |
244 | with open(recipe, "w") as recipef: | 244 | os.path.join(layerpath, "recipes", "%s.bb" % target.target) |
245 | recipef.write("require %s\n" % customrecipe.base_recipe.file_path) | 245 | with open(recipe_path, "w") as recipef: |
246 | packages = [pkg.name for pkg in customrecipe.packages.all()] | 246 | recipef.write(customrecipe.generate_recipe_file_contents()) |
247 | if packages: | 247 | |
248 | recipef.write('IMAGE_INSTALL = "%s"\n' % ' '.join(packages)) | 248 | # Update the layer and recipe objects |
249 | customrecipe.layer_version.dirpath = layerpath | ||
250 | customrecipe.layer_version.save() | ||
251 | |||
252 | customrecipe.file_path = recipe_path | ||
253 | customrecipe.save() | ||
249 | 254 | ||
250 | # create *Layer* objects needed for build machinery to work | 255 | # create *Layer* objects needed for build machinery to work |
251 | layer = Layer.objects.get_or_create(name="Toaster Custom layer", | 256 | BRLayer.objects.get_or_create(req=target.req, |
252 | summary="Layer for custom recipes", | 257 | name=layer.name, |
253 | vcs_url="file://%s" % layerpath)[0] | 258 | dirpath=layerpath, |
254 | breq = target.req | ||
255 | lver = Layer_Version.objects.get_or_create(project=breq.project, layer=layer, | ||
256 | dirpath=layerpath, build=breq.build)[0] | ||
257 | ProjectLayer.objects.get_or_create(project=breq.project, layercommit=lver, | ||
258 | optional=False) | ||
259 | BRLayer.objects.get_or_create(req=breq, name=layer.name, dirpath=layerpath, | ||
260 | giturl="file://%s" % layerpath) | 259 | giturl="file://%s" % layerpath) |
261 | if os.path.isdir(layerpath): | 260 | if os.path.isdir(layerpath): |
262 | layerlist.append(layerpath) | 261 | layerlist.append(layerpath) |
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index 995937a077..389457daf3 100755 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py | |||
@@ -2362,10 +2362,37 @@ if True: | |||
2362 | 2362 | ||
2363 | # create custom recipe | 2363 | # create custom recipe |
2364 | try: | 2364 | try: |
2365 | # create layer 'Custom layer' and verion if needed | ||
2366 | layer = Layer.objects.get_or_create(name="toaster-custom-images", | ||
2367 | summary="Layer for custom recipes", | ||
2368 | vcs_url="file:///toaster_created_layer" | ||
2369 | )[0] | ||
2370 | |||
2371 | lver = Layer_Version.objects.get_or_create( | ||
2372 | project=params['project'], | ||
2373 | layer=layer, | ||
2374 | dirpath='toaster_created_layer', | ||
2375 | build=None)[0] | ||
2376 | |||
2377 | # Add a dependency on our layer to the base recipe's layer | ||
2378 | LayerVersionDependency.objects.get_or_create(layer_version=lver, | ||
2379 | depends_on=params["base"].layer_version) | ||
2380 | |||
2381 | # Add it to our current project if needed | ||
2382 | ProjectLayer.objects.get_or_create(project=params['project'], | ||
2383 | layercommit=lver, | ||
2384 | optional=False) | ||
2385 | |||
2386 | # Create the actual recipe | ||
2365 | recipe = CustomImageRecipe.objects.create( | 2387 | recipe = CustomImageRecipe.objects.create( |
2366 | name=request.POST["name"], | 2388 | name=request.POST["name"], |
2367 | base_recipe=params["base"], | 2389 | base_recipe=params["base"], |
2368 | project=params["project"]) | 2390 | project=params["project"], |
2391 | file_path=request.POST["name"], | ||
2392 | license="MIT", | ||
2393 | version="0.1", | ||
2394 | layer_version=lver) | ||
2395 | |||
2369 | except Error as err: | 2396 | except Error as err: |
2370 | return {"error": "Can't create custom recipe: %s" % err} | 2397 | return {"error": "Can't create custom recipe: %s" % err} |
2371 | 2398 | ||
@@ -2378,20 +2405,24 @@ if True: | |||
2378 | # We don't want these packages to be linked to anything because | 2405 | # We don't want these packages to be linked to anything because |
2379 | # that underlying data may change e.g. delete a build | 2406 | # that underlying data may change e.g. delete a build |
2380 | for package in build.package_set.all(): | 2407 | for package in build.package_set.all(): |
2381 | # Create the duplicate | 2408 | _copy_packge_to_recipe(recipe, package) |
2382 | package.pk = None | ||
2383 | package.save() | ||
2384 | # Disassociate the package from the build | ||
2385 | package.build = None | ||
2386 | package.save() | ||
2387 | recipe.packages.add(package) | ||
2388 | else: | 2409 | else: |
2389 | logger.warn("No packages found for this base recipe") | 2410 | logger.debug("No packages found for this base recipe") |
2390 | 2411 | ||
2391 | return {"error": "ok", | 2412 | return {"error": "ok", |
2392 | "url": reverse('customrecipe', args=(params['project'].pk, | 2413 | "url": reverse('customrecipe', args=(params['project'].pk, |
2393 | recipe.id))} | 2414 | recipe.id))} |
2394 | 2415 | ||
2416 | def _copy_packge_to_recipe(recipe, package): | ||
2417 | """ copy a package from another recipe """ | ||
2418 | package.pk = None | ||
2419 | package.save() | ||
2420 | # Disassociate the package from the build | ||
2421 | package.build = None | ||
2422 | package.recipe = recipe | ||
2423 | package.save() | ||
2424 | return package | ||
2425 | |||
2395 | @xhr_response | 2426 | @xhr_response |
2396 | def xhr_customrecipe_id(request, recipe_id): | 2427 | def xhr_customrecipe_id(request, recipe_id): |
2397 | """ | 2428 | """ |
@@ -2454,8 +2485,12 @@ if True: | |||
2454 | "not found" % recipe_id} | 2485 | "not found" % recipe_id} |
2455 | 2486 | ||
2456 | if request.method == 'GET' and not package_id: | 2487 | if request.method == 'GET' and not package_id: |
2488 | packages = recipe.package_set.values("id", "name", "version") | ||
2489 | |||
2457 | return {"error": "ok", | 2490 | return {"error": "ok", |
2458 | "packages": list(recipe.packages.values_list('id'))} | 2491 | "packages" : list(packages), |
2492 | "total" : len(packages) | ||
2493 | } | ||
2459 | 2494 | ||
2460 | try: | 2495 | try: |
2461 | package = Package.objects.get(id=package_id) | 2496 | package = Package.objects.get(id=package_id) |
@@ -2464,11 +2499,38 @@ if True: | |||
2464 | "not found" % package_id} | 2499 | "not found" % package_id} |
2465 | 2500 | ||
2466 | if request.method == 'PUT': | 2501 | if request.method == 'PUT': |
2467 | recipe.packages.add(package) | 2502 | # As these requests are asynchronous we need to make sure we don't |
2468 | return {"error": "ok"} | 2503 | # already have the package in the image recipe |
2504 | if recipe.package_set.filter(Q(name=package.name) & | ||
2505 | Q(version=package.version)).count() > 0: | ||
2506 | return {"error" : "Package %s already in recipe" % | ||
2507 | package.name } | ||
2508 | |||
2509 | # Make a copy of this package | ||
2510 | dependencies = _get_package_dependencies(package.pk) | ||
2511 | |||
2512 | package = _copy_packge_to_recipe(recipe, package) | ||
2513 | recipe.package_set.add(package) | ||
2514 | |||
2515 | # Filter out dependencies already in the custom image | ||
2516 | all_in_image = recipe.package_set.all().values_list('name', | ||
2517 | flat=True) | ||
2518 | def in_image(pkg): | ||
2519 | return pkg['name'] not in all_in_image | ||
2520 | |||
2521 | dependencies = filter(in_image, dependencies['runtime_deps']) | ||
2522 | return {"error": "ok", | ||
2523 | "new_package" : {"id": package.pk, | ||
2524 | "url": reverse('xhr_customrecipe_packages', | ||
2525 | args=(recipe.pk, package.pk)) | ||
2526 | }, | ||
2527 | "dependencies_needed" : dependencies, | ||
2528 | } | ||
2529 | |||
2469 | elif request.method == 'DELETE': | 2530 | elif request.method == 'DELETE': |
2470 | if package in recipe.packages.all(): | 2531 | if package in recipe.package_set.all(): |
2471 | recipe.packages.remove(package) | 2532 | # note that we are infact deleting the copy of the package |
2533 | package.delete() | ||
2472 | return {"error": "ok"} | 2534 | return {"error": "ok"} |
2473 | else: | 2535 | else: |
2474 | return {"error": "Package '%s' is not in the recipe '%s'" % \ | 2536 | return {"error": "Package '%s' is not in the recipe '%s'" % \ |