mirror of
https://git.yoctoproject.org/poky
synced 2026-04-03 02:02:21 +02:00
bitbake: toaster: Add new ReST API for Image Customisation feature
Implemented xhr_customrecipe API. To create a custom recipe from a base recipe. Implemented xhr_customrecipe_packages API to add/remove packages to/from custom recipe. co-authored see Signed-off-by (Bitbake rev: 84be400237173970716616eeab6a37d776aa011b) Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com> Signed-off-by: Elliot Smith <elliot.smith@intel.com> Signed-off-by: Michael Wood <michael.g.wood@intel.com> Signed-off-by: brian avery <avery.brian@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
28153acb0a
commit
a3ff4b28ba
@@ -152,6 +152,14 @@ urlpatterns = patterns('toastergui.views',
|
||||
# JS Unit tests
|
||||
url(r'^js-unit-tests/$', 'jsunittests', name='js-unit-tests'),
|
||||
|
||||
# default redirection
|
||||
# image customisation functionality
|
||||
url(r'^xhr_customrecipe/(?P<recipe_id>\d+)/packages/(?P<package_id>\d+|)$',
|
||||
'xhr_customrecipe_packages', name='xhr_customrecipe_packages'),
|
||||
url(r'^xhr_customrecipe/(?P<recipe_id>\d+)$', 'xhr_customrecipe_id',
|
||||
name='xhr_customrecipe_id'),
|
||||
url(r'^xhr_customrecipe/', 'xhr_customrecipe',
|
||||
name='xhr_customrecipe'),
|
||||
|
||||
# default redirection
|
||||
url(r'^$', RedirectView.as_view( url= 'landing')),
|
||||
)
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
import operator,re
|
||||
|
||||
from django.db.models import F, Q, Sum, Count, Max
|
||||
from django.db import IntegrityError
|
||||
from django.db import IntegrityError, Error
|
||||
from django.shortcuts import render, redirect
|
||||
from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe, LogMessage, Variable
|
||||
from orm.models import Task_Dependency, Recipe_Dependency, Package, Package_File, Package_Dependency
|
||||
from orm.models import Target_Installed_Package, Target_File, Target_Image_File, BuildArtifact
|
||||
from orm.models import BitbakeVersion
|
||||
from orm.models import BitbakeVersion, CustomImageRecipe
|
||||
from bldcontrol import bbcontroller
|
||||
from django.views.decorators.cache import cache_control
|
||||
from django.core.urlresolvers import reverse, resolve
|
||||
@@ -2596,7 +2596,155 @@ if True:
|
||||
|
||||
return HttpResponse(jsonfilter({"error": "ok",}), content_type = "application/json")
|
||||
|
||||
@xhr_response
|
||||
def xhr_customrecipe(request):
|
||||
"""
|
||||
Custom image recipe REST API
|
||||
|
||||
Entry point: /xhr_customrecipe/
|
||||
Method: POST
|
||||
|
||||
Args:
|
||||
name: name of custom recipe to create
|
||||
project: target project id of orm.models.Project
|
||||
base: base recipe id of orm.models.Recipe
|
||||
|
||||
Returns:
|
||||
{"error": "ok",
|
||||
"url": <url of the created recipe>}
|
||||
or
|
||||
{"error": <error message>}
|
||||
"""
|
||||
# check if request has all required parameters
|
||||
for param in ('name', 'project', 'base'):
|
||||
if param not in request.POST:
|
||||
return {"error": "Missing parameter '%s'" % param}
|
||||
|
||||
# get project and baserecipe objects
|
||||
params = {}
|
||||
for name, model in [("project", Project),
|
||||
("base", Recipe)]:
|
||||
value = request.POST[name]
|
||||
try:
|
||||
params[name] = model.objects.get(id=value)
|
||||
except model.DoesNotExist:
|
||||
return {"error": "Invalid %s id %s" % (name, value)}
|
||||
|
||||
# create custom recipe
|
||||
try:
|
||||
recipe = CustomImageRecipe.objects.create(
|
||||
name=request.POST["name"],
|
||||
base_recipe=params["base"],
|
||||
project=params["project"])
|
||||
except Error as err:
|
||||
return {"error": "Can't create custom recipe: %s" % err}
|
||||
|
||||
# Find the package list from the last build of this recipe/target
|
||||
build = Build.objects.filter(target__target=params['base'].name,
|
||||
project=params['project']).last()
|
||||
|
||||
if build:
|
||||
# Copy in every package
|
||||
# We don't want these packages to be linked to anything because
|
||||
# that underlying data may change e.g. delete a build
|
||||
for package in build.package_set.all():
|
||||
# Create the duplicate
|
||||
package.pk = None
|
||||
package.save()
|
||||
# Disassociate the package from the build
|
||||
package.build = None
|
||||
package.save()
|
||||
recipe.packages.add(package)
|
||||
else:
|
||||
logger.warn("No packages found for this base recipe")
|
||||
|
||||
return {"error": "ok",
|
||||
"url": reverse('customrecipe', args=(params['project'].pk,
|
||||
recipe.id))}
|
||||
|
||||
@xhr_response
|
||||
def xhr_customrecipe_id(request, recipe_id):
|
||||
"""
|
||||
Set of ReST API processors working with recipe id.
|
||||
|
||||
Entry point: /xhr_customrecipe/<recipe_id>
|
||||
|
||||
Methods:
|
||||
GET - Get details of custom image recipe
|
||||
DELETE - Delete custom image recipe
|
||||
|
||||
Returns:
|
||||
GET:
|
||||
{"error": "ok",
|
||||
"info": dictionary of field name -> value pairs
|
||||
of the CustomImageRecipe model}
|
||||
DELETE:
|
||||
{"error": "ok"}
|
||||
or
|
||||
{"error": <error message>}
|
||||
"""
|
||||
objects = CustomImageRecipe.objects.filter(id=recipe_id)
|
||||
if not objects:
|
||||
return {"error": "Custom recipe with id=%s "
|
||||
"not found" % recipe_id}
|
||||
if request.method == 'GET':
|
||||
values = CustomImageRecipe.objects.filter(id=recipe_id).values()
|
||||
if values:
|
||||
return {"error": "ok", "info": values[0]}
|
||||
else:
|
||||
return {"error": "Custom recipe with id=%s "
|
||||
"not found" % recipe_id}
|
||||
return {"error": "ok", "info": objects.values()[0]}
|
||||
elif request.method == 'DELETE':
|
||||
objects.delete()
|
||||
return {"error": "ok"}
|
||||
else:
|
||||
return {"error": "Method %s is not supported" % request.method}
|
||||
|
||||
@xhr_response
|
||||
def xhr_customrecipe_packages(request, recipe_id, package_id):
|
||||
"""
|
||||
ReST API to add/remove packages to/from custom recipe.
|
||||
|
||||
Entry point: /xhr_customrecipe/<recipe_id>/packages/
|
||||
|
||||
Methods:
|
||||
PUT - Add package to the recipe
|
||||
DELETE - Delete package from the recipe
|
||||
|
||||
Returns:
|
||||
{"error": "ok"}
|
||||
or
|
||||
{"error": <error message>}
|
||||
"""
|
||||
try:
|
||||
recipe = CustomImageRecipe.objects.get(id=recipe_id)
|
||||
except CustomImageRecipe.DoesNotExist:
|
||||
return {"error": "Custom recipe with id=%s "
|
||||
"not found" % recipe_id}
|
||||
|
||||
if request.method == 'GET' and not package_id:
|
||||
return {"error": "ok",
|
||||
"packages": list(recipe.packages.values_list('id'))}
|
||||
|
||||
try:
|
||||
package = Package.objects.get(id=package_id)
|
||||
except Package.DoesNotExist:
|
||||
return {"error": "Package with id=%s "
|
||||
"not found" % package_id}
|
||||
|
||||
if request.method == 'PUT':
|
||||
recipe.packages.add(package)
|
||||
return {"error": "ok"}
|
||||
elif request.method == 'DELETE':
|
||||
if package in recipe.packages.all():
|
||||
recipe.packages.remove(package)
|
||||
return {"error": "ok"}
|
||||
else:
|
||||
return {"error": "Package '%s' is not in the recipe '%s'" % \
|
||||
(package.name, recipe.name)}
|
||||
else:
|
||||
return {"error": "Method %s is not supported" % request.method}
|
||||
|
||||
def importlayer(request, pid):
|
||||
template = "importlayer.html"
|
||||
|
||||
Reference in New Issue
Block a user