Merge pull request #2127 from charltonaustin/ui_cancel_anytime

Adding in UI for cancel anytime.
This commit is contained in:
Charlton Austin 2016-11-21 11:19:39 -05:00 committed by GitHub
commit ee99929f56
11 changed files with 31 additions and 25 deletions

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="123" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><mask id="a"><rect width="123" height="20" rx="3" fill="#fff"/></mask><g mask="url(#a)"><path fill="#555" d="M0 0h63v20H0z"/><path fill="#9f9f9f" d="M63 0h60v20H63z"/><path fill="url(#b)" d="M0 0h123v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="32.5" y="15" fill="#010101" fill-opacity=".3">container</text><text x="32.5" y="14">container</text><text x="92" y="15" fill="#010101" fill-opacity=".3">cancelled</text><text x="92" y="14">cancelled</text></g></svg>

After

Width:  |  Height:  |  Size: 751 B

View file

@ -128,7 +128,7 @@ class DefaultConfig(object):
# Status tag config
STATUS_TAGS = {}
for tag_name in ['building', 'failed', 'none', 'ready']:
for tag_name in ['building', 'failed', 'none', 'ready', 'cancelled']:
tag_path = os.path.join('buildstatus', tag_name + '.svg')
with open(tag_path) as tag_svg:
STATUS_TAGS[tag_name] = tag_svg.read()

View file

@ -13,6 +13,7 @@ PRESUMED_DEAD_BUILD_AGE = timedelta(days=15)
PHASES_NOT_ALLOWED_TO_CANCEL_FROM = (BUILD_PHASE.PUSHING, BUILD_PHASE.COMPLETE,
BUILD_PHASE.ERROR, BUILD_PHASE.INTERNAL_ERROR)
ARCHIVABLE_BUILD_PHASES = [BUILD_PHASE.COMPLETE, BUILD_PHASE.ERROR, BUILD_PHASE.CANCELLED]
def update_build_trigger(trigger, config, auth_token=None):
trigger.config = json.dumps(config or {})
@ -184,19 +185,11 @@ def create_cancel_build_in_queue(build, build_queue):
def create_cancel_build_in_manager(build, build_canceller):
""" A function to cancel the build before it starts to push """
def cancel_build():
original_phase = build.phase
if build.phase in PHASES_NOT_ALLOWED_TO_CANCEL_FROM:
return False
build.phase = BUILD_PHASE.CANCELLED
build.save()
return build_canceller.try_cancel_build(build.uuid)
if not build_canceller.try_cancel_build(build.uuid):
build.phase = original_phase
build.save()
return False
return True
return cancel_build
@ -213,22 +206,23 @@ def cancel_repository_build(build, build_queue):
cancel_builds = [create_cancel_build_in_queue(build, build_queue),
create_cancel_build_in_manager(build, build_canceller), ]
original_phase = build.phase
for cancelled in cancel_builds:
if cancelled():
# Delete the build row.
# TODO Charlie 2016-11-11 Add in message that says build was cancelled and remove the delete build.
build.delete_instance()
build.phase = BUILD_PHASE.CANCELLED
build.save()
return True
build.phase = original_phase
build.save()
return False
def get_archivable_build():
presumed_dead_date = datetime.utcnow() - PRESUMED_DEAD_BUILD_AGE
candidates = (RepositoryBuild
.select(RepositoryBuild.id)
.where((RepositoryBuild.phase == BUILD_PHASE.COMPLETE) |
(RepositoryBuild.phase == BUILD_PHASE.ERROR) |
.where((RepositoryBuild.phase << ARCHIVABLE_BUILD_PHASES) |
(RepositoryBuild.started < presumed_dead_date),
RepositoryBuild.logs_archived == False)
.limit(50)

View file

@ -318,7 +318,7 @@ class RepositoryBuildResource(RepositoryParamResource):
@require_repo_admin
@nickname('cancelRepoBuild')
def delete(self, namespace, repository, build_uuid):
""" Cancels a repository build if it has not yet been picked up by a build worker. """
""" Cancels a repository build. """
try:
build = model.build.get_repository_build(build_uuid)
except model.build.InvalidRepositoryBuildException:

View file

@ -440,6 +440,8 @@ def build_status_badge(namespace_name, repo_name):
status_name = 'ready'
elif recent_build and recent_build.phase == 'error':
status_name = 'failed'
elif recent_build and recent_build.phase == 'cancelled':
status_name = 'cancelled'
elif recent_build and recent_build.phase != 'complete':
status_name = 'building'
else:

View file

@ -20,4 +20,8 @@
.build-state-icon .complete {
color: #2fcc66;
}
}
.build-state-icon .cancelled {
color: #9b9b9b;
}

View file

@ -5,5 +5,6 @@
<i class="fa fa-times-circle" ng-if="build.phase == 'error'"></i>
<i class="fa fa-exclamation-circle" ng-if="build.phase == 'expired'"></i>
<i class="fa fa-exclamation-circle" ng-if="build.phase == 'internalerror'"></i>
<i class="fa fa-minus-circle" ng-if="build.phase == 'cancelled'"></i>
</span>
</span>

View file

@ -12,10 +12,10 @@ angular.module('quay').directive('buildMiniStatus', function () {
'build': '=build',
'isAdmin': '=isAdmin'
},
controller: function($scope, $element) {
controller: function($scope, $element, BuildService) {
$scope.isBuilding = function(build) {
if (!build) { return true; }
return build.phase != 'complete' && build.phase != 'error';
return BuildService.isActive(build)
};
}
};

View file

@ -2,9 +2,9 @@
* Service which provides helper methods for reasoning about builds.
*/
angular.module('quay').factory('BuildService', [function() {
var buildService = {}
var buildService = {};
buildService.isActive = function(build) {
return build.phase != 'complete' && build.phase != 'error' && build.phase != 'expired';
return build.phase != 'complete' && build.phase != 'error' && build.phase != 'expired' && build.phase != 'cancelled';
};
buildService.getBuildMessage = function(phase) {
@ -51,6 +51,10 @@ angular.module('quay').factory('BuildService', [function() {
case 'internalerror':
return 'An internal system error occurred while building; the build will be retried in the next few minutes.';
case 'cancelled':
return 'This build was previously cancelled.';
}
};

View file

@ -41,8 +41,7 @@
<i class="fa fa-clock-o"></i> Show Timestamps
</span>
</span>
<span class="cor-option" option-click="askCancelBuild(build)"
ng-if="build.phase == 'waiting'">
<span class="cor-option" option-click="askCancelBuild(build)">
<i class="fa fa-times"></i> Cancel Build
</span>
</span>

View file

@ -2191,7 +2191,8 @@ class TestRepositoryBuildResource(ApiTestCase):
json = self.getJsonResponse(RepositoryBuildList,
params=dict(repository=ADMIN_ACCESS_USER + '/simple'))
self.assertEquals(0, len(json['builds']))
self.assertEquals(1, len(json['builds']))
self.assertEquals('cancelled', json['builds'][0]['phase'])
# Check for the build's queue item.
try: