Last active
November 18, 2021 12:50
-
-
Save askalee/2148608fb4423d97ded690829daae173 to your computer and use it in GitHub Desktop.
Monitor jenkins slave disk space
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://gist.github.com/askalee/2148608fb4423d97ded690829daae173 | |
// HISTORY: | |
// * 2017/10/19: show free disk size for all nodes | |
// * 2017/10/23: auto check nodes labeled with _autoClean | |
// * 2017/10/26: 1. monitor all nodes instead of only monitor specific nodes with certain label | |
// 2. catch exceptions | |
import hudson.model.*; | |
import hudson.util.*; | |
import jenkins.model.*; | |
import hudson.FilePath.FileCallable; | |
import hudson.slaves.OfflineCause; | |
import hudson.node_monitors.*; | |
import static Constatns.*; | |
def RunUnitTests() { | |
println("INFO: Running Unit Tests") | |
def tests = [:] | |
// define unit tests here | |
tests["sample test"] = { | |
assert 1==1 | |
} | |
// end of define unit tests | |
tests.each {testName, testScript -> | |
println("UNITTEST [${testName}]: Run...") | |
testScript() | |
println("UNITTEST [${testName}]: Passed") | |
} | |
println("INFO: End of Unit Tests, all tests should have passed") | |
} | |
RunUnitTests() | |
if(build.buildVariableResolver.resolve("HandleUnitTests") == "TestOnly"){ | |
println("WARNING: Run tests only, skip running main script") | |
return 0 | |
} | |
////// Main Script /////// | |
class Constatns{ | |
static final MINIMUM_SPACE_IN_G = 10 | |
} | |
def mapNodeToFreeSize = [:] | |
def mapDangerousNodeToFreeSize = [:] | |
def nodesToCheck = Jenkins.instance.nodes | |
for (node in nodesToCheck) { | |
println("=== Begin to handle node ${node.name} ===") | |
try { | |
computer = node.toComputer() | |
rootPath = node.getRootPath() | |
if(rootPath == null){ | |
println("WARNING: Cannot get rootPath on node ${node.name}") | |
continue | |
} | |
println("jenkins folder: ${rootPath}") | |
size = DiskSpaceMonitor.DESCRIPTOR.get(computer).size | |
roundedSize = (size / (1024f * 1024f * 1024f)).round(2) | |
println("node: " + node.getDisplayName() + ", free space: " + roundedSize + "GB") | |
mapNodeToFreeSize[node.name.toString()] = roundedSize | |
if (roundedSize < MINIMUM_SPACE_IN_G) { | |
mapDangerousNodeToFreeSize[node.name.toString()] = roundedSize | |
} | |
} catch(e) { | |
println("ERROR: exception: " + e.toString()) | |
e.printStackTrace() | |
} | |
} | |
Thread.currentThread().executable.setDescription( | |
GenerateDescription(nodesToCheck, mapNodeToFreeSize, mapDangerousNodeToFreeSize)) | |
return (mapDangerousNodeToFreeSize.size() > 0) ? false : true | |
////////////////////////////////////////////// | |
def GenerateDescription(nodesToCheck, mapNodeToFreeSize, mapDangerousNodeToFreeSize) { | |
def desc = StringBuilder.newInstance() | |
if(mapDangerousNodeToFreeSize.size() > 0) { | |
desc << "<h1>Found some dangerous nodes, which have free space lower than ${MINIMUM_SPACE_IN_G}G</h1>" | |
desc << "Dangerous Nodes:" | |
desc << "<table border=1>" | |
mapDangerousNodeToFreeSize.each{node, freeSpace -> | |
desc << "<tr>" | |
desc << "<th align='left'>${node}</th>" | |
desc << "<td align='right'><font color=red>${String.format("%.2f",freeSpace)}G</font></td>" | |
desc << "</tr>" | |
} | |
desc << "</table>" | |
} else { | |
desc << "<h1>Great! No dangerous nodes, which have free space lower than ${MINIMUM_SPACE_IN_G}G</h1>" | |
} | |
desc << "<br/>Verified nodes:" | |
nodesToCheck.each{v -> | |
desc << "<ul>" | |
desc << "<li>${v.name}: ${mapNodeToFreeSize[v.name]}G</li>" | |
desc << "</ul>" | |
} | |
return desc.toString() | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment