Some of these Groovy scripts can be pasted into user jobs, and others require Admin script console access.
The low-diskspace was forked from someone else.
I made the multiAxis.groovy --though it seems so simple that it should be built in.
| // paste in per-job --requires Active Choices plugin https://wiki.jenkins-ci.org/display/JENKINS/Active+Choices+Plugin | |
| // TBD: get the defaults from some external source rather than store in code here | |
| def rf_subsets = "smoke.txt,[a-d]*.txt,[ne]*.txt,[f-mo-z]*.txt" // default values -- used when called from other jobs vs. Jenkins web UI | |
| if (context != null) { | |
| rf_subsets = context.build.buildVariableResolver.resolve("rf_subsets") // read input parameter | |
| } | |
| subsets = rf_subsets.split(",|\n+") // regex to handle multi-line text parameter | |
| return subsets as List |
| // paste into Script Console under Admin | |
| // Check if a slave has < 10 GB of free space, wipe out workspaces if it does --skipping folders, preserving offline status | |
| import hudson.model.*; | |
| import hudson.util.*; | |
| import jenkins.model.*; | |
| import hudson.FilePath.FileCallable; | |
| import hudson.slaves.OfflineCause; | |
| import hudson.node_monitors.*; | |
| def sizeLimit = 10 // GB | |
| println "${Jenkins.instance.nodes.size()} remote nodes detected." | |
| for (node in Jenkins.instance.nodes) { | |
| computer = node.toComputer() | |
| if (computer.getChannel() == null) continue | |
| rootPath = node.getRootPath() | |
| size = DiskSpaceMonitor.DESCRIPTOR.get(computer).size | |
| roundedSize = size / (1024 * 1024 * 1024) as int | |
| println("node: " + node.getDisplayName() + ", free space: " + roundedSize + "GB") | |
| if (roundedSize < sizeLimit) { | |
| prevOffline = computer.isOffline() | |
| if (!prevOffline) { | |
| computer.setTemporarilyOffline(true, new hudson.slaves.OfflineCause.ByCLI("disk cleanup")) | |
| } | |
| for (item in Jenkins.instance.items) { | |
| jobName = item.getFullDisplayName() | |
| // If the installation uses cloudbees Folders, not everything is a Job | |
| if (!(item instanceof Job)) { | |
| println "Skipping ${item.name}, not a Job" | |
| continue | |
| } | |
| if (item.isBuilding()) { | |
| println(".. job " + jobName + " is currently running, skipped") | |
| continue | |
| } | |
| println(".. Reporting on workspaces of job " + jobName) | |
| workspacePath = node.getWorkspaceFor(item) | |
| if (workspacePath == null) { | |
| println(".... could not get workspace path") | |
| continue | |
| } | |
| println(".... workspace = " + workspacePath) | |
| customWorkspace = item.getCustomWorkspace() | |
| if (customWorkspace != null) { | |
| workspacePath = node.getRootPath().child(customWorkspace) | |
| println(".... custom workspace = " + workspacePath) | |
| } | |
| pathAsString = workspacePath.getRemote() | |
| if (workspacePath.exists()) { | |
| // workspacePath.deleteRecursive() // un-comment this line to take action | |
| println(".... location " + pathAsString + " // TBD: report size(s)") | |
| } else { | |
| println(".... nothing to delete at " + pathAsString) | |
| } | |
| } | |
| if (!prevOffline) { | |
| computer.setTemporarilyOffline(false, null) | |
| } | |
| } | |
| } |
Integrated changes from https://gist.github.com/akomakom