To accurately reflect the state of a build request we also need a cancelling state. This is set when we've started a build and then for whatever reason cancel it, cancelling is not instantaneous so we have this state to indicate that a cancel is in progress.
Also add a state transition guard. As the state of a BuildRequest can currently be modified by three processes; Toastergui, Runbuilds/bldcontrol and the buildinofhelper we cannot say for sure which process will be running at the time of cancellation so in order to avoid one of these processes making an incorrect transition only allow transitions of state to increase. e.g. CREATED -> QUEUED -> INPROGRESS And to ignore such requested changes such as INPROGRESS -> CREATED Signed-off-by: Michael Wood <[email protected]> --- .../migrations/0002_add_cancelling_state.py | 19 +++++++++++++++ bitbake/lib/toaster/bldcontrol/models.py | 27 +++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 bitbake/lib/toaster/bldcontrol/migrations/0002_add_cancelling_state.py diff --git a/bitbake/lib/toaster/bldcontrol/migrations/0002_add_cancelling_state.py b/bitbake/lib/toaster/bldcontrol/migrations/0002_add_cancelling_state.py new file mode 100644 index 0000000..efcdf49 --- /dev/null +++ b/bitbake/lib/toaster/bldcontrol/migrations/0002_add_cancelling_state.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bldcontrol', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='buildrequest', + name='state', + field=models.IntegerField(default=0, choices=[(0, b'created'), (1, b'queued'), (2, b'in progress'), (3, b'completed'), (4, b'failed'), (5, b'deleted'), (6, b'cancelling'), (7, b'archive')]), + ), + ] diff --git a/bitbake/lib/toaster/bldcontrol/models.py b/bitbake/lib/toaster/bldcontrol/models.py index a3a49ce..0343ae9 100644 --- a/bitbake/lib/toaster/bldcontrol/models.py +++ b/bitbake/lib/toaster/bldcontrol/models.py @@ -2,6 +2,8 @@ from django.db import models from django.core.validators import MaxValueValidator, MinValueValidator from orm.models import Project, ProjectLayer, ProjectVariable, ProjectTarget, Build, Layer_Version +import logging +logger = logging.getLogger("toaster") # a BuildEnvironment is the equivalent of the "build/" directory on the localhost class BuildEnvironment(models.Model): SERVER_STOPPED = 0 @@ -60,7 +62,8 @@ class BuildRequest(models.Model): REQ_COMPLETED = 3 REQ_FAILED = 4 REQ_DELETED = 5 - REQ_ARCHIVE = 6 + REQ_CANCELLING = 6 + REQ_ARCHIVE = 7 REQUEST_STATE = ( (REQ_CREATED, "created"), @@ -69,6 +72,7 @@ class BuildRequest(models.Model): (REQ_COMPLETED, "completed"), (REQ_FAILED, "failed"), (REQ_DELETED, "deleted"), + (REQ_CANCELLING, "cancelling"), (REQ_ARCHIVE, "archive"), ) @@ -81,6 +85,27 @@ class BuildRequest(models.Model): created = models.DateTimeField(auto_now_add = True) updated = models.DateTimeField(auto_now = True) + def __init__(self, *args, **kwargs): + super(BuildRequest, self).__init__(*args, **kwargs) + # Save the old state incase it's about to be modified + self.old_state = self.state + + def save(self, *args, **kwargs): + # Check that the state we're trying to set is not going backwards + # e.g. from REQ_FAILED to REQ_INPROGRESS + if self.old_state != self.state and self.old_state > self.state: + logger.warn("Invalid state change requested: " + "Cannot go from %s to %s - ignoring request" % + (BuildRequest.REQUEST_STATE[self.old_state][1], + BuildRequest.REQUEST_STATE[self.state][1]) + ) + # Set property back to the old value + self.state = self.old_state + return + + super(BuildRequest, self).save(*args, **kwargs) + + def get_duration(self): return (self.updated - self.created).total_seconds() -- 2.5.0 -- _______________________________________________ toaster mailing list [email protected] https://lists.yoctoproject.org/listinfo/toaster
