summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Wood <michael.g.wood@intel.com>2016-12-09 16:52:45 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-12-12 20:44:47 +0000
commit0c8e41d2217fd568a84e857d1be230fcfd4bb5c7 (patch)
tree0e8d6441142220ed1487c7fd9e414bd40b711f3e
parent78dc7b9f1801e7f4c266ba1369e5706f177ddaa1 (diff)
downloadbitbake-contrib-0c8e41d2217fd568a84e857d1be230fcfd4bb5c7.tar.gz
toaster: api Add layer Add api
Add layer adding REST api and remove old views method. Signed-off-by: Michael Wood <michael.g.wood@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--lib/toaster/toastergui/api.py101
-rw-r--r--lib/toaster/toastergui/templates/importlayer.html2
-rw-r--r--lib/toaster/toastergui/urls.py6
-rwxr-xr-xlib/toaster/toastergui/views.py115
4 files changed, 103 insertions, 121 deletions
diff --git a/lib/toaster/toastergui/api.py b/lib/toaster/toastergui/api.py
index 4851047bf..5be633ed1 100644
--- a/lib/toaster/toastergui/api.py
+++ b/lib/toaster/toastergui/api.py
@@ -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(
diff --git a/lib/toaster/toastergui/templates/importlayer.html b/lib/toaster/toastergui/templates/importlayer.html
index 1f426969a..bd507b567 100644
--- a/lib/toaster/toastergui/templates/importlayer.html
+++ b/lib/toaster/toastergui/templates/importlayer.html
@@ -13,7 +13,7 @@
<script>
$(document).ready(function (){
var ctx = {
- xhrImportLayerUrl : "{% url 'xhr_importlayer' %}",
+ xhrLayerUrl : "{% url 'xhr_layer' project.id %}",
};
try {
diff --git a/lib/toaster/toastergui/urls.py b/lib/toaster/toastergui/urls.py
index ece9ac169..29f0d96ba 100644
--- a/lib/toaster/toastergui/urls.py
+++ b/lib/toaster/toastergui/urls.py
@@ -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'),
diff --git a/lib/toaster/toastergui/views.py b/lib/toaster/toastergui/views.py
index 2efb0fd56..94b630a8f 100755
--- a/lib/toaster/toastergui/views.py
+++ b/lib/toaster/toastergui/views.py
@@ -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)