我们大多会选择 Jenkins 来部署我们的持续集成/测试/交互系统,但是当我们需要做 Jenkins 相关服务的维护时可以怎么做呢?笔者摸索了如下的一些方案:
基础方法——Jenkins Script Console
Jenkins Script Console 是 Jenkins 设计来在 Jenkins Server 或者 Slave Nodes 上执行任意的 scripts的。该功能的入口在 “Manage Jenkins” 之中,也可以直接通过 http://server/jenkins/script 来访问。
Jenkins Script Console 除了能执行各种指令外,最为重要的是它具备远程控制的能力:
$ curl -d "script=<your_script_here>" http://jenkins/script
$ # or
$ curl -d "script=<your_script_here>" http://jenkins/scriptText
或者,也可以将本地工作空间的脚本通过如下的方式传至 Jenkins Script Console:
$ curl --data-urlencode "script=$(<./somescript.groovy)" http://jenkins/scriptText
如果想了解更多关于 Jenkins Script Console 的信息,可以直接查看官方文档。
常用 Jenkins Script
以下给出的均是笔者使用过的一些 Groovy Scripts。
定时检查各 Node 的磁盘剩余空间
for (node in jenkins.model.Jenkins.instance.nodes) {
computer = node.toComputer()
if (node.toComputer().online) {
size = hudson.node_monitors.DiskSpaceMonitor.DESCRIPTOR.get(computer).size
roundedSize = size / (1024 * 1024 * 1024) as int
println("node: " + node.getDisplayName() + ", free space: " + roundedSize + "GB")
}
}
查看某个时间段内的所有 Build
import hudson.model.AbstractBuild
import hudson.model.AbstractProject
import java.text.SimpleDateFormat
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
starttime = new GregorianCalendar()
endtime = new GregorianCalendar()
buildEnd = new GregorianCalendar()
starttime.setTime(df.parse("2016-12-01 00:00:00"))
endtime.setTime(df.parse("2016-12-01 23:59:59"))
for (AbstractProject p : hudson.model.Hudson.instance.projects) {
for (AbstractBuild b : p.getBuilds()) {
if (b == null) break
if (b.isBuilding() || b.timestamp >= endtime) continue
buildEnd.setTimeInMillis(b.timestamp.getTimeInMillis() + b.duration)
if (buildEnd < starttime) break
println b
}
}
清理部分已经长时间未构建的 Job
import hudson.model.AbstractProject
int days = 30
Date xDaysAgo = new Date(((long) new Date().time - (1000L * 60 * 60 * 24 * days)))
jenkins = jenkins.model.Jenkins.instance
jobs = jenkins.items.findAll { job ->
(job instanceof AbstractProject && job.disabled && (job.lastSuccessfulBuild?.time?.before(xDaysAgo) || job.lastSuccessfulBuild == null))
}
int count = 0
jobs.each { job ->
println "Deleting ${job.name}. It's lastSuccessfulBuild is ${job.lastSuccessfulBuild?.time}"
job.delete()
count++
}
println "\nDeleted ${count} jobs.\n"