bitbake: toaster: api Add layer Add api

Add layer adding REST api and remove old views method.

(Bitbake rev: 0c8e41d2217fd568a84e857d1be230fcfd4bb5c7)

Signed-off-by: Michael Wood <michael.g.wood@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Michael Wood 2016-12-09 16:52:45 +00:00 committed by Richard Purdie
parent 90d995c637
commit 7e80e501fb
4 changed files with 103 additions and 121 deletions

View File

@ -20,6 +20,7 @@
import re
import logging
import json
from collections import Counter
from orm.models import Project, ProjectTarget, Build, Layer_Version
@ -136,14 +137,17 @@ class XhrBuildRequest(View):
class XhrLayer(View):
""" Get and Update Layer information """
""" Delete, Get, Add and Update Layer information
Methods: POST DELETE PUT
"""
def post(self, request, *args, **kwargs):
"""
Update a layer
Entry point: /xhr_layer/<layerversion_id>
Method: POST
Entry point: /xhr_layer/<layerversion_id>
Args:
vcs_url, dirpath, commit, up_branch, summary, description,
@ -201,9 +205,100 @@ class XhrLayer(View):
return error_response("Could not update layer version entry: %s"
% e)
return JsonResponse({"error": "ok"})
return error_response("ok")
def put(self, request, *args, **kwargs):
""" Add a new layer
Method: PUT
Entry point: /xhr_layer/
Args:
project_id, name,
[vcs_url, dir_path, git_ref], [local_source_dir], [layer_deps
(csv)]
"""
try:
project = Project.objects.get(pk=kwargs['pid'])
layer_data = json.loads(request.body.decode('utf-8'))
# We require a unique layer name as otherwise the lists of layers
# becomes very confusing
existing_layers = \
project.get_all_compatible_layer_versions().values_list(
"layer__name",
flat=True)
add_to_project = False
layer_deps_added = []
if 'add_to_project' in layer_data:
add_to_project = True
if layer_data['name'] in existing_layers:
return JsonResponse({"error": "layer-name-exists"})
layer = Layer.objects.create(name=layer_data['name'])
layer_version = Layer_Version.objects.create(
layer=layer,
project=project,
layer_source=LayerSource.TYPE_IMPORTED)
# Local layer
if 'local_source_dir' in layer_data:
layer.local_source_dir = layer_data['local_source_dir']
# git layer
elif 'vcs_url' in layer_data:
layer.vcs_url = layer_data['vcs_url']
layer_version.dirpath = layer_data['dir_path']
layer_version.commit = layer_data['get_ref']
layer_version.branch = layer_data['get_ref']
layer.save()
layer_version.save()
if add_to_project:
ProjectLayer.objects.get_or_create(
layercommit=layer_version, project=project)
# Add the layer dependencies
if 'layer_deps' in layer_data:
for layer_dep_id in layer_data['layer_deps'].split(","):
layer_dep = Layer_Version.objects.get(pk=layer_dep_id)
LayerVersionDependency.objects.get_or_create(
layer_version=layer_version, depends_on=layer_dep)
# Add layer deps to the project if specified
if add_to_project:
created, pl = ProjectLayer.objects.get_or_create(
layercommit=layer_dep, project=project)
layer_deps_added.append(
{'name': layer_dep.layer.name,
'layerdetailurl':
layer_dep.get_detailspage_url(project.pk)})
except Layer_Version.DoesNotExist:
return error_response("layer-dep-not-found")
except Project.DoesNotExist:
return error_response("project-not-found")
except KeyError:
return error_response("incorrect-parameters")
return JsonResponse({'error': "ok",
'imported_layer': {
'name': layer.name,
'layerdetailurl':
layer_version.get_detailspage_url()},
'deps_added': layer_deps_added})
def delete(self, request, *args, **kwargs):
""" Delete an imported layer
Method: DELETE
Entry point: /xhr_layer/<layerversion_id>
"""
try:
# We currently only allow Imported layers to be deleted
layer_version = Layer_Version.objects.get(

View File

@ -13,7 +13,7 @@
<script>
$(document).ready(function (){
var ctx = {
xhrImportLayerUrl : "{% url 'xhr_importlayer' %}",
xhrLayerUrl : "{% url 'xhr_layer' project.id %}",
};
try {

View File

@ -190,12 +190,14 @@ urlpatterns = patterns('toastergui.views',
url(r'^xhr_configvaredit/(?P<pid>\d+)$', 'xhr_configvaredit',
name='xhr_configvaredit'),
url(r'^xhr_importlayer/$', 'xhr_importlayer', name='xhr_importlayer'),
url(r'^xhr_layer/(?P<pid>\d+)/(?P<layerversion_id>\d+)$',
api.XhrLayer.as_view(),
name='xhr_layer'),
url(r'^xhr_layer/(?P<pid>\d+)$',
api.XhrLayer.as_view(),
name='xhr_layer'),
# JS Unit tests
url(r'^js-unit-tests/$', 'jsunittests', name='js-unit-tests'),

View File

@ -1509,121 +1509,6 @@ if True:
return HttpResponse(json.dumps({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json")
def xhr_importlayer(request):
if ('vcs_url' not in request.POST or
'name' not in request.POST or
'git_ref' not in request.POST or
'project_id' not in request.POST):
return HttpResponse(jsonfilter({"error": "Missing parameters; requires vcs_url, name, git_ref and project_id"}), content_type = "application/json")
layers_added = [];
# Rudimentary check for any possible html tags
for val in request.POST.values():
if "<" in val:
return HttpResponse(jsonfilter(
{"error": "Invalid character <"}),
content_type="application/json")
prj = Project.objects.get(pk=request.POST['project_id'])
# Strip trailing/leading whitespace from all values
# put into a new dict because POST one is immutable.
post_data = dict()
for key,val in request.POST.items():
post_data[key] = val.strip()
try:
layer, layer_created = Layer.objects.get_or_create(name=post_data['name'])
except MultipleObjectsReturned:
return HttpResponse(jsonfilter({"error": "hint-layer-exists"}), content_type = "application/json")
if layer:
if layer_created:
layer.vcs_url = post_data.get('vcs_url')
layer.local_source_dir = post_data.get('local_source_dir')
layer.up_date = timezone.now()
layer.save()
else:
# We have an existing layer by this name, let's see if the git
# url is the same, if it is then we can just create a new layer
# version for this layer. Otherwise we need to bail out.
if layer.vcs_url != post_data['vcs_url']:
return HttpResponse(jsonfilter({"error": "hint-layer-exists-with-different-url" , "current_url" : layer.vcs_url, "current_id": layer.id }), content_type = "application/json")
layer_version, version_created = \
Layer_Version.objects.get_or_create(
layer_source=LayerSource.TYPE_IMPORTED,
layer=layer, project=prj,
release=prj.release,
branch=post_data['git_ref'],
commit=post_data['git_ref'],
dirpath=post_data['dir_path'])
if layer_version:
if not version_created:
return HttpResponse(jsonfilter({"error":
"hint-layer-version-exists",
"existing_layer_version":
layer_version.id }),
content_type = "application/json")
layer_version.layer_source = LayerSource.TYPE_IMPORTED
layer_version.up_date = timezone.now()
layer_version.save()
# Add the dependencies specified for this new layer
if ('layer_deps' in post_data and
version_created and
len(post_data["layer_deps"]) > 0):
for layer_dep_id in post_data["layer_deps"].split(","):
layer_dep_obj = Layer_Version.objects.get(pk=layer_dep_id)
LayerVersionDependency.objects.get_or_create(layer_version=layer_version, depends_on=layer_dep_obj)
# Now add them to the project, we could get an execption
# if the project now contains the exact
# dependency already (like modified on another page)
try:
prj_layer, prj_layer_created = ProjectLayer.objects.get_or_create(layercommit=layer_dep_obj, project=prj)
except IntegrityError as e:
logger.warning("Integrity error while saving Project Layers: %s (original %s)" % (e, e.__cause__))
continue
if prj_layer_created:
layerdepdetailurl = reverse('layerdetails', args=(prj.id, layer_dep_obj.pk))
layers_added.append({'id': layer_dep_obj.id, 'name': Layer.objects.get(id=layer_dep_obj.layer_id).name, 'layerdetailurl': layerdepdetailurl })
# If an old layer version exists in our project then remove it
for prj_layers in ProjectLayer.objects.filter(project=prj):
dup_layer_v = Layer_Version.objects.filter(id=prj_layers.layercommit_id, layer_id=layer.id)
if len(dup_layer_v) >0 :
prj_layers.delete()
# finally add the imported layer (version id) to the project
ProjectLayer.objects.create(layercommit=layer_version, project=prj,optional=1)
else:
# We didn't create a layer version so back out now and clean up.
if layer_created:
layer.delete()
return HttpResponse(jsonfilter({"error": "Uncaught error: Could not create layer version"}), content_type = "application/json")
layerdetailurl = reverse('layerdetails', args=(prj.id, layer_version.pk))
json_response = {"error": "ok",
"imported_layer" : {
"name" : layer.name,
"id": layer_version.id,
"layerdetailurl": layerdetailurl,
},
"deps_added": layers_added }
return HttpResponse(jsonfilter(json_response), content_type = "application/json")
def customrecipe_download(request, pid, recipe_id):
recipe = get_object_or_404(CustomImageRecipe, pk=recipe_id)