From 1ad65ecea11522c880b4012733b6538177c3c94d Mon Sep 17 00:00:00 2001 From: Martin Pokorny <89339813+mPokornyETM@users.noreply.github.com> Date: Sat, 25 Nov 2023 00:05:00 +0100 Subject: [PATCH] Show used resources in build page (#583) --- .../lockableresources/LockStepExecution.java | 9 +- .../actions/LockedResourcesBuildAction.java | 86 ++++++++++++++++- .../lockableresources/Messages.properties | 1 + .../LockedResourcesBuildAction/index.jelly | 95 ++++++++++++++----- .../index.properties | 11 ++- 5 files changed, 170 insertions(+), 32 deletions(-) diff --git a/src/main/java/org/jenkins/plugins/lockableresources/LockStepExecution.java b/src/main/java/org/jenkins/plugins/lockableresources/LockStepExecution.java index e34acfb09..ca45db46a 100644 --- a/src/main/java/org/jenkins/plugins/lockableresources/LockStepExecution.java +++ b/src/main/java/org/jenkins/plugins/lockableresources/LockStepExecution.java @@ -16,6 +16,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import org.jenkins.plugins.lockableresources.actions.LockedResourcesBuildAction; import org.jenkins.plugins.lockableresources.queue.LockableResourcesStruct; import org.jenkinsci.plugins.workflow.graph.FlowNode; import org.jenkinsci.plugins.workflow.steps.AbstractStepExecutionImpl; @@ -110,10 +111,10 @@ public static void proceed( String resourceDescription, final String variable, boolean inversePrecedence) { - Run r; + Run build; FlowNode node; try { - r = context.get(Run.class); + build = context.get(Run.class); node = context.get(FlowNode.class); context.get(TaskListener.class).getLogger().println("Lock acquired on [" + resourceDescription + "]"); } catch (Exception e) { @@ -121,8 +122,10 @@ public static void proceed( return; } - LOGGER.finest("Lock acquired on [" + resourceDescription + "] by " + r.getExternalizableId()); + LOGGER.finest("Lock acquired on [" + resourceDescription + "] by " + build.getExternalizableId()); try { + + LockedResourcesBuildAction.updateAction(build, new ArrayList<>(lockedResources.keySet())); PauseAction.endCurrentPause(node); BodyInvoker bodyInvoker = context.newBodyInvoker() .withCallback(new Callback( diff --git a/src/main/java/org/jenkins/plugins/lockableresources/actions/LockedResourcesBuildAction.java b/src/main/java/org/jenkins/plugins/lockableresources/actions/LockedResourcesBuildAction.java index 47581c371..477b7e8cc 100644 --- a/src/main/java/org/jenkins/plugins/lockableresources/actions/LockedResourcesBuildAction.java +++ b/src/main/java/org/jenkins/plugins/lockableresources/actions/LockedResourcesBuildAction.java @@ -9,65 +9,145 @@ package org.jenkins.plugins.lockableresources.actions; import hudson.model.Action; +import hudson.model.Run; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.jenkins.plugins.lockableresources.LockableResource; +import org.jenkins.plugins.lockableresources.LockableResourcesManager; +import org.jenkins.plugins.lockableresources.Messages; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +// ----------------------------------------------------------------------------- +/** BuildAction for lockable resources. + * Shows usage of resources in the build page. + * url: jobUrl/buildNr/locked-resources/ + */ +@Restricted(NoExternalUse.class) public class LockedResourcesBuildAction implements Action { + // ------------------------------------------------------------------------- private final List lockedResources; + // ------------------------------------------------------------------------- public LockedResourcesBuildAction(List lockedResources) { this.lockedResources = lockedResources; } + // ------------------------------------------------------------------------- public List getLockedResources() { return lockedResources; } + // ------------------------------------------------------------------------- @Override public String getIconFileName() { return LockableResourcesRootAction.ICON; } + // ------------------------------------------------------------------------- @Override public String getDisplayName() { - return "Locked Resources"; + return Messages.LockedResourcesBuildAction_displayName(); } + // ------------------------------------------------------------------------- @Override public String getUrlName() { return "locked-resources"; } + // ------------------------------------------------------------------------- + /** Adds *resourceNames* to *build*. + * When the action does not exists, will be created as well. + * When the resource has been used by this build just now, the counter will + * increased to eliminate multiple entries. + * Used in pipelines - lock() step + */ + @Restricted(NoExternalUse.class) + public static void updateAction(Run build, List resourceNames) { + LockedResourcesBuildAction action = build.getAction(LockedResourcesBuildAction.class); + + if (action == null) { + List resPojos = new ArrayList<>(); + action = new LockedResourcesBuildAction(resPojos); + build.addAction(action); + } + + for (String name : resourceNames) { + LockableResource r = LockableResourcesManager.get().fromName(name); + action.add(new ResourcePOJO(r)); + } + } + + // ------------------------------------------------------------------------- + /** Add the resource to build action.*/ + @Restricted(NoExternalUse.class) + private void add(ResourcePOJO r) { + for (ResourcePOJO pojo : this.lockedResources) { + if (pojo.getName().equals(r.getName())) { + pojo.inc(); + return; + } + } + this.lockedResources.add(r); + } + + // ------------------------------------------------------------------------- + /** Create action from resources. + * Used in free-style projects. + */ + @Restricted(NoExternalUse.class) public static LockedResourcesBuildAction fromResources(Collection resources) { List resPojos = new ArrayList<>(); for (LockableResource r : resources) resPojos.add(new ResourcePOJO(r)); return new LockedResourcesBuildAction(resPojos); } + // ------------------------------------------------------------------------- public static class ResourcePOJO { + // --------------------------------------------------------------------- private String name; private String description; + private int count = 1; + // --------------------------------------------------------------------- public ResourcePOJO(String name, String description) { this.name = name; this.description = description; } + // --------------------------------------------------------------------- public ResourcePOJO(LockableResource r) { this.name = r.getName(); this.description = r.getDescription(); } + // --------------------------------------------------------------------- public String getName() { - return name; + return this.name; } + // --------------------------------------------------------------------- public String getDescription() { - return description; + return this.description; + } + + // --------------------------------------------------------------------- + /** Return the counter, how many was / is the resource used in the build. + * Example: you can use the lock() function in parallel stages for the + * same resource. + */ + public int getCounter() { + return this.count; + } + + // --------------------------------------------------------------------- + /** Increment counter */ + public void inc() { + this.count++; } } } diff --git a/src/main/resources/org/jenkins/plugins/lockableresources/Messages.properties b/src/main/resources/org/jenkins/plugins/lockableresources/Messages.properties index f53e5256f..7c85b5e1a 100644 --- a/src/main/resources/org/jenkins/plugins/lockableresources/Messages.properties +++ b/src/main/resources/org/jenkins/plugins/lockableresources/Messages.properties @@ -20,6 +20,7 @@ LockableResourcesRootAction.StealPermission.Description=This permission grants t LockableResourcesRootAction.ViewPermission=View LockableResourcesRootAction.ViewPermission.Description=This permission grants the ability to view \ lockable resources. +LockedResourcesBuildAction.displayName=Used lockable resources # Java errors error.labelDoesNotExist=The resource label does not exist: {0}. error.resourceDoesNotExist=The resource does not exist: {0}. diff --git a/src/main/resources/org/jenkins/plugins/lockableresources/actions/LockedResourcesBuildAction/index.jelly b/src/main/resources/org/jenkins/plugins/lockableresources/actions/LockedResourcesBuildAction/index.jelly index 13e80efde..0cace6df6 100644 --- a/src/main/resources/org/jenkins/plugins/lockableresources/actions/LockedResourcesBuildAction/index.jelly +++ b/src/main/resources/org/jenkins/plugins/lockableresources/actions/LockedResourcesBuildAction/index.jelly @@ -1,34 +1,83 @@ - + + - - + + + + + - + + -

${%header.resources}

-

${%header.resources.list}

-
    - -
  • - ${resource.name} - ${resource.description} -
  • -
    -
+ + + + ${%app.bar.resources} + + + + + + + +
+ + + + + + + + + + + + + + + + + +
${%table.column.index}${%table.column.name}${%table.column.description}${%table.column.counter}
${idx.index + 1}${resource.name}${resource.description}${resource.counter}
+
+