* [PATCH 1/6] toaster: api / project Cancel any in progress builds before project delete
2016-10-06 0:08 [PATCH 0/6] toaster: Delete project fixes and clean ups bavery
@ 2016-10-06 0:08 ` bavery
2016-10-06 0:08 ` [PATCH 2/6] toaster: buildinfohelper: Use correct way to get message from LogMessage bavery
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: bavery @ 2016-10-06 0:08 UTC (permalink / raw)
To: bitbake-devel; +Cc: bavery
From: Michael Wood <michael.g.wood@intel.com>
Before we finally delete any project make sure we send the cancel command to
any in-progress builds. This ensures that an inaccessible build doesn't block
up the system and that we don't get errors after deletion.
[YOCTO #10289]
Signed-off-by: Michael Wood <michael.g.wood@intel.com>
Signed-off-by: bavery <brian.avery@intel.com>
---
lib/toaster/toastergui/api.py | 55 +++++++++++++++++----------
lib/toaster/toastergui/templates/project.html | 12 +++---
2 files changed, 41 insertions(+), 26 deletions(-)
diff --git a/lib/toaster/toastergui/api.py b/lib/toaster/toastergui/api.py
index 3a05d66..b01d4ba 100644
--- a/lib/toaster/toastergui/api.py
+++ b/lib/toaster/toastergui/api.py
@@ -49,6 +49,28 @@ class XhrBuildRequest(View):
def get(self, request, *args, **kwargs):
return HttpResponse()
+ @staticmethod
+ def cancel_build(br):
+ """Cancel a build request"""
+ try:
+ bbctrl = bbcontroller.BitbakeController(br.environment)
+ bbctrl.forceShutDown()
+ except:
+ # We catch a bunch of exceptions here because
+ # this is where the server has not had time to start up
+ # and the build request or build is in transit between
+ # processes.
+ # We can safely just set the build as cancelled
+ # already as it never got started
+ build = br.build
+ build.outcome = Build.CANCELLED
+ build.save()
+
+ # We now hand over to the buildinfohelper to update the
+ # build state once we've finished cancelling
+ br.state = BuildRequest.REQ_CANCELLING
+ br.save()
+
def post(self, request, *args, **kwargs):
"""
Build control
@@ -74,26 +96,7 @@ class XhrBuildRequest(View):
for i in request.POST['buildCancel'].strip().split(" "):
try:
br = BuildRequest.objects.get(project=project, pk=i)
-
- try:
- bbctrl = bbcontroller.BitbakeController(br.environment)
- bbctrl.forceShutDown()
- except:
- # We catch a bunch of exceptions here because
- # this is where the server has not had time to start up
- # and the build request or build is in transit between
- # processes.
- # We can safely just set the build as cancelled
- # already as it never got started
- build = br.build
- build.outcome = Build.CANCELLED
- build.save()
-
- # We now hand over to the buildinfohelper to update the
- # build state once we've finished cancelling
- br.state = BuildRequest.REQ_CANCELLING
- br.save()
-
+ self.cancel_build(br)
except BuildRequest.DoesNotExist:
return error_response('No such build request id %s' % i)
@@ -823,11 +826,21 @@ class XhrProject(View):
return HttpResponse()
def delete(self, request, *args, **kwargs):
+ """Delete a project. Cancels any builds in progress"""
try:
- Project.objects.get(pk=kwargs['project_id']).delete()
+ project = Project.objects.get(pk=kwargs['project_id'])
+ # Cancel any builds in progress
+ for br in BuildRequest.objects.filter(
+ project=project,
+ state=BuildRequest.REQ_INPROGRESS):
+ XhrBuildRequest.cancel_build(br)
+
+ project.delete()
+
except Project.DoesNotExist:
return error_response("Project %s does not exist" %
kwargs['project_id'])
+
return JsonResponse({
"error": "ok",
"gotoUrl": reverse("all-projects", args=[])
diff --git a/lib/toaster/toastergui/templates/project.html b/lib/toaster/toastergui/templates/project.html
index 7644dad..5abe241 100644
--- a/lib/toaster/toastergui/templates/project.html
+++ b/lib/toaster/toastergui/templates/project.html
@@ -31,12 +31,14 @@
<h4>Are you sure you want to delete this project?</h4>
</div>
<div class="modal-body">
- <p>Deleting the <strong class="project-name"></strong> project will remove forever:</p>
+ <p>Deleting the <strong class="project-name"></strong> project
+ will:</p>
<ul>
- <li>Its configuration information</li>
- <li>Its imported layers</li>
- <li>Its custom images</li>
- <li>All its build information</li>
+ <li>Cancel its builds currently in progress</li>
+ <li>Remove its configuration information</li>
+ <li>Remove its imported layers</li>
+ <li>Remove its custom images</li>
+ <li>Remove all its build information</li>
</ul>
</div>
<div class="modal-footer">
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 2/6] toaster: buildinfohelper: Use correct way to get message from LogMessage
2016-10-06 0:08 [PATCH 0/6] toaster: Delete project fixes and clean ups bavery
2016-10-06 0:08 ` [PATCH 1/6] toaster: api / project Cancel any in progress builds before project delete bavery
@ 2016-10-06 0:08 ` bavery
2016-10-06 0:08 ` [PATCH 3/6] toaster: checksettings Remove confusing startup messages bavery
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: bavery @ 2016-10-06 0:08 UTC (permalink / raw)
To: bitbake-devel; +Cc: bavery
From: Michael Wood <michael.g.wood@intel.com>
Use the correct method to get a message value from the LogMessage object
rather than constructing it ourselves which is not recommended. This
causes an exception when the msg contains a '%' such as when there are
wildcards in file names (something2.%.bbappends)
Signed-off-by: Michael Wood <michael.g.wood@intel.com>
Signed-off-by: bavery <brian.avery@intel.com>
---
lib/bb/ui/buildinfohelper.py | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/lib/bb/ui/buildinfohelper.py b/lib/bb/ui/buildinfohelper.py
index 970a941..5b69660 100644
--- a/lib/bb/ui/buildinfohelper.py
+++ b/lib/bb/ui/buildinfohelper.py
@@ -1565,16 +1565,12 @@ class BuildInfoHelper(object):
mockevent.lineno = -1
self.store_log_event(mockevent)
-
def store_log_event(self, event):
self._ensure_build()
if event.levelno < formatter.WARNING:
return
- if 'args' in vars(event):
- event.msg = event.msg % event.args
-
# early return for CLI builds
if self.brbe is None:
if not 'backlog' in self.internal_state:
@@ -1586,7 +1582,8 @@ class BuildInfoHelper(object):
# if we have a backlog of events, do our best to save them here
if len(self.internal_state['backlog']):
tempevent = self.internal_state['backlog'].pop()
- logger.debug(1, "buildinfohelper: Saving stored event %s " % tempevent)
+ logger.debug(1, "buildinfohelper: Saving stored event %s "
+ % tempevent)
self.store_log_event(tempevent)
else:
logger.info("buildinfohelper: All events saved")
@@ -1605,7 +1602,7 @@ class BuildInfoHelper(object):
else:
log_information['level'] = LogMessage.INFO
- log_information['message'] = event.msg
+ log_information['message'] = event.getMessage()
log_information['pathname'] = event.pathname
log_information['lineno'] = event.lineno
logger.info("Logging error 2: %s", log_information)
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 3/6] toaster: checksettings Remove confusing startup messages
2016-10-06 0:08 [PATCH 0/6] toaster: Delete project fixes and clean ups bavery
2016-10-06 0:08 ` [PATCH 1/6] toaster: api / project Cancel any in progress builds before project delete bavery
2016-10-06 0:08 ` [PATCH 2/6] toaster: buildinfohelper: Use correct way to get message from LogMessage bavery
@ 2016-10-06 0:08 ` bavery
2016-10-06 0:08 ` [PATCH 4/6] toaster: importlayer Fix layer dependencies button state toggle bavery
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: bavery @ 2016-10-06 0:08 UTC (permalink / raw)
To: bitbake-devel; +Cc: bavery
From: Michael Wood <michael.g.wood@intel.com>
These "validation" messages are shown regardless as to whether the
settings are being correctly set or not.
For the time being remove them.
[YOCTO #9097]
Signed-off-by: Michael Wood <michael.g.wood@intel.com>
Signed-off-by: bavery <brian.avery@intel.com>
---
lib/toaster/bldcontrol/management/commands/checksettings.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/lib/toaster/bldcontrol/management/commands/checksettings.py b/lib/toaster/bldcontrol/management/commands/checksettings.py
index 28b9945..2ed994f 100644
--- a/lib/toaster/bldcontrol/management/commands/checksettings.py
+++ b/lib/toaster/bldcontrol/management/commands/checksettings.py
@@ -42,7 +42,6 @@ class Command(NoArgsCommand):
return True
if len(be.sourcedir) == 0:
- print("\n -- Validation: The layers checkout directory must be set.")
is_changed = _update_sourcedir()
if not be.sourcedir.startswith("/"):
@@ -59,7 +58,6 @@ class Command(NoArgsCommand):
return True
if len(be.builddir) == 0:
- print("\n -- Validation: The build directory must be set.")
is_changed = _update_builddir()
if not be.builddir.startswith("/"):
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 4/6] toaster: importlayer Fix layer dependencies button state toggle
2016-10-06 0:08 [PATCH 0/6] toaster: Delete project fixes and clean ups bavery
` (2 preceding siblings ...)
2016-10-06 0:08 ` [PATCH 3/6] toaster: checksettings Remove confusing startup messages bavery
@ 2016-10-06 0:08 ` bavery
2016-10-06 0:08 ` [PATCH 5/6] toaster: Delete notification update front end implementation to design bavery
2016-10-06 0:08 ` [PATCH 6/6] toaster: Update tests to reflect front end changes bavery
5 siblings, 0 replies; 7+ messages in thread
From: bavery @ 2016-10-06 0:08 UTC (permalink / raw)
To: bitbake-devel; +Cc: bavery
From: Michael Wood <michael.g.wood@intel.com>
Fix regression introduced by switching typeahead library. Make sure we
enable and disable the add button based on whether the selection event
has fired or not.
[YOCTO #9936]
Signed-off-by: Michael Wood <michael.g.wood@intel.com>
Signed-off-by: bavery <brian.avery@intel.com>
---
lib/toaster/toastergui/static/js/importlayer.js | 30 +++++--------------------
1 file changed, 5 insertions(+), 25 deletions(-)
diff --git a/lib/toaster/toastergui/static/js/importlayer.js b/lib/toaster/toastergui/static/js/importlayer.js
index 570ca33..30dc282 100644
--- a/lib/toaster/toastergui/static/js/importlayer.js
+++ b/lib/toaster/toastergui/static/js/importlayer.js
@@ -21,21 +21,11 @@ function importLayerPageInit (ctx) {
libtoaster.ctx.layersTypeAheadUrl,
{ include_added: "true" }, function(item){
currentLayerDepSelection = item;
+ layerDepBtn.removeAttr("disabled");
});
- // choices available in the typeahead
- var layerDepsChoices = {};
-
- // when the typeahead choices change, store an array of the available layer
- // choices locally, to use for enabling/disabling the "Add layer" button
- layerDepInput.on("typeahead-choices-change", function (event, data) {
- layerDepsChoices = {};
-
- if (data.choices) {
- data.choices.forEach(function (item) {
- layerDepsChoices[item.name] = item;
- });
- }
+ layerDepInput.on("typeahead:select", function(event, data){
+ currentLayerDepSelection = data;
});
// Disable local dir repo when page is loaded.
@@ -43,18 +33,8 @@ function importLayerPageInit (ctx) {
// disable the "Add layer" button when the layer input typeahead is empty
// or not in the typeahead choices
- layerDepInput.on("input change", function () {
- // get the choices from the typeahead
- var choice = layerDepsChoices[$(this).val()];
-
- if (choice) {
- layerDepBtn.removeAttr("disabled");
- currentLayerDepSelection = choice;
- }
- else {
- layerDepBtn.attr("disabled","disabled");
- currentLayerDepSelection = undefined;
- }
+ layerDepInput.on("input change", function(){
+ layerDepBtn.attr("disabled","disabled");
});
/* We automatically add "openembedded-core" layer for convenience as a
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 5/6] toaster: Delete notification update front end implementation to design
2016-10-06 0:08 [PATCH 0/6] toaster: Delete project fixes and clean ups bavery
` (3 preceding siblings ...)
2016-10-06 0:08 ` [PATCH 4/6] toaster: importlayer Fix layer dependencies button state toggle bavery
@ 2016-10-06 0:08 ` bavery
2016-10-06 0:08 ` [PATCH 6/6] toaster: Update tests to reflect front end changes bavery
5 siblings, 0 replies; 7+ messages in thread
From: bavery @ 2016-10-06 0:08 UTC (permalink / raw)
To: bitbake-devel; +Cc: bavery
From: Michael Wood <michael.g.wood@intel.com>
Update the delete notifications to reflect feedback from design
review comments.
Signed-off-by: Michael Wood <michael.g.wood@intel.com>
Signed-off-by: bavery <brian.avery@intel.com>
---
lib/toaster/toastergui/api.py | 2 +-
lib/toaster/toastergui/static/js/layerdetails.js | 2 ++
lib/toaster/toastergui/static/js/libtoaster.js | 2 +-
lib/toaster/toastergui/templates/base.html | 2 +-
lib/toaster/toastergui/templates/basebuildpage.html | 6 +++++-
5 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/lib/toaster/toastergui/api.py b/lib/toaster/toastergui/api.py
index b01d4ba..ae1f150 100644
--- a/lib/toaster/toastergui/api.py
+++ b/lib/toaster/toastergui/api.py
@@ -224,7 +224,7 @@ class XhrLayer(View):
return JsonResponse({
"error": "ok",
- "gotoUrl": reverse('project', args=(kwargs['pid'],))
+ "gotoUrl": reverse('projectlayers', args=(kwargs['pid'],))
})
diff --git a/lib/toaster/toastergui/static/js/layerdetails.js b/lib/toaster/toastergui/static/js/layerdetails.js
index 4c0d042..9ead393 100644
--- a/lib/toaster/toastergui/static/js/layerdetails.js
+++ b/lib/toaster/toastergui/static/js/layerdetails.js
@@ -392,6 +392,8 @@ function layerDetailsPageInit (ctx) {
$("#layer-delete-confirmed").click(function(){
+ $("#delete-layer-modal button[data-dismiss='modal']").hide();
+
var message = $('<span>You have deleted <strong>1</strong> layer from your project: <strong id="deleted-layer-name"></strong>');
message.find("#deleted-layer-name").text(ctx.layerVersion.name);
diff --git a/lib/toaster/toastergui/static/js/libtoaster.js b/lib/toaster/toastergui/static/js/libtoaster.js
index 0832ba4..86662b7 100644
--- a/lib/toaster/toastergui/static/js/libtoaster.js
+++ b/lib/toaster/toastergui/static/js/libtoaster.js
@@ -342,7 +342,7 @@ var libtoaster = (function () {
}
function _showChangeNotification(message){
- $(".alert").fadeOut().promise().done(function(){
+ $(".alert-dismissible").fadeOut().promise().done(function(){
var alertMsg = $("#change-notification-msg");
alertMsg.html(message);
diff --git a/lib/toaster/toastergui/templates/base.html b/lib/toaster/toastergui/templates/base.html
index c1b1417..496dd6e 100644
--- a/lib/toaster/toastergui/templates/base.html
+++ b/lib/toaster/toastergui/templates/base.html
@@ -74,7 +74,7 @@
</div>
<div id="change-notification" class="alert alert-info alert-dismissible change-notification" style="display:none">
- <button type="button" class="close" id="hide-alert" data-dismiss="alert">×</button>
+ <button type="button" class="close" id="hide-alert" data-toggle="alert">×</button>
<span id="change-notification-msg"></span>
</div>
diff --git a/lib/toaster/toastergui/templates/basebuildpage.html b/lib/toaster/toastergui/templates/basebuildpage.html
index 0b6ef56..f5eee96 100644
--- a/lib/toaster/toastergui/templates/basebuildpage.html
+++ b/lib/toaster/toastergui/templates/basebuildpage.html
@@ -28,6 +28,8 @@
if (data.error !== "ok") {
console.warn(data.error);
} else {
+ libtoaster.setNotification("build-deleted",
+ $("#deleted-build-message").html());
window.location.replace(data.gotoUrl);
}
},
@@ -61,7 +63,9 @@
});
</script>
-
+<span style="display:none" id="deleted-build-message">
+ You have deleted 1 build: <strong>{{build.get_sorted_target_list|field_values:"target"|join:", "}} {{build.machine}}</strong> completed on <strong>{{build.completed_on|date:"d/m/y H:i"}}</strong>
+</span>
<div class="modal fade" tabindex="-1" role="dialog" id="delete-build-modal" style="display: none;" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog">
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 6/6] toaster: Update tests to reflect front end changes
2016-10-06 0:08 [PATCH 0/6] toaster: Delete project fixes and clean ups bavery
` (4 preceding siblings ...)
2016-10-06 0:08 ` [PATCH 5/6] toaster: Delete notification update front end implementation to design bavery
@ 2016-10-06 0:08 ` bavery
5 siblings, 0 replies; 7+ messages in thread
From: bavery @ 2016-10-06 0:08 UTC (permalink / raw)
To: bitbake-devel; +Cc: bavery
From: Michael Wood <michael.g.wood@intel.com>
- Browser test we changed the project heading access to use the class name
- Update toastergui unit test for additional gotoUrl property
- On faster browsers we had a race for layer details inputs being
visible
Signed-off-by: Michael Wood <michael.g.wood@intel.com>
Signed-off-by: bavery <brian.avery@intel.com>
---
lib/toaster/tests/browser/test_layerdetails_page.py | 4 ++++
lib/toaster/tests/browser/test_project_page.py | 2 +-
lib/toaster/toastergui/tests.py | 8 +++++++-
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/lib/toaster/tests/browser/test_layerdetails_page.py b/lib/toaster/tests/browser/test_layerdetails_page.py
index 72b6f60..6392d1e 100644
--- a/lib/toaster/tests/browser/test_layerdetails_page.py
+++ b/lib/toaster/tests/browser/test_layerdetails_page.py
@@ -91,6 +91,10 @@ class TestLayerDetailsPage(SeleniumTestCase):
for btn in self.find_all("dd .glyphicon-edit"):
btn.click()
+ # Wait for the inputs to become visible
+ self.wait_until_visible("#layer-git input[type=text]")
+ self.wait_until_visible("dd textarea")
+
# Edit each value
for inputs in self.find_all("#layer-git input[type=text]") + \
self.find_all("dd textarea"):
diff --git a/lib/toaster/tests/browser/test_project_page.py b/lib/toaster/tests/browser/test_project_page.py
index 786bef1..0186463 100644
--- a/lib/toaster/tests/browser/test_project_page.py
+++ b/lib/toaster/tests/browser/test_project_page.py
@@ -55,5 +55,5 @@ class TestProjectPage(SeleniumTestCase):
self.get(url)
# check that we get a project page with the correct heading
- project_name = self.find('#project-name').text.strip()
+ project_name = self.find('.project-name').text.strip()
self.assertEqual(project_name, self.CLI_BUILDS_PROJECT_NAME)
diff --git a/lib/toaster/toastergui/tests.py b/lib/toaster/toastergui/tests.py
index 0508611..2b5894f 100644
--- a/lib/toaster/toastergui/tests.py
+++ b/lib/toaster/toastergui/tests.py
@@ -248,7 +248,13 @@ class ViewTests(TestCase):
url = reverse('xhr_customrecipe_id', args=(recipe.id,))
response = self.client.delete(url)
self.assertEqual(response.status_code, 200)
- self.assertEqual(json.loads(response.content.decode('utf-8')), {"error": "ok"})
+
+ gotoUrl = reverse('projectcustomimages', args=(self.project.pk,))
+
+ self.assertEqual(json.loads(response.content.decode('utf-8')),
+ {"error": "ok",
+ "gotoUrl": gotoUrl})
+
# try to delete not-existent recipe
url = reverse('xhr_customrecipe_id', args=(recipe.id,))
response = self.client.delete(url)
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread