当前位置: 首页 > 知识库问答 >
问题:

有没有办法通过Jenkins脚本控制台用groovy脚本清理Jenkins Worflowjob工作区?

曾实
2023-03-14

这个问题似乎被问了多次,但所有答案都与Jenkins Pipeline jobs(插件:workflow job)有关。

我正在将一堆旧的自由式作业从旧的Jenkins独立服务器迁移到分布式Jenkinsenv,我决定将它们转换为Jenkins管道作业(不能使用Blue Ocean,因为SCM是SVN。

无论如何,对于某些作业来说,不希望清理它们的工作空间,因为它们是某种健全/验证作业,而且因为SVN签出和构建的内容的大小很大(20K文件中有2GB,只是删除它太慢)。

然而,我确实偶尔(临时)需要删除此类作业的工作区。我不想这样做:

  • 修改Jenkinsfile并将其提交给SVN
  • "重放"管道运行修改

我没有对从节点上的FS的r/w访问权限(这是最容易做到的)。

互联网上的快速搜索给我带来了大量结果[1,2,3,4,…]如何从Jenkins脚本控制台运行的Groovy脚本中清除WS()。

不幸的是,它们都没有尝试删除作业的trueorg.jenkinsci.plugins.workflow.job.Workflow Jobs项实例的工作区。

基于从互联网上收集到的答案,我启动了我的Groovy清理脚本,可以从Jenkins脚本控制台

import hudson.model.*
import com.cloudbees.hudson.*
import com.cloudbees.hudson.plugins.*
import com.cloudbees.hudson.plugins.folder.*
import org.jenkinsci.plugins.workflow.job.*

//jobsToRetrieve = ["aFolder/aJobInFolder","topLevelJob"]
jobsToRetrieve = ["Sandbox/PipelineTests/SamplePipeline"]

enumerateItems(Hudson.instance.items)

def enumerateItems(items) {
  items.each { item ->
    println("===============::: GENERAL INFO::: =======================")
    println(" item: " + item)
    println(" item FN:  " + item.fullName)
    println(" item.getClass " + item.getClass())
    println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")

    if ( !(item instanceof Folder)) {
      jobName = item.getFullDisplayName()
      println(" :::jobname::: " + jobName)
      if (jobsToRetrieve.contains(item.getFullName())) {
        if (item instanceof WorkflowJob) {
          println("XXXXXXXXXXXXX--- THIS IS THE JOB --- XXXXXXXXXXXXXXXXXXXXX")
          println(" item.workspace: " + item.WORKSPACE)
          println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
          println(" following methods ain't implemented for WorkflowJob type of Item\nand it will blow out.")
          //see https://javadoc.jenkins.io/hudson/model/FreeStyleProject.html
          println(" customWS: " + item.getCustomWorkspace())
          println(" WS:" + item.getWorkspace())
          item.doDoWipeOutWorkspace()
        }
      }
    } else {
        println(" :::foldername::: " + item.displayName)
        enumerateItems(((Folder) item).getItems())
    }
    println("==========================================================")
  }
}

如您所见,我的脚本将在以下调用中爆炸:

item.getCustomWorkspace()
item.getWorkspace()
item.doDoWipeOutWorkspace()

带有MissingMethodException

groovy.lang.MissingMethodException: No signature of method: org.jenkinsci.plugins.workflow.job.WorkflowJob.doDoWipeOutWorkspace() is applicable for argument types: () values: []
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:58)
    at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:49)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
    at Script1$_enumerateItems_closure1.doCall(Script1.groovy:33)

只是因为这些方法不适用于此类项目,而仅适用于hudson。模型自由泳项目

还有另一个Jenkins插件:Workspace Cleanup可能在Jenkinsfile中使用,方法是在阶段() {}内调用清洁Ws(),但我不知道如何从Jenkinsfile外部使用它(就像从我Jenkins脚本控制台运行的groovy脚本一样)。

这是一个错误/请求增强Jenkins管道作业插件?或者有任何其他方法如何将项目转换为我可以访问所需功能的东西?


共有2个答案

濮嘉茂
2023-03-14

这不是最漂亮的方法,但您可以执行OS命令:

def isWin = Jenkins.instance.windows
def cmd = isWin ? "rmdir /s /q $workspace" : "rm -rf $workspace"

cmd.execute()

如果您只使用一次代码或不处理多个操作系统,您可以将代码缩短为相应的命令:

"rm -rf $workspace".execute()
厍晋鹏
2023-03-14

好吧,更多地调查这件事,更多地用谷歌搜索,倾听你的想法(这件事特别是丹尼尔·斯皮尔克启发了我),我已经实现了我想要的,那就是:

(仅使用Jenkins可用的方法,并且不会弄乱作业配置,也不会更新Jenkins文件,也不会重播)

代码的难度并不出人意料,对于手动演示,它看起来是这样的:

Jenkins jenkins = Jenkins.instance
Job item = jenkins.getItemByFullName('Sandbox/PipelineTests/SamplePipeline')
println("RootDir: " + item.getRootDir())

for (Node node in jenkins.nodes) {
  // Make sure slave is online
  if (!node.toComputer().online) {
    println "Node '$node.nodeName' is currently offline - skipping workspace cleanup"
    continue
  }

  println "Node '$node.nodeName' is online - performing cleanup:"

  // Do some cleanup
  FilePath wrksp = node.getWorkspaceFor(item)
  println("WRKSP "  + wrksp)
  println("ls " + wrksp.list())
  println("Free space " + wrksp.getFreeDiskSpace())
  println("===== PERFORMING CLEAN UP!!! =====")
  wrksp.deleteContents()
  println("ls now " + wrksp.list())
  println("Free space now " + wrksp.getFreeDiskSpace())
}

如果找到工作,其输出如下:

RootDir: /var/lib/jenkins/jobs/Sandbox/jobs/PipelineTests/jobs/SamplePipeline
....
.... other node's output noise
....
Node 'mcs-ubuntu-chch' is online - performing cleanup:
WRKSP /var/lib/jenkins/workspace/Sandbox/PipelineTests/SamplePipeline
ls [/var/lib/jenkins/workspace/Sandbox/PipelineTests/SamplePipeline/README.md, /var/lib/jenkins/workspace/Sandbox/PipelineTests/SamplePipeline/.git]
Free space 3494574714880
===== PERFORMING CLEAN UP!!! =====
ls now []
Free space now 3494574919680

任务完成:)

主要是詹金斯·贾瓦多克

  • https://javadoc.jenkins.io/hudson/model/Node.html
 类似资料:
  • 问题内容: 在我的jenkins管道文件中,我使用从.json文件读取构建配置。但是,这引入了需要 在进程内“脚本批准” 页面上批准的代码。通过GUI执行此操作时,效果很好。 但是,我还有一个脚本会自动设置我的jenkins机器,该机器将创建不需要任何GUI操作即可使用的现成机器。该脚本已使用jenkins脚本控制台批准从属启动命令。在脚本控制台中执行此操作的常规代码如下所示。 效果很好,但现在我

  • 我需要从Jenkins作业中获取脚本路径。 请查看下面的屏幕截图,以便更清楚地了解需求。 我已经登录谷歌,获取了一些Groovy控制台脚本,其中列出了每个作业的详细信息。 通过使用jenkins.model.Jenkins.getJobNames()方法,我能够得到Jenkins中的所有作业,但实际上需要的是获得Scriptpath值,在每个作业中提到。 哪个Jenkins类/方法可以提供这些细节

  • 问题内容: 我是Jenkins中使用的Groovy脚本的新手。我的问题是,我们如何根据作业名称和内部版本号获取作业的时间戳? 示例 :我想获取“ MyDeployJob”(JobName)的时间戳,并获取BuildNumber-105的时间戳。 我尝试使用方法方法,但无法正常工作。另外,我发现环境变量具有时间戳,但是我无法弄清楚如何使用Groovy Script获取细节。请帮助。 提前致谢。 问题

  • 我正在使用Netbeans 7.4。我使用glassfish服务器创建了一个新的web项目。现在我喜欢在其中使用groovy脚本。但问题是groovy代码没有在那里进行解释。其输出与代码相同。 它应该给输出Hello Barun!但不是给我输出def name='Barun'println“Hello$name!” 我还将最新的groovy-all jar文件包含到我的项目库中。但是还没有运气。我

  • 我所说的“完全相同”是指脚本是相同的,但是脚本控制台和管道之间的DSL是不同的。例如,在脚本控制台中,我使用 而在管道中,我使用

  • 我正在Liferay控制面板服务器管理脚本控制台中测试一个快速groovy脚本。我需要尝试一下,看看是否可以使用Liferay API以编程方式添加新用户。 我是groovy的新手,可能犯了一个新手错误。我不知道为什么会出错,我一直在努力寻找解决办法。 我正在tomcat上使用Liferay 6.2 EE sp7。 我的脚本代码是 我得到的错误是: groovy.lang.缺少方法异常:没有方法的